From 0d1cf04a34c61bf764a538c08b35eaab932d1f1e Mon Sep 17 00:00:00 2001 From: Astro Date: Sun, 15 Dec 2019 19:28:55 +0100 Subject: [PATCH] zynq::flash: split into mod transfer --- src/zynq/flash/mod.rs | 126 +----------------------------------- src/zynq/flash/transfer.rs | 127 +++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 124 deletions(-) create mode 100644 src/zynq/flash/transfer.rs diff --git a/src/zynq/flash/mod.rs b/src/zynq/flash/mod.rs index e73b817..70b62a3 100644 --- a/src/zynq/flash/mod.rs +++ b/src/zynq/flash/mod.rs @@ -10,6 +10,8 @@ mod bytes; pub use bytes::{BytesTransferExt, BytesTransfer}; mod spi_flash_register; use spi_flash_register::*; +mod transfer; +use transfer::Transfer; const FLASH_BAUD_RATE: u32 = 50_000_000; /// 16 MB @@ -403,128 +405,4 @@ impl Flash { { Transfer::new(self, args, len) } -} -pub struct Transfer<'a, Args: Iterator, W: Into> { - flash: &'a mut Flash, - args: Args, - sent: usize, - received: usize, - len: usize, -} - -impl<'a, Args: Iterator, W: Into> Transfer<'a, Args, W> { - pub fn new(flash: &'a mut Flash, args: Args, len: usize) -> Self { - flash.regs.config.modify(|_, w| w.pcs(false)); - flash.regs.enable.write( - regs::Enable::zeroed() - .spi_en(true) - ); - - let mut xfer = Transfer { - flash, - args, - sent: 0, - received: 0, - len, - }; - xfer.fill_tx_fifo(); - xfer.flash.regs.config.modify(|_, w| w.man_start_com(true)); - xfer - } - - fn fill_tx_fifo(&mut self) { - while self.sent < self.len && !self.flash.regs.intr_status.read().tx_fifo_full() { - let arg = self.args.next() - .map(|n| n.into()) - .unwrap_or(SpiWord::W32(0)); - match arg { - SpiWord::W32(w) => { - // println!("txd0 {:08X}", w); - unsafe { - self.flash.regs.txd0.write(w); - } - self.sent += 4; - } - // Only txd0 can be used without flushing - _ => { - if !self.flash.regs.intr_status.read().tx_fifo_not_full() { - // Flush if neccessary - self.flash.regs.config.modify(|_, w| w.man_start_com(true)); - self.flash.wait_tx_fifo_flush(); - } - - match arg { - SpiWord::W8(w) => { - // println!("txd1 {:02X}", w); - unsafe { - self.flash.regs.txd1.write(u32::from(w) << 24); - } - self.sent += 1; - } - SpiWord::W16(w) => { - unsafe { - self.flash.regs.txd2.write(u32::from(w) << 16); - } - self.sent += 2; - } - SpiWord::W24(w) => { - unsafe { - self.flash.regs.txd3.write(w << 8); - } - self.sent += 3; - } - SpiWord::W32(_) => unreachable!(), - } - - self.flash.regs.config.modify(|_, w| w.man_start_com(true)); - self.flash.wait_tx_fifo_flush(); - } - } - } - } - - fn can_read(&mut self) -> bool { - self.flash.regs.intr_status.read().rx_fifo_not_empty() - } - - fn read(&mut self) -> u32 { - let rx = self.flash.regs.rx_data.read(); - self.received += 4; - rx - } -} - -impl<'a, Args: Iterator, W: Into> Drop for Transfer<'a, Args, W> { - fn drop(&mut self) { - // Discard remaining rx_data - while self.can_read() { - self.read(); - } - - // Stop - self.flash.regs.enable.write( - regs::Enable::zeroed() - .spi_en(false) - ); - self.flash.regs.config.modify(|_, w| w - .pcs(true) - .man_start_com(false) - ); - } -} - -impl<'a, Args: Iterator, W: Into> Iterator for Transfer<'a, Args, W> { - type Item = u32; - - fn next<'s>(&'s mut self) -> Option { - if self.received >= self.len { - return None; - } - - self.fill_tx_fifo(); - - while !self.can_read() {} - Some(self.read()) - } -} diff --git a/src/zynq/flash/transfer.rs b/src/zynq/flash/transfer.rs new file mode 100644 index 0000000..0889f85 --- /dev/null +++ b/src/zynq/flash/transfer.rs @@ -0,0 +1,127 @@ +use crate::regs::{RegisterR, RegisterW, RegisterRW}; +use super::regs; +use super::{SpiWord, Flash, Manual}; + +pub struct Transfer<'a, Args: Iterator, W: Into> { + flash: &'a mut Flash, + args: Args, + sent: usize, + received: usize, + len: usize, +} + +impl<'a, Args: Iterator, W: Into> Transfer<'a, Args, W> { + pub fn new(flash: &'a mut Flash, args: Args, len: usize) -> Self { + flash.regs.config.modify(|_, w| w.pcs(false)); + flash.regs.enable.write( + regs::Enable::zeroed() + .spi_en(true) + ); + + let mut xfer = Transfer { + flash, + args, + sent: 0, + received: 0, + len, + }; + xfer.fill_tx_fifo(); + xfer.flash.regs.config.modify(|_, w| w.man_start_com(true)); + xfer + } + + fn fill_tx_fifo(&mut self) { + while self.sent < self.len && !self.flash.regs.intr_status.read().tx_fifo_full() { + let arg = self.args.next() + .map(|n| n.into()) + .unwrap_or(SpiWord::W32(0)); + match arg { + SpiWord::W32(w) => { + // println!("txd0 {:08X}", w); + unsafe { + self.flash.regs.txd0.write(w); + } + self.sent += 4; + } + // Only txd0 can be used without flushing + _ => { + if !self.flash.regs.intr_status.read().tx_fifo_not_full() { + // Flush if necessary + self.flash.regs.config.modify(|_, w| w.man_start_com(true)); + self.flash.wait_tx_fifo_flush(); + } + + match arg { + SpiWord::W8(w) => { + // println!("txd1 {:02X}", w); + unsafe { + self.flash.regs.txd1.write(u32::from(w) << 24); + } + self.sent += 1; + } + SpiWord::W16(w) => { + unsafe { + self.flash.regs.txd2.write(u32::from(w) << 16); + } + self.sent += 2; + } + SpiWord::W24(w) => { + unsafe { + self.flash.regs.txd3.write(w << 8); + } + self.sent += 3; + } + SpiWord::W32(_) => unreachable!(), + } + + self.flash.regs.config.modify(|_, w| w.man_start_com(true)); + self.flash.wait_tx_fifo_flush(); + } + } + } + } + + fn can_read(&mut self) -> bool { + self.flash.regs.intr_status.read().rx_fifo_not_empty() + } + + fn read(&mut self) -> u32 { + let rx = self.flash.regs.rx_data.read(); + self.received += 4; + rx + } +} + +impl<'a, Args: Iterator, W: Into> Drop for Transfer<'a, Args, W> { + fn drop(&mut self) { + // Discard remaining rx_data + while self.can_read() { + self.read(); + } + + // Stop + self.flash.regs.enable.write( + regs::Enable::zeroed() + .spi_en(false) + ); + self.flash.regs.config.modify(|_, w| w + .pcs(true) + .man_start_com(false) + ); + } +} + +impl<'a, Args: Iterator, W: Into> Iterator for Transfer<'a, Args, W> { + type Item = u32; + + fn next<'s>(&'s mut self) -> Option { + if self.received >= self.len { + return None; + } + + self.fill_tx_fifo(); + + while !self.can_read() {} + Some(self.read()) + } +}