Merge pull request #9037 from gemu2015/st7789

st7789 display driver
This commit is contained in:
Theo Arends 2020-08-06 09:25:25 +02:00 committed by GitHub
commit d7e8c41141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1658 additions and 0 deletions

View File

@ -0,0 +1,554 @@
/***************************************************
This is a library for the ST7789 IPS SPI display.
Originally written by Limor Fried/Ladyada for
Adafruit Industries.
Modified by Ananev Ilia
****************************************************/
#include "Arduino_ST7789.h"
#include <limits.h>
#include "pins_arduino.h"
#include "wiring_private.h"
#include <SPI.h>
const uint16_t ST7789_colors[]={ST7789_BLACK,ST7789_WHITE,ST7789_RED,ST7789_GREEN,ST7789_BLUE,ST7789_CYAN,ST7789_MAGENTA,\
ST7789_YELLOW,ST7789_NAVY,ST7789_DARKGREEN,ST7789_DARKCYAN,ST7789_MAROON,ST7789_PURPLE,ST7789_OLIVE,\
ST7789_LIGHTGREY,ST7789_DARKGREY,ST7789_ORANGE,ST7789_GREENYELLOW,ST7789_PINK};
uint16_t Arduino_ST7789::GetColorFromIndex(uint8_t index) {
if (index>=sizeof(ST7789_colors)/2) index=0;
return ST7789_colors[index];
}
static const uint8_t PROGMEM
cmd_240x240[] = { // Initialization commands for 7789 screens
10, // 9 commands in list:
ST7789_SWRESET, ST_CMD_DELAY, // 1: Software reset, no args, w/delay
150, // 150 ms delay
ST7789_SLPOUT , ST_CMD_DELAY, // 2: Out of sleep mode, no args, w/delay
255, // 255 = 500 ms delay
ST7789_COLMOD , 1+ST_CMD_DELAY, // 3: Set color mode, 1 arg + delay:
0x55, // 16-bit color
10, // 10 ms delay
ST7789_MADCTL , 1, // 4: Memory access ctrl (directions), 1 arg:
0x00, // Row addr/col addr, bottom to top refresh
ST7789_CASET , 4, // 5: Column addr set, 4 args, no delay:
0x00, ST7789_240x240_XSTART, // XSTART = 0
(ST7789_TFTWIDTH+ST7789_240x240_XSTART) >> 8,
(ST7789_TFTWIDTH+ST7789_240x240_XSTART) & 0xFF, // XEND = 240
ST7789_RASET , 4, // 6: Row addr set, 4 args, no delay:
0x00, ST7789_240x240_YSTART, // YSTART = 0
(ST7789_TFTHEIGHT+ST7789_240x240_YSTART) >> 8,
(ST7789_TFTHEIGHT+ST7789_240x240_YSTART) & 0xFF, // YEND = 240
ST7789_INVON , ST_CMD_DELAY, // 7: Inversion ON
10,
ST7789_NORON , ST_CMD_DELAY, // 8: Normal display on, no args, w/delay
10, // 10 ms delay
ST7789_DISPON , ST_CMD_DELAY, // 9: Main screen turn on, no args, w/delay
255 }; // 255 = 500 ms delay
inline uint16_t swapcolor(uint16_t x) {
return (x << 11) | (x & 0x07E0) | (x >> 11);
}
#if defined (SPI_HAS_TRANSACTION)
static SPISettings mySPISettings;
#elif defined (__AVR__) || defined(CORE_TEENSY)
static uint8_t SPCRbackup;
static uint8_t mySPCR;
#endif
#if defined (SPI_HAS_TRANSACTION)
#define SPI_BEGIN_TRANSACTION() if (_hwSPI) SPI.beginTransaction(mySPISettings)
#define SPI_END_TRANSACTION() if (_hwSPI) SPI.endTransaction()
#else
#define SPI_BEGIN_TRANSACTION() (void)
#define SPI_END_TRANSACTION() (void)
#endif
// Constructor when using software SPI. All output pins are configurable.
Arduino_ST7789::Arduino_ST7789(int8_t dc, int8_t rst, int8_t sid, int8_t sclk, int8_t cs, int8_t bp)
: Renderer(ST7789_TFTWIDTH, ST7789_TFTHEIGHT)
{
_cs = cs;
_dc = dc;
_sid = sid;
_sclk = sclk;
_rst = rst;
_hwSPI = false;
_bp = bp;
if(dc == -1) _SPI9bit = true;
else _SPI9bit = false;
}
// Constructor when using hardware SPI. Faster, but must use SPI pins
// specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.)
Arduino_ST7789::Arduino_ST7789(int8_t dc, int8_t rst, int8_t cs)
: Renderer(ST7789_TFTWIDTH, ST7789_TFTHEIGHT) {
_cs = cs;
_dc = dc;
_rst = rst;
_hwSPI = true;
_SPI9bit = false;
_sid = _sclk = -1;
}
void Arduino_ST7789::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) {
setRotation(rot);
//invertDisplay(false);
invertDisplay(true);
//setTextWrap(false); // Allow text to run off edges
//cp437(true);
setTextFont(font&3);
setTextSize(size&7);
setTextColor(ST7789_WHITE,ST7789_BLACK);
setCursor(0,0);
fillScreen(ST7789_BLACK);
}
inline void Arduino_ST7789::spiwrite(uint8_t c)
{
//Serial.println(c, HEX);
if (_hwSPI)
{
#if defined (SPI_HAS_TRANSACTION)
SPI.transfer(c);
#elif defined (__AVR__) || defined(CORE_TEENSY)
SPCRbackup = SPCR;
SPCR = mySPCR;
SPI.transfer(c);
SPCR = SPCRbackup;
#elif defined (__arm__)
SPI.setClockDivider(21); //4MHz
SPI.setDataMode(SPI_MODE2);
SPI.transfer(c);
#endif
}
else
{
if(_SPI9bit)
{
//9s bit send first
#if defined(USE_FAST_IO)
*clkport &= ~clkpinmask;
if(_DCbit) *dataport |= datapinmask;
else *dataport &= ~datapinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sclk, LOW);
if(_DCbit) digitalWrite(_sid, HIGH);
else digitalWrite(_sid, LOW);
digitalWrite(_sclk, HIGH);
#endif
// Fast SPI bitbang swiped from LPD8806 library
for(uint8_t bit = 0x80; bit; bit >>= 1) {
#if defined(USE_FAST_IO)
*clkport &= ~clkpinmask;
if(c & bit) *dataport |= datapinmask;
else *dataport &= ~datapinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sclk, LOW);
if(c & bit) digitalWrite(_sid, HIGH);
else digitalWrite(_sid, LOW);
digitalWrite(_sclk, HIGH);
#endif
}
}
else
{
// Fast SPI bitbang swiped from LPD8806 library
for(uint8_t bit = 0x80; bit; bit >>= 1) {
#if defined(USE_FAST_IO)
*clkport &= ~clkpinmask;
if(c & bit) *dataport |= datapinmask;
else *dataport &= ~datapinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sclk, LOW);
if(c & bit) digitalWrite(_sid, HIGH);
else digitalWrite(_sid, LOW);
digitalWrite(_sclk, HIGH);
#endif
}
}
}
}
void Arduino_ST7789::writecommand(uint8_t c) {
DC_LOW();
CS_LOW();
SPI_BEGIN_TRANSACTION();
spiwrite(c);
CS_HIGH();
SPI_END_TRANSACTION();
}
void Arduino_ST7789::writedata(uint8_t c) {
SPI_BEGIN_TRANSACTION();
DC_HIGH();
CS_LOW();
spiwrite(c);
CS_HIGH();
SPI_END_TRANSACTION();
}
// Companion code to the above tables. Reads and issues
// a series of LCD commands stored in PROGMEM byte array.
void Arduino_ST7789::displayInit(const uint8_t *addr) {
uint8_t numCommands, numArgs;
uint16_t ms;
//<-----------------------------------------------------------------------------------------
DC_HIGH();
#if defined(USE_FAST_IO)
*clkport |= clkpinmask;
#else
digitalWrite(_sclk, HIGH);
#endif
//<-----------------------------------------------------------------------------------------
numCommands = pgm_read_byte(addr++); // Number of commands to follow
while(numCommands--) { // For each command...
writecommand(pgm_read_byte(addr++)); // Read, issue command
numArgs = pgm_read_byte(addr++); // Number of args to follow
ms = numArgs & ST_CMD_DELAY; // If hibit set, delay follows args
numArgs &= ~ST_CMD_DELAY; // Mask out delay bit
while(numArgs--) { // For each argument...
writedata(pgm_read_byte(addr++)); // Read, issue argument
}
if(ms) {
ms = pgm_read_byte(addr++); // Read post-command delay time (ms)
if(ms == 255) ms = 500; // If 255, delay for 500 ms
delay(ms);
}
}
}
// Initialization code common to all ST7789 displays
void Arduino_ST7789::commonInit(const uint8_t *cmdList) {
_ystart = _xstart = 0;
_colstart = _rowstart = 0; // May be overridden in init func
pinMode(_dc, OUTPUT);
if (_cs>=0) {
pinMode(_cs, OUTPUT);
}
if (_bp>=0) {
pinMode(_bp, OUTPUT);
}
#if defined(USE_FAST_IO)
dcport = portOutputRegister(digitalPinToPort(_dc));
dcpinmask = digitalPinToBitMask(_dc);
if (_cs>=0) {
csport = portOutputRegister(digitalPinToPort(_cs));
cspinmask = digitalPinToBitMask(_cs);
}
#endif
if(_hwSPI) { // Using hardware SPI
#if defined (SPI_HAS_TRANSACTION)
SPI.begin();
mySPISettings = SPISettings(24000000, MSBFIRST, SPI_MODE2);
#elif defined (__AVR__) || defined(CORE_TEENSY)
SPCRbackup = SPCR;
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV4);
SPI.setDataMode(SPI_MODE2);
mySPCR = SPCR; // save our preferred state
SPCR = SPCRbackup; // then restore
#elif defined (__SAM3X8E__)
SPI.begin();
SPI.setClockDivider(21); //4MHz
SPI.setDataMode(SPI_MODE2);
#endif
} else {
pinMode(_sclk, OUTPUT);
pinMode(_sid , OUTPUT);
digitalWrite(_sclk, LOW);
digitalWrite(_sid, LOW);
#if defined(USE_FAST_IO)
clkport = portOutputRegister(digitalPinToPort(_sclk));
dataport = portOutputRegister(digitalPinToPort(_sid));
clkpinmask = digitalPinToBitMask(_sclk);
datapinmask = digitalPinToBitMask(_sid);
#endif
}
// toggle RST low to reset; CS low so it'll listen to us
CS_LOW();
if (_rst != -1) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(50);
digitalWrite(_rst, LOW);
delay(50);
digitalWrite(_rst, HIGH);
delay(50);
}
if(cmdList)
displayInit(cmdList);
}
void Arduino_ST7789::setRotation(uint8_t m) {
writecommand(ST7789_MADCTL);
rotation = m % 4; // can't be higher than 3
switch (rotation) {
case 0:
writedata(ST7789_MADCTL_MX | ST7789_MADCTL_MY | ST7789_MADCTL_RGB);
_xstart = _colstart;
// _ystart = _rowstart;
_ystart = 80;
break;
case 1:
writedata(ST7789_MADCTL_MY | ST7789_MADCTL_MV | ST7789_MADCTL_RGB);
_ystart = _colstart;
// _xstart = _rowstart;
_xstart = 80;
break;
case 2:
writedata(ST7789_MADCTL_RGB);
_xstart = _colstart;
_ystart = _rowstart;
break;
case 3:
writedata(ST7789_MADCTL_MX | ST7789_MADCTL_MV | ST7789_MADCTL_RGB);
_ystart = _colstart;
_xstart = _rowstart;
break;
}
}
void Arduino_ST7789::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,
uint16_t y1) {
uint16_t x_start = x0 + _xstart, x_end = x1 + _xstart;
uint16_t y_start = y0 + _ystart, y_end = y1 + _ystart;
writecommand(ST7789_CASET); // Column addr set
writedata(x_start >> 8);
writedata(x_start & 0xFF); // XSTART
writedata(x_end >> 8);
writedata(x_end & 0xFF); // XEND
writecommand(ST7789_RASET); // Row addr set
writedata(y_start >> 8);
writedata(y_start & 0xFF); // YSTART
writedata(y_end >> 8);
writedata(y_end & 0xFF); // YEND
writecommand(ST7789_RAMWR); // write to RAM
}
void Arduino_ST7789::pushColor(uint16_t color) {
SPI_BEGIN_TRANSACTION();
DC_HIGH();
CS_LOW();
spiwrite(color >> 8);
spiwrite(color);
CS_HIGH();
SPI_END_TRANSACTION();
}
void Arduino_ST7789::drawPixel(int16_t x, int16_t y, uint16_t color) {
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
setAddrWindow(x,y,x+1,y+1);
SPI_BEGIN_TRANSACTION();
DC_HIGH();
CS_LOW();
spiwrite(color >> 8);
spiwrite(color);
CS_HIGH();
SPI_END_TRANSACTION();
}
void Arduino_ST7789::drawFastVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
if((y+h-1) >= _height) h = _height-y;
setAddrWindow(x, y, x, y+h-1);
uint8_t hi = color >> 8, lo = color;
SPI_BEGIN_TRANSACTION();
DC_HIGH();
CS_LOW();
while (h--) {
spiwrite(hi);
spiwrite(lo);
}
CS_HIGH();
SPI_END_TRANSACTION();
}
void Arduino_ST7789::drawFastHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
// Rudimentary clipping
if((x >= _width) || (y >= _height)) return;
if((x+w-1) >= _width) w = _width-x;
setAddrWindow(x, y, x+w-1, y);
uint8_t hi = color >> 8, lo = color;
SPI_BEGIN_TRANSACTION();
DC_HIGH();
CS_LOW();
while (w--) {
spiwrite(hi);
spiwrite(lo);
}
CS_HIGH();
SPI_END_TRANSACTION();
}
void Arduino_ST7789::fillScreen(uint16_t color) {
fillRect(0, 0, _width, _height, color);
}
// fill a rectangle
void Arduino_ST7789::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color) {
// rudimentary clipping (drawChar w/big text requires this)
if((x >= _width) || (y >= _height)) return;
if((x + w - 1) >= _width) w = _width - x;
if((y + h - 1) >= _height) h = _height - y;
setAddrWindow(x, y, x+w-1, y+h-1);
uint8_t hi = color >> 8, lo = color;
SPI_BEGIN_TRANSACTION();
DC_HIGH();
CS_LOW();
for(y=h; y>0; y--) {
for(x=w; x>0; x--) {
spiwrite(hi);
spiwrite(lo);
}
}
CS_HIGH();
SPI_END_TRANSACTION();
}
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
uint16_t Arduino_ST7789::Color565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
void Arduino_ST7789::invertDisplay(boolean i) {
writecommand(i ? ST7789_INVON : ST7789_INVOFF);
}
/******** low level bit twiddling **********/
inline void Arduino_ST7789::CS_HIGH(void) {
if(_cs>=0) {
#if defined(USE_FAST_IO)
*csport |= cspinmask;
#else
digitalWrite(_cs, HIGH);
#endif
}
}
inline void Arduino_ST7789::CS_LOW(void) {
if(_cs>=0) {
#if defined(USE_FAST_IO)
*csport &= ~cspinmask;
#else
digitalWrite(_cs, LOW);
#endif
}
}
inline void Arduino_ST7789::DC_HIGH(void) {
_DCbit = true;
#if defined(USE_FAST_IO)
*dcport |= dcpinmask;
#else
digitalWrite(_dc, HIGH);
#endif
}
inline void Arduino_ST7789::DC_LOW(void) {
_DCbit = false;
#if defined(USE_FAST_IO)
*dcport &= ~dcpinmask;
#else
digitalWrite(_dc, LOW);
#endif
}
void Arduino_ST7789::init(uint16_t width, uint16_t height) {
commonInit(NULL);
_colstart = ST7789_240x240_XSTART;
_rowstart = ST7789_240x240_YSTART;
_height = height;
_width = width;
displayInit(cmd_240x240);
setRotation(2);
}
void Arduino_ST7789::DisplayOnff(int8_t on) {
if (on) {
writecommand(ST7789_DISPON); //Display on
if (_bp>=0) {
digitalWrite(_bp,HIGH);
}
} else {
writecommand(ST7789_DISPOFF);
if (_bp>=0) {
digitalWrite(_bp,LOW);
}
}
}

View File

@ -0,0 +1,178 @@
/***************************************************
This is a library for the ST7789 IPS SPI display.
Originally written by Limor Fried/Ladyada for
Adafruit Industries.
Modified by Ananev Ilia
****************************************************/
#ifndef _ADAFRUIT_ST7789H_
#define _ADAFRUIT_ST7789H_
#include "Arduino.h"
#include "Print.h"
#include <Adafruit_GFX.h>
#include <renderer.h>
#if defined(__AVR__) || defined(CORE_TEENSY)
#include <avr/pgmspace.h>
#define USE_FAST_IO
typedef volatile uint8_t RwReg;
#elif defined(ARDUINO_STM32_FEATHER)
typedef volatile uint32 RwReg;
#define USE_FAST_IO
#elif defined(ARDUINO_FEATHER52)
typedef volatile uint32_t RwReg;
#define USE_FAST_IO
#elif defined(ESP8266)
#include <pgmspace.h>
#elif defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#include <include/pio.h>
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
typedef unsigned char prog_uchar;
#endif
#define SPI_HAS_TRANSACTION
#define ST7789_TFTWIDTH 240
#define ST7789_TFTHEIGHT 240
#define ST7789_240x240_XSTART 0
#define ST7789_240x240_YSTART 0
#define ST_CMD_DELAY 0x80 // special signifier for command lists
#define ST7789_NOP 0x00
#define ST7789_SWRESET 0x01
#define ST7789_RDDID 0x04
#define ST7789_RDDST 0x09
#define ST7789_SLPIN 0x10
#define ST7789_SLPOUT 0x11
#define ST7789_PTLON 0x12
#define ST7789_NORON 0x13
#define ST7789_INVOFF 0x20
#define ST7789_INVON 0x21
#define ST7789_DISPOFF 0x28
#define ST7789_DISPON 0x29
#define ST7789_CASET 0x2A
#define ST7789_RASET 0x2B
#define ST7789_RAMWR 0x2C
#define ST7789_RAMRD 0x2E
#define ST7789_PTLAR 0x30
#define ST7789_COLMOD 0x3A
#define ST7789_MADCTL 0x36
#define ST7789_MADCTL_MY 0x80
#define ST7789_MADCTL_MX 0x40
#define ST7789_MADCTL_MV 0x20
#define ST7789_MADCTL_ML 0x10
#define ST7789_MADCTL_RGB 0x00
#define ST7789_RDID1 0xDA
#define ST7789_RDID2 0xDB
#define ST7789_RDID3 0xDC
#define ST7789_RDID4 0xDD
// Color definitions
#undef BLACK
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#undef WHITE
#define WHITE 0xFFFF
// Color definitions
#define ST7789_BLACK 0x0000 /* 0, 0, 0 */
#define ST7789_NAVY 0x000F /* 0, 0, 128 */
#define ST7789_DARKGREEN 0x03E0 /* 0, 128, 0 */
#define ST7789_DARKCYAN 0x03EF /* 0, 128, 128 */
#define ST7789_MAROON 0x7800 /* 128, 0, 0 */
#define ST7789_PURPLE 0x780F /* 128, 0, 128 */
#define ST7789_OLIVE 0x7BE0 /* 128, 128, 0 */
#define ST7789_LIGHTGREY 0xC618 /* 192, 192, 192 */
#define ST7789_DARKGREY 0x7BEF /* 128, 128, 128 */
#define ST7789_BLUE 0x001F /* 0, 0, 255 */
#define ST7789_GREEN 0x07E0 /* 0, 255, 0 */
#define ST7789_CYAN 0x07FF /* 0, 255, 255 */
#define ST7789_RED 0xF800 /* 255, 0, 0 */
#define ST7789_MAGENTA 0xF81F /* 255, 0, 255 */
#define ST7789_YELLOW 0xFFE0 /* 255, 255, 0 */
#define ST7789_WHITE 0xFFFF /* 255, 255, 255 */
#define ST7789_ORANGE 0xFD20 /* 255, 165, 0 */
#define ST7789_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
#define ST7789_PINK 0xF81F
class Arduino_ST7789 : public Renderer {
public:
Arduino_ST7789(int8_t DC, int8_t RST, int8_t SID, int8_t SCLK, int8_t CS = -1,int8_t bp = -1);
Arduino_ST7789(int8_t DC, int8_t RST, int8_t CS = -1);
void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1),
pushColor(uint16_t color),
fillScreen(uint16_t color),
drawPixel(int16_t x, int16_t y, uint16_t color),
drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color),
setRotation(uint8_t r),
invertDisplay(boolean i),
DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font),
init(uint16_t width, uint16_t height);
uint16_t Color565(uint8_t r, uint8_t g, uint8_t b);
uint16_t GetColorFromIndex(uint8_t index);
uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return Color565(r, g, b); }
void DisplayOnff(int8_t on);
protected:
uint8_t _colstart, _rowstart, _xstart, _ystart; // some displays need this changed
void displayInit(const uint8_t *addr);
void spiwrite(uint8_t),
writecommand(uint8_t c),
writedata(uint8_t d),
commonInit(const uint8_t *cmdList);
private:
inline void CS_HIGH(void);
inline void CS_LOW(void);
inline void DC_HIGH(void);
inline void DC_LOW(void);
boolean _hwSPI;
boolean _SPI9bit;
boolean _DCbit;
int8_t _cs, _dc, _rst, _sid, _sclk, _bp;
#if defined(USE_FAST_IO)
volatile RwReg *dataport, *clkport, *csport, *dcport;
#if defined(__AVR__) || defined(CORE_TEENSY) // 8 bit!
uint8_t datapinmask, clkpinmask, cspinmask, dcpinmask;
#else // 32 bit!
uint32_t datapinmask, clkpinmask, cspinmask, dcpinmask;
#endif
#endif
};
#endif

