diff --git a/examples/rpi-pico-w/src/main.rs b/examples/rpi-pico-w/src/main.rs index 43485137..e3c59223 100644 --- a/examples/rpi-pico-w/src/main.rs +++ b/examples/rpi-pico-w/src/main.rs @@ -215,16 +215,26 @@ impl MySpi { } impl cyw43::SpiBusCyw43 for MySpi { - async fn cmd_write(&mut self, write: &[u32]) { + async fn cmd_write(&mut self, write: &[u32]) -> u32 { self.cs.set_low(); self.write(write).await; + + let mut status = 0; + self.read(slice::from_mut(&mut status)).await; + self.cs.set_high(); + status } - async fn cmd_read(&mut self, write: u32, read: &mut [u32]) { + async fn cmd_read(&mut self, write: u32, read: &mut [u32]) -> u32 { self.cs.set_low(); self.write(slice::from_ref(&write)).await; self.read(read).await; + + let mut status = 0; + self.read(slice::from_mut(&mut status)).await; + self.cs.set_high(); + status } } diff --git a/examples/rpi-pico-w/src/pio.rs b/examples/rpi-pico-w/src/pio.rs index 1cefb173..84611306 100644 --- a/examples/rpi-pico-w/src/pio.rs +++ b/examples/rpi-pico-w/src/pio.rs @@ -108,7 +108,7 @@ where } } - pub async fn write(&mut self, write: &[u32]) { + pub async fn write(&mut self, write: &[u32]) -> u32 { self.sm.set_enable(false); let write_bits = write.len() * 32 - 1; let read_bits = 31; @@ -125,15 +125,14 @@ where self.sm.dma_push(dma.reborrow(), write).await; - let mut status = 0; - self.sm.dma_pull(dma, slice::from_mut(&mut status)).await; - defmt::trace!("{:#08x}", status); + let status = self.sm.wait_pull().await; + status } - pub async fn cmd_read(&mut self, cmd: u32, read: &mut [u32]) { + pub async fn cmd_read(&mut self, cmd: u32, read: &mut [u32]) -> u32 { self.sm.set_enable(false); let write_bits = 31; - let read_bits = read.len() * 32 - 1; + let read_bits = read.len() * 32 + 32 - 1; defmt::trace!("write={} read={}", write_bits, read_bits); @@ -147,6 +146,9 @@ where self.sm.dma_push(dma.reborrow(), slice::from_ref(&cmd)).await; self.sm.dma_pull(dma, read).await; + + let status = self.sm.wait_pull().await; + status } } @@ -156,16 +158,18 @@ where SM: PioStateMachine, DMA: Channel, { - async fn cmd_write(&mut self, write: &[u32]) { + async fn cmd_write(&mut self, write: &[u32]) -> u32 { self.cs.set_low(); - self.write(write).await; + let status = self.write(write).await; self.cs.set_high(); + status } - async fn cmd_read(&mut self, write: u32, read: &mut [u32]) { + async fn cmd_read(&mut self, write: u32, read: &mut [u32]) -> u32 { self.cs.set_low(); - self.cmd_read(write, read).await; + let status = self.cmd_read(write, read).await; self.cs.set_high(); + status } async fn wait_for_event(&mut self) { diff --git a/src/bus.rs b/src/bus.rs index d2a249f9..65caea8e 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -12,14 +12,14 @@ use crate::consts::*; pub trait SpiBusCyw43 { /// Issues a write command on the bus /// First 32 bits of `word` are expected to be a cmd word - async fn cmd_write(&mut self, write: &[u32]); + async fn cmd_write(&mut self, write: &[u32]) -> u32; /// Issues a read command on the bus /// `write` is expected to be a 32 bit cmd word /// `read` will contain the response of the device /// Backplane reads have a response delay that produces one extra unspecified word at the beginning of `read`. /// Callers that want to read `n` word from the backplane, have to provide a slice that is `n+1` words long. - async fn cmd_read(&mut self, write: u32, read: &mut [u32]); + async fn cmd_read(&mut self, write: u32, read: &mut [u32]) -> u32; /// Wait for events from the Device. A typical implementation would wait for the IRQ pin to be high. /// The default implementation always reports ready, resulting in active polling of the device. @@ -32,6 +32,7 @@ pub(crate) struct Bus { backplane_window: u32, pwr: PWR, spi: SPI, + status: u32, } impl Bus @@ -44,6 +45,7 @@ where backplane_window: 0xAAAA_AAAA, pwr, spi, + status: 0, } } @@ -70,8 +72,11 @@ where trace!("{:#010b}", (val & 0xff)); // 32-bit word length, little endian (which is the default endianess). - self.write32_swapped(REG_BUS_CTRL, WORD_LENGTH_32 | HIGH_SPEED | INTERRUPT_HIGH | WAKE_UP) - .await; + self.write32_swapped( + REG_BUS_CTRL, + WORD_LENGTH_32 | HIGH_SPEED | INTERRUPT_HIGH | WAKE_UP | STATUS_ENABLE, + ) + .await; let val = self.read8(FUNC_BUS, REG_BUS_CTRL).await; trace!("{:#b}", val); @@ -88,7 +93,7 @@ where let cmd = cmd_word(READ, INC_ADDR, FUNC_WLAN, 0, len_in_u8); let len_in_u32 = (len_in_u8 as usize + 3) / 4; - self.spi.cmd_read(cmd, &mut buf[..len_in_u32]).await; + self.status = self.spi.cmd_read(cmd, &mut buf[..len_in_u32]).await; } pub async fn wlan_write(&mut self, buf: &[u32]) { @@ -98,7 +103,7 @@ where cmd_buf[0] = cmd; cmd_buf[1..][..buf.len()].copy_from_slice(buf); - self.spi.cmd_write(&cmd_buf).await; + self.status = self.spi.cmd_write(&cmd_buf).await; } #[allow(unused)] @@ -124,7 +129,7 @@ where let cmd = cmd_word(READ, INC_ADDR, FUNC_BACKPLANE, window_offs, len as u32); // round `buf` to word boundary, add one extra word for the response delay - self.spi.cmd_read(cmd, &mut buf[..(len + 3) / 4 + 1]).await; + self.status = self.spi.cmd_read(cmd, &mut buf[..(len + 3) / 4 + 1]).await; // when writing out the data, we skip the response-delay byte data[..len].copy_from_slice(&slice8_mut(&mut buf[1..])[..len]); @@ -157,7 +162,7 @@ where let cmd = cmd_word(WRITE, INC_ADDR, FUNC_BACKPLANE, window_offs, len as u32); buf[0] = cmd; - self.spi.cmd_write(&buf[..(len + 3) / 4 + 1]).await; + self.status = self.spi.cmd_write(&buf[..(len + 3) / 4 + 1]).await; // Advance ptr. addr += len as u32; @@ -273,7 +278,7 @@ where // if we are reading from the backplane, we need an extra word for the response delay let len = if func == FUNC_BACKPLANE { 2 } else { 1 }; - self.spi.cmd_read(cmd, &mut buf[..len]).await; + self.status = self.spi.cmd_read(cmd, &mut buf[..len]).await; // if we read from the backplane, the result is in the second word, after the response delay if func == FUNC_BACKPLANE { @@ -286,7 +291,7 @@ where async fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) { let cmd = cmd_word(WRITE, INC_ADDR, func, addr, len); - self.spi.cmd_write(&[cmd, val]).await; + self.status = self.spi.cmd_write(&[cmd, val]).await; } async fn read32_swapped(&mut self, addr: u32) -> u32 { @@ -294,7 +299,7 @@ where let cmd = swap16(cmd); let mut buf = [0; 1]; - self.spi.cmd_read(cmd, &mut buf).await; + self.status = self.spi.cmd_read(cmd, &mut buf).await; swap16(buf[0]) } @@ -303,12 +308,16 @@ where let cmd = cmd_word(WRITE, INC_ADDR, FUNC_BUS, addr, 4); let buf = [swap16(cmd), swap16(val)]; - self.spi.cmd_write(&buf).await; + self.status = self.spi.cmd_write(&buf).await; } pub async fn wait_for_event(&mut self) { self.spi.wait_for_event().await; } + + pub fn status(&self) -> u32 { + self.status + } } fn swap16(x: u32) -> u32 { diff --git a/src/consts.rs b/src/consts.rs index 70d6660e..6ed7feb9 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -16,6 +16,7 @@ pub(crate) const WORD_LENGTH_32: u32 = 0x1; pub(crate) const HIGH_SPEED: u32 = 0x10; pub(crate) const INTERRUPT_HIGH: u32 = 1 << 5; pub(crate) const WAKE_UP: u32 = 1 << 7; +pub(crate) const STATUS_ENABLE: u32 = 0x10000; // SPI_STATUS_REGISTER bits pub(crate) const STATUS_DATA_NOT_AVAILABLE: u32 = 0x00000001; diff --git a/src/runner.rs b/src/runner.rs index abfac3ae..ccdbbf1a 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -315,10 +315,7 @@ where /// Handle F2 events while status register is set async fn check_status(&mut self, buf: &mut [u32; 512]) { loop { - let mut status = 0xFFFF_FFFF; - while status == 0xFFFF_FFFF { - status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await; - } + let status = self.bus.status(); trace!("check status{}", FormatStatus(status)); if status & STATUS_F2_PKT_AVAILABLE != 0 {