Skip to content

Commit 551f36f

Browse files
committed
when doing AGC reset, call Calibrate(0x7F)
1. warm sleep 2. wake to stdby 3. Calibrate(0x7F) to reset all internal blocks 4. re-apply DIO2 RF / boosted gain & register patch to make sure everything is as it was
1 parent 86edfe2 commit 551f36f

6 files changed

Lines changed: 114 additions & 5 deletions

File tree

src/helpers/radiolib/CustomLLCC68Wrapper.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,30 @@ class CustomLLCC68Wrapper : public RadioLibWrapper {
1919
int sf = ((CustomLLCC68 *)_radio)->spreadingFactor;
2020
return packetScoreInt(snr, sf, packet_len);
2121
}
22+
23+
void doResetAGC() override {
24+
auto* radio = (CustomLLCC68 *)_radio;
25+
radio->sleep(true);
26+
radio->standby(RADIOLIB_SX126X_STANDBY_RC, true);
27+
uint8_t calData = RADIOLIB_SX126X_CALIBRATE_ALL;
28+
radio->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE, &calData, 1, true, false);
29+
radio->mod->hal->delay(5);
30+
uint32_t start = millis();
31+
while (radio->mod->hal->digitalRead(radio->mod->getGpio())) {
32+
if (millis() - start > 50) break;
33+
radio->mod->hal->yield();
34+
}
35+
#ifdef SX126X_DIO2_AS_RF_SWITCH
36+
radio->setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
37+
#endif
38+
#ifdef SX126X_RX_BOOSTED_GAIN
39+
radio->setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
40+
#endif
41+
#ifdef SX126X_REGISTER_PATCH
42+
uint8_t r_data = 0;
43+
radio->readRegister(0x8B5, &r_data, 1);
44+
r_data |= 0x01;
45+
radio->writeRegister(0x8B5, &r_data, 1);
46+
#endif
47+
}
2248
};

src/helpers/radiolib/CustomSTM32WLxWrapper.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,30 @@ class CustomSTM32WLxWrapper : public RadioLibWrapper {
2020
int sf = ((CustomSTM32WLx *)_radio)->spreadingFactor;
2121
return packetScoreInt(snr, sf, packet_len);
2222
}
23+
24+
void doResetAGC() override {
25+
auto* radio = (CustomSTM32WLx *)_radio;
26+
radio->sleep(true);
27+
radio->standby(RADIOLIB_SX126X_STANDBY_RC, true);
28+
uint8_t calData = RADIOLIB_SX126X_CALIBRATE_ALL;
29+
radio->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE, &calData, 1, true, false);
30+
radio->mod->hal->delay(5);
31+
uint32_t start = millis();
32+
while (radio->mod->hal->digitalRead(radio->mod->getGpio())) {
33+
if (millis() - start > 50) break;
34+
radio->mod->hal->yield();
35+
}
36+
#ifdef SX126X_DIO2_AS_RF_SWITCH
37+
radio->setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
38+
#endif
39+
#ifdef SX126X_RX_BOOSTED_GAIN
40+
radio->setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
41+
#endif
42+
#ifdef SX126X_REGISTER_PATCH
43+
uint8_t r_data = 0;
44+
radio->readRegister(0x8B5, &r_data, 1);
45+
r_data |= 0x01;
46+
radio->writeRegister(0x8B5, &r_data, 1);
47+
#endif
48+
}
2349
};

