增加mini模型

This commit is contained in:
2026-07-19 15:13:41 +08:00
parent 9237cf9012
commit fbbfcf072f
6 changed files with 273 additions and 41 deletions
@@ -8,7 +8,9 @@ DIY Meshtastic node variant based on the RF-BM-ND05 nRF52840 module.
- **LF clock**: internal RC (`USE_LFRC`) - RF-BM-ND05 has no 32.768 kHz crystal; using - **LF clock**: internal RC (`USE_LFRC`) - RF-BM-ND05 has no 32.768 kHz crystal; using
`USE_LFXO` without a crystal makes SoftDevice hang in `RTC1_IRQHandler` waiting `USE_LFXO` without a crystal makes SoftDevice hang in `RTC1_IRQHandler` waiting
for LFCLK, causing LED-stuck-on and silent BLE failure. for LFCLK, causing LED-stuck-on and silent BLE failure.
- **LoRa**: multi-module compatible (SX1262 / SX1268 / RF95 / LLCC68 / LR1121 / LR2021) with TCXO - **LoRa**: E22-400M33S (SX1268 + 33dBm PA, 2W, 433MHz) - `SX126X_MAX_POWER=8`,
`TX_GAIN_LORA=25` required (22dBm default overdrives PA to ~47dBm, causing current
spikes and system reset even at low tx_power settings)
- **GPS**: u-blox (no EN pin) - **GPS**: u-blox (no EN pin)
- **Battery ADC**: 0.5 voltage divider (equal resistors) - **Battery ADC**: 0.5 voltage divider (equal resistors)
@@ -111,21 +111,13 @@ MOONSHINE NRF52 PIN ASSIGNMENT (RF-BM-ND05)
#define LORA_CS (0 + 29) // P0.29 #define LORA_CS (0 + 29) // P0.29
// LORA MODULES // LORA MODULES
#define USE_LLCC68 #define USE_SX1268 // E22-400M33S uses SX1268 (433MHz)
#define USE_SX1262
#define USE_RF95
#define USE_SX1268
#define USE_LR1121
#define USE_LR2021
// RF95 CONFIG // E22-400M33S: 33dBm/2W module with ~25dB PA gain
#define LORA_DIO0 (0 + 22) // P0.22 BUSY // SX1268 outputs 8dBm -> PA -> 33dBm (2W)
#define LORA_DIO1 (0 + 21) // P0.21 IRQ // 22dBm default would overdrive PA to ~47dBm, causing current spikes and system reset
#define LORA_RESET (0 + 23) // P0.23 NRST #define SX126X_MAX_POWER 8
#define TX_GAIN_LORA 25
// RX/TX for RFM95/SX127x
#define RF95_RXEN (0 + 11) // P0.11
#define RF95_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin. If not, TXEN must be connected.
// SX126X CONFIG // SX126X CONFIG
#define SX126X_CS (0 + 29) // P0.29 FIXME - we really should define LORA_CS instead #define SX126X_CS (0 + 29) // P0.29 FIXME - we really should define LORA_CS instead
@@ -137,32 +129,6 @@ MOONSHINE NRF52 PIN ASSIGNMENT (RF-BM-ND05)
#define SX126X_RXEN (0 + 11) // P0.11 #define SX126X_RXEN (0 + 11) // P0.11
#define SX126X_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin. If not, TXEN must be connected. #define SX126X_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin. If not, TXEN must be connected.
// LR1121
#ifdef USE_LR1121
#define LR1121_IRQ_PIN (0 + 21) // P0.21 IRQ
#define LR1121_NRESET_PIN LORA_RESET // P0.23 NRST
#define LR1121_BUSY_PIN (0 + 22) // P0.22 BUSY
#define LR1121_SPI_NSS_PIN LORA_CS // P0.29
#define LR1121_SPI_SCK_PIN LORA_SCK
#define LR1121_SPI_MOSI_PIN LORA_MOSI
#define LR1121_SPI_MISO_PIN LORA_MISO
#define LR11X0_DIO3_TCXO_VOLTAGE 1.8
#define LR11X0_DIO_AS_RF_SWITCH
#endif
// LR2021
#ifdef USE_LR2021
#define LR2021_IRQ_PIN (0 + 21) // P0.21 IRQ
#define LR2021_NRESET_PIN LORA_RESET // P0.23 NRST
#define LR2021_BUSY_PIN (0 + 22) // P0.22 BUSY
#define LR2021_SPI_NSS_PIN LORA_CS // P0.29
#define LR2021_DIO3_TCXO_VOLTAGE 1.8
#define LR2021_DIO_AS_RF_SWITCH
#define LR2021_IRQ_DIO_NUM 9 // DIO9 -> P0.21
#endif
// #define SX126X_MAX_POWER 8 set this if using a high-power board!
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 #define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define TCXO_OPTIONAL // make it so that the firmware can try both TCXO and XTAL #define TCXO_OPTIONAL // make it so that the firmware can try both TCXO and XTAL
@@ -0,0 +1,17 @@
; Moonshine NRF52 mini - minimal DIY variant (nRF52840 + RA-01S-P SX1262)
[env:moonshine_NRF52_node_mini]
extends = nrf52840_base
board = adafruit_feather_nrf52840
board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld
build_flags = ${nrf52840_base.build_flags}
-I variants/nrf52840/diy/moonshine_NRF52_mini
-D PRIVATE_HW
-D MESHTASTIC_EXCLUDE_I2C=1
-D MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR=1
-D MESHTASTIC_EXCLUDE_INPUTBROKER=1
-D MESHTASTIC_EXCLUDE_ACCELEROMETER=1
-D MESHTASTIC_EXCLUDE_MAGNETOMETER=1
-D MESHTASTIC_EXCLUDE_GPS=1
-D MESHTASTIC_EXCLUDE_SCREEN=1
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/diy/moonshine_NRF52_mini>
debug_tool = jlink
@@ -0,0 +1,100 @@
# Moonshine NRF52 Mini
Minimal DIY Meshtastic node variant: nRF52840 + RA-01S-P (SX1262) LoRa module
with a single status LED on P0.13. No display, GPS, button, or battery ADC -
LoRa-only minimal system.
## 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=22`
- `TCXO_OPTIONAL` (no TCXO on module - firmware tries XTAL first)
- DIO2 drives TXEN internally; RXEN is controlled by `P0.17`
- **LED**: status LED on P0.13 (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.13 | 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.13 is wired (no button, battery ADC, GPS, or display).
The board has no user button, so DFU entry is via the 1200 bps touch or SWD.
## Build & Flash
### Build
```sh
pio run -e moonshine_NRF52_node_mini
```
Uses `PRIVATE_HW` (HardwareModel 255) - no protobuf or `architecture.h` changes
required.
The build links against `nrf52840_s140_v7.ld`, so the application is linked to
start at `0x27000` and requires the S140 SoftDevice v7.x to be present on the
chip at `0x0`-`0x26FFF` (or the Adafruit nRF52 UF2 "bright-future" bootloader,
which bundles its own SoftDevice). The build output (`firmware-*.hex` / `.uf2`)
contains **only the application**, not the SoftDevice.
### Flash (first time on a bare nRF52840)
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.
The S140 v7.3.0 SoftDevice hex is shipped in this repo at
`bin/s140_nrf52_7.3.0_softdevice.hex`. 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).
```sh
# Full flow: recover (erase all + unlock) -> 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/s140_nrf52_7.3.0_softdevice.hex verify; \
program .pio/build/moonshine_NRF52_node_mini/firmware-moonshine_NRF52_node_mini-*.hex verify; \
reset run; exit"
```
### Flash (app only, SoftDevice already present)
When the SoftDevice is already on the chip and only the application changed
(e.g. after editing the variant and rebuilding), skip `nrf52_recover` and the
SoftDevice line:
```sh
C:/openocd/bin/openocd.exe -s C:/openocd/share/openocd/scripts \
-f interface/cmsis-dap.cfg -f target/nrf52.cfg \
-c "init; \
program .pio/build/moonshine_NRF52_node_mini/firmware-moonshine_NRF52_node_mini-*.hex verify; \
reset run; exit"
```
### Notes
- The firmware hex filename contains a commit hash (e.g. `2.8.0.421838f`); use
the actual file produced by `pio run` or a shell glob.
- The SoftDevice hex occupies `0x0`-`0x26498` (~156 KB) and does **not** write
UICR, so `nrf52_recover` is safe (UICR resets to defaults).
- Swap `interface/cmsis-dap.cfg` for `interface/jlink.cfg` or
`interface/stlink.cfg` if using a different SWD probe.
- No UF2 bootloader is installed in this flow, so subsequent updates must go
through BLE DFU (secure DFU service) or SWD again. To enable UF2 drag-and-drop
updates, flash an Adafruit nRF52 UF2 bootloader
(https://github.com/adafruit/Adafruit_nRF52_Bootloader) at `0x0` in place of
the bare SoftDevice - the bootloader bundles its own SoftDevice.
@@ -0,0 +1,36 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
const uint32_t g_ADigitalPinMap[] = {
// P0
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
// P1
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
void initVariant()
{
// No dedicated 3V3 enable pin on this board
}
@@ -0,0 +1,111 @@
#ifndef _VARIANT_MOONSHINE_NRF52_MINI_
#define _VARIANT_MOONSHINE_NRF52_MINI_
/** Master clock frequency */
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/*
MOONSHINE NRF52 MINI PIN ASSIGNMENT (minimal system: nRF52840 + RA-01S-P)
| Pin | Function | Notes |
| ----- | ----------- | --------------------------- |
| P0.02 | SPI MISO | LORA_MISO |
| P0.09 | LORA RESET | SX126X_RESET |
| P0.10 | LORA DIO1 | SX126X_DIO1 (IRQ) |
| P0.13 | LED | Status LED (active high) |
| P0.17 | LORA RXEN | SX126X_RXEN |
| P0.29 | LORA BUSY | SX126X_BUSY |
| P1.11 | SPI SCK | LORA_SCK |
| P1.13 | LORA CS | SX126X_CS |
| P1.15 | SPI MOSI | LORA_MOSI |
*/
// Number of pins defined in PinDescription array
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
#define NUM_ANALOG_INPUTS (0)
#define NUM_ANALOG_OUTPUTS (0)
// No dedicated 3V3 enable pin on this board
#define PIN_3V3_EN (-1)
// LED - status LED on P0.13 (active high)
#define PIN_LED1 (0 + 13) // P0.13
#define LED_BLUE PIN_LED1
#define LED_STATE_ON 1 // State when LED is lit (active high)
// Analog pins - no ADC devices wired
#define PIN_A0 (-1)
#define PIN_AREF (-1)
#define ADC_RESOLUTION 14
// UART interfaces - no physical serial ports wired. The Adafruit nRF52 core
// always declares Serial1/Serial2 and requires these macros to exist; -1 means
// no pin assigned. SerialModule.cpp also references Serial2 unconditionally.
#define PIN_SERIAL1_RX (-1)
#define PIN_SERIAL1_TX (-1)
#define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (-1)
// WIRE - no physical I2C devices, but WIRE_INTERFACES_COUNT must be >= 1 so the
// Adafruit core declares the Wire singleton (referenced by display lib deps).
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (32 + 4) // P1.04 - free pin, no I2C device wired
#define PIN_WIRE_SCL (0 + 11) // P0.11 - free pin, no I2C device wired
// Serial interfaces
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (0 + 2) // P0.02
#define PIN_SPI_MOSI (32 + 15) // P1.15
#define PIN_SPI_SCK (32 + 11) // P1.11
#define LORA_MISO PIN_SPI_MISO
#define LORA_MOSI PIN_SPI_MOSI
#define LORA_SCK PIN_SPI_SCK
#define LORA_CS (32 + 13) // P1.13
// GPS - no GPS hardware; sentinels required by GPS code paths
#define GPS_RX_PIN (-1)
#define GPS_TX_PIN (-1)
#define PIN_GPS_EN (-1)
#define PIN_GPS_PPS (-1)
// LORA MODULE - RA-01S-P (Ai-Thinker SX1262, no TCXO, internal RF switch, 22dBm)
#define USE_SX1262
// SX126X CONFIG
#define SX126X_CS (32 + 13) // P1.13 FIXME - we really should define LORA_CS instead
#define SX126X_DIO1 (0 + 10) // P0.10 IRQ
#define SX126X_DIO2_AS_RF_SWITCH // DIO2 drives TXEN for automatic TX/RX switching
#define SX126X_BUSY (0 + 29) // P0.29
#define SX126X_RESET (0 + 9) // P0.09
#define SX126X_RXEN (0 + 17) // P0.17
#define SX126X_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin. If not, TXEN must be connected.
#define SX126X_MAX_POWER 22 // RA-01S-P max is 22dBm
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define TCXO_OPTIONAL // RA-01S-P has no TCXO - firmware tries XTAL first, falls back to TCXO
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif