feat: Add NiceRF LoRa2021 (LR2021 Gen 4) variant support#2739
Conversation
Adds MeshCore support for the NiceRF LoRa2021 module (Semtech LR2021 Gen 4) on ESP32-C3_Mini_V1 development board. RadioLib LR2021 class (extends LRxxxx -> PhysicalLayer). This is a separate class from LR1121 (extends LR11x0). Key differences from SX1262: - IRQ on DIO9 (not DIO1): irqDioNum=9 + setDioFunction(9) - setRxBoostedGainMode(uint8_t 0-7) vs bool - No DIO2-as-RF-switch (NiceRF handles internally) - Crystal oscillator (XTAL): tcxoVoltage=0 - getPacketLength() override handles header errors Uses ESP-IDF SPI HAL (EspIdfHal) because Arduino SPIClass returns all-zero responses on the ESP32-C3_Mini_V1 with non-default SPI pins. Direct spi_bus_initialize() works correctly. See EspIdfHal.h for details. Build targets: companion_usb/ble/wifi, repeater, room_server, secure_chat, kiss_modem. All verified building. Hardware tested: radio init OK, noise floor -102 dBm, companion connects via meshcore-cli v1.5.7, advert TX verified.
|
Community mesh test (Berlin): Prior to opening this PR, I tested the LR2021 + ESP32-C3 against the live Berlin MeshCore community mesh:
|
|
Looks good. Just a small suggestion: I'd probably move the IDF Hal to /src/helpers/radiolib, as it's related only to RadioLib and could potentially be re-used by other variants |
|
Thanks for the detailed review @oltaco! I'm working through all 4 items:
Will push updates to this branch soon. |
… constants (meshcore-dev#3), make irqDioNum configurable (meshcore-dev#4)
…, keep EspIdfHal as opt-in via USE_ESPIDF_HAL
…estion Move the ESP-IDF SPI HAL from the variant-specific directory to the shared helpers/radiolib/ directory, making it available for reuse by other ESP32 variants that may need the same SPI workaround. Addresses feedback from @ripplebiz: 'I'd probably move the IDF Hal to /src/helpers/radiolib, as it's related only to RadioLib and could potentially be re-used by other variants' Also update the include path in target.cpp to use the shared location.
|
Thanks again @oltaco and @ripplebiz! All review items are now addressed and tested on real hardware. Latest commit: 05ad173. Review items resolved:
Build verification: All 7 LR2021 targets + 2 reference targets (Xiao_C3, Heltec_v3) compile clean. No regressions. 2-device hardware test: Two ESP32-C3 + LR2021 boards, ~10cm apart, EU MeshCore PHY (869.618 MHz, SF8, BW62.5):
Ready for another pass when you have a moment. |
|
Full hardware test evidence (annotated serial logs, build matrix, wiring diagram, test timeline) published on Nostr: https://npub1l06qpv6kr4l4sfjqm30jcd0jdtqlrel5nhhdtxfprjdu6dfyns0qnghahp.nsite.lol/ Includes 2-device cross-board flood routing confirmation, all 9 build targets, and the EspIdfHal explanation. |
Enables USE_ESPIDF_HAL in platformio.ini to ensure reliable SPI communication on ESP32-C3 boards where SPIClass(0) may return zeros.
Summary
Adds MeshCore support for the NiceRF LoRa2021 module (Semtech LR2021 Gen 4) on ESP32-C3_Mini_V1 development board.
Hardware
RadioLib Class
Uses the
LR2021class (extendsLRxxxx→PhysicalLayer). This is a separate RadioLib class fromLR1121(which extendsLR11x0). RadioLib v7.6.0 (already in MeshCore deps) includes LR2021 support.Key differences from SX1262:
irqDioNum = 9+setDioFunction(9)setRxBoostedGainMode(uint8_t level)takes 0-7, notbooltcxoVoltage = 0getPacketLength()override handles header errors (same as LR1110 pattern)Known Issue: Arduino SPI
The Arduino
SPIClasson ESP32-C3_Mini_V1 returns all-zero SPI responses, causingRADIOLIB_ERR_SPI_CMD_FAILED(-707). The same hardware works with ESP-IDF'sspi_bus_initialize().This variant includes
EspIdfHal.h— a custom RadioLib HAL that bypasses ArduinoSPIClassand uses ESP-IDF'sspi_bus_initialize()/spi_device_polling_transmit()directly. This is the same approach used in our ESP-IDF tracker firmware.Root cause hypothesis: The ESP32-C3 has one SPI peripheral (FSPI/SPI2_HOST). The Arduino SPIClass may not properly reconfigure FSPI when the SPI pins differ from the default boot-time configuration (our board uses GPIO2/6/7 instead of default SPI pins).
If anyone has insight into why Arduino SPI fails on this board, I would love to fix this properly and remove the custom HAL.
Build Targets
All verified building against
devbranch:LR2021_companion_radio_usbLR2021_repeaterLR2021_room_serverLR2021_secure_chatLR2021_kiss_modemAll fit within ESP32-C3 4MB flash. Reference build (
Heltec_v3_companion_radio_ble) passes — no regressions.Files Added
Radio Helpers (in
src/helpers/radiolib/)CustomLR2021.h— ExtendsLR2021, addsstd_init(),isReceiving(),getPacketLength()overrideCustomLR2021Wrapper.h— ExtendsRadioLibWrapper, implementssetParams(),doResetAGC(),getSpreadingFactor()Board Variant (in
variants/nicerf_lr2021/)platformio.ini— 5 build environments with LR2021 pin mappingtarget.h/target.cpp— Radio init via EspIdfHalNiceRFLR2021Board.h— Board class (deep sleep, battery ADC)EspIdfHal.h— ESP-IDF SPI HAL (documented workaround)Board Definition (shared)
boards/esp32c3_supermini.json— ESP32-C3 SuperMini V1 board definitionvariants/esp32c3_supermini/pins_arduino.h— Pin mapping (D0-D10 = GPIO0-GPIO10)Testing
devbranchRelated
Pin Mapping