From 6e110788fd2eb2e44d89031ca8c72002c57ecc4d Mon Sep 17 00:00:00 2001 From: Wessel Date: Thu, 8 Jan 2026 12:42:01 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Fix=20LNA/PA=20power=20control?= =?UTF-8?q?=20for=20Heltec=20v4,=20wireless=20tracker=20v2=20(#9029)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix LNA/PA power control for Heltec v4, wireless tracker v2 * Stop using pin 46 as RF switch, just let DIO2 switch handle the RF path --------- Co-authored-by: Ben Meadors --- src/mesh/SX126xInterface.cpp | 20 +++++++++---- variants/esp32s3/heltec_v4/variant.h | 30 ++++++++++++++++--- .../heltec_wireless_tracker_v2/variant.h | 30 ++++++++++++++++--- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 2d7996a13..53cf3154e 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -53,13 +53,21 @@ template bool SX126xInterface::init() #endif #if defined(USE_GC1109_PA) + // GC1109 FEM chip initialization + // See variant.h for full pin mapping and control logic documentation + + // VFEM_Ctrl (LORA_PA_POWER): Power enable for GC1109 LDO (always on) pinMode(LORA_PA_POWER, OUTPUT); digitalWrite(LORA_PA_POWER, HIGH); + // CSD (LORA_PA_EN): Chip enable - must be HIGH to enable GC1109 for both RX and TX pinMode(LORA_PA_EN, OUTPUT); - digitalWrite(LORA_PA_EN, LOW); + digitalWrite(LORA_PA_EN, HIGH); + + // CPS (LORA_PA_TX_EN): PA mode select - HIGH enables full PA during TX, LOW for RX (don't care) + // Note: TX/RX path switching (CTX) is handled by DIO2 via SX126X_DIO2_AS_RF_SWITCH pinMode(LORA_PA_TX_EN, OUTPUT); - digitalWrite(LORA_PA_TX_EN, LOW); + digitalWrite(LORA_PA_TX_EN, LOW); // Start in RX-ready state #endif #ifdef RF95_FAN_EN @@ -377,13 +385,13 @@ template bool SX126xInterface::sleep() return true; } -/** Some boards require GPIO control of tx vs rx paths */ +/** Control PA mode for GC1109 FEM - CPS pin selects full PA (txon=true) or bypass mode (txon=false) */ template void SX126xInterface::setTransmitEnable(bool txon) { #if defined(USE_GC1109_PA) - digitalWrite(LORA_PA_POWER, HIGH); - digitalWrite(LORA_PA_EN, HIGH); - digitalWrite(LORA_PA_TX_EN, txon ? 1 : 0); + digitalWrite(LORA_PA_POWER, HIGH); // Ensure LDO is on + digitalWrite(LORA_PA_EN, HIGH); // CSD=1: Chip enabled + digitalWrite(LORA_PA_TX_EN, txon ? 1 : 0); // CPS: 1=full PA, 0=bypass (for RX, CPS is don't care) #endif } diff --git a/variants/esp32s3/heltec_v4/variant.h b/variants/esp32s3/heltec_v4/variant.h index 6524bbc72..1c1168d94 100644 --- a/variants/esp32s3/heltec_v4/variant.h +++ b/variants/esp32s3/heltec_v4/variant.h @@ -29,10 +29,32 @@ #define SX126X_DIO2_AS_RF_SWITCH #define SX126X_DIO3_TCXO_VOLTAGE 1.8 -#define USE_GC1109_PA // We have a GC1109 power amplifier+attenuator -#define LORA_PA_POWER 7 // power en -#define LORA_PA_EN 2 -#define LORA_PA_TX_EN 46 // enable tx +// ---- GC1109 RF FRONT END CONFIGURATION ---- +// The Heltec V4 uses a GC1109 FEM chip with integrated PA and LNA +// RF path: SX1262 -> GC1109 PA -> Pi attenuator -> Antenna +// Measured net TX gain (non-linear due to PA compression): +// +11dB at 0-15dBm input (e.g., 10dBm in -> 21dBm out) +// +10dB at 16-17dBm input +// +9dB at 18-19dBm input +// +7dB at 21dBm input (e.g., 21dBm in -> 28dBm out max) +// Control logic (from GC1109 datasheet): +// Shutdown: CSD=0, CTX=X, CPS=X +// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF) +// Transmit bypass: CSD=1, CTX=1, CPS=0 (~1dB loss, no PA) +// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled) +// Pin mapping: +// CTX (pin 6) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH) +// CSD (pin 4) -> GPIO2: Chip enable (HIGH=on, LOW=shutdown) +// CPS (pin 5) -> GPIO46: PA mode select (HIGH=full PA, LOW=bypass) +// VCC0/VCC1 -> Vfem via U3 LDO, controlled by GPIO7 +#define USE_GC1109_PA +#define LORA_PA_POWER 7 // VFEM_Ctrl - GC1109 LDO power enable +#define LORA_PA_EN 2 // CSD - GC1109 chip enable (HIGH=on) +#define LORA_PA_TX_EN 46 // CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass) + +// GC1109 FEM: TX/RX path switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH) +// GPIO46 is CPS (PA mode), not TX control - setTransmitEnable() handles it in SX126xInterface.cpp +// Do NOT use SX126X_TXEN/RXEN as that would cause double-control of GPIO46 #if HAS_TFT #define USE_TFTDISPLAY 1 diff --git a/variants/esp32s3/heltec_wireless_tracker_v2/variant.h b/variants/esp32s3/heltec_wireless_tracker_v2/variant.h index 0ce6b3e00..a5489173d 100644 --- a/variants/esp32s3/heltec_wireless_tracker_v2/variant.h +++ b/variants/esp32s3/heltec_wireless_tracker_v2/variant.h @@ -73,7 +73,29 @@ #define SX126X_DIO2_AS_RF_SWITCH #define SX126X_DIO3_TCXO_VOLTAGE 1.8 -#define USE_GC1109_PA // We have a GC1109 power amplifier+attenuator -#define LORA_PA_POWER 7 // power en -#define LORA_PA_EN 4 -#define LORA_PA_TX_EN 46 // enable tx \ No newline at end of file +// ---- GC1109 RF FRONT END CONFIGURATION ---- +// The Heltec Wireless Tracker V2 uses a GC1109 FEM chip with integrated PA and LNA +// RF path: SX1262 -> GC1109 PA -> Pi attenuator -> Antenna +// Measured net TX gain (non-linear due to PA compression): +// +11dB at 0-15dBm input (e.g., 10dBm in -> 21dBm out) +// +10dB at 16-17dBm input +// +9dB at 18-19dBm input +// +7dB at 21dBm input (e.g., 21dBm in -> 28dBm out max) +// Control logic (from GC1109 datasheet): +// Shutdown: CSD=0, CTX=X, CPS=X +// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF) +// Transmit bypass: CSD=1, CTX=1, CPS=0 (~1dB loss, no PA) +// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled) +// Pin mapping: +// CTX (pin 6) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH) +// CSD (pin 4) -> GPIO4: Chip enable (HIGH=on, LOW=shutdown) +// CPS (pin 5) -> GPIO46: PA mode select (HIGH=full PA, LOW=bypass) +// VCC0/VCC1 -> Vfem via U3 LDO, controlled by GPIO7 +#define USE_GC1109_PA +#define LORA_PA_POWER 7 // VFEM_Ctrl - GC1109 LDO power enable +#define LORA_PA_EN 4 // CSD - GC1109 chip enable (HIGH=on) +#define LORA_PA_TX_EN 46 // CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass) + +// GC1109 FEM: TX/RX path switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH) +// GPIO46 is CPS (PA mode), not TX control - setTransmitEnable() handles it in SX126xInterface.cpp +// Do NOT use SX126X_TXEN/RXEN as that would cause double-control of GPIO46 \ No newline at end of file