5.4 KiB
Moonshine NRF52 Mini
Minimal DIY Meshtastic node variant: nRF52840 + RA-01S-P (SX1262) LoRa module with a single status LED on P0.15. No display, GPS, button, or battery ADC - LoRa-only minimal system.
Tested on a nice!nano board (nRF52840, S140 SoftDevice v6.1.1, Adafruit UF2 bootloader 0.9.2). Also compatible with any nRF52840 board that has the Adafruit UF2 bootloader with S140 v6.x SoftDevice (e.g. Adafruit Feather nRF52840 Express factory bootloader).
Hardware
- MCU: nRF52840 (512 KB flash / 128 KB RAM)
- LF clock: external 32.768 kHz crystal (
USE_LFXO) - LoRa: Ai-Thinker RA-01S-P (SX1262, no TCXO, internal RF switch, 22 dBm max)
SX126X_MAX_POWER=22TCXO_OPTIONAL(no TCXO on module - firmware tries XTAL first)- DIO2 drives TXEN internally; RXEN is controlled by
P0.17
- LED: status LED on P0.15 (active high,
LED_STATE_ON = 1)
Pin map
| Function | Pin | Notes |
|---|---|---|
| SPI_MISO | P0.02 | LORA_MISO |
| LORA_RESET | P0.09 | SX126X_RESET |
| LORA_DIO1 | P0.10 | SX126X_DIO1 (IRQ) |
| LED | P0.15 | Status LED (active high) |
| LORA_RXEN | P0.17 | SX126X_RXEN |
| LORA_BUSY | P0.29 | SX126X_BUSY |
| SPI_SCK | P1.11 | LORA_SCK |
| LORA_CS | P1.13 | SX126X_CS |
| SPI_MOSI | P1.15 | LORA_MOSI |
Only the status LED on P0.15 is wired (no button, battery ADC, GPS, or display). The board has no user button, so DFU entry is via double-tap reset or the 1200 bps touch.
Build & Flash
Build
pio run -e moonshine_NRF52_node_mini
Uses PRIVATE_HW (HardwareModel 255) - no protobuf or architecture.h changes
required.
The build inherits the default v6 ldscript from [nrf52840_base]
(src/platform/nrf52/nrf52840_s140_v6.ld), so the application is linked to
start at 0x26000 and requires the S140 SoftDevice v6.x to be present on the
chip at 0x0-0x25FFF. The Adafruit nRF52 UF2 bootloader bundles its own
SoftDevice (v6.1.1 on the nice!nano), so if UF2 mode works the SoftDevice is
already present. The build output (firmware-*.hex / .uf2) contains only
the application, not the SoftDevice.
Flash via UF2 (recommended - no SWD required)
Prerequisite: the board has the Adafruit UF2 bootloader installed (factory
default on nice!nano and Adafruit Feather nRF52840 Express). Confirm by entering
UF2 mode and reading INFO_UF2.TXT on the bootloader USB volume - it should
show SoftDevice: S140 6.1.1 (or similar v6.x).
First-time install (clean flash):
- Double-tap the Reset button to enter UF2 bootloader mode. A USB mass storage
volume appears (e.g.
NICENANOorFTHR840BOOT). - Drag-and-drop
bin/Meshtastic_nRF52_factory_erase_v3_S140_6.1.0.uf2onto the volume. This erases any stale LittleFS/NodeDB/config from a prior firmware. The board reboots when the copy completes. - Double-tap Reset again to re-enter UF2 mode.
- Drag-and-drop
.pio/build/moonshine_NRF52_node_mini/firmware-moonshine_NRF52_node_mini-*.uf2onto the volume. The board reboots into Meshtastic.
App-only update (SoftDevice already present, config already clean):
Skip steps 2-3 above - just double-tap Reset and drag-and-drop the application
.uf2.
Flash via SWD (for a bare nRF52840 without bootloader)
A factory-fresh nRF52840 has no SoftDevice and no bootloader. The SoftDevice
must be flashed once via SWD before the application; otherwise Bluefruit.begin()
fails, sd_flash_* calls (LittleFS, NodeDB, config persistence) return errors,
and the node appears dead.
For a v6 SoftDevice layout, use the combined bootloader+SoftDevice hex at
bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.hex (this installs
both the UF2 bootloader and the SoftDevice in one SWD pass, enabling UF2
updates thereafter). Flash via SWD with OpenOCD (CMSIS-DAP / J-Link / ST-Link).
The nrf52_recover command does a chip-wide ERASEALL through the nRF52 CTRL-AP
and clears APPROTECT, so it is the recommended first step on a fresh module
(ebyte/Raytac modules ship with APPROTECT engaged).
# Full flow: recover (erase all + unlock) -> bootloader+SoftDevice -> app -> reset
C:/openocd/bin/openocd.exe -s C:/openocd/share/openocd/scripts \
-f interface/cmsis-dap.cfg -f target/nrf52.cfg \
-c "init; nrf52_recover; \
program bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.hex verify; \
program .pio/build/moonshine_NRF52_node_mini/firmware-moonshine_NRF52_node_mini-*.hex verify; \
reset run; exit"
Notes
- The firmware hex/uf2 filename contains a commit hash (e.g.
2.8.0.fbbfcf0); use the actual file produced bypio runor a shell glob. - The combined bootloader+SoftDevice hex occupies
0x0-0x26000and does not write UICR, sonrf52_recoveris safe (UICR resets to defaults). - Swap
interface/cmsis-dap.cfgforinterface/jlink.cfgorinterface/stlink.cfgif using a different SWD probe. - To switch to the S140 v7 SoftDevice (app start at
0x27000, slightly larger app region), addboard_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ldtoplatformio.iniand flashbin/generic/Meshtastic_7.3.0_bootloader-0.9.2_s140_7.3.0.hexvia SWD. The v6 SoftDevice cannot be upgraded via UF2 - SWD is required.