From 038ae7e1110dbbdc43edbf6fd9253b30e7bf122a Mon Sep 17 00:00:00 2001 From: taco Date: Sat, 28 Mar 2026 11:01:46 +1100 Subject: [PATCH] board support: add Heltec T096 --- src/boards/boards.c | 144 +++++++++++++++++++++++++++++ src/boards/heltec_t096/board.cmake | 1 + src/boards/heltec_t096/board.h | 123 ++++++++++++++++++++++++ src/boards/heltec_t096/board.mk | 3 + src/boards/heltec_t096/pinconfig.c | 19 ++++ 5 files changed, 290 insertions(+) create mode 100644 src/boards/heltec_t096/board.cmake create mode 100644 src/boards/heltec_t096/board.h create mode 100644 src/boards/heltec_t096/board.mk create mode 100644 src/boards/heltec_t096/pinconfig.c diff --git a/src/boards/boards.c b/src/boards/boards.c index 9eaf7b0..90d592a 100644 --- a/src/boards/boards.c +++ b/src/boards/boards.c @@ -777,3 +777,147 @@ static void tft_controller_init(void) { } #endif + +#ifdef DISPLAY_CONTROLLER_ST7735 + +#define ST_CMD_DELAY 0x80 // special signifier for command lists + +// ST77XX common commands (shared with ST7789) +#define ST77XX_NOP 0x00 +#define ST77XX_SWRESET 0x01 +#define ST77XX_RDDID 0x04 +#define ST77XX_RDDST 0x09 + +#define ST77XX_SLPIN 0x10 +#define ST77XX_SLPOUT 0x11 +#define ST77XX_PTLON 0x12 +#define ST77XX_NORON 0x13 + +#define ST77XX_INVOFF 0x20 +#define ST77XX_INVON 0x21 +#define ST77XX_DISPOFF 0x28 +#define ST77XX_DISPON 0x29 +#define ST77XX_CASET 0x2A +#define ST77XX_RASET 0x2B +#define ST77XX_RAMWR 0x2C +#define ST77XX_RAMRD 0x2E + +#define ST77XX_PTLAR 0x30 +#define ST77XX_TEOFF 0x34 +#define ST77XX_TEON 0x35 +#define ST77XX_MADCTL 0x36 +#define ST77XX_VSCSAD 0x37 +#define ST77XX_COLMOD 0x3A + +#define ST77XX_MADCTL_MY 0x80 +#define ST77XX_MADCTL_MX 0x40 +#define ST77XX_MADCTL_MV 0x20 +#define ST77XX_MADCTL_ML 0x10 +#define ST77XX_MADCTL_RGB 0x00 + +#define ST77XX_RDID1 0xDA +#define ST77XX_RDID2 0xDB +#define ST77XX_RDID3 0xDC +#define ST77XX_RDID4 0xDD + +// ST7735-specific commands +#define ST7735_FRMCTR1 0xB1 +#define ST7735_FRMCTR2 0xB2 +#define ST7735_FRMCTR3 0xB3 +#define ST7735_INVCTR 0xB4 +#define ST7735_PWCTR1 0xC0 +#define ST7735_PWCTR2 0xC1 +#define ST7735_PWCTR3 0xC2 +#define ST7735_PWCTR4 0xC3 +#define ST7735_PWCTR5 0xC4 +#define ST7735_VMCTR1 0xC5 +#define ST7735_GMCTRP1 0xE0 +#define ST7735_GMCTRN1 0xE1 +#define ST7735_MADCTL_BGR 0x08 + +// Some ready-made 16-bit ('565') color settings: +#define ST77XX_BLACK 0x0000 +#define ST77XX_WHITE 0xFFFF +#define ST77XX_RED 0xF800 +#define ST77XX_GREEN 0x07E0 +#define ST77XX_BLUE 0x001F +#define ST77XX_CYAN 0x07FF +#define ST77XX_MAGENTA 0xF81F +#define ST77XX_YELLOW 0xFFE0 +#define ST77XX_ORANGE 0xFC00 + +static void tft_controller_init(void) { + // Init commands for ST7735 mini 160x80 screens + // Based on Adafruit INITR_MINI160x80 sequence + uint8_t cmdinit_st7735[] = { + #if !defined(DISPLAY_PIN_RST) || (DISPLAY_PIN_RST < 0) + // Software reset if rst pin not available + ST77XX_SWRESET, ST_CMD_DELAY, 150, + #endif + // Out of sleep mode, w/delay 255 = 500ms + ST77XX_SLPOUT, ST_CMD_DELAY, 255, + // Frame rate control - normal mode (3 args) + ST7735_FRMCTR1, 3, 0x01, 0x2C, 0x2D, + // Frame rate control - idle mode (3 args) + ST7735_FRMCTR2, 3, 0x01, 0x2C, 0x2D, + // Frame rate control - partial mode (6 args) + ST7735_FRMCTR3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, + // Display inversion control (1 arg) + ST7735_INVCTR, 1, 0x07, + // Power control 1 (3 args) + ST7735_PWCTR1, 3, 0xA2, 0x02, 0x84, + // Power control 2 (1 arg) + ST7735_PWCTR2, 1, 0xC5, + // Power control 3 - normal mode (2 args) + ST7735_PWCTR3, 2, 0x0A, 0x00, + // Power control 4 - idle mode (2 args) + ST7735_PWCTR4, 2, 0x8A, 0x2A, + // Power control 5 - partial mode (2 args) + ST7735_PWCTR5, 2, 0x8A, 0xEE, + // VCOM control (1 arg) + ST7735_VMCTR1, 1, 0x0E, + // Inversion off (required for Heltec T096) + ST77XX_INVOFF, 0, + // Set color mode, 1 arg: 16-bit color (0x05 for ST7735) + ST77XX_COLMOD, 1 + ST_CMD_DELAY, 0x05, 10, + // Mem access ctrl, 1 arg: row/col addr, color order + ST77XX_MADCTL, 1, DISPLAY_MADCTL, + // Column addr set, 4 args: XSTART/XEND (132 wide framebuffer) + ST77XX_CASET, 4, 0x00, 0x00, 0x00, 0x83, + // Row addr set, 4 args: YSTART/YEND (162 tall framebuffer) + ST77XX_RASET, 4, 0x00, 0x00, 0x00, 0xA1, + // Positive gamma correction (16 args) + ST7735_GMCTRP1, 16, + 0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D, + 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, + // Negative gamma correction (16 args) + ST7735_GMCTRN1, 16, + 0x03, 0x1D, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, + 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, + // Normal display on, w/delay 10ms + ST77XX_NORON, ST_CMD_DELAY, 10, + // Main screen turn on, w/delay 100ms + ST77XX_DISPON, ST_CMD_DELAY, 100 + }; + + size_t count = 0; + while (count < sizeof(cmdinit_st7735)) { + uint8_t const cmd = cmdinit_st7735[count++]; + uint8_t const cmd_arg = cmdinit_st7735[count++]; + uint8_t const has_delay = cmd_arg & ST_CMD_DELAY; + uint8_t const narg = cmd_arg & ~ST_CMD_DELAY; + + tft_cmd(cmd, cmdinit_st7735 + count, narg); + count += narg; + + if (has_delay) { + uint16_t delay = (uint16_t) cmdinit_st7735[count++]; + if (delay == 255) { + delay = 500; // If 255, delay for 500 ms + } + NRFX_DELAY_MS(delay); + } + } +} + +#endif \ No newline at end of file diff --git a/src/boards/heltec_t096/board.cmake b/src/boards/heltec_t096/board.cmake new file mode 100644 index 0000000..25daf71 --- /dev/null +++ b/src/boards/heltec_t096/board.cmake @@ -0,0 +1 @@ +set(MCU_VARIANT nrf52840) diff --git a/src/boards/heltec_t096/board.h b/src/boards/heltec_t096/board.h new file mode 100644 index 0000000..60abab1 --- /dev/null +++ b/src/boards/heltec_t096/board.h @@ -0,0 +1,123 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Ha Thach for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _HELTEC_T096_H +#define _HELTEC_T096_H + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +/*------------------------------------------------------------------*/ +/* LED + *------------------------------------------------------------------*/ +#define LEDS_NUMBER 1 +#define LED_PRIMARY_PIN _PINNUM(0, 28) // White +#define LED_STATE_ON 0 + +// #define LED_NEOPIXEL _PINNUM(0, 14) +// #define NEOPIXEL_POWER_PIN _PINNUM(0, 21) +// #define NEOPIXELS_NUMBER 2 +#define BOARD_RGB_BRIGHTNESS 0x040404 + +/*------------------------------------------------------------------*/ +/* BUTTON + *------------------------------------------------------------------*/ +#define BUTTONS_NUMBER 2 +#define BUTTON_1 _PINNUM(1, 10) +#define BUTTON_2 _PINNUM(1, 2) // stock bootloader has this set to 34 +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +//--------------------------------------------------------------------+ +// Display +//--------------------------------------------------------------------+ + +// VSensor required to power the display +#define DISPLAY_VSENSOR_PIN _PINNUM(0, 26) +#define DISPLAY_VSENSOR_ON 1 + +// #define DISPLAY_CONTROLLER_ST7789 +#define DISPLAY_CONTROLLER_ST7735 + +#define DISPLAY_PIN_SCK _PINNUM(0, 20) +#define DISPLAY_PIN_MOSI _PINNUM(0, 17) + +#define DISPLAY_PIN_CS _PINNUM(0, 22) +#define DISPLAY_PIN_DC _PINNUM(0, 15) +#define DISPLAY_PIN_RST _PINNUM(0, 13) +#define DISPLAY_PIN_BL _PINNUM(1, 12) +#define DISPLAY_BL_ON 0 // GPIO state to enable back light + +#define DISPLAY_WIDTH 160 +#define DISPLAY_HEIGHT 80 + +// USB FACING LEFT +#define DISPLAY_COL_OFFSET 24 +#define DISPLAY_ROW_OFFSET 0 +#define DISPLAY_MADCTL (TFT_MADCTL_MY | TFT_MADCTL_BGR) + +// USB FACING RIGHT +//#define DISPLAY_COL_OFFSET 52 +//#define DISPLAY_ROW_OFFSET 40 +//#define DISPLAY_MADCTL (TFT_MADCTL_MY | TFT_MADCTL_RGB) + +#define DISPLAY_VSCSAD 0 + +#define DISPLAY_TITLE "T096" +#define BANNER_TEXT "https://github.com/oltaco" +#define FONT_SIZE_LARGE 3 +#define NOLABELS + +#define SCREEN_BAR1_Y 0 +#define SCREEN_BAR1_H 32 +#define SCREEN_BAR2_Y 32 +#define SCREEN_BAR2_H 36 +#define SCREEN_BAR3_Y 68 +#define SCREEN_BAR3_H 12 +#define BANNER_TEXT_X 0 +#define BANNER_TEXT_Y 70 +#define DISPLAY_TITLE_Y 1 +#define UF2_VERSION_BASE_Y 24 +#define BLE_OTA_Y 38 +#define DRAG 34 +#define DRAGX 4 + +//--------------------------------------------------------------------+ +// BLE OTA +//--------------------------------------------------------------------+ +#define BLEDIS_MANUFACTURER "Heltec AutoMation" +#define BLEDIS_MODEL "Tracker" + +//--------------------------------------------------------------------+ +// USB +//--------------------------------------------------------------------+ +#define USB_DESC_VID 0x239A +#define USB_DESC_UF2_PID 0x0071 +#define USB_DESC_CDC_ONLY_PID 0x0071 + +//------------- UF2 -------------// +#define UF2_PRODUCT_NAME "Heltec-T096" +#define UF2_VOLUME_LABEL "HeltecT096" +#define UF2_BOARD_ID "Heltec-T096-v1" +#define UF2_INDEX_URL "http://heltec.org/" + +#endif diff --git a/src/boards/heltec_t096/board.mk b/src/boards/heltec_t096/board.mk new file mode 100644 index 0000000..e89d22d --- /dev/null +++ b/src/boards/heltec_t096/board.mk @@ -0,0 +1,3 @@ +MCU_SUB_VARIANT = nrf52840 +CFLAGS += -DDEVICE_NAME='"T096_DFU"' + diff --git a/src/boards/heltec_t096/pinconfig.c b/src/boards/heltec_t096/pinconfig.c new file mode 100644 index 0000000..a983e4a --- /dev/null +++ b/src/boards/heltec_t096/pinconfig.c @@ -0,0 +1,19 @@ +#include "boards.h" +#include "uf2/configkeys.h" + +__attribute__((used, section(".bootloaderConfig"))) +const uint32_t bootloaderConfig[] = +{ + /* CF2 START */ + CFG_MAGIC0, CFG_MAGIC1, // magic + 5, 100, // used entries, total entries + + 204, 0x100000, // FLASH_BYTES = 0x100000 + 205, 0x40000, // RAM_BYTES = 0x40000 + 208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2 + 209, 0xada52840, // UF2_FAMILY = 0xada52840 + 210, 0x20, // PINS_PORT_SIZE = PA_32 + + 0, 0, 0, 0, 0, 0, 0, 0 + /* CF2 END */ +};