aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-12-27 01:19:26 +0100
committerDario Nieuwenhuis <[email protected]>2022-12-27 01:19:26 +0100
commit2548bbdd65fc3094f624bd043a1a9a296f9184b5 (patch)
treef3b50c80846dfb077cf16e6a223e7602a3c4aa1a /src
parent1b6799d93f0bbd6154c124d51aa47aeed0acf15d (diff)
Update Embassy.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs218
1 files changed, 87 insertions, 131 deletions
diff --git a/src/lib.rs b/src/lib.rs
index fa73b32e0..25e6f8f16 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,14 +15,10 @@ mod structs;
15use core::cell::Cell; 15use core::cell::Cell;
16use core::cmp::{max, min}; 16use core::cmp::{max, min};
17use core::slice; 17use core::slice;
18use core::sync::atomic::Ordering;
19use core::task::Waker;
20 18
21use atomic_polyfill::AtomicBool; 19use ch::driver::LinkState;
22use embassy_futures::yield_now; 20use embassy_futures::yield_now;
23use embassy_net::{PacketBoxExt, PacketBuf}; 21use embassy_net_driver_channel as ch;
24use embassy_sync::blocking_mutex::raw::NoopRawMutex;
25use embassy_sync::channel::Channel;
26use embassy_time::{block_for, Duration, Timer}; 22use embassy_time::{block_for, Duration, Timer};
27use embedded_hal_1::digital::OutputPin; 23use embedded_hal_1::digital::OutputPin;
28use embedded_hal_async::spi::{SpiBusRead, SpiBusWrite, SpiDevice}; 24use embedded_hal_async::spi::{SpiBusRead, SpiBusWrite, SpiDevice};
@@ -32,6 +28,8 @@ use crate::consts::*;
32use crate::events::Event; 28use crate::events::Event;
33use crate::structs::*; 29use crate::structs::*;
34 30
31const MTU: usize = 1514;
32
35#[derive(Clone, Copy)] 33#[derive(Clone, Copy)]
36pub enum IoctlType { 34pub enum IoctlType {
37 Get = 0, 35 Get = 0,
@@ -128,30 +126,25 @@ enum IoctlState {
128 126
129pub struct State { 127pub struct State {
130 ioctl_state: Cell<IoctlState>, 128 ioctl_state: Cell<IoctlState>,
131 129 ch: ch::State<MTU, 4, 4>,
132 tx_channel: Channel<NoopRawMutex, PacketBuf, 8>,
133 rx_channel: Channel<NoopRawMutex, PacketBuf, 8>,
134 link_up: AtomicBool,
135} 130}
136 131
137impl State { 132impl State {
138 pub fn new() -> Self { 133 pub fn new() -> Self {
139 Self { 134 Self {
140 ioctl_state: Cell::new(IoctlState::Idle), 135 ioctl_state: Cell::new(IoctlState::Idle),
141 136 ch: ch::State::new(),
142 tx_channel: Channel::new(),
143 rx_channel: Channel::new(),
144 link_up: AtomicBool::new(true), // TODO set up/down as we join/deassociate
145 } 137 }
146 } 138 }
147} 139}
148 140
149pub struct Control<'a> { 141pub struct Control<'a> {
150 state: &'a State, 142 state_ch: ch::StateRunner<'a>,
143 ioctl_state: &'a Cell<IoctlState>,
151} 144}
152 145
153impl<'a> Control<'a> { 146impl<'a> Control<'a> {
154 pub async fn init(&mut self, clm: &[u8]) -> NetDevice<'a> { 147 pub async fn init(&mut self, clm: &[u8]) {
155 const CHUNK_SIZE: usize = 1024; 148 const CHUNK_SIZE: usize = 1024;
156 149
157 info!("Downloading CLM..."); 150 info!("Downloading CLM...");
@@ -258,12 +251,10 @@ impl<'a> Control<'a> {
258 251
259 Timer::after(Duration::from_millis(100)).await; 252 Timer::after(Duration::from_millis(100)).await;
260 253
261 info!("INIT DONE"); 254 self.state_ch.set_ethernet_address(mac_addr);
255 self.state_ch.set_link_state(LinkState::Up); // TODO do on join/leave
262 256
263 NetDevice { 257 info!("INIT DONE");
264 state: self.state,
265 mac_addr,
266 }
267 } 258 }
268 259
269 pub async fn join_open(&mut self, ssid: &str) { 260 pub async fn join_open(&mut self, ssid: &str) {
@@ -381,75 +372,30 @@ impl<'a> Control<'a> {
381 async fn ioctl(&mut self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize { 372 async fn ioctl(&mut self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize {
382 // TODO cancel ioctl on future drop. 373 // TODO cancel ioctl on future drop.
383 374
384 while !matches!(self.state.ioctl_state.get(), IoctlState::Idle) { 375 while !matches!(self.ioctl_state.get(), IoctlState::Idle) {
385 yield_now().await; 376 yield_now().await;
386 } 377 }
387 378
388 self.state 379 self.ioctl_state.set(IoctlState::Pending { kind, cmd, iface, buf });
389 .ioctl_state
390 .set(IoctlState::Pending { kind, cmd, iface, buf });
391 380
392 let resp_len = loop { 381 let resp_len = loop {
393 if let IoctlState::Done { resp_len } = self.state.ioctl_state.get() { 382 if let IoctlState::Done { resp_len } = self.ioctl_state.get() {
394 break resp_len; 383 break resp_len;
395 } 384 }
396 yield_now().await; 385 yield_now().await;
397 }; 386 };
398 387
399 self.state.ioctl_state.set(IoctlState::Idle); 388 self.ioctl_state.set(IoctlState::Idle);
400 389
401 resp_len 390 resp_len
402 } 391 }
403} 392}
404 393
405pub struct NetDevice<'a> {
406 state: &'a State,
407 mac_addr: [u8; 6],
408}
409
410impl<'a> embassy_net::Device for NetDevice<'a> {
411 fn register_waker(&mut self, waker: &Waker) {
412 // loopy loopy wakey wakey
413 waker.wake_by_ref()
414 }
415
416 fn link_state(&mut self) -> embassy_net::LinkState {
417 match self.state.link_up.load(Ordering::Relaxed) {
418 true => embassy_net::LinkState::Up,
419 false => embassy_net::LinkState::Down,
420 }
421 }
422
423 fn capabilities(&self) -> embassy_net::DeviceCapabilities {
424 let mut caps = embassy_net::DeviceCapabilities::default();
425 caps.max_transmission_unit = 1514; // 1500 IP + 14 ethernet header
426 caps.medium = embassy_net::Medium::Ethernet;
427 caps
428 }
429
430 fn is_transmit_ready(&mut self) -> bool {
431 true
432 }
433
434 fn transmit(&mut self, pkt: PacketBuf) {
435 if self.state.tx_channel.try_send(pkt).is_err() {
436 warn!("TX failed")
437 }
438 }
439
440 fn receive(&mut self) -> Option<PacketBuf> {
441 self.state.rx_channel.try_recv().ok()
442 }
443
444 fn ethernet_address(&self) -> [u8; 6] {
445 self.mac_addr
446 }
447}
448
449pub struct Runner<'a, PWR, SPI> { 394pub struct Runner<'a, PWR, SPI> {
395 ch: ch::Runner<'a, MTU>,
450 bus: Bus<PWR, SPI>, 396 bus: Bus<PWR, SPI>,
451 397
452 state: &'a State, 398 ioctl_state: &'a Cell<IoctlState>,
453 ioctl_id: u16, 399 ioctl_id: u16,
454 sdpcm_seq: u8, 400 sdpcm_seq: u8,
455 sdpcm_seq_max: u8, 401 sdpcm_seq_max: u8,
@@ -466,21 +412,27 @@ struct LogState {
466 buf_count: usize, 412 buf_count: usize,
467} 413}
468 414
415pub type NetDriver<'a> = ch::Device<'a, MTU>;
416
469pub async fn new<'a, PWR, SPI>( 417pub async fn new<'a, PWR, SPI>(
470 state: &'a State, 418 state: &'a mut State,
471 pwr: PWR, 419 pwr: PWR,
472 spi: SPI, 420 spi: SPI,
473 firmware: &[u8], 421 firmware: &[u8],
474) -> (Control<'a>, Runner<'a, PWR, SPI>) 422) -> (NetDriver<'a>, Control<'a>, Runner<'a, PWR, SPI>)
475where 423where
476 PWR: OutputPin, 424 PWR: OutputPin,
477 SPI: SpiDevice, 425 SPI: SpiDevice,
478 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>, 426 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>,
479{ 427{
428 let (ch_runner, device) = ch::new(&mut state.ch, [0; 6]);
429 let state_ch = ch_runner.state_runner();
430
480 let mut runner = Runner { 431 let mut runner = Runner {
432 ch: ch_runner,
481 bus: Bus::new(pwr, spi), 433 bus: Bus::new(pwr, spi),
482 434
483 state, 435 ioctl_state: &state.ioctl_state,
484 ioctl_id: 0, 436 ioctl_id: 0,
485 sdpcm_seq: 0, 437 sdpcm_seq: 0,
486 sdpcm_seq_max: 1, 438 sdpcm_seq_max: 1,
@@ -496,7 +448,14 @@ where
496 448
497 runner.init(firmware).await; 449 runner.init(firmware).await;
498 450
499 (Control { state }, runner) 451 (
452 device,
453 Control {
454 state_ch,
455 ioctl_state: &state.ioctl_state,
456 },
457 runner,
458 )
500} 459}
501 460
502impl<'a, PWR, SPI> Runner<'a, PWR, SPI> 461impl<'a, PWR, SPI> Runner<'a, PWR, SPI>
@@ -662,15 +621,55 @@ where
662 if !self.has_credit() { 621 if !self.has_credit() {
663 warn!("TX stalled"); 622 warn!("TX stalled");
664 } else { 623 } else {
665 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { 624 if let IoctlState::Pending { kind, cmd, iface, buf } = self.ioctl_state.get() {
666 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await; 625 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await;
667 self.state.ioctl_state.set(IoctlState::Sent { buf }); 626 self.ioctl_state.set(IoctlState::Sent { buf });
668 } 627 }
669 if !self.has_credit() { 628 if !self.has_credit() {
670 warn!("TX stalled"); 629 warn!("TX stalled");
671 } else { 630 } else {
672 if let Ok(p) = self.state.tx_channel.try_recv() { 631 if let Some(packet) = self.ch.try_tx_buf() {
673 self.send_packet(&p).await; 632 trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]);
633
634 let mut buf = [0; 512];
635 let buf8 = slice8_mut(&mut buf);
636
637 let total_len = SdpcmHeader::SIZE + BcdHeader::SIZE + packet.len();
638
639 let seq = self.sdpcm_seq;
640 self.sdpcm_seq = self.sdpcm_seq.wrapping_add(1);
641
642 let sdpcm_header = SdpcmHeader {
643 len: total_len as u16, // TODO does this len need to be rounded up to u32?
644 len_inv: !total_len as u16,
645 sequence: seq,
646 channel_and_flags: CHANNEL_TYPE_DATA,
647 next_length: 0,
648 header_length: SdpcmHeader::SIZE as _,
649 wireless_flow_control: 0,
650 bus_data_credit: 0,
651 reserved: [0, 0],
652 };
653
654 let bcd_header = BcdHeader {
655 flags: BDC_VERSION << BDC_VERSION_SHIFT,
656 priority: 0,
657 flags2: 0,
658 data_offset: 0,
659 };
660 trace!("tx {:?}", sdpcm_header);
661 trace!(" {:?}", bcd_header);
662
663 buf8[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes());
664 buf8[SdpcmHeader::SIZE..][..BcdHeader::SIZE].copy_from_slice(&bcd_header.to_bytes());
665 buf8[SdpcmHeader::SIZE + BcdHeader::SIZE..][..packet.len()].copy_from_slice(packet);
666
667 let total_len = (total_len + 3) & !3; // round up to 4byte
668
669 trace!(" {:02x}", &buf8[..total_len.min(48)]);
670
671 self.bus.wlan_write(&buf[..(total_len / 4)]).await;
672 self.ch.tx_done();
674 } 673 }
675 } 674 }
676 } 675 }
@@ -686,7 +685,6 @@ where
686 685
687 if status & STATUS_F2_PKT_AVAILABLE != 0 { 686 if status & STATUS_F2_PKT_AVAILABLE != 0 {
688 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT; 687 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
689
690 self.bus.wlan_read(&mut buf[..(len as usize + 3) / 4]).await; 688 self.bus.wlan_read(&mut buf[..(len as usize + 3) / 4]).await;
691 trace!("rx {:02x}", &slice8_mut(&mut buf)[..(len as usize).min(48)]); 689 trace!("rx {:02x}", &slice8_mut(&mut buf)[..(len as usize).min(48)]);
692 self.rx(&slice8_mut(&mut buf)[..len as usize]); 690 self.rx(&slice8_mut(&mut buf)[..len as usize]);
@@ -698,49 +696,6 @@ where
698 } 696 }
699 } 697 }
700 698
701 async fn send_packet(&mut self, packet: &[u8]) {
702 trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]);
703
704 let mut buf = [0; 512];
705 let buf8 = slice8_mut(&mut buf);
706
707 let total_len = SdpcmHeader::SIZE + BcdHeader::SIZE + packet.len();
708
709 let seq = self.sdpcm_seq;
710 self.sdpcm_seq = self.sdpcm_seq.wrapping_add(1);
711
712 let sdpcm_header = SdpcmHeader {
713 len: total_len as u16, // TODO does this len need to be rounded up to u32?
714 len_inv: !total_len as u16,
715 sequence: seq,
716 channel_and_flags: CHANNEL_TYPE_DATA,
717 next_length: 0,
718 header_length: SdpcmHeader::SIZE as _,
719 wireless_flow_control: 0,
720 bus_data_credit: 0,
721 reserved: [0, 0],
722 };
723
724 let bcd_header = BcdHeader {
725 flags: BDC_VERSION << BDC_VERSION_SHIFT,
726 priority: 0,
727 flags2: 0,
728 data_offset: 0,
729 };
730 trace!("tx {:?}", sdpcm_header);
731 trace!(" {:?}", bcd_header);
732
733 buf8[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes());
734 buf8[SdpcmHeader::SIZE..][..BcdHeader::SIZE].copy_from_slice(&bcd_header.to_bytes());
735 buf8[SdpcmHeader::SIZE + BcdHeader::SIZE..][..packet.len()].copy_from_slice(packet);
736
737 let total_len = (total_len + 3) & !3; // round up to 4byte
738
739 trace!(" {:02x}", &buf8[..total_len.min(48)]);
740
741 self.bus.wlan_write(&buf[..(total_len / 4)]).await;
742 }
743
744 fn rx(&mut self, packet: &[u8]) { 699 fn rx(&mut self, packet: &[u8]) {
745 if packet.len() < SdpcmHeader::SIZE { 700 if packet.len() < SdpcmHeader::SIZE {
746 warn!("packet too short, len={}", packet.len()); 701 warn!("packet too short, len={}", packet.len());
@@ -775,7 +730,7 @@ where
775 let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap()); 730 let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap());
776 trace!(" {:?}", cdc_header); 731 trace!(" {:?}", cdc_header);
777 732
778 if let IoctlState::Sent { buf } = self.state.ioctl_state.get() { 733 if let IoctlState::Sent { buf } = self.ioctl_state.get() {
779 if cdc_header.id == self.ioctl_id { 734 if cdc_header.id == self.ioctl_id {
780 if cdc_header.status != 0 { 735 if cdc_header.status != 0 {
781 // TODO: propagate error instead 736 // TODO: propagate error instead
@@ -786,7 +741,7 @@ where
786 info!("IOCTL Response: {:02x}", &payload[CdcHeader::SIZE..][..resp_len]); 741 info!("IOCTL Response: {:02x}", &payload[CdcHeader::SIZE..][..resp_len]);
787 742
788 (unsafe { &mut *buf }[..resp_len]).copy_from_slice(&payload[CdcHeader::SIZE..][..resp_len]); 743 (unsafe { &mut *buf }[..resp_len]).copy_from_slice(&payload[CdcHeader::SIZE..][..resp_len]);
789 self.state.ioctl_state.set(IoctlState::Done { resp_len }); 744 self.ioctl_state.set(IoctlState::Done { resp_len });
790 } 745 }
791 } 746 }
792 } 747 }
@@ -859,11 +814,12 @@ where
859 let packet = &payload[packet_start..]; 814 let packet = &payload[packet_start..];
860 trace!("rx pkt {:02x}", &packet[..(packet.len() as usize).min(48)]); 815 trace!("rx pkt {:02x}", &packet[..(packet.len() as usize).min(48)]);
861 816
862 let mut p = unwrap!(embassy_net::PacketBox::new(embassy_net::Packet::new())); 817 match self.ch.try_rx_buf() {
863 p[..packet.len()].copy_from_slice(packet); 818 Some(buf) => {
864 819 buf[..packet.len()].copy_from_slice(packet);
865 if let Err(_) = self.state.rx_channel.try_send(p.slice(0..packet.len())) { 820 self.ch.rx_done(packet.len())
866 warn!("failed to push rxd packet to the channel.") 821 }
822 None => warn!("failed to push rxd packet to the channel."),
867 } 823 }
868 } 824 }
869 _ => {} 825 _ => {}