Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf9151 preview #23

Merged
merged 11 commits into from
Aug 9, 2024
15 changes: 11 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,32 @@ description = "Async modem api for the nRF9160"
homepage = "https://github.com/diondokter/nrf-modem"
repository = "https://github.com/diondokter/nrf-modem"
readme = "README.md"
keywords = ["nRF9160", "LTE", "GPS", "NB-IoT", "embedded"]
keywords = ["nRF9160", "nRF9151", "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.4.2"
nrfxlib-sys = "2.7.0"
nerwalt marked this conversation as resolved.
Show resolved Hide resolved

futures = { version = "0.3.24", default-features = false, features = ["async-await"] }
num_enum = { version = "0.7.0", default-features = false }
defmt = { version = "0.3", optional = true }
cortex-m = "0.7"
linked_list_allocator = { version="0.10.1", default-features=false, features=["use_spin"] }
nrf9160-pac = "0.12.2"
arrayvec = { version = "0.7", default-features = false }
nrf9160-pac = { version = "0.12.2", optional = true }
nrf9120-pac = { version = "0.12.2", optional = true }
at-commands = "0.5.2"
no-std-net = "0.6.0"
critical-section = "1.1"
embassy-sync = "0.6.0"
grounded = "0.2.0"

[features]
default = []
default = ["nrf9160"]
defmt = ["dep:defmt", "at-commands/defmt"]

nrf9160 = ["nrfxlib-sys/nrf9160", "dep:nrf9160-pac"]
nrf9151 = ["nrf9120"]
nrf9161 = ["nrf9120"]
nrf9120 = ["nrfxlib-sys/nrf9120", "dep:nrf9120-pac"]
4 changes: 2 additions & 2 deletions src/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ pub async fn get_host_by_name_with_cancellation(
while !result_iter.is_null() && found_ip.is_none() {
let address = (*result_iter).ai_addr;

if (*address).sa_family == nrfxlib_sys::NRF_AF_INET as i32 {
if (*address).sa_family == nrfxlib_sys::NRF_AF_INET as u16 {
let dns_addr: &nrfxlib_sys::nrf_sockaddr_in =
&*(address as *const nrfxlib_sys::nrf_sockaddr_in);

let socket_addr: SocketAddr = NrfSockAddr::from(*dns_addr).into();
found_ip = Some(socket_addr.ip());
} else if (*address).sa_family == nrfxlib_sys::NRF_AF_INET6 as i32 {
} else if (*address).sa_family == nrfxlib_sys::NRF_AF_INET6 as u16 {
let dns_addr: &nrfxlib_sys::nrf_sockaddr_in6 =
&*(address as *const nrfxlib_sys::nrf_sockaddr_in6);

Expand Down
59 changes: 51 additions & 8 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

use core::sync::atomic::{AtomicBool, AtomicU32, Ordering};

#[cfg(feature = "nrf9160")]
use nrf9160_pac as pac;

#[cfg(feature = "nrf9120")]
use nrf9120_pac as pac;

/// Number of IPC configurations in `NrfxIpcConfig`
const IPC_CONF_NUM: usize = 8;

Expand Down Expand Up @@ -103,7 +109,7 @@ pub fn get_last_error() -> isize {
#[no_mangle]
pub extern "C" fn nrf_modem_os_busywait(usec: i32) {
if usec > 0 {
// NRF9160 runs at 64 MHz, so this is close enough
// The nRF91* Arm Cortex-M33 runs at 64 MHz, so this is close enough
cortex_m::asm::delay((usec as u32) * 64);
}
}
Expand Down Expand Up @@ -206,7 +212,7 @@ pub unsafe extern "C" fn nrf_modem_os_shm_tx_free(ptr: *mut u8) {
pub unsafe extern "C" fn nrfx_ipc_config_load(p_config: *const NrfxIpcConfig) {
let config: &NrfxIpcConfig = &*p_config;

let ipc = &(*nrf9160_pac::IPC_NS::ptr());
let ipc = &(*pac::IPC_NS::ptr());

for (i, value) in config.send_task_config.iter().enumerate() {
ipc.send_cnf[i].write(|w| w.bits(*value));
Expand Down Expand Up @@ -235,7 +241,7 @@ pub extern "C" fn nrfx_ipc_init(
p_context: usize,
) -> NrfxErr {
use cortex_m::interrupt::InterruptNumber;
let irq = nrf9160_pac::Interrupt::IPC;
let irq = pac::Interrupt::IPC;
let irq_num = usize::from(irq.number());
unsafe {
cortex_m::peripheral::NVIC::unmask(irq);
Expand All @@ -250,7 +256,7 @@ pub extern "C" fn nrfx_ipc_init(
/// Function for uninitializing the IPC module.
#[no_mangle]
pub extern "C" fn nrfx_ipc_uninit() {
let ipc = unsafe { &(*nrf9160_pac::IPC_NS::ptr()) };
let ipc = unsafe { &(*pac::IPC_NS::ptr()) };

for i in 0..IPC_CONF_NUM {
ipc.send_cnf[i].reset();
Expand All @@ -265,14 +271,14 @@ pub extern "C" fn nrfx_ipc_uninit() {

#[no_mangle]
pub extern "C" fn nrfx_ipc_receive_event_enable(event_index: u8) {
let ipc = unsafe { &(*nrf9160_pac::IPC_NS::ptr()) };
let ipc = unsafe { &(*pac::IPC_NS::ptr()) };
ipc.inten
.modify(|r, w| unsafe { w.bits(r.bits() | 1 << event_index) })
}

#[no_mangle]
pub extern "C" fn nrfx_ipc_receive_event_disable(event_index: u8) {
let ipc = unsafe { &(*nrf9160_pac::IPC_NS::ptr()) };
let ipc = unsafe { &(*pac::IPC_NS::ptr()) };
ipc.inten
.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << event_index)) })
}
Expand Down Expand Up @@ -337,7 +343,7 @@ unsafe fn generic_free(ptr: *mut u8, heap: &crate::WrappedHeap) {
// 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();
let events_map = (*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);
Expand All @@ -356,7 +362,7 @@ pub unsafe fn nrf_ipc_irq_handler() {
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));
(*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
if let Some(handler) = handler {
Expand Down Expand Up @@ -517,3 +523,40 @@ struct Semaphore {
pub extern "C" fn nrf_modem_os_is_in_isr() -> bool {
cortex_m::peripheral::SCB::vect_active() != cortex_m::peripheral::scb::VectActive::ThreadMode
}

// This function is called by the library to allocate and initialize a mutex.
// Required action:
// Allocate and initialize a mutex.
// If the address of an already allocated mutex is provided as an input, the allocation part is skipped and the mutex is only reinitialized.
// Note
// Mutexes are not required if multithreaded access to modem functionalities is not needed. In this case, the function must blindly return 0.
#[no_mangle]
pub unsafe extern "C" fn nrf_modem_os_mutex_init() -> i32 {
// TODO FIXME
0
}

// This function is called by the library to lock a mutex.
#[no_mangle]
pub unsafe extern "C" fn nrf_modem_os_mutex_lock() -> i32 {
// TODO FIXME
0
}

// This function is called by the library to unlock a mutex.
#[no_mangle]
pub unsafe extern "C" fn nrf_modem_os_mutex_unlock() {
// TODO FIXME
}

// This function is called by the library to output logs. This function can be called in an interrupt context.
#[no_mangle]
pub unsafe extern "C" fn nrf_modem_os_log() {
// TODO FIXME
}

// This function is called by the library to dump binary data. This function can be called in an interrupt context.
#[no_mangle]
pub unsafe extern "C" fn nrf_modem_os_logdump() {
// TODO FIXME
}
8 changes: 4 additions & 4 deletions src/gnss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ enum GnssEventType {
/// NMEA event.
Nmea = nrfxlib_sys::NRF_MODEM_GNSS_EVT_NMEA,
/// Need new APGS data event.
AgpsRequest = nrfxlib_sys::NRF_MODEM_GNSS_EVT_AGPS_REQ,
AgpsRequest = nrfxlib_sys::NRF_MODEM_GNSS_EVT_AGNSS_REQ,
/// GNSS is blocked by LTE event.
BlockedByLte = nrfxlib_sys::NRF_MODEM_GNSS_EVT_BLOCKED,
/// GNSS is unblocked by LTE event.
Expand Down Expand Up @@ -374,7 +374,7 @@ pub enum GnssPowerSaveMode {
enum GnssDataType {
PositionVelocityTime = nrfxlib_sys::NRF_MODEM_GNSS_DATA_PVT,
Nmea = nrfxlib_sys::NRF_MODEM_GNSS_DATA_NMEA,
Agps = nrfxlib_sys::NRF_MODEM_GNSS_DATA_AGPS_REQ,
Agps = nrfxlib_sys::NRF_MODEM_GNSS_DATA_AGNSS_REQ,
}

/// An enum containing all possible GNSS data types
Expand All @@ -385,7 +385,7 @@ pub enum GnssData {
/// An NMEA string
Nmea(ArrayString<83>),
/// An assisted gps data frame
Agps(nrfxlib_sys::nrf_modem_gnss_agps_data_frame),
Agps(nrfxlib_sys::nrf_modem_gnss_agnss_data_frame),
}

impl GnssData {
Expand Down Expand Up @@ -435,7 +435,7 @@ impl GnssData {
unsafe {
nrfxlib_sys::nrf_modem_gnss_read(
data.as_mut_ptr() as *mut _,
size_of::<nrfxlib_sys::nrf_modem_gnss_agps_data_frame>() as i32,
size_of::<nrfxlib_sys::nrf_modem_gnss_agnss_data_frame>() as i32,
data_type as u32 as _,
)
.into_result()?;
Expand Down
16 changes: 8 additions & 8 deletions src/ip.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::socket::SocketFamily;
use core::mem::size_of;
// use core::mem::size_of;
use no_std_net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use nrfxlib_sys::{nrf_sockaddr, nrf_sockaddr_in, nrf_sockaddr_in6};

Expand All @@ -12,22 +12,22 @@ impl From<SocketAddr> for NrfSockAddr {
fn from(addr: SocketAddr) -> Self {
match addr {
SocketAddr::V4(addr) => nrf_sockaddr_in {
sin_len: size_of::<nrf_sockaddr_in>() as u8,
sin_family: SocketFamily::Ipv4 as u32,
// sin_len: size_of::<nrf_sockaddr_in>() as u8,
sin_family: SocketFamily::Ipv4 as u16,
sin_port: addr.port().to_be(),
sin_addr: nrfxlib_sys::nrf_in_addr {
s_addr: u32::to_be((*addr.ip()).into()),
},
}
.into(),
SocketAddr::V6(addr) => nrf_sockaddr_in6 {
sin6_len: size_of::<nrf_sockaddr_in6>() as u8,
sin6_family: SocketFamily::Ipv6 as u32,
// sin6_len: size_of::<nrf_sockaddr_in6>() as u8,
sin6_family: SocketFamily::Ipv6 as u16,
sin6_port: addr.port().to_be(),
sin6_addr: nrfxlib_sys::nrf_in6_addr {
s6_addr: addr.ip().octets(),
},
sin6_flowinfo: 0,
// sin6_flowinfo: 0,
sin6_scope_id: 0,
}
.into(),
Expand All @@ -54,8 +54,8 @@ impl From<NrfSockAddr> for SocketAddr {

impl From<*const nrf_sockaddr> for NrfSockAddr {
fn from(v: *const nrf_sockaddr) -> Self {
const IPV4: i32 = SocketFamily::Ipv4 as u32 as i32;
const IPV6: i32 = SocketFamily::Ipv6 as u32 as i32;
const IPV4: u16 = SocketFamily::Ipv4 as u16;
const IPV6: u16 = SocketFamily::Ipv6 as u16;

unsafe {
match (*v).sa_family {
Expand Down
30 changes: 22 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ pub use sms::*;
pub use tcp_stream::*;
pub use udp_socket::*;

#[cfg(feature = "nrf9160")]
use nrf9160_pac as pac;

#[cfg(feature = "nrf9120")]
use nrf9120_pac as pac;

/// We need to wrap our heap so it's creatable at run-time and accessible from an ISR.
///
/// * The Mutex allows us to safely share the heap between interrupt routines
Expand Down Expand Up @@ -88,9 +94,10 @@ pub async fn init_with_custom_layout(
if !SHARED_MEMORY_RANGE.contains(&memory_layout.base_address) {
return Err(Error::BadMemoryLayout);
}

if !SHARED_MEMORY_RANGE.contains(
&(memory_layout.base_address
+ nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE
+ nrfxlib_sys::NRF_MODEM_CELLULAR_SHMEM_CTRL_SIZE
+ memory_layout.tx_area_size
+ memory_layout.rx_area_size
+ memory_layout.trace_area_size
Expand All @@ -102,7 +109,7 @@ pub async fn init_with_custom_layout(

// The modem is only certified when the DC/DC converter is enabled and it isn't by default
unsafe {
(*nrf9160_pac::REGULATORS_NS::PTR)
(*pac::REGULATORS_NS::PTR)
.dcdcen
.modify(|_, w| w.dcdcen().enabled());
}
Expand All @@ -125,28 +132,29 @@ pub async fn init_with_custom_layout(
shmem: nrfxlib_sys::nrf_modem_shmem_cfg {
ctrl: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_1 {
base: memory_layout.base_address,
size: nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE,
size: nrfxlib_sys::NRF_MODEM_CELLULAR_SHMEM_CTRL_SIZE,
},
tx: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_2 {
base: memory_layout.base_address + nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE,
base: memory_layout.base_address + nrfxlib_sys::NRF_MODEM_CELLULAR_SHMEM_CTRL_SIZE,
size: memory_layout.tx_area_size,
},
rx: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_3 {
base: memory_layout.base_address
+ nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE
+ nrfxlib_sys::NRF_MODEM_CELLULAR_SHMEM_CTRL_SIZE
+ memory_layout.tx_area_size,
size: memory_layout.rx_area_size,
},
trace: nrfxlib_sys::nrf_modem_shmem_cfg__bindgen_ty_4 {
base: memory_layout.base_address
+ nrfxlib_sys::NRF_MODEM_SHMEM_CTRL_SIZE
+ nrfxlib_sys::NRF_MODEM_CELLULAR_SHMEM_CTRL_SIZE
+ memory_layout.tx_area_size
+ memory_layout.rx_area_size,
size: memory_layout.trace_area_size,
},
},
ipc_irq_prio: 0,
diondokter marked this conversation as resolved.
Show resolved Hide resolved
ipc_irq_prio: 1,
fault_handler: Some(modem_fault_handler),
dfu_handler: Some(modem_dfu_handler),
};

critical_section::with(|_| unsafe { PARAMS.get().write(params) });
Expand Down Expand Up @@ -231,6 +239,11 @@ unsafe extern "C" fn modem_fault_handler(_info: *mut nrfxlib_sys::nrf_modem_faul
);
}

unsafe extern "C" fn modem_dfu_handler(_val: u32) {
#[cfg(feature = "defmt")]
defmt::trace!("Modem DFU handler");
}

/// IPC code now lives outside `lib_modem`, so call our IPC handler function.
pub fn ipc_irq_handler() {
unsafe {
Expand All @@ -239,7 +252,7 @@ pub fn ipc_irq_handler() {
cortex_m::asm::sev();
}

/// Identifies which radios in the nRF9160 should be active
/// Identifies which radios in the nRF91* SiP should be active
///
/// Based on: <https://infocenter.nordicsemi.com/index.jsp?topic=%2Fref_at_commands%2FREF%2Fat_commands%2Fmob_termination_ctrl_status%2Fcfun.html>
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -321,6 +334,7 @@ impl SystemMode {
///
/// Works on the nRF9160-DK (PCA10090NS) and Actinius Icarus. Other PCBs may
/// use different MAGPIO pins to control the GNSS switch.
#[cfg(feature = "nrf9160")]
pub async fn configure_gnss_on_pca10090ns() -> Result<(), Error> {
#[cfg(feature = "defmt")]
defmt::debug!("Configuring XMAGPIO pins for 1574-1577 MHz");
Expand Down
2 changes: 1 addition & 1 deletion src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ impl Socket {
0 if !buffer.is_empty() => Poll::Ready(Err(Error::Disconnected)),
NRF_ENOTCONN => Poll::Ready(Err(Error::Disconnected)),
bytes_received @ 0.. => Poll::Ready(Ok((bytes_received as usize, {
unsafe { (*socket_addr_ptr).sa_family = self.family as u32 as i32 }
unsafe { (*socket_addr_ptr).sa_family = self.family as u16 }
NrfSockAddr::from(socket_addr_ptr as *const _).into()
}))),
NRF_EWOULDBLOCK => Poll::Pending,
Expand Down
Loading