fix(kiss): periodic noise floor calibration and AGC reset

- Trigger noise floor calibration every 2s and AGC reset every 30s in main loop.
- Reorder loop to match Dispatcher: calibrate + radio.loop() before AGC reset
  and recvRaw() so RSSI is never sampled right after startReceive().
- Update protocol doc with calibration intervals and typical noise floor range.
- Variant platformio.ini updates (heltec_v3, rak4631).
This commit is contained in:
agessaman 2026-02-03 20:58:37 -08:00
parent e03f311e51
commit 0fb570338f
4 changed files with 54 additions and 9 deletions

View file

@ -12,9 +12,14 @@
#include <SPIFFS.h>
#endif
#define NOISE_FLOOR_CALIB_INTERVAL_MS 2000 // match Dispatcher default
#define AGC_RESET_INTERVAL_MS 30000 // periodic RX restart so AGC doesn't drift (repeater uses same via prefs)
StdRNG rng;
mesh::LocalIdentity identity;
KissModem* modem;
static uint32_t next_noise_floor_calib_ms = 0;
static uint32_t next_agc_reset_ms = 0;
void halt() {
while (1) ;
@ -94,7 +99,16 @@ void loop() {
uint8_t packet[KISS_MAX_PACKET_SIZE];
uint16_t len;
// Match Dispatcher order: noise floor calib + loop() first, so we never sample RSSI in the same
// iteration as startReceive() (AGC reset -> recvRaw below). Sampling right after startReceive()
// can yield settling/cold RSSI and drive the floor toward -120.
if ((uint32_t)(millis() - next_noise_floor_calib_ms) >= NOISE_FLOOR_CALIB_INTERVAL_MS) {
radio_driver.triggerNoiseFloorCalibrate(0); // 0 = no interference threshold (KISS has no prefs)
next_noise_floor_calib_ms = millis();
}
radio_driver.loop();
if (modem->getPacketToSend(packet, &len)) {
radio_driver.startSendRaw(packet, len);
while (!radio_driver.isSendComplete()) {
@ -104,14 +118,15 @@ void loop() {
modem->onTxComplete(true);
}
if ((uint32_t)(millis() - next_agc_reset_ms) >= AGC_RESET_INTERVAL_MS) {
radio_driver.resetAGC(); // next recvRaw() will startReceive() and reset AGC so RSSI/noise floor don't stick at -120
next_agc_reset_ms = millis();
}
uint8_t rx_buf[256];
int rx_len = radio_driver.recvRaw(rx_buf, sizeof(rx_buf));
if (rx_len > 0) {
int8_t snr = (int8_t)(radio_driver.getLastSNR() * 4);
int8_t rssi = (int8_t)radio_driver.getLastRSSI();
modem->onPacketReceived(snr, rssi, rx_buf, rx_len);
}
radio_driver.loop();
}