diff options
| -rw-r--r-- | embassy-nrf/src/embassy_net_802154_driver.rs | 8 | ||||
| -rw-r--r-- | embassy-nrf/src/radio/ieee802154.rs | 58 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/sixlowpan.rs | 2 |
3 files changed, 37 insertions, 31 deletions
diff --git a/embassy-nrf/src/embassy_net_802154_driver.rs b/embassy-nrf/src/embassy_net_802154_driver.rs index 8662be787..b3fc5df2c 100644 --- a/embassy-nrf/src/embassy_net_802154_driver.rs +++ b/embassy-nrf/src/embassy_net_802154_driver.rs | |||
| @@ -32,12 +32,12 @@ impl<const N_RX: usize, const N_TX: usize> State<N_RX, N_TX> { | |||
| 32 | /// Background runner for the driver. | 32 | /// Background runner for the driver. |
| 33 | /// | 33 | /// |
| 34 | /// You must call `.run()` in a background task for the driver to operate. | 34 | /// You must call `.run()` in a background task for the driver to operate. |
| 35 | pub struct Runner<'d, T: nrf::radio::Instance> { | 35 | pub struct Runner<'d> { |
| 36 | radio: nrf::radio::ieee802154::Radio<'d, T>, | 36 | radio: nrf::radio::ieee802154::Radio<'d>, |
| 37 | ch: ch::Runner<'d, MTU>, | 37 | ch: ch::Runner<'d, MTU>, |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | impl<'d, T: nrf::radio::Instance> Runner<'d, T> { | 40 | impl<'d> Runner<'d> { |
| 41 | /// Drives the radio. Needs to run to use the driver. | 41 | /// Drives the radio. Needs to run to use the driver. |
| 42 | pub async fn run(mut self) -> ! { | 42 | pub async fn run(mut self) -> ! { |
| 43 | let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); | 43 | let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); |
| @@ -84,7 +84,7 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, T: nrf::radio::Instan | |||
| 84 | radio: nrf::Peri<'a, T>, | 84 | radio: nrf::Peri<'a, T>, |
| 85 | irq: Irq, | 85 | irq: Irq, |
| 86 | state: &'a mut State<N_RX, N_TX>, | 86 | state: &'a mut State<N_RX, N_TX>, |
| 87 | ) -> Result<(Device<'a>, Runner<'a, T>), ()> | 87 | ) -> Result<(Device<'a>, Runner<'a>), ()> |
| 88 | where | 88 | where |
| 89 | Irq: interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a, | 89 | Irq: interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a, |
| 90 | { | 90 | { |
diff --git a/embassy-nrf/src/radio/ieee802154.rs b/embassy-nrf/src/radio/ieee802154.rs index 7f4f8f462..62af03a5a 100644 --- a/embassy-nrf/src/radio/ieee802154.rs +++ b/embassy-nrf/src/radio/ieee802154.rs | |||
| @@ -1,15 +1,17 @@ | |||
| 1 | //! IEEE 802.15.4 radio driver | 1 | //! IEEE 802.15.4 radio driver |
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | ||
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 4 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 5 | use core::task::Poll; |
| 5 | 6 | ||
| 6 | use embassy_hal_internal::drop::OnDrop; | 7 | use embassy_hal_internal::drop::OnDrop; |
| 7 | 8 | ||
| 8 | use super::{Error, Instance, InterruptHandler, TxPower}; | 9 | use super::{Error, InterruptHandler, TxPower}; |
| 9 | use crate::interrupt::typelevel::Interrupt; | 10 | use crate::interrupt::typelevel::Interrupt; |
| 10 | use crate::interrupt::{self}; | 11 | use crate::interrupt::{self}; |
| 11 | use crate::pac::radio::vals; | 12 | use crate::pac::radio::vals; |
| 12 | pub use crate::pac::radio::vals::State as RadioState; | 13 | pub use crate::pac::radio::vals::State as RadioState; |
| 14 | use crate::radio::Instance; | ||
| 13 | use crate::Peri; | 15 | use crate::Peri; |
| 14 | 16 | ||
| 15 | /// Default (IEEE compliant) Start of Frame Delimiter | 17 | /// Default (IEEE compliant) Start of Frame Delimiter |
| @@ -32,18 +34,20 @@ pub enum Cca { | |||
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | /// IEEE 802.15.4 radio driver. | 36 | /// IEEE 802.15.4 radio driver. |
| 35 | pub struct Radio<'d, T: Instance> { | 37 | pub struct Radio<'d> { |
| 36 | _p: Peri<'d, T>, | 38 | r: crate::pac::radio::Radio, |
| 39 | state: &'static crate::radio::State, | ||
| 37 | needs_enable: bool, | 40 | needs_enable: bool, |
| 41 | phantom: PhantomData<&'d ()>, | ||
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | impl<'d, T: Instance> Radio<'d, T> { | 44 | impl<'d> Radio<'d> { |
| 41 | /// Create a new IEEE 802.15.4 radio driver. | 45 | /// Create a new IEEE 802.15.4 radio driver. |
| 42 | pub fn new( | 46 | pub fn new<T: Instance>( |
| 43 | radio: Peri<'d, T>, | 47 | _radio: Peri<'d, T>, |
| 44 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 48 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 45 | ) -> Self { | 49 | ) -> Self { |
| 46 | let r = T::regs(); | 50 | let r = crate::pac::RADIO; |
| 47 | 51 | ||
| 48 | // Disable and enable to reset peripheral | 52 | // Disable and enable to reset peripheral |
| 49 | r.power().write(|w| w.set_power(false)); | 53 | r.power().write(|w| w.set_power(false)); |
| @@ -89,12 +93,14 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 89 | }); | 93 | }); |
| 90 | 94 | ||
| 91 | // Enable NVIC interrupt | 95 | // Enable NVIC interrupt |
| 92 | T::Interrupt::unpend(); | 96 | crate::interrupt::typelevel::RADIO::unpend(); |
| 93 | unsafe { T::Interrupt::enable() }; | 97 | unsafe { crate::interrupt::typelevel::RADIO::enable() }; |
| 94 | 98 | ||
| 95 | let mut radio = Self { | 99 | let mut radio = Self { |
| 96 | _p: radio, | 100 | r: crate::pac::RADIO, |
| 101 | state: T::state(), | ||
| 97 | needs_enable: false, | 102 | needs_enable: false, |
| 103 | phantom: PhantomData, | ||
| 98 | }; | 104 | }; |
| 99 | 105 | ||
| 100 | radio.set_sfd(DEFAULT_SFD); | 106 | radio.set_sfd(DEFAULT_SFD); |
| @@ -107,7 +113,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 107 | 113 | ||
| 108 | /// Changes the radio channel | 114 | /// Changes the radio channel |
| 109 | pub fn set_channel(&mut self, channel: u8) { | 115 | pub fn set_channel(&mut self, channel: u8) { |
| 110 | let r = T::regs(); | 116 | let r = self.r; |
| 111 | if channel < 11 || channel > 26 { | 117 | if channel < 11 || channel > 26 { |
| 112 | panic!("Bad 802.15.4 channel"); | 118 | panic!("Bad 802.15.4 channel"); |
| 113 | } | 119 | } |
| @@ -121,7 +127,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 121 | 127 | ||
| 122 | /// Changes the Clear Channel Assessment method | 128 | /// Changes the Clear Channel Assessment method |
| 123 | pub fn set_cca(&mut self, cca: Cca) { | 129 | pub fn set_cca(&mut self, cca: Cca) { |
| 124 | let r = T::regs(); | 130 | let r = self.r; |
| 125 | self.needs_enable = true; | 131 | self.needs_enable = true; |
| 126 | match cca { | 132 | match cca { |
| 127 | Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CARRIER_MODE)), | 133 | Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CARRIER_MODE)), |
| @@ -138,19 +144,19 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 138 | 144 | ||
| 139 | /// Changes the Start of Frame Delimiter (SFD) | 145 | /// Changes the Start of Frame Delimiter (SFD) |
| 140 | pub fn set_sfd(&mut self, sfd: u8) { | 146 | pub fn set_sfd(&mut self, sfd: u8) { |
| 141 | let r = T::regs(); | 147 | let r = self.r; |
| 142 | r.sfd().write(|w| w.set_sfd(sfd)); | 148 | r.sfd().write(|w| w.set_sfd(sfd)); |
| 143 | } | 149 | } |
| 144 | 150 | ||
| 145 | /// Clear interrupts | 151 | /// Clear interrupts |
| 146 | pub fn clear_all_interrupts(&mut self) { | 152 | pub fn clear_all_interrupts(&mut self) { |
| 147 | let r = T::regs(); | 153 | let r = self.r; |
| 148 | r.intenclr().write(|w| w.0 = 0xffff_ffff); | 154 | r.intenclr().write(|w| w.0 = 0xffff_ffff); |
| 149 | } | 155 | } |
| 150 | 156 | ||
| 151 | /// Changes the radio transmission power | 157 | /// Changes the radio transmission power |
| 152 | pub fn set_transmission_power(&mut self, power: i8) { | 158 | pub fn set_transmission_power(&mut self, power: i8) { |
| 153 | let r = T::regs(); | 159 | let r = self.r; |
| 154 | self.needs_enable = true; | 160 | self.needs_enable = true; |
| 155 | 161 | ||
| 156 | let tx_power: TxPower = match power { | 162 | let tx_power: TxPower = match power { |
| @@ -201,12 +207,12 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 201 | 207 | ||
| 202 | /// Get the current radio state | 208 | /// Get the current radio state |
| 203 | fn state(&self) -> RadioState { | 209 | fn state(&self) -> RadioState { |
| 204 | T::regs().state().read().state() | 210 | self.r.state().read().state() |
| 205 | } | 211 | } |
| 206 | 212 | ||
| 207 | /// Moves the radio from any state to the DISABLED state | 213 | /// Moves the radio from any state to the DISABLED state |
| 208 | fn disable(&mut self) { | 214 | fn disable(&mut self) { |
| 209 | let r = T::regs(); | 215 | let r = self.r; |
| 210 | // See figure 110 in nRF52840-PS | 216 | // See figure 110 in nRF52840-PS |
| 211 | loop { | 217 | loop { |
| 212 | match self.state() { | 218 | match self.state() { |
| @@ -238,15 +244,15 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 238 | } | 244 | } |
| 239 | 245 | ||
| 240 | fn set_buffer(&mut self, buffer: &[u8]) { | 246 | fn set_buffer(&mut self, buffer: &[u8]) { |
| 241 | let r = T::regs(); | 247 | let r = self.r; |
| 242 | r.packetptr().write_value(buffer.as_ptr() as u32); | 248 | r.packetptr().write_value(buffer.as_ptr() as u32); |
| 243 | } | 249 | } |
| 244 | 250 | ||
| 245 | /// Moves the radio to the RXIDLE state | 251 | /// Moves the radio to the RXIDLE state |
| 246 | fn receive_prepare(&mut self) { | 252 | fn receive_prepare(&mut self) { |
| 247 | // clear related events | 253 | // clear related events |
| 248 | T::regs().events_ccabusy().write_value(0); | 254 | self.r.events_ccabusy().write_value(0); |
| 249 | T::regs().events_phyend().write_value(0); | 255 | self.r.events_phyend().write_value(0); |
| 250 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RXIDLE | 256 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RXIDLE |
| 251 | let disable = match self.state() { | 257 | let disable = match self.state() { |
| 252 | RadioState::DISABLED => false, | 258 | RadioState::DISABLED => false, |
| @@ -263,7 +269,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 263 | fn receive_start(&mut self, packet: &mut Packet) { | 269 | fn receive_start(&mut self, packet: &mut Packet) { |
| 264 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's | 270 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's |
| 265 | // allocated in RAM | 271 | // allocated in RAM |
| 266 | let r = T::regs(); | 272 | let r = self.r; |
| 267 | 273 | ||
| 268 | self.receive_prepare(); | 274 | self.receive_prepare(); |
| 269 | 275 | ||
| @@ -290,7 +296,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 290 | 296 | ||
| 291 | /// Cancel receiving packet | 297 | /// Cancel receiving packet |
| 292 | fn receive_cancel() { | 298 | fn receive_cancel() { |
| 293 | let r = T::regs(); | 299 | let r = crate::pac::RADIO; |
| 294 | r.shorts().write(|_| {}); | 300 | r.shorts().write(|_| {}); |
| 295 | r.tasks_stop().write_value(1); | 301 | r.tasks_stop().write_value(1); |
| 296 | loop { | 302 | loop { |
| @@ -309,8 +315,8 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 309 | /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` | 315 | /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` |
| 310 | /// will be updated with the received packet's data | 316 | /// will be updated with the received packet's data |
| 311 | pub async fn receive(&mut self, packet: &mut Packet) -> Result<(), Error> { | 317 | pub async fn receive(&mut self, packet: &mut Packet) -> Result<(), Error> { |
| 312 | let s = T::state(); | 318 | let s = self.state; |
| 313 | let r = T::regs(); | 319 | let r = self.r; |
| 314 | 320 | ||
| 315 | // Start the read | 321 | // Start the read |
| 316 | self.receive_start(packet); | 322 | self.receive_start(packet); |
| @@ -356,8 +362,8 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 356 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's | 362 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's |
| 357 | // allocated in RAM | 363 | // allocated in RAM |
| 358 | pub async fn try_send(&mut self, packet: &mut Packet) -> Result<(), Error> { | 364 | pub async fn try_send(&mut self, packet: &mut Packet) -> Result<(), Error> { |
| 359 | let s = T::state(); | 365 | let s = self.state; |
| 360 | let r = T::regs(); | 366 | let r = self.r; |
| 361 | 367 | ||
| 362 | // enable radio to perform cca | 368 | // enable radio to perform cca |
| 363 | self.receive_prepare(); | 369 | self.receive_prepare(); |
diff --git a/examples/nrf52840/src/bin/sixlowpan.rs b/examples/nrf52840/src/bin/sixlowpan.rs index 00a597366..12e385e01 100644 --- a/examples/nrf52840/src/bin/sixlowpan.rs +++ b/examples/nrf52840/src/bin/sixlowpan.rs | |||
| @@ -21,7 +21,7 @@ bind_interrupts!(struct Irqs { | |||
| 21 | }); | 21 | }); |
| 22 | 22 | ||
| 23 | #[embassy_executor::task] | 23 | #[embassy_executor::task] |
| 24 | async fn ieee802154_task(runner: net::Runner<'static, peripherals::RADIO>) -> ! { | 24 | async fn ieee802154_task(runner: net::Runner<'static>) -> ! { |
| 25 | runner.run().await | 25 | runner.run().await |
| 26 | } | 26 | } |
| 27 | 27 | ||