View File

@ -0,0 +1,3 @@
This is a library for the ST7789 IPS SPI display.
Also requires the Adafruit_GFX library for Arduino.

View File

@ -0,0 +1,278 @@
/***************************************************
This is a library for the ST7789 IPS SPI display.
Originally written by Limor Fried/Ladyada for
Adafruit Industries.
Modified by Ananev Ilia
****************************************************/
#include <Adafruit_GFX.h> // Core graphics library by Adafruit
#include <Arduino_ST7789.h> // Hardware-specific library for ST7789 (with or without CS pin)
#include <SPI.h>
#define TFT_DC 8
#define TFT_RST 9
#define TFT_CS 10 // only for displays with CS pin
#define TFT_MOSI 11 // for hardware SPI data pin (all of available pins)
#define TFT_SCLK 13 // for hardware SPI sclk pin (all of available pins)
//You can use different type of hardware initialization
//using hardware SPI (11, 13 on UNO; 51, 52 on MEGA; ICSP-4, ICSP-3 on DUE and etc)
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST); //for display without CS pin
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_CS); //for display with CS pin
//or you can use software SPI on all available pins (slow)
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK); //for display without CS pin
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin
Arduino_ST7789 tft = Arduino_ST7789(-1, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin and DC via 9bit SPI
float p = 3.1415926;
void setup(void) {
Serial.begin(9600);
Serial.print("Hello! ST7789 TFT Test");
tft.init(240, 240); // initialize a ST7789 chip, 240x240 pixels
Serial.println("Initialized");
uint16_t time = millis();
tft.fillScreen(BLACK);
time = millis() - time;
Serial.println(time, DEC);
delay(500);
// large block of text
tft.fillScreen(BLACK);
testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", WHITE);
delay(1000);
// tft print function
tftPrintTest();
delay(4000);
// a single pixel
tft.drawPixel(tft.width()/2, tft.height()/2, GREEN);
delay(500);
// line draw test
testlines(YELLOW);
delay(500);
// optimized lines
testfastlines(RED, BLUE);
delay(500);
testdrawrects(GREEN);
delay(500);
testfillrects(YELLOW, MAGENTA);
delay(500);
tft.fillScreen(BLACK);
testfillcircles(10, BLUE);
testdrawcircles(10, WHITE);
delay(500);
testroundrects();
delay(500);
testtriangles();
delay(500);
mediabuttons();
delay(500);
Serial.println("done");
delay(1000);
}
void loop() {
tft.invertDisplay(true);
delay(500);
tft.invertDisplay(false);
delay(500);
}
void testlines(uint16_t color) {
tft.fillScreen(BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, 0, x, tft.height()-1, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, 0, tft.width()-1, y, color);
}
tft.fillScreen(BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, 0, 0, y, color);
}
tft.fillScreen(BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, tft.height()-1, x, 0, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
}
tft.fillScreen(BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
}
}
void testdrawtext(char *text, uint16_t color) {
tft.setCursor(0, 0);
tft.setTextColor(color);
tft.setTextWrap(true);
tft.print(text);
}
void testfastlines(uint16_t color1, uint16_t color2) {
tft.fillScreen(BLACK);
for (int16_t y=0; y < tft.height(); y+=5) {
tft.drawFastHLine(0, y, tft.width(), color1);
}
for (int16_t x=0; x < tft.width(); x+=5) {
tft.drawFastVLine(x, 0, tft.height(), color2);
}
}
void testdrawrects(uint16_t color) {
tft.fillScreen(BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
}
}
void testfillrects(uint16_t color1, uint16_t color2) {
tft.fillScreen(BLACK);
for (int16_t x=tft.width()-1; x > 6; x-=6) {
tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
}
}
void testfillcircles(uint8_t radius, uint16_t color) {
for (int16_t x=radius; x < tft.width(); x+=radius*2) {
for (int16_t y=radius; y < tft.height(); y+=radius*2) {
tft.fillCircle(x, y, radius, color);
}
}
}
void testdrawcircles(uint8_t radius, uint16_t color) {
for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
tft.drawCircle(x, y, radius, color);
}
}
}
void testtriangles() {
tft.fillScreen(BLACK);
int color = 0xF800;
int t;
int w = tft.width()/2;
int x = tft.height()-1;
int y = 0;
int z = tft.width();
for(t = 0 ; t <= 15; t++) {
tft.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
z-=4;
color+=100;
}
}
void testroundrects() {
tft.fillScreen(BLACK);
int color = 100;
int i;
int t;
for(t = 0 ; t <= 4; t+=1) {
int x = 0;
int y = 0;
int w = tft.width()-2;
int h = tft.height()-2;
for(i = 0 ; i <= 16; i+=1) {
tft.drawRoundRect(x, y, w, h, 5, color);
x+=2;
y+=3;
w-=4;
h-=6;
color+=1100;
}
color+=100;
}
}
void tftPrintTest() {
tft.setTextWrap(false);
tft.fillScreen(BLACK);
tft.setCursor(0, 30);
tft.setTextColor(RED);
tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(YELLOW);
tft.setTextSize(2);
tft.println("Hello World!");
tft.setTextColor(GREEN);
tft.setTextSize(3);
tft.println("Hello World!");
tft.setTextColor(BLUE);
tft.setTextSize(4);
tft.print(1234.567);
delay(1500);
tft.setCursor(0, 0);
tft.fillScreen(BLACK);
tft.setTextColor(WHITE);
tft.setTextSize(0);
tft.println("Hello World!");
tft.setTextSize(1);
tft.setTextColor(GREEN);
tft.print(p, 6);
tft.println(" Want pi?");
tft.println(" ");
tft.print(8675309, HEX); // print 8,675,309 out in HEX!
tft.println(" Print HEX!");
tft.println(" ");
tft.setTextColor(WHITE);
tft.println("Sketch has been");
tft.println("running for: ");
tft.setTextColor(MAGENTA);
tft.print(millis() / 1000);
tft.setTextColor(WHITE);
tft.print(" seconds.");
}
void mediabuttons() {
// play
tft.fillScreen(BLACK);
tft.fillRoundRect(25, 10, 78, 60, 8, WHITE);
tft.fillTriangle(42, 20, 42, 60, 90, 40, RED);
delay(500);
// pause
tft.fillRoundRect(25, 90, 78, 60, 8, WHITE);
tft.fillRoundRect(39, 98, 20, 45, 5, GREEN);
tft.fillRoundRect(69, 98, 20, 45, 5, GREEN);
delay(500);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, BLUE);
delay(50);
// pause color
tft.fillRoundRect(39, 98, 20, 45, 5, RED);
tft.fillRoundRect(69, 98, 20, 45, 5, RED);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, GREEN);
}

