mirror of
https://github.com/meshtastic/firmware.git
synced 2026-04-06 16:33:20 -04:00
Merge branch 'develop' into baseui_statusmessage
This commit is contained in:
16
bin/config.d/lora-lyra-ultra_1w.yaml
Normal file
16
bin/config.d/lora-lyra-ultra_1w.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# For use with Armbian luckfox-lyra-ultra-w
|
||||
# Enable overlay 'luckfox-lyra-ultra-w-spi0-cs0-spidev' with armbian-config
|
||||
# https://github.com/wehooper4/Meshtastic-Hardware/tree/main/Luckfox%20Ultra%20Hat
|
||||
# 1 Watt Lyra Ultra hat
|
||||
Lora:
|
||||
Module: sx1262
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
CS: 10
|
||||
IRQ: 5
|
||||
Busy: 11
|
||||
Reset: 9
|
||||
RXen: 14
|
||||
|
||||
spidev: spidev0.0 #pins are (CS=10, CLK=8, MOSI=6, MISO=7)
|
||||
spiSpeed: 2000000
|
||||
17
bin/config.d/lora-lyra-ultra_2w.yaml
Normal file
17
bin/config.d/lora-lyra-ultra_2w.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
# For use with Armbian luckfox-lyra-ultra-w
|
||||
# Enable overlay 'luckfox-lyra-ultra-w-spi0-cs0-spidev' with armbian-config
|
||||
# https://github.com/wehooper4/Meshtastic-Hardware/tree/main/Luckfox%20Ultra%20Hat
|
||||
# 2 Watt Lyra Ultra hat
|
||||
Lora:
|
||||
Module: sx1262
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
SX126X_MAX_POWER: 8
|
||||
CS: 10
|
||||
IRQ: 5
|
||||
Busy: 11
|
||||
Reset: 9
|
||||
RXen: 14
|
||||
|
||||
spidev: spidev0.0 #pins are (CS=10, CLK=8, MOSI=6, MISO=7)
|
||||
spiSpeed: 2000000
|
||||
25
bin/config.d/lora-lyra-ws-raspberry-pi-pico-hat.yaml
Normal file
25
bin/config.d/lora-lyra-ws-raspberry-pi-pico-hat.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
# For use with Armbian luckfox-lyra // luckfox-lyra-plus
|
||||
# Enable overlay 'luckfox-lyra-plus-spi0-cs0_rmio13-spidev' with armbian-config
|
||||
# Waveshare LoRa HAT for Raspberry Pi Pico
|
||||
# https://www.waveshare.com/wiki/Pico-LoRa-SX1262
|
||||
Lora:
|
||||
Module: sx1262
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
DIO3_TCXO_VOLTAGE: true
|
||||
spidev: spidev0.0
|
||||
CS: # GPIO0_B5
|
||||
pin: 13
|
||||
gpiochip: 0
|
||||
line: 13
|
||||
IRQ: # GPIO1_C2
|
||||
pin: 50
|
||||
gpiochip: 1
|
||||
line: 18
|
||||
Busy: # GPIO0_B4
|
||||
pin: 12
|
||||
gpiochip: 0
|
||||
line: 12
|
||||
Reset: # GPIO0_A2
|
||||
pin: 2
|
||||
gpiochip: 0
|
||||
line: 2
|
||||
@@ -1125,6 +1125,13 @@ void loop()
|
||||
lastRadioMissedIrqPoll = millis();
|
||||
RadioLibInterface::instance->pollMissedIrqs();
|
||||
}
|
||||
|
||||
// Periodic AGC reset — warm sleep + recalibrate to prevent stuck AGC gain
|
||||
static uint32_t lastAgcReset;
|
||||
if (!Throttle::isWithinTimespanMs(lastAgcReset, AGC_RESET_INTERVAL_MS)) {
|
||||
lastAgcReset = millis();
|
||||
RadioLibInterface::instance->resetAGC();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_STACK
|
||||
|
||||
@@ -299,6 +299,38 @@ template <typename T> bool LR11x0Interface<T>::isActivelyReceiving()
|
||||
RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED);
|
||||
}
|
||||
|
||||
#ifdef LR11X0_AGC_RESET
|
||||
template <typename T> void LR11x0Interface<T>::resetAGC()
|
||||
{
|
||||
// Safety: don't reset mid-packet
|
||||
if (sendingPacket != NULL || (isReceiving && isActivelyReceiving()))
|
||||
return;
|
||||
|
||||
LOG_DEBUG("LR11x0 AGC reset: warm sleep + Calibrate(0x3F)");
|
||||
|
||||
// 1. Warm sleep — powers down the analog frontend, resetting AGC state
|
||||
lora.sleep(true, 0);
|
||||
|
||||
// 2. Wake to RC standby for stable calibration
|
||||
lora.standby(RADIOLIB_LR11X0_STANDBY_RC, true);
|
||||
|
||||
// 3. Calibrate all blocks (PLL, ADC, image, RC oscillators)
|
||||
// calibrate() is protected on LR11x0, so use raw SPI (same as internal implementation)
|
||||
uint8_t calData = RADIOLIB_LR11X0_CALIBRATE_ALL;
|
||||
module.SPIwriteStream(RADIOLIB_LR11X0_CMD_CALIBRATE, &calData, 1, true, true);
|
||||
|
||||
// 4. Re-calibrate image rejection for actual operating frequency
|
||||
// Calibrate(0x3F) defaults to 902-928 MHz which is wrong for other regions.
|
||||
lora.calibrateImageRejection(getFreq() - 4.0f, getFreq() + 4.0f);
|
||||
|
||||
// 5. Re-apply RX boosted gain mode
|
||||
lora.setRxBoostedGainMode(config.lora.sx126x_rx_boosted_gain);
|
||||
|
||||
// 6. Resume receiving
|
||||
startReceive();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T> bool LR11x0Interface<T>::sleep()
|
||||
{
|
||||
// \todo Display actual typename of the adapter, not just `LR11x0`
|
||||
|
||||
@@ -27,6 +27,10 @@ template <class T> class LR11x0Interface : public RadioLibInterface
|
||||
|
||||
bool isIRQPending() override { return lora.getIrqFlags() != 0; }
|
||||
|
||||
#ifdef LR11X0_AGC_RESET
|
||||
void resetAGC() override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Specific module instance
|
||||
|
||||
@@ -529,6 +529,11 @@ void RadioLibInterface::pollMissedIrqs()
|
||||
}
|
||||
}
|
||||
|
||||
void RadioLibInterface::resetAGC()
|
||||
{
|
||||
// Base implementation: no-op. Override in chip-specific subclasses.
|
||||
}
|
||||
|
||||
void RadioLibInterface::checkRxDoneIrqFlag()
|
||||
{
|
||||
if (iface->checkIrq(RADIOLIB_IRQ_RX_DONE)) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
// 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 AGC_RESET_INTERVAL_MS (60 * 1000) // 60 seconds
|
||||
|
||||
/**
|
||||
* We need to override the RadioLib ArduinoHal class to add mutex protection for SPI bus access
|
||||
*/
|
||||
@@ -117,6 +119,13 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
*/
|
||||
void pollMissedIrqs();
|
||||
|
||||
/**
|
||||
* Reset AGC by power-cycling the analog frontend.
|
||||
* Subclasses override with chip-specific calibration sequences.
|
||||
* Safe to call periodically — skips if currently sending or receiving.
|
||||
*/
|
||||
virtual void resetAGC();
|
||||
|
||||
/**
|
||||
* Debugging counts
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,8 @@ template <class T> class SX126xInterface : public RadioLibInterface
|
||||
|
||||
bool isIRQPending() override { return lora.getIrqFlags() != 0; }
|
||||
|
||||
void resetAGC() override;
|
||||
|
||||
void setTCXOVoltage(float voltage) { tcxoVoltage = voltage; }
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user