Ping-Pong Example FAQ

This document summarizes the most common questions and answers when using and porting the ping_pong example.


1. Build & Flashing

A:

rm -Rf build/ ; \
cmake -L -S examples \
      -B build \
      -DCMAKE_BUILD_TYPE=MinSizeRel \
      -DLEGACY_EVK_LR20XX=true \
      -DBOARD=STM32F103CB \
      -DRAC_RADIO=lr2021 \
      -G Ninja ; \
cmake --build build --target ping_pong

If using Ra-11, please set -DRAC_RADIO=lr1121 (the LEGACY_EVK_LR20XX is not required).

Q: How do I flash the firmware?

Use st-flash or STM32_Programmer_CLI directly.


2. Running the Example

Q: How do I configure one board to only listen (subordinate) and the other to start transmission (manager)?

A: By default, the example starts as the manager and immediately sends the first PING.

Build the subordinate board:

cmake ... -DPING_PONG_START_AS_SUBORDINATE=1

Q: What should the serial log look like during normal operation?

A: You should continuously see successful round-trip communication with an incrementing counter:

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: new event: transaction (reception) has ended (success)
INFO: payload is correct, continuing
INFO: sending (value=1, delay=250ms)
...

If the message "starting ping-pong as manager" appears repeatedly, the board is resetting (see Section 3).


3. Common Runtime Issues

Q: Why does the board keep resetting / repeatedly print smtc_rac_init?

A: This is almost always caused by one of the following two issues:

  1. DIO interrupt enabled too early
    In hal_mcu_init(), RADIO_DIOX must be configured as a normal input (IRQ_MODE_OFF). Only smtc_modem_hal_irq_config_radio_irq() should enable the rising-edge interrupt and register the callback.

  2. Long delay in the main loop
    The original code once used hal_mcu_set_sleep_for_ms(1000), which starves the radio planner. The current version uses a tight loop:

    while (true) {
        hal_watchdog_reload();
        smtc_rac_run_engine();
    }
    

Q: Why does TX complete, but there is no "transmission has ended (success)" message, and radio_planner keeps aborting?

A: This happens because the ping_pong target defines ENABLE_PERIODIC_UPLINK, which conflicts with the ping-pong manager transaction. Check whether this definition has been removed from CMakeLists.txt.

Q: Why does the subordinate board never reply?

A: Make sure it was built with -DPING_PONG_START_AS_SUBORDINATE=1. Also check that both boards use the same frequency, SF, BW, and sync word (defined in app_ping_pong.h).


4. Driver Porting and Platform Adaptation

Q: Which files should I modify when porting to a new MCU?

A: For the complete list, refer to driver_manual.md. In short:

Q: Why does the DIO pin require special handling during initialization?

A: If the external interrupt of RADIO_DIOX is enabled before the callback is registered by smtc_modem_hal_irq_config_radio_irq(), any edge on the pin will call a NULL function pointer, causing a hard fault or watchdog reset.

Correct sequence:

  1. hal_mcu_init()IRQ_MODE_OFF (normal input)
  2. smtc_rac_init() → calls smtc_modem_hal_irq_config_radio_irq() → safely enables the rising edge and registers the callback at this point

Q: Can I use a 1000ms (or any long) delay in the main loop on a new platform?

A: No. The radio planner depends on frequent calls to smtc_rac_run_engine(). Long blocking delays will cause scheduled tasks to miss their deadlines, and the planner will abort them.

Q: How do I port to BL602?

A: Refer to the “Porting to BL602 (Bouffalo SDK)” section in driver_manual.md. Key points:


5. Debugging and Monitoring

Q: Why does the log show garbled characters or lines being truncated in the middle?

A: This is usually caused by improper normalization of \r\n in the serial port tool, or by the MCU outputting incomplete lines.