Heltec-Tracker: TFT LCD support (#2612)

* Heltec-Tracker: TFT LCD support

* trunk fmt

* backwards compatibility  with ST7735 devices

* trunk fmt
This commit is contained in:
Manuel 2023-07-15 15:53:26 +02:00 committed by GitHub
parent 003047baaf
commit c75965480f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 156 additions and 48 deletions

View File

@ -9,6 +9,7 @@
;default_envs = heltec-v1
;default_envs = heltec-v2_0
;default_envs = heltec-v2_1
;default_envs = heltec-wireless-tracker
;default_envs = tlora-v1
;default_envs = tlora_v1_3
;default_envs = tlora-v2
@ -119,4 +120,4 @@ lib_deps =
adafruit/Adafruit SHT31 Library@^2.2.0
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
adafruit/Adafruit MPU6050@^2.2.4
adafruit/Adafruit LIS3DH@^1.2.4
adafruit/Adafruit LIS3DH@^1.2.4

View File

@ -1,12 +1,112 @@
#include "configuration.h"
#ifndef TFT_BACKLIGHT_ON
#define TFT_BACKLIGHT_ON HIGH
#endif
// convert 24-bit color to 16-bit (56K)
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
#if defined(ST7735S)
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
#if defined(ST7735_BACKLIGHT_EN) && !defined(TFT_BL)
#define TFT_BL ST7735_BACKLIGHT_EN
#endif
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ST7735S _panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
// configure SPI
cfg.spi_host = ST7735_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
cfg.spi_mode = 0;
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
// 80MHz by an integer)
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
cfg.use_lock = true; // Set to true to use transaction locking
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
// SPI_DMA_CH_AUTO=auto setting)
cfg.pin_sclk = ST7735_SCK; // Set SPI SCLK pin number
cfg.pin_mosi = ST7735_SDA; // Set SPI MOSI pin number
cfg.pin_miso = ST7735_MISO; // Set SPI MISO pin number (-1 = disable)
cfg.pin_dc = ST7735_RS; // Set SPI DC pin number (-1 = disable)
_bus_instance.config(cfg); // applies the set value to the bus.
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
}
{ // Set the display panel control.
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
cfg.pin_cs = ST7735_CS; // Pin number where CS is connected (-1 = disable)
cfg.pin_rst = ST7735_RESET; // Pin number where RST is connected (-1 = disable)
cfg.pin_busy = ST7735_BUSY; // Pin number where BUSY is connected (-1 = disable)
// The following setting values are general initial values for each panel, so please comment out any
// unknown items and try them.
cfg.panel_width = TFT_WIDTH; // actual displayable width
cfg.panel_height = TFT_HEIGHT; // actual displayable height
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
cfg.offset_rotation = 0; // Rotation direction value offset 0~7 (4~7 is upside down)
cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
cfg.readable = true; // Set to true if data can be read
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
cfg.dlen_16bit =
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
// ST7735 or ILI9163.
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
_panel_instance.config(cfg);
}
// Set the backlight control
{
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
cfg.invert = true; // true to invert the brightness of the backlight
// cfg.freq = 44100; // PWM frequency of backlight
// cfg.pwm_channel = 1; // PWM channel number to use
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
setPanel(&_panel_instance);
}
};
static LGFX tft;
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER)
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
#endif
#if defined(ST7735_CS) || defined(ILI9341_DRIVER)
#include "SPILock.h"
#include "TFTDisplay.h"
#include <SPI.h>
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
{
@ -26,11 +126,11 @@ void TFTDisplay::display(void)
for (y = 0; y < displayHeight; y++) {
for (x = 0; x < displayWidth; x++) {
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficient
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
auto dblbuf_isset = buffer_back[x + (y / 8) * displayWidth] & (1 << (y & 7));
if (isset != dblbuf_isset) {
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
tft.drawPixel(x, y, isset ? TFT_MESH : TFT_BLACK);
}
}
}
@ -46,8 +146,31 @@ void TFTDisplay::display(void)
// Send a command to the display (low level function)
void TFTDisplay::sendCommand(uint8_t com)
{
(void)com;
// Drop all commands to device (we just update the buffer)
// handle display on/off directly
switch (com) {
case DISPLAYON: {
#ifdef TFT_BL
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
#endif
#ifdef VTFT_CTRL
digitalWrite(VTFT_CTRL, LOW);
#endif
break;
}
case DISPLAYOFF: {
#ifdef TFT_BL
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
#endif
#ifdef VTFT_CTRL
digitalWrite(VTFT_CTRL, HIGH);
#endif
break;
}
default:
break;
}
// Drop all other commands to device (we just update the buffer)
}
void TFTDisplay::setDetected(uint8_t detected)
@ -62,18 +185,10 @@ bool TFTDisplay::connect()
LOG_INFO("Doing TFT init\n");
#ifdef TFT_BL
digitalWrite(TFT_BL, HIGH);
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
pinMode(TFT_BL, OUTPUT);
#endif
#ifdef TFT_POWER_EN
digitalWrite(TFT_POWER_EN, HIGH);
pinMode(TFT_POWER_EN, OUTPUT);
#endif
#ifdef ST7735_BACKLIGHT_EN
digitalWrite(ST7735_BACKLIGHT_EN, HIGH);
pinMode(ST7735_BACKLIGHT_EN, OUTPUT);
#endif
tft.init();
#ifdef M5STACK
tft.setRotation(1); // M5Stack has the TFT in landscape
@ -81,7 +196,6 @@ bool TFTDisplay::connect()
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
#endif
tft.fillScreen(TFT_BLACK);
// tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left
return true;
}

