Restructured code, added ST7796

RPi MHS-4.0 inch Display-B type display now supported.
This commit is contained in:
Bodmer 2020-01-11 00:58:38 +00:00
parent b6574ff373
commit 1476da56ba
29 changed files with 2734 additions and 2377 deletions

View File

@ -57,9 +57,6 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
a zero/one terminated character string giving the font name
last byte is 0 for non-anti-aliased and 1 for anti-aliased (smoothed)
Then the font name seen by Java when it's created
Then the postscript name of the font
Then a boolean to tell if smoothing is on or not.
Glyph bitmap example is:
// Cursor coordinate positions for this and next character are marked by 'C'
@ -79,7 +76,7 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
// | + x..@@@@@@@..x | x marks the corner pixels of the bitmap
// | |
// +---------------------------+ yAdvance is y delta for the next line, font size or (ascent + descent)
// some fonts can overlay in y direction so may need a user adjust value
// some fonts can overlay in y direction so may need a user adjust value
*/
@ -277,126 +274,6 @@ void TFT_eSPI::unloadFont( void )
}
/***************************************************************************************
** Function name: decodeUTF8
** Description: Line buffer UTF-8 decoder with fall-back to extended ASCII
*************************************************************************************x*/
/* Function moved to TFT_eSPI.cpp
#define DECODE_UTF8
uint16_t TFT_eSPI::decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining)
{
byte c = buf[(*index)++];
//Serial.print("Byte from string = 0x"); Serial.println(c, HEX);
#ifdef DECODE_UTF8
// 7 bit Unicode
if ((c & 0x80) == 0x00) return c;
// 11 bit Unicode
if (((c & 0xE0) == 0xC0) && (remaining > 1))
return ((c & 0x1F)<<6) | (buf[(*index)++]&0x3F);
// 16 bit Unicode
if (((c & 0xF0) == 0xE0) && (remaining > 2))
{
c = ((c & 0x0F)<<12) | ((buf[(*index)++]&0x3F)<<6);
return c | ((buf[(*index)++]&0x3F));
}
// 21 bit Unicode not supported so fall-back to extended ASCII
// if ((c & 0xF8) == 0xF0) return c;
#endif
return c; // fall-back to extended ASCII
}
*/
/***************************************************************************************
** Function name: decodeUTF8
** Description: Serial UTF-8 decoder with fall-back to extended ASCII
*************************************************************************************x*/
/* Function moved to TFT_eSPI.cpp
uint16_t TFT_eSPI::decodeUTF8(uint8_t c)
{
#ifdef DECODE_UTF8
// 7 bit Unicode
if ((c & 0x80) == 0x00) {
decoderState = 0;
return (uint16_t)c;
}
if (decoderState == 0)
{
// 11 bit Unicode
if ((c & 0xE0) == 0xC0)
{
decoderBuffer = ((c & 0x1F)<<6);
decoderState = 1;
return 0;
}
// 16 bit Unicode
if ((c & 0xF0) == 0xE0)
{
decoderBuffer = ((c & 0x0F)<<12);
decoderState = 2;
return 0;
}
// 21 bit Unicode not supported so fall-back to extended ASCII
if ((c & 0xF8) == 0xF0) return (uint16_t)c;
}
else
{
if (decoderState == 2)
{
decoderBuffer |= ((c & 0x3F)<<6);
decoderState--;
return 0;
}
else
{
decoderBuffer |= (c & 0x3F);
decoderState = 0;
return decoderBuffer;
}
}
#endif
decoderState = 0;
return (uint16_t)c; // fall-back to extended ASCII
}
*/
/***************************************************************************************
** Function name: alphaBlend
** Description: Blend foreground and background and return new colour
*************************************************************************************x*/
uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc)
{
// For speed use fixed point maths and rounding to permit a power of 2 division
uint16_t fgR = ((fgc >> 10) & 0x3E) + 1;
uint16_t fgG = ((fgc >> 4) & 0x7E) + 1;
uint16_t fgB = ((fgc << 1) & 0x3E) + 1;
uint16_t bgR = ((bgc >> 10) & 0x3E) + 1;
uint16_t bgG = ((bgc >> 4) & 0x7E) + 1;
uint16_t bgB = ((bgc << 1) & 0x3E) + 1;
// Shift right 1 to drop rounding bit and shift right 8 to divide by 256
uint16_t r = (((fgR * alpha) + (bgR * (255 - alpha))) >> 9);
uint16_t g = (((fgG * alpha) + (bgG * (255 - alpha))) >> 9);
uint16_t b = (((fgB * alpha) + (bgB * (255 - alpha))) >> 9);
// Combine RGB565 colours into 16 bits
//return ((r&0x18) << 11) | ((g&0x30) << 5) | ((b&0x18) << 0); // 2 bit greyscale
//return ((r&0x1E) << 11) | ((g&0x3C) << 5) | ((b&0x1E) << 0); // 4 bit greyscale
return (r << 11) | (g << 5) | (b << 0);
}
/***************************************************************************************
** Function name: readInt32
** Description: Get a 32 bit integer from the font file

View File

@ -9,8 +9,6 @@
void unloadFont( void );
bool getUnicodeIndex(uint16_t unicode, uint16_t *index);
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
virtual void drawGlyph(uint16_t code);
void showFont(uint32_t td);

View File

@ -269,13 +269,116 @@ int16_t TFT_eSprite::getPivotY(void)
/***************************************************************************************
** Function name: pushRotated
** Description: Push a rotated copy of the Sprite to TFT screen
** Function name: pushRotated - Fast fixed point integer maths version
** Description: Push rotated Sprite to TFT screen
*************************************************************************************x*/
#define FP_SCALE 10
bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
{
if ( !_created ) return false;
// Trig values for the rotation
float radAngle = -angle * 0.0174532925; // Convert degrees to radians
float sinraf = sin(radAngle);
float cosraf = cos(radAngle);
int32_t sinra = sinraf * (1<<FP_SCALE);
int32_t cosra = cosraf * (1<<FP_SCALE);
// Bounding box parameters
int16_t min_x;
int16_t min_y;
int16_t max_x;
int16_t max_y;
// Get the bounding box of this rotated source Sprite relative to Sprite pivot
getRotatedBounds(sinraf, cosraf, width(), height(), _xpivot, _ypivot, &min_x, &min_y, &max_x, &max_y);
// Move bounding box so source Sprite pivot coincides with TFT pivot
min_x += _tft->_xpivot;
max_x += _tft->_xpivot;
min_y += _tft->_ypivot;
max_y += _tft->_ypivot;
// Test only to show bounding box on TFT
// _tft->drawRect(min_x, min_y, max_x - min_x + 1, max_y - min_y + 1, TFT_GREEN);
// Return if bounding box is outside of TFT area
if (min_x > _tft->width()) return true;
if (min_y > _tft->height()) return true;
if (max_x < 0) return true;
if (max_y < 0) return true;
// Clip bounding box to be within TFT area
if (min_x < 0) min_x = 0;
if (min_y < 0) min_y = 0;
if (max_x > _tft->width()) max_x = _tft->width();
if (max_y > _tft->height()) max_y = _tft->height();
uint16_t sline_buffer[max_y - min_y + 1];
int32_t xt = min_x - _tft->_xpivot;
int32_t yt = min_y - _tft->_ypivot;
// Keep multiply out of the loop
int32_t cxt = cosra * xt + (_xpivot<<FP_SCALE);
int32_t sxt = sinra * xt + (_ypivot<<FP_SCALE);
int32_t init_cyt = cosra * yt;
int32_t init_syt = sinra * yt;
_tft->startWrite(); // ESP32: avoid transaction overhead for every tft pixel
// Scan destination bounding box and fetch transformed pixels from source Sprite
for (int32_t x = min_x; x <= max_x; x++) {
cxt += cosra;
sxt += sinra;
bool column_drawn = false;
uint32_t pixel_count = 0;
int32_t y_start = 0;
int32_t xs = cxt - init_syt;
int32_t cyt = init_cyt;
for (int32_t y = min_y; y <= max_y; y++) {
cyt += cosra;
xs -= sinra;
// Do not calculate yp unless xp is in bounds
int32_t xp = truncateFP(xs, FP_SCALE);
if ((xp >= 0) && (xp < _iwidth))
{
int32_t yp = truncateFP(sxt + cyt, FP_SCALE);
// Check if yp is in bounds
if ((yp >= 0) && (yp < _iheight)) {
uint32_t rp;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; rp = rp>>8 | rp<<8; }
else rp = readPixel(xp, yp);
if (transp >= 0 ) {
if (rp != transp) _tft->drawPixel(x, y, rp);
}
else {
if (!column_drawn) y_start = y;
sline_buffer[pixel_count++] = rp>>8 | rp<<8;
}
column_drawn = true;
}
}
else if (column_drawn) y = max_y; // Skip remaining column pixels
}
if (pixel_count) _tft->pushImage(x, y_start, 1, pixel_count, sline_buffer);
}
_tft->endWrite(); // ESP32: end transaction
return true;
}
/***************************************************************************************
** Function name: pushRotatedHP - Higher Precision version of pushRotated
** Description: Push rotated Sprite to TFT screen
*************************************************************************************x*/
bool TFT_eSprite::pushRotatedHP(int16_t angle, int32_t transp)
{
if ( !_created ) return false;
// Trig values for the rotation
float radAngle = -angle * 0.0174532925; // Convert degrees to radians
float sinra = sin(radAngle);
@ -308,7 +411,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
// Clip bounding box to be within TFT area
if (min_x < 0) min_x = 0;
if (min_y < 0) min_y = 0;
if (max_x > _tft->width()) max_x = _tft->width();
if (max_x > _tft->width()) max_x = _tft->width();
if (max_y > _tft->height()) max_y = _tft->height();
_tft->startWrite(); // ESP32: avoid transaction overhead for every tft pixel
@ -344,7 +447,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, int32_t transp)
/***************************************************************************************
** Function name: pushRotated
** Function name: pushRotated - Fast fixed point integer maths version
** Description: Push a rotated copy of the Sprite to another Sprite
*************************************************************************************x*/
bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
@ -352,6 +455,89 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
if ( !_created ) return false; // Check this Sprite is created
if ( !spr->_created ) return false; // Ckeck destination Sprite is created
// Trig values for the rotation
float radAngle = -angle * 0.0174532925; // Convert degrees to radians
float sinraf = sin(radAngle);
float cosraf = cos(radAngle);
int32_t sinra = sinraf * (1<<FP_SCALE);
int32_t cosra = cosraf * (1<<FP_SCALE);
// Bounding box parameters
int16_t min_x;
int16_t min_y;
int16_t max_x;
int16_t max_y;
// Get the bounding box of this rotated source Sprite
getRotatedBounds(sinraf, cosraf, width(), height(), _xpivot, _ypivot, &min_x, &min_y, &max_x, &max_y);
// Move bounding box so source Sprite pivot coincides with destination Sprite pivot
min_x += spr->_xpivot;
max_x += spr->_xpivot;
min_y += spr->_ypivot;
max_y += spr->_ypivot;
// Test only to show bounding box
// spr->fillSprite(TFT_BLACK);
// spr->drawRect(min_x, min_y, max_x - min_x + 1, max_y - min_y + 1, TFT_GREEN);
// Return if bounding box is completely outside of destination Sprite
if (min_x > spr->width()) return true;
if (min_y > spr->height()) return true;
if (max_x < 0) return true;
if (max_y < 0) return true;
// Clip bounding box if it is partially within destination Sprite
if (min_x < 0) min_x = 0;
if (min_y < 0) min_y = 0;
if (max_x > spr->width()) max_x = spr->width();
if (max_y > spr->height()) max_y = spr->height();
// Scan destination bounding box and fetch transformed pixels from source Sprite
for (int32_t x = min_x; x <= max_x; x++)
{
int32_t xt = x - spr->_xpivot;
float cxt = cosra * xt + (_xpivot<<FP_SCALE);
float sxt = sinra * xt + (_ypivot<<FP_SCALE);
bool column_drawn = false;
for (int32_t y = min_y; y <= max_y; y++)
{
int32_t yt = y - spr->_ypivot;
int32_t xs = cxt - sinra * yt;
// Do not calculate yp unless xp is in bounds
int32_t xp = truncateFP(xs, FP_SCALE);
if (xp >= 0 && xp < _iwidth)
{
int32_t ys = sxt + cosra * yt;
// Check if ys is in bounds
int32_t yp = truncateFP(ys, FP_SCALE);
if (yp >= 0 && yp < _iheight)
{
uint32_t rp;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; rp = rp>>8 | rp<<8; }
else rp = readPixel(xp, yp);
if (rp != transp) spr->drawPixel(x, y, rp);
column_drawn = true;
}
}
else if (column_drawn) y = max_y; // Skip the remaining pixels below the Sprite
}
}
return true;
}
/***************************************************************************************
** Function name: pushRotated - Higher Precision version of pushRotated
** Description: Push a rotated copy of the Sprite to another Sprite
*************************************************************************************x*/
bool TFT_eSprite::pushRotatedHP(TFT_eSprite *spr, int16_t angle, int32_t transp)
{
if ( !_created ) return false; // Check this Sprite is created
if ( !spr->_created ) return false; // Ckeck destination Sprite is created
// Trig values for the rotation
float radAngle = -angle * 0.0174532925; // Convert degrees to radians
float sinra = sin(radAngle);
@ -385,7 +571,7 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp)
// Clip bounding box if it is partially within destination Sprite
if (min_x < 0) min_x = 0;
if (min_y < 0) min_y = 0;
if (max_x > spr->width()) max_x = spr->width();
if (max_x > spr->width()) max_x = spr->width();
if (max_y > spr->height()) max_y = spr->height();
// Scan destination bounding box and fetch transformed pixels from source Sprite
@ -516,7 +702,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
*************************************************************************************x*/
uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
{
if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0;
if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0xFFFF;
if (_bpp == 16)
{
@ -557,7 +743,8 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
uint16_t color = (_img8[(x + y * _bitwidth)>>3] << (x & 0x7)) & 0x80;
return color >> 7;
if (color >> 7) return _tft->bitmap_fg;
else return _tft->bitmap_bg;
}
@ -1148,7 +1335,7 @@ void TFT_eSprite::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint3
{
if (!_created ) return;
boolean steep = abs(y1 - y0) > abs(x1 - x0);
bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap_coord(x0, y0);
swap_coord(x1, y1);
@ -1492,7 +1679,7 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
#endif
//>>>>>>>>>>>>>>>>>>
boolean fillbg = (bg != color);
bool fillbg = (bg != color);
if ((size==1) && fillbg)
{

View File

@ -5,22 +5,29 @@
// graphics are written to the Sprite rather than the TFT.
***************************************************************************************/
// pushRotated support - Bitwise truncation of fixed point integer value V scaled by S
//#define truncateFP(V,S) ((V + (V < 0 ? -1<<(S-1) : 0))>>S)
#define truncateFP(V,S) ((V + (V < 0 ? -1<<(S-1) : 1<<(S-1)))>>S)
class TFT_eSprite : public TFT_eSPI {
public:
TFT_eSprite(TFT_eSPI *tft);
virtual ~TFT_eSprite();
// Create a sprite of width x height pixels, return a pointer to the RAM area
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
// RAM required is 1 byte per pixel for 8 bit colour depth, 2 bytes for 16 bit
// RAM required is:
// - 1 bit per pixel for 1 bit colour depth
// - 1 byte per pixel for 8 bit colour
// - 2 bytes per pixel for 16 bit color depth
void* createSprite(int16_t width, int16_t height, uint8_t frames = 1);
// Delete the sprite to free up the RAM
void deleteSprite(void);
// Select the frame buffer for graphics
// Select the frame buffer for graphics write (for 2 colour ePaper and DMA toggle buffer)
// Returns a pointer to the Sprite frame buffer
void* frameBuffer(int8_t f);
// Set or get the colour depth to 8 or 16 bits. Can be used to change depth an existing
@ -28,18 +35,22 @@ class TFT_eSprite : public TFT_eSPI {
void* setColorDepth(int8_t b);
int8_t getColorDepth(void);
void setBitmapColor(uint16_t c, uint16_t b);
// Set foreground and background colours for 1 bit per pixel Sprite
void setBitmapColor(uint16_t fg, uint16_t bg);
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 size),
void drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t font),
// Fill Sprite with a colour
fillSprite(uint32_t color),
// Define a window to push 16 bit colour pixels into in a raster order
// Colours are converted to 8 bit if depth is set to 8
// 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
pushColor(uint32_t color),
// Push len colors (pixels) to the screen
pushColor(uint32_t color, uint16_t len),
// Push a pixel preformatted as a 8 or 16 bit colour (avoids conversion overhead)
writeColor(uint16_t color),
@ -52,23 +63,29 @@ class TFT_eSprite : public TFT_eSPI {
// The sprite coordinate frame does not move because pixels are moved
scroll(int16_t dx, int16_t dy = 0),
// Draw lines
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color),
drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color),
drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color),
// Fill a rectangular area with a color (aka draw a filled rectangle)
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
// Set the sprite text cursor position for print class (does not change the TFT screen cursor)
//setCursor(int16_t x, int16_t y);
//setCursor(int16_t x, int16_t y); // Not needed, so uses TFT class function
// Set the rotation of the Sprite (for 1bpp Sprites only)
// Set the coordinate rotation of the Sprite (for 1bpp Sprites only)
// Note: this uses coordinate rotation and is primarily for ePaper which does not support
// CGRAM rotation (like TFT drivers do) within the displays internal hardware
void setRotation(uint8_t rotation);
uint8_t getRotation(void);
// Push a rotated copy of Sprite to TFT with optional transparent colour
bool pushRotated(int16_t angle, int32_t transp = -1);
bool pushRotated(int16_t angle, int32_t transp = -1); // Using fixed point maths
bool pushRotatedHP(int16_t angle, int32_t transp = -1); // Using higher precision floating point maths
// Push a rotated copy of Sprite to another different Sprite with optional transparent colour
bool pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp = -1);
bool pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp = -1); // Using fixed point maths
bool pushRotatedHP(TFT_eSprite *spr, int16_t angle, int32_t transp = -1); // Using higher precision floating point maths
// Set and get the pivot point for this Sprite
void setPivot(int16_t x, int16_t y);
int16_t getPivotX(void),
@ -138,7 +155,7 @@ class TFT_eSprite : public TFT_eSPI {
uint32_t _sw, _sh; // w,h for scroll zone
uint32_t _scolor; // gap fill colour for scroll zone
boolean _iswapBytes; // Swap the byte order for Sprite pushImage()
bool _iswapBytes; // Swap the byte order for Sprite pushImage()
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)

