From a7ff39352cbacbbc5826d344dab51b5edf5adec9 Mon Sep 17 00:00:00 2001 From: Matthew Burton <19491784+matthew73210@users.noreply.github.com> Date: Mon, 29 Jun 2026 18:39:09 +0200 Subject: [PATCH] added screen build --- .../boards/nrf52840/heltec_t096/README.md | 34 +++++-- .../boards/nrf52840/heltec_t096/board.conf | 11 ++- .../heltec_t096_nrf52840-pinctrl.dtsi | 16 ++++ .../heltec_t096/heltec_t096_nrf52840.dts | 92 +++++++++++++++++++ zephcore/boards/supported_boards.md | 2 +- 5 files changed, 145 insertions(+), 10 deletions(-) diff --git a/zephcore/boards/nrf52840/heltec_t096/README.md b/zephcore/boards/nrf52840/heltec_t096/README.md index 2168b4c..c21eff2 100644 --- a/zephcore/boards/nrf52840/heltec_t096/README.md +++ b/zephcore/boards/nrf52840/heltec_t096/README.md @@ -14,10 +14,11 @@ west build -b heltec_t096 zephcore --pristine - Radio: SX1262 - RF front-end: KCT8103L PA/FEM, official maximum LoRa output power up to 28+/-1 dBm - GNSS: UC6580 +- Display: ST7735S 0.96" TFT, 160x80 pixels ## Confirmed Pinout -Sources: MeshCore `variants/heltec_t096` for comparison, verified against the official Heltec `Mesh_Node_T096_V0.2` schematic. +Sources: official Heltec Mesh Node T096 datasheet/schematic, with MeshCore `variants/heltec_t096` and Zephyr's Heltec Wireless Tracker ST7735 160x80 node used as implementation references. | Function | nRF52840 pin | Schematic net | ZephCore mapping | | --- | --- | --- | --- | @@ -37,14 +38,29 @@ Sources: MeshCore `variants/heltec_t096` for comparison, verified against the of | GNSS reset | P1.14 | GNSS_RST | `gps-reset` alias | | GNSS power | P0.06 | VGNSS_CTRL | fixed regulator `gps_power` | | GNSS PPS | P1.11 | PPS | documented, not consumed | +| Display SCK | P0.20 | SCLK | `spi3` SCK | +| Display MOSI | P0.17 | SDIN | `spi3` MOSI | +| Display CS | P0.22 | CS | `spi3` `cs-gpios` | +| Display DC | P0.15 | RS | MIPI-DBI `dc-gpios` | +| Display reset | P0.13 | RESET | MIPI-DBI `reset-gpios` | +| Display backlight | P1.12 | LEDA | `disp_pwr_enable`, active-low | +| Display/peripheral rail | P0.26 | Vext_Ctrl | `tft_pwr_enable`, active-high | | LED | P0.28 | LED | `led0`, `lora-tx-led` | | Button | P1.10 | Button | `sw0` | | Battery ADC | P0.03 / AIN1 | ADC_IN | ADC channel 1 | | Battery ADC enable | P1.15 | ADC_Ctrl | fixed regulator `vbat_enable` | +## Display + +- Controller: ST7735S, modeled with Zephyr's `sitronix,st7735r` ST7735R/ST7735S driver. +- Resolution: 160x80 pixels. +- Bus: SPI3 through Zephyr MIPI-DBI, write-only. +- Orientation/init: ST7735 mini 160x80 parameters from Zephyr's Heltec Wireless Tracker node, with `madctl = 0xa8` matching MeshCore's T096 `DISPLAY_ROTATION=1` plus BGR override. +- UI path: `zephcore,mono-tft` wraps the color TFT as a 1bpp display for ZephCore's CFB companion UI. +- Power: `Vext_Ctrl` is boot-enabled so the ST7735 init sequence reaches a powered panel; `LEDA` follows ZephCore display on/off as the backlight control. + ## Not Enabled -- Display: the schematic confirms FFC nets (`LEDA`, `RESET`, `RS`, `SDIN`, `SCLK`, `CS`) but not a controller node in this board port. - External flash: the schematic shows `F_SPI_*` nets and a flash footprint, but the flash device and parameters are not confirmed. ## T096 vs T114 Differences @@ -53,6 +69,7 @@ Sources: MeshCore `variants/heltec_t096` for comparison, verified against the of - T096 adds a KCT8103L PA/FEM path with `PA_CSD`, `PA_CTX`, `PA_CPS`, and `VFEM_Ctrl`; T114 uses SX1262 DIO2 RF switch without those MCU PA/FEM GPIOs. - T096 GNSS is UC6580 at 115200 baud with `VGNSS_CTRL`, `GNSS_RST`, and `PPS`; T114 uses ATGM336H-style wiring at 9600 baud. - T096 battery ADC is P0.03/AIN1 with enable P1.15; T114 battery ADC is P0.04/AIN2 with enable P0.06. +- T096 display is an ST7735S 160x80 panel on P0.20/P0.17 SPI3 with P0.26 rail enable and P1.12 active-low backlight; T114 display is an ST7789V 240x135 panel with different pins and power polarity. - T096 LED is P0.28 active-high; T114 LED is P1.03 active-low. - T096 button is P1.10, matching T114's user button pin. @@ -62,9 +79,10 @@ Sources: MeshCore `variants/heltec_t096` for comparison, verified against the of 2. Confirm USB CDC/logging appears. 3. Confirm BLE advertises as ZephCore/MeshCore companion. 4. Confirm MeshCore app pairing works. -5. Confirm SX1262 init succeeds with no reset, busy, or DIO1 errors. -6. Confirm RX starts. -7. Test low-power TX first. -8. Confirm PA/FEM control before testing higher TX power. -9. Test PA progressively. -10. Confirm GNSS only after radio and BLE are stable. +5. Confirm the display wakes, shows the normal ZephCore companion status/pairing UI, and blanks/backlights off after the configured timeout. +6. Confirm SX1262 init succeeds with no reset, busy, or DIO1 errors. +7. Confirm RX starts. +8. Test low-power TX first. +9. Confirm PA/FEM control before testing higher TX power. +10. Test PA progressively. +11. Confirm GNSS only after radio and BLE are stable. diff --git a/zephcore/boards/nrf52840/heltec_t096/board.conf b/zephcore/boards/nrf52840/heltec_t096/board.conf index 44bfc40..9f70dd5 100644 --- a/zephcore/boards/nrf52840/heltec_t096/board.conf +++ b/zephcore/boards/nrf52840/heltec_t096/board.conf @@ -8,7 +8,7 @@ # - I2C0 header bus (SDA=P0.07, SCL=P0.08) # - LED: P0.28 (active-HIGH) # - Button: P1.10 (active-LOW) -# - Display connector present but no controller enabled here +# - ST7735S 0.96" 160x80 TFT (SPI3, MIPI-DBI, mono-tft wrapper) # - External SPI flash footprint present but device is not identified/enabled # Board identification (matches Arduino MeshCore variant name) @@ -26,3 +26,12 @@ CONFIG_ZEPHCORE_DEFAULT_TX_POWER_DBM=9 # Same KCT8103L-class Heltec PA path as the V4.3 boards. CONFIG_ZEPHCORE_SX126X_HELTEC_REG_PATCH=y + +# ========== RAM budget ========== +# CFB mono-tft framebuffer = 160x80/8 = 1600 bytes, allocated from k_malloc. +# Default heap (2048) is sized tightly for SSD1306 128x64 (1024 bytes). +CONFIG_HEAP_MEM_POOL_SIZE=4096 + +# Single-button board with longpress filter: a "double long-press" is +# physically slower than 500 ms, so widen the confirmation window. +CONFIG_ZEPHCORE_UI_CONFIRM_WINDOW_MS=3000 diff --git a/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840-pinctrl.dtsi b/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840-pinctrl.dtsi index e175fee..530c598 100644 --- a/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840-pinctrl.dtsi +++ b/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840-pinctrl.dtsi @@ -10,6 +10,7 @@ * * Confirmed T096 mappings: * - SPI2 (SX1262 LoRa): SCK=P1.08, MOSI=P0.11, MISO=P0.14 + * - SPI3 (ST7735S display): SCK=P0.20, MOSI=P0.17 * - I2C0: SDA=P0.07, SCL=P0.08 * - UART0 (UC6580 GNSS): TX=P0.25 -> GNSS_RX, RX=P0.23 <- GNSS_TX */ @@ -32,6 +33,21 @@ }; }; + spi3_default: spi3_default { + group1 { + psels = , + ; + }; + }; + + spi3_sleep: spi3_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + i2c0_default: i2c0_default { group1 { psels = , diff --git a/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts b/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts index 6266059..730a5e8 100644 --- a/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts +++ b/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts @@ -27,6 +27,7 @@ zephyr,code-partition = &code_partition; zephyr,console = &cdc_acm_uart; zephyr,shell-uart = &cdc_acm_uart; + zephyr,display = &mono_tft; zephcore,gps-power = &gps_power; }; @@ -37,6 +38,7 @@ lora0 = &lora; watchdog0 = &wdt0; gps-reset = &gps_reset_pin; + display0 = &tft; }; leds { @@ -113,6 +115,86 @@ enable-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; }; + /* + * Schematic net Vext_Ctrl: P0.26 enables the switched peripheral rail + * that MeshCore's T096 variant claims before ST7735 display init. + */ + tft_pwr_enable: tft-pwr-enable { + compatible = "regulator-fixed"; + regulator-name = "tft-pwr-enable"; + enable-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + startup-delay-us = <10000>; + }; + + /* + * Schematic/datasheet display LED net LEDA: P1.12. MeshCore defines + * PIN_TFT_LEDA_CTL_ACTIVE=LOW for the T096 backlight control. + */ + disp_pwr_enable: disp-pwr-enable { + compatible = "regulator-fixed"; + regulator-name = "disp-pwr-enable"; + enable-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + }; + + /* + * Monochrome wrapper around the ST7735S-compatible TFT. + * Reports PIXEL_FORMAT_MONO01 to CFB and converts rows to RGB565. + */ + mono_tft: mono-tft { + compatible = "zephcore,mono-tft"; + tft-dev = <&tft>; + width = <160>; + height = <80>; + }; + + /* + * MIPI-DBI SPI bus for the ST7735S 0.96" 160x80 TFT. + * T096 schematic nets: + * - RS -> P0.15, data/command + * - RESET -> P0.13, active-LOW reset + * - SDIN -> P0.17, SPI MOSI + * - SCLK -> P0.20, SPI SCK + * - CS -> P0.22, SPI chip-select + */ + mipi_dbi { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&spi3>; + dc-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + write-only; + #address-cells = <1>; + #size-cells = <0>; + + tft: st7735s@0 { + compatible = "sitronix,st7735r"; + mipi-max-frequency = <20000000>; + mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; + reg = <0>; + width = <160>; + height = <80>; + inversion-on; + x-offset = <1>; + y-offset = <26>; + madctl = <0xa8>; + colmod = <0x05>; + invctr = <7>; + vmctr1 = <0x0e>; + pwctr1 = [a2 02 84]; + pwctr2 = [c1]; + pwctr3 = [0a 00]; + pwctr4 = [8a 2a]; + pwctr5 = [8a ee]; + frmctr1 = [01 26 2e]; + frmctr2 = [01 26 2e]; + frmctr3 = [01 26 2e 01 26 2e]; + gamctrp1 = [0f 1a 0f 18 2f 28 20 22 1f 1b 23 37 00 07 02 10]; + gamctrn1 = [0f 1b 0f 17 33 2c 29 2e 30 2e 30 3b 00 07 03 10]; + caset = [00 01 00 a0]; + raset = [00 1a 00 69]; + }; + }; + zephyr,user { io-channels = <&adc 1>; /* @@ -183,6 +265,16 @@ }; }; +/* SPI3 - ST7735S 0.96" 160x80 TFT display */ +&spi3 { + compatible = "nordic,nrf-spim"; + status = "okay"; + pinctrl-0 = <&spi3_default>; + pinctrl-1 = <&spi3_sleep>; + pinctrl-names = "default", "sleep"; + cs-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; /* Schematic net CS */ +}; + /* SPI2 - SX1262 LoRa radio */ &spi2 { compatible = "nordic,nrf-spim"; diff --git a/zephcore/boards/supported_boards.md b/zephcore/boards/supported_boards.md index 592276e..53931ce 100644 --- a/zephcore/boards/supported_boards.md +++ b/zephcore/boards/supported_boards.md @@ -27,7 +27,7 @@ gat562_30s > > **Heltec T114** screenless build: append `boards/nrf52840/heltec_t114/no_display.conf` to `EXTRA_CONF_FILE` for units without the TFT module. > -> **Heltec Mesh Node T096** (`heltec_t096`): nRF52840 with SX1262 + KCT8103L PA/FEM and UC6580 GNSS. The display connector and external SPI flash footprint are documented in the board notes but left disabled until the controller/device parameters are hardware-confirmed. +> **Heltec Mesh Node T096** (`heltec_t096`): nRF52840 with SX1262 + KCT8103L PA/FEM, UC6580 GNSS, and ST7735S 160x80 TFT companion display. The external SPI flash footprint is documented in the board notes but left disabled until the device parameters are confirmed. ## ESP32