Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,52 @@ void HeltecTrackerV2Board::begin() {
pinMode(PIN_ADC_CTRL, OUTPUT);
digitalWrite(PIN_ADC_CTRL, LOW); // Initially inactive

pinMode(P_LORA_PA_POWER, OUTPUT);
digitalWrite(P_LORA_PA_POWER,HIGH);

rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
pinMode(P_LORA_PA_EN, OUTPUT);
digitalWrite(P_LORA_PA_EN,HIGH);
pinMode(P_LORA_PA_TX_EN, OUTPUT);
digitalWrite(P_LORA_PA_TX_EN,LOW);

periph_power.begin();

// Check if waking from deep sleep
esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_DEEPSLEEP) {
long wakeup_source = esp_sleep_get_ext1_wakeup_status();
if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep)
startup_reason = BD_STARTUP_RX_PACKET;
}

// Release RTC holds - pins retain their state, no need to reconfigure
rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS);
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER);
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1);
} else {
// Cold boot: Configure GC1109 FEM pins
// Control logic (from GC1109 datasheet):
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
// Pin mapping: CTX->DIO2 (auto), CSD->GPIO4, CPS->GPIO46, VFEM->GPIO7

// VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO
pinMode(P_LORA_PA_POWER, OUTPUT);
digitalWrite(P_LORA_PA_POWER, HIGH);

// CSD (GPIO4): Chip enable - must be HIGH for GC1109 to work
pinMode(P_LORA_PA_EN, OUTPUT);
digitalWrite(P_LORA_PA_EN, HIGH);
}

periph_power.begin();

// Note: GPIO46 (CPS) is a strapping pin - do NOT configure it here.
// TX handlers are fully responsible for GPIO46 (see onBeforeTransmit/onAfterTransmit)
}

void HeltecTrackerV2Board::onBeforeTransmit(void) {
digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on
digitalWrite(P_LORA_PA_TX_EN,HIGH);
// GPIO46 is a strapping pin - only drive it when actively transmitting
pinMode(P_LORA_PA_TX_EN, OUTPUT);
digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode
digitalWrite(P_LORA_TX_LED, HIGH);
}

void HeltecTrackerV2Board::onAfterTransmit(void) {
digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off
digitalWrite(P_LORA_PA_TX_EN,LOW);
digitalWrite(P_LORA_PA_TX_EN, LOW);
pinMode(P_LORA_PA_TX_EN, INPUT); // Release strapping pin
digitalWrite(P_LORA_TX_LED, LOW);
}

void HeltecTrackerV2Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
Expand All @@ -48,7 +63,11 @@ void HeltecTrackerV2Board::begin() {

rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);

rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); //It also needs to be enabled in receive mode
// Hold GC1109 FEM pins during sleep for RX wake capability
// State: CSD=1, CTX=0 (DIO2), CPS=X -> Receive LNA mode
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER); // VFEM_Ctrl - keep LDO powered
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); // CSD=1 - chip enabled
// Note: GPIO46 (CPS) is NOT an RTC GPIO, cannot hold - but CPS is don't care for RX

if (pin_wake_btn < 0) {
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
Expand Down
12 changes: 7 additions & 5 deletions variants/heltec_tracker_v2/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ build_flags =
-D P_LORA_SCLK=9
-D P_LORA_MISO=11
-D P_LORA_MOSI=10
-D P_LORA_PA_POWER=7 ;power en
-D P_LORA_PA_EN=4
-D P_LORA_PA_TX_EN=46 ;enable tx
-D LORA_TX_POWER=10 ;If it is configured as 10 here, the final output will be 22 dbm.
-D MAX_LORA_TX_POWER=22 ;Max SX1262 output
-D P_LORA_PA_POWER=7 ; VFEM_Ctrl - GC1109 LDO power enable
-D P_LORA_PA_EN=4 ; CSD - GC1109 chip enable (HIGH=on)
-D P_LORA_PA_TX_EN=46 ; CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass)
-D LORA_TX_POWER=10 ; 10dBm + 11dB gain = ~21dBm output (see gain curve above)
-D MAX_LORA_TX_POWER=22 ; Max SX1262 output -> ~28dBm at antenna
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
; GC1109 FEM: TX/RX switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH)
; GPIO46 is CPS (PA mode), not TX control - do not use for RF switching
-D PIN_BOARD_SDA=5
-D PIN_BOARD_SCL=6
-D PIN_USER_BTN=0
Expand Down
53 changes: 35 additions & 18 deletions variants/heltec_v4/HeltecV4Board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,55 @@
void HeltecV4Board::begin() {
ESP32Board::begin();


pinMode(PIN_ADC_CTRL, OUTPUT);
digitalWrite(PIN_ADC_CTRL, LOW); // Initially inactive

pinMode(P_LORA_PA_POWER, OUTPUT);
digitalWrite(P_LORA_PA_POWER,HIGH);

rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
pinMode(P_LORA_PA_EN, OUTPUT);
digitalWrite(P_LORA_PA_EN,HIGH);
pinMode(P_LORA_PA_TX_EN, OUTPUT);
digitalWrite(P_LORA_PA_TX_EN,LOW);


periph_power.begin();

// Check if waking from deep sleep
esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_DEEPSLEEP) {
long wakeup_source = esp_sleep_get_ext1_wakeup_status();
if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep)
startup_reason = BD_STARTUP_RX_PACKET;
}

