From 7a2af13ae90278a6216fe34e62910dacee1e41d1 Mon Sep 17 00:00:00 2001 From: Paul Kendall Date: Sun, 3 Nov 2024 12:51:04 +1300 Subject: [PATCH] Allow LR1121 single RF path (#2998) * Remove Dual Band option from hardware with only a single LR1121 * Allow LR1121 devices to define only a single RF path * Extract common code to a function Also check the supported rate in the SetRFLinkRate and bail early if not supported * move isSupportedRFRate() after change via sync pkt... SetRFLinkRate() is now set correctly with the current rate and the initial frequency configured. * check allowed rf modes in display menu * extra check to catch freshly flashed modules with default config config.GetRate() can return a disabled rf mode, which will get set on uartconnected. --------- Co-authored-by: Jye <14170229+JyeSmith@users.noreply.github.com> --- src/include/common.h | 8 +++++++- src/include/hardware.h | 2 ++ src/include/target/Unified_ESP32_TX.h | 2 ++ src/include/target/Unified_ESP8285_TX.h | 2 ++ src/include/target/Unified_ESP_RX.h | 2 ++ src/lib/CONFIG/config.cpp | 4 +++- src/lib/LUA/tx_devLUA.cpp | 4 ++++ src/lib/OPTIONS/hardware.cpp | 2 ++ src/lib/POWERMGNT/POWERMGNT.cpp | 2 +- src/lib/SCREEN/menu.cpp | 4 ++-- src/src/common.cpp | 27 ++++++++++++++++++++++++++- src/src/rx_main.cpp | 24 +++++++++++++++++++++++- src/src/tx_main.cpp | 4 ++-- 13 files changed, 78 insertions(+), 9 deletions(-) diff --git a/src/include/common.h b/src/include/common.h index e03f8581..909a825e 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -312,4 +312,10 @@ extern uint32_t ChannelData[CRSF_NUM_CHANNELS]; // Current state of channels, CR uint32_t uidMacSeedGet(); bool isDualRadio(); -void EnterBindingModeSafely(); // defined in rx_main/tx_main \ No newline at end of file +void EnterBindingModeSafely(); // defined in rx_main/tx_main + +#if defined(RADIO_LR1121) +bool isSupportedRFRate(uint8_t index); +#else +inline bool isSupportedRFRate(uint8_t index) { return true; }; +#endif diff --git a/src/include/hardware.h b/src/include/hardware.h index 80e9a313..83b0d1ec 100644 --- a/src/include/hardware.h +++ b/src/include/hardware.h @@ -51,8 +51,10 @@ typedef enum { HARDWARE_power_control, HARDWARE_power_values, + HARDWARE_power_values_count, HARDWARE_power_values2, HARDWARE_power_values_dual, + HARDWARE_power_values_dual_count, // Input HARDWARE_joystick, diff --git a/src/include/target/Unified_ESP32_TX.h b/src/include/target/Unified_ESP32_TX.h index 2ceb92c5..cd397e85 100644 --- a/src/include/target/Unified_ESP32_TX.h +++ b/src/include/target/Unified_ESP32_TX.h @@ -90,8 +90,10 @@ #define POWER_OUTPUT_DACWRITE (hardware_int(HARDWARE_power_control)==3) #define POWER_OUTPUT_FIXED -99 #define POWER_OUTPUT_VALUES hardware_i16_array(HARDWARE_power_values) +#define POWER_OUTPUT_VALUES_COUNT hardware_int(HARDWARE_power_values_count) #define POWER_OUTPUT_VALUES2 hardware_i16_array(HARDWARE_power_values2) #define POWER_OUTPUT_VALUES_DUAL hardware_i16_array(HARDWARE_power_values_dual) +#define POWER_OUTPUT_VALUES_DUAL_COUNT hardware_int(HARDWARE_power_values_dual_count) // Input #define HAS_FIVE_WAY_BUTTON diff --git a/src/include/target/Unified_ESP8285_TX.h b/src/include/target/Unified_ESP8285_TX.h index aaa692dd..985ff850 100644 --- a/src/include/target/Unified_ESP8285_TX.h +++ b/src/include/target/Unified_ESP8285_TX.h @@ -40,8 +40,10 @@ //#define POWER_OUTPUT_DACWRITE (hardware_int(HARDWARE_power_control)==3) #define POWER_OUTPUT_FIXED -99 #define POWER_OUTPUT_VALUES hardware_i16_array(HARDWARE_power_values) +#define POWER_OUTPUT_VALUES_COUNT hardware_int(HARDWARE_power_values_count) #define POWER_OUTPUT_VALUES2 hardware_i16_array(HARDWARE_power_values) #define POWER_OUTPUT_VALUES_DUAL hardware_i16_array(HARDWARE_power_values_dual) +#define POWER_OUTPUT_VALUES_DUAL_COUNT hardware_int(HARDWARE_power_values_dual_count) // Input #define GPIO_PIN_BUTTON hardware_pin(HARDWARE_button) diff --git a/src/include/target/Unified_ESP_RX.h b/src/include/target/Unified_ESP_RX.h index 566e47f3..e83bc186 100644 --- a/src/include/target/Unified_ESP_RX.h +++ b/src/include/target/Unified_ESP_RX.h @@ -91,8 +91,10 @@ #define POWER_OUTPUT_DACWRITE (hardware_int(HARDWARE_power_control)==3) #define POWER_OUTPUT_FIXED -99 #define POWER_OUTPUT_VALUES hardware_i16_array(HARDWARE_power_values) +#define POWER_OUTPUT_VALUES_COUNT hardware_int(HARDWARE_power_values_count) #define POWER_OUTPUT_VALUES2 hardware_i16_array(HARDWARE_power_values2) #define POWER_OUTPUT_VALUES_DUAL hardware_i16_array(HARDWARE_power_values_dual) +#define POWER_OUTPUT_VALUES_DUAL_COUNT hardware_int(HARDWARE_power_values_dual_count) // Input #define GPIO_PIN_BUTTON hardware_pin(HARDWARE_button) diff --git a/src/lib/CONFIG/config.cpp b/src/lib/CONFIG/config.cpp index a3391632..33db6954 100644 --- a/src/lib/CONFIG/config.cpp +++ b/src/lib/CONFIG/config.cpp @@ -654,8 +654,10 @@ TxConfig::SetDefaults(bool commit) for (unsigned i=0; iinterval * get_elrs_airRateConfig(rate)->numOfSends) >= minInterval; + + // Skip unsupported modes for hardware with only a single LR1121 or with a single RF path + rateAllowed &= isSupportedRFRate(rate); + const char *semi = strchrnul(pos, ';'); if (rateAllowed) { diff --git a/src/lib/OPTIONS/hardware.cpp b/src/lib/OPTIONS/hardware.cpp index 42c6f614..a32e5456 100644 --- a/src/lib/OPTIONS/hardware.cpp +++ b/src/lib/OPTIONS/hardware.cpp @@ -64,8 +64,10 @@ static const struct { {HARDWARE_power_pdet_slope, "power_pdet_slope", FLOAT}, {HARDWARE_power_control, "power_control", INT}, {HARDWARE_power_values, "power_values", ARRAY}, + {HARDWARE_power_values_count, "power_values", COUNT}, {HARDWARE_power_values2, "power_values2", ARRAY}, {HARDWARE_power_values_dual, "power_values_dual", ARRAY}, + {HARDWARE_power_values_dual_count, "power_values_dual", COUNT}, {HARDWARE_joystick, "joystick", INT}, {HARDWARE_joystick_values, "joystick_values", ARRAY}, {HARDWARE_five_way1, "five_way1", INT}, diff --git a/src/lib/POWERMGNT/POWERMGNT.cpp b/src/lib/POWERMGNT/POWERMGNT.cpp index 9c1e719a..31875e3d 100644 --- a/src/lib/POWERMGNT/POWERMGNT.cpp +++ b/src/lib/POWERMGNT/POWERMGNT.cpp @@ -286,7 +286,7 @@ void POWERMGNT::setPower(PowerLevels_e Power) analogWrite(GPIO_PIN_RFamp_APC2, powerValues[Power - MinPower]); #else #if defined(PLATFORM_ESP32) - if (POWER_OUTPUT_DACWRITE) + if (POWER_OUTPUT_DACWRITE && POWER_OUTPUT_VALUES != nullptr) { if (POWER_OUTPUT_VALUES2 != nullptr) { diff --git a/src/lib/SCREEN/menu.cpp b/src/lib/SCREEN/menu.cpp index 67cf2475..666bf841 100644 --- a/src/lib/SCREEN/menu.cpp +++ b/src/lib/SCREEN/menu.cpp @@ -210,7 +210,7 @@ static void incrementValueIndex(bool init) values_index = (values_index - values_min + 1) % values_count + values_min; if (state_machine.getParentState() == STATE_PACKET) { - while (get_elrs_airRateConfig(values_index)->interval < handset->getMinPacketInterval()) + while (get_elrs_airRateConfig(values_index)->interval < handset->getMinPacketInterval() || !isSupportedRFRate(values_index)) { values_index = (values_index - values_min + 1) % values_count + values_min; } @@ -223,7 +223,7 @@ static void decrementValueIndex(bool init) values_index = (values_index - values_min + values_count - 1) % values_count + values_min; if (state_machine.getParentState() == STATE_PACKET) { - while (get_elrs_airRateConfig(values_index)->interval < handset->getMinPacketInterval()) + while (get_elrs_airRateConfig(values_index)->interval < handset->getMinPacketInterval() || !isSupportedRFRate(values_index)) { values_index = (values_index - values_min + values_count - 1) % values_count + values_min; } diff --git a/src/src/common.cpp b/src/src/common.cpp index d48f76d4..35e6df6b 100644 --- a/src/src/common.cpp +++ b/src/src/common.cpp @@ -122,7 +122,7 @@ uint8_t get_elrs_HandsetRate_max(uint8_t rateIndex, uint32_t minInterval) expresslrs_mod_settings_s const * const ModParams = &ExpressLRS_AirRateConfig[rateIndex]; // Handset interval = time between packets from handset, which is expected to be air rate * number of times it is sent uint32_t handsetInterval = ModParams->interval * ModParams->numOfSends; - if (handsetInterval >= minInterval) + if (handsetInterval >= minInterval && isSupportedRFRate(rateIndex)) break; ++rateIndex; } @@ -207,3 +207,28 @@ bool ICACHE_RAM_ATTR isDualRadio() { return GPIO_PIN_NSS_2 != UNDEF_PIN; } + + +#if defined(RADIO_LR1121) +bool isSupportedRFRate(uint8_t index) +{ + expresslrs_mod_settings_s *const ModParams = get_elrs_airRateConfig(index); + + // Dual Band modes not supported for hardware with only a single LR1121 + if (GPIO_PIN_NSS_2 == UNDEF_PIN && ModParams->radio_type == RADIO_TYPE_LR1121_LORA_DUAL) + { + return false; + } + // 900MHz and Dual Band modes not supported for hardware with no 900MHz power values + if (POWER_OUTPUT_VALUES_COUNT == 0 && (ModParams->radio_type == RADIO_TYPE_LR1121_LORA_900 || ModParams->radio_type == RADIO_TYPE_LR1121_GFSK_900 || ModParams->radio_type == RADIO_TYPE_LR1121_LORA_DUAL)) + { + return false; + } + // 2.4GHz and Dual Band modes not supported for hardware with no 2.4GHz power values + if (POWER_OUTPUT_VALUES_DUAL_COUNT == 0 && (ModParams->radio_type == RADIO_TYPE_LR1121_LORA_2G4 || ModParams->radio_type == RADIO_TYPE_LR1121_GFSK_2G4 || ModParams->radio_type == RADIO_TYPE_LR1121_LORA_DUAL)) + { + return false; + } + return true; +} +#endif diff --git a/src/src/rx_main.cpp b/src/src/rx_main.cpp index e226ecae..c629a50d 100644 --- a/src/src/rx_main.cpp +++ b/src/src/rx_main.cpp @@ -357,6 +357,7 @@ void SetRFLinkRate(uint8_t index, bool bindMode) // Set speed of RF link { expresslrs_mod_settings_s *const ModParams = get_elrs_airRateConfig(index); expresslrs_rf_pref_params_s *const RFperf = get_elrs_RFperfParams(index); + // Binding always uses invertIQ bool invertIQ = bindMode || (UID[5] & 0x01); @@ -1693,6 +1694,14 @@ static void setupRadio() Radio.TXdoneCallback = &TXdoneISR; scanIndex = config.GetRateInitialIdx(); + for (int i=0 ; iinterval); + // Skip unsupported modes for hardware with only a single LR1121 or with a single RF path + while (!isSupportedRFRate(scanIndex % RATE_MAX)) + { + DBGLN("Skip %u", get_elrs_airRateConfig(scanIndex % RATE_MAX)->interval); + scanIndex++; + } + // Switch to FAST_SYNC if not already in it (won't be if was just connected) RFmodeCycleMultiplier = 1; } // if time to switch RF mode @@ -2192,8 +2208,14 @@ void loop() return; } - if ((connectionState != disconnected) && (ExpressLRS_currAirRate_Modparams->index != ExpressLRS_nextAirRateIndex)){ // forced change + if ((connectionState != disconnected) && (ExpressLRS_currAirRate_Modparams->index != ExpressLRS_nextAirRateIndex)) // forced change + { DBGLN("Req air rate change %u->%u", ExpressLRS_currAirRate_Modparams->index, ExpressLRS_nextAirRateIndex); + if (!isSupportedRFRate(ExpressLRS_nextAirRateIndex)) + { + DBGLN("Mode %u not supported, ignoring", get_elrs_airRateConfig(index)->interval); + ExpressLRS_nextAirRateIndex = ExpressLRS_currAirRate_Modparams->index; + } LostConnection(true); LastSyncPacket = now; // reset this variable to stop rf mode switching and add extra time RFmodeLastCycled = now; // reset this variable to stop rf mode switching and add extra time diff --git a/src/src/tx_main.cpp b/src/src/tx_main.cpp index 81d58e93..4427a06b 100644 --- a/src/src/tx_main.cpp +++ b/src/src/tx_main.cpp @@ -1028,8 +1028,8 @@ static void ExitBindingMode() // Reset CRCInit to UID-defined value OtaUpdateCrcInitFromUid(); InBindingMode = false; // Clear binding mode before SetRFLinkRate() for correct IQ - - SetRFLinkRate(config.GetRate()); //return to original rate + + UARTconnected(); DBGLN("Exiting binding mode"); } -- 2.11.4.GIT