Merge pull request #53 from kbleeke/send-status

use send status feature of cyw43 instead of manually checking status
This commit is contained in:
Dario Nieuwenhuis 2023-03-27 16:54:59 +00:00 committed by GitHub
commit d918919cb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 28 deletions

View file

@ -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
}
}

View file

@ -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) {

View file

@ -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<PWR, SPI> {
backplane_window: u32,
pwr: PWR,
spi: SPI,
status: u32,
}
impl<PWR, SPI> Bus<PWR, SPI>
@ -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 {

View file

@ -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;

View file

@ -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 {