View File

@ -0,0 +1,30 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
ST7789 KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
setRotation KEYWORD2
setAddrWindow KEYWORD2
pushColor KEYWORD2
drawPixel KEYWORD2
drawFastVLine KEYWORD2
drawFastHLine KEYWORD2
fillRect KEYWORD2
setRotation KEYWORD2
setRotation KEYWORD2
height KEYWORD2
width KEYWORD2
invertDisplay KEYWORD2
drawImage KEYWORD2
setScrollArea KEYWORD2
scroll KEYWORD2

View File

@ -0,0 +1,9 @@
name=Arduino ST7789 Library
version=0.9.5
author=Ananev Ilya
maintainer=Ananev Ilya <ananevilya@gmail.com>
sentence=This is a library for the ST7789 IPS SPI display.
paragraph=This is a library for the ST7789 IPS SPI display.
category=Display
url=https://github.com/ananevilya/Arduino-ST7789-Library
architectures=*

2
lib/FT5206_Library/.gitignore vendored Executable file
View File

@ -0,0 +1,2 @@
.vscode
.DS_Store

21
lib/FT5206_Library/LICENSE Executable file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 lewis he
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.

2
lib/FT5206_Library/README.md Executable file
View File

@ -0,0 +1,2 @@
FT5206 Library
=====================================

