Skip to content

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

Merged
thebentern merged 4 commits intomeshtastic:developfrom
weebl2000:implement-agc-reset-sx126x
Feb 24, 2026
Merged

Implement 'agc' reset for SX126x & LR11x0 chip families#9705
thebentern merged 4 commits intomeshtastic:developfrom
weebl2000:implement-agc-reset-sx126x

Conversation

@weebl2000
Copy link
Contributor

@weebl2000 weebl2000 commented Feb 21, 2026

There's no actual agc on SX126x chips but you can reset the analog registers by doing a warm sleep & running calibration. I saw there were earlier attempts #8163 but reverted in #9702. I've built this firmware for a Heltec Wireless Tracker v1.2 and it builds & runs fine.

I looked into the docs and implemented it here, ported the changes to meshtastic too.

  • tried to simply explicitly call sleep briefly to reset AGC -> not sufficient it seems
  • do more thorough reset using Calibrate (0x7F) -> success
  • should work on all SX126x based chips by using Calibrate(0x7F)
  • should work on all LR11x0 based chips by using Calibrate(0x3F)
  • default calibration is in 902-928 MHz range, made sure to follow up with actual configured frequency

I've referenced SX1262 datasheet to implement the calibration reset.

  • p25 4.3 ,64-65 table 12-1 listing ΣΔ ADC architecture
  • p55 table 9-1 sleep enable vs stdby_rc enable
  • p55 9.2 states which blocks can be calibrated
  • p66 warm sleep restores register state confirms we need more aggressive Calibrate(0x7F) reset
  • p73 total calibration time is 3.5 ms and must be launched in STDBY_RC mode

For LR1110 similar implementation, the 'AGC' is completely black boxed behind firmware so you can only reset it by resetting registers.

LR1110 datasheet page 9 section 1.2.1 states:
•Air interface fully compatible with the SX1261/2/8 family

So reset is very similar.

Also see LR1110 user docs

@github-actions github-actions bot added the hardware-support Hardware related: new devices or modules, problems specific to hardware label Feb 21, 2026
@thebentern thebentern requested review from GUVWAF and Copilot February 21, 2026 14:22
@thebentern
Copy link
Contributor

Since I can't request his review, tagging @compumike 😅

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements periodic AGC (Automatic Gain Control) reset functionality for SX126x radio chips to prevent stuck AGC gain states. The implementation follows datasheet specifications by performing a warm sleep followed by an aggressive calibration sequence (Calibrate 0x7F) every 60 seconds.

Changes:

  • Adds virtual resetAGC() method to RadioLibInterface base class (no-op by default)
  • Implements SX126x-specific AGC reset using warm sleep, RC standby, and full calibration
  • Integrates periodic AGC reset into main loop with 60-second interval

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/mesh/RadioLibInterface.h Adds AGC_RESET_INTERVAL_MS constant and virtual resetAGC() method declaration
src/mesh/RadioLibInterface.cpp Provides base no-op implementation of resetAGC()
src/mesh/SX126xInterface.h Declares resetAGC() override for SX126x chips
src/mesh/SX126xInterface.cpp Implements AGC reset sequence: warm sleep, RC standby, calibrate all blocks, restore settings, resume receiving
src/main.cpp Adds periodic AGC reset execution in main loop using Throttle pattern

@weebl2000 weebl2000 changed the title Implement 'agc' reset for SX126x chip family Implement 'agc' reset for SX126x & LR11x0 chip families Feb 21, 2026
@GUVWAF
Copy link
Member

GUVWAF commented Feb 21, 2026

Very nice digging work!

Do you have any idea how long the full resetAGC() procedure now takes? I think we'll need to balance the AGC_RESET_INTERVAL_MS value, as each reset will result in some time we are deaf and hence we may miss receiving packets. Or maybe there is a more clever way to determine when we need to do it? For example, it's probably not needed if we just received a packet successfully.

@weebl2000
Copy link
Contributor Author

weebl2000 commented Feb 21, 2026

Very nice digging work!

Do you have any idea how long the full resetAGC() procedure now takes? I think we'll need to balance the AGC_RESET_INTERVAL_MS value, as each reset will result in some time we are deaf and hence we may miss receiving packets. Or maybe there is a more clever way to determine when we need to do it? For example, it's probably not needed if we just received a packet successfully.

