Coder Social home page Coder Social logo

nrf-modem's Introduction

nRF-Modem

crates.io Documentation

This is a library that provides a high-level async API for the nRF9160 modem.

It can be used with any executor.

Errors and recovery

Dropping LteLink and Gnss (which also include all sockets and GnssStream) can lead to the modem staying active. There's an internal mutex that can be locked. Panicking is the only sane reaction to that. If you have a better idea, please open an issue or PR! The async deactivate function is way less likely to go wrong and you'll get a Result back so you know that something has gone wrong.

If anything does go wrong, has_runtime_state_error() will return true. Everything should stay working, but it's likely that the modem won't be properly turned off. This can be recovered by calling the reset_runtime_state() function when you've made sure nothing of the modem is used anymore.

Setup

There are a couple of things you must do to be able to use the library.

First of which, make sure to have the llvm-tools installed. This can be done using rustup component add llvm-tools-preview.

The library also needs some libc functions. The best way to import them is with tinyrlibc. As of writing the newest release is 0.3.0. This version does not include a needed API, so it's better to include the latest master branch or any newer released version.

This library has been tested with modem firmware version 1.3.4 but might work with earlier versions. When this library starts to require a newer version, then that will be seen as a breaking change. But it's easy to miss something, so this is a 'best effort' guarantee only.

Nonsecure

Nordic has made it so that the modem can only be used when in the nonsecure context. Make sure you are in that context by using e.g. the SPM.

Interrupts

The EGU1 and IPC interrupts must be routed to the modem software.

// Interrupt Handler for LTE related hardware. Defer straight to the library.
#[interrupt]
#[allow(non_snake_case)]
fn IPC() {
    nrf_modem::ipc_irq_handler();
}

let mut cp = unwrap!(cortex_m::Peripherals::take());

// Enable the modem interrupts
unsafe {
    NVIC::unmask(pac::Interrupt::IPC);
    cp.NVIC.set_priority(pac::Interrupt::IPC, 0 << 5);
}

Power

The DC/DC converter is automatically enabled for you when the library is initialized. This is required for certified operation of the modem.

Initialization

Now it's time to initialize the library. Here you can make a selection for the connectivity for the modem:

nrf_modem::init(SystemMode {
    lte_support: true,
    lte_psm_support: true,
    nbiot_support: true,
    gnss_support: true,
    preference: ConnectionPreference::None,
})
.await
.unwrap();

Now the library is ready to be used.

AT Commands

let response = nrf_modem::send_at::<64>("AT+CGMI").await.unwrap();
assert_eq!(response, "AT+CGMI\n\rNordic Semiconductor ASA\n\rOK\n\r");

DNS request

let google_ip = nrf_modem::get_host_by_name("www.google.com").await.unwrap();

Tcp connection

let stream = nrf_modem::TcpStream::connect(SocketAddr::from((google_ip, 80))).await.unwrap();

stream
    .write("GET / HTTP/1.0\nHost: google.com\r\n\r\n".as_bytes())
    .await
    .unwrap();

let mut buffer = [0; 1024];
let received = stream.receive(&mut buffer).await.unwrap();

println!("Google response: {}", core::str::from_utf8(received).unwrap());

// Drop the stream async (normal Drop is ok too, but that's blocking)
stream.deactivate().await.unwrap();

Udp socket

let socket =
    nrf_modem::UdpSocket::bind(SocketAddr::from_str("0.0.0.0:53").unwrap())
        .await
        .unwrap();

// Do a DNS request
socket
    .send_to(
        &[
            0xdb, 0x42, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77,
            0x77, 0x77, 0x0C, 0x6E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, 0x73, 0x74, 0x65, 0x72,
            0x6E, 0x03, 0x65, 0x64, 0x75, 0x00, 0x00, 0x01, 0x00, 0x01,
        ],
        SocketAddr::from_str("8.8.8.8:53").unwrap(),
    )
    .await
    .unwrap();
let (response, source_addr) = socket.receive_from(&mut buffer).await.unwrap();

println!("Result: {:X}", response);
println!("Source: {}", source_addr);

nrf-modem's People

Contributors

diondokter avatar dragonnn avatar macthestack avatar tdittr avatar dkhayes117 avatar kaffetorsk avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.