LoRaWAN with NXP LPC55S16 and ARM Cortex-M33

LoRaWAN is getting more an more popular, both for terrestrial and increasingly with low-orbit satellite systems. The ‘Long Range’ in ‘LoRa’ makes it an ideal solution for low-power and low data rate applications. For a university research project we selected the Semtech SX1261/62 transceiver together with the NXP LPC55S16 mikrocontroller. Because the board used for that project is not available for the public (yet), I share here how you can run the LoRaWAN stack with the NXP LPC55S16-EVK.

LoRaWAN with Semtech SX126x and NXP LPC55S16

In that research project completed by my master student Diego Bienz, devices are located in remote rural areas and do not always have connection to a terrestrial gateway. So they are able to communicate to LEO (Low Earth Orbit) satellites using the Semtech SX1262 transceiver.

Tardigrade board (Courtesy of Diego Bienz)

The project uses the NXP LPC55S16 because of its security and low power capabilities.


Because of the current silicon shortage, the MCU is hard to get. But luckily some EVKs and evaluation boards are still available, so the LoRaWAN stack ported for this project can run on hardware still available. Unless this article now lets everyone rush ordering the last boards ;-).

Here is what you need:

  • NXP LPC55S16-EVK (ARM Cortex-M33, 150 MHz, 256 KByte Flash, 96 KByte SRAM)
  • SX1261MB2xAS shield (868 MHz, Mouser 947-SX1261MB2BAS).
Semtech SX1261 with NXP LPC55S16-EVK

The SX1262DVK1DAS is supported too, but more expensive:

Semtech SX1262 with NXP LPC55S16-EVK

The boards do not need any special configuration or settings.


The project is based on the official Semtech LoRaMac-node code base from GitHub. The Semtech HAL interface has been ported to the MCUXpresso SDK and the project has been created for the Eclipse based NXP MCUXpresso IDE:

MCUXpresso IDE

The project uses build configurations to switch between different Semtech transceiver and demo applications:

Build Configuration in Eclipse

Additionally it takes advantage of the Pins and Clocks tools, making it easier to port to a different mikrocontroller:

Clocks Tool
Pins Tool

All the integration with the NXP MCUXpresso SDK is done inside the LPC55S16-EVK board folder, and can be used as a base for any other NXP boards:

The stack can be run bare-metal or with using FreeRTOS. Switching is done with a define in a configuration header file:

FreeRTOS or bare-metal mode setting

The project includes UART and SEGGER RTT support:

UART and SEGGER RTT support

The port includes a non-volatile memory storage using the on-chip FLASH memory. The implementation has been very tricky, because the FLASH memory of the LPC55Sxx

The McuFlash module and command line interface is used for maintenance and or inspection of the FLASH memory. Additionally the MinINI module is integrated, so settings can be stored as key-value pairs in FLASH too.

LoRaWAN Device Integration

With the latest TheThingsNetwork changes and LoRaWAN stack, many existing tutorials do not work any more. So here is how to setup a device:

Create your application and end device using the console on https://www.thethingsnetwork.org/.

Manually register your end device:

Manually register end device

Important are the DevEUI, AppKey and NwkKey which we will need to store on the device itself:

LoRaWAN device settings

Enter these values into the se-identity.h file as below:

se-identity.h file

With this, the device shall be able to connect to the network, as shown below for the ‘periodic-uplink’ app:


There seems to be very few LoRaWAN applications and examples for NXP devices: even less taking advantage of the MCUXpresso tools. Which is a pity, because especially the LPC55Sxx devices are vary capable. The integration with FreeRTOS and the MCUXpresso SDK is not easy, especially the LPC55Sxx FLASH architecture for the storage is challenging, but very doable. I hope this example and port is useful, and LoRaWAN is used on more and more devices. All the sources are available on GitHub (see links below).

Happy LoRaWANing 🙂

