Update Heltec Tracker v2 to version KCT8103L. (#9822)

* Update Heltec Tracker v2 to version KCT8103L.

* Fixed the issue of inaccurate comments.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
Quency-D
2026-03-06 06:15:42 -06:00
committed by GitHub
co-authored by GitHub Ben Meadors
parent cb28c38828
commit 3d524be965
5 changed files with 64 additions and 30 deletions
+6
View File
@@ -149,6 +149,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define TX_GAIN_LORA 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7
#endif
#ifdef USE_KCT8103L_PA
// Power Amps are often non-linear, so we can use an array of values for the power curve
#define NUM_PA_POINTS 22
#define TX_GAIN_LORA 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 10, 9, 8, 7
#endif
#ifdef RAK13302
#define NUM_PA_POINTS 22
#define TX_GAIN_LORA 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8
+40 -5
View File
@@ -41,18 +41,33 @@ void LoRaFEMInterface::init(void)
}
#elif defined(USE_GC1109_PA)
fem_type = GC1109_PA;
pinMode(LORA_PA_POWER, OUTPUT);
digitalWrite(LORA_PA_POWER, HIGH);
#if defined(ARCH_ESP32)
rtc_gpio_hold_dis((gpio_num_t)LORA_PA_POWER);
rtc_gpio_hold_dis((gpio_num_t)LORA_GC1109_PA_EN);
rtc_gpio_hold_dis((gpio_num_t)LORA_GC1109_PA_TX_EN);
#endif
pinMode(LORA_PA_POWER, OUTPUT);
digitalWrite(LORA_PA_POWER, HIGH);
delay(1);
pinMode(LORA_GC1109_PA_EN, OUTPUT);
digitalWrite(LORA_GC1109_PA_EN, HIGH);
pinMode(LORA_GC1109_PA_TX_EN, OUTPUT);
digitalWrite(LORA_GC1109_PA_TX_EN, LOW);
#elif defined(USE_KCT8103L_PA)
fem_type = KCT8103L_PA;
pinMode(LORA_PA_POWER, OUTPUT);
digitalWrite(LORA_PA_POWER, HIGH);
#if defined(ARCH_ESP32)
rtc_gpio_hold_dis((gpio_num_t)LORA_PA_POWER);
rtc_gpio_hold_dis((gpio_num_t)LORA_KCT8103L_PA_CSD);
rtc_gpio_hold_dis((gpio_num_t)LORA_KCT8103L_PA_CTX);
#endif
delay(1);
pinMode(LORA_KCT8103L_PA_CSD, OUTPUT);
digitalWrite(LORA_KCT8103L_PA_CSD, HIGH);
pinMode(LORA_KCT8103L_PA_CTX, OUTPUT);
digitalWrite(LORA_KCT8103L_PA_CTX, HIGH);
setLnaCanControl(true);
#endif
}
@@ -73,6 +88,9 @@ void LoRaFEMInterface::setSleepModeEnable(void)
#elif defined(USE_GC1109_PA)
digitalWrite(LORA_GC1109_PA_EN, LOW);
digitalWrite(LORA_GC1109_PA_TX_EN, LOW);
#elif defined(USE_KCT8103L_PA)
// shutdown the PA
digitalWrite(LORA_KCT8103L_PA_CSD, LOW);
#endif
}
@@ -89,6 +107,9 @@ void LoRaFEMInterface::setTxModeEnable(void)
#elif defined(USE_GC1109_PA)
digitalWrite(LORA_GC1109_PA_EN, HIGH); // CSD=1: Chip enabled
digitalWrite(LORA_GC1109_PA_TX_EN, HIGH); // CPS: 1=full PA, 0=bypass (for RX, CPS is don't care)
#elif defined(USE_KCT8103L_PA)
digitalWrite(LORA_KCT8103L_PA_CSD, HIGH);
digitalWrite(LORA_KCT8103L_PA_CTX, HIGH);
#endif
}
@@ -109,6 +130,13 @@ void LoRaFEMInterface::setRxModeEnable(void)
#elif defined(USE_GC1109_PA)
digitalWrite(LORA_GC1109_PA_EN, HIGH); // CSD=1: Chip enabled
digitalWrite(LORA_GC1109_PA_TX_EN, LOW);
#elif defined(USE_KCT8103L_PA)
digitalWrite(LORA_KCT8103L_PA_CSD, HIGH);
if (lna_enabled) {
digitalWrite(LORA_KCT8103L_PA_CTX, LOW);
} else {
digitalWrite(LORA_KCT8103L_PA_CTX, HIGH);
}
#endif
}
@@ -143,6 +171,15 @@ void LoRaFEMInterface::setRxModeEnableWhenMCUSleep(void)
rtc_gpio_hold_en((gpio_num_t)LORA_GC1109_PA_EN);
gpio_pulldown_en((gpio_num_t)LORA_GC1109_PA_TX_EN);
#endif
#elif defined(USE_KCT8103L_PA)
digitalWrite(LORA_KCT8103L_PA_CSD, HIGH);
rtc_gpio_hold_en((gpio_num_t)LORA_KCT8103L_PA_CSD);
if (lna_enabled) {
digitalWrite(LORA_KCT8103L_PA_CTX, LOW);
} else {
digitalWrite(LORA_KCT8103L_PA_CTX, HIGH);
}
rtc_gpio_hold_en((gpio_num_t)LORA_KCT8103L_PA_CTX);
#endif
}
@@ -169,11 +206,9 @@ int8_t LoRaFEMInterface::powerConversion(int8_t loraOutputPower)
}
#else
#ifdef ARCH_PORTDUINO
size_t num_pa_points = portduino_config.num_pa_points;
const uint16_t *tx_gain = portduino_config.tx_gain_lora;
uint16_t tx_gain_num = num_pa_points;
uint16_t tx_gain_num = portduino_config.num_pa_points;
#else
size_t num_pa_points = NUM_PA_POINTS;
const uint16_t tx_gain[NUM_PA_POINTS] = {TX_GAIN_LORA};
uint16_t tx_gain_num = NUM_PA_POINTS;
#endif
+2 -2
View File
@@ -65,12 +65,12 @@
// Pin mapping:
// CPS (pin 5) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH)
// CSD (pin 4) -> GPIO2: Chip enable (HIGH=on, LOW=shutdown)
// CTX (pin 6) -> GPIO5: Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=bypass PA, LOW=LNA)
// CTX (pin 6) -> GPIO5: Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=RX bypass, LOW=RX LNA)
// VCC0/VCC1 -> Vfem via U3 LDO, controlled by GPIO7
// KCT8103L FEM: TX/RX path switching is handled by DIO2 -> CPS pin (via SX126X_DIO2_AS_RF_SWITCH)
#define LORA_KCT8103L_PA_CSD 2 // CSD - KCT8103L chip enable (HIGH=on)
#define LORA_KCT8103L_PA_CTX 5 // CTX - Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=bypass PA, LOW=LNA)
#define LORA_KCT8103L_PA_CTX 5 // CTX - Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=RX bypass, LOW=RX LNA)
#if HAS_TFT
#define USE_TFTDISPLAY 1
@@ -13,8 +13,8 @@
static const uint8_t TX = 43;
static const uint8_t RX = 44;
static const uint8_t SDA = 5;
static const uint8_t SCL = 6;
static const uint8_t SDA = 6;
static const uint8_t SCL = 17;
static const uint8_t SS = 8;
static const uint8_t MOSI = 10;
@@ -73,29 +73,22 @@
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// ---- 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):
// ---- KCT8103L RF FRONT END CONFIGURATION ----
// The heltec_wireless_tracker_v2 uses a KCT8103L FEM chip with integrated PA and LNA
// RF path: SX1262 -> Pi attenuator -> KCT8103L PA -> Antenna
// Control logic (from KCT8103L datasheet):
// Transmit PA: CSD=1, CTX=1, CPS=1
// Receive LNA: CSD=1, CTX=0, CPS=X (21dB gain, 1.9dB NF)
// Receive bypass: CSD=1, CTX=1, CPS=0
// 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)
// CPS (pin 5) -> 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)
// CTX (pin 6) -> GPIO5: Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=RX bypass, LOW=RX LNA)
// 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_GC1109_PA_EN 4 // CSD - GC1109 chip enable (HIGH=on)
#define LORA_GC1109_PA_TX_EN 46 // CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass)
// KCT8103L FEM: TX/RX path switching is handled by DIO2 -> CPS pin (via SX126X_DIO2_AS_RF_SWITCH)
// 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
#define USE_KCT8103L_PA
#define LORA_PA_POWER 7 // VFEM_Ctrl - KCT8103L LDO power enable
#define LORA_KCT8103L_PA_CSD 4 // CSD - KCT8103L chip enable (HIGH=on)
#define LORA_KCT8103L_PA_CTX 5 // CTX - Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=RX bypass, LOW=RX LNA)