Skip to content

Commit 0b0fdb8

Browse files
authored
Merge pull request #2097 from Quency-D/heltec-t096
add heltec_mesh_node_t096 board.
2 parents 467959c + f6cfed6 commit 0b0fdb8

11 files changed

Lines changed: 690 additions & 4 deletions

File tree

boards/heltec_t096.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"build": {
3+
"arduino": {
4+
"ldscript": "nrf52840_s140_v6.ld"
5+
},
6+
"core": "nRF5",
7+
"cpu": "cortex-m4",
8+
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
9+
"f_cpu": "64000000L",
10+
"hwids": [
11+
["0x239A","0x8029"],
12+
["0x239A","0x0029"],
13+
["0x239A","0x002A"],
14+
["0x239A","0x802A"]
15+
],
16+
"usb_product": "HT-n5262G",
17+
"mcu": "nrf52840",
18+
"variant": "Heltec_T096_Board",
19+
"bsp": {
20+
"name": "adafruit"
21+
},
22+
"softdevice": {
23+
"sd_flags": "-DS140",
24+
"sd_name": "s140",
25+
"sd_version": "6.1.1",
26+
"sd_fwid": "0x00B6"
27+
},
28+
"bootloader": {
29+
"settings_addr": "0xFF000"
30+
}
31+
},
32+
"connectivity": [
33+
"bluetooth"
34+
],
35+
"debug": {
36+
"jlink_device": "nRF52840_xxAA",
37+
"svd_path": "nrf52840.svd",
38+
"openocd_target": "nrf52.cfg"
39+
},
40+
"frameworks": [
41+
"arduino"
42+
],
43+
"name": "Heltec T096 Board",
44+
"upload": {
45+
"maximum_ram_size": 235520,
46+
"maximum_size": 815104,
47+
"speed": 115200,
48+
"protocol": "nrfutil",
49+
"protocols": [
50+
"jlink",
51+
"nrfjprog",
52+
"nrfutil",
53+
"stlink"
54+
],
55+
"use_1200bps_touch": true,
56+
"require_upload_port": true,
57+
"wait_for_upload_port": true
58+
},
59+
"url": "https://heltec.org/",
60+
"vendor": "Heltec"
61+
}

