aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-07-18 18:28:12 -0500
committerxoviat <[email protected]>2023-07-18 18:28:12 -0500
commit890d113b855dc11be75a9716401c7703f4ce48e1 (patch)
tree1906fc00f0ffea07f0f9a0b4c47810916c8a7c7e
parentd040871f7a078db94846305463c30a461f821d7f (diff)
wpan: fully implement initial draft concept
-rw-r--r--embassy-stm32-wpan/src/mac/control.rs8
-rw-r--r--embassy-stm32-wpan/src/mac/driver.rs75
-rw-r--r--embassy-stm32-wpan/src/mac/mod.rs2
-rw-r--r--embassy-stm32-wpan/src/mac/runner.rs21
-rw-r--r--embassy-sync/src/channel.rs22
-rw-r--r--examples/stm32wb/src/bin/mac_ffd_net.rs2
6 files changed, 80 insertions, 50 deletions
diff --git a/embassy-stm32-wpan/src/mac/control.rs b/embassy-stm32-wpan/src/mac/control.rs
index 6e45e595f..2f8a7d07f 100644
--- a/embassy-stm32-wpan/src/mac/control.rs
+++ b/embassy-stm32-wpan/src/mac/control.rs
@@ -6,13 +6,13 @@ pub struct Error {
6} 6}
7 7
8pub struct Control<'a> { 8pub struct Control<'a> {
9 runner: &'a Runner, 9 runner: &'a Runner<'a>,
10} 10}
11 11
12impl<'a> Control<'a> { 12impl<'a> Control<'a> {
13 pub(crate) fn new(runner: &'a Runner) -> Self { 13 pub(crate) fn new(runner: &'a Runner<'a>) -> Self {
14 Self { runner: runner } 14 Self { runner: runner }
15 } 15 }
16 16
17 pub async fn init(&mut self) { 17 pub async fn init(&mut self) {
18 // TODO 18 // TODO
diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs
index 118f6908f..8ebfb2b72 100644
--- a/embassy-stm32-wpan/src/mac/driver.rs
+++ b/embassy-stm32-wpan/src/mac/driver.rs
@@ -4,16 +4,20 @@
4use core::task::Context; 4use core::task::Context;
5 5
6use embassy_net_driver::{Capabilities, LinkState, Medium}; 6use embassy_net_driver::{Capabilities, LinkState, Medium};
7use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
8use embassy_sync::channel::Channel;
7 9
10use super::event::MacEvent;
11use crate::mac::event::Event;
8use crate::mac::runner::Runner; 12use crate::mac::runner::Runner;
9use crate::mac::MTU; 13use crate::mac::MTU;
10 14
11pub struct Driver<'d> { 15pub struct Driver<'d> {
12 runner: &'d Runner, 16 runner: &'d Runner<'d>,
13} 17}
14 18
15impl<'d> Driver<'d> { 19impl<'d> Driver<'d> {
16 pub(crate) fn new(runner: &'d Runner) -> Self { 20 pub(crate) fn new(runner: &'d Runner<'d>) -> Self {
17 Self { runner: runner } 21 Self { runner: runner }
18 } 22 }
19} 23}
@@ -21,33 +25,32 @@ impl<'d> Driver<'d> {
21impl<'d> embassy_net_driver::Driver for Driver<'d> { 25impl<'d> embassy_net_driver::Driver for Driver<'d> {
22 // type RxToken<'a> = RxToken<'a, 'd> where Self: 'a; 26 // type RxToken<'a> = RxToken<'a, 'd> where Self: 'a;
23 // type TxToken<'a> = TxToken<'a, 'd> where Self: 'a; 27 // type TxToken<'a> = TxToken<'a, 'd> where Self: 'a;
24 type RxToken<'a> = RxToken where Self: 'a; 28 type RxToken<'a> = RxToken<'d> where Self: 'a;
25 type TxToken<'a> = TxToken where Self: 'a; 29 type TxToken<'a> = TxToken<'d> where Self: 'a;
26 30
27 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 31 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
28 self.runner.rx_waker.register(cx.waker()); 32 if self.runner.rx_channel.poll_ready_to_receive(cx) && self.runner.tx_channel.poll_ready_to_receive(cx) {
29 33 Some((
30 // WAKER.register(cx.waker()); 34 RxToken {
31 // if self.rx.available().is_some() && self.tx.available().is_some() { 35 rx: &self.runner.rx_channel,
32 // Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx })) 36 },
33 // } else { 37 TxToken {
34 // None 38 tx: &self.runner.tx_channel,
35 // } 39 },
36 40 ))
37 None 41 } else {
42 None
43 }
38 } 44 }
39 45
40 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> { 46 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
41 self.runner.tx_waker.register(cx.waker()); 47 if self.runner.tx_channel.poll_ready_to_receive(cx) {
42 48 Some(TxToken {
43 // WAKER.register(cx.waker()); 49 tx: &self.runner.tx_channel,
44 // / if self.tx.available().is_some() { 50 })
45 // / Some(TxToken { tx: &mut self.tx }) 51 } else {
46 // / } else { 52 None
47 // / None 53 }
48 // / }
49
50 None
51 } 54 }
52 55
53 fn capabilities(&self) -> Capabilities { 56 fn capabilities(&self) -> Capabilities {
@@ -76,30 +79,38 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
76 } 79 }
77} 80}
78 81
79pub struct RxToken { 82pub struct RxToken<'d> {
80 // rx: &'a mut RDesRing<'d>, 83 rx: &'d Channel<CriticalSectionRawMutex, Event, 1>,
81} 84}
82 85
83impl embassy_net_driver::RxToken for RxToken { 86impl<'d> embassy_net_driver::RxToken for RxToken<'d> {
84 fn consume<R, F>(self, f: F) -> R 87 fn consume<R, F>(self, f: F) -> R
85 where 88 where
86 F: FnOnce(&mut [u8]) -> R, 89 F: FnOnce(&mut [u8]) -> R,
87 { 90 {
88 // NOTE(unwrap): we checked the queue wasn't full when creating the token. 91 // Only valid data events should be put into the queue
89 // let pkt = unwrap!(self.rx.available()); 92
93 let event = self.rx.try_recv().unwrap();
94 let mac_event = event.mac_event().unwrap();
95 let data_event = match mac_event {
96 MacEvent::McpsDataInd(data_event) => data_event,
97 _ => unreachable!(),
98 };
90 99
91 let pkt = &mut []; 100 let pkt = &mut [];
92 let r = f(&mut pkt[0..]); 101 let r = f(&mut pkt[0..]);
93 // self.rx.pop_packet(); 102
103 // let r = f(&mut data_event.payload());
94 r 104 r
95 } 105 }
96} 106}
97 107
98pub struct TxToken { 108pub struct TxToken<'d> {
109 tx: &'d Channel<CriticalSectionRawMutex, &'d [u8], 1>,
99 // tx: &'a mut TDesRing<'d>, 110 // tx: &'a mut TDesRing<'d>,
100} 111}
101 112
102impl embassy_net_driver::TxToken for TxToken { 113impl<'d> embassy_net_driver::TxToken for TxToken<'d> {
103 fn consume<R, F>(self, len: usize, f: F) -> R 114 fn consume<R, F>(self, len: usize, f: F) -> R
104 where 115 where
105 F: FnOnce(&mut [u8]) -> R, 116 F: FnOnce(&mut [u8]) -> R,
diff --git a/embassy-stm32-wpan/src/mac/mod.rs b/embassy-stm32-wpan/src/mac/mod.rs
index 2f9d1c81e..3dcda17ae 100644
--- a/embassy-stm32-wpan/src/mac/mod.rs
+++ b/embassy-stm32-wpan/src/mac/mod.rs
@@ -18,7 +18,7 @@ pub use crate::mac::runner::Runner;
18 18
19const MTU: usize = 127; 19const MTU: usize = 127;
20 20
21pub async fn new<'a>(runner: &'a Runner) -> (Control<'a>, Driver<'a>) { 21pub async fn new<'a>(runner: &'a Runner<'a>) -> (Control<'a>, Driver<'a>) {
22 (Control::new(runner), Driver::new(runner)) 22 (Control::new(runner), Driver::new(runner))
23} 23}
24 24
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs
index d545d6c96..911ff60b9 100644
--- a/embassy-stm32-wpan/src/mac/runner.rs
+++ b/embassy-stm32-wpan/src/mac/runner.rs
@@ -1,4 +1,6 @@
1use embassy_futures::select::{select3, Either3}; 1use embassy_futures::select::{select3, Either3};
2use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
3use embassy_sync::channel::Channel;
2use embassy_sync::waitqueue::AtomicWaker; 4use embassy_sync::waitqueue::AtomicWaker;
3 5
4use crate::mac::event::{Event, MacEvent}; 6use crate::mac::event::{Event, MacEvent};
@@ -44,22 +46,18 @@ impl TxRing {
44 } 46 }
45} 47}
46 48
47pub struct Runner { 49pub struct Runner<'a> {
48 mac_subsystem: Mac, 50 mac_subsystem: Mac,
49 pub(crate) rx_ring: Option<Event>, 51 pub(crate) rx_channel: Channel<CriticalSectionRawMutex, Event, 1>,
50 pub(crate) tx_ring: TxRing, 52 pub(crate) tx_channel: Channel<CriticalSectionRawMutex, &'a [u8], 1>,
51 pub(crate) rx_waker: AtomicWaker,
52 pub(crate) tx_waker: AtomicWaker,
53} 53}
54 54
55impl Runner { 55impl<'a> Runner<'a> {
56 pub fn new(mac: Mac) -> Self { 56 pub fn new(mac: Mac) -> Self {
57 Self { 57 Self {
58 mac_subsystem: mac, 58 mac_subsystem: mac,
59 rx_ring: None, 59 rx_channel: Channel::new(),
60 tx_ring: TxRing::new(), 60 tx_channel: Channel::new(),
61 rx_waker: AtomicWaker::new(),
62 tx_waker: AtomicWaker::new(),
63 } 61 }
64 } 62 }
65 63
@@ -73,8 +71,7 @@ impl Runner {
73 if let Ok(evt) = event.mac_event() { 71 if let Ok(evt) = event.mac_event() {
74 match evt { 72 match evt {
75 MacEvent::McpsDataInd(data_ind) => { 73 MacEvent::McpsDataInd(data_ind) => {
76 // TODO: store mac_event in rx_ring 74 self.rx_channel.try_send(event);
77 self.rx_waker.wake();
78 } 75 }
79 _ => {} 76 _ => {}
80 } 77 }
diff --git a/embassy-sync/src/channel.rs b/embassy-sync/src/channel.rs
index 77352874d..f421af392 100644
--- a/embassy-sync/src/channel.rs
+++ b/embassy-sync/src/channel.rs
@@ -335,6 +335,12 @@ impl<T, const N: usize> ChannelState<T, N> {
335 } 335 }
336 } 336 }
337 337
338 fn poll_ready_to_receive(&mut self, cx: &mut Context<'_>) -> bool {
339 self.receiver_waker.register(cx.waker());
340
341 !self.queue.is_empty()
342 }
343
338 fn try_send(&mut self, message: T) -> Result<(), TrySendError<T>> { 344 fn try_send(&mut self, message: T) -> Result<(), TrySendError<T>> {
339 self.try_send_with_context(message, None) 345 self.try_send_with_context(message, None)
340 } 346 }
@@ -353,6 +359,12 @@ impl<T, const N: usize> ChannelState<T, N> {
353 } 359 }
354 } 360 }
355 } 361 }
362
363 fn poll_ready_to_send(&mut self, cx: &mut Context<'_>) -> bool {
364 self.senders_waker.register(cx.waker());
365
366 !self.queue.is_full()
367 }
356} 368}
357 369
358/// A bounded channel for communicating between asynchronous tasks 370/// A bounded channel for communicating between asynchronous tasks
@@ -401,6 +413,16 @@ where
401 self.lock(|c| c.try_send_with_context(m, cx)) 413 self.lock(|c| c.try_send_with_context(m, cx))
402 } 414 }
403 415
416 /// Allows a poll_fn to poll until the channel is ready to receive
417 pub fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> bool {
418 self.lock(|c| c.poll_ready_to_receive(cx))
419 }
420
421 /// Allows a poll_fn to poll until the channel is ready to send
422 pub fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> bool {
423 self.lock(|c| c.poll_ready_to_send(cx))
424 }
425
404 /// Get a sender for this channel. 426 /// Get a sender for this channel.
405 pub fn sender(&self) -> Sender<'_, M, T, N> { 427 pub fn sender(&self) -> Sender<'_, M, T, N> {
406 Sender { channel: self } 428 Sender { channel: self }
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs
index b1cf051bf..6072f418c 100644
--- a/examples/stm32wb/src/bin/mac_ffd_net.rs
+++ b/examples/stm32wb/src/bin/mac_ffd_net.rs
@@ -25,7 +25,7 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) {
25} 25}
26 26
27#[embassy_executor::task] 27#[embassy_executor::task]
28async fn run_mac(runner: &'static Runner) { 28async fn run_mac(runner: &'static Runner<'static>) {
29 runner.run().await; 29 runner.run().await;
30} 30}
31 31