diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 7da9325d46f..49757b3579e 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -1481,6 +1481,17 @@ void RadioInterface::limitPower(int8_t loraMaxPower) if (power > loraMaxPower) // Clamp power to maximum defined level power = loraMaxPower; + // Floor as well as ceiling. On a board that declares an external PA gain the + // subtraction above can push the level below what the radio can physically + // emit: the chip then rejects the setting and stops transmitting altogether + // rather than transmitting weakly. Measured on a board with + // TX_GAIN_LORA 25 and tx_power -9: "Final Tx power: -34 dBm" and no packet + // ever left the queue. + if (power < RADIO_MIN_TX_POWER_DBM) { + LOG_WARN("Tx power %d dBm below radio minimum, raising to %d dBm", power, RADIO_MIN_TX_POWER_DBM); + power = RADIO_MIN_TX_POWER_DBM; + } + LOG_INFO("Final Tx power: %d dBm", power); } diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index e76b977bf40..43814fe3595 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -17,6 +17,15 @@ typedef struct _meshtastic_Config_LoRaConfig meshtastic_Config_LoRaConfig; #define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission +// Lowest level the radio can actually emit. Below this the chip rejects the +// setting and transmits nothing at all, so limitPower() floors here rather than +// handing the driver an impossible value. -9 dBm covers SX126x (RadioLib's +// SX1268::checkOutputPower allows -9..22); boards with a different floor can +// override it in variant.h. +#ifndef RADIO_MIN_TX_POWER_DBM +#define RADIO_MIN_TX_POWER_DBM -9 +#endif + #define MAX_LORA_PAYLOAD_LEN 255 // max length of 255 per Semtech's datasheets on SX12xx #define MESHTASTIC_HEADER_LENGTH 16 #define MESHTASTIC_PKC_OVERHEAD 12