summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2022-03-26 18:52:10 +0100
committerGitHub <noreply@github.com>2022-03-26 18:52:10 +0100
commit20558a4c63d77f2ed51888619813f08ae0c05cbf (patch)
tree6aa851719dae645428cc0f644c5b979918c878b4
parent6ee09a134d9366029462963650dcd7e3921d6c1d (diff)
parent4f283a4555736715cfb1ae0d21e062a6f5e28919 (diff)
downloadnrf-softdevice-20558a4c63d77f2ed51888619813f08ae0c05cbf.zip
Merge pull request #104 from alexmoon/soc-events
Add `Softdevice::run_with_callback()` to receive unhandled `SocEvent`s
-rw-r--r--nrf-softdevice/src/events.rs30
-rw-r--r--nrf-softdevice/src/softdevice.rs13
2 files changed, 27 insertions, 16 deletions
diff --git a/nrf-softdevice/src/events.rs b/nrf-softdevice/src/events.rs
index bf7c5d6..5df73f1 100644
--- a/nrf-softdevice/src/events.rs
+++ b/nrf-softdevice/src/events.rs
@@ -11,15 +11,14 @@ use crate::RawError;
static SWI2_WAKER: AtomicWaker = AtomicWaker::new();
+/// SoC events reported by the softdevice.
#[rustfmt::skip]
#[repr(u32)]
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-enum SocEvent {
+pub enum SocEvent {
Hfclkstarted = raw::NRF_SOC_EVTS_NRF_EVT_HFCLKSTARTED,
PowerFailureWarning = raw::NRF_SOC_EVTS_NRF_EVT_POWER_FAILURE_WARNING,
- FlashOperationSuccess = raw::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_SUCCESS,
- FlashOperationError = raw::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_ERROR,
RadioBlocked = raw::NRF_SOC_EVTS_NRF_EVT_RADIO_BLOCKED,
RadioCanceled = raw::NRF_SOC_EVTS_NRF_EVT_RADIO_CANCELED,
RadioSignalCallbackInvalidReturn = raw::NRF_SOC_EVTS_NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN,
@@ -33,31 +32,34 @@ enum SocEvent {
PowerUsbRemoved = raw::NRF_SOC_EVTS_NRF_EVT_POWER_USB_REMOVED,
}
-fn on_soc_evt(evt: u32) {
- let evt = match SocEvent::try_from(evt) {
- Ok(evt) => evt,
- Err(_) => panic!("Unknown soc evt {:?}", evt),
- };
-
+fn on_soc_evt<F: FnMut(SocEvent)>(evt: u32, evt_handler: &mut F) {
info!("soc evt {:?}", evt);
+
match evt {
- SocEvent::FlashOperationError => crate::flash::on_flash_error(),
- SocEvent::FlashOperationSuccess => crate::flash::on_flash_success(),
- _ => {}
+ raw::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_ERROR => crate::flash::on_flash_error(),
+ raw::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_SUCCESS => crate::flash::on_flash_success(),
+ _ => {
+ let evt = match SocEvent::try_from(evt) {
+ Ok(evt) => evt,
+ Err(_) => panic!("Unknown soc evt {:?}", evt),
+ };
+
+ evt_handler(evt)
+ }
}
}
// TODO actually derive this from the headers + the ATT_MTU
const BLE_EVT_MAX_SIZE: u16 = 128;
-pub(crate) async fn run() -> ! {
+pub(crate) async fn run<F: FnMut(SocEvent)>(mut soc_evt_handler: F) -> ! {
poll_fn(|cx| unsafe {
SWI2_WAKER.register(cx.waker());
let mut evt: u32 = 0;
loop {
match RawError::convert(raw::sd_evt_get(&mut evt as _)) {
- Ok(()) => on_soc_evt(evt),
+ Ok(()) => on_soc_evt(evt, &mut soc_evt_handler),
Err(RawError::NotFound) => break,
Err(err) => panic!("sd_evt_get err {:?}", err),
}
diff --git a/nrf-softdevice/src/softdevice.rs b/nrf-softdevice/src/softdevice.rs
index cbcfe8b..d697cbe 100644
--- a/nrf-softdevice/src/softdevice.rs
+++ b/nrf-softdevice/src/softdevice.rs
@@ -3,9 +3,9 @@ use core::ptr;
use core::sync::atomic::{AtomicBool, Ordering};
use embassy::util::Forever;
-use crate::pac;
use crate::raw;
use crate::RawError;
+use crate::{pac, SocEvent};
unsafe extern "C" fn fault_handler(id: u32, pc: u32, info: u32) {
match (id, info) {
@@ -320,6 +320,15 @@ impl Softdevice {
/// It must be called in its own async task after enabling the softdevice
/// and before doing any operation. Failure to doing so will cause async operations to never finish.
pub async fn run(&self) -> ! {
- crate::events::run().await
+ self.run_with_callback(|_| {}).await
+ }
+
+ /// Runs the softdevice event handling loop with a callback for [`SocEvent`]s.
+ ///
+ /// It must be called under the same conditions as [`Softdevice::run()`]. This
+ /// version allows the application to provide a callback to receive SoC events
+ /// from the softdevice (other than flash events which are handled by [`Flash`](crate::flash::Flash)).
+ pub async fn run_with_callback<F: FnMut(SocEvent)>(&self, f: F) -> ! {
+ crate::events::run(f).await
}
}