Implement 'agc' reset for SX126x & LR11x0 chip families (#9705)

* Implement 'agc' reset for SX126x chip family

There's no actual agc on SX126x chips but you can reset the analog
registers by doing a warm sleep & running calibration.

* Address PR comments & implement for LR11x0 too

* calibrate for configured frequency band

* Gate LR11X0_AGC_RESET
This commit is contained in:
Wessel
2026-02-24 08:03:25 -06:00
committed by GitHub
parent 607b631114
commit 02d42f87d3
7 changed files with 114 additions and 0 deletions
+55
View File
@@ -434,6 +434,61 @@ template <typename T> bool SX126xInterface<T>::sleep()
return true;
}
template <typename T> void SX126xInterface<T>::resetAGC()
{
// Safety: don't reset mid-packet
if (sendingPacket != NULL || (isReceiving && isActivelyReceiving()))
return;
LOG_DEBUG("SX126x AGC reset: warm sleep + Calibrate(0x7F)");
// 1. Warm sleep — powers down the entire analog frontend, resetting AGC state.
// A plain standby→startReceive cycle does NOT reset the AGC.
lora.sleep(true);
// 2. Wake to RC standby for stable calibration
lora.standby(RADIOLIB_SX126X_STANDBY_RC, true);
// 3. Calibrate all blocks (ADC, PLL, image, RC oscillators)
uint8_t calData = RADIOLIB_SX126X_CALIBRATE_ALL;
module.SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE, &calData, 1, true, false);
// 4. Wait for calibration to complete (BUSY pin goes low)
module.hal->delay(5);
uint32_t start = millis();
while (module.hal->digitalRead(module.getGpio())) {
if (millis() - start > 50)
break;
module.hal->yield();
}
if (module.hal->digitalRead(module.getGpio())) {
LOG_WARN("SX126x AGC reset: calibration did not complete within 50ms");
startReceive();
return;
}
// 5. Re-calibrate image rejection for actual operating frequency
// Calibrate(0x7F) defaults to 902-928 MHz which is wrong for other regions.
lora.calibrateImage(getFreq());
// Re-apply settings that calibration may have reset
// DIO2 as RF switch
#ifdef SX126X_DIO2_AS_RF_SWITCH
lora.setDio2AsRfSwitch(true);
#elif defined(ARCH_PORTDUINO)
if (portduino_config.dio2_as_rf_switch)
lora.setDio2AsRfSwitch(true);
#endif
// RX boosted gain mode
lora.setRxBoostedGainMode(config.lora.sx126x_rx_boosted_gain);
// 6. Resume receiving
startReceive();
}
/** Control PA mode for GC1109 FEM - CPS pin selects full PA (txon=true) or bypass mode (txon=false) */
template <typename T> void SX126xInterface<T>::setTransmitEnable(bool txon)
{