From 03d1ace9229f3dbc8b620ce6e3c4c654d4be83ab Mon Sep 17 00:00:00 2001 From: Henry Potgieter Date: Mon, 30 Mar 2026 00:47:08 -0400 Subject: [PATCH] Allow support for <= v4.2 and v4.3 Heltec ESP32 boards due to KCT8103L PA in v4.3 --- Boards.h | 7 ++--- RNode_Firmware.ino | 10 ++++--- sx126x.cpp | 66 ++++++++++++++++++++++------------------------ sx126x.h | 3 +++ 4 files changed, 45 insertions(+), 41 deletions(-) diff --git a/Boards.h b/Boards.h index 9d69bf6..ca97b71 100644 --- a/Boards.h +++ b/Boards.h @@ -422,10 +422,11 @@ #define LORA_LNA_GAIN 17 #define LORA_LNA_GVT 12 - #define LORA_PA_KCT8103L true + #define LORA_PA_AUTO_DETECT true #define LORA_PA_PWR_EN 7 - #define LORA_PA_CSD 2 - #define LORA_PA_CTX 5 + #define LORA_PA_CSD 2 // GC1109: PA_EN | KCT8103L: CSD (same pin, different pull resistor) + #define LORA_PA_CTX 5 // KCT8103L: TX/LNA select (CTX=LOW=LNA, CTX=HIGH=PA) + #define LORA_PA_CPS 46 // GC1109: TX_EN #define PA_MAX_OUTPUT 28 #define PA_GAIN_POINTS 22 diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino index 1f13040..5e77883 100644 --- a/RNode_Firmware.ino +++ b/RNode_Firmware.ino @@ -1767,10 +1767,12 @@ void sleep_now() { #endif #endif #if BOARD_MODEL == BOARD_HELTEC32_V4 - #if LORA_PA_KCT8103L - digitalWrite(LORA_PA_CTX, LOW); - #elif LORA_PA_GC1109 - digitalWrite(LORA_PA_CPS, LOW); + #if LORA_PA_AUTO_DETECT + if (sx126x_modem.isKCT8103L()) { + digitalWrite(LORA_PA_CTX, LOW); + } else { + digitalWrite(LORA_PA_CPS, LOW); + } #endif digitalWrite(LORA_PA_CSD, LOW); digitalWrite(LORA_PA_PWR_EN, LOW); diff --git a/sx126x.cpp b/sx126x.cpp index ddb7c07..6d31e63 100644 --- a/sx126x.cpp +++ b/sx126x.cpp @@ -343,33 +343,29 @@ int sx126x::begin(long frequency) { setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); #if HAS_LORA_PA - #if LORA_PA_KCT8103L - // Enable Vfem_ctl for supply to PA power net. + #if LORA_PA_AUTO_DETECT + // Power up the FEM, then read GPIO LORA_PA_CSD as input. + // The V4.2 (GC1109) board pulls it LOW; V4.3 (KCT8103L) pulls it HIGH. pinMode(LORA_PA_PWR_EN, OUTPUT); digitalWrite(LORA_PA_PWR_EN, HIGH); + delay(1); + pinMode(LORA_PA_CSD, INPUT); + delay(1); + _kct8103l = (digitalRead(LORA_PA_CSD) == HIGH); - // Enable KCT8103L: CSD=HIGH activates the chip. - pinMode(LORA_PA_CSD, OUTPUT); - digitalWrite(LORA_PA_CSD, HIGH); - - // CTX=LOW selects LNA/RX mode by default. - // CTX=HIGH switches to PA/TX mode. - // Must be toggled on each TX/RX transition. - pinMode(LORA_PA_CTX, OUTPUT); - digitalWrite(LORA_PA_CTX, LOW); - #elif LORA_PA_GC1109 - // Enable Vfem_ctl for supply to - // PA power net. - pinMode(LORA_PA_PWR_EN, OUTPUT); - digitalWrite(LORA_PA_PWR_EN, HIGH); - - // Enable PA LNA and TX standby - pinMode(LORA_PA_CSD, OUTPUT); - digitalWrite(LORA_PA_CSD, HIGH); - - // Keep PA CPS high permanently. - pinMode(LORA_PA_CPS, OUTPUT); - digitalWrite(LORA_PA_CPS, HIGH); + if (_kct8103l) { + // KCT8103L (V4.3): CSD=HIGH enables chip, CTX=LOW=LNA/RX, CTX=HIGH=PA/TX + pinMode(LORA_PA_CSD, OUTPUT); + digitalWrite(LORA_PA_CSD, HIGH); + pinMode(LORA_PA_CTX, OUTPUT); + digitalWrite(LORA_PA_CTX, LOW); // LNA enabled by default + } else { + // GC1109 (V4.2): PA_EN=HIGH enables chip, CPS=HIGH=full PA mode + pinMode(LORA_PA_CSD, OUTPUT); + digitalWrite(LORA_PA_CSD, HIGH); + pinMode(LORA_PA_CPS, OUTPUT); + digitalWrite(LORA_PA_CPS, HIGH); + } #endif #endif @@ -380,11 +376,12 @@ void sx126x::end() { sleep(); SPI.end(); _preinit_done = false; } int sx126x::beginPacket(int implicitHeader) { #if HAS_LORA_PA - #if LORA_PA_KCT8103L - // CTX=HIGH: switch KCT8103L to PA/TX mode. - digitalWrite(LORA_PA_CTX, HIGH); - #elif LORA_PA_GC1109 - // CPS kept HIGH permanently, no action needed. + #if LORA_PA_AUTO_DETECT + if (_kct8103l) { + // CTX=HIGH: switch KCT8103L to PA/TX mode. + digitalWrite(LORA_PA_CTX, HIGH); + } + // GC1109: CPS kept HIGH permanently, no action needed. #endif #endif @@ -596,11 +593,12 @@ void sx126x::onReceive(void(*callback)(int)){ void sx126x::receive(int size) { #if HAS_LORA_PA - #if LORA_PA_KCT8103L - // CTX=LOW: switch KCT8103L to LNA/RX mode. - digitalWrite(LORA_PA_CTX, LOW); - #elif LORA_PA_GC1109 - // CPS kept HIGH permanently, no action needed. + #if LORA_PA_AUTO_DETECT + if (_kct8103l) { + // CTX=LOW: switch KCT8103L to LNA/RX mode. + digitalWrite(LORA_PA_CTX, LOW); + } + // GC1109: CPS kept HIGH permanently, no action needed. #endif #endif diff --git a/sx126x.h b/sx126x.h index 068a1bb..c31202a 100644 --- a/sx126x.h +++ b/sx126x.h @@ -97,6 +97,8 @@ public: void dumpRegisters(Stream& out); + bool isKCT8103L() { return _kct8103l; } + private: void explicitHeaderMode(); void implicitHeaderMode(); @@ -137,6 +139,7 @@ private: int _fifo_rx_addr_ptr; uint8_t _packet[255]; bool _preinit_done; + bool _kct8103l; void (*_onReceive)(int); };