Should take around 3.5 millisceonds. See page 73 on the datasheet

image

@weebl2000 weebl2000 force-pushed the implement-agc-reset-sx126x branch from 8b35518 to eb855f2 Compare February 21, 2026 15:18
@GUVWAF
Copy link
Member

GUVWAF commented Feb 21, 2026

Should take around 3.5 millisceonds. See page 73 on the datasheet

Yes, that's the calibration itself, but I'm curious what it is including putting it to sleep, standby, and setting it to startReceive() (which calls standby() again) also.

@weebl2000
Copy link
Contributor Author

Should take around 3.5 millisceonds. See page 73 on the datasheet

Yes, that's the calibration itself, but I'm curious what it is including putting it to sleep, standby, and setting it to startReceive() (which calls standby() again) also.

For SX1262 I guess 10-50 ms max, probably closer to 10-12 ms realistically. LR1110 is probably 6-7 ms.

@GUVWAF
Copy link
Member

GUVWAF commented Feb 21, 2026

Okay, that's not too bad, but still enough to miss a preamble especially on the faster presets. I guess for now an interval of 1 minute is acceptable then.

@thebentern
Copy link
Contributor

Okay, that's not too bad, but still enough to miss a preamble especially on the faster presets. I guess for now an interval of 1 minute is acceptable then.

Do you thinks it's necessary to reset that frequently? I think Jonathon's PR had it at 15 minutes, but I'm not sure either of these numbers are based on empirical data.

@GUVWAF
Copy link
Member

GUVWAF commented Feb 21, 2026

Do you thinks it's necessary to reset that frequently? I think Jonathon's PR had it at 15 minutes, but I'm not sure either of these numbers are based on empirical data.

In #8163 it was also set to 1 minute: !Throttle::isWithinTimespanMs(last_listen, 1000 * 60).
To be honest I don't know how often "the AGC gets stuck", and it might well be that it depends on other signals present in the area, so YMMV. And if it happens, it would be nice to fix it as soon as possible, but we should be careful not to waste too much time on re-calibrating. That's why maybe an additional check for having received a packet in the last minute would be nice.

@weebl2000
Copy link
Contributor Author

weebl2000 commented Feb 21, 2026

Okay, that's not too bad, but still enough to miss a preamble especially on the faster presets. I guess for now an interval of 1 minute is acceptable then.

Do you thinks it's necessary to reset that frequently? I think Jonathon's PR had it at 15 minutes, but I'm not sure either of these numbers are based on empirical data.

Ideally it would be configurable, but 1 min seems a reasonable start for SX1262 because it does suffer from progressive deafness. I think the 5-10ms deafness during AGC reset weighs up to the deafness that nodes hearing a lot of noise can suffer from.

See also: https://web.archive.org/web/20240310141746/https://forum.lora-developers.semtech.com/t/sx1262-reduced-rx-sensitivity-packet-reception-fails/162

Let's put it like this: most nodes that don't suffer from deafness probably have relatively low interference so the "gain" reset probably won't affect them negatively anyway.

@weebl2000 weebl2000 force-pushed the implement-agc-reset-sx126x branch from eb1cc9a to 9d1d9c8 Compare February 23, 2026 09:15
@thebentern
Copy link
Contributor

@weebl2000 have we seen any indicators that this happens on the LR11XX series? I noticed you added the reset to that family as well.

@weebl2000
Copy link
Contributor Author

weebl2000 commented Feb 23, 2026

@weebl2000 have we seen any indicators that this happens on the LR11XX series? I noticed you added the reset to that family as well.

Not that I'm aware of, the LR1110 is a bit more sophisticated in that regard. I'll gate it behind a compile flag so anyone that wants to try it can try it.

I don't have any LR1110 device myself but anyone that has can go ahead & try it and let us know if it actually provides a benefit.

weebl2000 and others added 4 commits February 24, 2026 10:05
There's no actual agc on SX126x chips but you can reset the analog
registers by doing a warm sleep & running calibration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hardware-support Hardware related: new devices or modules, problems specific to hardware

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants