This example demonstrates how to implement bidirectional LoRa Ping-Pong communication on an STM32F103CBT6 development board using the Semtech Radio Access Controller (RAC) to drive the LR2021 or Ra-11 RF chip.
git clone https://github.com/Ai-Thinker-Open/ra11-ra20.git Ra-20_Ra-11
cd Ra-20_Ra-11
git submodule update --init --recursive # If the repository contains submodules
sudo apt update
# 1. ARM cross-compilation toolchain (10.x or 12.x recommended)
sudo apt install -y gcc-arm-none-eabi binutils-arm-none-eabi gdb-multiarch
# 2. Build system
sudo apt install -y cmake ninja-build
# 3. ST-Link flashing and debugging tools
sudo apt install -y stlink-tools
# 4. Python3 + pyserial (for debug.py serial monitoring and flashing helper scripts)
sudo apt install -y python3 python3-pip
pip3 install --user pyserial
# 5. Git (usually pre-installed)
sudo apt install -y git
Run the following commands to confirm that all tools have been installed successfully:
arm-none-eabi-gcc --version
cmake --version # Requires ≥ 3.16
ninja --version
st-info --version
python3 -c "import serial; print('pyserial OK')"
If arm-none-eabi-gcc is not in the default PATH, please export the toolchain directory:
export ARM_GNU_BIN=/usr/bin
# or
export ARM_GNU_BIN=/opt/gcc-arm-none-eabi-10/bin
It is recommended to add the command above to ~/.bashrc or ~/.zshrc.
~/project/stm32_project/semtech_chip_driver/Ra-20_Ra-11/
├── examples/ # CMake entry point (includes README documentation)
├── smtc_rac_lib/
├── examples/smtc_hal_f1/ # F103-specific HAL
├── build/ # Intermediate and final build files (can be deleted)
└── ...
rm -Rf build/ ; \
cmake -L -S examples \
-B build \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DLEGACY_EVK_LR20XX=true \
-DBOARD=STM32F103CB \
-DRAC_RADIO=lr1121 \
-G Ninja ; \
cmake --build build --target ping_pong
| RF Chip | Example Build Parameters | Description |
|---|---|---|
| Ra-20 | -DRAC_RADIO=lr2021 -DLEGACY_EVK_LR20XX=true |
Legacy EVK pin definition |
| Ra-11 | -DRAC_RADIO=lr1121 |
Standard LR11xx pins |
| STM32F103CB | -DBOARD=STM32F103CB ... |
Use STM32F103CB HAL |
After a successful build, the following files will be generated in the build/ directory:
ping_pong.elfping_pong.hexping_pong.bin| STM32F103CBT6 Pin | RF Chip Pin | Function | Notes |
|---|---|---|---|
| PA4 | NSS / CS | SPI chip select | — |
| PA5 | SCK | SPI clock | — |
| PA6 | MISO | SPI MISO | — |
| PA7 | MOSI | SPI MOSI | — |
| PB14 | NRST | RF reset | Active low |
| PB1 | DIO1 / DIOX | RF interrupt | Rising-edge trigger |
| PA0 | BUSY | RF busy signal | LR11xx / LR20xx |
| PA8 | — | LED_TX | LED ON when transmitting |
| PB15 | — | LED_RX | LED ON when receiving |
| PA9 | UART_TX | Debug UART | 115200 8N1 |
| PA10 | UART_RX | Debug UART | — |
-DLEGACY_EVK_LR20XX=true during compilationRAC_RADIO=lr1121 is configured, antenna switching and LNA control are automatically handled by the driverPower supply recommendation: The MCU and RF chip should share a 3.3V power supply. Place 100nF + 10µF decoupling capacitors close to each VDD pin.
st-flash --serial <ST-serial number> --reset write build/ping_pong.bin 0x08000000
STM32_Programmer_CLI -c port=SWD sn=<ST-serial number> -w build/ping_pong.bin 0x08000000 -v -rst
cmake ... -DPING_PONG_START_AS_SUBORDINATE=0 # Default
cmake ... -DPING_PONG_START_AS_SUBORDINATE=1
After successful operation, the following log should be seen continuously (counter increments):
INFO: smtc_rac_init
INFO: USP/RAC Version: 1.0.0
...
INFO: starting ping-pong as manager
INFO: sending (value=0, delay=0ms)
INFO: usp/rac: transaction is starting
INFO: usp/rac: new event: transaction (transmission) has ended (success)
INFO: receiving...
INFO: usp/rac: transaction is starting
INFO: usp/rac: new event: transaction (reception) has ended (success)
INFO: payload is correct, continuing
INFO: sending (value=1, delay=250ms)
...
smtc_rac_init or watchdog reset should not appearsmtc_rac_init / watchdog reset: Usually caused by DIO pins being configured with interrupts before the callback is registered, or by a 1000ms long delay in the main loop that prevents the radio_planner from processing in time. This issue has been fixed in this repository.ping_pong target does not define ENABLE_PERIODIC_UPLINK (this macro conflicts with the ping-pong transaction).-DRAC_RADIO=lr2021 or lr1121).