From e9b80eaef9afc7b9ccff9274e1dcec3cfbdb99b0 Mon Sep 17 00:00:00 2001 From: Astro Date: Tue, 10 Dec 2019 02:50:44 +0100 Subject: [PATCH] zynq::flash: don't send excess data, fixes, refactorings --- src/main.rs | 30 ++++++++++++- src/zynq/flash/mod.rs | 99 ++++++++++++++++++++++++------------------- 2 files changed, 84 insertions(+), 45 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9f0af11..b0a7ab4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,13 +29,41 @@ mod ram; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; pub fn main() { - println!("Main."); + println!("\nzc706 main"); + + let mut flash = zynq::flash::Flash::new(200_000_000).linear_addressing_mode(); + let flash_ram: &[u8] = unsafe { core::slice::from_raw_parts(flash.ptr(), flash.size()) }; + for i in 0..=1 { + print!("Flash {}:", i); + for b in &flash_ram[(i * 16 * 1024 * 1024)..][..128] { + print!(" {:02X}", *b); + } + println!(""); + } + let mut flash = flash.stop(); let mut ddr = zynq::ddr::DdrRam::new(); println!("DDR: {:?}", ddr.status()); ddr.memtest(); ram::init_alloc(&mut ddr); + for i in 0..=1 { + let mut flash_io = flash.manual_mode(i); + print!("Flash {} ID:", i); + for b in flash_io.rdid() { + print!(" {:02X}", b); + } + println!(""); + print!("Flash {} I/O:", i); + for o in 0..4 { + for b in flash_io.read(32 * o, 32) { + print!(" {:02X}", b); + } + } + println!(""); + flash = flash_io.stop(); + } + let core1_stack = vec![0; 2048]; println!("{} bytes stack for core1", core1_stack.len()); boot::Core1::start(core1_stack); diff --git a/src/zynq/flash/mod.rs b/src/zynq/flash/mod.rs index 69d2492..83f5282 100644 --- a/src/zynq/flash/mod.rs +++ b/src/zynq/flash/mod.rs @@ -281,7 +281,7 @@ impl Flash<()> { .mode_en(true) // 2 devices .two_mem(true) - // .sep_bus(true) + .sep_bus(true) .u_page(chip_index != 0) // Manual I/O mode .lq_mode(false) @@ -317,41 +317,45 @@ impl Flash { /// Read Configuration Register pub fn rdcr(&mut self) -> u8 { - self.transfer(INST_RDCR, core::iter::empty()) + let args = Some((INST_RDCR as u32) << 24); + self.transfer(args.into_iter(), 4) .bytes_transfer().skip(1) .next().unwrap() as u8 } /// Read Identifiaction - pub fn rdid(&mut self) -> core::iter::Skip>>> { - self.transfer(INST_RDID, core::iter::empty()) + pub fn rdid(&mut self) -> core::iter::Skip>>> { + let args = Some((INST_RDID as u32) << 24); + self.transfer(args.into_iter(), 0x44) .bytes_transfer().skip(1) } - pub fn transfer<'s: 't, 't, Args>(&'s mut self, inst_code: u8, args: Args) -> Transfer<'t, Args> + /// Read flash data + pub fn read(&mut self, offset: u32, len: usize) -> core::iter::Take>>>> { + // INST_READ + let args = Some((0x03 << 24) | (offset as u32)); + self.transfer(args.into_iter(), len + 6) + .bytes_transfer().skip(6).take(len) + } + + pub fn transfer<'s: 't, 't, Args>(&'s mut self, args: Args, len: usize) -> Transfer<'t, Args> where Args: Iterator, { - Transfer::new(self, inst_code, args) - } - - pub fn read(&mut self, offset: u32, len: usize) -> core::iter::Take>>>> { - - // TODO: - let args = Some(0u32); - // Read - self.transfer(0x03, args.into_iter()) - .bytes_transfer().skip(1).take(len) + Transfer::new(self, args, len) } } pub struct Transfer<'a, Args: Iterator> { flash: &'a mut Flash, args: Args, + sent: usize, + received: usize, + len: usize, } impl<'a, Args: Iterator> Transfer<'a, Args> { - pub fn new(flash: &'a mut Flash, inst_code: u8, mut args: Args) -> Self + pub fn new(flash: &'a mut Flash, args: Args, len: usize) -> Self where Args: Iterator, { @@ -360,37 +364,45 @@ impl<'a, Args: Iterator> Transfer<'a, Args> { regs::Enable::zeroed() .spi_en(true) ); - while flash.regs.intr_status.read().rx_fifo_not_empty() { - flash.regs.rx_data.read(); - } - unsafe { - flash.regs.txd1.write(inst_code.into()); - } - flash.regs.config.modify(|_, w| w.man_start_com(true)); - // Flush after `txd1` access - while !flash.regs.intr_status.read().tx_fifo_not_full() {} - - while !flash.regs.intr_status.read().tx_fifo_full() { - let arg = args.next().unwrap_or(0); - unsafe { - flash.regs.txd0.write(arg); - } - } - - flash.regs.config.modify(|_, w| w.man_start_com(true)); - Transfer { + 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().unwrap_or(0); + unsafe { + self.flash.regs.txd0.write(arg); + } + self.sent += 4; } } + + 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> Drop for Transfer<'a, Args> { fn drop(&mut self) { // Discard remaining rx_data - while self.flash.regs.intr_status.read().rx_fifo_not_empty() { - self.flash.regs.rx_data.read(); + while self.can_read() { + self.read(); } // Stop @@ -409,14 +421,13 @@ impl<'a, Args: Iterator> Iterator for Transfer<'a, Args> { type Item = u32; 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); + if self.received >= self.len { + return None; } - Some(rx) + self.fill_tx_fifo(); + + while !self.can_read() {} + Some(self.read()) } }