Update TFT_eSpi for better ESP32 S3 support

This commit is contained in:
Luc 2022-09-11 16:34:42 +08:00
parent ee9906e3da
commit 3eabce6204
562 changed files with 12475 additions and 7234 deletions

View File

@ -10,7 +10,7 @@ cp -r ./libraries/ESP32SSDP-1.2.0 $HOME/arduino_ide/libraries/
cp -r ./libraries/arduinoWebSockets-2.3.6 $HOME/arduino_ide/libraries/
cp -r ./libraries/DHT_sensor_library_for_ESPx-1.0.6 $HOME/arduino_ide/libraries/
cp -r ./libraries/esp8266-oled-ssd1306-4.3.0 $HOME/arduino_ide/libraries/
cp -r ./libraries/TFT_eSPI-2.4.61 $HOME/arduino_ide/libraries/
cp -r ./libraries/TFT_eSPI-2.4.72 $HOME/arduino_ide/libraries/
cp -r ./libraries/lvgl-8.2.0 $HOME/arduino_ide/libraries/
cp -r ./libraries/ESP8266-Arduino-Lua-0.0.30 $HOME/arduino_ide/libraries/
cp -r ./libraries/BMx280MI-1.2.0 $HOME/arduino_ide/libraries/

View File

@ -1,39 +0,0 @@
// See SetupX_Template.h for all options available
#define ST7789_DRIVER
#define TFT_SDA_READ // Display has a bidirectional SDA pin
#define TFT_WIDTH 135
#define TFT_HEIGHT 240
#define CGRAM_OFFSET // Library will add offsets required
//#define TFT_MISO -1
#define TFT_MOSI 19
#define TFT_SCLK 18
#define TFT_CS 5
#define TFT_DC 16
#define TFT_RST 23
#define TOUCH_CS -1
#define TFT_BL 4 // Display backlight control pin
#define TFT_BACKLIGHT_ON HIGH // HIGH or LOW are options
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT
//#define SPI_FREQUENCY 27000000
#define SPI_FREQUENCY 40000000
#define SPI_READ_FREQUENCY 6000000 // 6 MHz is the maximum SPI read speed for the ST7789V

View File

