diff options
author | Dario Nieuwenhuis <dirbaio@dirbaio.net> | 2020-09-05 02:56:06 +0200 |
---|---|---|
committer | Dario Nieuwenhuis <dirbaio@dirbaio.net> | 2020-09-05 02:59:59 +0200 |
commit | 5749858daf778f4f46dee5fe6d9a1d6ebfd752f4 (patch) | |
tree | d4b9564b218a8ff2cf7c87660aeb4baf5e3c716f | |
parent | 95d648d13d5e7ff014c255a361bbc61713978892 (diff) | |
download | nrf-softdevice-5749858daf778f4f46dee5fe6d9a1d6ebfd752f4.zip |
Add Error enum. Better Event enums.
-rw-r--r-- | .vscode/settings.json | 6 | ||||
-rw-r--r-- | examples/flash/Cargo.toml | 2 | ||||
-rw-r--r-- | nrf-softdevice/Cargo.toml | 1 | ||||
-rw-r--r-- | nrf-softdevice/src/error.rs | 74 | ||||
-rw-r--r-- | nrf-softdevice/src/events.rs | 189 | ||||
-rw-r--r-- | nrf-softdevice/src/flash.rs | 42 | ||||
-rw-r--r-- | nrf-softdevice/src/interrupt.rs | 5 | ||||
-rw-r--r-- | nrf-softdevice/src/lib.rs | 32 | ||||
-rw-r--r-- | nrf-softdevice/src/util/mod.rs | 2 |
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}; |