View File

@ -7,8 +7,6 @@
// Comment out next line to return character 0x60 to the grave accent:
#define TFT_ESPI_GRAVE_IS_DEGREE
#include <pgmspace.h>
// Width has been increased by 1 pixel so pixel lengths are calculated correctly
// for the displayed string

View File

@ -4,8 +4,6 @@
//
// This font contains 96 ASCII characters
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f32[96] = // character width table
{

View File

@ -7,9 +7,6 @@
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f64[96] = // character width table
{
12, 12, 12, 12, 12, 12, 12, 12, // char 32 - 39

View File

@ -6,8 +6,6 @@
// This font only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : - .
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f72[96] = // character width table
{

View File

@ -7,8 +7,6 @@
// This font only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : - .
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f72[96] = // character width table
{

View File

@ -6,8 +6,6 @@
// This font only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : . -
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f7s[96] = // character width table
{

View File

@ -1,4 +1,4 @@
// Adopted by Bodmer to support TFT_HX8357_Due library.
// Adopted by Bodmer to support TFT_eSPI library.
// Font structures for newer Adafruit_GFX (1.1 and later).
// Example fonts are included in 'Fonts' directory.
@ -25,6 +25,71 @@ typedef struct { // Data stored for FONT AS A WHOLE:
uint8_t yAdvance; // Newline distance (y axis)
} GFXfont;
// Original Adafruit_GFX "Free Fonts"
#include <Fonts/GFXFF/TomThumb.h> // TT1
#include <Fonts/GFXFF/FreeMono9pt7b.h> // FF1 or FM9
#include <Fonts/GFXFF/FreeMono12pt7b.h> // FF2 or FM12
#include <Fonts/GFXFF/FreeMono18pt7b.h> // FF3 or FM18
#include <Fonts/GFXFF/FreeMono24pt7b.h> // FF4 or FM24
#include <Fonts/GFXFF/FreeMonoOblique9pt7b.h> // FF5 or FMO9
#include <Fonts/GFXFF/FreeMonoOblique12pt7b.h> // FF6 or FMO12
#include <Fonts/GFXFF/FreeMonoOblique18pt7b.h> // FF7 or FMO18
#include <Fonts/GFXFF/FreeMonoOblique24pt7b.h> // FF8 or FMO24
#include <Fonts/GFXFF/FreeMonoBold9pt7b.h> // FF9 or FMB9
#include <Fonts/GFXFF/FreeMonoBold12pt7b.h> // FF10 or FMB12
#include <Fonts/GFXFF/FreeMonoBold18pt7b.h> // FF11 or FMB18
#include <Fonts/GFXFF/FreeMonoBold24pt7b.h> // FF12 or FMB24
#include <Fonts/GFXFF/FreeMonoBoldOblique9pt7b.h> // FF13 or FMBO9
#include <Fonts/GFXFF/FreeMonoBoldOblique12pt7b.h> // FF14 or FMBO12
#include <Fonts/GFXFF/FreeMonoBoldOblique18pt7b.h> // FF15 or FMBO18
#include <Fonts/GFXFF/FreeMonoBoldOblique24pt7b.h> // FF16 or FMBO24
// Sans serif fonts
#include <Fonts/GFXFF/FreeSans9pt7b.h> // FF17 or FSS9
#include <Fonts/GFXFF/FreeSans12pt7b.h> // FF18 or FSS12
#include <Fonts/GFXFF/FreeSans18pt7b.h> // FF19 or FSS18
#include <Fonts/GFXFF/FreeSans24pt7b.h> // FF20 or FSS24
#include <Fonts/GFXFF/FreeSansOblique9pt7b.h> // FF21 or FSSO9
#include <Fonts/GFXFF/FreeSansOblique12pt7b.h> // FF22 or FSSO12
#include <Fonts/GFXFF/FreeSansOblique18pt7b.h> // FF23 or FSSO18
#include <Fonts/GFXFF/FreeSansOblique24pt7b.h> // FF24 or FSSO24
#include <Fonts/GFXFF/FreeSansBold9pt7b.h> // FF25 or FSSB9
#include <Fonts/GFXFF/FreeSansBold12pt7b.h> // FF26 or FSSB12
#include <Fonts/GFXFF/FreeSansBold18pt7b.h> // FF27 or FSSB18
#include <Fonts/GFXFF/FreeSansBold24pt7b.h> // FF28 or FSSB24
#include <Fonts/GFXFF/FreeSansBoldOblique9pt7b.h> // FF29 or FSSBO9
#include <Fonts/GFXFF/FreeSansBoldOblique12pt7b.h> // FF30 or FSSBO12
#include <Fonts/GFXFF/FreeSansBoldOblique18pt7b.h> // FF31 or FSSBO18
#include <Fonts/GFXFF/FreeSansBoldOblique24pt7b.h> // FF32 or FSSBO24
// Serif fonts
#include <Fonts/GFXFF/FreeSerif9pt7b.h> // FF33 or FS9
#include <Fonts/GFXFF/FreeSerif12pt7b.h> // FF34 or FS12
#include <Fonts/GFXFF/FreeSerif18pt7b.h> // FF35 or FS18
#include <Fonts/GFXFF/FreeSerif24pt7b.h> // FF36 or FS24
#include <Fonts/GFXFF/FreeSerifItalic9pt7b.h> // FF37 or FSI9
#include <Fonts/GFXFF/FreeSerifItalic12pt7b.h> // FF38 or FSI12
#include <Fonts/GFXFF/FreeSerifItalic18pt7b.h> // FF39 or FSI18
#include <Fonts/GFXFF/FreeSerifItalic24pt7b.h> // FF40 or FSI24
#include <Fonts/GFXFF/FreeSerifBold9pt7b.h> // FF41 or FSB9
#include <Fonts/GFXFF/FreeSerifBold12pt7b.h> // FF42 or FSB12
#include <Fonts/GFXFF/FreeSerifBold18pt7b.h> // FF43 or FSB18
#include <Fonts/GFXFF/FreeSerifBold24pt7b.h> // FF44 or FSB24
#include <Fonts/GFXFF/FreeSerifBoldItalic9pt7b.h> // FF45 or FSBI9
#include <Fonts/GFXFF/FreeSerifBoldItalic12pt7b.h> // FF46 or FSBI12
#include <Fonts/GFXFF/FreeSerifBoldItalic18pt7b.h> // FF47 or FSBI18
#include <Fonts/GFXFF/FreeSerifBoldItalic24pt7b.h> // FF48 or FSBI24
#endif // LOAD_GFXFF
#endif // _GFXFONT_H_

View File

@ -3,8 +3,6 @@
#ifndef FONT5X7_H
#define FONT5X7_H
#include <pgmspace.h>
// Standard ASCII 5x7 font
static const unsigned char font[] PROGMEM = {

475
Processors/TFT_eSPI_ESP32.c Normal file
View File

@ -0,0 +1,475 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// Global variables
////////////////////////////////////////////////////////////////////////////////////////
// Select the SPI port to use, ESP32 has 2 options
#if !defined (TFT_PARALLEL_8_BIT)
#ifdef USE_HSPI_PORT
SPIClass spi = SPIClass(HSPI);
#else // use default VSPI port
SPIClass& spi = SPI;
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: beginSDA
** Description: Detach SPI from pin to permit software SPI
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
pinMatrixOutDetach(TFT_MOSI, false, false);
pinMode(TFT_MOSI, INPUT);
pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false);
}
/***************************************************************************************
** Function name: endSDA
** Description: Attach SPI pins after software SPI
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
pinMode(TFT_MOSI, OUTPUT);
pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false);
pinMode(TFT_MISO, INPUT);
pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false);
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: read byte - supports class functions
** Description: Read a byte from ESP32 8 bit data port
***************************************************************************************/
// Parallel bus MUST be set to input before calling this function!
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0xAA;
#if defined (TFT_PARALLEL_8_BIT)
RD_L;
uint32_t reg; // Read all GPIO pins 0-31
reg = gpio_input_get(); // Read three times to allow for bus access time
reg = gpio_input_get();
reg = gpio_input_get(); // Data should be stable now
RD_H;
// Check GPIO bits used and build value
b = (((reg>>TFT_D0)&1) << 0);
b |= (((reg>>TFT_D1)&1) << 1);
b |= (((reg>>TFT_D2)&1) << 2);
b |= (((reg>>TFT_D3)&1) << 3);
b |= (((reg>>TFT_D4)&1) << 4);
b |= (((reg>>TFT_D5)&1) << 5);
b |= (((reg>>TFT_D6)&1) << 6);
b |= (((reg>>TFT_D7)&1) << 7);
#endif
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: GPIO direction control - supports class functions
** Description: Set parallel bus to INPUT or OUTPUT
***************************************************************************************/
void TFT_eSPI::busDir(uint32_t mask, uint8_t mode)
{
gpioMode(TFT_D0, mode);
gpioMode(TFT_D1, mode);
gpioMode(TFT_D2, mode);
gpioMode(TFT_D3, mode);
gpioMode(TFT_D4, mode);
gpioMode(TFT_D5, mode);
gpioMode(TFT_D6, mode);
gpioMode(TFT_D7, mode);
return;
/*
// Arduino generic native function, but slower
pinMode(TFT_D0, mode);
pinMode(TFT_D1, mode);
pinMode(TFT_D2, mode);
pinMode(TFT_D3, mode);
pinMode(TFT_D4, mode);
pinMode(TFT_D5, mode);
pinMode(TFT_D6, mode);
pinMode(TFT_D7, mode);
return; //*/
}
/***************************************************************************************
** Function name: GPIO direction control - supports class functions
** Description: Set ESP32 GPIO pin to input or output (set high) ASAP
***************************************************************************************/
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
{
if(mode == INPUT) GPIO.enable_w1tc = ((uint32_t)1 << gpio);
else GPIO.enable_w1ts = ((uint32_t)1 << gpio);
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[gpio].reg) // Register lookup
= ((uint32_t)2 << FUN_DRV_S) // Set drive strength 2
| (FUN_IE) // Input enable
| ((uint32_t)2 << MCU_SEL_S); // Function select 2
GPIO.pin[gpio].val = 1; // Set pin HIGH
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #ifdef TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (RPI_WRITE_STROBE) && !defined (TFT_PARALLEL_8_BIT) // Code for RPi TFT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 or ESP8266 RPi TFT
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
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;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 or ESP8266 RPi TFT
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len)
{
uint8_t *data = (uint8_t*)data_in;
if(_swapBytes) {
while ( len-- ) {tft_Write_16(*data); data++;}
return;
}
while ( len >=64 ) {spi.writePattern(data, 64, 1); data += 64; len -= 64; }
if (len) spi.writePattern(data, len, 1);
}
////////////////////////////////////////////////////////////////////////////////////////
#elif !defined (ILI9488_DRIVER) && !defined (TFT_PARALLEL_8_BIT) // Most displays
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
uint32_t color32 = (color<<8 | color >>8)<<16 | (color<<8 | color >>8);
if (len > 31)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511);
while(len>31)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), color32);
WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), color32);
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 32;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
if (len)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1);
for (uint32_t i=0; i <= (len<<1); i+=4) WRITE_PERI_REG(SPI_W0_REG(SPI_PORT) + i, color32);
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint8_t* data = (uint8_t*)data_in;
uint32_t color[16];
if (len > 31)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511);
while(len>31)
{
uint32_t i = 0;
while(i<16)
{
color[i++] = DAT8TO32(data);
data+=4;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), color[8]);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), color[9]);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), color[10]);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), color[11]);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), color[12]);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), color[13]);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), color[14]);
WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), color[15]);
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 32;
}
}
if (len > 15)
{
uint32_t i = 0;
while(i<8)
{
color[i++] = DAT8TO32(data);
data+=4;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 255);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]);
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 16;
}
if (len)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1);
for (uint32_t i=0; i <= (len<<1); i+=4) {
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT)+i, DAT8TO32(data)); data+=4;
}
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
/***************************************************************************************
** Function name: pushPixels - for ESP32
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
if(_swapBytes) {
pushSwapBytePixels(data_in, len);
return;
}
uint32_t *data = (uint32_t*)data_in;
if (len > 31)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511);
while(len>31)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), *data++);
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 32;
}
}
if (len)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1);
for (uint32_t i=0; i <= (len<<1); i+=4) WRITE_PERI_REG((SPI_W0_REG(SPI_PORT) + i), *data++);
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (ILI9488_DRIVER) && !defined (TFT_PARALLEL_8_BIT)// Now code for ILI9488
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 and 3 byte RGB display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
// Split out the colours
uint32_t r = (color & 0xF800)>>8;
uint32_t g = (color & 0x07E0)<<5;
uint32_t b = (color & 0x001F)<<19;
// Concatenate 4 pixels into three 32 bit blocks
uint32_t r0 = r<<24 | b | g | r;
uint32_t r1 = r0>>8 | g<<16;
uint32_t r2 = r1>>8 | b<<8;
if (len > 19)
{
SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_PORT), SPI_USR_MOSI_DBITLEN, 479, SPI_USR_MOSI_DBITLEN_S);
while(len>19)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2);
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 20;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
if (len)
{
SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_PORT), SPI_USR_MOSI_DBITLEN, (len * 24) - 1, SPI_USR_MOSI_DBITLEN_S);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2);
if (len > 8 )
{
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2);
}
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 and 3 byte RGB display
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
while ( len-- ) {tft_Write_16(*data); data++;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 and 3 byte RGB display
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
if(_swapBytes) { while ( len-- ) {tft_Write_16(*data); data++;} }
else { while ( len-- ) {tft_Write_16S(*data); data++;} }
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (TFT_PARALLEL_8_BIT) // Now the code for ESP32 8 bit parallel
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 and parallel display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
if ( (color >> 8) == (color & 0x00FF) )
{ if (!len) return;
tft_Write_16(color); WR_L; WR_H;
while (--len) {WR_L; WR_H; WR_L; WR_H;}
}
else while (len--) {tft_Write_16(color);}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 and parallel display
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
while ( len-- ) {tft_Write_16(*data); data++;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 and parallel display
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
if(_swapBytes) { while ( len-- ) {tft_Write_16(*data); data++; } }
else { while ( len-- ) {tft_Write_16S(*data); data++;} }
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of display interface specific functions
////////////////////////////////////////////////////////////////////////////////////////

354
Processors/TFT_eSPI_ESP32.h Normal file
View File

@ -0,0 +1,354 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
#ifndef _TFT_eSPI_ESP32H_
#define _TFT_eSPI_ESP32H_
// Processor ID reported by getSetup()
#define PROCESSOR_ID 0x32
// Include processor specific header
#include "soc/spi_reg.h"
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
#define SET_SPI_WRITE_MODE // Not used
#define SET_SPI_READ_MODE // Not used
// Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions
#define DMA_BUSY_CHECK // DMA not implemented for this processor (yet)
// SUPPORT_TRANSACTIONS is mandatory for ESP32 so the hal mutex is toggled
#if !defined (SUPPORT_TRANSACTIONS)
#define SUPPORT_TRANSACTIONS
#endif
// ESP32 specific SPI port selection
#ifdef USE_HSPI_PORT
#define SPI_PORT HSPI
#else
#define SPI_PORT VSPI
#endif
// If it is a 16bit serial display we must transfer 16 bits every time
// Set commands bits to 16 or 8
#ifdef RPI_ILI9486_DRIVER
#ifndef RPI_DRIVER
#define RPI_DRIVER
#endif
#endif
#ifdef RPI_DRIVER
#define CMD_BITS (16-1)
#else
#define CMD_BITS (8-1)
#endif
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS // Not used
// Define a generic flag for 8 bit parallel
#if defined (ESP32_PARALLEL) // Specific to ESP32 for backwards compatibility
#define TFT_PARALLEL_8_BIT // Generic parallel flag
#endif
// If smooth font is used then it is likely SPIFFS will be needed
#ifdef SMOOTH_FONT
// Call up the SPIFFS (SPI FLASH Filing System) for the anti-aliased fonts
#define FS_NO_GLOBALS
#include <FS.h>
#include "SPIFFS.h" // ESP32 only
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the DC (TFT Data/Command or Register Select (RS))pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_DC
#define DC_C // No macro allocated so it generates no code
#define DC_D // No macro allocated so it generates no code
#else
#if defined (TFT_PARALLEL_8_BIT)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)
#else
#if TFT_DC >= 32
#ifdef RPI_DRIVER // RPi displays need a slower DC change
#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))
#else
#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))
#endif
#elif TFT_DC >= 0
#ifdef RPI_ILI9486_DRIVER // RPi ILI9486 display needs a slower DC change
#define DC_C GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#elif defined (RPI_DRIVER) // Other RPi displays need a slower C->D change
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#else
#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)
#endif
#else
#define DC_C
#define DC_D
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the CS (TFT chip select) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_CS
#define CS_L // No macro allocated so it generates no code
#define CS_H // No macro allocated so it generates no code
#else
#if defined (TFT_PARALLEL_8_BIT)
#if TFT_CS >= 32
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#elif TFT_CS >= 0
#define CS_L GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS)
#else
#define CS_L
#define CS_H
#endif
#else
#if TFT_CS >= 32
#ifdef RPI_ILI9486_DRIVER // RPi ILI9486 display needs a slower CS change
#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))
#else
#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))
#endif
#elif TFT_CS >= 0
#ifdef RPI_ILI9486_DRIVER // RPi ILI9486 display needs a slower CS change
#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)
#else
#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)
#endif
#else
#define CS_L
#define CS_H
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_WR
#define WR_L GPIO.out_w1tc = (1 << TFT_WR)
#define WR_H GPIO.out_w1ts = (1 << TFT_WR)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the touch screen chip select pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TOUCH_CS
#define T_CS_L // No macro allocated so it generates no code
#define T_CS_H // No macro allocated so it generates no code
#else // XPT2046 is slow, so use slower digitalWrite here
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_MISO is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT)
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the parallel bus interface chip pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_PARALLEL_8_BIT)
// Create a bit set lookup table for data bus - wastes 1kbyte of RAM but speeds things up dramatically
// can then use e.g. GPIO.out_w1ts = set_mask(0xFF); to set data bus to 0xFF
#define CONSTRUCTOR_INIT_TFT_DATA_BUS \
for (int32_t c = 0; c<256; c++) \
{ \
xset_mask[c] = 0; \
if ( c & 0x01 ) xset_mask[c] |= (1 << TFT_D0); \
if ( c & 0x02 ) xset_mask[c] |= (1 << TFT_D1); \
if ( c & 0x04 ) xset_mask[c] |= (1 << TFT_D2); \
if ( c & 0x08 ) xset_mask[c] |= (1 << TFT_D3); \
if ( c & 0x10 ) xset_mask[c] |= (1 << TFT_D4); \
if ( c & 0x20 ) xset_mask[c] |= (1 << TFT_D5); \
if ( c & 0x40 ) xset_mask[c] |= (1 << TFT_D6); \
if ( c & 0x80 ) xset_mask[c] |= (1 << TFT_D7); \
} \
// Mask for the 8 data bits to set pin directions
#define dir_mask ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7))
// Data bits and the write line are cleared to 0 in one step
#define clr_mask (dir_mask | (1 << TFT_WR))
// A lookup table is used to set the different bit patterns, this uses 1kByte of RAM
#define set_mask(C) xset_mask[C] // 63fps Sprite rendering test 33% faster, graphicstest only 1.8% faster than shifting in real time
// Real-time shifting alternative to above to save 1KByte RAM, 47 fps Sprite rendering test
/*#define set_mask(C) (((C)&0x80)>>7)<<TFT_D7 | (((C)&0x40)>>6)<<TFT_D6 | (((C)&0x20)>>5)<<TFT_D5 | (((C)&0x10)>>4)<<TFT_D4 | \
(((C)&0x08)>>3)<<TFT_D3 | (((C)&0x04)>>2)<<TFT_D2 | (((C)&0x02)>>1)<<TFT_D1 | (((C)&0x01)>>0)<<TFT_D0
//*/
// Write 8 bits to TFT
#define tft_Write_8(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C)); WR_H
// Write 16 bits to TFT
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)((C) >> 0)); WR_H
// 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
// Write 32 bits to TFT
#define tft_Write_32(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 24)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 16)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
// Write two concatenated 16 bit values to TFT
#define tft_Write_32C(C,D) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 0)); WR_H
// Write 16 bit value twice to TFT - used by drawPixel()
#define tft_Write_32D(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
// Read pin
#ifdef TFT_RD
#define RD_L GPIO.out_w1tc = (1 << TFT_RD)
//#define RD_L digitalWrite(TFT_WR, LOW)
#define RD_H GPIO.out_w1ts = (1 << TFT_RD)
//#define RD_H digitalWrite(TFT_WR, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an ILI9488 TFT
////////////////////////////////////////////////////////////////////////////////////////
#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)
// 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)
// 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) & 0xE000)>>11 | ((C) & 0x07)<<5); \
spi.transfer(((C) & 0x1F00)>>5)
// Write 32 bits to TFT
#define tft_Write_32(C) spi.write32(C)
// Write two concatenated 16 bit values to TFT
#define tft_Write_32C(C,D) spi.write32((C)<<16 | (D))
// Write 16 bit value twice to TFT
#define tft_Write_32D(C) spi.write32((C)<<16 | (C))
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an Raspberry Pi TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_DRIVER)
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS((C)<<8, 16)
// Write 16 bits with corrected endianess for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((C)<<24 | (C), 32); \
TFT_WRITE_BITS((D)<<24 | (D), 32)
// Write same value twice
#define tft_Write_32D(C) tft_Write_32C(C,C)
////////////////////////////////////////////////////////////////////////////////////////
// Macros for all other SPI displays
////////////////////////////////////////////////////////////////////////////////////////
#else
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
// Write 16 bits with corrected endianess for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
// Write same value twice
#define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to read from display using SPI or software SPI
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT)
// Read from display using SPI or software SPI
// Use a SPI read transfer
#define tft_Read_8() spi.transfer(0)
#endif
// Concatenate a byte sequence A,B,C,D to CDAB, P is a uint8_t pointer
#define DAT8TO32(P) ( (uint32_t)P[0]<<8 | P[1] | P[2]<<24 | P[3]<<16 )
#endif // Header end

