Skip to content
Merged
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
61 changes: 61 additions & 0 deletions boards/heltec_tower_v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A","0x4405"],
["0x239A","0x0029"],
["0x239A","0x002A"],
["0x239A","0x0071"]
],
"usb_product": "HT-n5262",
"mcu": "nrf52840",
"variant": "heltec_tower_v2",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": [
"bluetooth"
],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52.cfg"
},
"frameworks": [
"arduino"
],
"name": "Heltec Tower V2 Board",
"upload": {
"maximum_ram_size": 235520,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"stlink"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://heltec.org/",
"vendor": "Heltec"
}
4 changes: 0 additions & 4 deletions src/helpers/CommonCLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,13 +953,9 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
strcpy(reply, "ERROR: Power management not supported");
#endif
} else if (memcmp(config, "pwrmgt.bootreason", 17) == 0) {
#ifdef NRF52_POWER_MANAGEMENT
sprintf(reply, "> Reset: %s; Shutdown: %s",
_board->getResetReasonString(_board->getResetReason()),
_board->getShutdownReasonString(_board->getShutdownReason()));
#else
strcpy(reply, "ERROR: Power management not supported");
#endif
} else if (memcmp(config, "pwrmgt.bootmv", 13) == 0) {
#ifdef NRF52_POWER_MANAGEMENT
sprintf(reply, "> %u mV", _board->getBootVoltage());
Expand Down
36 changes: 36 additions & 0 deletions src/helpers/ESP32Board.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,42 @@ class ESP32Board : public mesh::MainBoard {
void setInhibitSleep(bool inhibit) {
inhibit_sleep = inhibit;
}

uint32_t getResetReason() const override {
return esp_reset_reason();
}

// https://docs.espressif.com/projects/esp-idf/en/v4.4.7/esp32/api-reference/system/system.html
const char* getResetReasonString(uint32_t reason) {
switch (reason) {
case ESP_RST_UNKNOWN:
return "Unknown or first boot";
case ESP_RST_POWERON:
return "Power-on reset";
case ESP_RST_EXT:
return "External reset";
case ESP_RST_SW:
return "Software reset";
case ESP_RST_PANIC:
return "Panic / exception reset";
case ESP_RST_INT_WDT:
return "Interrupt watchdog reset";
case ESP_RST_TASK_WDT:
return "Task watchdog reset";
case ESP_RST_WDT:
return "Other watchdog reset";
case ESP_RST_DEEPSLEEP:
return "Wake from deep sleep";
case ESP_RST_BROWNOUT:
return "Brownout (low voltage)";
case ESP_RST_SDIO:
return "SDIO reset";
default:
static char buf[40];
snprintf(buf, sizeof(buf), "Unknown reset reason (%d)", reason);
return buf;
}
}
};

class ESP32RTCClock : public mesh::RTCClock {
Expand Down
1 change: 0 additions & 1 deletion variants/heltec_mesh_solar/platformio.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[Heltec_mesh_solar]
extends = nrf52_base
board = heltec_mesh_solar
platform_packages = framework-arduinoadafruitnrf52
board_build.ldscript = boards/nrf52840_s140_v6.ld
build_flags = ${nrf52_base.build_flags}
-I src/helpers/nrf52
Expand Down
2 changes: 1 addition & 1 deletion variants/heltec_t114/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock);

#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
#else
EnvironmentSensorManager sensors;
Expand Down
103 changes: 103 additions & 0 deletions variants/heltec_tower_v2/HeltecTowerV2Board.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "HeltecTowerV2Board.h"

#include <Arduino.h>
#include <Wire.h>

extern void variant_shutdown();

#ifdef NRF52_POWER_MANAGEMENT
const PowerMgtConfig power_config = {
.lpcomp_ain_channel = PWRMGT_LPCOMP_AIN,
.lpcomp_refsel = PWRMGT_LPCOMP_REFSEL,
.voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK
};

void HeltecTowerV2Board::initiateShutdown(uint8_t reason) {
pinMode(PIN_GPS_EN, OUTPUT);
digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, LOW);
pinMode(PIN_GPS_RESET, OUTPUT);
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE);
loRaFEMControl.setSleepModeEnable();

bool enable_lpcomp = (reason == SHUTDOWN_REASON_LOW_VOLTAGE ||
reason == SHUTDOWN_REASON_BOOT_PROTECT);
pinMode(PIN_BAT_CTL, OUTPUT);
digitalWrite(PIN_BAT_CTL, enable_lpcomp ? HIGH : LOW);

if (enable_lpcomp) {
configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel);
}

variant_shutdown();
enterSystemOff(reason);
}
#endif

