add support for heltec t114

This commit is contained in:
liamcottle 2024-12-22 04:36:24 +13:00
parent 6c82de161c
commit f9234733e2
8 changed files with 237 additions and 25 deletions

136
Display.h
View file

@ -18,6 +18,9 @@
#if BOARD_MODEL == BOARD_TDECK
#include <Adafruit_ST7789.h>
#elif BOARD_MODEL == BOARD_HELTEC_T114
#include "ST7789Spi.h"
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
#include <Adafruit_SH110X.h>
#else
@ -77,6 +80,10 @@
Adafruit_ST7789 display = Adafruit_ST7789(DISPLAY_CS, DISPLAY_DC, -1);
#define SSD1306_WHITE ST77XX_WHITE
#define SSD1306_BLACK ST77XX_BLACK
#elif BOARD_MODEL == BOARD_HELTEC_T114
ST7789Spi display(&SPI1, DISPLAY_RST, DISPLAY_DC, DISPLAY_CS);
#define SSD1306_WHITE ST77XX_WHITE
#define SSD1306_BLACK ST77XX_BLACK
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, &Wire, -1);
#define SSD1306_WHITE SH110X_WHITE
@ -121,15 +128,15 @@ GFXcanvas1 disp_area(64, 64);
void update_area_positions() {
if (disp_mode == DISP_MODE_PORTRAIT) {
p_ad_x = 0;
p_ad_y = 0;
p_as_x = 0;
p_as_y = 64;
p_ad_x = 0 * DISPLAY_SCALE;
p_ad_y = 0 * DISPLAY_SCALE;
p_as_x = 0 * DISPLAY_SCALE;
p_as_y = 64 * DISPLAY_SCALE;
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
p_ad_x = 0;
p_ad_y = 0;
p_as_x = 64;
p_as_y = 0;
p_ad_x = 0 * DISPLAY_SCALE;
p_ad_y = 0 * DISPLAY_SCALE;
p_as_x = 64 * DISPLAY_SCALE;
p_as_y = 0 * DISPLAY_SCALE;
}
}
@ -137,6 +144,9 @@ uint8_t display_contrast = 0x00;
#if BOARD_MODEL == BOARD_TBEAM_S_V1
void set_contrast(Adafruit_SH1106G *display, uint8_t value) {
}
#elif BOARD_MODEL == BOARD_HELTEC_T114
void set_contrast(ST7789Spi *display, uint8_t value) {
}
#elif BOARD_MODEL == BOARD_TDECK
void set_contrast(Adafruit_ST7789 *display, uint8_t value) {
static uint8_t level = 0;
@ -198,6 +208,24 @@ bool display_init() {
delay(50);
digitalWrite(pin_display_en, HIGH);
Wire.begin(SDA_OLED, SCL_OLED);
#elif BOARD_MODEL == BOARD_HELTEC_T114
// enable vext (not required for screen to work, but is done in Heltec example)
digitalWrite(PIN_T114_VEXT_EN, HIGH);
pinMode(PIN_T114_VEXT_EN, OUTPUT);
// enable power to display
digitalWrite(PIN_T114_TFT_EN, LOW);
pinMode(PIN_T114_TFT_EN, OUTPUT);
// enable backlight led (display is always black without this)
digitalWrite(PIN_T114_TFT_BLGT, LOW);
pinMode(PIN_T114_TFT_BLGT, OUTPUT);
// enable adc (not required for screen to work, but is done in Heltec example)
digitalWrite(PIN_T114_ADC_EN, HIGH);
pinMode(PIN_T114_ADC_EN, OUTPUT);
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
Wire.begin(SDA_OLED, SCL_OLED);
#endif
@ -235,6 +263,10 @@ bool display_init() {
#if BOARD_MODEL == BOARD_TDECK
display.init(240, 320);
display.setSPISpeed(80e6);
#elif BOARD_MODEL == BOARD_HELTEC_T114
display.init();
// set white as default pixel colour for Heltec T114
display.setRGB(COLOR565(0xFF, 0xFF, 0xFF));
if (false) {
#elif BOARD_MODEL == BOARD_TBEAM_S_V1
if (!display.begin(display_address, true)) {
@ -250,7 +282,9 @@ bool display_init() {
} else {
disp_mode = DISP_MODE_PORTRAIT;
}
#if BOARD_MODEL != BOARD_HELTEC_T114
display.setRotation(display_rotation);
#endif
} else {
#if BOARD_MODEL == BOARD_RNODE_NG_20
disp_mode = DISP_MODE_PORTRAIT;
@ -279,6 +313,8 @@ bool display_init() {
#elif BOARD_MODEL == BOARD_HELTEC32_V3
disp_mode = DISP_MODE_PORTRAIT;
display.setRotation(1);
#elif BOARD_MODEL == BOARD_HELTEC_T114
disp_mode = DISP_MODE_LANDSCAPE;
#elif BOARD_MODEL == BOARD_RAK4631
disp_mode = DISP_MODE_LANDSCAPE;
display.setRotation(0);
@ -300,7 +336,10 @@ bool display_init() {
stat_area.cp437(true);
disp_area.cp437(true);
#if BOARD_MODEL != BOARD_HELTEC_T114
display.cp437(true);
#endif
#if HAS_EEPROM
#if MCU_VARIANT != MCU_NRF52
@ -321,6 +360,56 @@ bool display_init() {
#endif
}
// draws a line on the screen
void drawLine(int16_t x, int16_t y, int16_t width, int16_t height, uint16_t colour) {
#if BOARD_MODEL == BOARD_HELTEC_T114
if(colour == SSD1306_WHITE){
display.setColor(WHITE);
} else if(colour == SSD1306_BLACK) {
display.setColor(BLACK);
}
display.drawLine(x, y, width, height);
#else
display.drawLine(x, y, width, height, colour);
#endif
}
// draws a filled rectangle on the screen
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height, uint16_t colour) {
#if BOARD_MODEL == BOARD_HELTEC_T114
if(colour == SSD1306_WHITE){
display.setColor(WHITE);
} else if(colour == SSD1306_BLACK) {
display.setColor(BLACK);
}
display.fillRect(x, y, width, height);
#else
display.fillRect(x, y, width, height, colour);
#endif
}
// draws a bitmap to the display and auto scales it based on the boards configured DISPLAY_SCALE
void drawBitmap(int16_t startX, int16_t startY, const uint8_t* bitmap, int16_t bitmapWidth, int16_t bitmapHeight, uint16_t foregroundColour, uint16_t backgroundColour) {
for(int16_t row = 0; row < bitmapHeight; row++){
for(int16_t col = 0; col < bitmapWidth; col++){
// determine index and bitmask
int16_t index = row * ((bitmapWidth + 7) / 8) + (col / 8);
uint8_t bitmask = 1 << (7 - (col % 8));
// check if the current pixel is set in the bitmap
if(bitmap[index] & bitmask){
// draw a scaled rectangle for the foreground pixel
fillRect(startX + col * DISPLAY_SCALE, startY + row * DISPLAY_SCALE, DISPLAY_SCALE, DISPLAY_SCALE, foregroundColour);
} else {
// draw a scaled rectangle for the background pixel
fillRect(startX + col * DISPLAY_SCALE, startY + row * DISPLAY_SCALE, DISPLAY_SCALE, DISPLAY_SCALE, backgroundColour);
}
}
}
}
void draw_cable_icon(int px, int py) {
if (cable_state == CABLE_STATE_DISCONNECTED) {
stat_area.drawBitmap(px, py, bm_cable+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
@ -527,19 +616,19 @@ void update_stat_area() {
draw_stat_area();
if (disp_mode == DISP_MODE_PORTRAIT) {
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
display.drawBitmap(p_as_x+2, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
if (device_init_done && !disp_ext_fb) display.drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
drawBitmap(p_as_x+2, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
if (device_init_done && !disp_ext_fb) drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
}
} else {
if (firmware_update_mode) {
display.drawBitmap(p_as_x, p_as_y, bm_updating, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
drawBitmap(p_as_x, p_as_y, bm_updating, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
} else if (console_active && device_init_done) {
display.drawBitmap(p_as_x, p_as_y, bm_console, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
drawBitmap(p_as_x, p_as_y, bm_console, stat_area.width(), stat_area.height(), SSD1306_BLACK, SSD1306_WHITE);
if (disp_mode == DISP_MODE_LANDSCAPE) {
display.drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
drawLine(p_as_x, 0, p_as_x, 64, SSD1306_WHITE);
}
}
}
@ -700,10 +789,10 @@ void draw_disp_area() {
void update_disp_area() {
draw_disp_area();
display.drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
if (disp_mode == DISP_MODE_LANDSCAPE) {
if (device_init_done && !firmware_update_mode && !disp_ext_fb) {
display.drawLine(0, 0, 0, 63, SSD1306_WHITE);
drawLine(0, 0, 0, 63, SSD1306_WHITE);
}
}
}
@ -715,11 +804,11 @@ void display_recondition() {
disp_area.drawBitmap(0, iy, rand_seg, 64, 1, SSD1306_WHITE, SSD1306_BLACK);
}
display.drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
drawBitmap(p_ad_x, p_ad_y, disp_area.getBuffer(), disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
if (disp_mode == DISP_MODE_PORTRAIT) {
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
} else if (disp_mode == DISP_MODE_LANDSCAPE) {
display.drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
drawBitmap(p_as_x, p_as_y, stat_area.getBuffer(), stat_area.width(), stat_area.height(), SSD1306_WHITE, SSD1306_BLACK);
}
}
@ -750,7 +839,10 @@ void update_display(bool blank = false) {
set_contrast(&display, display_contrast);
}
#if BOARD_MODEL != BOARD_TDECK
#if BOARD_MODEL == BOARD_HELTEC_T114
display.clear();
display.display();
#elif BOARD_MODEL != BOARD_TDECK
display.clearDisplay();
display.display();
#else
@ -766,7 +858,9 @@ void update_display(bool blank = false) {
set_contrast(&display, display_contrast);
}
#if BOARD_MODEL != BOARD_TDECK
#if BOARD_MODEL == BOARD_HELTEC_T114
display.clear();
#elif BOARD_MODEL != BOARD_TDECK
display.clearDisplay();
#endif