mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-14 14:52:32 +00:00
Compare commits
1 Commits
ble-Banner
...
agc-reset-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c89cc1da44 |
@@ -181,6 +181,9 @@ template <typename T> bool LR11x0Interface<T>::reconfigure()
|
|||||||
err = lora.setOutputPower(power);
|
err = lora.setOutputPower(power);
|
||||||
assert(err == RADIOLIB_ERR_NONE);
|
assert(err == RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
|
// Initialize AGC/AFC reset timing (30 second interval)
|
||||||
|
nextAgcResetMs = millis() + THIRY_SECONDS_MS;
|
||||||
|
|
||||||
startReceive(); // restart receiving
|
startReceive(); // restart receiving
|
||||||
|
|
||||||
return RADIOLIB_ERR_NONE;
|
return RADIOLIB_ERR_NONE;
|
||||||
|
|||||||
@@ -248,6 +248,9 @@ bool RF95Interface::reconfigure()
|
|||||||
if (err != RADIOLIB_ERR_NONE)
|
if (err != RADIOLIB_ERR_NONE)
|
||||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||||
|
|
||||||
|
// Initialize AGC reset timing
|
||||||
|
nextAgcResetMs = millis() + 30000;
|
||||||
|
|
||||||
startReceive(); // restart receiving
|
startReceive(); // restart receiving
|
||||||
|
|
||||||
return RADIOLIB_ERR_NONE;
|
return RADIOLIB_ERR_NONE;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)
|
|||||||
|
|
||||||
RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
|
RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
|
||||||
RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface)
|
RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface)
|
||||||
: NotifiedWorkerThread("RadioIf"), module(hal, cs, irq, rst, busy), iface(_iface)
|
: NotifiedWorkerThread("RadioIf"), module(hal, cs, irq, rst, busy), iface(_iface), nextAgcResetMs(0)
|
||||||
{
|
{
|
||||||
instance = this;
|
instance = this;
|
||||||
#if defined(ARCH_STM32WL) && defined(USE_SX1262)
|
#if defined(ARCH_STM32WL) && defined(USE_SX1262)
|
||||||
@@ -245,6 +245,9 @@ currently active.
|
|||||||
*/
|
*/
|
||||||
void RadioLibInterface::onNotify(uint32_t notification)
|
void RadioLibInterface::onNotify(uint32_t notification)
|
||||||
{
|
{
|
||||||
|
// Check for AGC reset before processing notifications
|
||||||
|
checkAndPerformAgcReset();
|
||||||
|
|
||||||
switch (notification) {
|
switch (notification) {
|
||||||
case ISR_TX:
|
case ISR_TX:
|
||||||
handleTransmitInterrupt();
|
handleTransmitInterrupt();
|
||||||
@@ -552,4 +555,46 @@ bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
|
|||||||
|
|
||||||
return res == RADIOLIB_ERR_NONE;
|
return res == RADIOLIB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadioLibInterface::checkAndPerformAgcReset()
|
||||||
|
{
|
||||||
|
// Use a sensible default of 30 seconds for AGC/AFC reset
|
||||||
|
// Based on MeshCore's approach and SX126x datasheet recommendations
|
||||||
|
static const uint32_t AGC_RESET_INTERVAL_MS = 30 * 1000U;
|
||||||
|
|
||||||
|
uint32_t now = millis();
|
||||||
|
|
||||||
|
// Add debug info on first call or when nextAgcResetMs is not set
|
||||||
|
static bool first_call = true;
|
||||||
|
if (first_call || nextAgcResetMs == 0) {
|
||||||
|
LOG_DEBUG("AGC reset: now=%u, nextAgcResetMs=%u, first_call=%d", now, nextAgcResetMs, first_call);
|
||||||
|
first_call = false;
|
||||||
|
if (nextAgcResetMs == 0) {
|
||||||
|
// Initialize if not set by reconfigure()
|
||||||
|
nextAgcResetMs = now + AGC_RESET_INTERVAL_MS;
|
||||||
|
LOG_DEBUG("AGC reset initialized to %u", nextAgcResetMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now < nextAgcResetMs) {
|
||||||
|
return; // Not time yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only reset if we're not actively sending, receiving, or processing packets
|
||||||
|
if (isSending() || isActivelyReceiving() || isReceiving) {
|
||||||
|
// Postpone reset by a short delay to avoid interfering with active operations
|
||||||
|
nextAgcResetMs = now + 1000; // Retry in 1 second
|
||||||
|
LOG_DEBUG("AGC reset postponed - radio busy");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("Performing AGC/AFC reset via startReceive()");
|
||||||
|
|
||||||
|
// Use MeshCore's approach: issue startReceive() to reset AGC/AFC
|
||||||
|
// This is cleaner than direct register manipulation and works across all radio types
|
||||||
|
startReceive();
|
||||||
|
|
||||||
|
// Schedule next reset
|
||||||
|
nextAgcResetMs = now + AGC_RESET_INTERVAL_MS;
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#define RADIOLIB_PIN_TYPE uint32_t
|
#define RADIOLIB_PIN_TYPE uint32_t
|
||||||
|
|
||||||
|
#define THIRY_SECONDS_MS 30000
|
||||||
|
|
||||||
// In addition to the default Rx flags, we need the PREAMBLE_DETECTED flag to detect whether we are actively receiving
|
// In addition to the default Rx flags, we need the PREAMBLE_DETECTED flag to detect whether we are actively receiving
|
||||||
#define MESHTASTIC_RADIOLIB_IRQ_RX_FLAGS (RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1 << RADIOLIB_IRQ_PREAMBLE_DETECTED))
|
#define MESHTASTIC_RADIOLIB_IRQ_RX_FLAGS (RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1 << RADIOLIB_IRQ_PREAMBLE_DETECTED))
|
||||||
|
|
||||||
@@ -181,8 +183,18 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
|||||||
protected:
|
protected:
|
||||||
uint32_t activeReceiveStart = 0;
|
uint32_t activeReceiveStart = 0;
|
||||||
|
|
||||||
|
/** Track when we should next perform an AGC/AFC reset */
|
||||||
|
uint32_t nextAgcResetMs = 0;
|
||||||
|
|
||||||
bool receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag);
|
bool receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform AGC/AFC reset by issuing a startReceive() call if enough time has passed
|
||||||
|
* and we're not currently receiving or transmitting.
|
||||||
|
* Based on MeshCore's approach of using RadioLib startReceive() to reset AGC.
|
||||||
|
*/
|
||||||
|
void checkAndPerformAgcReset();
|
||||||
|
|
||||||
/** Do any hardware setup needed on entry into send configuration for the radio.
|
/** Do any hardware setup needed on entry into send configuration for the radio.
|
||||||
* Subclasses can customize, but must also call this base method */
|
* Subclasses can customize, but must also call this base method */
|
||||||
virtual void configHardwareForSend();
|
virtual void configHardwareForSend();
|
||||||
|
|||||||
@@ -228,6 +228,9 @@ template <typename T> bool SX126xInterface<T>::reconfigure()
|
|||||||
LOG_ERROR("SX126X setOutputPower %s%d", radioLibErr, err);
|
LOG_ERROR("SX126X setOutputPower %s%d", radioLibErr, err);
|
||||||
assert(err == RADIOLIB_ERR_NONE);
|
assert(err == RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
|
// Initialize AGC/AFC reset timing (30 second interval)
|
||||||
|
nextAgcResetMs = millis() + THIRY_SECONDS_MS;
|
||||||
|
|
||||||
startReceive(); // restart receiving
|
startReceive(); // restart receiving
|
||||||
|
|
||||||
return RADIOLIB_ERR_NONE;
|
return RADIOLIB_ERR_NONE;
|
||||||
|
|||||||
@@ -150,6 +150,9 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
|
|||||||
LOG_ERROR("SX128X setOutputPower %s%d", radioLibErr, err);
|
LOG_ERROR("SX128X setOutputPower %s%d", radioLibErr, err);
|
||||||
assert(err == RADIOLIB_ERR_NONE);
|
assert(err == RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
|
// Initialize AGC/AFC reset timing (30 second interval)
|
||||||
|
nextAgcResetMs = millis() + THIRY_SECONDS_MS;
|
||||||
|
|
||||||
startReceive(); // restart receiving
|
startReceive(); // restart receiving
|
||||||
|
|
||||||
return RADIOLIB_ERR_NONE;
|
return RADIOLIB_ERR_NONE;
|
||||||
|
|||||||
Reference in New Issue
Block a user