29
lib/FT5206_Library/keywords.txt Executable file
View File

@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map For FT5206 Library By lewis He
# github:https://github.com/lewisxhe
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
TP_Point KEYWORD1
FT5206_Class KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
adjustTheshold KEYWORD2
getPoint KEYWORD2
enterSleepMode KEYWORD2
enterMonitorMode KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,10 @@
name=FT5206_Library
version=1.0.0
author=Lewis He
maintainer=Lewis He <lewishe@outlook.com>
sentence=Arduino library for FT5206 chip.
paragraph=Arduino library for FT5206 chip. Tested with ESP32
category=Communication
url=https://github.com/lewisxhe/FT5206_Library
architectures=*
architectures=esp32

108
lib/FT5206_Library/src/FT5206.cpp Executable file
View File

@ -0,0 +1,108 @@
/////////////////////////////////////////////////////////////////
/*
MIT License
Copyright (c) 2019 lewis he
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.
FT5206.cpp - Arduino library for FT5206 chip.
Created by Lewis on April 17, 2019.
github:https://github.com/lewisxhe/FT5206_Library
*/
/////////////////////////////////////////////////////////////////
#include "FT5206.h"
int FT5206_Class::begin(TwoWire &port, uint8_t addr)
{
_i2cPort = &port;
_address = addr;
uint8_t val;
_readByte(FT5206_VENDID_REG, 1, &val);
//Serial.printf("vend id %d\n",val );
if (val != FT5206_VENDID) {
// return false;
}
_readByte(FT5206_CHIPID_REG, 1, &val);
//Serial.printf("chip id %d\n",val );
if ((val != FT6206_CHIPID) && (val != FT6236_CHIPID) && (val != FT6236U_CHIPID) && (val != FT5206U_CHIPID)) {
return false;
}
_init = true;
return true;
}
// valid touching detect threshold.
void FT5206_Class::adjustTheshold(uint8_t thresh)
{
if (!_init)return;
_writeByte(FT5206_THRESHHOLD_REG, 1, &thresh);
}
TP_Point FT5206_Class::getPoint(uint8_t num)
{
if (!_init) return TP_Point(0, 0);
_readRegister();
if ((_touches == 0) || (num > 1)) {
return TP_Point(0, 0);
} else {
return TP_Point(_x[num], _y[num]);
}
}
uint8_t FT5206_Class::touched()
{
if (!_init)return 0;
uint8_t val = 0;
_readByte(FT5206_TOUCHES_REG,1,&val);
return val > 2 ? 0: val;
}
void FT5206_Class::enterSleepMode()
{
if (!_init)return;
uint8_t val = FT5206_SLEEP_IN;
_writeByte(FT5206_POWER_REG, 1, &val);
}
void FT5206_Class::enterMonitorMode()
{
if (!_init)return;
uint8_t val = FT5206_MONITOR;
_writeByte(FT5206_POWER_REG, 1, &val);
}
void FT5206_Class::_readRegister()
{
_readByte(DEVIDE_MODE, 16, _data);
_touches = _data[TD_STATUS];
if ((_touches > 2) || (_touches == 0)) {
_touches = 0;
return;
}
for (uint8_t i = 0; i < 2; i++) {
_x[i] = _data[TOUCH1_XH + i * 6] & 0x0F;
_x[i] <<= 8;
_x[i] |= _data[TOUCH1_XL + i * 6];
_y[i] = _data[TOUCH1_YH + i * 6] & 0x0F;
_y[i] <<= 8;
_y[i] |= _data[TOUCH1_YL + i * 6];
_id[i] = _data[TOUCH1_YH + i * 6] >> 4;
}
}

