USP RELEASE v1.2.1' - Stable Release
USP provides an abstraction layer for scheduling and managing multiple radio access across available modulations (LoRa, FSK, LR-FHSS, FLRC) and protocols (LoRaWAN). The library enables applications to request radio access, configure transmissions/receptions, and schedule operations with priority management.
Current Version is v1.2.1:
|
|
The USP repository includes LoRa Basics Modem 4.9.0.
The supported Semtech radios are:
- Validated1 on LoRa Plus EVK(LoRa Plus Expansion Board + Wio-LR2021/Wio-LR2022/Wio-LR2012 radios)2
- buildable1 on LR11xx shield radios
- buildable1 on SX126x shield radios
The supported platforms are:
- Validated1 on STMicro NUCLEO-STM32L476RG
- buildable1 on Linux (x86/x86_64 native + ARM cross-compilation for Raspberry Pi, embedded Linux).
- For documentation, see the "Build Examples on ARM Linux" in the following chapters below
- if required, check also the Linux Porting Documentation )
- Linux porting was only tested with LR2021. The radio_hal for other radios shall be implemented before use.
- Experimental1 on Renesas FPB-RA0E2 (R7FA0E209, see FPB-RA0E2 Porting Documentation)
- only tested with LoRa Plus EVK (LR2021)
- only tested with porting_tests & periodical_uplink applications (CLASS A, US915 region)
- Experimental1 on STMicro NUCLEO-STM32L073RZ
1
Validated: passed the Semtech nominal validation process,Buildable: can be compiled but did not go through full Semtech validation process,Experimental: was compiled and tested onperiodical_uplinksample only with low validation2WIO-LR20xx CN version
⚠️ For WIO-LR20xx China (CN) versions the PA table configuration shall be adjusted as defined in the datasheet. For example, in LR2021 Datasheet page 134 to (CN - 490Mhz) band for optimal performances. Refer to USP Porting Guide for more details.
The USP architecture, its main SW components (RAC, protocols, MCU/Radio HAL & BSP), the RAC API and the dynamic behaviour & priorities are described in the USP Architecture documentation →.
| Component | Description | Documentation |
|---|---|---|
| USP/RAC Library | Radio Access Component (RAC) API for Semtech transceiver management, including also RAL & Semtech Radio Drivers | View Full API Documentation → |
| LoRa Basics Modem | Integrated LoRaWAN stack (v4.9.0) | LBM User Guide → |
| FLRP (Fast LoRa communication Protocol) | High-speed LoRa + FLRC protocol (up to 2.6 Mbps) with LoRa WOR time/frequency synchronization | FLRP Documentation → · flrp_api Example → |
| Semtech Radio Drivers | Legacy Drivers for supported Semtech Radios | Semtech Radio Drivers |
| Examples Core | Sample applications demonstrating RAC API usage that can be compiled for baremetal | USP Samples Guide → |
- Priority-based scheduling - Manage radio access with configurable priorities
- Multi-modulation support - LoRa, FSK, LR-FHSS, and FLRC modulations
- LoRa capabilities - Full support for transmission, reception, and ranging
- Precise timing - Schedule radio operations with accurate timing control
- Asynchronous operations - Callback support for non-blocking execution
- Seamless integration - Built on Semtech's radio planner
The USP software was tested with:
- gcc 13.3 or higher
- CMake 3.28 or higher
- OpenOCD 0.12 or higher
- Ninja build tool 1.11 or higher
The Samples & documentation &re available here : USP Samples Guide →.
flrp_api_initiator: FLRP API peer-to-peer high-speed transfer (initiator role)flrp_api_slave: FLRP API peer-to-peer high-speed transfer (slave role)
rttof_manager: RTToF ranging manager devicerttof_subordinate: RTToF ranging subordinate device
ping_pong: Ping-pong communication exampleperiodical_uplink: Periodical uplink transmission examplemultiprotocol: Multiprotocol example (LoRa + Ranging)
per_tx: LoRa packet error rate - transmitterper_rx: LoRa packet error rate - receiverper_fsk_tx: FSK packet error rate - transmitterper_fsk_rx: FSK packet error rate - receiverper_flrc_tx: FLRC packet error rate - transmitterper_flrc_rx: FLRC packet error rate - receiver
lrfhss_tx: LR-FHSS transmission example
rf_certification_etsi: RF certification for ETSI regionrf_certification_arib: RF certification for ARIB regionrf_certification_fcc: RF certification for FCC regionlctt_certif: LCTT certification exampleporting_tests: porting test example
spectral_scan: Spectral scan analysis exampletx_cw: Continuous wave transmission exampledirect_driver_access: Direct radio driver access example (Use RAL or Drivers API instead of USP/RAC API to manage radio, and fine-tune radio sleeping operations)immediate_radio_access: Immediate radio access example (Use USP/RAC API to manage radio)geolocation: Manage geolocation of LR1110 & LR1120 radio familyfull_almanac_update: Manage almanac update of LR1110 & LR1120 radio familywifi_region_detect: Manage wifi region detection for LR1110 & LR1120 radio familyhw_modem: Drive USP based MCU through UART (only LBM is currently stable)cad: Channel Activity Detection example
Compilation is done through the cmake command line.
Each example has its own CMakeLists.txt in its directory under examples/main_examples/. You can either:
- Build a single example by pointing cmake to its directory
- Build all examples by pointing cmake to
examples/main_examples - Build a single example by pointing cmake to
examples/main_examplesand using--target <example>
To build a specific example, point cmake to its directory:
rm -Rf build/
cmake -S examples/main_examples/periodical_uplink_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L476 \
-DRAC_RADIO=lr2021 \
-G Ninja
cmake --build buildTo build all examples at once, point cmake to examples/main_examples:
rm -Rf build/
cmake -S examples/main_examples -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L476 \
-DRAC_RADIO=lr2021 \
-G Ninja
cmake --build build --target all_examplesYou can also build a specific example from the all_examples configuration:
cmake --build build --target periodical_uplinkWhen pointing to examples/main_examples, the cmake configuration will display available examples:
-- Available examples:
-- - flrp_api_initiator : FLRP API (initiator)
-- - flrp_api_slave : FLRP API (slave)
-- - flrc_burst_tx : FLRC burst data transfer (transmitter)
-- - flrc_burst_rx : FLRC burst data transfer (receiver)
-- - full_almanac_update : Full almanac update (LR11XX only)
-- - geolocation : Geolocation example (LR11XX only)
-- - cad : Channel Activity Detection (LR20XX only)
-- - direct_driver_access : Direct radio driver access (LR20XX only)
-- - immediate_radio_access : Immediate radio access (LR20XX only)
-- - hw_modem : Hardware modem with serial interface
-- - lctt_certif : LCTT LoRaWAN certification example
-- - lrfhss_tx : LR-FHSS transmission example
-- - multiprotocol : Multiprotocol (LoRaWAN + ranging) example
-- - per_tx : Packet error rate - LoRa (transmitter)
-- - per_rx : Packet error rate - LoRa (receiver)
-- - per_flrc_tx : Packet error rate - FLRC (transmitter)
-- - per_flrc_rx : Packet error rate - FLRC (receiver)
-- - per_fsk_tx : Packet error rate - FSK (transmitter)
-- - per_fsk_rx : Packet error rate - FSK (receiver)
-- - periodical_uplink : Periodical LoRaWAN uplink example
-- - ping_pong : Ping-pong communication example
-- - porting_tests : HAL porting verification tests
-- - radio_planner_test : Radio Planner stress test
-- - rttof_manager : Ranging (RTToF) manager
-- - rttof_subordinate : Ranging (RTToF) subordinate
-- - rf_certification_etsi : RF certification (ETSI region)
-- - rf_certification_arib : RF certification (ARIB region)
-- - rf_certification_fcc : RF certification (FCC region)
-- - spectral_scan : Spectral scan analysis example
-- - tx_cw : Continuous wave (TX CW) transmission
-- - wifi_region_detection : WiFi region detection (LR11XX only)
Some examples have radio-specific requirements:
- geolocation: Only available for LR11XX radios (lr1110, lr1120, lr1121). Automatically skipped for other radios.
- hw_modem: Supports all radios. Geolocation features are automatically enabled only for LR11XX radios.
Example building geolocation for lr1120:
rm -Rf build/
cmake -S examples/main_examples/geolocation/geoloc_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L476 \
-DRAC_RADIO=lr1120 \
-G Ninja
cmake --build buildExample building hw_modem for lr2021 (automatically without geolocation):
rm -Rf build/
cmake -S examples/main_examples/hw_modem -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L476 \
-DRAC_RADIO=lr2021 \
-G Ninja
cmake --build buildFor RTToF example with custom flags:
rm -Rf build/
env CFLAGS="-DCONTINUOUS_RANGING=false" \
cmake -S examples/main_examples/ranging_demo -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L476 \
-DRAC_RADIO=lr2021 \
-UCMAKE_C_FLAGS \
-G Ninja
cmake --build build --target rttof_subordinate rttof_managerManagement of compilation symbols
- When cmake symbols are available (often activating compiler definitions), use them directly in cmake configuration command line with
-Doption (e.g. -DBOARD=NUCLEO_L476) :- cmake symbols are described in example documentation,
- for advanced users, some cmake symbols are defined in cmake sub components like examples/common.cmake, smtc_rac_lib/CMakeLists.txt, protocols/lbm_lib/CMakeLists.txt, protocols/lbm_lib/options.cmake, protocols/lbm_lib/smtc_modem_core/CMakeLists.txt
- Some important compilation defines are not yet available through cmake symbols. In this case, with care, they can be updated in cmake command line by using the
CFLAGS&-UCMAKE_C_FLAGS. For example, for LoRa Basics Modem examples, you can use the following command to pass LoRaWAN keys & regions in cmake command lines:
env CFLAGS="-DMODEM_EXAMPLE_REGION=SMTC_MODEM_REGION_WW_2G4 \
-DUSER_LORAWAN_DEVICE_EUI='{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}' \
-DUSER_LORAWAN_JOIN_EUI='{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}' \
-DUSER_LORAWAN_APP_KEY='{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}'" \
cmake -S examples/main_examples/periodical_uplink_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L476 \
-DRAC_RADIO=lr1120 \
-UCMAKE_C_FLAGS \
-G Ninja
cmake --build buildHave a look on traces when compiling to understand which cmake symbols are activated or not :
APP_MODE:STRING=APP_MODE_CERTIFICATION
CCACHE_PROGRAM:FILEPATH=/usr/bin/ccache
CMAKE_BUILD_TYPE:STRING=MinSizeRel
CMAKE_INSTALL_PREFIX:PATH=/usr/local
CMAKE_TOOLCHAIN_FILE:FILEPATH=xxx/examples/smtc_hal_l4/cmake_stm32l4_toolchain.cmake
INFINITE_PREAMBLE:BOOL=OFF
LBM_ALC_SYNC:BOOL=ON
LBM_ALC_SYNC_VERSION:STRING=1
LBM_ALMANAC:BOOL=OFF
LBM_BEACON_TX:BOOL=OFF
LBM_CLASS_B:BOOL=ON
LBM_CLASS_C:BOOL=ON
LBM_CMAKE_CONFIG_AUTO:BOOL=ON
LBM_CRYPTO:STRING=SOFT
LBM_CSMA:BOOL=ON
LBM_CSMA_BY_DEFAULT:BOOL=OFF
LBM_DEVICE_MANAGEMENT:BOOL=ON
LBM_FUOTA:BOOL=ON
LBM_FUOTA_FMP:BOOL=ON
LBM_FUOTA_FRAGMENTS_MAX_NUM:STRING=
LBM_FUOTA_FRAGMENTS_MAX_REDUNDANCY:STRING=
LBM_FUOTA_FRAGMENTS_MAX_SIZE:STRING=
LBM_FUOTA_MPA:BOOL=ON
LBM_FUOTA_VERSION:STRING=1
LBM_GEOLOCATION:BOOL=OFF
LBM_LFU:BOOL=ON
LBM_MODEM_TRACE:BOOL=ON
LBM_MODEM_TRACE_DEEP:BOOL=OFF
LBM_MULTICAST:BOOL=ON
LBM_NUMBER_OF_STACKS:STRING=1
LBM_PERF_TEST:BOOL=OFF
LBM_RADIO:STRING=lr2021
LBM_REGIONS:STRING=ALL
LBM_RELAY_RX:BOOL=ON
LBM_RELAY_TX:BOOL=ON
LBM_STORE_AND_FORWARD:BOOL=ON
LBM_STREAM:BOOL=ON
LBM_TEST_BYPASS_JOIN_DUTY_CYCLE:BOOL=OFF
LEGACY_EVK_LR20XX:BOOL=OFF
NOTIFICATION_MODE:STRING=NOTIFICATIONS_OFF
RAC_CORE_LOG_API_ENABLE:BOOL=OFF
RAC_CORE_LOG_CONFIG_ENABLE:BOOL=ON
RAC_CORE_LOG_DEBUG_ENABLE:BOOL=OFF
RAC_CORE_LOG_ERROR_ENABLE:BOOL=ON
RAC_CORE_LOG_INFO_ENABLE:BOOL=OFF
RAC_CORE_LOG_RADIO_ENABLE:BOOL=OFF
RAC_CORE_LOG_WARN_ENABLE:BOOL=OFF
RAC_FSK_LOG_ENABLE:BOOL=OFF
RAC_LIB_LOG_PROFILE:STRING=DEFAULT
RAC_LOG_ENABLE:BOOL=ON
RAC_LOG_PROFILE:STRING=DEFAULT
RAC_LORA_LOG_CONFIG_ENABLE:BOOL=ON
RAC_LORA_LOG_DEBUG_ENABLE:BOOL=OFF
RAC_LORA_LOG_ENABLE:BOOL=OFF
RAC_LORA_LOG_ERROR_ENABLE:BOOL=ON
RAC_LORA_LOG_INFO_ENABLE:BOOL=OFF
RAC_LORA_LOG_RX_ENABLE:BOOL=ON
RAC_LORA_LOG_TX_ENABLE:BOOL=ON
RAC_LORA_LOG_WARN_ENABLE:BOOL=OFF
RAC_LRFHSS_LOG_ENABLE:BOOL=OFF
RAC_RADIO:STRING=lr2021
RP_MARGIN_DELAY:STRING=8
RP_VERSION:STRING=RP2_103
TYPE_OF_CAD:STRING=CAD_ONLY
The -DBOARD=NUCLEO_L476 cmake symbol shall be selected :
rm -Rf build/
cmake -L -S examples/main_examples/periodical_uplink_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L476 \
-DRAC_RADIO=lr2021 \
-G Ninja
cmake --build buildOptions
RAC_RADIO: Target radio (sx1261,sx1262,sx1268,lr1110,lr1120,lr1121,lr2021,udp_pf)BOARD: Target platform:NUCLEO_L476,NUCLEO_L073,FPB_RA0E2,LINUX, orLINUX_ARM- Other options are related to examples
Example of openocdcommand to flash:
openocd -f interface/stlink.cfg -f target/stm32l4x.cfg -c "adapter serial <serial_number>" -c "program build/periodical_uplink verify reset exit"
For deployment on ARM Linux devices with physical LR2021 radio:
# Cross-compile for ARM with LR2021 radio
rm -Rf build/
cmake -S examples/main_examples/periodical_uplink_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=LINUX_ARM \
-DRAC_RADIO=lr2021 \
-G Ninja
cmake --build build
# Transfer to target device
scp build/periodical_uplink pi@raspberrypi.local:~/Prerequisites:
- SPI enabled:
/dev/spidev0.0 - GPIO access:
/dev/gpiochip0 - User in
spiandgpiogroups
For detailed Linux HAL implementation and hardware setup, see → Linux HAL Documentation
The virtual radio (udp_pf) implements the Semtech UDP Packet Forwarder protocol to connect directly to a LoRaWAN Network Server (TTN, ChirpStack, etc.) without physical radio hardware or gateway. Suitable for development, testing, and CI/CD integration.
Configure via environment variables:
# Build with virtual radio (native x86/x86_64)
rm -Rf build/
cmake -S examples/main_examples/periodical_uplink_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=LINUX \
-DRAC_RADIO=udp_pf \
-G Ninja
cmake --build build
# Run the application
./build/periodical_uplink
# Configure server address/port and gateway EUI (optional)
UDP_PF_SERVER_ADDR=eu1.cloud.thethings.network \
UDP_PF_SERVER_PORT=1700 \
UDP_PF_GATEWAY_EUI=AA555AFFFE000000 \
./build/periodical_uplinkEnvironment variables for configuration:
UDP_PF_SERVER_ADDR- Network server address (default:127.0.0.1)UDP_PF_SERVER_PORT- Network server port (default:1700)UDP_PF_GATEWAY_EUI- Gateway EUI identifier (default:000000FFFE000000)
Notes:
- Only periodical_uplink was tested with low validation.
- The
-DBOARD=NUCLEO_L073cmake symbol shall be selected. - Store & Forward feature shall be deactivated.
Build Periodical uplink:
rm -Rf build/
cmake -S examples/main_examples/periodical_uplink_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L073 \
-DRAC_RADIO=lr2021 \
-DLBM_STORE_AND_FORWARD=OFF \
-G Ninja
cmake --build buildBuild LCTT Certif:
rm -Rf build/
cmake -L -S examples/main_examples/lctt_certif_example -B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=NUCLEO_L073 \
-DRAC_RADIO=lr2021 \
-DLBM_STORE_AND_FORWARD=OFF \
-G Ninja
cmake --build buildExample of openocdcommand to flash:
openocd -f interface/stlink.cfg -f target/stm32l0_dual_bank.cfg -c "adapter serial 066DFF515055657867152019" -c "adapter speed 500" -c "reset_config srst_only connect_assert_srst" -c "init" -c "program build/periodical_uplink verify reset exit"
Note : Not all examples are compiling on NUCLEO-L073RZ. Only periodical_uplink was tested.
More details and how to build & use Samples are available on USP Sample Documentation
This chapter explains how to port USP
- on other MCU
- on other radio PCB
This chapter explains how to port existing LoRa Basics Modem application to USP
Below is a non-exhaustive list of errors that can cause panics when using the RAC API or LoRa Basics Modem (LBM).
A panic will trig when the modem software is in an invalid state. Most of the time when the modem is in an invalid or unsupported combination of settings in smtc_rac_context_t or in LBM configuration.
The printed message will use this format:
Modem panic: function():line_number end of message
To debug, you can search the file where the function is defined, and open it at the line number. If not sufficient to understand the issue, a debugger can be used to find out the sequence of calls and branching that led to the error.
Main RAC API Panics are:
This error occurs when invoking smtc_rac_open_radio(priority) a second time with the same priority.
It comes from the file smtc_rac_lib/radio_planner/src/radio_planner.c, in the function rp_hook_init.
To fix it, please make sure that no two calls to smtc_rac_open_radio have the same priority.
This error occurs when using an invalid radio_access_id as a parameter in API functions requiring it.
To fix it, ensure that you use an ID returned by smtc_rac_open_radio() and that no smtc_rac_close_radio() were called with it.
This error occurs when one field member in smtc_rac_context_t associated with the radio ID has been filled incorrectly, usually the size of the RX buffer.
It comes from the file smtc_rac_lib/smtc_rac/smtc_rac.c, in the function smtc_rac_submit_radio_transaction.
To fix it, ensure that size_of_rx_payload_buffer is greater or equal to max_rx_size of the selected modulation.
For example, in LoRa, ensure ctx->smtc_rac_data_buffer_setup.size_of_rx_payload_buffer >= ctx->radio_params.lora.max_rx_size.
This error usually occurs when invoking a NULL callback.
It might comes from the file smtc_rac_lib/smtc_rac/smtc_rac.c, in the function smtc_rac_rp_callback.
To fix it, ensure that ctx->scheduler_config.callback_post_radio_transaction != NULL.