diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 7c46bee71..4bf9d3509 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -3,6 +3,7 @@ #include "configuration.h" #include "error.h" #include "mesh/NodeDB.h" +#include "meshUtils.h" // for pow_of_2 #ifdef ARCH_PORTDUINO #include "PortduinoGlue.h" #endif @@ -191,12 +192,28 @@ template bool SX126xInterface::reconfigure() // configure publicly accessible settings int err = lora.setSpreadingFactor(sf); - if (err != RADIOLIB_ERR_NONE) - RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); + if (err != RADIOLIB_ERR_NONE) { + LOG_ERROR("SX126X setSpreadingFactor(%d) at BW %.1f kHz rejected (%s%d), attempting fallback", sf, bw, radioLibErr, err); + for (uint8_t fallbackSf = sf - 1; fallbackSf >= 5; fallbackSf--) { + err = lora.setSpreadingFactor(fallbackSf); + if (err == RADIOLIB_ERR_NONE) { + LOG_WARN("SX126X fell back to SF%d at BW %.1f kHz (requested SF%d), change modem preset to match", fallbackSf, bw, + sf); + this->sf = fallbackSf; + preambleTimeMsec = preambleLength * (pow_of_2(sf) / bw); + slotTimeMsec = computeSlotTimeMsec(); + break; + } + } + if (err != RADIOLIB_ERR_NONE) + RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); + } err = lora.setBandwidth(bw); - if (err != RADIOLIB_ERR_NONE) + if (err != RADIOLIB_ERR_NONE) { + LOG_ERROR("SX126X setBandwidth(%.1f) rejected (%s%d)", bw, radioLibErr, err); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); + } err = lora.setCodingRate(cr); if (err != RADIOLIB_ERR_NONE) diff --git a/variants/esp32c3/diy/moonshine_ESP_C3/platformio.ini b/variants/esp32c3/diy/moonshine_ESP_C3/platformio.ini index 314a7ae6c..217dcb111 100644 --- a/variants/esp32c3/diy/moonshine_ESP_C3/platformio.ini +++ b/variants/esp32c3/diy/moonshine_ESP_C3/platformio.ini @@ -8,4 +8,5 @@ build_flags = -D PRIVATE_HW -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_CDC_ON_BOOT=1 + -D USERPREFS_LORACONFIG_MODEM_PRESET=meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW -I variants/esp32c3/diy/moonshine_ESP_C3 diff --git a/variants/esp32c3/diy/moonshine_ESP_C3/readme.md b/variants/esp32c3/diy/moonshine_ESP_C3/readme.md index 8dc641ca6..545204c08 100644 --- a/variants/esp32c3/diy/moonshine_ESP_C3/readme.md +++ b/variants/esp32c3/diy/moonshine_ESP_C3/readme.md @@ -24,9 +24,9 @@ commenting/uncommenting the `#define` lines at the top of `variant.h`: Only one module should be enabled at a time. -| Module | Chip | Power | `USE_*` | `TX_GAIN_LORA` | `SX126X_MAX_POWER` | Total output | -| ------------ | ------ | ------------ | ------------ | -------------- | ------------------ | --------------- | -| E220-400M30S | LLCC68 | 30 dBm (1 W) | `USE_LLCC68` | 8 | 22 | 22 + 8 = 30 dBm | +| Module | Chip | Power | `USE_*` | `TX_GAIN_LORA` | `SX126X_MAX_POWER` | Total output | +| ------------ | ------ | ------------ | ------------ | -------------- | ------------------ | ---------------- | +| E220-400M30S | LLCC68 | 30 dBm (1 W) | `USE_LLCC68` | 8 | 22 | 22 + 8 = 30 dBm | | E220-400M33S | LLCC68 | 33 dBm (2 W) | `USE_LLCC68` | 11 | 22 | 22 + 11 = 33 dBm | | E22-400M33S | SX1268 | 33 dBm (2 W) | `USE_SX1268` | 25 | 8 | 8 + 25 = 33 dBm | @@ -42,21 +42,47 @@ See `variants/nrf52840/diy/moonshine_NRF52/variant.h` for the same module wired with a more conservative power profile (`SX126X_MAX_POWER = 2`, ~27 dBm output). +### LLCC68 modem preset limitation + +The E220-400M30S and E220-400M33S use the LLCC68 chip, which does **not** +support all spreading-factor/bandwidth combinations: + +| Bandwidth | Max SF | +| --------- | ------ | +| 125 kHz | SF9 | +| 250 kHz | SF10 | +| 500 kHz | SF11 | + +SF12 is never supported on the LLCC68. + +The Meshtastic default preset **LongFast** (BW 250 kHz / SF11) is invalid +for the LLCC68. This variant therefore ships with **MediumSlow** +(BW 250 kHz / SF10) as the default preset via +`USERPREFS_LORACONFIG_MODEM_PRESET`. + +If you switch to the E22-400M33S (SX1268), you can safely change the preset +back to LongFast or any other - the SX1268 supports the full SF/BW range. + +**Note**: All nodes in a mesh must use the same modem preset to communicate. +If other nodes in your network are on LongFast, either switch them to +MediumSlow as well, or use LongTurbo (BW 500 kHz / SF11) which the LLCC68 +also supports. + ## Pin map -| Function | GPIO | Notes | -| ------------- | ---- | -------------------------------------- | -| BUTTON | 9 | BOOT button | -| LED | 0 | Active high (`LED_STATE_ON = 1`) | -| BATTERY_ADC | 1 | 0.5 divider (`ADC_MULTIPLIER = 2.0`) | -| LORA_RXEN | 2 | RF switch RX enable | -| LORA_DIO1 | 3 | IRQ | -| LORA_BUSY | 4 | | -| LORA_RESET | 5 | | -| LORA_MISO | 6 | | -| LORA_MOSI | 7 | | -| LORA_CS | 8 | | -| LORA_SCK | 10 | | +| Function | GPIO | Notes | +| ----------- | ---- | ------------------------------------ | +| BUTTON | 9 | BOOT button | +| LED | 0 | Active high (`LED_STATE_ON = 1`) | +| BATTERY_ADC | 1 | 0.5 divider (`ADC_MULTIPLIER = 2.0`) | +| LORA_RXEN | 2 | RF switch RX enable | +| LORA_DIO1 | 3 | IRQ | +| LORA_BUSY | 4 | | +| LORA_RESET | 5 | | +| LORA_MISO | 6 | | +| LORA_MOSI | 7 | | +| LORA_CS | 8 | | +| LORA_SCK | 10 | | DIO2 drives the module's TXEN pin internally (`SX126X_DIO2_AS_RF_SWITCH`), so `SX126X_TXEN` is left as `RADIOLIB_NC`. `SX126X_RXEN` is driven by GPIO2.