121
lib/FT5206_Library/src/FT5206.h Executable file
View File

@ -0,0 +1,121 @@
/////////////////////////////////////////////////////////////////
/*
MIT License
Copyright (c) 2019 lewis he
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.
FT5206.h - Arduino library for FT5206 chip.
Created by Lewis on April 17, 2019.
github:https://github.com/lewisxhe/FT5206_Library
*/
/////////////////////////////////////////////////////////////////
#pragma once
#include <Arduino.h>
#include <Wire.h>
#define FT5206_SLAVE_ADDRESS (0x38)
#define FT5206_MODE_REG (0x00)
#define FT5206_TOUCHES_REG (0x02)
#define FT5206_VENDID_REG (0xA8)
#define FT5206_CHIPID_REG (0xA3)
#define FT5206_THRESHHOLD_REG (0x80)
#define FT5206_POWER_REG (0x87)
#define FT5206_MONITOR (0x01)
#define FT5206_SLEEP_IN (0x03)
#define FT5206_VENDID 0x11
#define FT6206_CHIPID 0x06
#define FT6236_CHIPID 0x36
#define FT6236U_CHIPID 0x64
#define FT5206U_CHIPID 0x64
#define DEVIDE_MODE 0x00
#define TD_STATUS 0x02
#define TOUCH1_XH 0x03
#define TOUCH1_XL 0x04
#define TOUCH1_YH 0x05
#define TOUCH1_YL 0x06
class TP_Point
{
public:
TP_Point(void)
{
x = 0;
y = 0;
}
TP_Point(int16_t _x, int16_t _y)
{
x = _x;
y = _y;
}
int16_t x;
int16_t y;
};
class FT5206_Class
{
public:
FT5206_Class() {};
int begin(TwoWire &port = Wire, uint8_t addr = FT5206_SLAVE_ADDRESS);
// valid touching detect threshold.
void adjustTheshold(uint8_t thresh);
TP_Point getPoint(uint8_t num = 0);
uint8_t touched();
void enterSleepMode();
void enterMonitorMode();
private:
void _readRegister();
int _readByte(uint8_t reg, uint8_t nbytes, uint8_t *data)
{
_i2cPort->beginTransmission(_address);
_i2cPort->write(reg);
_i2cPort->endTransmission();
_i2cPort->requestFrom(_address, nbytes);
uint8_t index = 0;
while (_i2cPort->available())
data[index++] = _i2cPort->read();
return 0;
}
int _writeByte(uint8_t reg, uint8_t nbytes, uint8_t *data)
{
_i2cPort->beginTransmission(_address);
_i2cPort->write(reg);
for (uint8_t i = 0; i < nbytes; i++) {
_i2cPort->write(data[i]);
}
_i2cPort->endTransmission();
return 0;
}
uint8_t _address;
uint8_t _data[16];
uint16_t _x[2];
uint16_t _y[2];
uint16_t _id[2];
uint8_t _touches = 0;
bool _init = false;
TwoWire *_i2cPort;
};