View File

@ -0,0 +1,403 @@
//////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP8266 processors //
//////////////////////////////////////////////////////
// Select the SPI port to use
// ESP8266 default (FLASH port also available via overlap mode)
SPIClass& spi = SPI;
// Buffer for SPI transmit byte padding and byte order manipulation
uint8_t spiBuffer[8] = {0,0,0,0,0,0,0,0};
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: tft_Read_8
** Description: ESP8266 software SPI to read bidirectional SDA line
***************************************************************************************/
uint8_t TFT_eSPI::tft_Read_8(void)
{
uint8_t ret = 0;
uint32_t reg = 0;
for (uint8_t i = 0; i < 8; i++) { // read results
ret <<= 1;
SCLK_L;
if (digitalRead(TFT_MOSI)) ret |= 1;
SCLK_H;
}
return ret;
}
/***************************************************************************************
** Function name: beginSDA
** Description: Detach SPI from pin to permit software SPI
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
#ifdef TFT_SPI_OVERLAP
// Reads in overlap mode not supported
#else
spi.end();
#endif
}
/***************************************************************************************
** Function name: endSDA
** Description: Attach SPI pins after software SPI
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
#ifdef TFT_SPI_OVERLAP
spi.pins(6, 7, 8, 0);
#else
spi.begin();
#endif
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: read byte - supports class functions
** Description: Parallel bus only - dummy function - not used
***************************************************************************************/
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0xAA;
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#if defined (RPI_WRITE_STROBE)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 or ESP8266 RPi TFT
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
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;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 or ESP8266 RPi TFT
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
uint8_t *data = (uint8_t*)data_in;
while ( len >=64 ) {spi.writePattern(data, 64, 1); data += 64; len -= 64; }
if (len) spi.writePattern(data, len, 1);
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 or ESP8266 RPi TFT
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
while ( len-- ) {tft_Write_16(*data); data++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (ILI9488_DRIVER)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP8266 and 3 byte RGB display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
// Split out the colours
uint8_t r = (color & 0xF800)>>8;
uint8_t g = (color & 0x07E0)>>3;
uint8_t b = (color & 0x001F)<<3;
// Concatenate 4 pixels into three 32 bit blocks
uint32_t r0 = r<<24 | b<<16 | g<<8 | r;
uint32_t r1 = g<<24 | r<<16 | b<<8 | g;
uint32_t r2 = b<<24 | g<<16 | r<<8 | b;
SPI1W0 = r0;
SPI1W1 = r1;
SPI1W2 = r2;
if (len > 4)
{
SPI1W3 = r0;
SPI1W4 = r1;
SPI1W5 = r2;
}
if (len > 8)
{
SPI1W6 = r0;
SPI1W7 = r1;
SPI1W8 = r2;
}
if (len > 12)
{
SPI1W9 = r0;
SPI1W10 = r1;
SPI1W11 = r2;
SPI1W12 = r0;
SPI1W13 = r1;
SPI1W14 = r2;
SPI1W15 = r0;
}
if (len > 20)
{
SPI1U1 = (503 << SPILMOSI);
while(len>20)
{
while(SPI1CMD & SPIBUSY) {}
SPI1CMD |= SPIBUSY;
len -= 21;
}
while(SPI1CMD & SPIBUSY) {}
}
if (len)
{
len = (len * 24) - 1;
SPI1U1 = (len << SPILMOSI);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
}
/***************************************************************************************
** Function name: pushPixels - for ESP8266 and 3 byte RGB display
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
if (_swapBytes) while ( len-- ) { tft_Write_16S(*data); data++;}
else while ( len-- ) {tft_Write_16(*data); data++;}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP8266 and 3 byte RGB display
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
while ( len-- ) {tft_Write_16S(*data); data++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#else
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP8266
** Description: Write a block of pixels of the same colour
***************************************************************************************/
//Clear screen test 76.8ms theoretical. 81.5ms TFT_eSPI, 967ms Adafruit_ILI9341
//Performance 26.15Mbps@26.66MHz, 39.04Mbps@40MHz, 75.4Mbps@80MHz SPI clock
//Efficiency:
// TFT_eSPI 98.06% 97.59% 94.24%
// Adafruit_GFX 19.62% 14.31% 7.94%
//
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
/*
while (len>1) { tft_Write_32(color<<16 | color); len-=2;}
if (len) tft_Write_16(color);
return;
//*/
uint16_t color16 = (color >> 8) | (color << 8);
uint32_t color32 = color16 | color16 << 16;
/*
while(len--) {
SPI1U1 = ((16-1) << SPILMOSI) | ((16-1) << SPILMISO);
SPI1W0 = color16;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
return;
//*/
SPI1W0 = color32;
SPI1W1 = color32;
SPI1W2 = color32;
SPI1W3 = color32;
if (len > 8)
{
SPI1W4 = color32;
SPI1W5 = color32;
SPI1W6 = color32;
SPI1W7 = color32;
}
if (len > 16)
{
SPI1W8 = color32;
SPI1W9 = color32;
SPI1W10 = color32;
SPI1W11 = color32;
}
if (len > 24)
{
SPI1W12 = color32;
SPI1W13 = color32;
SPI1W14 = color32;
SPI1W15 = color32;
}
if (len > 31)
{
SPI1U1 = (511 << SPILMOSI);
while(len>31)
{
#if defined SPI_FREQUENCY && (SPI_FREQUENCY == 80000000)
if(SPI1CMD & SPIBUSY) // added to sync with flag change
#endif
while(SPI1CMD & SPIBUSY) {}
SPI1CMD |= SPIBUSY;
len -= 32;
}
while(SPI1CMD & SPIBUSY) {}
}
if (len)
{
len = (len << 4) - 1;
SPI1U1 = (len << SPILMOSI);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
}
/***************************************************************************************
** Function name: pushPixels - for ESP8266
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
if(_swapBytes) {
pushSwapBytePixels(data_in, len);
return;
}
uint16_t *data = (uint16_t*) data_in;
uint32_t color[8];
SPI1U1 = (255 << SPILMOSI) | (255 << SPILMISO);
while(len>15)
{
memcpy(color,data,32);
data+=16;
len -= 16;
// ESP8266 wait time here at 40MHz SPI is ~5.45us
while(SPI1CMD & SPIBUSY) {}
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
if(len)
{
uint32_t bits = (len*16-1); // bits left to shift - 1
memcpy(color,data,len<<1);
while(SPI1CMD & SPIBUSY) {}
SPI1U1 = (bits << SPILMOSI) | (bits << SPILMISO);
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP8266
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint8_t* data = (uint8_t*)data_in;
//uint16_t* data = (uint16_t*)data_in;
uint32_t color[8];
SPI1U1 = (255 << SPILMOSI) | (255 << SPILMISO);
while(len>15)
{
uint32_t i = 0;
while(i<8) { color[i++] = DAT8TO32(data); data+=4; }
len -= 16;
// ESP8266 wait time here at 40MHz SPI is ~5.45us
while(SPI1CMD & SPIBUSY) {}
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
if(len)
{
uint32_t i = 0;
uint32_t bits = (len*16-1); // bits left to shift - 1
len = (len+1)>>1;
while(len--) { color[i++] = DAT8TO32(data); data+=4; }
while(SPI1CMD & SPIBUSY) {}
SPI1U1 = (bits << SPILMOSI) | (bits << SPILMISO);
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
}
////////////////////////////////////////////////////////////////////////////////////////
#endif
////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,243 @@
//////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP8266 processors //
//////////////////////////////////////////////////////
#ifndef _TFT_eSPI_ESP8266H_
#define _TFT_eSPI_ESP8266H_
// Processor ID reported by getSetup()
#define PROCESSOR_ID 0x8266
// Include processor specific header
// None
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
#define SET_SPI_WRITE_MODE SPI1U=SPI1U_WRITE
#define SET_SPI_READ_MODE SPI1U=SPI1U_READ
// Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions
#define DMA_BUSY_CHECK // DMA not available, leave blank
// Initialise processor specific SPI functions, used by init()
#if !defined (SUPPORT_TRANSACTIONS) && defined (ESP8266)
#define INIT_TFT_DATA_BUS \
spi.setBitOrder(MSBFIRST); \
spi.setDataMode(TFT_SPI_MODE); \
spi.setFrequency(SPI_FREQUENCY);
#else
#define INIT_TFT_DATA_BUS
#endif
// If smooth fonts are enabled the filing system may need to be loaded
#ifdef SMOOTH_FONT
// Call up the SPIFFS FLASH filing system for the anti-aliased fonts
#define FS_NO_GLOBALS
#include <FS.h>
#endif
// Do not allow parallel mode for ESP8266
#ifdef ESP32_PARALLEL
#undef ESP32_PARALLEL
#endif
#ifdef TFT_PARALLEL_8_BIT
#undef TFT_PARALLEL_8_BIT
#endif
// If it is a 16bit serial display we must transfer 16 bits every time
// Set commands bits to 16 or 8
#ifdef RPI_ILI9486_DRIVER
#ifndef RPI_DRIVER
#define RPI_DRIVER
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the DC (TFT Data/Command or Register Select (RS))pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_DC
#define DC_C // No macro allocated so it generates no code
#define DC_D // No macro allocated so it generates no code
#else
#if (TFT_DC == 16)
#define DC_C digitalWrite(TFT_DC, LOW)
#define DC_D digitalWrite(TFT_DC, HIGH)
#else
#define DC_C GPOC=dcpinmask
#define DC_D GPOS=dcpinmask
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the CS (TFT chip select) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_CS
#define CS_L // No macro allocated so it generates no code
#define CS_H // No macro allocated so it generates no code
#else
#if (TFT_CS == 16)
#define CS_L digitalWrite(TFT_CS, LOW)
#define CS_H digitalWrite(TFT_CS, HIGH)
#else
#define CS_L GPOC=cspinmask
#define CS_H GPOS=cspinmask
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_WR
#define WR_L GPOC=wrpinmask
#define WR_H GPOS=wrpinmask
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the touch screen chip select pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TOUCH_CS
#define T_CS_L // No macro allocated so it generates no code
#define T_CS_H // No macro allocated so it generates no code
#else
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_MISO is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
////////////////////////////////////////////////////////////////////////////////////////
// ESP8266 specific SPI macros
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SPI_OVERLAP)
#undef TFT_CS
#define SPI1U_WRITE (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD)
#define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD | SPIUDUPLEX)
#else
#define SPI1U_WRITE (SPIUMOSI | SPIUSSE)
#define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUDUPLEX)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an ILI9488 TFT
////////////////////////////////////////////////////////////////////////////////////////
#if 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)
// 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)
// 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) & 0xE000)>>11 | ((C) & 0x07)<<5); \
spi.transfer(((C) & 0x1F00)>>5)
// Write 32 bits to TFT
#define tft_Write_32(C) spi.write32(C)
// Write two address coordinates
#define tft_Write_32C(C,D) spi.write32((C)<<16 | (D))
// Write same value twice
#define tft_Write_32D(C) spi.write32((C)<<16 | (C))
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an Raspberry Pi TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_DRIVER)
// Command is 16 bits
#define CMD_BITS 16
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
SPI1U1 = ((B-1) << SPILMOSI); \
SPI1W0 = D; \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {}
#define tft_Write_8(C) TFT_WRITE_BITS((uint16_t)(C)<<8, CMD_BITS)
#define tft_Write_16(C) TFT_WRITE_BITS((C)>>8 | (C)<<8, 16)
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
#define tft_Write_32C(C,D) SPI1U1 = ((64-1) << SPILMOSI); \
SPI1W0 = ((C)<<24) | (C); \
SPI1W1 = ((D)<<24) | (D); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32D(C) tft_Write_32C(C,C)
////////////////////////////////////////////////////////////////////////////////////////
// Macros for all other SPI displays
////////////////////////////////////////////////////////////////////////////////////////
#else
// Command is 8 bits
#define CMD_BITS (8-1)
#define tft_Write_8(C) \
SPI1U1 = (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO); \
SPI1W0 = (C)<<(CMD_BITS + 1 - 8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_16(C) \
SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \
SPI1W0 = ((C)<<8 | (C)>>8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_16S(C) \
SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \
SPI1W0 = C; \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32(C) \
SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \
SPI1W0 = C; \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32C(C,D) \
SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \
SPI1W0 = ((D)>>8 | (D)<<8)<<16 | ((C)>>8 | (C)<<8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32D(C) \
SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \
SPI1W0 = ((C)>>8 | (C)<<8)<<16 | ((C)>>8 | (C)<<8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to read from display using SPI or software SPI
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ)
// Use a bit banged function call for ESP8266 and bi-directional SDA pin
#define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8(void);
#define SCLK_L GPOC=sclkpinmask
#define SCLK_H GPOS=sclkpinmask
#else
// Use a SPI read transfer
#define tft_Read_8() spi.transfer(0)
#endif
// Concatenate a byte sequence A,B,C,D to CDAB, P is a uint8_t pointer
#define DAT8TO32(P) ( (uint32_t)P[0]<<8 | P[1] | P[2]<<24 | P[3]<<16 )
#endif // Header end

View File

@ -12,10 +12,12 @@ You can take this one step further and have your own setup select file and then
To select a new setup you then edit your own my_setup_select.h file (which will not get over-written during an upgrade).
# News
1. A new beta test branch has been added to support other processors, in particular STM32:
1. The ST7789 display controller has been added. The ST7796 RPi MHS-4.0 inch Display-B type display is supported (this is fast for a SPI display as an ESP32 can clock it at 80MHz (ESP8266 at 40MHz)), see setups 27 and 28.
2. A new beta test branch has been added to support other processors, in particular STM32:
https://github.com/Bodmer/TFT_eSPI/tree/STM32
2. A callback function has been added, this allows antialiased fonts to be rendered over colour gradients or images. Two new examples have been added to illustrate this new capability:
3. A callback function has been added, this allows antialiased fonts to be rendered over colour gradients or images. Two new examples have been added to illustrate this new capability:
"Smooth_font_reading_TFT"
@ -23,25 +25,22 @@ To select a new setup you then edit your own my_setup_select.h file (which will
![AA_gradien](https://i.imgur.com/YMBcPHp.png)
3. Sprites can now by pushed to the screen (or another Sprite) with a rotation angle. The new function is pushRotated(). Three new examples (Rotate_Sprite_1/2/3) have been added to show how the functions can be used to rotate text, images and to draw animated dials with moving needles.
4. Sprites can now by pushed to the screen (or another Sprite) with a rotation angle. The new function is pushRotated(). Three new examples (Rotate_Sprite_1/2/3) have been added to show how the functions can be used to rotate text, images and to draw animated dials with moving needles.
4. A new TFT_eFEX support library has been created which includes extra functions such as drawing a BMP or Jpeg to the screen. This library will simplify the examples. It will be expanded at a future date to include meters, dials and GUI elements like progress bars, graphs and animated buttons:
5. A new TFT_eFEX support library has been created which includes extra functions such as drawing a BMP or Jpeg to the screen. This library will simplify the examples. It will be expanded at a future date to include meters, dials and GUI elements like progress bars, graphs and animated buttons:
https://github.com/Bodmer/TFT_eFEX
5. androdlang has published a really nice companion library to extend the graphics capabilities of TFT_eSPI, you can find this here:
https://github.com/androdlang/TFTShape
6. I have created a user updateable graphics extension library template that can be used to create your own graphics extensions. The Library contains examples and is commented so it should be clear what you need to do to add functions. You can find it here:
https://github.com/Bodmer/TFT_eFX
# TFT_eSPI
An Arduino IDE compatible graphics and fonts library for ESP8266 and ESP32 processors with drivers for ILI9341, ILI9163, ST7735, S6D02A1, ILI9481, ILI9486, ILI9488, HX8357D and ST7789 based TFT displays that support SPI. The library can be loaded using the Arduino IDE's Library Manager.
An Arduino IDE compatible graphics and fonts library for ESP8266 and ESP32 processors with drivers for ILI9341, ILI9163, ST7735, S6D02A1, ILI9481, ILI9486, ILI9488, HX8357D, ST7789 and ST7796 based TFT displays that support SPI. The library can be loaded using the Arduino IDE's Library Manager.
8 bit parallel interface TFTs (e.g. UNO format mcufriend shields) can used with an ESP32.
The library supports TFT displays designed for the Raspberry Pi that are based on a ILI9486 driver chip with a 480 x 320 pixel screen. This display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. A modification to these displays is possible (see mod image in Tools folder) to make many graphics functions much faster (e.g. 23ms to clear the screen, 1.2ms to draw a 72 pixel high numeral).
The library supports TFT displays designed for the Raspberry Pi (RPi) that are based on a ILI9486 or ST7796 driver chip with a 480 x 320 pixel screen. The ILI9486 RPi display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. A modification to these displays is possible (see mod image in Tools folder) to make many graphics functions much faster (e.g. 23ms to clear the screen, 1.2ms to draw a 72 pixel high numeral). The RPi ST7796 display is superior to the Waveshare design, it must be of the MHS-4.0 inch Display-B type.
Some displays permit the internal TFT screen RAM to be read. The library supports reading from ILI9341, ST7789 and ILI9488 SPI displays for the ESP32 and ESP8266. The 8 bit parallel displays used with the ESP32 can usually can be read too. The TFT_Screen_Capture example allows full screens to be captured and sent to a PC, this is handy to create program documentation.

View File

@ -0,0 +1,108 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#define TFT_WIDTH 320
#define TFT_HEIGHT 480
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#define TFT_CASET 0x2A
#define TFT_PASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_IDXRD 0xDD // ILI9341 only, indexed control register read
#define TFT_MADCTL 0x36
#define TFT_MAD_MY 0x80
#define TFT_MAD_MX 0x40
#define TFT_MAD_MV 0x20
#define TFT_MAD_ML 0x10
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_RGB 0x00
#ifdef TFT_RGB_ORDER
#if (TFT_RGB_ORDER == 1)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21
// All ST7796 specific commands some are used by init()
#define ST7796_NOP 0x00
#define ST7796_SWRESET 0x01
#define ST7796_RDDID 0x04
#define ST7796_RDDST 0x09
#define ST7796_SLPIN 0x10
#define ST7796_SLPOUT 0x11
#define ST7796_PTLON 0x12
#define ST7796_NORON 0x13
#define ST7796_RDMODE 0x0A
#define ST7796_RDMADCTL 0x0B
#define ST7796_RDPIXFMT 0x0C
#define ST7796_RDIMGFMT 0x0A
#define ST7796_RDSELFDIAG 0x0F
#define ST7796_INVOFF 0x20
#define ST7796_INVON 0x21
#define ST7796_GAMMASET 0x26
#define ST7796_DISPOFF 0x28
#define ST7796_DISPON 0x29
#define ST7796_CASET 0x2A
#define ST7796_PASET 0x2B
#define ST7796_RAMWR 0x2C
#define ST7796_RAMRD 0x2E
#define ST7796_PTLAR 0x30
#define ST7796_VSCRDEF 0x33
#define ST7796_MADCTL 0x36
#define ST7796_VSCRSADD 0x37
#define ST7796_PIXFMT 0x3A
#define ST7796_WRDISBV 0x51
#define ST7796_RDDISBV 0x52
#define ST7796_WRCTRLD 0x53
#define ST7796_FRMCTR1 0xB1
#define ST7796_FRMCTR2 0xB2
#define ST7796_FRMCTR3 0xB3
#define ST7796_INVCTR 0xB4
#define ST7796_DFUNCTR 0xB6
#define ST7796_PWCTR1 0xC0
#define ST7796_PWCTR2 0xC1
#define ST7796_PWCTR3 0xC2
#define ST7796_PWCTR4 0xC3
#define ST7796_PWCTR5 0xC4
#define ST7796_VMCTR1 0xC5
#define ST7796_VMCTR2 0xC7
#define ST7796_RDID4 0xD3
#define ST7796_RDINDEX 0xD9
#define ST7796_RDID1 0xDA
#define ST7796_RDID2 0xDB
#define ST7796_RDID3 0xDC
#define ST7796_RDIDX 0xDD // TBC
#define ST7796_GMCTRP1 0xE0
#define ST7796_GMCTRN1 0xE1
#define ST7796_MADCTL_MY 0x80
#define ST7796_MADCTL_MX 0x40
#define ST7796_MADCTL_MV 0x20
#define ST7796_MADCTL_ML 0x10
#define ST7796_MADCTL_RGB 0x00
#define ST7796_MADCTL_BGR 0x08
#define ST7796_MADCTL_MH 0x04

110
TFT_Drivers/ST7796_Init.h Normal file
View File

@ -0,0 +1,110 @@
// This is the command sequence that initialises the ST7796 driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
//
// See ST7735_Setup.h file for an alternative format
#define TFT_INIT_DELAY 0
{
delay(120);
writecommand(0x01); //Software reset
delay(120);
writecommand(0x11); //Sleep exit
delay(120);
writecommand(0xF0); //Command Set control
writedata(0xC3); //Enable extension command 2 partI
writecommand(0xF0); //Command Set control
writedata(0x96); //Enable extension command 2 partII
writecommand(0x36); //Memory Data Access Control MX, MY, RGB mode
writedata(0x48); //X-Mirror, Top-Left to right-Buttom, RGB
writecommand(0x3A); //Interface Pixel Format
writedata(0x05); //Control interface color format set to 16
writecommand(0xB4); //Column inversion
writedata(0x01); //1-dot inversion
writecommand(0xB6); //Display Function Control
writedata(0x20); //RGB interface for RAM access, RGB transfer in DE mode
//display data path in memory
//Gate outputs in non-display area in Normal scan
//Source output in non-display area =V63
writedata(0x02); //Source Output Scan from S1 to S960, Gate Output scan from G1 to G480, scan cycle=2
writedata(0x3B); //LCD Drive Line=8*(59+1)
writecommand(0xE8); //Display Output Ctrl Adjust
writedata(0x40);
writedata(0x8A);
writedata(0x00);
writedata(0x00);
writedata(0x29); //Source eqaulizing period time= 22.5 us
writedata(0x19); //Timing for "Gate start"=25 (Tclk)
writedata(0xA5); //Timing for "Gate End"=37 (Tclk), Gate driver EQ function ON
writedata(0x33);
writecommand(0xC1); //Power control2
writedata(0x06); //VAP(GVDD)=3.85+( vcom+vcom offset), VAN(GVCL)=-3.85+( vcom+vcom offset)
writecommand(0xC2); //Power control 3
writedata(0xA7); //Source driving current level=low, Gamma driving current level=High
writecommand(0xC5); //VCOM Control
writedata(0x18); //VCOM=0.9
delay(120);
//ST7796 Gamma Sequence
writecommand(0xE0); //Gamma"+"
writedata(0xF0);
writedata(0x09);
writedata(0x0b);
writedata(0x06);
writedata(0x04);
writedata(0x15);
writedata(0x2F);
writedata(0x54);
writedata(0x42);
writedata(0x3C);
writedata(0x17);
writedata(0x14);
writedata(0x18);
writedata(0x1B);
writecommand(0xE1); //Gamma"-"
writedata(0xE0);
writedata(0x09);
writedata(0x0B);
writedata(0x06);
writedata(0x04);
writedata(0x03);
writedata(0x2B);
writedata(0x43);
writedata(0x42);
writedata(0x3B);
writedata(0x16);
writedata(0x14);
writedata(0x17);
writedata(0x1B);
delay(120);
writecommand(0xF0); //Command Set control
writedata(0x3C); //Disable extension command 2 partI
writecommand(0xF0); //Command Set control
writedata(0x69); //Disable extension command 2 partII
spi_end();
delay(120);
spi_begin();
writecommand(0x29); //Display on
}

View File

@ -0,0 +1,50 @@
// This is the command sequence that rotates the ST7796 driver coordinate frame
rotation = m % 8; // Limit the range of values to 0-7
writecommand(TFT_MADCTL);
switch (rotation) {
case 0:
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 1:
writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 2:
writedata(TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 3:
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
// These next rotations are for bottom up BMP drawing
case 4:
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 5:
writedata(TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 6:
writedata(TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 7:
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -15,14 +15,36 @@
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "1.4.21"
//#define ESP32 //Just used to test ESP32 options
#define TFT_ESPI_VERSION "1.4.30"
// Include header file that defines the fonts loaded, the TFT drivers
// available and the pins to be used
// available and the pins to be used, etc, etc
#include <User_Setup_Select.h>
//Standard support
#include <Arduino.h>
#include <Print.h>
#include <SPI.h>
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#else
#define PROGMEM
#endif
// Include the processor specific drivers
#if defined (ESP32)
#include "Processors/TFT_eSPI_ESP32.h"
#elif defined (ESP8266)
#include "Processors/TFT_eSPI_ESP8266.h"
#elif defined (STM32)
//#include "Processors/TFT_eSPI_STM32.h"
#else
//#include "Processors/TFT_eSPI_Generic.h"
#endif
#ifndef TAB_COLOUR
#define TAB_COLOUR 0
#endif
@ -98,398 +120,12 @@
#endif
#endif
#include <Arduino.h>
#include <Print.h>
#include <pgmspace.h>
#include <SPI.h>
#ifdef ESP32
#include "soc/spi_reg.h"
#ifdef USE_HSPI_PORT
#define SPI_PORT HSPI
#else
#define SPI_PORT VSPI
#endif
#endif
#ifdef SMOOTH_FONT
// Call up the SPIFFS FLASH filing system for the anti-aliased fonts
#define FS_NO_GLOBALS
#include <FS.h>
#ifdef ESP32
#include "SPIFFS.h"
#endif
#endif
#ifndef TFT_DC
#define DC_C // No macro allocated so it generates no code
#define DC_D // No macro allocated so it generates no code
#else
#if defined (ESP8266) && (TFT_DC == 16)
#define DC_C digitalWrite(TFT_DC, LOW)
#define DC_D digitalWrite(TFT_DC, HIGH)
#elif defined (ESP32)
#if defined (ESP32_PARALLEL)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)
#else
#if TFT_DC >= 32
#ifdef RPI_ILI9486_DRIVER // RPi display needs a slower DC change
#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))
#else
#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))
#endif
#else
#if TFT_DC >= 0
#ifdef RPI_ILI9486_DRIVER // RPi display needs a slower DC change
#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)
#else
#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)
#endif
#else
#define DC_C
#define DC_D
#endif
#endif
#endif
#else
#define DC_C GPOC=dcpinmask
#define DC_D GPOS=dcpinmask
#endif
#endif
#if defined (TFT_SPI_OVERLAP)
#undef TFT_CS
#define SPI1U_WRITE (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD)
#define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD | SPIUDUPLEX)
#else
#ifdef ESP8266
#define SPI1U_WRITE (SPIUMOSI | SPIUSSE)
#define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUDUPLEX)
#endif
#endif
#ifndef TFT_CS
#define CS_L // No macro allocated so it generates no code
#define CS_H // No macro allocated so it generates no code
#else
#if defined (ESP8266) && (TFT_CS == 16)
#define CS_L digitalWrite(TFT_CS, LOW)
#define CS_H digitalWrite(TFT_CS, HIGH)
#elif defined (ESP32)
#if defined (ESP32_PARALLEL)
#if TFT_CS >= 32
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#elif TFT_CS >= 0
#define CS_L GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS)
#else
#define CS_L
#define CS_H
#endif
#else
#if TFT_CS >= 32
#ifdef RPI_ILI9486_DRIVER // RPi display needs a slower CS change
#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))
#else
#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))
#endif
#else
#if TFT_CS >= 0
#ifdef RPI_ILI9486_DRIVER // RPi display needs a slower CS change
#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)
#else
#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)
#endif
#else
#define CS_L
#define CS_H
#endif
#endif
#endif
#else
#define CS_L GPOC=cspinmask
#define CS_H GPOS=cspinmask
#endif
#endif
// Use single register write for CS_L and DC_C if pins are both in range 0-31
#ifdef ESP32
#ifdef TFT_CS
#if (TFT_CS >= 0) && (TFT_CS < 32) && (TFT_DC >= 0) && (TFT_DC < 32)
#ifdef RPI_ILI9486_DRIVER // RPi display needs a slower CD and DC change
#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 GPIO.out_w1tc = ((1 << TFT_CS) | (1 << TFT_DC)); GPIO.out_w1tc = ((1 << TFT_CS) | (1 << TFT_DC))
#endif
#else
#define CS_L_DC_C CS_L; DC_C
#endif
#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
#define T_CS_H // No macro allocated so it generates no code
#else
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
#ifdef TFT_WR
#if defined (ESP32)
#define WR_L GPIO.out_w1tc = (1 << TFT_WR)
#define WR_H GPIO.out_w1ts = (1 << TFT_WR)
#else
#define WR_L GPOC=wrpinmask
#define WR_H GPOS=wrpinmask
#endif
#endif
#ifdef ESP8266
// Concatenate two 16 bit values for the SPI 32 bit register write
#define SPI_32(H,L) ( (H)<<16 | (L) )
#define COL_32(H,L) ( (H)<<16 | (L) )
#else
#if defined (ESP32_PARALLEL) || defined (ILI9488_DRIVER)
#define SPI_32(H,L) ( (H)<<16 | (L) )
#else
#define SPI_32(H,L) ( ((H)<<8 | (H)>>8) | (((L)<<8 | (L)>>8)<<16 ) )
#endif
// Swap byte order for concatenated 16 bit colors
// AB CD -> DCBA for 32 bit register write
#define COL_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
#define dir_mask ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7))
// Data bits and the write line are cleared to 0 in one step
#define clr_mask (dir_mask | (1 << TFT_WR))
// A lookup table is used to set the different bit patterns, this uses 1kByte of RAM
#define set_mask(C) xset_mask[C] // 63fps Sprite rendering test 33% faster, graphicstest only 1.8% faster than shifting in real time
// Real-time shifting alternative to above to save 1KByte RAM, 47 fps Sprite rendering test
/*#define set_mask(C) ((C&0x80)>>7)<<TFT_D7 | ((C&0x40)>>6)<<TFT_D6 | ((C&0x20)>>5)<<TFT_D5 | ((C&0x10)>>4)<<TFT_D4 | \
((C&0x08)>>3)<<TFT_D3 | ((C&0x04)>>2)<<TFT_D2 | ((C&0x02)>>1)<<TFT_D1 | ((C&0x01)>>0)<<TFT_D0
//*/
// Write 8 bits to TFT
#define tft_Write_8(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)C); WR_H
// Write 16 bits to TFT
#ifdef PSEUDO_8_BIT
#define tft_Write_16(C) WR_L;GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H
#else
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H
#endif
// 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H
// Write 32 bits to TFT
#define tft_Write_32(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 24)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 16)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H
#ifdef TFT_RD
#define RD_L GPIO.out_w1tc = (1 << TFT_RD)
//#define RD_L digitalWrite(TFT_WR, LOW)
#define RD_H GPIO.out_w1ts = (1 << TFT_RD)
//#define RD_H digitalWrite(TFT_WR, HIGH)
#endif
#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)
// 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)
// 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 & 0xE000)>>11 | (C & 0x07)<<5); \
spi.transfer((C & 0x1F00)>>5)
// Write 32 bits to TFT
#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_16S(C) spi.write16(C<<8 | C>>8)
#define tft_Write_32(C) spi.write32(C)
#elif defined ESP8266
#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_PORT), 8-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), C); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&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_PORT), 16-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), C<<8 | C>>8); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 16 bits
#define tft_Write_16S(C) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 16-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), C); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 32 bits
#define tft_Write_32(C) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 32-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), C); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
#endif
#if !defined (ESP32_PARALLEL)
// Read from display using SPI or software SPI
#if defined (ESP8266) && defined (TFT_SDA_READ)
// Use a bit banged function call for ESP8266 and bi-directional SDA pin
#define SCLK_L GPOC=sclkpinmask
#define SCLK_H GPOS=sclkpinmask
#else
// Use a SPI read transfer
#define tft_Read_8() spi.transfer(0)
#endif
// Make sure TFT_MISO is defined if not used to avoid an error message
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
#endif
#ifdef LOAD_GFXFF
// We can include all the free fonts and they will only be built into
// the sketch if they are used
#include <Fonts/GFXFF/gfxfont.h>
// Call up any user custom fonts
#include <User_Setups/User_Custom_Fonts.h>
// Original Adafruit_GFX "Free Fonts"
#include <Fonts/GFXFF/TomThumb.h> // TT1
#include <Fonts/GFXFF/FreeMono9pt7b.h> // FF1 or FM9
#include <Fonts/GFXFF/FreeMono12pt7b.h> // FF2 or FM12
#include <Fonts/GFXFF/FreeMono18pt7b.h> // FF3 or FM18
#include <Fonts/GFXFF/FreeMono24pt7b.h> // FF4 or FM24
#include <Fonts/GFXFF/FreeMonoOblique9pt7b.h> // FF5 or FMO9
#include <Fonts/GFXFF/FreeMonoOblique12pt7b.h> // FF6 or FMO12
#include <Fonts/GFXFF/FreeMonoOblique18pt7b.h> // FF7 or FMO18
#include <Fonts/GFXFF/FreeMonoOblique24pt7b.h> // FF8 or FMO24
#include <Fonts/GFXFF/FreeMonoBold9pt7b.h> // FF9 or FMB9
#include <Fonts/GFXFF/FreeMonoBold12pt7b.h> // FF10 or FMB12
#include <Fonts/GFXFF/FreeMonoBold18pt7b.h> // FF11 or FMB18
#include <Fonts/GFXFF/FreeMonoBold24pt7b.h> // FF12 or FMB24
#include <Fonts/GFXFF/FreeMonoBoldOblique9pt7b.h> // FF13 or FMBO9
#include <Fonts/GFXFF/FreeMonoBoldOblique12pt7b.h> // FF14 or FMBO12
#include <Fonts/GFXFF/FreeMonoBoldOblique18pt7b.h> // FF15 or FMBO18
#include <Fonts/GFXFF/FreeMonoBoldOblique24pt7b.h> // FF16 or FMBO24
// Sans serif fonts
#include <Fonts/GFXFF/FreeSans9pt7b.h> // FF17 or FSS9
#include <Fonts/GFXFF/FreeSans12pt7b.h> // FF18 or FSS12
#include <Fonts/GFXFF/FreeSans18pt7b.h> // FF19 or FSS18
#include <Fonts/GFXFF/FreeSans24pt7b.h> // FF20 or FSS24
#include <Fonts/GFXFF/FreeSansOblique9pt7b.h> // FF21 or FSSO9
#include <Fonts/GFXFF/FreeSansOblique12pt7b.h> // FF22 or FSSO12
#include <Fonts/GFXFF/FreeSansOblique18pt7b.h> // FF23 or FSSO18
#include <Fonts/GFXFF/FreeSansOblique24pt7b.h> // FF24 or FSSO24
#include <Fonts/GFXFF/FreeSansBold9pt7b.h> // FF25 or FSSB9
#include <Fonts/GFXFF/FreeSansBold12pt7b.h> // FF26 or FSSB12
#include <Fonts/GFXFF/FreeSansBold18pt7b.h> // FF27 or FSSB18
#include <Fonts/GFXFF/FreeSansBold24pt7b.h> // FF28 or FSSB24
#include <Fonts/GFXFF/FreeSansBoldOblique9pt7b.h> // FF29 or FSSBO9
#include <Fonts/GFXFF/FreeSansBoldOblique12pt7b.h> // FF30 or FSSBO12
#include <Fonts/GFXFF/FreeSansBoldOblique18pt7b.h> // FF31 or FSSBO18
#include <Fonts/GFXFF/FreeSansBoldOblique24pt7b.h> // FF32 or FSSBO24
// Serif fonts
#include <Fonts/GFXFF/FreeSerif9pt7b.h> // FF33 or FS9
#include <Fonts/GFXFF/FreeSerif12pt7b.h> // FF34 or FS12
#include <Fonts/GFXFF/FreeSerif18pt7b.h> // FF35 or FS18
#include <Fonts/GFXFF/FreeSerif24pt7b.h> // FF36 or FS24
#include <Fonts/GFXFF/FreeSerifItalic9pt7b.h> // FF37 or FSI9
#include <Fonts/GFXFF/FreeSerifItalic12pt7b.h> // FF38 or FSI12
#include <Fonts/GFXFF/FreeSerifItalic18pt7b.h> // FF39 or FSI18
#include <Fonts/GFXFF/FreeSerifItalic24pt7b.h> // FF40 or FSI24
#include <Fonts/GFXFF/FreeSerifBold9pt7b.h> // FF41 or FSB9
#include <Fonts/GFXFF/FreeSerifBold12pt7b.h> // FF42 or FSB12
#include <Fonts/GFXFF/FreeSerifBold18pt7b.h> // FF43 or FSB18
#include <Fonts/GFXFF/FreeSerifBold24pt7b.h> // FF44 or FSB24
#include <Fonts/GFXFF/FreeSerifBoldItalic9pt7b.h> // FF45 or FSBI9
#include <Fonts/GFXFF/FreeSerifBoldItalic12pt7b.h> // FF46 or FSBI12
#include <Fonts/GFXFF/FreeSerifBoldItalic18pt7b.h> // FF47 or FSBI18
#include <Fonts/GFXFF/FreeSerifBoldItalic24pt7b.h> // FF48 or FSBI24
#endif // #ifdef LOAD_GFXFF
//These enumerate the text plotting alignment (reference datum point)
@ -542,7 +178,7 @@ 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))
// #define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
// This structure allows sketches to retrieve the user setup parameters at runtime
@ -550,7 +186,7 @@ swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
typedef struct
{
String version = TFT_ESPI_VERSION;
int16_t esp;
int32_t esp;
uint8_t trans;
uint8_t serial;
uint8_t overlap;
@ -702,7 +338,7 @@ class TFT_eSPI : public Print {
fillRoundRect(int32_t x0, int32_t y0, int32_t w, int32_t h, int32_t radius, uint32_t color),
setRotation(uint8_t r),
invertDisplay(boolean i),
invertDisplay(bool i),
drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color),
drawCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t cornername, uint32_t color),
@ -715,10 +351,12 @@ class TFT_eSPI : public Print {
drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color),
fillTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color),
drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color),
drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color),
drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor),
drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor),
drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor),
drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor),
setBitmapColor(uint16_t fgcolor, uint16_t bgcolor), // For 1bpp sprites
setPivot(int16_t x, int16_t y),
setCursor(int16_t x, int16_t y),
setCursor(int16_t x, int16_t y, uint8_t font),
@ -726,7 +364,7 @@ class TFT_eSPI : public Print {
setTextColor(uint16_t fgcolor, uint16_t bgcolor),
setTextSize(uint8_t size),
setTextWrap(boolean wrapX, boolean wrapY = false),
setTextWrap(bool wrapX, bool wrapY = false),
setTextDatum(uint8_t datum),
setTextPadding(uint16_t x_width),
@ -769,7 +407,13 @@ class TFT_eSPI : public Print {
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data, bool bpp8 = true);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true);
// Swap the byte order for pushImage() - corrects endianness
// Write a solid block of a single colour
void pushBlock(uint16_t color, uint32_t len);
// Write a set of pixels stored in memory, use setSwapBytes(true/false) function to correct endianess
void pushPixels(const void * data_in, uint32_t len);
// Swap the byte order for pushImage() and pushPixels() - corrects endianness
void setSwapBytes(bool swap);
bool getSwapBytes(void);
@ -820,15 +464,17 @@ class TFT_eSPI : public Print {
// Compatibility additions
void startWrite(void); // Begin SPI transaction
void writeColor(uint16_t color, uint32_t len); // Write colours without transaction overhead
void writeColor(uint16_t color, uint32_t len); // Write colours without transaction overhead Deprecated, use pushBlock()
void endWrite(void); // End SPI transaction
uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining);
uint16_t decodeUTF8(uint8_t c);
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
size_t write(uint8_t);
#ifdef TFT_SDA_READ
#if defined (ESP8266) && defined (TFT_SDA_READ)
#if defined (TFT_eSPI_ENABLE_8_BIT_READ)
uint8_t tft_Read_8(void);
#endif
void begin_SDA_Read(void);
@ -867,8 +513,20 @@ class TFT_eSPI : public Print {
inline void spi_begin_read() __attribute__((always_inline));
inline void spi_end_read() __attribute__((always_inline));
// Private function, sketches must use pushPixels() with setSwapBytes(true)
void pushSwapBytePixels(const void* data_in, uint32_t len);
void readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h);
// Byte read prototype
uint8_t readByte(void);
// GPIO parallel input/output control
void busDir(uint32_t mask, uint8_t mode);
// Single GPIO input/output direction control
void gpioMode(uint8_t gpio, uint8_t mode);
uint8_t tabcolor,
colstart = 0, rowstart = 0; // some ST7735 displays need this changed
@ -900,7 +558,7 @@ class TFT_eSPI : public Print {
bool isDigits; // adjust bounding box for numbers to reduce visual jiggling
bool textwrapX, textwrapY; // If set, 'wrap' text at right and optionally bottom edge of display
bool _swapBytes; // Swap the byte order for TFT pushImage()
bool locked, inTransaction; // Transaction and mutex lock flags for ESP32
bool locked, inTransaction; // Transaction and mutex lock flags
bool _booted; // init() or begin() has already run once
bool _cp437; // If set, use correct CP437 charset (default is ON)

View File

@ -15,6 +15,9 @@
//
// ##################################################################################
// Display type - only define if RPi display
//#define RPI_DRIVER
// Only define one driver, the other ones must be commented out
#define ILI9341_DRIVER
//#define ST7735_DRIVER // Define additional parameters below for this display
@ -29,6 +32,7 @@
//#define ST7789_2_DRIVER // Minimal configuration option, define additional parameters below for this display
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
// Some displays support SPI reads via the MISO pin, other displays have a single
// bi-directional SDA pin and the library will try to read this via the MOSI line.

View File

@ -52,6 +52,9 @@
//#include <User_Setups/Setup25_TTGO_T_Display.h> // Setup file for ESP32 and TTGO T-Display ST7789V SPI bus TFT
//#include <User_Setups/Setup26_TTGO_T_Wristband.h> // Setup file for ESP32 and TTGO T-Wristband ST7735 SPI bus TFT
//#include <User_Setups/Setup27_RPi_ST7796_ESP32.h> // ESP32 RPi MHS-4.0 inch Display-B
//#include <User_Setups/Setup28_RPi_ST7796_ESP8266.h> // ESP8266 RPi MHS-4.0 inch Display-B
//#include <User_Setups/Setup43_ST7735.h> // Setup file configured for my ST7735S 80x160
//#include <User_Setups/Setup135_ST7789.h> // Setup file for ESP8266 and ST7789 125 x 240 TFT
@ -89,6 +92,9 @@
#elif defined (S6D02A1_DRIVER)
#include <TFT_Drivers/S6D02A1_Defines.h>
#define TFT_DRIVER 0x6D02
#elif defined (ST7796_DRIVER)
#include "TFT_Drivers/ST7796_Defines.h"
#define TFT_DRIVER 0x7796
#elif defined (RPI_ILI9486_DRIVER)
#include <TFT_Drivers/ILI9486_Defines.h>
#define TFT_DRIVER 0x9486
@ -117,8 +123,8 @@
#include "TFT_Drivers/ST7789_2_Defines.h"
#define TFT_DRIVER 0x778B
#elif defined (RM68140_DRIVER)
#include "TFT_Drivers/RM68140_Defines.h"
#define TFT_DRIVER 0x6814
#include "TFT_Drivers/RM68140_Defines.h"
#define TFT_DRIVER 0x6814
#elif defined (XYZZY_DRIVER) // <<<<<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVER HERE
#include "TFT_Drivers/XYZZY_Defines.h"
#define TFT_DRIVER 0x0000

View File

@ -0,0 +1,100 @@
// USER DEFINED SETTINGS
// Set driver type, fonts to be loaded, pins used and SPI control method etc
//
// See the User_Setup_Select.h file if you wish to be able to define multiple
// setups and then easily select which setup file is used by the compiler.
//
// If this file is edited correctly then all the library example sketches should
// run without the need to make any more changes for a particular hardware setup!
// ##################################################################################
//
// Section 0. Call up the right driver file and any options for it
//
// ##################################################################################
// Display type - only define if RPi display
#define RPI_DRIVER
// Only define one driver
#define ST7796_DRIVER
// ##################################################################################
//
// Section 1. Define the pins that are used to interface with the display here
//
// ##################################################################################
// >>>>> EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP32 SETUP <<<<<
// The ESP32 hardware SPI can be mapped to any pins, these are the recommended default
#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 15 // Chip select control pin
#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 TOUCH_CS 22 // Chip select pin (T_CS) of touch screen
// ##################################################################################
//
// Section 2. Not used for ESP32
//
// ##################################################################################
// ##################################################################################
//
// Section 3. Define the fonts that are to be used here
//
// ##################################################################################
// Comment out the #defines below with // to stop that font being loaded
// The ESP8366 and ESP32 have plenty of memory so commenting out fonts is not
// normally necessary. If all fonts are loaded the extra FLASH space required is
// about 17Kbytes. To save FLASH space only enable the fonts you need!
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#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_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#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
// this will save ~20kbytes of FLASH
#define SMOOTH_FONT
// ##################################################################################
//
// Section 4. Not used
//
// ##################################################################################
// ##################################################################################
//
// Section 5. Other options
//
// ##################################################################################
// Define the SPI clock frequency, this affects the graphics rendering speed. Too
// fast and the TFT driver will not keep up and display corruption appears.
// With an RPi ST7796 MH4.0 display 80MHz is OK for ESP32, 40MHz maximum for ESP8266
// #define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 40000000
#define SPI_FREQUENCY 80000000
// The ESP32 has 2 free SPI ports i.e. VSPI and HSPI, the VSPI is the default.
// If the VSPI port is in use and pins are not accessible (e.g. TTGO T-Beam)
// then uncomment the following line:
//#define USE_HSPI_PORT
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY 2500000

View File

@ -0,0 +1,105 @@
// USER DEFINED SETTINGS
// Set driver type, fonts to be loaded, pins used and SPI control method etc
//
// See the User_Setup_Select.h file if you wish to be able to define multiple
// setups and then easily select which setup file is used by the compiler.
//
// If this file is edited correctly then all the library example sketches should
// run without the need to make any more changes for a particular hardware setup!
// ##################################################################################
//
// Section 0. Call up the right driver file and any options for it
//
// ##################################################################################
// Display type - only define if RPi display
#define RPI_DRIVER
// Only define one driver
#define ST7796_DRIVER
// ##################################################################################
//
// Section 1. Define the pins that are used to interface with the display here
//
// ##################################################################################
// >>>> EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP <<<<
// These are the recommended default
// Avoid PIN_D8 as this will prevent upload if display pulls the pin high at boot
// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS PIN_D2 // Chip select control pin D2
#define TFT_DC PIN_D3 // 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
#define TOUCH_CS PIN_D1 // Chip select pin (T_CS) of touch screen
// ##################################################################################
//
// Section 2. Not used for ESP32
//
// ##################################################################################
// ##################################################################################
//
// Section 3. Define the fonts that are to be used here
//
// ##################################################################################
// Comment out the #defines below with // to stop that font being loaded
// The ESP8366 and ESP32 have plenty of memory so commenting out fonts is not
// normally necessary. If all fonts are loaded the extra FLASH space required is
// about 17Kbytes. To save FLASH space only enable the fonts you need!
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#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_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#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
// this will save ~20kbytes of FLASH
#define SMOOTH_FONT
// ##################################################################################
//
// Section 4. Not used
//
// ##################################################################################
// ##################################################################################
//
// Section 5. Other options
//
// ##################################################################################
// Define the SPI clock frequency, this affects the graphics rendering speed. Too
// fast and the TFT driver will not keep up and display corruption appears.
// With an RPi ST7796 MH4.0 display 80MHz is OK for ESP32, 40MHz maximum for ESP8266
// #define SPI_FREQUENCY 20000000
#define SPI_FREQUENCY 40000000
#define SPI_TOUCH_FREQUENCY 2500000
// Comment out the following #define if "SPI Transactions" do not need to be
// supported. When commented out the code size will be smaller and sketches will
// run slightly faster, so leave it commented out unless you need it!
// Transaction support is needed to work with SD library but not needed with TFT_SdFat
// Transaction support is required if other SPI devices are connected.
// Transactions are automatically enabled by the library for an ESP32 (to use HAL mutex)
// so changing it here has no effect
#define SUPPORT_TRANSACTIONS

View File

@ -5,7 +5,6 @@ drawPixel KEYWORD2
drawChar KEYWORD2
setAddrWindow KEYWORD2
setWindow KEYWORD2
readAddrWindow KEYWORD2
startWrite KEYWORD2
writeColor KEYWORD2
endWrite KEYWORD2
@ -72,6 +71,21 @@ height KEYWORD2
width KEYWORD2
textWidth KEYWORD2
fontHeight KEYWORD2
getSetup KEYWORD2
setAttribute KEYWORD2
getAttribute KEYWORD2
alphaBlend KEYWORD2
getSPIinstance KEYWORD2
pushBlock KEYWORD2
pushPixels KEYWORD2
initDMA KEYWORD2
deInitDMA KEYWORD2
pushImageDMA KEYWORD2
pushBlockDMA KEYWORD2
pushPixelsDMA KEYWORD2
dmaBusy KEYWORD2
getTouchRaw KEYWORD2
convertRawXY KEYWORD2
@ -100,6 +114,7 @@ setColorDepth KEYWORD2
getColorDepth KEYWORD2
deleteSprite KEYWORD2
pushRotated KEYWORD2
pushRotatedHP KEYWORD2
rotatedBounds KEYWORD2
setPivot KEYWORD2
getPivotX KEYWORD2
@ -113,7 +128,6 @@ printToSprite KEYWORD2
frameBuffer KEYWORD2
setBitmapColor KEYWORD2
alphaBlend KEYWORD2
showFont KEYWORD2
loadFont KEYWORD2
unloadFont KEYWORD2

View File

@ -1,6 +1,6 @@
{
"name": "TFT_eSPI",
"version": "1.4.21",
"version": "1.4.30",
"keywords": "tft, ePaper, display, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140",
"description": "A TFT and ePaper SPI graphics library for ESP8266 and ESP32",
"repository":

View File

@ -1,5 +1,5 @@
name=TFT_eSPI
version=1.4.21
version=1.4.30
author=Bodmer
maintainer=Bodmer
sentence=A fast TFT graphics library for ESP8266 and ESP32 processors for the Arduino IDE