// Release RTC holds - pins retain their state, no need to reconfigure
rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS);
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER);
rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN);
rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1);
} else {
// Cold boot: Configure GC1109 FEM pins
// Control logic (from GC1109 datasheet):
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
// Pin mapping: CTX->DIO2 (auto), CSD->GPIO2, CPS->GPIO46, VFEM->GPIO7

// VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO
pinMode(P_LORA_PA_POWER, OUTPUT);
digitalWrite(P_LORA_PA_POWER, HIGH);

// CSD (GPIO2): Chip enable - must be HIGH for GC1109 to work
pinMode(P_LORA_PA_EN, OUTPUT);
digitalWrite(P_LORA_PA_EN, HIGH);
}

periph_power.begin();

// Note: GPIO46 (CPS) is a strapping pin - do NOT configure it here.
// TX handlers are fully responsible for GPIO46 (see onBeforeTransmit/onAfterTransmit)
}

void HeltecV4Board::onBeforeTransmit(void) {
digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on
digitalWrite(P_LORA_PA_TX_EN,HIGH);
// GPIO46 is a strapping pin - only drive it when actively transmitting
pinMode(P_LORA_PA_TX_EN, OUTPUT);
digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode
digitalWrite(P_LORA_TX_LED, HIGH);
}

void HeltecV4Board::onAfterTransmit(void) {
digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off
digitalWrite(P_LORA_PA_TX_EN,LOW);
digitalWrite(P_LORA_PA_TX_EN, LOW);
pinMode(P_LORA_PA_TX_EN, INPUT); // Release strapping pin
digitalWrite(P_LORA_TX_LED, LOW);
}

void HeltecV4Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) {
Expand All @@ -50,7 +63,11 @@ void HeltecV4Board::begin() {

rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);

rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); //It also needs to be enabled in receive mode
// Hold GC1109 FEM pins during sleep for RX wake capability
// State: CSD=1, CTX=0 (DIO2), CPS=X -> Receive LNA mode
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER); // VFEM_Ctrl - keep LDO powered
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); // CSD=1 - chip enabled
// Note: GPIO46 (CPS) is NOT an RTC GPIO, cannot hold - but CPS is don't care for RX

if (pin_wake_btn < 0) {
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
Expand Down
8 changes: 5 additions & 3 deletions variants/heltec_v4/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ build_flags =
-D P_LORA_SCLK=9
-D P_LORA_MISO=11
-D P_LORA_MOSI=10
-D P_LORA_PA_POWER=7 ;power en
-D P_LORA_PA_EN=2
-D P_LORA_PA_TX_EN=46 ;enable tx
-D P_LORA_PA_POWER=7 ; VFEM_Ctrl - GC1109 LDO power enable
-D P_LORA_PA_EN=2 ; CSD - GC1109 chip enable (HIGH=on)
-D P_LORA_PA_TX_EN=46 ; CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass)
-D PIN_BOARD_SDA=17
-D PIN_BOARD_SCL=18
-D PIN_USER_BTN=0
Expand All @@ -31,6 +31,8 @@ build_flags =
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
; GC1109 FEM: TX/RX switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH)
; GPIO46 is CPS (power save), not TX control - do not use for RF switching
-D PIN_GPS_RX=38
-D PIN_GPS_TX=39
-D PIN_GPS_RESET=42
Expand Down