Skip to content

Commit dd5e868

Browse files
committed
Don't touch pin 46 except when transmitting.
Set pinmode output/input too to make sure
1 parent d466246 commit dd5e868

File tree

2 files changed

+60
-87
lines changed

2 files changed

+60
-87
lines changed

variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,65 +6,52 @@ void HeltecTrackerV2Board::begin() {
66
pinMode(PIN_ADC_CTRL, OUTPUT);
77
digitalWrite(PIN_ADC_CTRL, LOW); // Initially inactive
88

9-
// ---- GC1109 RF FRONT END CONFIGURATION ----
10-
// The Heltec Tracker V2 uses a GC1109 FEM chip with integrated PA and LNA
11-
// RF path: SX1262 -> GC1109 PA -> Pi attenuator -> Antenna
12-
// Measured net TX gain (non-linear due to PA compression):
13-
// +11dB at 0-15dBm input (e.g., 10dBm in -> 21dBm out)
14-
// +10dB at 16-17dBm input
15-
// +9dB at 18-19dBm input
16-
// +7dB at 21dBm input (e.g., 21dBm in -> 28dBm out max)
17-
// Control logic (from GC1109 datasheet):
18-
// Shutdown: CSD=0, CTX=X, CPS=X
19-
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
20-
// Transmit bypass: CSD=1, CTX=1, CPS=0 (~1dB loss, no PA)
21-
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
22-
// Pin mapping:
23-
// CTX (pin 6) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH)
24-
// CSD (pin 4) -> GPIO4: Chip enable (HIGH=on, LOW=shutdown)
25-
// CPS (pin 5) -> GPIO46: PA mode select (HIGH=full PA, LOW=bypass)
26-
// VCC0/VCC1 -> Vfem via LDO, controlled by GPIO7
27-
28-
// VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO
29-
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER);
30-
pinMode(P_LORA_PA_POWER, OUTPUT);
31-
digitalWrite(P_LORA_PA_POWER, HIGH);
32-
33-
// CSD (GPIO4): Chip enable - must be HIGH to enable GC1109
34-
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
35-
pinMode(P_LORA_PA_EN, OUTPUT);
36-
digitalWrite(P_LORA_PA_EN, HIGH);
37-
38-
// CPS (GPIO46): PA mode - LOW for RX (don't care), HIGH during TX for full PA
39-
// Note: GPIO46 is NOT an RTC GPIO, so no rtc_gpio_hold_dis needed
40-
pinMode(P_LORA_PA_TX_EN, OUTPUT);
41-
digitalWrite(P_LORA_PA_TX_EN, LOW); // Start in RX-ready state
42-
// -------------------------------------------
43-
44-
periph_power.begin();
45-
9+
// Check if waking from deep sleep
4610
esp_reset_reason_t reason = esp_reset_reason();
4711
if (reason == ESP_RST_DEEPSLEEP) {
4812
long wakeup_source = esp_sleep_get_ext1_wakeup_status();
4913
if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep)
5014
startup_reason = BD_STARTUP_RX_PACKET;
5115
}
5216

17+
// Release RTC holds - pins retain their state, no need to reconfigure
5318
rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS);
19+
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER);
20+
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
5421
rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1);
22+
} else {
23+
// Cold boot: Configure GC1109 FEM pins
24+
// Control logic (from GC1109 datasheet):
25+
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
26+
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
27+
// Pin mapping: CTX->DIO2 (auto), CSD->GPIO4, CPS->GPIO46, VFEM->GPIO7
28+
29+
// VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO
30+
pinMode(P_LORA_PA_POWER, OUTPUT);
31+
digitalWrite(P_LORA_PA_POWER, HIGH);
32+
33+
// CSD (GPIO4): Chip enable - must be HIGH for GC1109 to work
34+
pinMode(P_LORA_PA_EN, OUTPUT);
35+
digitalWrite(P_LORA_PA_EN, HIGH);
5536
}
37+
38+
periph_power.begin();
39+
40+
// Note: GPIO46 (CPS) is a strapping pin - do NOT configure it here.
41+
// TX handlers are fully responsible for GPIO46 (see onBeforeTransmit/onAfterTransmit)
5642
}
5743

5844
void HeltecTrackerV2Board::onBeforeTransmit(void) {
59-
digitalWrite(P_LORA_TX_LED, HIGH); // Turn TX LED on
60-
digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode (+30dBm)
61-
// CTX (TX/RX path) handled by SX1262 DIO2 -> GC1109 CTX (hardware)
45+
// GPIO46 is a strapping pin - only drive it when actively transmitting
46+
pinMode(P_LORA_PA_TX_EN, OUTPUT);
47+
digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode
48+
digitalWrite(P_LORA_TX_LED, HIGH);
6249
}
6350

6451
void HeltecTrackerV2Board::onAfterTransmit(void) {
65-
digitalWrite(P_LORA_PA_TX_EN, LOW); // CPS=0: Back to RX mode (CPS=X for RX)
66-
digitalWrite(P_LORA_TX_LED, LOW); // Turn TX LED off
67-
// CTX (TX/RX path) handled by SX1262 DIO2 -> GC1109 CTX (hardware)
52+
digitalWrite(P_LORA_PA_TX_EN, LOW);
53+
pinMode(P_LORA_PA_TX_EN, INPUT); // Release strapping pin
54+
digitalWrite(P_LORA_TX_LED, LOW);
6855
}
6956

