mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-08-05 21:54:42 +02:00
Minor performance improvements for ESP32
Remove legacy changes for double buffered SPI Eliminate unecessary ESP32 SPI read/modify write Eliminate two stage control bit changes (may impact some diplays with setup/hold timing and show ESP32 hardware register bug?) Add single register write for CS and DC command Make setAddrWindow smarter (as used in previous AVR library) Improve compatibility with GFX sketches Re-arrange comments slightly to improve positioning
This commit is contained in:
@@ -78,6 +78,12 @@ void TFT_eSPI::loadFont(String fontName)
|
||||
|
||||
_gFontFilename = "/" + fontName + ".vlw";
|
||||
|
||||
// Avoid a crash on the ESP32 if the file does not exist
|
||||
if (SPIFFS.exists(_gFontFilename) == false) {
|
||||
Serial.println("Font file " + fontName + " not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
fontFile = SPIFFS.open( _gFontFilename, "r");
|
||||
|
||||
if(!fontFile) return;
|
||||
@@ -479,7 +485,6 @@ void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
void TFT_eSPI::showFont(uint32_t td)
|
||||
{
|
||||
if(!fontLoaded) return;
|
||||
// fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||
|
||||
if(!fontFile)
|
||||
{
|
||||
|
@@ -9,15 +9,15 @@
|
||||
|
||||
|
||||
// Enumerate the different configurations
|
||||
#define INITR_GREENTAB 0x0
|
||||
#define INITR_REDTAB 0x1
|
||||
#define INITR_BLACKTAB 0x2
|
||||
#define INITR_GREENTAB2 0x3 // Use if you get random pixels on two edges of green tab display
|
||||
#define INITR_GREENTAB3 0x4 // Use if you get random pixels on edge(s) of 128x128 screen
|
||||
#define INITR_GREENTAB128 0x5 // Use if you only get part of 128x128 screen in rotation 0 & 1
|
||||
#define INITR_GREENTAB 0x0
|
||||
#define INITR_REDTAB 0x1
|
||||
#define INITR_BLACKTAB 0x2 // Display with no offsets
|
||||
#define INITR_GREENTAB2 0x3 // Use if you get random pixels on two edges of green tab display
|
||||
#define INITR_GREENTAB3 0x4 // Use if you get random pixels on edge(s) of 128x128 screen
|
||||
#define INITR_GREENTAB128 0x5 // Use if you only get part of 128x128 screen in rotation 0 & 1
|
||||
#define INITR_GREENTAB160x80 0x6 // Use if you only get part of 128x128 screen in rotation 0 & 1
|
||||
#define INITR_REDTAB160x80 0x7 // Added for https://www.aliexpress.com/item/ShengYang-1pcs-IPS-0-96-inch-7P-SPI-HD-65K-Full-Color-OLED-Module-ST7735-Drive/32918394604.html
|
||||
#define INITB 0xB
|
||||
#define INITR_REDTAB160x80 0x7 // Added for https://www.aliexpress.com/item/ShengYang-1pcs-IPS-0-96-inch-7P-SPI-HD-65K-Full-Color-OLED-Module-ST7735-Drive/32918394604.html
|
||||
#define INITB 0xB
|
||||
|
||||
|
||||
// Setup the tab color that will be used by the library setRotation() and setup command list
|
||||
|
238
TFT_eSPI.cpp
238
TFT_eSPI.cpp
@@ -185,8 +185,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
|
||||
|
||||
_booted = true;
|
||||
|
||||
addr_row = 0xFFFF;
|
||||
addr_col = 0xFFFF;
|
||||
ys_row = ye_row = addr_row = 0xFFFF;
|
||||
xs_col = xe_col = addr_col = 0xFFFF;
|
||||
|
||||
#ifdef LOAD_GLCD
|
||||
fontsloaded = 0x0002; // Bit 1 set
|
||||
@@ -530,7 +530,7 @@ uint8_t TFT_eSPI::readcommand8(uint8_t cmd_function, uint8_t index)
|
||||
CS_L;
|
||||
tft_Write_8(cmd_function);
|
||||
DC_D;
|
||||
reg = tft_Write_8(0);
|
||||
reg = tft_Read_8(0);
|
||||
CS_H;
|
||||
|
||||
spi_end_read();
|
||||
@@ -628,15 +628,15 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
|
||||
// Read the 3 RGB bytes, colour is actually only in the top 6 bits of each byte
|
||||
// as the TFT stores colours as 18 bits
|
||||
#if !defined (ILI9488_DRIVER)
|
||||
uint8_t r = tft_Write_8(0);
|
||||
uint8_t g = tft_Write_8(0);
|
||||
uint8_t b = tft_Write_8(0);
|
||||
uint8_t r = tft_Read_8(0);
|
||||
uint8_t g = tft_Read_8(0);
|
||||
uint8_t b = tft_Read_8(0);
|
||||
#else
|
||||
// The 6 colour bits are in MS 6 bits of each byte, but the ILI9488 needs an extra clock pulse
|
||||
// so bits appear shifted right 1 bit, so mask the middle 6 bits then shift 1 place left
|
||||
uint8_t r = (tft_Write_8(0)&0x7E)<<1;
|
||||
uint8_t g = (tft_Write_8(0)&0x7E)<<1;
|
||||
uint8_t b = (tft_Write_8(0)&0x7E)<<1;
|
||||
uint8_t r = (tft_Read_8(0)&0x7E)<<1;
|
||||
uint8_t g = (tft_Read_8(0)&0x7E)<<1;
|
||||
uint8_t b = (tft_Read_8(0)&0x7E)<<1;
|
||||
#endif
|
||||
|
||||
CS_H;
|
||||
@@ -768,15 +768,15 @@ void TFT_eSPI::readRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint16_t
|
||||
// Read the 3 RGB bytes, colour is actually only in the top 6 bits of each byte
|
||||
// as the TFT stores colours as 18 bits
|
||||
#if !defined (ILI9488_DRIVER)
|
||||
uint8_t r = tft_Write_8(0);
|
||||
uint8_t g = tft_Write_8(0);
|
||||
uint8_t b = tft_Write_8(0);
|
||||
uint8_t r = tft_Read_8(0);
|
||||
uint8_t g = tft_Read_8(0);
|
||||
uint8_t b = tft_Read_8(0);
|
||||
#else
|
||||
// The 6 colour bits are in LS 6 bits of each byte but we do not include the extra clock pulse
|
||||
// so we use a trick and mask the middle 6 bits of the byte, then only shift 1 place left
|
||||
uint8_t r = (tft_Write_8(0)&0x7E)<<1;
|
||||
uint8_t g = (tft_Write_8(0)&0x7E)<<1;
|
||||
uint8_t b = (tft_Write_8(0)&0x7E)<<1;
|
||||
uint8_t r = (tft_Read_8(0)&0x7E)<<1;
|
||||
uint8_t g = (tft_Read_8(0)&0x7E)<<1;
|
||||
uint8_t b = (tft_Read_8(0)&0x7E)<<1;
|
||||
#endif
|
||||
|
||||
// Swapped colour byte order for compatibility with pushRect()
|
||||
@@ -1354,15 +1354,15 @@ void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_
|
||||
// Read the 3 RGB bytes, colour is actually only in the top 6 bits of each byte
|
||||
// as the TFT stores colours as 18 bits
|
||||
#if !defined (ILI9488_DRIVER)
|
||||
*data++ = tft_Write_8(0);
|
||||
*data++ = tft_Write_8(0);
|
||||
*data++ = tft_Write_8(0);
|
||||
*data++ = tft_Read_8(0);
|
||||
*data++ = tft_Read_8(0);
|
||||
*data++ = tft_Read_8(0);
|
||||
#else
|
||||
// The 6 colour bits are in MS 6 bits of each byte, but the ILI9488 needs an extra clock pulse
|
||||
// so bits appear shifted right 1 bit, so mask the middle 6 bits then shift 1 place left
|
||||
*data++ = (tft_Write_8(0)&0x7E)<<1;
|
||||
*data++ = (tft_Write_8(0)&0x7E)<<1;
|
||||
*data++ = (tft_Write_8(0)&0x7E)<<1;
|
||||
*data++ = (tft_Read_8(0)&0x7E)<<1;
|
||||
*data++ = (tft_Read_8(0)&0x7E)<<1;
|
||||
*data++ = (tft_Read_8(0)&0x7E)<<1;
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -2473,7 +2473,7 @@ void TFT_eSPI::setWindow(int16_t x0, int16_t y0, int16_t x1, int16_t y1)
|
||||
// Chip select stays low, use setWindow() from sketches
|
||||
|
||||
#if defined (ESP8266) && !defined (RPI_WRITE_STROBE) && !defined (RPI_ILI9486_DRIVER)
|
||||
inline void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
|
||||
void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
|
||||
{
|
||||
//spi_begin();
|
||||
|
||||
@@ -2563,8 +2563,8 @@ void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
|
||||
|
||||
DC_D;
|
||||
|
||||
uint8_t xBin[] = { 0, (uint8_t) (xs>>8), 0, (uint8_t) (xs>>0), 0, (uint8_t) (xe>>8), 0, (uint8_t) (xe>>0), };
|
||||
SPI.writePattern(&xBin[0], 8, 1);
|
||||
uint8_t xb[] = { 0, (uint8_t) (xs>>8), 0, (uint8_t) (xs>>0), 0, (uint8_t) (xe>>8), 0, (uint8_t) (xe>>0), };
|
||||
SPI.writePattern(&xb[0], 8, 1);
|
||||
|
||||
// Row addr set
|
||||
DC_C;
|
||||
@@ -2577,8 +2577,8 @@ void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
|
||||
|
||||
DC_D;
|
||||
|
||||
uint8_t yBin[] = { 0, (uint8_t) (ys>>8), 0, (uint8_t) (ys>>0), 0, (uint8_t) (ye>>8), 0, (uint8_t) (ye>>0), };
|
||||
SPI.writePattern(&yBin[0], 8, 1);
|
||||
uint8_t yb[] = { 0, (uint8_t) (ys>>8), 0, (uint8_t) (ys>>0), 0, (uint8_t) (ye>>8), 0, (uint8_t) (ye>>0), };
|
||||
SPI.writePattern(&yb[0], 8, 1);
|
||||
|
||||
// write to RAM
|
||||
DC_C;
|
||||
@@ -2596,7 +2596,7 @@ void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
|
||||
#else
|
||||
|
||||
#if defined (ESP8266) && defined (RPI_ILI9486_DRIVER) // This is for the RPi display that needs 16 bits
|
||||
inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
|
||||
void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
|
||||
{
|
||||
//spi_begin();
|
||||
|
||||
@@ -2673,7 +2673,7 @@ inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t
|
||||
|
||||
#else // This is for the ESP32
|
||||
|
||||
inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
|
||||
void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
|
||||
{
|
||||
//spi_begin();
|
||||
|
||||
@@ -2687,42 +2687,48 @@ inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t
|
||||
y1+=rowstart;
|
||||
#endif
|
||||
|
||||
#if !defined (RPI_ILI9486_DRIVER)
|
||||
uint32_t xaw = ((uint32_t)x0 << 16) | x1;
|
||||
uint32_t yaw = ((uint32_t)y0 << 16) | y1;
|
||||
#endif
|
||||
CS_L_DC_C;
|
||||
|
||||
// Column addr set
|
||||
DC_C;
|
||||
CS_L;
|
||||
// No need to send x if it has not changed (small speed-up of complex transparent Sprites and bitmaps)
|
||||
// Nb: caller must fill the set address area so that setting same area again will fill from xs, ys
|
||||
if (xs_col != x0 || xe_col != x1) {
|
||||
// Column addr set
|
||||
|
||||
tft_Write_8(TFT_CASET);
|
||||
tft_Write_8(TFT_CASET);
|
||||
|
||||
DC_D;
|
||||
DC_D;
|
||||
|
||||
#if defined (RPI_ILI9486_DRIVER)
|
||||
uint8_t xBin[] = { 0, (uint8_t) (x0>>8), 0, (uint8_t) (x0>>0), 0, (uint8_t) (x1>>8), 0, (uint8_t) (x1>>0), };
|
||||
SPI.writePattern(&xBin[0], 8, 1);
|
||||
uint8_t xb[] = { 0, (uint8_t) (x0>>8), 0, (uint8_t) (x0>>0), 0, (uint8_t) (x1>>8), 0, (uint8_t) (x1>>0), };
|
||||
SPI.writePattern(&xb[0], 8, 1);
|
||||
#else
|
||||
tft_Write_32(xaw);
|
||||
tft_Write_32(SPI_32(x0, x1));
|
||||
#endif
|
||||
|
||||
// Row addr set
|
||||
DC_C;
|
||||
tft_Write_8(TFT_PASET);
|
||||
DC_C;
|
||||
xs_col = x0; xe_col = x1;
|
||||
}
|
||||
|
||||
DC_D;
|
||||
// No need to send y if it has not changed
|
||||
if (ys_row != y0 || ye_row != y1) {
|
||||
|
||||
// Row addr set
|
||||
tft_Write_8(TFT_PASET);
|
||||
|
||||
DC_D;
|
||||
|
||||
#if defined (RPI_ILI9486_DRIVER)
|
||||
uint8_t yBin[] = { 0, (uint8_t) (y0>>8), 0, (uint8_t) (y0>>0), 0, (uint8_t) (y1>>8), 0, (uint8_t) (y1>>0), };
|
||||
SPI.writePattern(&yBin[0], 8, 1);
|
||||
uint8_t yb[] = { 0, (uint8_t) (y0>>8), 0, (uint8_t) (y0>>0), 0, (uint8_t) (y1>>8), 0, (uint8_t) (y1>>0), };
|
||||
SPI.writePattern(&yb[0], 8, 1);
|
||||
#else
|
||||
tft_Write_32(yaw);
|
||||
tft_Write_32(SPI_32(y0, y1));
|
||||
#endif
|
||||
|
||||
DC_C;
|
||||
ys_row = y0; ye_row = y1;
|
||||
}
|
||||
|
||||
// write to RAM
|
||||
DC_C;
|
||||
|
||||
tft_Write_8(TFT_RAMWR);
|
||||
|
||||
DC_D;
|
||||
@@ -2819,19 +2825,15 @@ void TFT_eSPI::readAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
|
||||
y1+=rowstart;
|
||||
#endif
|
||||
|
||||
uint32_t xaw = ((uint32_t)x0 << 16) | x1;
|
||||
uint32_t yaw = ((uint32_t)y0 << 16) | y1;
|
||||
|
||||
// Column addr set
|
||||
DC_C;
|
||||
CS_L;
|
||||
CS_L_DC_C;
|
||||
|
||||
tft_Write_8(TFT_CASET);
|
||||
|
||||
|
||||
DC_D;
|
||||
|
||||
tft_Write_32(xaw);
|
||||
tft_Write_32(SPI_32(x0, x1));
|
||||
|
||||
// Row addr set
|
||||
DC_C;
|
||||
@@ -2840,7 +2842,7 @@ void TFT_eSPI::readAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
|
||||
|
||||
DC_D;
|
||||
|
||||
tft_Write_32(yaw);
|
||||
tft_Write_32(SPI_32(y0, y1));
|
||||
|
||||
DC_C;
|
||||
tft_Write_8(TFT_RAMRD); // Read CGRAM command
|
||||
@@ -3053,52 +3055,49 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
|
||||
y+=rowstart;
|
||||
#endif
|
||||
|
||||
#if !defined (RPI_ILI9486_DRIVER)
|
||||
uint32_t xaw = ((uint32_t)x << 16) | x;
|
||||
uint32_t yaw = ((uint32_t)y << 16) | y;
|
||||
#endif
|
||||
|
||||
CS_L;
|
||||
CS_L_DC_C;
|
||||
|
||||
// No need to send x if it has not changed (speeds things up)
|
||||
if (addr_col != x) {
|
||||
|
||||
DC_C;
|
||||
|
||||
tft_Write_8(TFT_CASET);
|
||||
|
||||
DC_D;
|
||||
|
||||
#if defined (RPI_ILI9486_DRIVER)
|
||||
uint8_t xBin[] = { 0, (uint8_t) (x>>8), 0, (uint8_t) (x>>0), 0, (uint8_t) (x>>8), 0, (uint8_t) (x>>0), };
|
||||
SPI.writePattern(&xBin[0], 8, 1);
|
||||
uint8_t xb[] = { 0, (uint8_t) (x>>8), 0, (uint8_t) (x>>0), 0, (uint8_t) (x>>8), 0, (uint8_t) (x>>0), };
|
||||
SPI.writePattern(&xb[0], 8, 1);
|
||||
#else
|
||||
tft_Write_32(xaw);
|
||||
tft_Write_32(SPI_32(x, x));
|
||||
#endif
|
||||
|
||||
|
||||
DC_C;
|
||||
|
||||
addr_col = x;
|
||||
xs_col = xe_col = x;
|
||||
|
||||
}
|
||||
|
||||
// No need to send y if it has not changed (speeds things up)
|
||||
if (addr_row != y) {
|
||||
|
||||
DC_C;
|
||||
|
||||
tft_Write_8(TFT_PASET);
|
||||
|
||||
DC_D;
|
||||
|
||||
#if defined (RPI_ILI9486_DRIVER)
|
||||
uint8_t yBin[] = { 0, (uint8_t) (y>>8), 0, (uint8_t) (y>>0), 0, (uint8_t) (y>>8), 0, (uint8_t) (y>>0), };
|
||||
SPI.writePattern(&yBin[0], 8, 1);
|
||||
uint8_t yb[] = { 0, (uint8_t) (y>>8), 0, (uint8_t) (y>>0), 0, (uint8_t) (y>>8), 0, (uint8_t) (y>>0), };
|
||||
SPI.writePattern(&yb[0], 8, 1);
|
||||
#else
|
||||
tft_Write_32(yaw);
|
||||
tft_Write_32(SPI_32(y, y));
|
||||
#endif
|
||||
|
||||
DC_C;
|
||||
|
||||
addr_row = y;
|
||||
ys_row = ye_row = y;
|
||||
}
|
||||
|
||||
DC_C;
|
||||
|
||||
tft_Write_8(TFT_RAMWR);
|
||||
|
||||
@@ -3159,6 +3158,48 @@ void TFT_eSPI::pushColor(uint16_t color, uint32_t len)
|
||||
spi_end();
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: startWrite
|
||||
** Description: begin transaction with CS low, MUST later call endWrite
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::startWrite(void)
|
||||
{
|
||||
spi_begin();
|
||||
|
||||
CS_L;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: endWrite
|
||||
** Description: end transaction with CS high
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::endWrite(void)
|
||||
{
|
||||
|
||||
CS_H;
|
||||
|
||||
spi_end();
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: writeColor (use startWrite() and endWrite() before & after)
|
||||
** Description: raw write of "len" pixels avoiding transaction check
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::writeColor(uint16_t color, uint32_t len)
|
||||
{
|
||||
#ifdef RPI_WRITE_STROBE
|
||||
uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
|
||||
if(len) SPI.writePattern(&colorBin[0], 2, 1); len--;
|
||||
while(len--) {WR_L; WR_H;}
|
||||
#else
|
||||
#if defined (ESP32_PARALLEL)
|
||||
while (len--) {tft_Write_16(color);}
|
||||
#else
|
||||
writeBlock(color, len);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushColors
|
||||
** Description: push an array of pixels for 16 bit raw image drawing
|
||||
@@ -4655,7 +4696,7 @@ void writeBlock(uint16_t color, uint32_t repeat)
|
||||
#elif defined (ILI9488_DRIVER)
|
||||
|
||||
#ifdef ESP8266
|
||||
void writeBlock(uint16_t color, uint32_t repeat)
|
||||
void TFT_eSPI::writeBlock(uint16_t color, uint32_t repeat)
|
||||
{
|
||||
|
||||
uint32_t mask = ~(SPIMMOSI << SPILMOSI);
|
||||
@@ -4722,9 +4763,6 @@ void writeBlock(uint16_t color, uint32_t repeat)
|
||||
}
|
||||
#else // Now the code for ESP32 and ILI9488
|
||||
|
||||
#include "soc/spi_reg.h"
|
||||
#define SPI_NUM 0x3
|
||||
|
||||
void writeBlock(uint16_t color, uint32_t repeat)
|
||||
{
|
||||
// Split out the colours
|
||||
@@ -4795,38 +4833,46 @@ void writeBlock(uint16_t color, uint32_t repeat)
|
||||
|
||||
#else // Low level register based ESP32 code for 16 bit colour SPI TFTs
|
||||
|
||||
#include "soc/spi_reg.h"
|
||||
#define SPI_NUM 0x3
|
||||
|
||||
|
||||
void writeBlock(uint16_t color, uint32_t repeat)
|
||||
{
|
||||
uint16_t color16 = (color >> 8) | (color << 8);
|
||||
uint32_t color32 = color16 | color16 << 16;
|
||||
uint32_t color32 = SPI_32(color, color);
|
||||
|
||||
if (repeat > 15)
|
||||
if (repeat > 31) // Revert legacy toggle buffer change
|
||||
{
|
||||
SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_NUM), SPI_USR_MOSI_DBITLEN, 255, SPI_USR_MOSI_DBITLEN_S);
|
||||
|
||||
while(repeat>15)
|
||||
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_NUM), 511);
|
||||
while(repeat>31)
|
||||
{
|
||||
while (READ_PERI_REG(SPI_CMD_REG(SPI_NUM))&SPI_USR);
|
||||
for (uint32_t i=0; i<8; i++) WRITE_PERI_REG((SPI_W0_REG(SPI_NUM) + (i << 2)), color32);
|
||||
WRITE_PERI_REG(SPI_W0_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W1_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W2_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W3_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W4_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W5_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W6_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W7_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W8_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W9_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W10_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W11_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W12_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W13_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W14_REG(SPI_NUM), color32);
|
||||
WRITE_PERI_REG(SPI_W15_REG(SPI_NUM), color32);
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_NUM), SPI_USR);
|
||||
repeat -= 16;
|
||||
repeat -= 32;
|
||||
}
|
||||
while (READ_PERI_REG(SPI_CMD_REG(SPI_NUM))&SPI_USR);
|
||||
}
|
||||
|
||||
if (repeat)
|
||||
{
|
||||
repeat = (repeat << 4) - 1;
|
||||
SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_NUM), SPI_USR_MOSI_DBITLEN, repeat, SPI_USR_MOSI_DBITLEN_S);
|
||||
for (uint32_t i=0; i<8; i++) WRITE_PERI_REG((SPI_W0_REG(SPI_NUM) + (i << 2)), color32);
|
||||
// Revert toggle buffer change
|
||||
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_NUM), (repeat << 4) - 1);
|
||||
for (uint32_t i=0; i <= (repeat>>1); i++) WRITE_PERI_REG((SPI_W0_REG(SPI_NUM) + (i << 2)), color32);
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_NUM), SPI_USR);
|
||||
while (READ_PERI_REG(SPI_CMD_REG(SPI_NUM))&SPI_USR);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4975,10 +5021,6 @@ void TFT_eSPI::getSetup(setup_t &tft_settings)
|
||||
|
||||
#include "Extensions/Sprite.cpp"
|
||||
|
||||
// #ifdef ESP32
|
||||
// #include "Extensions/pSprite.cpp"
|
||||
// #endif
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
#include "Extensions/Smooth_font.cpp"
|
||||
#endif
|
||||
|
130
TFT_eSPI.h
130
TFT_eSPI.h
@@ -103,6 +103,11 @@
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#ifdef ESP32
|
||||
#include "soc/spi_reg.h"
|
||||
#define SPI_NUM 0x3
|
||||
#endif
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
// Call up the SPIFFS FLASH filing system for the anti-aliased fonts
|
||||
#define FS_NO_GLOBALS
|
||||
@@ -127,16 +132,16 @@
|
||||
|
||||
#else
|
||||
#if TFT_DC >= 32
|
||||
#define DC_C GPIO.out1_w1ts.val = (1 << (TFT_DC - 32)); \
|
||||
GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
|
||||
#define DC_D GPIO.out1_w1tc.val = (1 << (TFT_DC - 32)); \
|
||||
GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
|
||||
#define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC - 32)); //\
|
||||
//GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
|
||||
#define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32)); //\
|
||||
//GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
|
||||
#else
|
||||
#if TFT_DC >= 0
|
||||
#define DC_C GPIO.out_w1ts = (1 << TFT_DC); \
|
||||
GPIO.out_w1tc = (1 << TFT_DC)
|
||||
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
|
||||
GPIO.out_w1ts = (1 << TFT_DC)
|
||||
#define DC_C GPIO.out_w1tc = (1 << TFT_DC); //\
|
||||
//GPIO.out_w1tc = (1 << TFT_DC)
|
||||
#define DC_D GPIO.out_w1ts = (1 << TFT_DC); //\
|
||||
//GPIO.out_w1ts = (1 << TFT_DC)
|
||||
#else
|
||||
#define DC_C
|
||||
#define DC_D
|
||||
@@ -166,14 +171,14 @@
|
||||
#define CS_H
|
||||
#else
|
||||
#if TFT_CS >= 32
|
||||
#define CS_L GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)); \
|
||||
GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
|
||||
#define CS_H GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); \
|
||||
GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
|
||||
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); //\
|
||||
//GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
|
||||
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)); //\
|
||||
//GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
|
||||
#else
|
||||
#if TFT_CS >= 0
|
||||
#define CS_L GPIO.out_w1ts = (1 << TFT_CS);GPIO.out_w1tc = (1 << TFT_CS)
|
||||
#define CS_H GPIO.out_w1tc = (1 << TFT_CS);GPIO.out_w1ts = (1 << TFT_CS)
|
||||
#define CS_L GPIO.out_w1tc = (1 << TFT_CS); //GPIO.out_w1tc = (1 << TFT_CS)
|
||||
#define CS_H GPIO.out_w1ts = (1 << TFT_CS); //GPIO.out_w1ts = (1 << TFT_CS)
|
||||
#else
|
||||
#define CS_L
|
||||
#define CS_H
|
||||
@@ -186,6 +191,18 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Use single register write for CS_L and DC_C if pins are both in range 0-31
|
||||
#ifdef ESP32
|
||||
#if (TFT_CS >= 0) && (TFT_CS < 32) && (TFT_DC >= 0) && (TFT_DC < 32)
|
||||
#define CS_L_DC_C GPIO.out_w1tc = ((1 << TFT_CS) | (1 << TFT_DC)); //\
|
||||
//GPIO.out_w1tc = ((1 << TFT_CS) | (1 << TFT_DC))
|
||||
#else
|
||||
#define CS_L_DC_C CS_L; DC_C
|
||||
#endif
|
||||
#else // ESP8266
|
||||
#define CS_L_DC_C CS_L; DC_C
|
||||
#endif
|
||||
|
||||
// chip select signal for touchscreen
|
||||
#ifndef TOUCH_CS
|
||||
#define T_CS_L // No macro allocated so it generates no code
|
||||
@@ -206,6 +223,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
// Concatenate two 16 bit values for the SPI 32 bit register write
|
||||
#define SPI_32(H,L) ( (H)<<16 | (L) )
|
||||
#else
|
||||
// Swap byte order for concatenated 16 bit window address or colors
|
||||
// AB CD -> DCBA for SPI 32 bit register write
|
||||
#define SPI_32(H,L) ( ((H)<<8 | (H)>>8) | (((L)<<8 | (L)>>8)<<16 ) )
|
||||
#endif
|
||||
|
||||
#if defined (ESP32) && defined (ESP32_PARALLEL)
|
||||
// Mask for the 8 data bits to set pin directions
|
||||
@@ -253,34 +278,75 @@
|
||||
#elif defined (ILI9488_DRIVER) // 16 bit colour converted to 3 bytes for 18 bit RGB
|
||||
|
||||
// Write 8 bits to TFT
|
||||
#define tft_Write_8(C) SPI.transfer(C)
|
||||
#define tft_Write_8(C) SPI.transfer(C)
|
||||
|
||||
// Convert 16 bit colour to 18 bit and write in 3 bytes
|
||||
#define tft_Write_16(C) SPI.transfer((C & 0xF800)>>8); \
|
||||
SPI.transfer((C & 0x07E0)>>3); \
|
||||
SPI.transfer((C & 0x001F)<<3)
|
||||
#define tft_Write_16(C) SPI.transfer((C & 0xF800)>>8); \
|
||||
SPI.transfer((C & 0x07E0)>>3); \
|
||||
SPI.transfer((C & 0x001F)<<3)
|
||||
|
||||
// Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
|
||||
#define tft_Write_16S(C) SPI.transfer(C & 0xF8); \
|
||||
SPI.transfer((C & 0xE0)>>11 | (C & 0x07)<<5); \
|
||||
SPI.transfer((C & 0x1F00)>>5)
|
||||
// Write 32 bits to TFT
|
||||
#define tft_Write_32(C) SPI.write32(C)
|
||||
#define tft_Write_32(C) SPI.write32(C)
|
||||
|
||||
#elif defined (RPI_ILI9486_DRIVER)
|
||||
|
||||
#define tft_Write_8(C) SPI.transfer(0); SPI.transfer(C)
|
||||
#define tft_Write_16(C) SPI.write16(C)
|
||||
#define tft_Write_32(C) SPI.write32(C)
|
||||
#define tft_Write_8(C) SPI.transfer(0); SPI.transfer(C)
|
||||
#define tft_Write_16(C) SPI.write16(C)
|
||||
#define tft_Write_16S(C) SPI.write16(C<<8 | C>>8)
|
||||
#define tft_Write_32(C) SPI.write32(C)
|
||||
|
||||
#else
|
||||
#elif defined ESP8266
|
||||
|
||||
#define tft_Write_8(C) SPI.transfer(C)
|
||||
#define tft_Write_16(C) SPI.write16(C)
|
||||
#define tft_Write_32(C) SPI.write32(C)
|
||||
#define tft_Write_8(C) SPI.write(C)
|
||||
#define tft_Write_16(C) SPI.write16(C)
|
||||
#define tft_Write_32(C) SPI.write32(C)
|
||||
|
||||
#else // ESP32 using SPI with 16 bit color display
|
||||
|
||||
// ESP32 low level SPI writes for 8, 16 and 32 bit values
|
||||
// to avoid the function call overhead
|
||||
|
||||
// Write 8 bits
|
||||
#define tft_Write_8(C) \
|
||||
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_NUM), 8-1); \
|
||||
WRITE_PERI_REG(SPI_W0_REG(SPI_NUM), C); \
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_NUM), SPI_USR); \
|
||||
while (READ_PERI_REG(SPI_CMD_REG(SPI_NUM))&SPI_USR);
|
||||
|
||||
// Write 16 bits with corrected endianess for 16 bit colours
|
||||
#define tft_Write_16(C) \
|
||||
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_NUM), 16-1); \
|
||||
WRITE_PERI_REG(SPI_W0_REG(SPI_NUM), C<<8 | C>>8); \
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_NUM), SPI_USR); \
|
||||
while (READ_PERI_REG(SPI_CMD_REG(SPI_NUM))&SPI_USR);
|
||||
|
||||
// Write 16 bits (used for ESP32_PARALLEL or ILI9488_DRIVER)
|
||||
#define tft_Write_16S(C) \
|
||||
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_NUM), 16-1); \
|
||||
WRITE_PERI_REG(SPI_W0_REG(SPI_NUM), C); \
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_NUM), SPI_USR); \
|
||||
while (READ_PERI_REG(SPI_CMD_REG(SPI_NUM))&SPI_USR);
|
||||
|
||||
// Write 32 bits
|
||||
#define tft_Write_32(C) \
|
||||
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_NUM), 32-1); \
|
||||
WRITE_PERI_REG(SPI_W0_REG(SPI_NUM), C); \
|
||||
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_NUM), SPI_USR); \
|
||||
while (READ_PERI_REG(SPI_CMD_REG(SPI_NUM))&SPI_USR);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ESP32_PARALLEL
|
||||
// Support SPI TFT reads (not all displays support this)
|
||||
#define tft_Read_8(C) SPI.transfer(C)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LOAD_GFXFF
|
||||
// We can include all the free fonts and they will only be built into
|
||||
// the sketch if they are used
|
||||
@@ -406,6 +472,7 @@ template <typename T> static inline void
|
||||
swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
|
||||
|
||||
#ifndef min
|
||||
// Return minimum of two numbers, may already be defined
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
@@ -667,6 +734,10 @@ class TFT_eSPI : public Print {
|
||||
|
||||
void setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye);
|
||||
|
||||
// These 3 functions are used together, for every startWrite() there must be an endWrite()
|
||||
void startWrite(void); // Begin SPI transaction
|
||||
void writeColor(uint16_t color, uint32_t len); // Write a colour without transaction overhead
|
||||
void endWrite(void); // End SPI transaction
|
||||
|
||||
size_t write(uint8_t);
|
||||
|
||||
@@ -713,6 +784,8 @@ class TFT_eSPI : public Print {
|
||||
uint32_t _init_width, _init_height; // Display w/h as input, used by setRotation()
|
||||
uint32_t _width, _height; // Display w/h as modified by current rotation
|
||||
uint32_t addr_row, addr_col;
|
||||
uint32_t xs_col, xe_col;
|
||||
uint32_t ys_row, ye_row;
|
||||
|
||||
uint32_t fontsloaded;
|
||||
|
||||
@@ -750,9 +823,4 @@ class TFT_eSPI : public Print {
|
||||
// Load the Sprite Class
|
||||
#include "Extensions/Sprite.h"
|
||||
|
||||
// #ifdef ESP32
|
||||
// // Load the Sprite Class
|
||||
// #include "Extensions/pSprite.h"
|
||||
// #endif
|
||||
|
||||
#endif
|
||||
|
12
User_Setup.h
12
User_Setup.h
@@ -113,14 +113,15 @@
|
||||
// but saves pins for other functions.
|
||||
// Use NodeMCU SD0=MISO, SD1=MOSI, CLK=SCLK to connect to TFT in overlap mode
|
||||
|
||||
// In ESP8266 overlap mode the following must be defined
|
||||
//#define TFT_SPI_OVERLAP
|
||||
|
||||
// In ESP8266 overlap mode the TFT chip select MUST connect to pin D3
|
||||
//#define TFT_CS PIN_D3
|
||||
//#define TFT_DC PIN_D5 // Data Command control pin
|
||||
//#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line)
|
||||
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V
|
||||
|
||||
// In ESP8266 overlap mode the following must be defined
|
||||
//#define TFT_SPI_OVERLAP
|
||||
|
||||
// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP32 SETUP ######
|
||||
|
||||
@@ -136,6 +137,9 @@
|
||||
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
|
||||
//#define TFT_BL 32 // LED back-light (only for ST7789 with backlight control pin)
|
||||
|
||||
//#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only
|
||||
|
||||
// For the M5Stack module use these #define lines
|
||||
//#define TFT_MISO 19
|
||||
@@ -146,10 +150,6 @@
|
||||
//#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin)
|
||||
//#define TFT_BL 32 // LED back-light (required for M5Stack)
|
||||
|
||||
//#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only
|
||||
|
||||
// ###### EDIT THE PINs BELOW TO SUIT YOUR ESP32 PARALLEL TFT SETUP ######
|
||||
|
||||
// The library supports 8 bit parallel TFTs with the ESP32, the pin
|
||||
|
@@ -102,7 +102,7 @@
|
||||
|
||||
//#define TFT_BL PIN_D1 // LED back-light (only for ST7789 with backlight control pin)
|
||||
|
||||
//#define TOUCH_CS PIN_D2 // Chip select pin (T_CS) of touch screen
|
||||
//#define TOUCH_CS PIN_D1 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR PIN_D2 // Write strobe for modified Raspberry Pi TFT only
|
||||
|
||||
@@ -113,14 +113,15 @@
|
||||
// but saves pins for other functions.
|
||||
// Use NodeMCU SD0=MISO, SD1=MOSI, CLK=SCLK to connect to TFT in overlap mode
|
||||
|
||||
// In ESP8266 overlap mode the following must be defined
|
||||
//#define TFT_SPI_OVERLAP
|
||||
|
||||
// In ESP8266 overlap mode the TFT chip select MUST connect to pin D3
|
||||
//#define TFT_CS PIN_D3
|
||||
//#define TFT_DC PIN_D5 // Data Command control pin
|
||||
//#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line)
|
||||
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V
|
||||
|
||||
// In ESP8266 overlap mode the following must be defined
|
||||
//#define TFT_SPI_OVERLAP
|
||||
|
||||
// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP32 SETUP ######
|
||||
|
||||
@@ -134,8 +135,10 @@
|
||||
//#define TFT_DC 2 // Data Command control pin
|
||||
//#define TFT_RST 4 // Reset pin (could connect to RST pin)
|
||||
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
|
||||
//#define TFT_BL 32 // LED back-light (only for ST7789 with backlight control pin)
|
||||
|
||||
//#define TOUCH_CS 22 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR 21 // Write strobe for modified Raspberry Pi TFT only
|
||||
|
||||
// For the M5Stack module use these #define lines
|
||||
//#define TFT_MISO 19
|
||||
@@ -144,11 +147,7 @@
|
||||
//#define TFT_CS 14 // Chip select control pin
|
||||
//#define TFT_DC 27 // Data Command control pin
|
||||
//#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin)
|
||||
//#define TFT_BL 32 // LED back-light (required for M5Stack)
|
||||
|
||||
//#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only
|
||||
//#define TFT_BL 32 // LED back-light (if needed)
|
||||
|
||||
// ###### EDIT THE PINs BELOW TO SUIT YOUR ESP32 PARALLEL TFT SETUP ######
|
||||
|
||||
@@ -209,9 +208,9 @@
|
||||
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
|
||||
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
|
||||
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
|
||||
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
|
||||
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
|
||||
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
|
||||
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
|
||||
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
|
||||
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
|
||||
|
||||
// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
|
||||
@@ -263,4 +262,4 @@
|
||||
// Transactions are automatically enabled by the library for an ESP32 (to use HAL mutex)
|
||||
// so changing it here has no effect
|
||||
|
||||
//#define SUPPORT_TRANSACTIONS
|
||||
// #define SUPPORT_TRANSACTIONS
|
||||
|
@@ -6,6 +6,9 @@ drawChar KEYWORD2
|
||||
setAddrWindow KEYWORD2
|
||||
setWindow KEYWORD2
|
||||
readAddrWindow KEYWORD2
|
||||
startWrite KEYWORD2
|
||||
writeColor KEYWORD2
|
||||
endWrite KEYWORD2
|
||||
pushColor KEYWORD2
|
||||
pushColors KEYWORD2
|
||||
fillScreen KEYWORD2
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "1.1.4",
|
||||
"version": "1.2.0",
|
||||
"keywords": "tft, ePaper, display, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789",
|
||||
"description": "A TFT and ePaper SPI graphics library for ESP8266 and ESP32",
|
||||
"repository":
|
||||
|
@@ -1,5 +1,5 @@
|
||||
name=TFT_eSPI
|
||||
version=1.1.4
|
||||
version=1.2.0
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=A fast TFT graphics library for ESP8266 and ESP32 processors for the Arduino IDE
|
||||
|
Reference in New Issue
Block a user