Support nearly all nRF5 RADIOs

This commit is contained in:
Erik Bånvik 2024-03-05 11:39:15 +01:00
parent 84935fbfab
commit bc258b322b
11 changed files with 95 additions and 3 deletions

View file

@ -99,6 +99,9 @@ embassy_hal_internal::peripherals! {
// TEMP
TEMP,
// Radio
RADIO,
}
impl_timer!(TIMER0, TIMER0, TIMER0);
@ -140,6 +143,8 @@ impl_pin!(P0_29, 0, 29);
impl_pin!(P0_30, 0, 30);
impl_pin!(P0_31, 0, 31);
impl_radio!(RADIO, RADIO, RADIO);
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,

View file

@ -129,6 +129,9 @@ embassy_hal_internal::peripherals! {
// QDEC
QDEC,
// Radio
RADIO,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@ -209,6 +212,8 @@ impl_ppi_channel!(PPI_CH31, 31 => static);
impl_saadc_input!(P0_04, ANALOG_INPUT2);
impl_saadc_input!(P0_05, ANALOG_INPUT3);
impl_radio!(RADIO, RADIO, RADIO);
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,

View file

@ -135,6 +135,9 @@ embassy_hal_internal::peripherals! {
// PDM
PDM,
// Radio
RADIO,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@ -235,6 +238,8 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
impl_saadc_input!(P0_30, ANALOG_INPUT6);
impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_radio!(RADIO, RADIO, RADIO);
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,

View file

@ -135,6 +135,9 @@ embassy_hal_internal::peripherals! {
// PDM
PDM,
// Radio
RADIO,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@ -237,6 +240,8 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
impl_saadc_input!(P0_30, ANALOG_INPUT6);
impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_radio!(RADIO, RADIO, RADIO);
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,

View file

@ -130,6 +130,9 @@ embassy_hal_internal::peripherals! {
// QDEC
QDEC,
// Radio
RADIO,
}
impl_usb!(USBD, USBD, USBD);
@ -224,6 +227,8 @@ impl_ppi_channel!(PPI_CH29, 29 => static);
impl_ppi_channel!(PPI_CH30, 30 => static);
impl_ppi_channel!(PPI_CH31, 31 => static);
impl_radio!(RADIO, RADIO, RADIO);
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,

View file

@ -150,6 +150,9 @@ embassy_hal_internal::peripherals! {
// PDM
PDM,
// Radio
RADIO,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@ -264,6 +267,8 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_i2s!(I2S, I2S, I2S);
impl_radio!(RADIO, RADIO, RADIO);
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,

View file

@ -248,6 +248,9 @@ embassy_hal_internal::peripherals! {
P1_13,
P1_14,
P1_15,
// Radio
RADIO,
}
impl_uarte!(SERIAL0, UARTE0, SERIAL0);
@ -345,6 +348,8 @@ impl_ppi_channel!(PPI_CH29, 29 => configurable);
impl_ppi_channel!(PPI_CH30, 30 => configurable);
impl_ppi_channel!(PPI_CH31, 31 => configurable);
impl_radio!(RADIO, RADIO, RADIO);
embassy_hal_internal::interrupt_mod!(
CLOCK_POWER,
RADIO,

View file

@ -47,7 +47,7 @@ pub mod gpio;
pub mod gpiote;
// TODO: tested on other chips
#[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
#[cfg(not(any(feature = "nrf51", feature = "_nrf9160")))]
pub mod radio;
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]

View file

@ -7,6 +7,7 @@ use core::task::Poll;
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
pub use pac::radio::mode::MODE_A as Mode;
#[cfg(not(feature = "nrf51"))]
use pac::radio::pcnf0::PLEN_A as PreambleLength;
use crate::interrupt::typelevel::Interrupt;
@ -84,6 +85,7 @@ impl<'d, T: Instance> Radio<'d, T> {
// Ch map between 2400 MHZ .. 2500 MHz
// All modes use this range
#[cfg(not(feature = "nrf51"))]
r.frequency.write(|w| w.map().default());
// Configure shortcuts to simplify and speed up sending and receiving packets.
@ -121,10 +123,18 @@ impl<'d, T: Instance> Radio<'d, T> {
let r = T::regs();
r.mode.write(|w| w.mode().variant(mode));
#[cfg(not(feature = "nrf51"))]
r.pcnf0.write(|w| {
w.plen().variant(match mode {
Mode::BLE_1MBIT => PreambleLength::_8BIT,
Mode::BLE_2MBIT => PreambleLength::_16BIT,
#[cfg(any(
feature = "nrf52811",
feature = "nrf52820",
feature = "nrf52833",
feature = "nrf52840",
feature = "_nrf5340-net"
))]
Mode::BLE_LR125KBIT | Mode::BLE_LR500KBIT => PreambleLength::LONG_RANGE,
_ => unimplemented!(),
})
@ -307,7 +317,11 @@ impl<'d, T: Instance> Radio<'d, T> {
self.trigger_and_wait_end(move || {
// Initialize the transmission
// trace!("txen");
#[cfg(not(any(feature = "nrf51", feature = "nrf52832")))]
r.tasks_txen.write(|w| w.tasks_txen().set_bit());
#[cfg(any(feature = "nrf51", feature = "nrf52832"))]
r.tasks_txen.write(|w| unsafe { w.bits(1) });
})
.await;
@ -324,7 +338,10 @@ impl<'d, T: Instance> Radio<'d, T> {
self.trigger_and_wait_end(move || {
// Initialize the transmission
// trace!("rxen");
#[cfg(not(any(feature = "nrf51", feature = "nrf52832")))]
r.tasks_rxen.write(|w| w.tasks_rxen().set_bit());
#[cfg(any(feature = "nrf51", feature = "nrf52832"))]
r.tasks_rxen.write(|w| unsafe { w.bits(1) });
})
.await;
@ -346,10 +363,16 @@ impl<'d, T: Instance> Radio<'d, T> {
r.intenclr.write(|w| w.end().clear());
r.events_end.reset();
#[cfg(not(any(feature = "nrf51", feature = "nrf52832")))]
r.tasks_stop.write(|w| w.tasks_stop().set_bit());
#[cfg(any(feature = "nrf51", feature = "nrf52832"))]
r.tasks_stop.write(|w| unsafe { w.bits(1) });
// The docs don't explicitly mention any event to acknowledge the stop task
#[cfg(not(any(feature = "nrf51", feature = "nrf52832")))]
while r.events_end.read().events_end().bit_is_clear() {}
#[cfg(any(feature = "nrf51", feature = "nrf52832"))]
while r.events_end.read().bits() == 0 {}
trace!("radio drop: stopped");
});
@ -370,7 +393,11 @@ impl<'d, T: Instance> Radio<'d, T> {
// On poll check if interrupt happen
poll_fn(|cx| {
s.event_waker.register(cx.waker());
if r.events_end.read().events_end().bit_is_set() {
#[cfg(not(any(feature = "nrf51", feature = "nrf52832")))]
let end_event = r.events_end.read().events_end().bit_is_set();
#[cfg(any(feature = "nrf51", feature = "nrf52832"))]
let end_event = r.events_end.read().bits() == 1;
if end_event {
// trace!("radio:end");
return core::task::Poll::Ready(());
}
@ -394,10 +421,16 @@ impl<'d, T: Instance> Radio<'d, T> {
if self.state() != RadioState::DISABLED {
trace!("radio:disable");
// Trigger the disable task
#[cfg(not(any(feature = "nrf51", feature = "nrf52832")))]
r.tasks_disable.write(|w| w.tasks_disable().set_bit());
#[cfg(any(feature = "nrf51", feature = "nrf52832"))]
r.tasks_disable.write(|w| unsafe { w.bits(1) });
// Wait until the radio is disabled
#[cfg(not(any(feature = "nrf51", feature = "nrf52832")))]
while r.events_disabled.read().events_disabled().bit_is_clear() {}
#[cfg(any(feature = "nrf51", feature = "nrf52832"))]
while r.events_disabled.read().bits() == 0 {}
compiler_fence(Ordering::SeqCst);

View file

@ -162,15 +162,34 @@ impl<'d, T: Instance> Radio<'d, T> {
self.needs_enable = true;
let tx_power: TxPower = match power {
#[cfg(not(feature = "_nrf5340-net"))]
8 => TxPower::POS8D_BM,
#[cfg(not(feature = "_nrf5340-net"))]
7 => TxPower::POS7D_BM,
#[cfg(not(feature = "_nrf5340-net"))]
6 => TxPower::POS6D_BM,
#[cfg(not(feature = "_nrf5340-net"))]
5 => TxPower::POS5D_BM,
#[cfg(not(feature = "_nrf5340-net"))]
4 => TxPower::POS4D_BM,
#[cfg(not(feature = "_nrf5340-net"))]
3 => TxPower::POS3D_BM,
#[cfg(not(feature = "_nrf5340-net"))]
2 => TxPower::POS2D_BM,
0 => TxPower::_0D_BM,
#[cfg(feature = "_nrf5340-net")]
-1 => TxPower::NEG1D_BM,
#[cfg(feature = "_nrf5340-net")]
-2 => TxPower::NEG2D_BM,
#[cfg(feature = "_nrf5340-net")]
-3 => TxPower::NEG3D_BM,
-4 => TxPower::NEG4D_BM,
#[cfg(feature = "_nrf5340-net")]
-5 => TxPower::NEG5D_BM,
#[cfg(feature = "_nrf5340-net")]
-6 => TxPower::NEG6D_BM,
#[cfg(feature = "_nrf5340-net")]
-7 => TxPower::NEG7D_BM,
-8 => TxPower::NEG8D_BM,
-12 => TxPower::NEG12D_BM,
-16 => TxPower::NEG16D_BM,

View file

@ -7,7 +7,12 @@
/// Bluetooth Low Energy Radio driver.
pub mod ble;
#[cfg(any(feature = "nrf52840", feature = "nrf52833", feature = "_nrf5340-net"))]
#[cfg(any(
feature = "nrf52820",
feature = "nrf52833",
feature = "nrf52840",
feature = "_nrf5340-net"
))]
/// IEEE 802.15.4
pub mod ieee802154;