src/helpers/ui/ST7735Display.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ bool ST7735Display::begin() {
2121
if (_peripher_power) _peripher_power->claim();
2222

2323
pinMode(PIN_TFT_LEDA_CTL, OUTPUT);
24-
digitalWrite(PIN_TFT_LEDA_CTL, HIGH);
24+
#if defined(PIN_TFT_LEDA_CTL_ACTIVE)
25+
digitalWrite(PIN_TFT_LEDA_CTL, PIN_TFT_LEDA_CTL_ACTIVE);
26+
#else
27+
digitalWrite(PIN_TFT_LEDA_CTL, HIGH);
28+
#endif
2529
digitalWrite(PIN_TFT_RST, HIGH);
2630

27-
#if defined(HELTEC_TRACKER_V2)
31+
#if defined(HELTEC_TRACKER_V2) || defined(HELTEC_T096)
2832
display.initR(INITR_MINI160x80);
2933
display.setRotation(DISPLAY_ROTATION);
3034
uint8_t madctl = ST77XX_MADCTL_MY | ST77XX_MADCTL_MV |ST7735_MADCTL_BGR;//Adjust color to BGR
@@ -50,9 +54,12 @@ void ST7735Display::turnOn() {
5054

5155
void ST7735Display::turnOff() {
5256
if (_isOn) {
53-
digitalWrite(PIN_TFT_LEDA_CTL, HIGH);
5457
digitalWrite(PIN_TFT_RST, LOW);
55-
digitalWrite(PIN_TFT_LEDA_CTL, LOW);
58+
#if defined(PIN_TFT_LEDA_CTL_ACTIVE)
59+
digitalWrite(PIN_TFT_LEDA_CTL, !PIN_TFT_LEDA_CTL_ACTIVE);
60+
#else
61+
digitalWrite(PIN_TFT_LEDA_CTL, LOW);
62+
#endif
5663
_isOn = false;
5764

5865
if (_peripher_power) _peripher_power->release();
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "LoRaFEMControl.h"
2+
#include <Arduino.h>
3+
4+
void LoRaFEMControl::init(void)
5+
{
6+
pinMode(P_LORA_PA_POWER, OUTPUT);
7+
digitalWrite(P_LORA_PA_POWER, HIGH);
8+
delay(1);
9+
pinMode(P_LORA_KCT8103L_PA_CSD, OUTPUT);
10+
digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
11+
pinMode(P_LORA_KCT8103L_PA_CTX, OUTPUT);
12+
digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
13+
setLnaCanControl(true);
14+
}
15+
16+
void LoRaFEMControl::setSleepModeEnable(void)
17+
{
18+
// shutdown the PA
19+
digitalWrite(P_LORA_KCT8103L_PA_CSD, LOW);
20+
}
21+
22+
void LoRaFEMControl::setTxModeEnable(void)
23+
{
24+
digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
25+
digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
26+
}
27+
28+
void LoRaFEMControl::setRxModeEnable(void)
29+
{
30+
digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
31+
if (lna_enabled) {
32+
digitalWrite(P_LORA_KCT8103L_PA_CTX, LOW);
33+
} else {
34+
digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
35+
}
36+
}
37+
38+
void LoRaFEMControl::setRxModeEnableWhenMCUSleep(void)
39+
{
40+
digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
41+
if (lna_enabled) {
42+
digitalWrite(P_LORA_KCT8103L_PA_CTX, LOW);
43+
} else {
44+
digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
45+
}
46+
}
47+
48+
void LoRaFEMControl::setLNAEnable(bool enabled)
49+
{
50+
lna_enabled = enabled;
51+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
#include <stdint.h>
3+
4+
class LoRaFEMControl
5+
{
6+
public:
7+
LoRaFEMControl() {}
8+
virtual ~LoRaFEMControl() {}
9+
void init(void);
10+
void setSleepModeEnable(void);
11+
void setTxModeEnable(void);
12+
void setRxModeEnable(void);
13+
void setRxModeEnableWhenMCUSleep(void);
14+
void setLNAEnable(bool enabled);
15+
bool isLnaCanControl(void) { return lna_can_control; }
16+
void setLnaCanControl(bool can_control) { lna_can_control = can_control; }
17+
18+
private:
19+
bool lna_enabled = false;
20+
bool lna_can_control = false;
21+
};

variants/heltec_t096/T096Board.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#include "T096Board.h"
2+
3+
#include <Arduino.h>
4+
#include <Wire.h>
5+
6+
#ifdef NRF52_POWER_MANAGEMENT
7+
// Static configuration for power management
8+
// Values come from variant.h defines
9+
const PowerMgtConfig power_config = {
10+
.lpcomp_ain_channel = PWRMGT_LPCOMP_AIN,
11+
.lpcomp_refsel = PWRMGT_LPCOMP_REFSEL,
12+
.voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK
13+
};
14+
15+
void T096Board::initiateShutdown(uint8_t reason) {
16+
#if ENV_INCLUDE_GPS == 1
17+
pinMode(PIN_GPS_EN, OUTPUT);
18+
digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
19+
#endif
20+
variant_shutdown();
21+
22+
bool enable_lpcomp = (reason == SHUTDOWN_REASON_LOW_VOLTAGE ||
23+
reason == SHUTDOWN_REASON_BOOT_PROTECT);
24+
pinMode(PIN_BAT_CTL, OUTPUT);
25+
digitalWrite(PIN_BAT_CTL, enable_lpcomp ? HIGH : LOW);
26+
27+
if (enable_lpcomp) {
28+
configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel);
29+
}
30+
31+
enterSystemOff(reason);
32+
}
33+
#endif // NRF52_POWER_MANAGEMENT
34+
35+
void T096Board::begin() {
36+
NRF52Board::begin();
37+
38+
#ifdef NRF52_POWER_MANAGEMENT
39+
// Boot voltage protection check (may not return if voltage too low)
40+
checkBootVoltage(&power_config);
41+
#endif
42+
43+
#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
44+
Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
45+
#endif
46+
47+
Wire.begin();
48+
49+
pinMode(P_LORA_TX_LED, OUTPUT);
50+
digitalWrite(P_LORA_TX_LED, LOW);
51+
52+
periph_power.begin();
53+
loRaFEMControl.init();
54+
delay(1);
55+
}
56+
57+
void T096Board::onBeforeTransmit() {
58+
digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on
59+
loRaFEMControl.setTxModeEnable();
60+
}
61+
62+
void T096Board::onAfterTransmit() {
63+
digitalWrite(P_LORA_TX_LED, LOW); //turn TX LED off
64+
loRaFEMControl.setRxModeEnable();
65+
}
66+
67+
uint16_t T096Board::getBattMilliVolts() {
68+
int adcvalue = 0;
69+
analogReadResolution(12);
70+
analogReference(AR_INTERNAL_3_0);
71+
pinMode(PIN_VBAT_READ, INPUT);
72+
pinMode(PIN_BAT_CTL, OUTPUT);
73+
digitalWrite(PIN_BAT_CTL, 1);
74+
75+
delay(10);
76+
adcvalue = analogRead(PIN_VBAT_READ);
77+
digitalWrite(PIN_BAT_CTL, 0);
78+
79+
return (uint16_t)((float)adcvalue * MV_LSB * 4.9);
80+
}
81+
void T096Board::variant_shutdown() {
82+
nrf_gpio_cfg_default(PIN_VEXT_EN);
83+
nrf_gpio_cfg_default(PIN_TFT_CS);
84+
nrf_gpio_cfg_default(PIN_TFT_DC);
85+
nrf_gpio_cfg_default(PIN_TFT_SDA);
86+
nrf_gpio_cfg_default(PIN_TFT_SCL);
87+
nrf_gpio_cfg_default(PIN_TFT_RST);
88+
nrf_gpio_cfg_default(PIN_TFT_LEDA_CTL);
89+
90+
nrf_gpio_cfg_default(PIN_LED);
91+
92+
nrf_gpio_cfg_default(P_LORA_KCT8103L_PA_CSD);
93+
nrf_gpio_cfg_default(P_LORA_KCT8103L_PA_CTX);
94+
pinMode(P_LORA_PA_POWER, OUTPUT);
95+
digitalWrite(P_LORA_PA_POWER, LOW);
96+
97+
digitalWrite(PIN_BAT_CTL, LOW);
98+
nrf_gpio_cfg_default(LORA_CS);
99+
nrf_gpio_cfg_default(SX126X_DIO1);
100+
nrf_gpio_cfg_default(SX126X_BUSY);
101+
nrf_gpio_cfg_default(SX126X_RESET);
102+
103+
nrf_gpio_cfg_default(PIN_SPI_MISO);
104+
nrf_gpio_cfg_default(PIN_SPI_MOSI);
105+
nrf_gpio_cfg_default(PIN_SPI_SCK);
106+
107+
// nrf_gpio_cfg_default(PIN_GPS_PPS);
108+
nrf_gpio_cfg_default(PIN_GPS_RESET);
109+
nrf_gpio_cfg_default(PIN_GPS_EN);
110+
nrf_gpio_cfg_default(PIN_GPS_RX);
111+
nrf_gpio_cfg_default(PIN_GPS_TX);
112+
}
113+
114+
void T096Board::powerOff() {
115+
#if ENV_INCLUDE_GPS == 1
116+
pinMode(PIN_GPS_EN, OUTPUT);
117+
digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
118+
#endif
119+
loRaFEMControl.setSleepModeEnable();
120+
variant_shutdown();
121+
sd_power_system_off();
122+
}
123+
124+
const char* T096Board::getManufacturerName() const {
125+
return "Heltec T096";
126+
}

variants/heltec_t096/T096Board.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <MeshCore.h>
4+
#include <Arduino.h>
5+
#include <helpers/NRF52Board.h>
6+
#include <helpers/RefCountedDigitalPin.h>
7+
#include "LoRaFEMControl.h"
8+
9+
class T096Board : public NRF52BoardDCDC {
10+
protected:
11+
#ifdef NRF52_POWER_MANAGEMENT
12+
void initiateShutdown(uint8_t reason) override;
13+
#endif
14+
void variant_shutdown();
15+
16+
public:
17+
RefCountedDigitalPin periph_power;
18+
LoRaFEMControl loRaFEMControl;
19+
20+
T096Board() :periph_power(PIN_VEXT_EN,PIN_VEXT_EN_ACTIVE), NRF52Board("T096_OTA") {}
21+
void begin();
22+
23+
void onBeforeTransmit(void) override;
24+
void onAfterTransmit(void) override;
25+
uint16_t getBattMilliVolts() override;
26+
const char* getManufacturerName() const override ;
27+
void powerOff() override;
28+
};

0 commit comments

Comments
 (0)