Browse Source

add heltec_mesh_node_t096 board.

Quency-D 4 months ago
parent
commit
f6cfed66b3

+ 61 - 0
boards/heltec_t096.json

@@ -0,0 +1,61 @@
+{
+  "build": {
+    "arduino": {
+      "ldscript": "nrf52840_s140_v6.ld"
+    },
+    "core": "nRF5",
+    "cpu": "cortex-m4",
+    "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
+    "f_cpu": "64000000L",
+    "hwids": [
+      ["0x239A","0x8029"],
+      ["0x239A","0x0029"],
+      ["0x239A","0x002A"],
+      ["0x239A","0x802A"]
+    ],
+    "usb_product": "HT-n5262G",
+    "mcu": "nrf52840",
+    "variant": "Heltec_T096_Board",
+    "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 T096 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"
+}

+ 11 - 4
src/helpers/ui/ST7735Display.cpp

@@ -21,10 +21,14 @@ bool ST7735Display::begin() {
     if (_peripher_power) _peripher_power->claim();
 
     pinMode(PIN_TFT_LEDA_CTL, OUTPUT);
-    digitalWrite(PIN_TFT_LEDA_CTL, HIGH);
+#if defined(PIN_TFT_LEDA_CTL_ACTIVE)
+    digitalWrite(PIN_TFT_LEDA_CTL, PIN_TFT_LEDA_CTL_ACTIVE);
+#else
+    digitalWrite(PIN_TFT_LEDA_CTL, HIGH); 
+#endif
     digitalWrite(PIN_TFT_RST, HIGH);
 
-#if defined(HELTEC_TRACKER_V2)
+#if defined(HELTEC_TRACKER_V2) || defined(HELTEC_T096)
     display.initR(INITR_MINI160x80);
     display.setRotation(DISPLAY_ROTATION);
     uint8_t madctl = ST77XX_MADCTL_MY | ST77XX_MADCTL_MV |ST7735_MADCTL_BGR;//Adjust color to BGR
@@ -50,9 +54,12 @@ void ST7735Display::turnOn() {
 
 void ST7735Display::turnOff() {
   if (_isOn) {
-    digitalWrite(PIN_TFT_LEDA_CTL, HIGH);
     digitalWrite(PIN_TFT_RST, LOW);
-    digitalWrite(PIN_TFT_LEDA_CTL, LOW);
+#if defined(PIN_TFT_LEDA_CTL_ACTIVE)
+    digitalWrite(PIN_TFT_LEDA_CTL, !PIN_TFT_LEDA_CTL_ACTIVE);
+#else
+    digitalWrite(PIN_TFT_LEDA_CTL, LOW); 
+#endif
     _isOn = false;
 
     if (_peripher_power) _peripher_power->release();

+ 51 - 0
variants/heltec_t096/LoRaFEMControl.cpp

@@ -0,0 +1,51 @@
+#include "LoRaFEMControl.h"
+#include <Arduino.h>
+
+void LoRaFEMControl::init(void)
+{
+    pinMode(P_LORA_PA_POWER, OUTPUT);
+    digitalWrite(P_LORA_PA_POWER, HIGH);
+    delay(1);
+    pinMode(P_LORA_KCT8103L_PA_CSD, OUTPUT);
+    digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
+    pinMode(P_LORA_KCT8103L_PA_CTX, OUTPUT);
+    digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
+    setLnaCanControl(true);
+}
+
+void LoRaFEMControl::setSleepModeEnable(void)
+{
+    // shutdown the PA
+    digitalWrite(P_LORA_KCT8103L_PA_CSD, LOW);
+}
+
+void LoRaFEMControl::setTxModeEnable(void)
+{
+    digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
+    digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
+}
+
+void LoRaFEMControl::setRxModeEnable(void)
+{
+    digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
+    if (lna_enabled) {
+        digitalWrite(P_LORA_KCT8103L_PA_CTX, LOW);
+    } else {
+        digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
+    }
+}
+
+void LoRaFEMControl::setRxModeEnableWhenMCUSleep(void)
+{
+    digitalWrite(P_LORA_KCT8103L_PA_CSD, HIGH);
+    if (lna_enabled) {
+        digitalWrite(P_LORA_KCT8103L_PA_CTX, LOW);
+    } else {
+        digitalWrite(P_LORA_KCT8103L_PA_CTX, HIGH);
+    }
+}
+
+void LoRaFEMControl::setLNAEnable(bool enabled)
+{
+    lna_enabled = enabled;
+}

+ 21 - 0
variants/heltec_t096/LoRaFEMControl.h

@@ -0,0 +1,21 @@
+#pragma once
+#include <stdint.h>
+
+class LoRaFEMControl
+{
+  public:
+    LoRaFEMControl() {}
+    virtual ~LoRaFEMControl() {}
+    void init(void);
+    void setSleepModeEnable(void);
+    void setTxModeEnable(void);
+    void setRxModeEnable(void);
+    void setRxModeEnableWhenMCUSleep(void);
+    void setLNAEnable(bool enabled);
+    bool isLnaCanControl(void) { return lna_can_control; }
+    void setLnaCanControl(bool can_control) { lna_can_control = can_control; }
+
+  private:
+    bool lna_enabled = false;
+    bool lna_can_control = false;
+};

+ 126 - 0
variants/heltec_t096/T096Board.cpp

@@ -0,0 +1,126 @@
+#include "T096Board.h"
+
+#include <Arduino.h>
+#include <Wire.h>
+
+#ifdef NRF52_POWER_MANAGEMENT
+// Static configuration for power management
+// Values come from variant.h defines
+const PowerMgtConfig power_config = {
+  .lpcomp_ain_channel = PWRMGT_LPCOMP_AIN,
+  .lpcomp_refsel = PWRMGT_LPCOMP_REFSEL,
+  .voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK
+};
+
+void T096Board::initiateShutdown(uint8_t reason) {
+#if ENV_INCLUDE_GPS == 1
+  pinMode(PIN_GPS_EN, OUTPUT);
+  digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
+#endif
+  variant_shutdown();
+
+  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);
+  }
+
+  enterSystemOff(reason);
+}
+#endif // NRF52_POWER_MANAGEMENT
+
+void T096Board::begin() {
+  NRF52Board::begin();
+
+#ifdef NRF52_POWER_MANAGEMENT
+  // Boot voltage protection check (may not return if voltage too low)
+  checkBootVoltage(&power_config);
+#endif
+
+#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
+  Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
+#endif
+
+  Wire.begin();
+
+  pinMode(P_LORA_TX_LED, OUTPUT);
+  digitalWrite(P_LORA_TX_LED, LOW);
+
+  periph_power.begin();
+  loRaFEMControl.init();
+  delay(1);
+}
+
+void T096Board::onBeforeTransmit() {
+    digitalWrite(P_LORA_TX_LED, HIGH);   // turn TX LED on
+    loRaFEMControl.setTxModeEnable();
+}
+
+void T096Board::onAfterTransmit() {
+    digitalWrite(P_LORA_TX_LED, LOW);   //turn TX LED off
+    loRaFEMControl.setRxModeEnable();
+}
+
+uint16_t T096Board::getBattMilliVolts() {
+    int adcvalue = 0;
+    analogReadResolution(12);
+    analogReference(AR_INTERNAL_3_0);
+    pinMode(PIN_VBAT_READ, INPUT);
+    pinMode(PIN_BAT_CTL, OUTPUT);
+    digitalWrite(PIN_BAT_CTL, 1);
+
+    delay(10);
+    adcvalue = analogRead(PIN_VBAT_READ);
+    digitalWrite(PIN_BAT_CTL, 0);
+
+    return (uint16_t)((float)adcvalue * MV_LSB * 4.9);
+}
+void T096Board::variant_shutdown() {
+ nrf_gpio_cfg_default(PIN_VEXT_EN);
+    nrf_gpio_cfg_default(PIN_TFT_CS);
+    nrf_gpio_cfg_default(PIN_TFT_DC);
+    nrf_gpio_cfg_default(PIN_TFT_SDA);
+    nrf_gpio_cfg_default(PIN_TFT_SCL);
+    nrf_gpio_cfg_default(PIN_TFT_RST);
+    nrf_gpio_cfg_default(PIN_TFT_LEDA_CTL);
+
+    nrf_gpio_cfg_default(PIN_LED);
+
+    nrf_gpio_cfg_default(P_LORA_KCT8103L_PA_CSD);
+    nrf_gpio_cfg_default(P_LORA_KCT8103L_PA_CTX);
+    pinMode(P_LORA_PA_POWER, OUTPUT);
+    digitalWrite(P_LORA_PA_POWER, LOW);
+
+    digitalWrite(PIN_BAT_CTL, LOW);
+    nrf_gpio_cfg_default(LORA_CS);
+    nrf_gpio_cfg_default(SX126X_DIO1);
+    nrf_gpio_cfg_default(SX126X_BUSY);
+    nrf_gpio_cfg_default(SX126X_RESET);
+
+    nrf_gpio_cfg_default(PIN_SPI_MISO);
+    nrf_gpio_cfg_default(PIN_SPI_MOSI);
+    nrf_gpio_cfg_default(PIN_SPI_SCK);
+
+    // nrf_gpio_cfg_default(PIN_GPS_PPS);
+    nrf_gpio_cfg_default(PIN_GPS_RESET);
+    nrf_gpio_cfg_default(PIN_GPS_EN);
+    nrf_gpio_cfg_default(PIN_GPS_RX);
+    nrf_gpio_cfg_default(PIN_GPS_TX);
+}
+
+void T096Board::powerOff() {
+#if ENV_INCLUDE_GPS == 1
+    pinMode(PIN_GPS_EN, OUTPUT);
+    digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
+#endif
+    loRaFEMControl.setSleepModeEnable();
+    variant_shutdown();
+    sd_power_system_off();
+}
+
+const char* T096Board::getManufacturerName() const {
+  return "Heltec T096";
+}

+ 28 - 0
variants/heltec_t096/T096Board.h

@@ -0,0 +1,28 @@
+#pragma once
+
+#include <MeshCore.h>
+#include <Arduino.h>
+#include <helpers/NRF52Board.h>
+#include <helpers/RefCountedDigitalPin.h>
+#include "LoRaFEMControl.h"
+
+class T096Board : public NRF52BoardDCDC {
+protected:
+#ifdef NRF52_POWER_MANAGEMENT
+  void initiateShutdown(uint8_t reason) override;
+#endif
+  void variant_shutdown();
+
+public:
+  RefCountedDigitalPin periph_power;
+  LoRaFEMControl loRaFEMControl;
+
+  T096Board() :periph_power(PIN_VEXT_EN,PIN_VEXT_EN_ACTIVE), NRF52Board("T096_OTA") {}
+  void begin();
+
+  void onBeforeTransmit(void) override;
+  void onAfterTransmit(void) override;
+  uint16_t getBattMilliVolts() override;
+  const char* getManufacturerName() const override ;
+  void powerOff() override;
+};

+ 148 - 0
variants/heltec_t096/platformio.ini

@@ -0,0 +1,148 @@
+[Heltec_t096]
+extends = nrf52_base
+board = heltec_t096
+board_build.ldscript = boards/nrf52840_s140_v6.ld
+build_flags = ${nrf52_base.build_flags}
+  ${sensor_base.build_flags}
+  -I lib/nrf52/s140_nrf52_6.1.1_API/include
+  -I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52
+  -I variants/heltec_t096
+  -I src/helpers/ui
+  -D HELTEC_T096
+  -D NRF52_POWER_MANAGEMENT
+  -D P_LORA_DIO_1=21
+  -D P_LORA_NSS=5
+  -D P_LORA_RESET=16
+  -D P_LORA_BUSY=19
+  -D P_LORA_SCLK=40
+  -D P_LORA_MISO=14
+  -D P_LORA_MOSI=11
+  -D P_LORA_TX_LED=28
+  -D P_LORA_PA_POWER=30  ;VFEM_Ctrl -LDO power enable
+  -D P_LORA_KCT8103L_PA_CSD=12
+  -D P_LORA_KCT8103L_PA_CTX=41
+  -D LORA_TX_POWER=9      ; 9dBm + ~13dB KCT8103L gain = ~22dBm output
+  -D MAX_LORA_TX_POWER=22 ; Max SX1262 output -> ~28dBm at antenna
+  -D RADIO_CLASS=CustomSX1262
+  -D WRAPPER_CLASS=CustomSX1262Wrapper
+  -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
+  -D PIN_VEXT_EN=26   ; Vext is connected to VDD which is also connected to TFT & GPS
+  -D PIN_VEXT_EN_ACTIVE=HIGH
+  -D PIN_GPS_RX=25
+  -D PIN_GPS_TX=23
+  -D PIN_GPS_EN=GPS_EN
+  -D PIN_GPS_EN_ACTIVE=LOW
+  -D PIN_GPS_RESET=GPS_RESET
+  -D PIN_GPS_RESET_ACTIVE=LOW
+  -D GPS_BAUD_RATE=115200
+  -D PIN_VBAT_READ=BATTERY_PIN
+  -D PIN_BAT_CTL=47
+  -D DISPLAY_CLASS=ST7735Display
+  -D DISPLAY_ROTATION=1
+build_src_filter = ${nrf52_base.build_src_filter}
+  +<helpers/*.cpp>
+  +<helpers/sensors>
+  +<../variants/heltec_t096>
+  +<helpers/ui/ST7735Display.cpp>
+  +<helpers/ui/MomentaryButton.cpp>
+lib_deps =
+  ${nrf52_base.lib_deps}
+  ${sensor_base.lib_deps}
+  adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
+debug_tool = jlink
+upload_protocol = nrfutil
+
+[env:Heltec_t096_repeater]
+extends = Heltec_t096
+build_src_filter = ${Heltec_t096.build_src_filter}
+  +<../examples/simple_repeater>
+
+build_flags =
+  ${Heltec_t096.build_flags}
+  -D ADVERT_NAME='"Heltec_t096 Repeater"'
+  -D ADVERT_LAT=0.0
+  -D ADVERT_LON=0.0
+  -D ADMIN_PASSWORD='"password"'
+  -D MAX_NEIGHBOURS=50
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+
+[env:Heltec_t096_repeater_bridge_rs232]
+extends = Heltec_t096
+build_flags =
+  ${Heltec_t096.build_flags}
+  -D ADVERT_NAME='"RS232 Bridge"'
+  -D ADVERT_LAT=0.0
+  -D ADVERT_LON=0.0
+  -D ADMIN_PASSWORD='"password"'
+  -D MAX_NEIGHBOURS=50
+  -D WITH_RS232_BRIDGE=Serial2
+  -D WITH_RS232_BRIDGE_RX=9
+  -D WITH_RS232_BRIDGE_TX=10
+;  -D BRIDGE_DEBUG=1
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${Heltec_t096.build_src_filter}
+  +<helpers/bridges/RS232Bridge.cpp>
+  +<../examples/simple_repeater>
+
+[env:Heltec_t096_room_server]
+extends = Heltec_t096
+build_src_filter = ${Heltec_t096.build_src_filter}
+  +<../examples/simple_room_server> 
+build_flags =
+  ${Heltec_t096.build_flags}
+  -D ADVERT_NAME='"Heltec_t096 Room"'
+  -D ADVERT_LAT=0.0
+  -D ADVERT_LON=0.0
+  -D ADMIN_PASSWORD='"password"'
+  -D ROOM_PASSWORD='"hello"'
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+
+[env:Heltec_t096_companion_radio_ble]
+extends = Heltec_t096
+board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
+board_upload.maximum_size = 712704
+build_flags =
+  ${Heltec_t096.build_flags}
+  -I examples/companion_radio/ui-new
+  -D MAX_CONTACTS=350
+  -D MAX_GROUP_CHANNELS=40
+  -D BLE_PIN_CODE=123456
+  -D ENV_INCLUDE_GPS=1   ; enable the GPS page in UI
+;  -D BLE_DEBUG_LOGGING=1
+  -D OFFLINE_QUEUE_SIZE=256
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${Heltec_t096.build_src_filter}
+  +<helpers/nrf52/SerialBLEInterface.cpp>
+  +<../examples/companion_radio/*.cpp>
+  +<../examples/companion_radio/ui-new/*.cpp>
+lib_deps =
+  ${Heltec_t096.lib_deps}
+  densaugeo/base64 @ ~1.4.0
+
+[env:Heltec_t096_companion_radio_usb]
+extends = Heltec_t096
+board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
+board_upload.maximum_size = 712704
+build_flags =
+  ${Heltec_t096.build_flags}
+  -I examples/companion_radio/ui-new
+  -D MAX_CONTACTS=350
+  -D MAX_GROUP_CHANNELS=40
+;  -D BLE_PIN_CODE=123456
+;  -D BLE_DEBUG_LOGGING=1
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${Heltec_t096.build_src_filter}
+  +<helpers/nrf52/*.cpp>
+  +<../examples/companion_radio/*.cpp>
+  +<../examples/companion_radio/ui-new/*.cpp>
+lib_deps =
+  ${Heltec_t096.lib_deps}
+  densaugeo/base64 @ ~1.4.0

+ 64 - 0
variants/heltec_t096/target.cpp

@@ -0,0 +1,64 @@
+#include "target.h"
+
+#include <Arduino.h>
+#include <helpers/ArduinoHelpers.h>
+
+#ifdef ENV_INCLUDE_GPS
+#include <helpers/sensors/MicroNMEALocationProvider.h>
+#endif
+
+T096Board board;
+
+#if defined(P_LORA_SCLK)
+RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
+#else
+RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
+#endif
+
+WRAPPER_CLASS radio_driver(radio, board);
+
+VolatileRTCClock fallback_clock;
+AutoDiscoverRTCClock rtc_clock(fallback_clock);
+
+#if ENV_INCLUDE_GPS
+#include <helpers/sensors/MicroNMEALocationProvider.h>
+MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock, GPS_RESET, GPS_EN, &board.periph_power);
+EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
+#else
+EnvironmentSensorManager sensors;
+#endif
+
+#ifdef DISPLAY_CLASS
+DISPLAY_CLASS display(&board.periph_power);
+MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
+#endif
+
+bool radio_init() {
+  rtc_clock.begin(Wire);
+
+#if defined(P_LORA_SCLK)
+  return radio.std_init(&SPI);
+#else
+  return radio.std_init();
+#endif
+}
+
+uint32_t radio_get_rng_seed() {
+  return radio.random(0x7FFFFFFF);
+}
+
+void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
+  radio.setFrequency(freq);
+  radio.setSpreadingFactor(sf);
+  radio.setBandwidth(bw);
+  radio.setCodingRate(cr);
+}
+
+void radio_set_tx_power(int8_t dbm) {
+  radio.setOutputPower(dbm);
+}
+
+mesh::LocalIdentity radio_new_identity() {
+  RadioNoiseListener rng(radio);
+  return mesh::LocalIdentity(&rng); // create new random identity
+}

+ 33 - 0
variants/heltec_t096/target.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#define RADIOLIB_STATIC_ONLY 1
+#include <RadioLib.h>
+#include <T096Board.h>
+#include <helpers/AutoDiscoverRTCClock.h>
+#include <helpers/radiolib/CustomSX1262Wrapper.h>
+#include <helpers/radiolib/RadioLibWrappers.h>
+#include <helpers/sensors/EnvironmentSensorManager.h>
+#include <helpers/sensors/LocationProvider.h>
+
+#ifdef DISPLAY_CLASS
+#include <helpers/ui/MomentaryButton.h>
+#include <helpers/ui/ST7735Display.h>
+#else
+#include "helpers/ui/NullDisplayDriver.h"
+#endif
+
+extern T096Board board;
+extern WRAPPER_CLASS radio_driver;
+extern AutoDiscoverRTCClock rtc_clock;
+extern EnvironmentSensorManager sensors;
+
+#ifdef DISPLAY_CLASS
+extern DISPLAY_CLASS display;
+extern MomentaryButton user_btn;
+#endif
+
+bool radio_init();
+uint32_t radio_get_rng_seed();
+void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
+void radio_set_tx_power(int8_t dbm);
+mesh::LocalIdentity radio_new_identity();

+ 15 - 0
variants/heltec_t096/variant.cpp

@@ -0,0 +1,15 @@
+#include "variant.h"
+#include "wiring_constants.h"
+#include "wiring_digital.h"
+
+const uint32_t g_ADigitalPinMap[] = {
+  0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+  14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+  27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+  40, 41, 42, 43, 44, 45, 46, 47
+};
+
+void initVariant()
+{
+  pinMode(PIN_USER_BTN, INPUT);
+}

+ 132 - 0
variants/heltec_t096/variant.h

@@ -0,0 +1,132 @@
+/*
+ * variant.h
+ * Copyright (C) 2023 Seeed K.K.
+ * MIT License
+ */
+
+#pragma once
+
+#include "WVariant.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// Low frequency clock source
+
+#define USE_LFXO    // 32.768 kHz crystal oscillator
+#define VARIANT_MCK (64000000ul)
+
+#define WIRE_INTERFACES_COUNT 	(2)
+
+////////////////////////////////////////////////////////////////////////////////
+// Power
+
+#define NRF_APM
+#define PIN_3V3_EN              (38)
+
+#define BATTERY_PIN             (3)
+#define ADC_MULTIPLIER          (4.90F)
+
+#define ADC_RESOLUTION          (14)
+#define BATTERY_SENSE_RES       (12)
+
+#define AREF_VOLTAGE            (3.0)
+#define MV_LSB   (3000.0F / 4096.0F) // 12-bit ADC with 3.0V input range
+
+// Power management boot protection threshold (millivolts)
+// Set to 0 to disable boot protection
+#define PWRMGT_VOLTAGE_BOOTLOCK 3300   // Won't boot below this voltage (mV)
+// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
+// AIN1 = P0.03 = BATTERY_PIN / PIN_VBAT_READ
+#define PWRMGT_LPCOMP_AIN    1
+#define PWRMGT_LPCOMP_REFSEL 1  // 2/8 VDD (~3.68-4.04V)
+
+////////////////////////////////////////////////////////////////////////////////
+// Number of pins
+
+#define PINS_COUNT              (48)
+#define NUM_DIGITAL_PINS        (48)
+#define NUM_ANALOG_INPUTS       (1)
+#define NUM_ANALOG_OUTPUTS      (0)
+
+
+// I2C pin definition
+
+#define PIN_WIRE_SDA (0 + 7)
+#define PIN_WIRE_SCL (0 + 8)
+
+// I2C bus 1
+// Available on header pins, for general use
+#define PIN_WIRE1_SDA (0 + 4)
+#define PIN_WIRE1_SCL (0 + 27)
+
+////////////////////////////////////////////////////////////////////////////////
+// Builtin LEDs
+
+#define LED_BUILTIN             (28)
+#define PIN_LED                 LED_BUILTIN
+#define LED_RED                 LED_BUILTIN
+#define LED_BLUE                (-1)            // No blue led, prevents Bluefruit flashing the green LED during advertising
+#define LED_PIN                 LED_BUILTIN
+
+#define LED_STATE_ON            1
+
+// #define PIN_NEOPIXEL            (-1)
+// #define NEOPIXEL_NUM            (2)
+
+////////////////////////////////////////////////////////////////////////////////
+// Builtin buttons
+
+#define PIN_BUTTON1             (32 + 10)
+#define BUTTON_PIN              PIN_BUTTON1
+
+// #define PIN_BUTTON2             (11)
+// #define BUTTON_PIN2             PIN_BUTTON2
+
+#define PIN_USER_BTN            BUTTON_PIN
+
+////////////////////////////////////////////////////////////////////////////////
+// Lora
+
+#define USE_SX1262
+#define LORA_CS                 (0 + 5)
+#define SX126X_DIO1             (0 + 21)
+#define SX126X_BUSY             (0 + 19)
+#define SX126X_RESET            (0 + 16)
+#define SX126X_DIO2_AS_RF_SWITCH
+#define SX126X_DIO3_TCXO_VOLTAGE 1.8
+
+////////////////////////////////////////////////////////////////////////////////
+// SPI pin definition
+
+#define SPI_INTERFACES_COUNT    (2)
+
+#define PIN_SPI_MISO            (0 + 14)
+#define PIN_SPI_MOSI            (0 + 11)
+#define PIN_SPI_SCK             (32 + 8)
+#define PIN_SPI_NSS             LORA_CS
+
+#define PIN_SPI1_MISO           (-1)
+#define PIN_SPI1_MOSI           (0+17)
+#define PIN_SPI1_SCK            (0+20)
+
+////////////////////////////////////////////////////////////////////////////////
+// GPS
+
+#define GPS_EN                  (0 + 6)
+#define GPS_RESET               (32 + 14)
+
+#define PIN_SERIAL1_RX          (0 + 23)
+#define PIN_SERIAL1_TX          (0 + 25)
+
+#define PIN_SERIAL2_RX          (0 + 9)
+#define PIN_SERIAL2_TX          (0 + 10)
+
+////////////////////////////////////////////////////////////////////////////////
+// TFT
+#define PIN_TFT_SCL             (0 + 20)
+#define PIN_TFT_SDA             (0 + 17)
+#define PIN_TFT_RST             (0 + 13)
+// #define PIN_TFT_VDD_CTL         (0 + 26)
+#define PIN_TFT_LEDA_CTL        (32 + 12)
+#define PIN_TFT_LEDA_CTL_ACTIVE LOW
+#define PIN_TFT_CS              (0 + 22)
+#define PIN_TFT_DC              (0 + 15)