8 thoughts on “LoRaWAN with NXP LPC55S16 and ARM Cortex-M33

  1. Good day Happy Holidays to you Erich,
    Thanks for the great post. Just a heads up about a very interesting pre-certified (FCC, etc) Lora module by Seeed Studio (part 317990687 and can be bought from Mouser). The part contains both a SX1261 and a STM32 MCU all in one 28-pin 12x12mm package for a price of around $10 USD. I cannot speak to how well it works, etc but I thought it was pretty slick all things considered. I suspect it would not meet the needs of your student’s project, but could be a quick and easy way to incorporate LoRA in other projects.
    All the best to you, your family, and everyone else in the upcoming New Year!
    Cheers, Sam

    Liked by 1 person

    • Hi Sam,
      I really would love to see some LoRa modules with NXP parts, as they are very low power and have a very interesting mix of peripherals for my applications. So until then, we need to build our own modules. We have used STM32 base modules in some applications too, but sometimes it is not the right fit with memory size and peripheral mix.

      Happy Holidays to you too!


      • Good day Erich,
        Understood and I agree. I really wished that Seeed chose one of the NXP devices, but I suspect that STM parts were easier to get and/or less expensive. With that said I use NXP (Freescale/Motorola) processors in virtually all of my personal and professional designs and so it is rare for me to use other vendors. However, these days with supply issues one has to make do with what is available. Thankfully I have ample supply of a variety of NXP parts (Kinetis, RT’s, IMX6 and 6Q’s, etc) and so I can still use NXP when needed, but there are times where they may be some advantages in other vendor’s devices such as the Lora-e5 module I mentioned (single device, smaller and easier to design board, module certification.etc).
        Anyway, I thought that the device might be of interest.

        Liked by 1 person

        • Hi Sam,
          yes, that Seeed module is definitely of interest. And yes: I see as well that at least some STM32 devices are easier to get than others, probably they have less ramped down the production lines in that panic mode at the beginning of the pandemic as others did? I have designed-in NXP devices which now show up on Mouser as expected for 02/01/2023 (yikes!), so I have to make a re-design using a different device :-(.
          As for STM and LoRa: I see that STM has invested in LoRa, supporting it seamlessly in the STMCube32 which is really nice, while other microcontroller vendors somehow missed the importance of LoRa. What I see coming is that more and more RISC-V & LoRa combinations seems to take off, so he future might be RISC-V anyway. We will see what 2022 and beyond will bring on this :-).


  2. Hi Erich,

    Thanks a lot for this great contribution. My name is Michel and I am designing a new wearable device based on LPC1549 and an RF Solution Lambda 62 module based on SX1262. I am currently checking out your project repo and I can’t wait to build and try out your SW. Once adaptation to LPC1549 is done, I will also publish my project.

    Mit frendlichen Grüssen aus dem Elsass,

    Liked by 1 person

  3. Hi Erich!

    I saw this project and since I’m looking at porting the lorawan stack to our current product I thought I would buy a LPC55S16-EVK and give it a try.

    I think I found an issue with the code when built for US915 vs EU868.

    The symptom is CryptoNvm->DevNonce used by the join request restarts at zero each time the board restarts. The Join server then see’s the nonce repeated and rejects the join request.

    I think the issue is the size of the nvm data stored in flash is too big for the space allocated for it.

    When you compile for region US915 sizeof(LoRaMacNvmData_t) comes out to 1804 bytes where the space allocated to store it in flash is 3 sectors or 1536 bytes. So the EepromMcuReadBuffer() and EepromMcuWriteBuffer() always return LMN_STATUS_ERROR.

    I think the difference is because in US915
    And in EU868 it’s
    ChannelParams_t Channels[ REGION_NVM_MAX_NB_CHANNELS ];

    Liked by 1 person

    • Thank you very much for pointing this out. Yes, indeed, the space allocated is not enough for example if you run it with US915 (it was enough for my case of EU868). I have now just extended the memory size for the secure element to 2 KByte and added documentation/comments to the source base, in case this needs to be extended again. I have tested the change on my side with using EU868 and this works fine on my end. Please have a look at the latest commits on git?


What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.