aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkbleeke <[email protected]>2023-03-02 19:02:32 +0100
committerkbleeke <[email protected]>2023-03-27 13:18:59 +0200
commitb58cc2aa239e4adba2c32462cc89133bb7d9f698 (patch)
tree236352d7335f0f81cea03a6e9c4646d643acceae /src
parenta2272dda08a2d1625eef0b79fcd80afc8a1e174a (diff)
use irqs to wait for events
Diffstat (limited to 'src')
-rw-r--r--src/bus.rs14
-rw-r--r--src/consts.rs2
-rw-r--r--src/ioctl.rs3
-rw-r--r--src/runner.rs94
4 files changed, 66 insertions, 47 deletions
diff --git a/src/bus.rs b/src/bus.rs
index 7700a832a..6ec5d0bd6 100644
--- a/src/bus.rs
+++ b/src/bus.rs
@@ -19,6 +19,9 @@ pub trait SpiBusCyw43 {
19 /// Backplane reads have a response delay that produces one extra unspecified word at the beginning of `read`. 19 /// Backplane reads have a response delay that produces one extra unspecified word at the beginning of `read`.
20 /// Callers that want to read `n` word from the backplane, have to provide a slice that is `n+1` words long. 20 /// Callers that want to read `n` word from the backplane, have to provide a slice that is `n+1` words long.
21 async fn cmd_read(&mut self, write: u32, read: &mut [u32]); 21 async fn cmd_read(&mut self, write: u32, read: &mut [u32]);
22
23 async fn wait_for_event(&mut self);
24 fn clear_event(&mut self);
22} 25}
23 26
24pub(crate) struct Bus<PWR, SPI> { 27pub(crate) struct Bus<PWR, SPI> {
@@ -63,7 +66,8 @@ where
63 trace!("{:#010b}", (val & 0xff)); 66 trace!("{:#010b}", (val & 0xff));
64 67
65 // 32-bit word length, little endian (which is the default endianess). 68 // 32-bit word length, little endian (which is the default endianess).
66 self.write32_swapped(REG_BUS_CTRL, WORD_LENGTH_32 | HIGH_SPEED).await; 69 self.write32_swapped(REG_BUS_CTRL, WORD_LENGTH_32 | HIGH_SPEED | INTERRUPT_HIGH | WAKE_UP)
70 .await;
67 71
68 let val = self.read8(FUNC_BUS, REG_BUS_CTRL).await; 72 let val = self.read8(FUNC_BUS, REG_BUS_CTRL).await;
69 trace!("{:#b}", val); 73 trace!("{:#b}", val);
@@ -297,6 +301,14 @@ where
297 301
298 self.spi.cmd_write(&buf).await; 302 self.spi.cmd_write(&buf).await;
299 } 303 }
304
305 pub async fn wait_for_event(&mut self) {
306 self.spi.wait_for_event().await;
307 }
308
309 pub fn clear_event(&mut self) {
310 self.spi.clear_event();
311 }
300} 312}
301 313
302fn swap16(x: u32) -> u32 { 314fn swap16(x: u32) -> u32 {
diff --git a/src/consts.rs b/src/consts.rs
index 140cb4b6d..70d6660e0 100644
--- a/src/consts.rs
+++ b/src/consts.rs
@@ -14,6 +14,8 @@ pub(crate) const REG_BUS_TEST_RW: u32 = 0x18;
14pub(crate) const REG_BUS_RESP_DELAY: u32 = 0x1c; 14pub(crate) const REG_BUS_RESP_DELAY: u32 = 0x1c;
15pub(crate) const WORD_LENGTH_32: u32 = 0x1; 15pub(crate) const WORD_LENGTH_32: u32 = 0x1;
16pub(crate) const HIGH_SPEED: u32 = 0x10; 16pub(crate) const HIGH_SPEED: u32 = 0x10;
17pub(crate) const INTERRUPT_HIGH: u32 = 1 << 5;
18pub(crate) const WAKE_UP: u32 = 1 << 7;
17 19
18// SPI_STATUS_REGISTER bits 20// SPI_STATUS_REGISTER bits
19pub(crate) const STATUS_DATA_NOT_AVAILABLE: u32 = 0x00000001; 21pub(crate) const STATUS_DATA_NOT_AVAILABLE: u32 = 0x00000001;
diff --git a/src/ioctl.rs b/src/ioctl.rs
index 6a7465593..4a2eb252f 100644
--- a/src/ioctl.rs
+++ b/src/ioctl.rs
@@ -75,7 +75,6 @@ impl IoctlState {
75 pub async fn wait_pending(&self) -> PendingIoctl { 75 pub async fn wait_pending(&self) -> PendingIoctl {
76 let pending = poll_fn(|cx| { 76 let pending = poll_fn(|cx| {
77 if let IoctlStateInner::Pending(pending) = self.state.get() { 77 if let IoctlStateInner::Pending(pending) = self.state.get() {
78 warn!("found pending ioctl");
79 Poll::Ready(pending) 78 Poll::Ready(pending)
80 } else { 79 } else {
81 self.register_runner(cx.waker()); 80 self.register_runner(cx.waker());
@@ -89,7 +88,6 @@ impl IoctlState {
89 } 88 }
90 89
91 pub async fn do_ioctl(&self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize { 90 pub async fn do_ioctl(&self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize {
92 warn!("doing ioctl");
93 self.state 91 self.state
94 .set(IoctlStateInner::Pending(PendingIoctl { buf, kind, cmd, iface })); 92 .set(IoctlStateInner::Pending(PendingIoctl { buf, kind, cmd, iface }));
95 self.wake_runner(); 93 self.wake_runner();
@@ -98,7 +96,6 @@ impl IoctlState {
98 96
99 pub fn ioctl_done(&self, response: &[u8]) { 97 pub fn ioctl_done(&self, response: &[u8]) {
100 if let IoctlStateInner::Sent { buf } = self.state.get() { 98 if let IoctlStateInner::Sent { buf } = self.state.get() {
101 warn!("ioctl complete");
102 // TODO fix this 99 // TODO fix this
103 (unsafe { &mut *buf }[..response.len()]).copy_from_slice(response); 100 (unsafe { &mut *buf }[..response.len()]).copy_from_slice(response);
104 101
diff --git a/src/runner.rs b/src/runner.rs
index 4abccf48b..a1de0770e 100644
--- a/src/runner.rs
+++ b/src/runner.rs
@@ -122,7 +122,11 @@ where
122 while self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {} 122 while self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {}
123 123
124 // "Set up the interrupt mask and enable interrupts" 124 // "Set up the interrupt mask and enable interrupts"
125 self.bus.bp_write32(CHIP.sdiod_core_base_address + 0x24, 0xF0).await; 125 // self.bus.bp_write32(CHIP.sdiod_core_base_address + 0x24, 0xF0).await;
126
127 self.bus
128 .write16(FUNC_BUS, REG_BUS_INTERRUPT_ENABLE, IRQ_F2_PACKET_AVAILABLE)
129 .await;
126 130
127 // "Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped." 131 // "Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped."
128 // Sounds scary... 132 // Sounds scary...
@@ -227,22 +231,22 @@ where
227 #[cfg(feature = "firmware-logs")] 231 #[cfg(feature = "firmware-logs")]
228 self.log_read().await; 232 self.log_read().await;
229 233
230 let ev = || async {
231 // TODO use IRQs
232 yield_now().await;
233 };
234
235 if self.has_credit() { 234 if self.has_credit() {
236 let ioctl = self.ioctl_state.wait_pending(); 235 let ioctl = self.ioctl_state.wait_pending();
237 let tx = self.ch.tx_buf(); 236 let tx = self.ch.tx_buf();
238 237 let ev = self.bus.wait_for_event();
239 match select3(ioctl, tx, ev()).await { 238
240 Either3::First(PendingIoctl { buf, kind, cmd, iface }) => { 239 match select3(ioctl, tx, ev).await {
241 warn!("ioctl"); 240 Either3::First(PendingIoctl {
242 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await; 241 buf: iobuf,
242 kind,
243 cmd,
244 iface,
245 }) => {
246 self.send_ioctl(kind, cmd, iface, unsafe { &*iobuf }).await;
247 self.check_status(&mut buf).await;
243 } 248 }
244 Either3::Second(packet) => { 249 Either3::Second(packet) => {
245 warn!("packet");
246 trace!("tx pkt {:02x}", Bytes(&packet[..packet.len().min(48)])); 250 trace!("tx pkt {:02x}", Bytes(&packet[..packet.len().min(48)]));
247 251
248 let mut buf = [0; 512]; 252 let mut buf = [0; 512];
@@ -284,47 +288,51 @@ where
284 288
285 self.bus.wlan_write(&buf[..(total_len / 4)]).await; 289 self.bus.wlan_write(&buf[..(total_len / 4)]).await;
286 self.ch.tx_done(); 290 self.ch.tx_done();
291 self.check_status(&mut buf).await;
287 } 292 }
288 Either3::Third(()) => { 293 Either3::Third(()) => {
289 // Receive stuff 294 self.handle_irq(&mut buf).await;
290 let irq = self.bus.read16(FUNC_BUS, REG_BUS_INTERRUPT).await;
291
292 if irq & IRQ_F2_PACKET_AVAILABLE != 0 {
293 let mut status = 0xFFFF_FFFF;
294 while status == 0xFFFF_FFFF {
295 status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await;
296 }
297
298 if status & STATUS_F2_PKT_AVAILABLE != 0 {
299 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
300 self.bus.wlan_read(&mut buf, len).await;
301 trace!("rx {:02x}", Bytes(&slice8_mut(&mut buf)[..(len as usize).min(48)]));
302 self.rx(&slice8_mut(&mut buf)[..len as usize]);
303 }
304 }
305 } 295 }
306 } 296 }
307 } else { 297 } else {
308 warn!("TX stalled"); 298 warn!("TX stalled");
309 ev().await; 299 self.bus.wait_for_event().await;
300 self.handle_irq(&mut buf).await;
301 }
302 }
303 }
310 304
311 // Receive stuff 305 /// Wait for IRQ on F2 packet available
312 let irq = self.bus.read16(FUNC_BUS, REG_BUS_INTERRUPT).await; 306 async fn handle_irq(&mut self, buf: &mut [u32; 512]) {
307 self.bus.clear_event();
308 // Receive stuff
309 let irq = self.bus.read16(FUNC_BUS, REG_BUS_INTERRUPT).await;
310 trace!("irq{}", FormatInterrupt(irq));
313 311
314 if irq & IRQ_F2_PACKET_AVAILABLE != 0 { 312 if irq & IRQ_F2_PACKET_AVAILABLE != 0 {
315 let mut status = 0xFFFF_FFFF; 313 self.check_status(buf).await;
316 while status == 0xFFFF_FFFF { 314 }
317 status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await; 315 }
318 }
319 316
320 if status & STATUS_F2_PKT_AVAILABLE != 0 { 317 /// Handle F2 events while status register is set
321 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT; 318 async fn check_status(&mut self, buf: &mut [u32; 512]) {
322 self.bus.wlan_read(&mut buf, len).await; 319 loop {
323 trace!("rx {:02x}", Bytes(&slice8_mut(&mut buf)[..(len as usize).min(48)])); 320 let mut status = 0xFFFF_FFFF;
324 self.rx(&slice8_mut(&mut buf)[..len as usize]); 321 while status == 0xFFFF_FFFF {
325 } 322 status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await;
326 }
327 } 323 }
324 trace!("check status{}", FormatStatus(status));
325
326 if status & STATUS_F2_PKT_AVAILABLE != 0 {
327 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
328 self.bus.wlan_read(buf, len).await;
329 trace!("rx {:02x}", Bytes(&slice8_mut(buf)[..(len as usize).min(48)]));
330 self.rx(&slice8_mut(buf)[..len as usize]);
331 } else {
332 break;
333 }
334
335 yield_now().await;
328 } 336 }
329 } 337 }
330 338