Apache NuttX on the BL602 Board

1. Scope

Build, flash, and configure Wi-Fi on the Bouffalo BL602 (or BL604) with Apache NuttX (bl602evb configuration) and a Linux host. Applies to the PineCone board, the BL602 EVB, and compatible modules.

2. The RF parameter area

The flash image contains a 1 KiB area at offset 0x400, tagged BLRFPARA. NuttX reserves this area for RF parameters: transmit power tables, crystal calibration data, and temperature compensation data.

The official Bouffalo flash tool writes this area. The blflash tool, up to version 0.3.5, does not. The area then stays at zero. Result: weak radio reception, failed Wi-Fi joins, and an access point that other devices cannot find.

Use a blflash build that writes this area. Refer to Procedure 7. See also apache/nuttx#4336.

3. Prerequisites

4. Get the source code

mkdir -p ~/src && cd ~/src
git clone https://github.com/apache/nuttx
git clone https://github.com/apache/nuttx-apps apps   # must sit beside nuttx/
git clone --depth 1 https://github.com/bouffalolab/bl_iot-sdk
# RF parameter device tree files:
#   bl_iot_sdk/tools/flash_tool/chips/bl602/device_tree/bl_factory_params_IoTKitA_*.dts

Note: the build downloads the Wi-Fi firmware files (bl_blob) automatically.

5. Build the firmware

cd nuttx
./tools/configure.sh bl602evb:wifi    # or bl602evb:nsh for shell only
make CROSSDEV=riscv64-elf- \
    COMPILER_RT_LIB=/usr/lib/gcc/riscv64-elf/15.2.0/rv32imafc/ilp32f/libgcc.a

Output: nuttx.bin.

6. Check the RF parameter area

xxd -s 0x400 -l 16 nuttx.bin

BLRFPARA followed by data is correct. Zeros after the magic mean the area is empty. Procedure 7 fills it at flash time.

7. Flash the firmware

  1. Build blflash with RF parameter support:

    git clone https://github.com/jxsme/blflash
    cd blflash
    cargo install --path blflash   # installs to ~/.cargo/bin/blflash
    

    This build adds the patch subcommand and the --dts option to the flash subcommand. The changes are not in the upstream release.

  2. Put the board in download mode. BL602 EVB: set the jumper to the FLASH position. PineCone: press and hold BOOT, tap RESET, release BOOT. Other boards: check the manual.

  3. Flash. Match the device tree file to your board crystal. Most boards use 40 MHz:

    blflash flash \
        --dts ~/src/bl_iot_sdk/tools/flash_tool/chips/bl602/device_tree/bl_factory_params_IoTKitA_40M.dts \
        nuttx.bin --port /dev/ttyUSB0
    

    The --dts option patches the RF parameters during the flash operation. Other crystal variants (24M, 26M, 32M, 38.4M, RC32M, None) are in the same directory.

  4. Set the board back to run mode, then reset.

To patch an image without flashing it:

blflash patch --input nuttx.bin --dts <factory_params.dts> --output nuttx-rf.bin

8. Connect to the serial console

picocom --baud 2000000 /dev/ttyUSB0

Press ENTER for the nsh> prompt. Stray bytes can build up in the input buffer at this baud rate; ENTER clears the line.

9. Configure Wi-Fi

Enter these commands at the nsh> prompt. Use the channel, MAC address, SSID, and password from your scan result.

ifup wlan0            # brings up the interface. Required before DHCP.
wapi mode wlan0 2     # station mode. Use `2` or `WAPI_MODE_MANAGED`
wapi scan wlan0       # fills the scan table. Note the channel and MAC address.
wapi ap <ap-mac>      # pin BSSID. without it join-time scan often returns empty (`status_code 12`).
wapi psk <password> 3 # sets the key. `3` = `WPA_ALG_CCMP` (AES). WPA version defaults to 2 (WPA2).
wapi essid <ssid> 1   # sets the SSID and starts the join (`WAPI_ESSID_ON`).
renew wlan0           # runs DHCP

10. Verify the Wi-Fi connection

nsh> wapi show wlan0
       IP: 192.168.0.2
    ESSID: <ssid>
      AP: <ap-mac>

nsh> ping 1.1.1.1
10 packets transmitted, 10 received, 0% packet loss

11. Fault isolation

12. References