void HeltecTowerV2Board::begin() {
NRF52Board::begin();

pinMode(P_LORA_TX_LED, OUTPUT);
digitalWrite(P_LORA_TX_LED, !LED_STATE_ON);

pinMode(PIN_BAT_CTL, OUTPUT);
digitalWrite(PIN_BAT_CTL, LOW);

#ifdef NRF52_POWER_MANAGEMENT
checkBootVoltage(&power_config);
#endif

Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
Wire.begin();

pinMode(PIN_GPS_EN, OUTPUT);
digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
pinMode(PIN_GPS_RESET, OUTPUT);
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE);
pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, HIGH);
loRaFEMControl.init();
}

void HeltecTowerV2Board::onBeforeTransmit() {
digitalWrite(P_LORA_TX_LED, LED_STATE_ON);
loRaFEMControl.setTxModeEnable();
}

void HeltecTowerV2Board::onAfterTransmit() {
digitalWrite(P_LORA_TX_LED, !LED_STATE_ON);
loRaFEMControl.setRxModeEnable();
}

uint16_t HeltecTowerV2Board::getBattMilliVolts() {
analogReadResolution(12);
analogReference(VBAT_AR_INTERNAL);
pinMode(PIN_VBAT_READ, INPUT);
pinMode(PIN_BAT_CTL, OUTPUT);
digitalWrite(PIN_BAT_CTL, HIGH);

delay(10);
int adcvalue = analogRead(PIN_VBAT_READ);
digitalWrite(PIN_BAT_CTL, LOW);

return (uint16_t)((float)adcvalue * MV_LSB * ADC_MULTIPLIER);
}

const char* HeltecTowerV2Board::getManufacturerName() const {
return "Heltec Tower V2";
}

void HeltecTowerV2Board::powerOff() {
pinMode(PIN_GPS_EN, OUTPUT);
digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, LOW);
pinMode(PIN_GPS_RESET, OUTPUT);
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE);
loRaFEMControl.setSleepModeEnable();
pinMode(PIN_BAT_CTL, OUTPUT);
digitalWrite(PIN_BAT_CTL, LOW);
variant_shutdown();
sd_power_system_off();
}
24 changes: 24 additions & 0 deletions variants/heltec_tower_v2/HeltecTowerV2Board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <Arduino.h>
#include <MeshCore.h>
#include <helpers/NRF52Board.h>
#include "LoRaFEMControl.h"

class HeltecTowerV2Board : public NRF52BoardDCDC {
protected:
#ifdef NRF52_POWER_MANAGEMENT
void initiateShutdown(uint8_t reason) override;
#endif

public:
LoRaFEMControl loRaFEMControl;

HeltecTowerV2Board() : NRF52Board("TOWER_V2_OTA") {}
void begin();
void onBeforeTransmit() override;
void onAfterTransmit() override;
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override;
void powerOff() override;
};
40 changes: 40 additions & 0 deletions variants/heltec_tower_v2/LoRaFEMControl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "LoRaFEMControl.h"

#include <Arduino.h>
#include "variant.h"

static void enableFEMPower() {
bool wasOff = digitalRead(LORA_KCT8103L_EN) != HIGH;
digitalWrite(LORA_KCT8103L_EN, HIGH);
if (wasOff) {
delay(5);
}
}

void LoRaFEMControl::init() {
pinMode(LORA_KCT8103L_EN, OUTPUT);
digitalWrite(LORA_KCT8103L_EN, HIGH);
delay(1);
pinMode(LORA_KCT8103L_TX_RX, OUTPUT);
digitalWrite(LORA_KCT8103L_TX_RX, LOW);
}

void LoRaFEMControl::setSleepModeEnable() {
pinMode(LORA_KCT8103L_EN, OUTPUT);
digitalWrite(LORA_KCT8103L_EN, LOW);
}

void LoRaFEMControl::setTxModeEnable() {
enableFEMPower();
digitalWrite(LORA_KCT8103L_TX_RX, HIGH);
}

void LoRaFEMControl::setRxModeEnable() {
enableFEMPower();
digitalWrite(LORA_KCT8103L_TX_RX, LOW);
}

void LoRaFEMControl::setRxModeEnableWhenMCUSleep() {
enableFEMPower();
digitalWrite(LORA_KCT8103L_TX_RX, LOW);
}
13 changes: 13 additions & 0 deletions variants/heltec_tower_v2/LoRaFEMControl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

class LoRaFEMControl {
public:
LoRaFEMControl() {}
virtual ~LoRaFEMControl() {}

void init();
void setSleepModeEnable();
void setTxModeEnable();
void setRxModeEnable();
void setRxModeEnableWhenMCUSleep();
};
Loading
Loading