Add Heltec T114 GPS support and fix T114 FW

This commit is contained in:
jacob.eva 2025-02-24 11:22:44 +00:00
parent 0f29d1b65e
commit 1d79b1e8a9
No known key found for this signature in database
GPG Key ID: 0B92E083BBCCAA1E
6 changed files with 85 additions and 5 deletions

View File

@ -111,6 +111,7 @@
#define BOARD_HELTEC_T114 0x3C #define BOARD_HELTEC_T114 0x3C
#define MODEL_C6 0xC6 // Heltec Mesh Node T114, 470-510 MHz #define MODEL_C6 0xC6 // Heltec Mesh Node T114, 470-510 MHz
#define MODEL_C7 0xC7 // Heltec Mesh Node T114, 863-928 MHz #define MODEL_C7 0xC7 // Heltec Mesh Node T114, 863-928 MHz
#define MODEL_CB 0xCB // Heltec Mesh Node T114, 863-928 MHz + GPS
#define PRODUCT_TECHO 0x15 // LilyGO T-Echo devices #define PRODUCT_TECHO 0x15 // LilyGO T-Echo devices
#define BOARD_TECHO 0x44 #define BOARD_TECHO 0x44
@ -131,7 +132,6 @@
#define EINK_3C 0x03 #define EINK_3C 0x03
#define MONO_OLED 0x04 #define MONO_OLED 0x04
#define TFT 0x05 #define TFT 0x05
#define ADAFRUIT_TFT 0x06
#if defined(ESP32) #if defined(ESP32)
#define PLATFORM PLATFORM_ESP32 #define PLATFORM PLATFORM_ESP32
@ -850,6 +850,7 @@
#elif BOARD_MODEL == BOARD_TDECK #elif BOARD_MODEL == BOARD_TDECK
#define IS_ESP32S3 true #define IS_ESP32S3 true
#define HAS_DISPLAY false #define HAS_DISPLAY false
#define DISPLAY TFT // to be tested...
#define HAS_CONSOLE false #define HAS_CONSOLE false
#define HAS_BLUETOOTH false #define HAS_BLUETOOTH false
#define HAS_BLE true #define HAS_BLE true
@ -1239,7 +1240,6 @@
#define HAS_BUSY true #define HAS_BUSY true
#define HAS_INPUT true #define HAS_INPUT true
#define HAS_SLEEP true #define HAS_SLEEP true
#define DIO2_AS_RF_SWITCH true
#define CONFIG_UART_BUFFER_SIZE 6144 #define CONFIG_UART_BUFFER_SIZE 6144
#define CONFIG_QUEUE_SIZE 6144 #define CONFIG_QUEUE_SIZE 6144
#define CONFIG_QUEUE_MAX_LENGTH 200 #define CONFIG_QUEUE_MAX_LENGTH 200
@ -1270,7 +1270,7 @@
// pins for ST7789 display on Heltec T114 // pins for ST7789 display on Heltec T114
const int DISPLAY_DC = 12; const int DISPLAY_DC = 12;
const int DISPLAY_CS = 11; const int DISPLAY_CS = 11;
const int DISPLAY_MISO = 11; const int DISPLAY_MISO = 11; // not connected
const int DISPLAY_MOSI = 9; const int DISPLAY_MOSI = 9;
const int DISPLAY_CLK = 8; const int DISPLAY_CLK = 8;
const int DISPLAY_BL_PIN = PIN_T114_TFT_BLGT; const int DISPLAY_BL_PIN = PIN_T114_TFT_BLGT;
@ -1302,6 +1302,13 @@
-1 // pin_tcxo_enable -1 // pin_tcxo_enable
} }
}; };
#if BOARD_VARIANT == MODEL_CB
#define HAS_GPS true
#define GPS_BAUD_RATE 9600
#define PIN_GPS_RX 37
#define PIN_GPS_TX 39
#endif
#else #else
#error An unsupported nRF board was selected. Cannot compile RNode firmware. #error An unsupported nRF board was selected. Cannot compile RNode firmware.
#endif #endif

View File

@ -106,6 +106,11 @@
#define ERROR_MEMORY_LOW 0x05 #define ERROR_MEMORY_LOW 0x05
#define ERROR_MODEM_TIMEOUT 0x06 #define ERROR_MODEM_TIMEOUT 0x06
#define CMD_GPS 0xA0
#define GPS_CMD_LAT 0x00
#define GPS_CMD_LNG 0x01
// Serial logging // Serial logging
#define LOG_MSG 0x2F #define LOG_MSG 0x2F

View File

@ -54,6 +54,7 @@ prep-nrf:
arduino-cli lib install "Crypto" arduino-cli lib install "Crypto"
arduino-cli lib install "Adafruit GFX Library" arduino-cli lib install "Adafruit GFX Library"
arduino-cli lib install "GxEPD2" arduino-cli lib install "GxEPD2"
arduino-cli lib install "TinyGPSPlus"
arduino-cli config set library.enable_unsafe_install true arduino-cli config set library.enable_unsafe_install true
arduino-cli lib install --git-url https://github.com/liamcottle/esp8266-oled-ssd1306#e16cee124fe26490cb14880c679321ad8ac89c95 arduino-cli lib install --git-url https://github.com/liamcottle/esp8266-oled-ssd1306#e16cee124fe26490cb14880c679321ad8ac89c95
pip install pyserial rns --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error. pip install pyserial rns --upgrade --user --break-system-packages # This looks scary, but it's actually just telling pip to install packages as a user instead of trying to install them systemwide, which bypasses the "externally managed environment" error.
@ -151,6 +152,9 @@ firmware-opencom-xl:
firmware-heltec_t114: firmware-heltec_t114:
arduino-cli compile --log --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\"" arduino-cli compile --log --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\""
firmware-heltec_t114_gps:
arduino-cli compile --log --fqbn Heltec_nRF52:Heltec_nRF52:HT-n5262 -e --build-property "build.partitions=no_ota" --build-property "upload.maximum_size=2097152" --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x3C\" \"-DBOARD_VARIANT=0xCB\""
upload-tbeam: upload-tbeam:
arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:t-beam arduino-cli upload -p $(or $(port), /dev/ttyACM0) --fqbn esp32:esp32:t-beam
@sleep 1 @sleep 1