src/helpers/radiolib/CustomSX1262Wrapper.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,34 @@ class CustomSX1262Wrapper : public RadioLibWrapper {
2222
virtual void powerOff() override {
2323
((CustomSX1262 *)_radio)->sleep(false);
2424
}
25+
26+
void doResetAGC() override {
27+
auto* radio = (CustomSX1262 *)_radio;
28+
// Warm sleep powers down analog frontend (resets AGC gain state)
29+
radio->sleep(true);
30+
// Wake to STDBY_RC for calibration
31+
radio->standby(RADIOLIB_SX126X_STANDBY_RC, true);
32+
// Recalibrate all blocks (ADC, PLL, image, oscillators)
33+
uint8_t calData = RADIOLIB_SX126X_CALIBRATE_ALL;
34+
radio->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE, &calData, 1, true, false);
35+
radio->mod->hal->delay(5);
36+
uint32_t start = millis();
37+
while (radio->mod->hal->digitalRead(radio->mod->getGpio())) {
38+
if (millis() - start > 50) break;
39+
radio->mod->hal->yield();
40+
}
41+
// Re-apply RX settings that calibration may reset
42+
#ifdef SX126X_DIO2_AS_RF_SWITCH
43+
radio->setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
44+
#endif
45+
#ifdef SX126X_RX_BOOSTED_GAIN
46+
radio->setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
47+
#endif
48+
#ifdef SX126X_REGISTER_PATCH
49+
uint8_t r_data = 0;
50+
radio->readRegister(0x8B5, &r_data, 1);
51+
r_data |= 0x01;
52+
radio->writeRegister(0x8B5, &r_data, 1);
53+
#endif
54+
}
2555
};

src/helpers/radiolib/CustomSX1268Wrapper.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,30 @@ class CustomSX1268Wrapper : public RadioLibWrapper {
1919
int sf = ((CustomSX1268 *)_radio)->spreadingFactor;
2020
return packetScoreInt(snr, sf, packet_len);
2121
}
22+
23+
void doResetAGC() override {
24+
auto* radio = (CustomSX1268 *)_radio;
25+
radio->sleep(true);
26+
radio->standby(RADIOLIB_SX126X_STANDBY_RC, true);
27+
uint8_t calData = RADIOLIB_SX126X_CALIBRATE_ALL;
28+
radio->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE, &calData, 1, true, false);
29+
radio->mod->hal->delay(5);
30+
uint32_t start = millis();
31+
while (radio->mod->hal->digitalRead(radio->mod->getGpio())) {
32+
if (millis() - start > 50) break;
33+
radio->mod->hal->yield();
34+
}
35+
#ifdef SX126X_DIO2_AS_RF_SWITCH
36+
radio->setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
37+
#endif
38+
#ifdef SX126X_RX_BOOSTED_GAIN
39+
radio->setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
40+
#endif
41+
#ifdef SX126X_REGISTER_PATCH
42+
uint8_t r_data = 0;
43+
radio->readRegister(0x8B5, &r_data, 1);
44+
r_data |= 0x01;
45+
radio->writeRegister(0x8B5, &r_data, 1);
46+
#endif
47+
}
2248
};

src/helpers/radiolib/RadioLibWrappers.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ void RadioLibWrapper::triggerNoiseFloorCalibrate(int threshold) {
5353
}
5454
}
5555

56+
void RadioLibWrapper::doResetAGC() {
57+
_radio->sleep(); // warm sleep to reset analog frontend
58+
}
59+
5660
void RadioLibWrapper::resetAGC() {
5761
// make sure we're not mid-receive of packet!
5862
if ((state & STATE_INT_READY) != 0 || isReceivingPacket()) return;
5963

60-
// Warm sleep powers down the entire analog frontend (including AGC), forcing a
61-
// fresh gain calibration on the next startReceive(). A plain standby->startReceive
62-
// cycle does NOT reset the AGC — the analog state can persist across STDBY_RC.
63-
// The ~1-2 ms sleep gap is negligible vs the preamble budget (131 ms at SF11/BW250).
64-
_radio->sleep();
64+
doResetAGC();
6565
state = STATE_IDLE; // trigger a startReceive()
6666
}
6767

src/helpers/radiolib/RadioLibWrappers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class RadioLibWrapper : public mesh::Radio {
1616
void startRecv();
1717
float packetScoreInt(float snr, int sf, int packet_len);
1818
virtual bool isReceivingPacket() =0;
19+
virtual void doResetAGC();
1920

2021
public:
2122
RadioLibWrapper(PhysicalLayer& radio, mesh::MainBoard& board) : _radio(&radio), _board(&board) { n_recv = n_sent = 0; }

0 commit comments

Comments
 (0)