aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-09-28 22:25:25 +0200
committerDario Nieuwenhuis <[email protected]>2025-09-28 22:25:25 +0200
commitb2727640ed5ff514ca2bbaacc058bfa546767e4d (patch)
treecbc2bb820531386f03a1132f19bdebe7168ccd78 /embassy-nrf/src
parent6d9bf03a3becbb2ffd35a6f42a03da4e383dc46e (diff)
nrf/radio: erase instance generic
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/embassy_net_802154_driver.rs8
-rw-r--r--embassy-nrf/src/radio/ieee802154.rs58
2 files changed, 36 insertions, 30 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.
35pub struct Runner<'d, T: nrf::radio::Instance> { 35pub 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
40impl<'d, T: nrf::radio::Instance> Runner<'d, T> { 40impl<'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>), ()>
88where 88where
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
3use core::marker::PhantomData;
3use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 5use core::task::Poll;
5 6
6use embassy_hal_internal::drop::OnDrop; 7use embassy_hal_internal::drop::OnDrop;
7 8
8use super::{Error, Instance, InterruptHandler, TxPower}; 9use super::{Error, InterruptHandler, TxPower};
9use crate::interrupt::typelevel::Interrupt; 10use crate::interrupt::typelevel::Interrupt;
10use crate::interrupt::{self}; 11use crate::interrupt::{self};
11use crate::pac::radio::vals; 12use crate::pac::radio::vals;
12pub use crate::pac::radio::vals::State as RadioState; 13pub use crate::pac::radio::vals::State as RadioState;
14use crate::radio::Instance;
13use crate::Peri; 15use 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.
35pub struct Radio<'d, T: Instance> { 37pub 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
40impl<'d, T: Instance> Radio<'d, T> { 44impl<'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();