7057
void HeltecTrackerV2Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {

variants/heltec_v4/HeltecV4Board.cpp

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,69 +3,55 @@
33
void HeltecV4Board::begin() {
44
ESP32Board::begin();
55

6-
76
pinMode(PIN_ADC_CTRL, OUTPUT);
87
digitalWrite(PIN_ADC_CTRL, LOW); // Initially inactive
98

10-
// ---- GC1109 RF FRONT END CONFIGURATION ----
11-
// The Heltec V4 uses a GC1109 FEM chip with integrated PA and LNA
12-
// RF path: SX1262 -> GC1109 PA -> Pi attenuator -> Antenna
13-
// Measured net TX gain (non-linear due to PA compression):
14-
// +11dB at 0-15dBm input (e.g., 10dBm in -> 21dBm out)
15-
// +10dB at 16-17dBm input
16-
// +9dB at 18-19dBm input
17-
// +7dB at 21dBm input (e.g., 21dBm in -> 28dBm out max)
18-
// Control logic (from GC1109 datasheet):
19-
// Shutdown: CSD=0, CTX=X, CPS=X
20-
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
21-
// Transmit bypass: CSD=1, CTX=1, CPS=0 (~1dB loss, no PA)
22-
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
23-
// Pin mapping:
24-
// CTX (pin 6) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH)
25-
// CSD (pin 4) -> GPIO2: Chip enable (HIGH=on, LOW=shutdown)
26-
// CPS (pin 5) -> GPIO46: PA mode select (HIGH=full PA, LOW=bypass)
27-
// VCC0/VCC1 -> Vfem via U3 LDO, controlled by GPIO7
28-
29-
// VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO (U3)
30-
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER);
31-
pinMode(P_LORA_PA_POWER, OUTPUT);
32-
digitalWrite(P_LORA_PA_POWER, HIGH);
33-
34-
// CSD (GPIO2): Chip enable - must be HIGH to enable GC1109
35-
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
36-
pinMode(P_LORA_PA_EN, OUTPUT);
37-
digitalWrite(P_LORA_PA_EN, HIGH);
38-
39-
// CPS (GPIO46): PA mode - LOW for RX (don't care), HIGH during TX for full PA
40-
// Note: GPIO46 is NOT an RTC GPIO, so no rtc_gpio_hold_dis needed
41-
pinMode(P_LORA_PA_TX_EN, OUTPUT);
42-
digitalWrite(P_LORA_PA_TX_EN, LOW); // Start in RX-ready state
43-
// -------------------------------------------
44-
45-
periph_power.begin();
46-
9+
// Check if waking from deep sleep
4710
esp_reset_reason_t reason = esp_reset_reason();
4811
if (reason == ESP_RST_DEEPSLEEP) {
4912
long wakeup_source = esp_sleep_get_ext1_wakeup_status();
5013
if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep)
5114
startup_reason = BD_STARTUP_RX_PACKET;
5215
}
5316

17+
// Release RTC holds - pins retain their state, no need to reconfigure
5418
rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS);
19+
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER);
20+
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
5521
rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1);
22+
} else {
23+
// Cold boot: Configure GC1109 FEM pins
24+
// Control logic (from GC1109 datasheet):
25+
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
26+
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
27+
// Pin mapping: CTX->DIO2 (auto), CSD->GPIO2, CPS->GPIO46, VFEM->GPIO7
28+
29+
// VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO
30+
pinMode(P_LORA_PA_POWER, OUTPUT);
31+
digitalWrite(P_LORA_PA_POWER, HIGH);
32+
33+
// CSD (GPIO2): Chip enable - must be HIGH for GC1109 to work
34+
pinMode(P_LORA_PA_EN, OUTPUT);
35+
digitalWrite(P_LORA_PA_EN, HIGH);
5636
}
37+
38+
periph_power.begin();
39+
40+
// Note: GPIO46 (CPS) is a strapping pin - do NOT configure it here.
41+
// TX handlers are fully responsible for GPIO46 (see onBeforeTransmit/onAfterTransmit)
5742
}
5843

5944
void HeltecV4Board::onBeforeTransmit(void) {
60-
digitalWrite(P_LORA_TX_LED, HIGH); // Turn TX LED on
61-
digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode (+30dBm)
62-
// CTX (TX/RX path) handled by SX1262 DIO2 -> GC1109 CTX (hardware)
45+
// GPIO46 is a strapping pin - only drive it when actively transmitting
46+
pinMode(P_LORA_PA_TX_EN, OUTPUT);
47+
digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode
48+
digitalWrite(P_LORA_TX_LED, HIGH);
6349
}
6450

6551
void HeltecV4Board::onAfterTransmit(void) {
66-
digitalWrite(P_LORA_PA_TX_EN, LOW); // CPS=0: Back to RX mode (CPS=X for RX)
67-
digitalWrite(P_LORA_TX_LED, LOW); // Turn TX LED off
68-
// CTX (TX/RX path) handled by SX1262 DIO2 -> GC1109 CTX (hardware)
52+
digitalWrite(P_LORA_PA_TX_EN, LOW);
53+
pinMode(P_LORA_PA_TX_EN, INPUT); // Release strapping pin
54+
digitalWrite(P_LORA_TX_LED, LOW);
6955
}
7056

7157
void HeltecV4Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {

0 commit comments

Comments
 (0)