@ -430,7 +430,7 @@ void TFT_eSPI::drawGlyph(uint16_t code)
startWrite(); // Avoid slow ESP32 transaction overhead for every pixel
int16_t fillwidth = 0;
int16_t fillwidth = 0;
int16_t fillheight = 0;
// Fill area above glyph
@ -438,6 +438,7 @@ void TFT_eSPI::drawGlyph(uint16_t code)
fillwidth = (cursor_x + gxAdvance[gNum]) - bg_cursor_x;
if (fillwidth > 0) {
fillheight = gFont.maxAscent - gdY[gNum];
// Could be negative
if (fillheight > 0) {
fillRect(bg_cursor_x, cursor_y, fillwidth, fillheight, textbgcolor);
}

View File

@ -3,7 +3,7 @@
public:
// These are for the new antialiased fonts
// These are for the new anti-aliased fonts
void loadFont(const uint8_t array[]);
#ifdef FONT_FS_AVAILABLE
void loadFont(String fontName, fs::FS &ffs);

View File

@ -423,7 +423,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, uint32_t transp)
if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F];
tpcolor = tpcolor>>8 | tpcolor<<8; // Working with swapped color bytes
}
_tft->startWrite(); // Avoid transaction overhead for every tft pixel
_tft->startWrite(); // Avoid transaction overhead for every tft pixel
// Scan destination bounding box and fetch transformed pixels from source Sprite
for (int32_t y = min_y; y <= max_y; y++, yt++) {
@ -441,7 +441,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, uint32_t transp)
int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; }
else { rp = readPixel(xp, yp); rp = (uint16_t)(rp>>8 | rp<<8); }
if (tpcolor == rp) {
if (transp != 0x00FFFFFF && tpcolor == rp) {
if (pixel_count) {
// TFT window is already clipped, so this is faster than pushImage()
_tft->setWindow(x - pixel_count, y, x - 1, y);
@ -517,7 +517,7 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp)
int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) rp = _img[xp + yp * _iwidth];
else { rp = readPixel(xp, yp); rp = (uint16_t)(rp>>8 | rp<<8); }
if (tpcolor == rp) {
if (transp != 0x00FFFFFF && tpcolor == rp) {
if (pixel_count) {
spr->pushImage(x - pixel_count, y, pixel_count, 1, sline_buffer);
pixel_count = 0;
@ -717,7 +717,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
// 16bpp -> 16bpp
// 16bpp -> 8bpp
// 8bpp -> 8bpp
// 4bpp -> 4bpp (note: color translation depends on the 2 sprites pallete colors)
// 4bpp -> 4bpp (note: color translation depends on the 2 sprites palette colors)
// 1bpp -> 1bpp (note: color translation depends on the 2 sprites bitmap colors)
bool TFT_eSprite::pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y)
@ -1555,7 +1555,7 @@ void TFT_eSprite::fillSprite(uint32_t color)
** Function name: width
** Description: Return the width of sprite
***************************************************************************************/
// Return the size of the display
// Return the size of the sprite
int16_t TFT_eSprite::width(void)
{
if (!_created ) return 0;
@ -1990,10 +1990,8 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
{
if ( _vpOoB || !_created ) return;
if ((x >= _vpW - _xDatum) || // Clip right
(y >= _vpH - _yDatum) || // Clip bottom
((x + 6 * size - 1) < (_vpX - _xDatum)) || // Clip left
((y + 8 * size - 1) < (_vpY - _yDatum))) // Clip top
if ((x >= _vpW - _xDatum) || // Clip right
(y >= _vpH - _yDatum)) // Clip bottom
return;
if (c < 32) return;
@ -2004,6 +2002,10 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
#endif
//>>>>>>>>>>>>>>>>>>
if (((x + 6 * size - 1) < (_vpX - _xDatum)) || // Clip left
((y + 8 * size - 1) < (_vpY - _yDatum))) // Clip top
return;
bool fillbg = (bg != color);
if ((size==1) && fillbg)
@ -2071,15 +2073,21 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
c -= pgm_read_word(&gfxFont->first);
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
uint32_t bo = pgm_read_word(&glyph->bitmapOffset);
uint8_t w = pgm_read_byte(&glyph->width),
h = pgm_read_byte(&glyph->height);
//xa = pgm_read_byte(&glyph->xAdvance);
int8_t xo = pgm_read_byte(&glyph->xOffset),
yo = pgm_read_byte(&glyph->yOffset);
if (((x + xo + w * size - 1) < (_vpX - _xDatum)) || // Clip left
((y + yo + h * size - 1) < (_vpY - _yDatum))) // Clip top
return;
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
uint32_t bo = pgm_read_word(&glyph->bitmapOffset);
uint8_t xx, yy, bits=0, bit=0;
//uint8_t xa = pgm_read_byte(&glyph->xAdvance);
int16_t xo16 = 0, yo16 = 0;
if(size > 1) {
@ -2119,6 +2127,12 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
#ifdef LOAD_GFXFF
} // End classic vs custom font
#endif
#else
#ifndef LOAD_GFXFF
color = color;
bg = bg;
size = size;
#endif
#endif
}
@ -2126,7 +2140,7 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
/***************************************************************************************
** Function name: drawChar
** Description: draw a unicode glyph onto the screen
** Description: draw a unicode glyph into the sprite
***************************************************************************************/
// TODO: Rationalise with TFT_eSPI
// Any UTF-8 decoding must be done before calling drawChar()
@ -2378,6 +2392,17 @@ int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t fo
}
// End of RLE font rendering
#endif
#if !defined (LOAD_FONT2) && !defined (LOAD_RLE)
// Stop warnings
flash_address = flash_address;
w = w;
pX = pX;
pY = pY;
line = line;
clip = clip;
#endif
return width * textsize; // x +
}
@ -2473,8 +2498,8 @@ void TFT_eSprite::drawGlyph(uint16_t code)
int16_t bx = 0;
uint8_t pixel = 0;
int16_t fillwidth = 0;
uint16_t fillheight = 0;
int16_t fillwidth = 0;
int16_t fillheight = 0;
// Fill area above glyph
if (_fillbg) {

View File

@ -16,9 +16,9 @@ class TFT_eSprite : public TFT_eSPI {
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
// RAM required is:
// - 1 bit per pixel for 1 bit colour depth
// - 1 nibble per pixel for 4 bit colour
// - 1 byte per pixel for 8 bit colour
// - 2 bytes per pixel for 16 bit color depth
// - 1 nibble per pixel for 4 bit colour (with palette table)
// - 1 byte per pixel for 8 bit colour (332 RGB format)
// - 2 bytes per pixel for 16 bit color depth (565 RGB format)
void* createSprite(int16_t width, int16_t height, uint8_t frames = 1);
// Returns a pointer to the sprite or nullptr if not created, user must cast to pointer type
@ -34,7 +34,7 @@ class TFT_eSprite : public TFT_eSPI {
// Returns a pointer to the Sprite frame buffer
void* frameBuffer(int8_t f);
// Set or get the colour depth to 4, 8 or 16 bits. Can be used to change depth an existing
// Set or get the colour depth to 1, 4, 8 or 16 bits. Can be used to change depth an existing
// sprite, but clears it to black, returns a new pointer if sprite is re-created.
void* setColorDepth(int8_t b);
int8_t getColorDepth(void);
@ -52,9 +52,11 @@ class TFT_eSprite : public TFT_eSPI {
// Set foreground and background colours for 1 bit per pixel Sprite
void setBitmapColor(uint16_t fg, uint16_t bg);
// Draw a single pixel at x,y
void drawPixel(int32_t x, int32_t y, uint32_t color);
void drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t font),
// Draw a single character in the GLCD or GFXFF font
void drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size),
// Fill Sprite with a colour
fillSprite(uint32_t color),
@ -62,18 +64,18 @@ class TFT_eSprite : public TFT_eSPI {
// Define a window to push 16 bit colour pixels into in a raster order
// Colours are converted to the set Sprite colour bit depth
setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1),
// Push a color (aka singe pixel) to the screen
// Push a color (aka singe pixel) to the sprite's set window area
pushColor(uint16_t color),
// Push len colors (pixels) to the screen
// Push len colors (pixels) to the sprite's set window area
pushColor(uint16_t color, uint32_t len),
// Push a pixel preformatted as a 8 or 16 bit colour (avoids conversion overhead)
// Push a pixel pre-formatted as a 1, 4, 8 or 16 bit colour (avoids conversion overhead)
writeColor(uint16_t color),
// Set the scroll zone, top left corner at x,y with defined width and height
// The colour (optional, black is default) is used to fill the gap after the scroll
setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color = TFT_BLACK),
// Scroll the defined zone dx,dy pixels. Negative values left,up, positive right,down
// dy is optional (default is then no up/down scroll).
// dy is optional (default is 0, so no up/down scroll).
// The sprite coordinate frame does not move because pixels are moved
scroll(int16_t dx, int16_t dy = 0),
@ -92,9 +94,9 @@ class TFT_eSprite : public TFT_eSPI {
uint8_t getRotation(void);
// Push a rotated copy of Sprite to TFT with optional transparent colour
bool pushRotated(int16_t angle, uint32_t transp = 0x00FFFFFF); // Using fixed point maths
bool pushRotated(int16_t angle, uint32_t transp = 0x00FFFFFF);
// Push a rotated copy of Sprite to another different Sprite with optional transparent colour
bool pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp = 0x00FFFFFF); // Using fixed point maths
bool pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp = 0x00FFFFFF);
// Get the TFT bounding box for a rotated copy of this Sprite
bool getRotatedBounds(int16_t angle, int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y);
@ -125,10 +127,10 @@ class TFT_eSprite : public TFT_eSPI {
bool pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int32_t sw, int32_t sh);
// Push the sprite to another sprite at x,y. This fn calls pushImage() in the destination sprite (dspr) class.
// >>>>>> Using a transparent color is not supported at the moment <<<<<<
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y);
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y, uint16_t transparent);
// Draw a single character in the selected font
int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y);
@ -137,9 +139,13 @@ class TFT_eSprite : public TFT_eSPI {
height(void);
// Functions associated with anti-aliased fonts
// Draw a single unicode character using the loaded font
void drawGlyph(uint16_t code);
// Print string to sprite using loaded font at cursor position
void printToSprite(String string);
// Print char array to sprite using loaded font at cursor position
void printToSprite(char *cbuffer, uint16_t len);
// Print indexed glyph to sprite using loaded font at x,y
int16_t printToSprite(int16_t x, int16_t y, uint16_t index);
private:
@ -155,19 +161,19 @@ class TFT_eSprite : public TFT_eSPI {
protected:
uint8_t _bpp; // bits per pixel (1, 8 or 16)
uint8_t _bpp; // bits per pixel (1, 4, 8 or 16)
uint16_t *_img; // pointer to 16 bit sprite
uint8_t *_img8; // pointer to 8 bit sprite frame 1 or frame 2
uint8_t *_img8; // pointer to 1 and 8 bit sprite frame 1 or frame 2
uint8_t *_img4; // pointer to 4 bit sprite (uses color map)
uint8_t *_img8_1; // pointer to frame 1
uint8_t *_img8_2; // pointer to frame 2
uint16_t *_colorMap; // color map: 16 entries, used with 4 bit color map.
uint16_t *_colorMap; // color map pointer: 16 entries, used with 4 bit color map.
int32_t _sinra;
int32_t _cosra;
int32_t _sinra; // Sine of rotation angle in fixed point
int32_t _cosra; // Cosine of rotation angle in fixed point
bool _created; // A Sprite has been created and memory reserved
bool _created; // A Sprite has been created and memory reserved
bool _gFont = false;
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow
@ -176,7 +182,7 @@ class TFT_eSprite : public TFT_eSPI {
uint32_t _scolor; // gap fill colour for scroll zone
int32_t _iwidth, _iheight; // Sprite memory image bit width and height (swapped during rotations)
int32_t _dwidth, _dheight; // Real display width and height (for <8bpp Sprites)
int32_t _dwidth, _dheight; // Real sprite width and height (for <8bpp Sprites)
int32_t _bitwidth; // Sprite image bit width for drawPixel (for <8bpp Sprites, not swapped)
};

View File

@ -28,9 +28,12 @@
// SPI PIO code for 16 bit colour transmit
#include "pio_SPI.pio.h"
#endif
#else
#elif defined (TFT_PARALLEL_8_BIT)
// SPI PIO code for 8 bit parallel interface (16 bit colour)
#include "pio_8bit_parallel.pio.h"
#else // must be TFT_PARALLEL_16_BIT
// SPI PIO code for 16 bit parallel interface (16 bit colour)
#include "pio_16bit_parallel.pio.h"
#endif
// Board package specific differences
@ -189,7 +192,7 @@ void pioinit(uint32_t clock_freq) {
pio_instr_set_dc = pio_encode_set((pio_src_dest)0, 1);
pio_instr_clr_dc = pio_encode_set((pio_src_dest)0, 0);
}
#else
#else // 8 or 16 bit parallel
void pioinit(uint16_t clock_div, uint16_t fract_div) {
// Find a free SM on one of the PIO's
@ -212,21 +215,27 @@ void pioinit(uint16_t clock_div, uint16_t fract_div) {
}
}
*/
#if defined (TFT_PARALLEL_8_BIT)
uint8_t bits = 8;
#else // must be TFT_PARALLEL_16_BIT
uint8_t bits = 16;
#endif
// Load the PIO program
program_offset = pio_add_program(tft_pio, &tft_io_program);
// Associate pins with the PIO
pio_gpio_init(tft_pio, TFT_DC);
pio_gpio_init(tft_pio, TFT_WR);
for (int i = 0; i < 8; i++) {
for (int i = 0; i < bits; i++) {
pio_gpio_init(tft_pio, TFT_D0 + i);
}
// Configure the pins to be outputs
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_DC, 1, true);
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_WR, 1, true);
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_D0, 8, true);
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_D0, bits, true);
// Configure the state machine
pio_sm_config c = tft_io_program_get_default_config(program_offset);
@ -234,8 +243,8 @@ void pioinit(uint16_t clock_div, uint16_t fract_div) {
sm_config_set_set_pins(&c, TFT_DC, 1);
// Define the single side-set pin
sm_config_set_sideset_pins(&c, TFT_WR);
// Define the 8 consecutive pins that are used for data output
sm_config_set_out_pins(&c, TFT_D0, 8);
// Define the consecutive pins that are used for data output
sm_config_set_out_pins(&c, TFT_D0, bits);
// Set clock divider and fractional divider
sm_config_set_clkdiv_int_frac(&c, clock_div, fract_div);
// Make a single 8 words FIFO from the 4 words TX and RX FIFOs

View File

@ -30,7 +30,7 @@
// Include processor specific header
// None
#if defined (TFT_PARALLEL_8_BIT) || defined (RP2040_PIO_SPI)
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RP2040_PIO_SPI)
#define RP2040_PIO_INTERFACE
#define RP2040_PIO_PUSHBLOCK
#endif
@ -80,18 +80,33 @@
#endif
#else
// ILI9481 needs a slower cycle time
// Byte rate = (CPU clock/(4 * divider))
#ifdef ILI9481_DRIVER
#define DIV_UNITS 1
#define DIV_FRACT 160
#else
#define DIV_UNITS 1
#define DIV_FRACT 0
// Different controllers have different minimum write cycle periods, so the PIO clock is changed accordingly
// The PIO clock is a division of the CPU clock so scales when the processor is overclocked
// PIO write frequency = (CPU clock/(4 * DIV_UNITS))
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RP2040_PIO_SPI)
#if defined (TFT_PARALLEL_16_BIT)
// Different display drivers have different minimum write cycle times
#if defined (HX8357C_DRIVER) || defined (SSD1963_DRIVER)
#define DIV_UNITS 1 // 32ns write cycle time SSD1963, HX8357C (maybe HX8357D?)
#elif defined (ILI9486_DRIVER) || defined (HX8357B_DRIVER) || defined (HX8357D_DRIVER)
#define DIV_UNITS 2 // 64ns write cycle time ILI9486, HX8357D, HX8357B
#else // ILI9481 needs a slower cycle time
#define DIV_UNITS 3 // 96ns write cycle time
#endif
#define DIV_FRACT 0
#else // 8 bit parallel mode
#ifdef ILI9481_DRIVER
#define DIV_UNITS 1
#define DIV_FRACT 160 // Note: Fractional values done with clock period dithering
#else
#define DIV_UNITS 1
#define DIV_FRACT 0
#endif
#endif
#endif
// Initialise TFT data bus
#if defined (TFT_PARALLEL_8_BIT)
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
#define INIT_TFT_DATA_BUS pioinit(DIV_UNITS, DIV_FRACT);
#elif defined (RP2040_PIO_SPI)
#define INIT_TFT_DATA_BUS pioinit(SPI_FREQUENCY);
@ -184,7 +199,7 @@
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT) // SPI
#if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT) // SPI
#ifdef TFT_WR
#define WR_L digitalWrite(TFT_WR, LOW)
#define WR_H digitalWrite(TFT_WR, HIGH)
@ -384,13 +399,18 @@
#define tft_Write_32D(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (((C)<<8) | ((C)>>8)); tft_Write_8L(C)
#else
// This writes 8 bits, then switches back to 16 bit mode automatically
// Have already waited for pio stalled (last data write complete) when DC switched to command mode
// The wait for stall allows DC to be changed immediately afterwards
#else // PIO interface, SPI or parallel
// This writes 8 bits, then switches back to 16 bit mode automatically
// Have already waited for pio stalled (last data write complete) when DC switched to command mode
// The wait for stall allows DC to be changed immediately afterwards
#if defined (TFT_PARALLEL_8_BIT) || defined (RP2040_PIO_SPI)
#define tft_Write_8(C) tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
TX_FIFO = (C); \
WAIT_FOR_STALL
#else // For 16 bit parallel 16 bits are always sent
#define tft_Write_8(C) TX_FIFO = (C); \
WAIT_FOR_STALL
#endif
// Note: the following macros do not wait for the end of transmission

Some files were not shown because too many files have changed in this diff Show More