summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2020-09-05 02:56:06 +0200
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2020-09-05 02:59:59 +0200
commit5749858daf778f4f46dee5fe6d9a1d6ebfd752f4 (patch)
treed4b9564b218a8ff2cf7c87660aeb4baf5e3c716f
parent95d648d13d5e7ff014c255a361bbc61713978892 (diff)
downloadnrf-softdevice-5749858daf778f4f46dee5fe6d9a1d6ebfd752f4.zip
Add Error enum. Better Event enums.
-rw-r--r--.vscode/settings.json6
-rw-r--r--examples/flash/Cargo.toml2
-rw-r--r--nrf-softdevice/Cargo.toml1
-rw-r--r--nrf-softdevice/src/error.rs74
-rw-r--r--nrf-softdevice/src/events.rs189
-rw-r--r--nrf-softdevice/src/flash.rs42
-rw-r--r--nrf-softdevice/src/interrupt.rs5
-rw-r--r--nrf-softdevice/src/lib.rs32
-rw-r--r--nrf-softdevice/src/util/mod.rs2
9 files changed, 240 insertions, 113 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 23fd35f..1e1c62d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,5 @@
{
- "editor.formatOnSave": true
-} \ No newline at end of file
+ "editor.formatOnSave": true,
+ "rust-analyzer.cargo.target": "thumbv7em-none-eabihf",
+ "rust-analyzer.checkOnSave.allTargets": false
+}
diff --git a/examples/flash/Cargo.toml b/examples/flash/Cargo.toml
index f5c7568..86678f9 100644
--- a/examples/flash/Cargo.toml
+++ b/examples/flash/Cargo.toml
@@ -22,7 +22,7 @@ defmt = "0.1.0"
defmt-rtt = "0.1.0"
panic-probe = "0.1.0"
nrf52840-hal = { version = "0.11.0" }
-nrf-softdevice = { version = "0.1.0", path = "../../nrf-softdevice" }
+nrf-softdevice = { version = "0.1.0", path = "../../nrf-softdevice", features = ["defmt-trace"] }
static-executor = { version = "0.1.0" }
static-executor-cortex-m = { version = "0.1.0" }
diff --git a/nrf-softdevice/Cargo.toml b/nrf-softdevice/Cargo.toml
index 2fb0cf4..dbe3ee5 100644
--- a/nrf-softdevice/Cargo.toml
+++ b/nrf-softdevice/Cargo.toml
@@ -13,6 +13,7 @@ defmt-warn = []
defmt-error = []
[dependencies]
+num_enum = { version = "0.5.1", default-features = false }
async-flash = { version = "0.1.0", path = "../async-flash" }
nrf-softdevice-s140 = { version = "0.1.1", path = "../nrf-softdevice-s140" }
cortex-m = "0.6.2"
diff --git a/nrf-softdevice/src/error.rs b/nrf-softdevice/src/error.rs
new file mode 100644
index 0000000..30623aa
--- /dev/null
+++ b/nrf-softdevice/src/error.rs
@@ -0,0 +1,74 @@
+use num_enum::{FromPrimitive, IntoPrimitive};
+
+use crate::sd;
+
+#[rustfmt::skip]
+#[repr(u32)]
+#[derive(defmt::Format, IntoPrimitive, FromPrimitive)]
+pub enum Error {
+ // This is not really an error, but IMO it's better to add it
+ // anyway, just in case mistakenly someone converts NRF_SUCCESS into Error.
+ // if they see "Success" they'll easily realize their mistake, if they see "Unknown" it'd be confusing.
+ Success = sd::NRF_SUCCESS,
+
+ #[num_enum(default)]
+ Unknown = 0xFFFFFFFF,
+
+ SvcHandlerMissing = sd::NRF_ERROR_SVC_HANDLER_MISSING,
+ SoftdeviceNotEnabled = sd::NRF_ERROR_SOFTDEVICE_NOT_ENABLED,
+ Internal = sd::NRF_ERROR_INTERNAL,
+ NoMem = sd::NRF_ERROR_NO_MEM,
+ NotFound = sd::NRF_ERROR_NOT_FOUND,
+ NotSupported = sd::NRF_ERROR_NOT_SUPPORTED,
+ InvalidParam = sd::NRF_ERROR_INVALID_PARAM,
+ InvalidState = sd::NRF_ERROR_INVALID_STATE,
+ InvalidLength = sd::NRF_ERROR_INVALID_LENGTH,
+ InvalidFlags = sd::NRF_ERROR_INVALID_FLAGS,
+ InvalidData = sd::NRF_ERROR_INVALID_DATA,
+ DataSize = sd::NRF_ERROR_DATA_SIZE,
+ Timeout = sd::NRF_ERROR_TIMEOUT,
+ Null = sd::NRF_ERROR_NULL,
+ Forbidden = sd::NRF_ERROR_FORBIDDEN,
+ InvalidAddr = sd::NRF_ERROR_INVALID_ADDR,
+ Busy = sd::NRF_ERROR_BUSY,
+ ConnCount = sd::NRF_ERROR_CONN_COUNT,
+ Resources = sd::NRF_ERROR_RESOURCES,
+ SdmLfclkSourceUnknown = sd::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN,
+ SdmIncorrectInterruptConfiguration = sd::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION,
+ SdmIncorrectClenr0 = sd::NRF_ERROR_SDM_INCORRECT_CLENR0,
+ SocMutexAlreadyTaken = sd::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN,
+ SocNvicInterruptNotAvailable = sd::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE,
+ SocNvicInterruptPriorityNotAllowed = sd::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED,
+ SocNvicShouldNotReturn = sd::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN,
+ SocPowerModeUnknown = sd::NRF_ERROR_SOC_POWER_MODE_UNKNOWN,
+ SocPowerPofThresholdUnknown = sd::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN,
+ SocPowerOffShouldNotReturn = sd::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN,
+ SocRandNotEnoughValues = sd::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES,
+ SocPpiInvalidChannel = sd::NRF_ERROR_SOC_PPI_INVALID_CHANNEL,
+ SocPpiInvalidGroup = sd::NRF_ERROR_SOC_PPI_INVALID_GROUP,
+ BleNotEnabled = sd::BLE_ERROR_NOT_ENABLED,
+ BleInvalidConnHandle = sd::BLE_ERROR_INVALID_CONN_HANDLE,
+ BleInvalidAttrHandle = sd::BLE_ERROR_INVALID_ATTR_HANDLE,
+ BleInvalidAdvHandle = sd::BLE_ERROR_INVALID_ADV_HANDLE,
+ BleInvalidRole = sd::BLE_ERROR_INVALID_ROLE,
+ BleBlockedByOtherLinks = sd::BLE_ERROR_BLOCKED_BY_OTHER_LINKS,
+ BleGapUuidListMismatch = sd::BLE_ERROR_GAP_UUID_LIST_MISMATCH,
+ BleGapDiscoverableWithWhitelist = sd::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST,
+ BleGapInvalidBleAddr = sd::BLE_ERROR_GAP_INVALID_BLE_ADDR,
+ BleGapWhitelistInUse = sd::BLE_ERROR_GAP_WHITELIST_IN_USE,
+ BleGapDeviceIdentitiesInUse = sd::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE,
+ BleGapDeviceIdentitiesDuplicate = sd::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE,
+ BleGattcProcNotPermitted = sd::BLE_ERROR_GATTC_PROC_NOT_PERMITTED,
+ BleGattsInvalidAttrType = sd::BLE_ERROR_GATTS_INVALID_ATTR_TYPE,
+ BleGattsSysAttrMissing = sd::BLE_ERROR_GATTS_SYS_ATTR_MISSING,
+}
+
+impl Error {
+ pub(crate) fn convert(err: u32) -> Result<(), Error> {
+ if err == sd::NRF_SUCCESS {
+ Ok(())
+ } else {
+ Err(Error::from(err))
+ }
+ }
+}
diff --git a/nrf-softdevice/src/events.rs b/nrf-softdevice/src/events.rs
index 7988d74..a92261b 100644
--- a/nrf-softdevice/src/events.rs
+++ b/nrf-softdevice/src/events.rs
@@ -1,85 +1,98 @@
-use core::marker::PhantomData;
+use core::convert::TryFrom;
use core::mem::MaybeUninit;
-use defmt::info;
-use nrf52840_pac::{interrupt, Interrupt};
-use nrf_softdevice_s140 as sd;
+use num_enum::{IntoPrimitive, TryFromPrimitive};
-use crate::util::Signal;
-
-unsafe extern "C" fn fault_handler(id: u32, pc: u32, info: u32) {
- depanic!("fault_handler {:u32} {:u32} {:u32}", id, pc, info);
-}
-
-/// safety: call at most once
-pub unsafe fn enable() {
- // TODO make this configurable via features or param
- let clock_cfg = sd::nrf_clock_lf_cfg_t {
- source: sd::NRF_CLOCK_LF_SRC_XTAL as u8,
- rc_ctiv: 0,
- rc_temp_ctiv: 0,
- accuracy: 7,
- };
-
- let ret = sd::sd_softdevice_enable(&clock_cfg as _, Some(fault_handler));
- if ret != sd::NRF_SUCCESS {
- depanic!("sd_softdevice_enable ret {:u32}", ret);
- }
-
- crate::interrupt::unmask(Interrupt::SWI2_EGU2);
-}
+use crate::error::Error;
+use crate::util::*;
+use crate::{pac, sd};
+use pac::interrupt;
static SWI2_SIGNAL: Signal<()> = Signal::new();
-#[derive(defmt::Format)]
+#[rustfmt::skip]
+#[repr(u32)]
+#[derive(defmt::Format, IntoPrimitive, TryFromPrimitive)]
enum SocEvent {
- Hfclkstarted,
- PowerFailureWarning,
- FlashOperationSuccess,
- FlashOperationError,
- RadioBlocked,
- RadioCanceled,
- RadioSignalCallbackinvalidReturn,
- RadioSessionIdle,
- RadioSessionClosed,
- PowerUsbPowerReady,
- PowerUsbDetected,
- PowerUsbRemoved,
-}
-
-impl SocEvent {
- fn from_raw(raw: u32) -> Self {
- match raw {
- sd::NRF_SOC_EVTS_NRF_EVT_HFCLKSTARTED => SocEvent::Hfclkstarted,
- sd::NRF_SOC_EVTS_NRF_EVT_POWER_FAILURE_WARNING => SocEvent::PowerFailureWarning,
- sd::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_SUCCESS => SocEvent::FlashOperationSuccess,
- sd::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_ERROR => SocEvent::FlashOperationError,
- sd::NRF_SOC_EVTS_NRF_EVT_RADIO_BLOCKED => SocEvent::RadioBlocked,
- sd::NRF_SOC_EVTS_NRF_EVT_RADIO_CANCELED => SocEvent::RadioCanceled,
- sd::NRF_SOC_EVTS_NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN => {
- SocEvent::RadioSignalCallbackinvalidReturn
- }
- sd::NRF_SOC_EVTS_NRF_EVT_RADIO_SESSION_IDLE => SocEvent::RadioSessionIdle,
- sd::NRF_SOC_EVTS_NRF_EVT_RADIO_SESSION_CLOSED => SocEvent::RadioSessionClosed,
- sd::NRF_SOC_EVTS_NRF_EVT_POWER_USB_POWER_READY => SocEvent::PowerUsbPowerReady,
- sd::NRF_SOC_EVTS_NRF_EVT_POWER_USB_DETECTED => SocEvent::PowerUsbDetected,
- sd::NRF_SOC_EVTS_NRF_EVT_POWER_USB_REMOVED => SocEvent::PowerUsbRemoved,
- x => depanic!("unknown soc evt {:u32}", x),
- }
- }
+ Hfclkstarted = sd::NRF_SOC_EVTS_NRF_EVT_HFCLKSTARTED,
+ PowerFailureWarning = sd::NRF_SOC_EVTS_NRF_EVT_POWER_FAILURE_WARNING,
+ FlashOperationSuccess = sd::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_SUCCESS,
+ FlashOperationError = sd::NRF_SOC_EVTS_NRF_EVT_FLASH_OPERATION_ERROR,
+ RadioBlocked = sd::NRF_SOC_EVTS_NRF_EVT_RADIO_BLOCKED,
+ RadioCanceled = sd::NRF_SOC_EVTS_NRF_EVT_RADIO_CANCELED,
+ RadioSignalCallbackInvalidReturn = sd::NRF_SOC_EVTS_NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN,
+ RadioSessionIdle = sd::NRF_SOC_EVTS_NRF_EVT_RADIO_SESSION_IDLE,
+ RadioSessionClosed = sd::NRF_SOC_EVTS_NRF_EVT_RADIO_SESSION_CLOSED,
+ PowerUsbPowerReady = sd::NRF_SOC_EVTS_NRF_EVT_POWER_USB_POWER_READY,
+ PowerUsbDetected = sd::NRF_SOC_EVTS_NRF_EVT_POWER_USB_DETECTED,
+ PowerUsbRemoved = sd::NRF_SOC_EVTS_NRF_EVT_POWER_USB_REMOVED,
}
-#[derive(defmt::Format)]
-enum BleEvent<'a> {
- ToDo(PhantomData<&'a ()>),
+#[rustfmt::skip]
+#[repr(u32)]
+#[derive(defmt::Format, IntoPrimitive, TryFromPrimitive)]
+enum BleEvent {
+ CommonUserMemRequest = sd::BLE_COMMON_EVTS_BLE_EVT_USER_MEM_REQUEST,
+ CommonUserMemRelease = sd::BLE_COMMON_EVTS_BLE_EVT_USER_MEM_RELEASE,
+ GapConnected = sd::BLE_GAP_EVTS_BLE_GAP_EVT_CONNECTED,
+ GapDisconnected = sd::BLE_GAP_EVTS_BLE_GAP_EVT_DISCONNECTED,
+ GapConnParamUpdate = sd::BLE_GAP_EVTS_BLE_GAP_EVT_CONN_PARAM_UPDATE,
+ GapSecParamsRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_SEC_PARAMS_REQUEST,
+ GapSecInfoRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_SEC_INFO_REQUEST,
+ GapPasskeyDisplay = sd::BLE_GAP_EVTS_BLE_GAP_EVT_PASSKEY_DISPLAY,
+ GapKeyPressed = sd::BLE_GAP_EVTS_BLE_GAP_EVT_KEY_PRESSED,
+ GapAuthKeyRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_AUTH_KEY_REQUEST,
+ GapLescDhkeyRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_LESC_DHKEY_REQUEST,
+ GapAuthStatus = sd::BLE_GAP_EVTS_BLE_GAP_EVT_AUTH_STATUS,
+ GapConnSecUpdate = sd::BLE_GAP_EVTS_BLE_GAP_EVT_CONN_SEC_UPDATE,
+ GapTimeout = sd::BLE_GAP_EVTS_BLE_GAP_EVT_TIMEOUT,
+ GapRssiChanged = sd::BLE_GAP_EVTS_BLE_GAP_EVT_RSSI_CHANGED,
+ GapAdvReport = sd::BLE_GAP_EVTS_BLE_GAP_EVT_ADV_REPORT,
+ GapSecRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_SEC_REQUEST,
+ GapConnParamUpdateRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST,
+ GapScanReqReport = sd::BLE_GAP_EVTS_BLE_GAP_EVT_SCAN_REQ_REPORT,
+ GapPhyUpdateRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_PHY_UPDATE_REQUEST,
+ GapPhyUpdate = sd::BLE_GAP_EVTS_BLE_GAP_EVT_PHY_UPDATE,
+ GapDataLengthUpdateRequest = sd::BLE_GAP_EVTS_BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST,
+ GapDataLengthUpdate = sd::BLE_GAP_EVTS_BLE_GAP_EVT_DATA_LENGTH_UPDATE,
+ GapQosChannelSurveyReport = sd::BLE_GAP_EVTS_BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT,
+ GapAdvSetTerminated = sd::BLE_GAP_EVTS_BLE_GAP_EVT_ADV_SET_TERMINATED,
+ L2CapChSetupRequest = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_SETUP_REQUEST,
+ L2CapChSetupRefused = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_SETUP_REFUSED,
+ L2CapChSetup = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_SETUP,
+ L2CapChReleased = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_RELEASED,
+ L2CapChSduBufReleased = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED,
+ L2CapChCredit = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_CREDIT,
+ L2CapChRx = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_RX,
+ L2CapChTx = sd::BLE_L2CAP_EVTS_BLE_L2CAP_EVT_CH_TX,
+ GattcPrimSrvcDiscRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP,
+ GattcRelDiscRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_REL_DISC_RSP,
+ GattcCharDiscRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_CHAR_DISC_RSP,
+ GattcDescDiscRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_DESC_DISC_RSP,
+ GattcAttrInfoDiscRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_ATTR_INFO_DISC_RSP,
+ GattcCharValByUuidReadRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP,
+ GattcReadRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_READ_RSP,
+ GattcCharValsReadRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_CHAR_VALS_READ_RSP,
+ GattcWriteRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_WRITE_RSP,
+ GattcHvx = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_HVX,
+ GattcExchangeMtuRsp = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_EXCHANGE_MTU_RSP,
+ GattcTimeout = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_TIMEOUT,
+ GattcWriteCmdTxComplete = sd::BLE_GATTC_EVTS_BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE,
+ GattsEvtWrite = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_WRITE,
+ GattsEvtRwAuthorizeRequest = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST,
+ GattsEvtSysAttrMissing = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_SYS_ATTR_MISSING,
+ GattsEvtHvc = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_HVC,
+ GattsEvtScConfirm = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_SC_CONFIRM,
+ GattsEvtExchangeMtuRequest = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST,
+ GattsEvtTimeout = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_TIMEOUT,
+ GattsEvtHvnTxComplete = sd::BLE_GATTS_EVTS_BLE_GATTS_EVT_HVN_TX_COMPLETE,
}
-impl<'a> BleEvent<'a> {
- fn from_raw(ble_evt: &'a sd::ble_evt_t, len: usize) -> Self {
- Self::ToDo(PhantomData)
- }
-}
+fn on_soc_evt(evt: u32) {
+ let evt = match SocEvent::try_from(evt) {
+ Ok(evt) => evt,
+ Err(_) => depanic!("Unknown soc evt {:u32}", evt),
+ };
-fn on_soc_evt(evt: SocEvent) {
info!("soc evt {:?}", evt);
match evt {
SocEvent::FlashOperationError => crate::flash::on_flash_error(),
@@ -88,8 +101,14 @@ fn on_soc_evt(evt: SocEvent) {
}
}
-fn on_ble_evt(evt: BleEvent<'_>) {
- info!("got ble evt");
+fn on_ble_evt(evt: &sd::ble_evt_t) {
+ let evt_id = evt.header.evt_id as u32;
+ let evt = match BleEvent::try_from(evt_id) {
+ Ok(evt) => evt,
+ Err(_) => depanic!("Unknown ble evt {:u32}", evt_id),
+ };
+
+ info!("ble evt {:?}", evt);
}
// TODO actually derive this from the headers + the ATT_MTU
@@ -102,10 +121,10 @@ pub async fn run() {
unsafe {
let mut evt: u32 = 0;
loop {
- match sd::sd_evt_get(&mut evt as _) {
- sd::NRF_SUCCESS => on_soc_evt(SocEvent::from_raw(evt)),
- sd::NRF_ERROR_NOT_FOUND => break,
- err => depanic!("sd_evt_get returned {:u32}", err),
+ match Error::convert(sd::sd_evt_get(&mut evt as _)) {
+ Ok(()) => on_soc_evt(evt),
+ Err(Error::NotFound) => break,
+ Err(err) => depanic!("sd_evt_get err {:?}", err),
}
}
@@ -114,15 +133,13 @@ pub async fn run() {
loop {
let mut len: u16 = BLE_EVT_MAX_SIZE;
- match sd::sd_ble_evt_get(evt.as_mut_ptr() as *mut u8, &mut len as _) {
- sd::NRF_SUCCESS => {
- let evt_ref = &*(evt.as_ptr() as *const sd::ble_evt_t);
- on_ble_evt(BleEvent::from_raw(evt_ref, len as usize));
- }
- sd::NRF_ERROR_NO_MEM => depanic!("BUG: BLE_EVT_MAX_SIZE is too low"),
- sd::NRF_ERROR_NOT_FOUND => break,
- sd::BLE_ERROR_NOT_ENABLED => break,
- err => depanic!("sd_ble_evt_get returned {:u32}", err),
+ let ret = sd::sd_ble_evt_get(evt.as_mut_ptr() as *mut u8, &mut len as _);
+ match Error::convert(ret) {
+ Ok(()) => on_ble_evt(&*(evt.as_ptr() as *const sd::ble_evt_t)),
+ Err(Error::NotFound) => break,
+ Err(Error::BleNotEnabled) => break,
+ Err(Error::NoMem) => depanic!("BUG: BLE_EVT_MAX_SIZE is too low"),
+ Err(err) => depanic!("sd_ble_evt_get err {:?}", err),
}
}
}
diff --git a/nrf-softdevice/src/flash.rs b/nrf-softdevice/src/flash.rs
index d161757..d8bb281 100644
--- a/nrf-softdevice/src/flash.rs
+++ b/nrf-softdevice/src/flash.rs
@@ -1,9 +1,8 @@
use core::future::Future;
-use defmt::{info, warn};
-use nrf_softdevice_s140 as sd;
-
-use crate::util::{DropBomb, Signal};
+use crate::error::Error;
+use crate::sd;
+use crate::util::*;
pub struct Flash {}
@@ -63,17 +62,17 @@ impl async_flash::Flash for Flash {
let words_len = data_len / 4;
let mut bomb = DropBomb::new();
-
let ret = unsafe { sd::sd_flash_write(address as _, words_ptr, words_len) };
- if ret != 0 {
- warn!("sd_flash_write failed: {:u32}", ret);
- bomb.defuse();
- return Err(async_flash::Error::Failed);
- }
+ let ret = match Error::convert(ret) {
+ Ok(()) => SIGNAL.wait().await,
+ Err(e) => {
+ warn!("sd_flash_write err {:?}", e);
+ Err(async_flash::Error::Failed)
+ }
+ };
- let res = SIGNAL.wait().await;
bomb.defuse();
- res
+ ret
}
}
@@ -83,19 +82,20 @@ impl async_flash::Flash for Flash {
return Err(async_flash::Error::AddressMisaligned);
}
- let mut bomb = DropBomb::new();
-
let page_number = address / Flash::PAGE_SIZE;
+
+ let mut bomb = DropBomb::new();
let ret = unsafe { sd::sd_flash_page_erase(page_number as u32) };
- if ret != 0 {
- warn!("sd_flash_page_erase failed: {:u32}", ret);
- bomb.defuse();
- return Err(async_flash::Error::Failed);
- }
+ let ret = match Error::convert(ret) {
+ Ok(()) => SIGNAL.wait().await,
+ Err(e) => {
+ warn!("sd_flash_page_erase err {:?}", e);
+ Err(async_flash::Error::Failed)
+ }
+ };
- let res = SIGNAL.wait().await;
bomb.defuse();
- res
+ ret
}
}
diff --git a/nrf-softdevice/src/interrupt.rs b/nrf-softdevice/src/interrupt.rs
index d026564..84b9aea 100644
--- a/nrf-softdevice/src/interrupt.rs
+++ b/nrf-softdevice/src/interrupt.rs
@@ -1,9 +1,8 @@
-pub use bare_metal::{CriticalSection, Mutex};
+use bare_metal::CriticalSection;
use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
use cortex_m::interrupt::InterruptNumber;
-pub use nrf52840_pac::Interrupt;
-use nrf52840_pac::{NVIC, NVIC_PRIO_BITS};
+use crate::pac::{Interrupt, NVIC, NVIC_PRIO_BITS};
const RESERVED_IRQS: [u32; 2] = [
(1 << (Interrupt::POWER_CLOCK as u8))
diff --git a/nrf-softdevice/src/lib.rs b/nrf-softdevice/src/lib.rs
index 5c7d126..2c37b55 100644
--- a/nrf-softdevice/src/lib.rs
+++ b/nrf-softdevice/src/lib.rs
@@ -6,9 +6,41 @@
pub(crate) mod util;
+// This is here so that the rest of the crate can easily use the right PAC and SD crates.
+// TODO change this dynamically based on features.
+pub(crate) use nrf52840_pac as pac;
+pub(crate) use nrf_softdevice_s140 as sd;
+
pub mod interrupt;
mod events;
pub use events::*;
mod flash;
pub use flash::*;
+mod error;
+pub use error::*;
+
+use defmt::{info, warn};
+
+unsafe extern "C" fn fault_handler(id: u32, pc: u32, info: u32) {
+ depanic!("fault_handler {:u32} {:u32} {:u32}", id, pc, info);
+}
+
+/// safety: call at most once
+pub unsafe fn enable() {
+ // TODO make this configurable via features or param
+ let clock_cfg = sd::nrf_clock_lf_cfg_t {
+ source: sd::NRF_CLOCK_LF_SRC_XTAL as u8,
+ rc_ctiv: 0,
+ rc_temp_ctiv: 0,
+ accuracy: 7,
+ };
+
+ let ret = sd::sd_softdevice_enable(&clock_cfg as _, Some(fault_handler));
+ match Error::convert(ret) {
+ Ok(()) => {}
+ Err(err) => depanic!("sd_softdevice_enable err {:?}", err),
+ }
+
+ crate::interrupt::unmask(pac::Interrupt::SWI2_EGU2);
+}
diff --git a/nrf-softdevice/src/util/mod.rs b/nrf-softdevice/src/util/mod.rs
index 3c3f802..22ca7ff 100644
--- a/nrf-softdevice/src/util/mod.rs
+++ b/nrf-softdevice/src/util/mod.rs
@@ -8,3 +8,5 @@ mod waker_store;
pub use waker_store::*;
mod drop_bomb;
pub use drop_bomb::*;
+
+pub(crate) use defmt::{info, warn};