View File

@ -46,7 +46,7 @@
SPIClass interface_spi[1] = { SPIClass interface_spi[1] = {
// SX1262 // SX1262
SPIClass( SPIClass(
NRF_SPIM3, NRF_SPIM1,
interface_pins[0][3], interface_pins[0][3],
interface_pins[0][1], interface_pins[0][1],
interface_pins[0][2] interface_pins[0][2]
@ -132,8 +132,14 @@ void setup() {
pinMode(PIN_LED_GREEN, OUTPUT); pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_LED_BLUE, OUTPUT); pinMode(PIN_LED_BLUE, OUTPUT);
delay(200); delay(200);
#elif BOARD_MODEL == BOARD_HELTEC_T114
delay(200);
pinMode(PIN_VEXT_EN, OUTPUT);
digitalWrite(PIN_VEXT_EN, HIGH);
delay(100);
#endif #endif
if (!eeprom_begin()) { Serial.write("EEPROM initialisation failed.\r\n"); } if (!eeprom_begin()) { Serial.write("EEPROM initialisation failed.\r\n"); }
#endif #endif
@ -208,6 +214,11 @@ void setup() {
fifo_init(&packet_rdy_interfaces, packet_rdy_interfaces_buf, MAX_INTERFACES); fifo_init(&packet_rdy_interfaces, packet_rdy_interfaces_buf, MAX_INTERFACES);
#if HAS_GPS
// init GPS
gps_s.begin(GPS_BAUD_RATE);
#endif
// add call to init_channel_stats here? \todo // add call to init_channel_stats here? \todo
// Create and configure interface objects // Create and configure interface objects
@ -1545,7 +1556,7 @@ void loop() {
process_serial(); process_serial();
#if HAS_DISPLAY #if HAS_DISPLAY
#if DISPLAY == OLED #if DISPLAY == OLED || DISPLAY == TFT || DISPLAY == ADAFRUIT_TFT
if (disp_ready) update_display(); if (disp_ready) update_display();
#elif DISPLAY == EINK_BW || DISPLAY == EINK_3C #elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
// Display refreshes take so long on e-paper displays that they can disrupt // Display refreshes take so long on e-paper displays that they can disrupt
@ -1577,6 +1588,20 @@ void loop() {
input_read(); input_read();
#endif #endif
#if HAS_GPS
while (gps_s.available() > 0) {
if (gps.encode(gps_s.read()) && millis() - last_gps >= GPS_INTERVAL) {
kiss_indicate_location();
last_gps = millis();
}
}
if (millis() > 5000 && gps.charsProcessed() < 10) {
while (true) {
Serial.println(F("No GPS detected: check wiring."));
}
}
#endif
if (memory_low) { if (memory_low) {
#if PLATFORM == PLATFORM_ESP32 #if PLATFORM == PLATFORM_ESP32
if (esp_get_free_heap_size() < 8192) { if (esp_get_free_heap_size() < 8192) {

View File

@ -61,6 +61,10 @@ uint8_t eeprom_read(uint32_t mapped_addr);
#include "Input.h" #include "Input.h"
#endif #endif
#if HAS_GPS
#include "src/misc/gps.h"
#endif
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52 #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
#include "Device.h" #include "Device.h"
#endif #endif
@ -1712,6 +1716,33 @@ void unlock_rom() {
eeprom_erase(); eeprom_erase();
} }
void kiss_indicate_location() {
char location[10];
int len;
int32_t val;
if (gps.location.isValid()) {
serial_write(FEND);
serial_write(CMD_GPS);
serial_write(GPS_CMD_LAT);
val = gps.location.lat() * 1000000;
escaped_serial_write(val>>24);
escaped_serial_write(val>>16);
escaped_serial_write(val>>8);
escaped_serial_write(val);
serial_write(FEND);
serial_write(FEND);
serial_write(CMD_GPS);
serial_write(GPS_CMD_LNG);
val = gps.location.lng() * 1000000;
escaped_serial_write(val>>24);
escaped_serial_write(val>>16);
escaped_serial_write(val>>8);
escaped_serial_write(val);
serial_write(FEND);
}
}
void log_debug(const char* msg) { void log_debug(const char* msg) {
serial_write(FEND); serial_write(FEND);
serial_write(LOG_MSG); serial_write(LOG_MSG);

8
src/misc/gps.h Normal file
View File

@ -0,0 +1,8 @@
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#define GPS_INTERVAL 5000 // ms
unsigned long last_gps = 0;
TinyGPSPlus gps;
SoftwareSerial gps_s(PIN_GPS_RX, PIN_GPS_TX);