From e37659e4b38f05e11bfbfb8566583a349f7bccac Mon Sep 17 00:00:00 2001 From: Astro Date: Thu, 5 Dec 2019 01:15:14 +0100 Subject: [PATCH] zynq::flash: refactor --- src/zynq/flash/bytes.rs | 41 ++++++++++ src/zynq/flash/instr.rs | 37 --------- src/zynq/flash/mod.rs | 166 +++++++++++++++------------------------- 3 files changed, 101 insertions(+), 143 deletions(-) create mode 100644 src/zynq/flash/bytes.rs delete mode 100644 src/zynq/flash/instr.rs diff --git a/src/zynq/flash/bytes.rs b/src/zynq/flash/bytes.rs new file mode 100644 index 00000000..31b794f7 --- /dev/null +++ b/src/zynq/flash/bytes.rs @@ -0,0 +1,41 @@ +pub trait BytesTransferExt: Sized { + // Turn u32 into u8 + fn bytes_transfer(self) -> BytesTransfer + where + Self: Iterator; +} + +impl> BytesTransferExt for I { + // Turn u32 into u8 + fn bytes_transfer(self) -> BytesTransfer { + BytesTransfer { + iter: self, + shift: 32, + word: 0, + } + } +} + +pub struct BytesTransfer + Sized> { + iter: I, + shift: u8, + word: u32, +} + +impl + Sized> Iterator for BytesTransfer { + type Item = u8; + + fn next(&mut self) -> Option { + if self.shift < 24 { + self.shift += 8; + Some((self.word >> self.shift) as u8) + } else { + self.shift = 0; + self.iter.next() + .map(|word| { + self.word = word; + word as u8 + }) + } + } +} diff --git a/src/zynq/flash/instr.rs b/src/zynq/flash/instr.rs deleted file mode 100644 index 36a349d0..00000000 --- a/src/zynq/flash/instr.rs +++ /dev/null @@ -1,37 +0,0 @@ -use super::Transfer; - -pub trait Instruction { - type Args: Iterator; - type Result: for<'r, 't> From<&'t mut Transfer<'r, Self::Args>>; - fn inst_code() -> u8; - fn args(&self) -> Self::Args; -} - -pub struct ReadId; - -impl Instruction for ReadId { - type Result = u32; // TODO: u8; - type Args = core::iter::Empty; - - fn inst_code() -> u8 { - 0x9f - } - fn args(&self) -> Self::Args { - core::iter::empty() - } -} - -/// Read configuration register -pub struct RdCr; - -impl Instruction for RdCr { - type Result = u8; - type Args = core::iter::Empty; - - fn inst_code() -> u8 { - 0x35 - } - fn args(&self) -> Self::Args { - core::iter::empty() - } -} diff --git a/src/zynq/flash/mod.rs b/src/zynq/flash/mod.rs index 46d88aaf..ab1435cb 100644 --- a/src/zynq/flash/mod.rs +++ b/src/zynq/flash/mod.rs @@ -6,7 +6,8 @@ use super::slcr; use super::clocks::CpuClocks; mod regs; -mod instr; +mod bytes; +pub use bytes::{BytesTransferExt, BytesTransfer}; const FLASH_BAUD_RATE: u32 = 50_000_000; const SINGLE_CAPACITY: u32 = 16 * 1024 * 1024; @@ -312,136 +313,89 @@ impl Flash { } pub fn rdcr(&mut self) -> u8 { - self.transfer(instr::RdCr) + self.transfer(0x35, core::iter::empty()) + .bytes_transfer().skip(1) + .next().unwrap() as u8 } - pub fn transfer(&mut self, input: I) -> I::Result { - let mut t = Transfer::new(&mut self.regs, I::inst_code(), input.args()); - (&mut t).into() + pub fn rdid(&mut self) -> core::iter::Skip>>> { + self.transfer(0x9f, core::iter::empty()) + .bytes_transfer().skip(1) } - pub fn read(&mut self, offset: u32, dest: &mut [u8]) { - - // Quad Read - let instr = 0xEB; - unsafe { - self.regs.txd0.write( - instr | - (offset << 8) - ); - } - let mut n = 0; - while !self.regs.intr_status.read().tx_fifo_full() { - unsafe { - self.regs.txd0.write(0); - } - n += 1; - } - - self.regs.config.modify(|_, w| w - .pcs(false) - .man_start_com(true) - ); - - let mut offset = 0; - while offset < dest.len() { - while !self.regs.intr_status.read().rx_fifo_not_empty() {} - - // TODO: drops data? - let rx = self.regs.rx_data.read(); - if offset < dest.len() { - dest[offset] = rx as u8; - } - offset += 1; - if offset < dest.len() { - dest[offset] = (rx >> 8) as u8; - } - offset += 1; - if offset < dest.len() { - dest[offset] = (rx >> 16) as u8; - } - offset += 1; - if offset < dest.len() { - dest[offset] = (rx << 24) as u8; - } - offset += 1; - - // Output dummy byte to generate clock for further RX - unsafe { - self.regs.txd0.write(0); - } - } - self.regs.config.modify(|_, w| w - .pcs(true) - .man_start_com(false) - ); - } -} - -pub struct Transfer<'r, Args: Iterator> { - regs: &'r mut regs::RegisterBlock, - args: Args, -} - -impl<'r, Args: Iterator> Transfer<'r, Args> { - pub fn new(regs: &'r mut regs::RegisterBlock, inst_code: u8, mut args: Args) -> Self + pub fn transfer<'s: 't, 't, Args>(&'s mut self, inst_code: u8, args: Args) -> Transfer<'t, Args> where Args: Iterator, { - unsafe { - regs.txd1.write(inst_code.into()); + Transfer::new(self, inst_code, args) + } + + pub fn read(&mut self, offset: u32, len: usize) -> core::iter::Take>>>> { + + // TODO: + let args = Some(0u32); + // Quad Read + self.transfer(0xEB, args.into_iter()) + .bytes_transfer().skip(1).take(len) + } +} + +pub struct Transfer<'a, Args: Iterator> { + flash: &'a mut Flash, + args: Args, +} + +impl<'a, Args: Iterator> Transfer<'a, Args> { + pub fn new(flash: &'a mut Flash, inst_code: u8, mut args: Args) -> Self + where + Args: Iterator, + { + while flash.regs.intr_status.read().rx_fifo_not_empty() { + flash.regs.rx_data.read(); } - while !regs.intr_status.read().tx_fifo_full() { + + unsafe { + flash.regs.txd1.write(inst_code.into()); + } + while !flash.regs.intr_status.read().tx_fifo_full() { let arg = args.next().unwrap_or(0); unsafe { - regs.txd0.write(arg); + flash.regs.txd0.write(arg); } } - regs.config.modify(|_, w| w + flash.regs.config.modify(|_, w| w .pcs(false) .man_start_com(true) ); - Transfer { regs, args } - } - - pub fn recv(&mut self) -> u32 { - while !self.regs.intr_status.read().rx_fifo_not_empty() {} - let rx = self.regs.rx_data.read(); - - let arg = self.args.next().unwrap_or(0); - unsafe { - self.regs.txd0.write(arg); + Transfer { + flash, + args, } - - rx } } -impl<'r, Args: Iterator> Drop for Transfer<'r, Args> { +impl<'a, Args: Iterator> Drop for Transfer<'a, Args> { fn drop(&mut self) { - self.regs.config.modify(|_, w| w - .pcs(true) - .man_start_com(false) + self.flash.regs.config.modify(|_, w| w + .pcs(false) + .man_start_com(true) ); } } +impl<'a, Args: Iterator> Iterator for Transfer<'a, Args> { + type Item = u32; -impl<'t, Args: Iterator> From<&'t mut Transfer<'_, Args>> for u32 { - fn from(t: &mut Transfer<'_, Args>) -> u32 { - t.recv() - } -} - -impl> From<&mut Transfer<'_, Args>> for u8 { - fn from(t: &mut Transfer<'_, Args>) -> u8 { - u32::from(t) as u8 - } -} - -impl> From<&mut Transfer<'_, Args>> for u16 { - fn from(t: &mut Transfer<'_, Args>) -> u16 { - u32::from(t) as u16 + fn next<'s>(&'s mut self) -> Option { + while !self.flash.regs.intr_status.read().rx_fifo_not_empty() {} + let rx = self.flash.regs.rx_data.read(); + + let arg = self.args.next().unwrap_or(0); + unsafe { + self.flash.regs.txd0.write(arg); + } + + Some(rx) } }