Troubleshooting guide for driver, the CMake development environment, and RF communication issues related to Ai-Thinker Ra-20 / Ra-20H modules (LR2021 RF chip).
Recommended build parameters:
-DBOARD=STM32F103CB -DRAC_RADIO=lr2021 -DLEGACY_EVK_LR20XX=ON
Repository: git@github.com:Ai-Thinker-Open/ra11-ra20.git
RAC_RADIO should be used?| Module | Chip | CMake Parameter |
|---|---|---|
| Ra-20 / Ra-20H | LR2021 (LR20xx) | -DRAC_RADIO=lr2021 |
When using Ai-Thinker or legacy EVK-compatible pin assignments, the following option is usually also required:
-DLEGACY_EVK_LR20XX=ON
Driver locations:
smtc_rac_lib/radio_drivers/ - Register-level drivers (including LR20xx)smtc_rac_lib/smtc_ral/ - Radio Abstraction Layer (RAL)smtc_rac_lib/smtc_rac/ - Radio Access Controller (RAC / USP)LEGACY_EVK_LR20XX be added?This option selects the legacy EVK pin definitions for LR20xx (e.g. the DIOX that matches the older board design). Most Ai-Thinker Ra-20 boards use this configuration.
-DLEGACY_EVK_LR20XX=ON (or true)OFF according to the schematicWhen the pin configuration does not match the hardware, common symptoms include missing interrupts, no TX/RX callbacks, and applications hanging even though SPI appears to work normally.
lr1121 or sx1262 be used to build firmware for Ra-20?No. The radio selection must match the actual chip. For Ra-20, always use lr2021, and configure LEGACY_EVK_LR20XX according to the board type.
LR2021 (LR20xx) provides a broader feature set, including:
rttof_manager and rttof_subordinate available)direct_driver_access and cad, which are primarily intended for LR20xxRa-11 (LR1121) does not support RTToF. To test ranging on Ra-20, use the LR2021-specific examples. Do not copy the parameter assumptions from the Ra-11 ping-pong examples for ranging tests.
LEGACY_EVK_LR20XX?Always clear the build cache and configure the project again:
rm -rf build
cmake -S examples -B build -G Ninja \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=STM32F103CB \
-DRAC_RADIO=lr2021 \
-DLEGACY_EVK_LR20XX=ON
cmake --build build --target ping_pong
git clone git@github.com:Ai-Thinker-Open/ra11-ra20.git
# or
git clone https://github.com/Ai-Thinker-AIoT/ra11-ra20.git
cd ra11-ra20
All subsequent cmake commands should be run from the repository root.
sudo apt update
sudo apt install -y gcc-arm-none-eabi binutils-arm-none-eabi \
cmake ninja-build git stlink-tools
Recommended versions: CMake ≥ 3.25 and Ninja ≥ 1.11. Verify:
arm-none-eabi-gcc --version
cmake --version
ninja --version
The preferred approach is WSL2 with Ubuntu, using the same commands as on Linux. For native Windows builds, install the ARM GNU Toolchain, CMake, and Ninja, and make sure that arm-none-eabi-gcc is available in PATH.
You must explicitly specify the board type. For Ra-20, use:
-DBOARD=STM32F103CB
Ra-20 requires the following:
-DRAC_RADIO=lr2021
Depending on the board type, also add -DLEGACY_EVK_LR20XX=ON (commonly required for Ai-Thinker boards).
-DBOARD=NUCLEO_L476?For Ai-Thinker Ra-20 boards, use STM32F103CB. NUCLEO_L476 uses a different HAL. With the current repository pin configuration, the L4 target may fail because macros such as HW_MODEM_* are not defined. Do not use the NUCLEO command line to validate an Ai-Thinker board.
rm -rf build
cmake -S examples -B build \
-G Ninja \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=STM32F103CB \
-DRAC_RADIO=lr2021 \
-DLEGACY_EVK_LR20XX=ON
cmake --build build --target ping_pong
Outputs: build/ping_pong.bin, build/ping_pong.hex, and the ELF file.
Make sure that you built an add_example target (e.g. ping_pong). The POST_BUILD generates the hex and bin files. Check the log for messages such as Creating ping_pong.hex... / Creating ping_pong.bin..., and verify that arm-none-eabi-objcopy is available in PATH.
st-flash --connect-under-reset write build/ping_pong.bin 0x8000000
# or
cmake --build build --target flash_ping_pong
You can also use STM32CubeProgrammer with a .hex or .bin file, the SWD interface, and address 0x08000000.
axk_cmd_example/...?Optional example directories may not be present in the source tree. Delete build/ and run CMake configuration again. When source files are missing, the project skips the corresponding target.
undefined reference to main_xxx?Check the macros and declarations in main.h, the MAKEFILE_APP branch in main.c and whether the second argument passed to add_example matches the macro name.
unexpected payload. Why?The most common cause is that both boards are configured as the default Manager.
| Device | Configuration |
|---|---|
| Device A (Manager) | Default configuration (do not enable Subordinate) |
| Device B (Subordinate) | -DPING_PONG_START_AS_SUBORDINATE=ON, followed by reconfiguration and rebuilding |
Recommended power-on sequence: power on the Subordinate first, then the Manager.
prefix_received='80' in decimal usually corresponds to ASCII 'P'. This means that a payload beginning with P was received, but the device role or expected frame type does not match.
rm -rf build
cmake -S examples -B build \
-G Ninja \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DBOARD=STM32F103CB \
-DRAC_RADIO=lr2021 \
-DLEGACY_EVK_LR20XX=ON \
-DPING_PONG_START_AS_SUBORDINATE=ON
cmake --build build --target ping_pong
The following parameters must be identical on both devices (see in main_ping_pong.h):
RF_FREQ_IN_HZ (The example default is often 868100000. Adjust it according to the actual Ra-20 frequency band and local regulations.)After changing these macros, rebuild and re-program both boards.
The debug UART is generally configured as 115200 8N1. A normal Manager sequence looks like: starting ping-pong as manager → successful transmission → successful reception → payload is correct. The counter should continue increasing, and the TX/RX LEDs should blink on each round.
smtc_rac_run_engine()lr2021 with the correct LEGACY_EVK_LR20XXIf the chip can be read over SPI but interrupts never occur, first suspect a mismatch between the DIO pin and LEGACY_EVK_LR20XX.
ENABLE_PERIODIC_UPLINK in some scenarios).Common SPI and control pins (STM32F103CBT6, refer to the repository):
| MCU Pin | RF Side | Function |
|---|---|---|
| PA4 | NSS | SPI chip select |
| PA5 | SCK | SPI clock |
| PA6 | MISO | SPI MISO |
| PA7 | MOSI | SPI MOSI |
| PB14 | NRST | RF reset |
| PB1 | DIOX | Interrupt (commonly used in legacy mode) |
| PA0 | BUSY | Busy signal |
The build must include -DLEGACY_EVK_LR20XX=ON (Ai-Thinker / legacy EVK). Do not modify Ra-20 according to the LR11xx LNA logic used by Ra-11 unless the schematic explicitly requires it.
Use rttof_manager / rttof_subordinate, and -DRAC_RADIO=lr2021. The ranging roles, channel, and RTToF-related macros must be configured consistently on both ends. Ranging and ordinary ping-pong use different application state machines, so validate them separately.
LEGACY_EVK_LR20XX=OFF has not been enabled accidentally, as this may cause intermittent interrupt loss.The main loop must periodically call:
smtc_rac_run_engine( );
| Symptom | Troubleshooting Direction |
|---|---|
rp_hook_init panic |
smtc_rac_open_radio() may be called repeatedly at the same priority |
radio_access_id is out of range |
The radio ID is invalid or has been closed |
smtc_rac_submit_radio_transaction panic |
Misconfigured context (e.g., RX buffer too small) |
HARDFAULT_Handler |
NULL callback (e.g. post-transaction callback not set) |
Use the function names and line numbers in the logs to inspect smtc_rac and radio_planner.
-DBOARD=STM32F103CB-DRAC_RADIO=lr2021-DLEGACY_EVK_LR20XX=ON (Ai-Thinker / legacy EVK)build/ after changing the configuration, then re-run configure.smtc_rac_run_engine() in the main loop.This document covers only Ra-20 / Ra-20H with LR2021. For Ra-11, refer to FAQ_ra11_cn.md.