View File

@ -7,7 +7,6 @@
*
* Remaining TODO:
* optimize display() to only draw changed pixels (see other OLED subclasses for examples)
* implement displayOn/displayOff to turn off the TFT device (and backlight)
* Use the fast NRF52 SPI API rather than the slow standard arduino version
*
* turn radio back on - currently with both on spi bus is fucked? or are we leaving chip select asserted?

View File

@ -1,23 +1,12 @@
[env:heltec-wireless-tracker]
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
upload_protocol = esp-builtin
build_flags =
${esp32s3_base.build_flags} -D HELTEC_WIRELESS_TRACKER -I variants/heltec_wireless_tracker
-DUSER_SETUP_LOADED
-DTFT_WIDTH=80
-DTFT_HEIGHT=160
-DST7735_GREENTAB160x80
-DST7735_DRIVER
;-TFT_RGB_ORDER=TFT_BGR
-DTFT_CS=38
-DTFT_DC=40
-DTFT_RST=39
-DTFT_WR=42
-DTFT_SCLK=41
;-DSPI_FREQUENCY=40000000
;-DSPI_FREQUENCY=27000000
;-DSPI_READ_FREQUENCY=16000000
;-DDISABLE_ALL_LIBRARY_WARNINGS
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
${esp32s3_base.lib_deps}
bodmer/TFT_eSPI@^2.4.76
lovyan03/LovyanGFX@^1.1.7

View File

@ -1,18 +1,25 @@
#define LED_PIN 18
#define TFT_POWER_EN 46
#define ST7735_RESET 39 // Output
// ST7735S TFT LCD
#define ST7735S 1 // there are different (sub-)versions of ST7735
#define ST7735_CS 38
#define ST7735_BACKLIGHT_EN 45
#define ST7735_RS 40
#define ST7735_SDA 42
#define ST7735_RS 40 // DC
#define ST7735_SDA 42 // MOSI
#define ST7735_SCK 41
// #define RESET_OLED 21
// #define I2C_SDA 17 // I2C pins for this board
// #define I2C_SCL 18
#define ST7735_RESET 39
#define ST7735_MISO -1
#define ST7735_BUSY -1
#define ST7735_BL 45
#define ST7735_SPI_HOST SPI3_HOST
#define ST7735_BACKLIGHT_EN 45
#define SPI_FREQUENCY 40000000
#define SPI_READ_FREQUENCY 16000000
#define SCREEN_ROTATE
#define TFT_HEIGHT 160
#define TFT_WIDTH 80
#define TFT_OFFSET_X 26
#define TFT_OFFSET_Y 0
#define VTFT_CTRL 46 // Heltec Tracker needs this pulled low for TFT
#define SCREEN_TRANSITION_FRAMERATE 1 // fps
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
@ -31,8 +38,6 @@
#define PIN_GPS_PPS 36
#define VGNSS_CTRL 37 // Heltec Tracker needs this pulled low for GPS
#define VTFT_CTRL 46 // Heltec Tracker needs this pulled low for TFT
#define USE_SX1262
#define LORA_DIO0 -1 // a No connect on the SX1262 module