Files
MeshCore/variants/heltec_v4_r8/HeltecV4R8Board.cpp
mikecarper a3d77a9a76 Clean project references and separate optional bench tooling
Remove unrelated ecosystem comparisons and software citations while retaining hardware links, measured model names, and required license notices.

Preserve stock-peer runners and tests in a verified local validation package. Keep shared Companion USB transport in the firmware repository for the raw-radio sweep and OTA seeder, with focused CI coverage. Restore missing hosted documentation links.
2026-10-21 17:35:37 -07:00

113 lines
3.3 KiB
C++

#include "HeltecV4R8Board.h"
#include <helpers/ESP32GpioHold.h>
// Expansion Kit V2 control-pin notes (kept here beside the shared-reset
// sequencing): display/touch I2C is SDA 17 / SCL 18; GPIO 21 is the shared
// LCD_RESET / TP_RESET line; GPIO 44 drives the active-high backlight. The
// optional R13 touch interrupt lands on GPIO 43, which is also ESP32-S3 U0TXD,
// so production builds deliberately poll touch and do not define PIN_TOUCH_INT.
void HeltecV4R8Board::begin() {
ESP32Board::begin();
periph_power.begin();
periph_power.claim(); // R8 VEXT also feeds the LoRa antenna boost rail.
loRaFEMControl.init();
#ifdef PIN_TOUCH_RST
pinMode(PIN_TOUCH_RST, OUTPUT);
digitalWrite(PIN_TOUCH_RST, HIGH);
delay(10);
digitalWrite(PIN_TOUCH_RST, LOW);
delay(100);
digitalWrite(PIN_TOUCH_RST, HIGH);
#endif
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)) {
startup_reason = BD_STARTUP_RX_PACKET;
}
mesh::esp32::releaseRtcGpioIfSupported((gpio_num_t)P_LORA_NSS);
mesh::esp32::deinitRtcGpioIfSupported((gpio_num_t)P_LORA_DIO_1);
}
}
void HeltecV4R8Board::onBeforeTransmit(void) {
if (mesh::leds::enabled()) digitalWrite(P_LORA_TX_LED, HIGH);
loRaFEMControl.setTxModeEnable();
}
void HeltecV4R8Board::onAfterTransmit(void) {
digitalWrite(P_LORA_TX_LED, LOW);
loRaFEMControl.setRxModeEnable();
}
void HeltecV4R8Board::powerOff() {
ESP32Board::powerOff();
}
void HeltecV4R8Board::shutdownPeripherals() {
ESP32Board::shutdownPeripherals();
loRaFEMControl.setSleepModeEnable();
mesh::esp32::holdOutputForDeepSleep((gpio_num_t)P_LORA_PA_POWER, LOW);
periph_power.release(); // Drop the permanent antenna-boost/VEXT claim from begin().
}
uint16_t HeltecV4R8Board::getBattMilliVolts() {
analogReadResolution(12);
uint32_t raw = 0;
for (int i = 0; i < 8; i++) {
raw += analogReadMilliVolts(PIN_VBAT_READ);
}
raw = raw / 8;
return (adc_mult * raw);
}
bool HeltecV4R8Board::isExternalPowered() {
// R8 has no MCU-connected VBUS/charger-status pin. A USB host is definitive;
// otherwise use the calibrated battery voltage as a best-effort estimate.
if (isUsbHostConnected()) return true;
const uint32_t now = millis();
if (!power_voltage_sampled || uint32_t(now - last_power_check_ms) >= 5000) {
last_power_check_ms = now;
power_voltage_sampled = true;
// Enter above a full Li-ion cell plus 10 mV. Release at 4.20 V to reduce
// display-profile chatter. This can miss a charger while the battery is
// low; it is not a charging-status flag.
const uint16_t millivolts = getBattMilliVolts();
voltage_external_power = millivolts > (voltage_external_power ? 4200 : 4210);
}
return voltage_external_power;
}
const char* HeltecV4R8Board::getManufacturerName() const {
#ifdef HELTEC_V4_R8_TFT
return "Heltec V4 R8 TFT";
#else
return "Heltec V4 R8 OLED";
#endif
}
bool HeltecV4R8Board::setLoRaFemLnaEnabled(bool enable) {
if (!loRaFEMControl.isLnaCanControl()) return false;
loRaFEMControl.setLNAEnable(enable);
loRaFEMControl.setRxModeEnable();
return true;
}
bool HeltecV4R8Board::canControlLoRaFemLna() const {
return loRaFEMControl.isLnaCanControl();
}
bool HeltecV4R8Board::isLoRaFemLnaEnabled() const {
return loRaFEMControl.isLNAEnabled();
}