zynq::flash: don't send excess data, fixes, refactorings

This commit is contained in:
Astro 2019-12-10 02:50:44 +01:00
parent 0823a74164
commit e9b80eaef9
2 changed files with 84 additions and 45 deletions

View File

@ -29,13 +29,41 @@ mod ram;
const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
pub fn main() { 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(); let mut ddr = zynq::ddr::DdrRam::new();
println!("DDR: {:?}", ddr.status()); println!("DDR: {:?}", ddr.status());
ddr.memtest(); ddr.memtest();
ram::init_alloc(&mut ddr); 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]; let core1_stack = vec![0; 2048];
println!("{} bytes stack for core1", core1_stack.len()); println!("{} bytes stack for core1", core1_stack.len());
boot::Core1::start(core1_stack); boot::Core1::start(core1_stack);

View File

@ -281,7 +281,7 @@ impl Flash<()> {
.mode_en(true) .mode_en(true)
// 2 devices // 2 devices
.two_mem(true) .two_mem(true)
// .sep_bus(true) .sep_bus(true)
.u_page(chip_index != 0) .u_page(chip_index != 0)
// Manual I/O mode // Manual I/O mode
.lq_mode(false) .lq_mode(false)
@ -317,41 +317,45 @@ impl Flash<Manual> {
/// Read Configuration Register /// Read Configuration Register
pub fn rdcr(&mut self) -> u8 { 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) .bytes_transfer().skip(1)
.next().unwrap() as u8 .next().unwrap() as u8
} }
/// Read Identifiaction /// Read Identifiaction
pub fn rdid(&mut self) -> core::iter::Skip<BytesTransfer<Transfer<core::iter::Empty<u32>>>> { pub fn rdid(&mut self) -> core::iter::Skip<BytesTransfer<Transfer<core::option::IntoIter<u32>>>> {
self.transfer(INST_RDID, core::iter::empty()) let args = Some((INST_RDID as u32) << 24);
self.transfer(args.into_iter(), 0x44)
.bytes_transfer().skip(1) .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<core::iter::Skip<BytesTransfer<Transfer<core::option::IntoIter<u32>>>>> {
// 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 where
Args: Iterator<Item = u32>, Args: Iterator<Item = u32>,
{ {
Transfer::new(self, inst_code, args) Transfer::new(self, args, len)
}
pub fn read(&mut self, offset: u32, len: usize) -> core::iter::Take<core::iter::Skip<BytesTransfer<Transfer<core::option::IntoIter<u32>>>>> {
// TODO:
let args = Some(0u32);
// Read
self.transfer(0x03, args.into_iter())
.bytes_transfer().skip(1).take(len)
} }
} }
pub struct Transfer<'a, Args: Iterator<Item = u32>> { pub struct Transfer<'a, Args: Iterator<Item = u32>> {
flash: &'a mut Flash<Manual>, flash: &'a mut Flash<Manual>,
args: Args, args: Args,
sent: usize,
received: usize,
len: usize,
} }
impl<'a, Args: Iterator<Item = u32>> Transfer<'a, Args> { impl<'a, Args: Iterator<Item = u32>> Transfer<'a, Args> {
pub fn new(flash: &'a mut Flash<Manual>, inst_code: u8, mut args: Args) -> Self pub fn new(flash: &'a mut Flash<Manual>, args: Args, len: usize) -> Self
where where
Args: Iterator<Item = u32>, Args: Iterator<Item = u32>,
{ {
@ -360,37 +364,45 @@ impl<'a, Args: Iterator<Item = u32>> Transfer<'a, Args> {
regs::Enable::zeroed() regs::Enable::zeroed()
.spi_en(true) .spi_en(true)
); );
while flash.regs.intr_status.read().rx_fifo_not_empty() {
flash.regs.rx_data.read();
}
unsafe { let mut xfer = Transfer {
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 {
flash, flash,
args, 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<Item = u32>> Drop for Transfer<'a, Args> { impl<'a, Args: Iterator<Item = u32>> Drop for Transfer<'a, Args> {
fn drop(&mut self) { fn drop(&mut self) {
// Discard remaining rx_data // Discard remaining rx_data
while self.flash.regs.intr_status.read().rx_fifo_not_empty() { while self.can_read() {
self.flash.regs.rx_data.read(); self.read();
} }
// Stop // Stop
@ -409,14 +421,13 @@ impl<'a, Args: Iterator<Item = u32>> Iterator for Transfer<'a, Args> {
type Item = u32; type Item = u32;
fn next<'s>(&'s mut self) -> Option<u32> { fn next<'s>(&'s mut self) -> Option<u32> {
while !self.flash.regs.intr_status.read().rx_fifo_not_empty() {} if self.received >= self.len {
let rx = self.flash.regs.rx_data.read(); return None;
let arg = self.args.next().unwrap_or(0);
unsafe {
self.flash.regs.txd0.write(arg);
} }
Some(rx) self.fill_tx_fifo();
while !self.can_read() {}
Some(self.read())
} }
} }