313
tasmota/xdsp_12_ST7789.ino Normal file
View File

@ -0,0 +1,313 @@
/*
xdsp_12_ST7789.ino - Display ST7789 support for Tasmota
Copyright (C) 2020 Gerhard Mutz and Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_SPI
#ifdef USE_DISPLAY
#ifdef USE_DISPLAY_ST7789
#define XDSP_12 12
#define XI2C_38 38 // See I2CDEVICES.md
#undef COLORED
#define COLORED 1
#undef UNCOLORED
#define UNCOLORED 0
// touch panel controller
#undef FT5206_address
#define FT5206_address 0x38
// using font 8 is opional (num=3)
// very badly readable, but may be useful for graphs
#undef USE_TINY_FONT
#define USE_TINY_FONT
#include <Arduino_ST7789.h>
#include <FT5206.h>
// currently fixed
#define BACKPLANE_PIN 2
extern uint8_t *buffer;
extern uint8_t color_type;
Arduino_ST7789 *st7789;
#ifdef USE_FT5206
#ifdef USE_TOUCH_BUTTONS
extern VButton *buttons[];
#endif
FT5206_Class *touchp;
uint8_t FT5206_found;
TP_Point st7789_pLoc;
uint8_t st7789_ctouch_counter = 0;
#endif // USE_FT5206
/*********************************************************************************************/
void ST7789_InitDriver()
{
if (!Settings.display_model) {
Settings.display_model = XDSP_12;
}
if (XDSP_12 == Settings.display_model) {
if (Settings.display_width != ST7789_TFTWIDTH) {
Settings.display_width = ST7789_TFTWIDTH;
}
if (Settings.display_height != ST7789_TFTHEIGHT) {
Settings.display_height = ST7789_TFTHEIGHT;
}
// disable screen buffer
buffer=NULL;
// default colors
fg_color = ST7789_WHITE;
bg_color = ST7789_BLACK;
uint8_t bppin=BACKPLANE_PIN;
if (PinUsed(GPIO_BACKLIGHT)) {
bppin=Pin(GPIO_BACKLIGHT);
}
uint8_t reset = -1;
if (PinUsed(GPIO_OLED_RESET)) {
reset=Pin(GPIO_OLED_RESET);
}
uint8_t cs = -1;
if (PinUsed(GPIO_SSPI_CS)) {
cs=Pin(GPIO_SSPI_CS);
} else if (PinUsed(GPIO_SPI_CS)) {
cs=Pin(GPIO_SPI_CS);
}
#ifdef ESP32
#undef HW_SPI_MOSI
#define HW_SPI_MOSI 23
#undef HW_SPI_CLK
#define HW_SPI_CLK 18
#else
#undef HW_SPI_MOSI
#define HW_SPI_MOSI 13
#undef HW_SPI_CLK
#define HW_SPI_CLK 14
#endif
// init renderer, may use hardware spi
if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK) && PinUsed(GPIO_SPI_DC)) {
st7789 = new Arduino_ST7789(Pin(GPIO_SPI_DC), reset, Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK), cs, bppin);
} else {
if ((PinUsed(GPIO_SSPI_CS) || PinUsed(GPIO_OLED_RESET)) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_DC)) {
st7789 = new Arduino_ST7789(Pin(GPIO_SSPI_DC), reset, Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK), cs, bppin);
} else {
return;
}
}
st7789->init(Settings.display_width,Settings.display_height);
renderer = st7789;
renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font);
#ifdef SHOW_SPLASH
// Welcome text
renderer->setTextFont(2);
renderer->setTextColor(ST7789_WHITE,ST7789_BLACK);
renderer->DrawStringAt(30, 100, "ST7789 TFT!", ST7789_WHITE,0);
delay(1000);
#endif
color_type = COLOR_COLOR;
#ifdef ESP32
#ifdef USE_FT5206
// start digitizer with fixed adress and pins for esp32
#define SDA_2 23
#define SCL_2 32
Wire1.begin(SDA_2, SCL_2, 400000);
touchp = new FT5206_Class();
if (touchp->begin(Wire1, FT5206_address)) {
FT5206_found=1;
//I2cSetDevice(FT5206_address);
I2cSetActiveFound(FT5206_address, "FT5206");
} else {
FT5206_found=0;
}
#endif // USE_FT5206
#endif // ESP32
}
}
#ifdef ESP32
#ifdef USE_FT5206
#ifdef USE_TOUCH_BUTTONS
void ST7789_MQTT(uint8_t count,const char *cp) {
ResponseTime_P(PSTR(",\"ST7789\":{\"%s%d\":\"%d\"}}"), cp,count+1,(buttons[count]->vpower&0x80)>>7);
MqttPublishTeleSensor();
}
void ST7789_RDW_BUTT(uint32_t count,uint32_t pwr) {
buttons[count]->xdrawButton(pwr);
if (pwr) buttons[count]->vpower|=0x80;
else buttons[count]->vpower&=0x7f;
}
// check digitizer hit
void FT5206Check() {
uint16_t temp;
uint8_t rbutt=0,vbutt=0;
st7789_ctouch_counter++;
if (2 == st7789_ctouch_counter) {
// every 100 ms should be enough
st7789_ctouch_counter=0;
if (touchp->touched()) {
// did find a hit
st7789_pLoc = touchp->getPoint(0);
if (renderer) {
uint8_t rot=renderer->getRotation();
switch (rot) {
case 0:
temp=st7789_pLoc.y;
st7789_pLoc.y=renderer->height()-st7789_pLoc.x;
st7789_pLoc.x=temp;
break;
case 1:
break;
case 2:
break;
case 3:
temp=st7789_pLoc.y;
st7789_pLoc.y=st7789_pLoc.x;
st7789_pLoc.x=renderer->width()-temp;
break;
}
// now must compare with defined buttons
for (uint8_t count=0; count<MAXBUTTONS; count++) {
if (buttons[count]) {
uint8_t bflags=buttons[count]->vpower&0x7f;
if (buttons[count]->contains(st7789_pLoc.x,st7789_pLoc.y)) {
// did hit
buttons[count]->press(true);
if (buttons[count]->justPressed()) {
if (!bflags) {
uint8_t pwr=bitRead(power,rbutt);
if (!SendKey(KEY_BUTTON, rbutt+1, POWER_TOGGLE)) {
ExecuteCommandPower(rbutt+1, POWER_TOGGLE, SRC_BUTTON);
ST7789_RDW_BUTT(count,!pwr);
}
} else {
// virtual button
const char *cp;
if (bflags==1) {
// toggle button
buttons[count]->vpower^=0x80;
cp="TBT";
} else {
// push button
buttons[count]->vpower|=0x80;
cp="PBT";
}
buttons[count]->xdrawButton(buttons[count]->vpower&0x80);
ST7789_MQTT(count,cp);
}
}
}
if (!bflags) {
rbutt++;
} else {
vbutt++;
}
}
}
}
} else {
// no hit
for (uint8_t count=0; count<MAXBUTTONS; count++) {
if (buttons[count]) {
uint8_t bflags=buttons[count]->vpower&0x7f;
buttons[count]->press(false);
if (buttons[count]->justReleased()) {
uint8_t bflags=buttons[count]->vpower&0x7f;
if (bflags>0) {
if (bflags>1) {
// push button
buttons[count]->vpower&=0x7f;
ST7789_MQTT(count,"PBT");
}
buttons[count]->xdrawButton(buttons[count]->vpower&0x80);
}
}
if (!bflags) {
// check if power button stage changed
uint8_t pwr=bitRead(power,rbutt);
uint8_t vpwr=(buttons[count]->vpower&0x80)>>7;
if (pwr!=vpwr) {
ST7789_RDW_BUTT(count,pwr);
}
rbutt++;
}
}
}
st7789_pLoc.x=0;
st7789_pLoc.y=0;
}
}
}
#endif // USE_TOUCH_BUTTONS
#endif // USE_FT5206
#endif // ESP32
/*********************************************************************************************/
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xdsp12(uint8_t function)
{
bool result = false;
//AddLog_P2(LOG_LEVEL_INFO, PSTR("touch %d - %d"), FT5206_found, function);
if (FUNC_DISPLAY_INIT_DRIVER == function) {
ST7789_InitDriver();
}
else if (XDSP_12 == Settings.display_model) {
switch (function) {
case FUNC_DISPLAY_MODEL:
result = true;
break;
case FUNC_DISPLAY_EVERY_50_MSECOND:
#ifdef USE_FT5206
#ifdef USE_TOUCH_BUTTONS
if (FT5206_found) {
FT5206Check();
}
#endif
#endif // USE_FT5206
break;
}
}
return result;
}
#endif // USE_DISPLAY_ST7789
#endif // USE_DISPLAY
#endif // USE_SPI