Skip to content

Commit

Permalink
Merge pull request #17 from tdittr/update-nrfxlib
Browse files Browse the repository at this point in the history
Update nrfxlib to 2.4.2
  • Loading branch information
diondokter authored Sep 7, 2023
2 parents 1498d28 + a5328cc commit 4b7101b
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 106 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,5 @@ jobs:
components: clippy, rustfmt, llvm-tools-preview
targets: thumbv8m.main-none-eabihf

- run: cargo install cargo-binutils
- run: cargo fmt -- --check
- run: cargo clippy --target thumbv8m.main-none-eabihf
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.4.0 (2023-09-07)

- Update nrfxlib-sys to 2.4.2, removing the need for the `EGU1` interrupt

## 0.3.4 (05-09-23)

- Fixed issue where LTE link waiting couldn't be cancelled
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nrf-modem"
version = "0.3.4"
version = "0.4.0"
edition = "2021"
rust-version = "1.64"
license = "MIT OR Apache-2.0"
Expand All @@ -13,7 +13,7 @@ keywords = ["nRF9160", "LTE", "GPS", "NB-IoT", "embedded"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
nrfxlib-sys = "2.1.0"
nrfxlib-sys = "2.4.2"
futures = { version = "0.3.24", default-features = false, features = ["async-await"] }
num_enum = { version = "0.6.1", default-features = false }
defmt = { version = "0.3.2", optional = true }
Expand Down
10 changes: 0 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ Make sure you are in that context by using e.g. the SPM.
The `EGU1` and `IPC` interrupts must be routed to the modem software.

```rust,ignore
// Interrupt Handler for LTE related hardware. Defer straight to the library.
#[interrupt]
#[allow(non_snake_case)]
fn EGU1() {
nrf_modem::application_irq_handler();
cortex_m::asm::sev();
}
// Interrupt Handler for LTE related hardware. Defer straight to the library.
#[interrupt]
#[allow(non_snake_case)]
Expand All @@ -63,9 +55,7 @@ let mut cp = unwrap!(cortex_m::Peripherals::take());
// Enable the modem interrupts
unsafe {
NVIC::unmask(pac::Interrupt::EGU1);
NVIC::unmask(pac::Interrupt::IPC);
cp.NVIC.set_priority(pac::Interrupt::EGU1, 4 << 5);
cp.NVIC.set_priority(pac::Interrupt::IPC, 0 << 5);
}
```
Expand Down
16 changes: 11 additions & 5 deletions src/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ static AT_DATA_WAKER: AtomicWaker = AtomicWaker::new();

/// The callback that will be called by nrfxlib when the at command has a response.
/// The `resp` is a null-terminated string.
unsafe extern "C" fn at_callback(resp: *const u8) {
unsafe extern "C" fn at_callback(resp: *const core::ffi::c_char) {
let resp = resp as *const u8;

#[cfg(feature = "defmt")]
defmt::trace!(
"AT <- {}",
Expand Down Expand Up @@ -102,7 +104,7 @@ pub fn send_at_blocking<const CAP: usize>(command: &str) -> Result<ArrayString<C
nrfxlib_sys::nrf_modem_at_cmd(
buffer.as_mut_ptr() as _,
buffer.len(),
b"%.*s\0".as_ptr(),
b"%.*s\0".as_ptr() as *const core::ffi::c_char,
command.len(),
command.as_ptr(),
)
Expand All @@ -114,8 +116,12 @@ pub fn send_at_blocking<const CAP: usize>(command: &str) -> Result<ArrayString<C
return_string
} else {
unsafe {
nrfxlib_sys::nrf_modem_at_printf(b"%.*s\0".as_ptr(), command.len(), command.as_ptr())
.into_result()?;
nrfxlib_sys::nrf_modem_at_printf(
b"%.*s\0".as_ptr() as *const core::ffi::c_char,
command.len(),
command.as_ptr(),
)
.into_result()?;
}

ArrayString::new()
Expand Down Expand Up @@ -169,7 +175,7 @@ impl<'c, const CAP: usize> Future for SendATFuture<'c, CAP> {
let result = unsafe {
nrfxlib_sys::nrf_modem_at_cmd_async(
Some(at_callback),
b"%.*s\0".as_ptr(),
b"%.*s\0".as_ptr() as *const core::ffi::c_char,
self.command.len(),
self.command.as_ptr(),
)
Expand Down
4 changes: 3 additions & 1 deletion src/at_notifications.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use critical_section::Mutex;
static WAKER_NODE_LIST: Mutex<RefCell<WakerNodeList<dyn NotificationBuffer>>> =
Mutex::new(RefCell::new(WakerNodeList::new()));

pub(crate) unsafe extern "C" fn at_notification_handler(notif: *const u8) {
pub(crate) unsafe extern "C" fn at_notification_handler(notif: *const core::ffi::c_char) {
let notif = notif as *const u8;

#[cfg(feature = "defmt")]
defmt::trace!(
"AT notification <- {}",
Expand Down
2 changes: 1 addition & 1 deletion src/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub async fn get_host_by_name_with_cancellation(
hostname.push('\0');

let err = nrfxlib_sys::nrf_getaddrinfo(
hostname.as_ptr(),
hostname.as_ptr() as *const core::ffi::c_char,
core::ptr::null(),
&hints as *const _,
&mut result as *mut *mut _,
Expand Down
103 changes: 38 additions & 65 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ pub struct NrfxIpcConfig {
}

/// IPC callback function type
type NrfxIpcHandler = extern "C" fn(event_mask: u32, ptr: *mut u8);
// based on https://github.com/NordicSemiconductor/nrfx/blob/98d6f433313a3d8dcf08dce25e744617b45aa913/drivers/include/nrfx_ipc.h#L56
type NrfxIpcHandler = extern "C" fn(event_idx: u8, ptr: *mut u8);

/// IPC error type
#[repr(u32)]
Expand Down Expand Up @@ -75,33 +76,15 @@ static IPC_CONTEXT: core::sync::atomic::AtomicUsize = core::sync::atomic::Atomic
/// Remembers the IPC handler function we were given
static IPC_HANDLER: core::sync::atomic::AtomicUsize = core::sync::atomic::AtomicUsize::new(0);

/// Function required by BSD library. We need to set the EGU1 interrupt.
#[no_mangle]
pub extern "C" fn nrf_modem_os_application_irq_set() {
cortex_m::peripheral::NVIC::pend(nrf9160_pac::Interrupt::EGU1);
}

/// Function required by BSD library. We need to clear the EGU1 interrupt.
#[no_mangle]
pub extern "C" fn nrf_modem_os_application_irq_clear() {
cortex_m::peripheral::NVIC::unpend(nrf9160_pac::Interrupt::EGU1);
}

/// Function required by BSD library. We need to set the EGU2 interrupt.
#[no_mangle]
pub extern "C" fn nrf_modem_os_trace_irq_set() {
cortex_m::peripheral::NVIC::pend(nrf9160_pac::Interrupt::EGU2);
}

/// Function required by BSD library. We need to clear the EGU2 interrupt.
/// Function required by BSD library. We have no init to do.
#[no_mangle]
pub extern "C" fn nrf_modem_os_trace_irq_clear() {
cortex_m::peripheral::NVIC::unpend(nrf9160_pac::Interrupt::EGU2);
pub extern "C" fn nrf_modem_os_init() {
// Nothing
}

/// Function required by BSD library. We have no init to do.
/// Function required by BSD library. We have no shutdown to do.
#[no_mangle]
pub extern "C" fn nrf_modem_os_init() {
pub extern "C" fn nrf_modem_os_shutdown() {
// Nothing
}

Expand Down Expand Up @@ -177,19 +160,6 @@ pub extern "C" fn nrf_modem_os_event_notify() {
NOTIFY_ACTIVE.store(true, Ordering::SeqCst);
}

/// Function required by BSD library
#[no_mangle]
pub extern "C" fn nrf_modem_os_trace_put(_data: *const u8, _len: u32) -> i32 {
// Do nothing
0
}

/// Function required by BSD library
#[no_mangle]
pub extern "C" fn nrf_modem_irrecoverable_error_handler(err: u32) -> ! {
panic!("bsd_irrecoverable_error_handler({})", err);
}

/// The Modem library needs to dynamically allocate memory (a heap) for proper
/// functioning. This memory is used to store the internal data structures that
/// are used to manage the communication between the application core and the
Expand Down Expand Up @@ -229,16 +199,6 @@ pub unsafe extern "C" fn nrf_modem_os_shm_tx_free(ptr: *mut u8) {
generic_free(ptr, &crate::TX_ALLOCATOR);
}

#[no_mangle]
pub extern "C" fn nrf_modem_os_trace_alloc(_bytes: usize) -> *mut u8 {
unimplemented!()
}

#[no_mangle]
pub extern "C" fn nrf_modem_os_trace_free(_mem: *mut u8) {
unimplemented!()
}

/// @brief Function for loading configuration directly into IPC peripheral.
///
/// @param p_config Pointer to the structure with the initial configuration.
Expand All @@ -260,7 +220,6 @@ pub unsafe extern "C" fn nrfx_ipc_config_load(p_config: *const NrfxIpcConfig) {
.write(|w| w.bits(config.receive_events_enabled));
}

///
/// @brief Function for initializing the IPC driver.
///
/// @param irq_priority Interrupt priority.
Expand Down Expand Up @@ -374,23 +333,39 @@ unsafe fn generic_free(ptr: *mut u8, heap: &crate::WrappedHeap) {

/// Call this when we have an IPC IRQ. Not `extern C` as its not called by the
/// library, only our interrupt handler code.
// This function seems to be based on this verion in C:
// https://github.com/NordicSemiconductor/nrfx/blob/98d6f433313a3d8dcf08dce25e744617b45aa913/drivers/src/nrfx_ipc.c#L146-L163
pub unsafe fn nrf_ipc_irq_handler() {
// Get the information about events that fired this interrupt
let events_map = (*nrf9160_pac::IPC_NS::ptr()).intpend.read().bits();

// Fetch interrupt handler and context to use during event resolution
let handler_addr = IPC_HANDLER.load(core::sync::atomic::Ordering::SeqCst);
let handler = if handler_addr != 0 {
let handler = core::mem::transmute::<usize, NrfxIpcHandler>(handler_addr);
Some(handler)
} else {
#[cfg(feature = "defmt")]
defmt::warn!("No IPC handler registered");
None
};
let context = IPC_CONTEXT.load(core::sync::atomic::Ordering::SeqCst);

// Clear these events
let mut bitmask = events_map;
while bitmask != 0 {
let event_idx = bitmask.trailing_zeros();
bitmask &= !(1 << event_idx);
(*nrf9160_pac::IPC_NS::ptr()).events_receive[event_idx as usize].write(|w| w.bits(0));
}

// Execute interrupt handler to provide information about events to app
let handler_addr = IPC_HANDLER.load(core::sync::atomic::Ordering::SeqCst);
let handler = core::mem::transmute::<usize, NrfxIpcHandler>(handler_addr);
let context = IPC_CONTEXT.load(core::sync::atomic::Ordering::SeqCst);
(handler)(events_map, context as *mut u8);
// Execute interrupt handler to provide information about events to app
if let Some(handler) = handler {
let event_idx = event_idx
.try_into()
.expect("A u32 has less then 255 trailing zeroes");
(handler)(event_idx, context as *mut u8);
}
}
}

/// Initialize a semaphore.
Expand All @@ -407,10 +382,10 @@ pub unsafe fn nrf_ipc_irq_handler() {
/// - 0 on success, a negative errno otherwise.
#[no_mangle]
pub unsafe extern "C" fn nrf_modem_os_sem_init(
sem: *mut *mut nrfxlib_sys::ctypes::c_void,
initial_count: nrfxlib_sys::ctypes::c_uint,
limit: nrfxlib_sys::ctypes::c_uint,
) -> nrfxlib_sys::ctypes::c_int {
sem: *mut *mut core::ffi::c_void,
initial_count: core::ffi::c_uint,
limit: core::ffi::c_uint,
) -> core::ffi::c_int {
if sem.is_null() || initial_count > limit {
return -(nrfxlib_sys::NRF_EINVAL as i32);
}
Expand Down Expand Up @@ -442,7 +417,7 @@ pub unsafe extern "C" fn nrf_modem_os_sem_init(
/// **Parameters**
/// - sem – The semaphore.
#[no_mangle]
pub extern "C" fn nrf_modem_os_sem_give(sem: *mut nrfxlib_sys::ctypes::c_void) {
pub extern "C" fn nrf_modem_os_sem_give(sem: *mut core::ffi::c_void) {
unsafe {
if sem.is_null() {
return;
Expand Down Expand Up @@ -471,9 +446,9 @@ pub extern "C" fn nrf_modem_os_sem_give(sem: *mut nrfxlib_sys::ctypes::c_void) {
/// - -NRF_EAGAIN – If the semaphore could not be taken.
#[no_mangle]
pub extern "C" fn nrf_modem_os_sem_take(
sem: *mut nrfxlib_sys::ctypes::c_void,
mut timeout: nrfxlib_sys::ctypes::c_int,
) -> nrfxlib_sys::ctypes::c_int {
sem: *mut core::ffi::c_void,
mut timeout: core::ffi::c_int,
) -> core::ffi::c_int {
unsafe {
if sem.is_null() {
return -(nrfxlib_sys::NRF_EAGAIN as i32);
Expand Down Expand Up @@ -520,9 +495,7 @@ pub extern "C" fn nrf_modem_os_sem_take(
/// **Returns**
/// - Current semaphore count.
#[no_mangle]
pub extern "C" fn nrf_modem_os_sem_count_get(
sem: *mut nrfxlib_sys::ctypes::c_void,
) -> nrfxlib_sys::ctypes::c_uint {
pub extern "C" fn nrf_modem_os_sem_count_get(sem: *mut core::ffi::c_void) -> core::ffi::c_uint {
unsafe {
if sem.is_null() {
return 0;
Expand Down
2 changes: 1 addition & 1 deletion src/gnss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ impl GnssData {
)
.into_result()?;

let data = data.assume_init().nmea_str;
let data = core::mem::transmute(data.assume_init().nmea_str); // Make data be u8
let mut string_data = ArrayString::from_byte_string(&data)?;
string_data.truncate(
string_data
Expand Down
24 changes: 9 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,22 +93,25 @@ pub async fn init(mode: SystemMode) -> Result<(), Error> {
// At start of shared memory (see memory.x)
base: 0x2001_0000,
// This is the amount specified in the NCS 1.5.1 release.
size: 0x0000_04e8,
size: nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE,
},
tx: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_2 {
// Follows on from control buffer
base: 0x2001_04e8,
base: 0x2001_0000 + nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE,
// This is the amount specified in the NCS 1.5.1 release.
size: 0x0000_2000,
},
rx: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_3 {
// Follows on from TX buffer
base: 0x2001_24e8,
base: 0x2001_0000 + nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE + 0x2000,
// This is the amount specified in the NCS 1.5.1 release.
size: 0x0000_2000,
},
// No trace info
trace: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_4 { base: 0, size: 0 },
trace: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_4 {
base: 0x2001_0000,
size: 0,
},
},
ipc_irq_prio: 0,
fault_handler: Some(modem_fault_handler),
Expand All @@ -125,8 +128,7 @@ pub async fn init(mode: SystemMode) -> Result<(), Error> {
}

// OK, let's start the library
unsafe { nrfxlib_sys::nrf_modem_init(&params, nrfxlib_sys::nrf_modem_mode_NORMAL_MODE) }
.into_result()?;
unsafe { nrfxlib_sys::nrf_modem_init(&params) }.into_result()?;

// Initialize AT notifications
at_notifications::initialize()?;
Expand Down Expand Up @@ -166,19 +168,11 @@ unsafe extern "C" fn modem_fault_handler(_info: *mut nrfxlib_sys::nrf_modem_faul
);
}

/// You must call this when an EGU1 interrupt occurs.
pub fn application_irq_handler() {
unsafe {
nrfxlib_sys::nrf_modem_application_irq_handler();
nrfxlib_sys::nrf_modem_os_event_notify();
}
}

/// IPC code now lives outside `lib_modem`, so call our IPC handler function.
pub fn ipc_irq_handler() {
unsafe {
crate::ffi::nrf_ipc_irq_handler();
nrfxlib_sys::nrf_modem_os_event_notify();
nrfxlib_sys::nrf_modem_os_event_notify(0);
crate::socket::wake_sockets();
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,12 +601,12 @@ impl<'a> SocketOption<'a> {
}
}

pub(crate) fn get_value(&self) -> *const nrfxlib_sys::ctypes::c_void {
pub(crate) fn get_value(&self) -> *const core::ffi::c_void {
match self {
SocketOption::TlsHostName(s) => s.as_ptr() as *const nrfxlib_sys::ctypes::c_void,
SocketOption::TlsPeerVerify(x) => x as *const _ as *const nrfxlib_sys::ctypes::c_void,
SocketOption::TlsSessionCache(x) => x as *const _ as *const nrfxlib_sys::ctypes::c_void,
SocketOption::TlsTagList(x) => x.as_ptr() as *const nrfxlib_sys::ctypes::c_void,
SocketOption::TlsHostName(s) => s.as_ptr() as *const core::ffi::c_void,
SocketOption::TlsPeerVerify(x) => x as *const _ as *const core::ffi::c_void,
SocketOption::TlsSessionCache(x) => x as *const _ as *const core::ffi::c_void,
SocketOption::TlsTagList(x) => x.as_ptr() as *const core::ffi::c_void,
}
}

Expand Down

0 comments on commit 4b7101b

Please sign in to comment.