diff options
| -rw-r--r-- | embassy-stm32-wpan/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/driver.rs | 22 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/runner.rs | 111 | ||||
| -rw-r--r-- | examples/stm32wb/Cargo.toml | 6 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/mac_ffd_net.rs | 10 |
5 files changed, 84 insertions, 69 deletions
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 082d00f1c..ab58714d6 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml | |||
| @@ -18,6 +18,7 @@ embassy-futures = { version = "0.1.0", path = "../embassy-futures" } | |||
| 18 | embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common" } | 18 | embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common" } |
| 19 | embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } | 19 | embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } |
| 20 | embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel", optional=true } | 20 | embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel", optional=true } |
| 21 | embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true } | ||
| 21 | 22 | ||
| 22 | defmt = { version = "0.3", optional = true } | 23 | defmt = { version = "0.3", optional = true } |
| 23 | cortex-m = "0.7.6" | 24 | cortex-m = "0.7.6" |
| @@ -27,13 +28,14 @@ aligned = "0.4.1" | |||
| 27 | bit_field = "0.10.2" | 28 | bit_field = "0.10.2" |
| 28 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } | 29 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } |
| 29 | stm32wb-hci = { version = "0.1.3", optional = true } | 30 | stm32wb-hci = { version = "0.1.3", optional = true } |
| 31 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 30 | bitflags = { version = "2.3.3", optional = true } | 32 | bitflags = { version = "2.3.3", optional = true } |
| 31 | 33 | ||
| 32 | [features] | 34 | [features] |
| 33 | defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "stm32wb-hci?/defmt"] | 35 | defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "stm32wb-hci?/defmt"] |
| 34 | 36 | ||
| 35 | ble = ["dep:stm32wb-hci"] | 37 | ble = ["dep:stm32wb-hci"] |
| 36 | mac = ["dep:bitflags", "dep:embassy-net-driver-channel"] | 38 | mac = ["dep:bitflags", "dep:embassy-net-driver-channel", "dep:embassy-net-driver"] |
| 37 | 39 | ||
| 38 | stm32wb10cc = [ "embassy-stm32/stm32wb10cc" ] | 40 | stm32wb10cc = [ "embassy-stm32/stm32wb10cc" ] |
| 39 | stm32wb15cc = [ "embassy-stm32/stm32wb15cc" ] | 41 | stm32wb15cc = [ "embassy-stm32/stm32wb15cc" ] |
diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs index 8ebfb2b72..a41b75094 100644 --- a/embassy-stm32-wpan/src/mac/driver.rs +++ b/embassy-stm32-wpan/src/mac/driver.rs | |||
| @@ -29,13 +29,14 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> { | |||
| 29 | type TxToken<'a> = TxToken<'d> where Self: 'a; | 29 | type TxToken<'a> = TxToken<'d> where Self: 'a; |
| 30 | 30 | ||
| 31 | 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<'_>)> { |
| 32 | if self.runner.rx_channel.poll_ready_to_receive(cx) && self.runner.tx_channel.poll_ready_to_receive(cx) { | 32 | if self.runner.rx_channel.poll_ready_to_receive(cx) && self.runner.tx_buf_channel.poll_ready_to_receive(cx) { |
| 33 | Some(( | 33 | Some(( |
| 34 | RxToken { | 34 | RxToken { |
| 35 | rx: &self.runner.rx_channel, | 35 | rx: &self.runner.rx_channel, |
| 36 | }, | 36 | }, |
| 37 | TxToken { | 37 | TxToken { |
| 38 | tx: &self.runner.tx_channel, | 38 | tx: &self.runner.tx_channel, |
| 39 | tx_buf: &self.runner.tx_buf_channel, | ||
| 39 | }, | 40 | }, |
| 40 | )) | 41 | )) |
| 41 | } else { | 42 | } else { |
| @@ -44,9 +45,10 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> { | |||
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> { | 47 | fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> { |
| 47 | if self.runner.tx_channel.poll_ready_to_receive(cx) { | 48 | if self.runner.tx_buf_channel.poll_ready_to_receive(cx) { |
| 48 | Some(TxToken { | 49 | Some(TxToken { |
| 49 | tx: &self.runner.tx_channel, | 50 | tx: &self.runner.tx_channel, |
| 51 | tx_buf: &self.runner.tx_buf_channel, | ||
| 50 | }) | 52 | }) |
| 51 | } else { | 53 | } else { |
| 52 | None | 54 | None |
| @@ -106,8 +108,8 @@ impl<'d> embassy_net_driver::RxToken for RxToken<'d> { | |||
| 106 | } | 108 | } |
| 107 | 109 | ||
| 108 | pub struct TxToken<'d> { | 110 | pub struct TxToken<'d> { |
| 109 | tx: &'d Channel<CriticalSectionRawMutex, &'d [u8], 1>, | 111 | tx: &'d Channel<CriticalSectionRawMutex, &'d mut [u8], 5>, |
| 110 | // tx: &'a mut TDesRing<'d>, | 112 | tx_buf: &'d Channel<CriticalSectionRawMutex, &'d mut [u8], 5>, |
| 111 | } | 113 | } |
| 112 | 114 | ||
| 113 | impl<'d> embassy_net_driver::TxToken for TxToken<'d> { | 115 | impl<'d> embassy_net_driver::TxToken for TxToken<'d> { |
| @@ -115,11 +117,13 @@ impl<'d> embassy_net_driver::TxToken for TxToken<'d> { | |||
| 115 | where | 117 | where |
| 116 | F: FnOnce(&mut [u8]) -> R, | 118 | F: FnOnce(&mut [u8]) -> R, |
| 117 | { | 119 | { |
| 118 | // NOTE(unwrap): we checked the queue wasn't full when creating the token. | 120 | // Only valid tx buffers should be put into the queue |
| 119 | // let pkt = unwrap!(self.tx.available()); | 121 | let buf = self.tx_buf.try_recv().unwrap(); |
| 120 | let pkt = &mut []; | 122 | let r = f(&mut buf[..len]); |
| 121 | let r = f(&mut pkt[..len]); | 123 | |
| 122 | // self.tx.transmit(len); | 124 | // The tx channel should always be of equal capacity to the tx_buf channel |
| 125 | self.tx.try_send(buf).unwrap(); | ||
| 126 | |||
| 123 | r | 127 | r |
| 124 | } | 128 | } |
| 125 | } | 129 | } |
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs index 911ff60b9..9edcff9b1 100644 --- a/embassy-stm32-wpan/src/mac/runner.rs +++ b/embassy-stm32-wpan/src/mac/runner.rs | |||
| @@ -1,83 +1,80 @@ | |||
| 1 | use embassy_futures::select::{select3, Either3}; | 1 | use embassy_futures::join; |
| 2 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 2 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 3 | use embassy_sync::channel::Channel; | 3 | use embassy_sync::channel::Channel; |
| 4 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 5 | 4 | ||
| 5 | use crate::mac::commands::DataRequest; | ||
| 6 | use crate::mac::event::{Event, MacEvent}; | 6 | use crate::mac::event::{Event, MacEvent}; |
| 7 | use crate::mac::typedefs::{AddressMode, MacAddress, PanId, SecurityLevel}; | ||
| 7 | use crate::mac::MTU; | 8 | use crate::mac::MTU; |
| 8 | use crate::sub::mac::Mac; | 9 | use crate::sub::mac::Mac; |
| 9 | 10 | ||
| 10 | pub(crate) struct TxRing { | ||
| 11 | // stores n packets of up to mtu size | ||
| 12 | ring: [[u8; MTU]; 5], | ||
| 13 | pending: bool, | ||
| 14 | // start: u8, | ||
| 15 | // end: u8, | ||
| 16 | } | ||
| 17 | |||
| 18 | impl TxRing { | ||
| 19 | pub(crate) fn new() -> Self { | ||
| 20 | Self { | ||
| 21 | ring: [[0; MTU]; 5], | ||
| 22 | pending: false, | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 26 | // wait for a free packet to become available | ||
| 27 | pub fn is_packet_free(&self) -> bool { | ||
| 28 | !self.pending | ||
| 29 | } | ||
| 30 | |||
| 31 | // get the next available free packet | ||
| 32 | pub fn get_free_packet<'a>(&'a mut self) -> &'a mut [u8] { | ||
| 33 | self.pending = true; | ||
| 34 | |||
| 35 | &mut self.ring[0] | ||
| 36 | } | ||
| 37 | |||
| 38 | pub fn get_packet_to_transmit<'a>(&'a mut self) -> Option<&'a [u8]> { | ||
| 39 | if self.pending { | ||
| 40 | self.pending = false; | ||
| 41 | |||
| 42 | Some(&self.ring[0]) | ||
| 43 | } else { | ||
| 44 | None | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | pub struct Runner<'a> { | 11 | pub struct Runner<'a> { |
| 50 | mac_subsystem: Mac, | 12 | mac_subsystem: Mac, |
| 51 | pub(crate) rx_channel: Channel<CriticalSectionRawMutex, Event, 1>, | 13 | pub(crate) rx_channel: Channel<CriticalSectionRawMutex, Event, 1>, |
| 52 | pub(crate) tx_channel: Channel<CriticalSectionRawMutex, &'a [u8], 1>, | 14 | pub(crate) tx_channel: Channel<CriticalSectionRawMutex, &'a mut [u8], 5>, |
| 15 | pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8], 5>, | ||
| 53 | } | 16 | } |
| 54 | 17 | ||
| 55 | impl<'a> Runner<'a> { | 18 | impl<'a> Runner<'a> { |
| 56 | pub fn new(mac: Mac) -> Self { | 19 | pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self { |
| 57 | Self { | 20 | let this = Self { |
| 58 | mac_subsystem: mac, | 21 | mac_subsystem: mac, |
| 59 | rx_channel: Channel::new(), | 22 | rx_channel: Channel::new(), |
| 60 | tx_channel: Channel::new(), | 23 | tx_channel: Channel::new(), |
| 24 | tx_buf_channel: Channel::new(), | ||
| 25 | }; | ||
| 26 | |||
| 27 | for buf in tx_buf_queue { | ||
| 28 | this.tx_buf_channel.try_send(buf).unwrap(); | ||
| 61 | } | 29 | } |
| 62 | } | ||
| 63 | 30 | ||
| 64 | pub(crate) async fn init(&mut self, firmware: &[u8]) { | 31 | this |
| 65 | debug!("wifi init done"); | ||
| 66 | } | 32 | } |
| 67 | 33 | ||
| 68 | pub async fn run(&self) -> ! { | 34 | pub async fn run(&self) -> ! { |
| 69 | loop { | 35 | join::join( |
| 70 | let event = self.mac_subsystem.read().await; | 36 | async { |
| 71 | if let Ok(evt) = event.mac_event() { | 37 | loop { |
| 72 | match evt { | 38 | let event = self.mac_subsystem.read().await; |
| 73 | MacEvent::McpsDataInd(data_ind) => { | 39 | if let Ok(evt) = event.mac_event() { |
| 74 | self.rx_channel.try_send(event); | 40 | match evt { |
| 41 | MacEvent::McpsDataInd(_) => { | ||
| 42 | self.rx_channel.send(event).await; | ||
| 43 | } | ||
| 44 | _ => {} | ||
| 45 | } | ||
| 75 | } | 46 | } |
| 76 | _ => {} | ||
| 77 | } | 47 | } |
| 78 | } | 48 | }, |
| 49 | async { | ||
| 50 | loop { | ||
| 51 | let buf = self.tx_channel.recv().await; | ||
| 79 | 52 | ||
| 80 | // TODO: select tx event | 53 | self.mac_subsystem |
| 81 | } | 54 | .send_command( |
| 55 | DataRequest { | ||
| 56 | src_addr_mode: AddressMode::Short, | ||
| 57 | dst_addr_mode: AddressMode::Short, | ||
| 58 | dst_pan_id: PanId([0x1A, 0xAA]), | ||
| 59 | dst_address: MacAddress::BROADCAST, | ||
| 60 | msdu_handle: 0x02, | ||
| 61 | ack_tx: 0x00, | ||
| 62 | gts_tx: false, | ||
| 63 | security_level: SecurityLevel::Unsecure, | ||
| 64 | ..Default::default() | ||
| 65 | } | ||
| 66 | .set_buffer(&buf), | ||
| 67 | ) | ||
| 68 | .await | ||
| 69 | .unwrap(); | ||
| 70 | |||
| 71 | // The tx channel should always be of equal capacity to the tx_buf channel | ||
| 72 | self.tx_buf_channel.try_send(buf).unwrap(); | ||
| 73 | } | ||
| 74 | }, | ||
| 75 | ) | ||
| 76 | .await; | ||
| 77 | |||
| 78 | loop {} | ||
| 82 | } | 79 | } |
| 83 | } | 80 | } |
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 8585b99f9..7c0b83e65 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml | |||
| @@ -21,7 +21,7 @@ embedded-hal = "0.2.6" | |||
| 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 22 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 22 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 23 | heapless = { version = "0.7.5", default-features = false } | 23 | heapless = { version = "0.7.5", default-features = false } |
| 24 | 24 | static_cell = { version = "1.1", features = ["nightly"]} | |
| 25 | 25 | ||
| 26 | [features] | 26 | [features] |
| 27 | default = ["ble", "mac"] | 27 | default = ["ble", "mac"] |
| @@ -41,6 +41,10 @@ name = "mac_ffd" | |||
| 41 | required-features = ["mac"] | 41 | required-features = ["mac"] |
| 42 | 42 | ||
| 43 | [[bin]] | 43 | [[bin]] |
| 44 | name = "mac_ffd_net" | ||
| 45 | required-features = ["mac"] | ||
| 46 | |||
| 47 | [[bin]] | ||
| 44 | name = "eddystone_beacon" | 48 | name = "eddystone_beacon" |
| 45 | required-features = ["ble"] | 49 | required-features = ["ble"] |
| 46 | 50 | ||
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs index 6072f418c..7b8c4b9dc 100644 --- a/examples/stm32wb/src/bin/mac_ffd_net.rs +++ b/examples/stm32wb/src/bin/mac_ffd_net.rs | |||
| @@ -172,7 +172,15 @@ async fn main(spawner: Spawner) { | |||
| 172 | defmt::info!("{:#x}", evt.mac_event()); | 172 | defmt::info!("{:#x}", evt.mac_event()); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | let runner = make_static!(Runner::new(mbox.mac_subsystem)); | 175 | let tx_queue = [ |
| 176 | make_static!([0u8; 127]), | ||
| 177 | make_static!([0u8; 127]), | ||
| 178 | make_static!([0u8; 127]), | ||
| 179 | make_static!([0u8; 127]), | ||
| 180 | make_static!([0u8; 127]), | ||
| 181 | ]; | ||
| 182 | |||
| 183 | let runner = make_static!(Runner::new(mbox.mac_subsystem, tx_queue)); | ||
| 176 | 184 | ||
| 177 | spawner.spawn(run_mac(runner)).unwrap(); | 185 | spawner.spawn(run_mac(runner)).unwrap(); |
| 178 | 186 | ||
