Raise to version 2.0.0

The library has been cleaned up as it has got a bit untidy due to the large number of small incremental changes.

4bit Sprite examples renaed to be consistent with others.

alphaBlend example moved to generic folder (alphaBlend fn was moved to TFT_eSPI class).
Added sections + explanatory comments to functions prototypes.

Temporary comments added for potential gotchas for noobs when using DMA.

spi_begin/end functions renamed to reflect functionality. Old fns  retained for backwards compatibility with user setup.h files.
This commit is contained in:
Bodmer
2020-01-26 21:17:49 +00:00
parent b954372859
commit 0e0fd75277
29 changed files with 1267 additions and 797 deletions

View File

@@ -171,7 +171,7 @@ void* TFT_eSprite::callocSprite(int16_t w, int16_t h, uint8_t frames)
}
/***************************************************************************************
** Function name: createPalette
** Function name: createPalette (from RAM array)
** Description: Set a palette for a 4-bit per pixel sprite
*************************************************************************************x*/
@@ -197,6 +197,33 @@ void TFT_eSprite::createPalette(uint16_t colorMap[], int colors)
}
}
/***************************************************************************************
** Function name: createPalette (from FLASH array)
** Description: Set a palette for a 4-bit per pixel sprite
*************************************************************************************x*/
void TFT_eSprite::createPalette(const uint16_t colorMap[], int colors)
{
if (_colorMap != nullptr)
{
free(_colorMap);
}
if (colorMap == nullptr)
{
return; // do nothing other than clear the existing map
}
// allocate color map
_colorMap = (uint16_t *)calloc(16, sizeof(uint16_t));
if (colors > 16)
colors = 16;
for (auto i = 0; i < colors; i++)
{
_colorMap[i] = pgm_read_word(colorMap++);
}
}
/***************************************************************************************
** Function name: frameBuffer
** Description: For 1 bpp Sprites, select the frame used for graphics
@@ -487,6 +514,8 @@ bool TFT_eSprite::pushRotatedHP(int16_t angle, int32_t transp)
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];
_tft->startWrite(); // ESP32: avoid transaction overhead for every tft pixel
// Scan destination bounding box and fetch transformed pixels from source Sprite
@@ -495,6 +524,8 @@ bool TFT_eSprite::pushRotatedHP(int16_t angle, int32_t transp)
float cxt = cosra * xt + _xpivot;
float sxt = sinra * xt + _ypivot;
bool column_drawn = false;
uint32_t pixel_count = 0;
int32_t y_start = 0;
for (int32_t y = min_y; y <= max_y; y++) {
int32_t yt = y - _tft->_ypivot;
int32_t xs = (int32_t)round(cxt - sinra * yt);
@@ -505,12 +536,19 @@ bool TFT_eSprite::pushRotatedHP(int16_t angle, int32_t transp)
// Check if ys is in bounds
if (ys >= 0 && ys < height()) {
int32_t rp = readPixel(xs, ys);
if (rp != transp) _tft->drawPixel(x, y, rp);
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
@@ -665,7 +703,10 @@ bool TFT_eSprite::pushRotatedHP(TFT_eSprite *spr, int16_t angle, int32_t transp)
// Check if ys is in bounds
if (ys >= 0 && ys < height())
{
int32_t rp = readPixel(xs, ys);
uint32_t rp;
// Can avoid bounds check overhead for reading 16bpp
if (_bpp == 16) {rp = _img[xs + ys * _iwidth]; rp = rp>>8 | rp<<8; }
else rp = readPixel(xs, ys);
if (rp != transp) spr->drawPixel(x, y, rp);
column_drawn = true;
}

View File

@@ -38,12 +38,13 @@ class TFT_eSprite : public TFT_eSPI {
int8_t getColorDepth(void);
// Set the palette for a 4 bit depth sprite. Only the first 16 colours in the map are used.
void createPalette(uint16_t *palette, int colors = 16);
void createPalette(uint16_t *palette, int colors = 16); // Palette in RAM
void createPalette(const uint16_t *palette, int colors = 16); // Palette in FLASH
// Set a single palette index to the given color
// Set a single palette index to the given color
void setPaletteColor(uint8_t index, uint16_t color);
// Get the color at the given palette index
// Get the color at the given palette index
uint16_t getPaletteColor(uint8_t index);
// Set foreground and background colours for 1 bit per pixel Sprite

View File

@@ -17,7 +17,7 @@
uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
uint16_t tmp;
spi_begin_touch();
begin_touch_read_write();
// Start YP sample request for x position, read 4 times and keep last sample
spi.transfer(0xd0); // Start new YP conversion
@@ -48,7 +48,7 @@ uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
*y = tmp;
spi_end_touch();
end_touch_read_write();
return true;
}
@@ -59,7 +59,7 @@ uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
***************************************************************************************/
uint16_t TFT_eSPI::getTouchRawZ(void){
spi_begin_touch();
begin_touch_read_write();
// Z sample request
int16_t tz = 0xFFF;
@@ -67,7 +67,7 @@ uint16_t TFT_eSPI::getTouchRawZ(void){
tz += spi.transfer16(0xc0) >> 3; // Read Z1 and start Z2 conversion
tz -= spi.transfer16(0x00) >> 3; // Read Z2
spi_end_touch();
end_touch_read_write();
return (uint16_t)tz;
}

View File

@@ -18,9 +18,13 @@
void setTouch(uint16_t *data);
private:
// Handlers for the SPI settings and clock speed change
inline void spi_begin_touch() __attribute__((always_inline));
inline void spi_end_touch() __attribute__((always_inline));
// Legacy support only - deprecated
void spi_begin_touch() {begin_touch_read_write();}
void spi_end_touch() { end_touch_read_write();}
// Handlers for the touch controller bus settings
inline void begin_touch_read_write() __attribute__((always_inline));
inline void end_touch_read_write() __attribute__((always_inline));
// Private function to validate a touch, allow settle time and reduce spurious coordinates
uint8_t validTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);

View File

@@ -12,8 +12,8 @@
#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
#define SET_BUS_WRITE_MODE // Not used
#define SET_BUS_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)
@@ -30,15 +30,7 @@
#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
#ifdef RPI_DISPLAY_TYPE
#define CMD_BITS (16-1)
#else
#define CMD_BITS (8-1)
@@ -73,7 +65,7 @@
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)
#else
#if TFT_DC >= 32
#ifdef RPI_DRIVER // RPi displays need a slower DC change
#ifdef RPI_DISPLAY_TYPE // 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)); \
@@ -83,12 +75,12 @@
#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
#ifdef RPI_DISPLAY_TYPE // 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
#elif defined (RPI_DISPLAY_TYPE) // 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)
@@ -123,7 +115,7 @@
#endif
#else
#if TFT_CS >= 32
#ifdef RPI_ILI9486_DRIVER // RPi ILI9486 display needs a slower CS change
#ifdef RPI_DISPLAY_TYPE // 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)); \
@@ -133,7 +125,7 @@
#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
#ifdef RPI_DISPLAY_TYPE // 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
@@ -277,7 +269,7 @@
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an Raspberry Pi TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_DRIVER)
#elif defined (RPI_DISPLAY_TYPE)
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead

View File

@@ -12,8 +12,8 @@
// 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
#define SET_BUS_WRITE_MODE SPI1U=SPI1U_WRITE
#define SET_BUS_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
@@ -43,14 +43,6 @@
#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
////////////////////////////////////////////////////////////////////////////////////////
@@ -151,7 +143,7 @@
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an Raspberry Pi TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_DRIVER)
#elif defined (RPI_DISPLAY_TYPE)
// Command is 16 bits
#define CMD_BITS 16

View File

@@ -12,8 +12,8 @@
// None
// 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
#define SET_BUS_WRITE_MODE // Not used
#define SET_BUS_READ_MODE // Not used
// Code to check if DMA is busy, used by SPI bus transaction startWrite and endWrite functions
#define DMA_BUSY_CHECK // Not used so leave blank
@@ -111,7 +111,7 @@
// Macros to write commands/pixel colour data to other displays
////////////////////////////////////////////////////////////////////////////////////////
#else
#if defined (RPI_ILI9486_DRIVER) // RPi TFT always needs 16 bit transfers
#if defined (RPI_DISPLAY_TYPE) // RPi TFT type always needs 16 bit transfers
#define tft_Write_8(C) spi.transfer(0); spi.transfer(C)
#else
#ifdef __AVR__ // AVR processors do not have 16 bit transfer
@@ -123,7 +123,7 @@
#define tft_Write_16(C) spi.transfer16(C)
#define tft_Write_16S(C) spi.transfer16(((C)>>8) | ((C)<<8))
#endif // AVR
#endif // RPI_ILI9486_DRIVER
#endif // RPI_DISPLAY_TYPE
#define tft_Write_32(C) \
tft_Write_16((uint16_t) ((C)>>16)); \

View File

@@ -353,7 +353,7 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
if (len == 0) return;
// Wait for any current DMA transaction to end
while (dmaHal.State == HAL_DMA_STATE_BUSY);
while (spiHal.State == HAL_SPI_STATE_BUSY_TX); // Check if SPI Tx is busy
if(_swapBytes) {
for (uint32_t i = 0; i < len; i++) (image[i] = image[i] << 8 | image[i] >> 8);
@@ -389,8 +389,7 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
uint32_t len = dw*dh;
// Wait for any current DMA transaction to end
while (dmaHal.State == HAL_DMA_STATE_BUSY);
while (spiHal.State == HAL_SPI_STATE_BUSY_TX); // Check if SPI Tx is busy
// If image is clipped, copy pixels into a contiguous block
if ( (dw != w) || (dh != h) ) {
@@ -418,9 +417,6 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
}
}
// Wait for any current SPI transaction to end
while (spiHal.State == HAL_SPI_STATE_BUSY_TX);
setWindow(x, y, x + dw - 1, y + dh - 1);
// DMA byte count for transmit is only 16 bits maximum, so to avoid this constraint
@@ -446,7 +442,7 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
** Description: Override the default HAL stream 3 interrupt handler
***************************************************************************************/
extern "C" void DMA2_Stream3_IRQHandler();
void DMA2_Stream3_IRQHandler()
void DMA2_Stream3_IRQHandler(void)
{
// Call the default end of buffer handler
HAL_DMA_IRQHandler(&dmaHal);
@@ -490,7 +486,7 @@ bool TFT_eSPI::initDMA(void)
***************************************************************************************/
extern "C" void DMA1_Channel3_IRQHandler();
void DMA1_Channel3_IRQHandler()
void DMA1_Channel3_IRQHandler(void)
{
// Call the default end of buffer handler
HAL_DMA_IRQHandler(&dmaHal);

View File

@@ -11,9 +11,11 @@
// Include processor specific header
// None
// RPi support not tested - Fast RPi not supported
// 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
#define SET_BUS_WRITE_MODE // Not used
#define SET_BUS_READ_MODE // Not used
// SUPPORT_TRANSACTIONS is mandatory for STM32
#if !defined (SUPPORT_TRANSACTIONS)
@@ -43,7 +45,7 @@
////////////////////////////////////////////////////////////////////////////////////////
// Write strobe timing setup
////////////////////////////////////////////////////////////////////////////////////////
#if defined (ILI9341_DRIVER) // WRX twc spec is 66ns = 15.15MHz
#if defined (ILI9341_DRIVER) || defined (ST7796_DRIVER) // WRX twc spec is 66ns = 15.15MHz
// Extra write pulse low time (delay for data setup)
#if defined (STM32F2xx) || defined (STM32F4xx)
@@ -731,7 +733,7 @@
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to a SPI Raspberry Pi TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_ILI9486_DRIVER)
#elif defined (RPI_DISPLAY_TYPE)
#define tft_Write_8(C) \
{ spiBuffer[0] = 0; spiBuffer[1] = C; \

View File

@@ -12,11 +12,13 @@ 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. The library has been upgraded to support STM32 processors when used with SPI or 8 bit parallel displays. DMA capability for SPI displays has been added for STM32F103 (e.g. "Blue Pill") and STM32F2xx/4xx/7xx (e.g. 32/64/144 Nucleo boards). New DMA demo examples have been added (for STM32 only). Smooth (anti-aliased) fonts are not yet supported for STM32 processors due to the lack of SPIFFS, support for smooth fonts using SD cards will be added at a future date.
1. The Sprite class now supports 4 bits per pixel with a 16 color palette. Three new examples have been added.
2. The ST7796 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. The library has been upgraded to support STM32 processors when used with SPI or 8 bit parallel displays. DMA capability for SPI displays has been added for STM32F103 (e.g. "Blue Pill") and STM32F2xx/4xx/7xx (e.g. 32/64/144 Nucleo boards). New DMA demo examples have been added (for STM32 only). Smooth (anti-aliased) fonts are not yet supported for STM32 processors due to the lack of SPIFFS, support for smooth fonts using SD cards will be added at a future date.
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:
3. The ST7796 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.
4. 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"
@@ -24,9 +26,9 @@ 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)
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.
5. 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.
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:
6. 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

View File

@@ -1,18 +1,7 @@
This is a standalone library that contains both graphics functions
and the TFT chip driver library.
This library has been derived from the Adafruit_GFX and driver library with
further code from other authors.
It is not compatible with legacy versions of the IDE (e.g. 1.0.6 and
older. Use the latest version.
New functions have been added in particular it contains proportional fonts
in addition to the original Adafruit font.
A sprite class has been added to aid the generation of flicker free complex
graphics.
Note: This version of the library might not be fully compatible with the
original.
and the TFT chip driver library. It supports the ESP8266, ESP32 and
STM32 processors with performance optimised code. Other Arduino IDE
compatible boards are also supported but the library then uses
generic functions which will be slower. The library uses 32 bit
variables extensively so this will affect performance on 8 and 16
bit processors.

View File

@@ -115,9 +115,9 @@
writecommand(ILI9341_SLPOUT); //Exit Sleep
spi_end();
end_tft_write();
delay(120);
spi_begin();
begin_tft_write();
writecommand(ILI9341_DISPON); //Display on

View File

@@ -109,9 +109,9 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
spi_end();
end_tft_write();
delay(120);
spi_begin();
begin_tft_write();
writecommand(ST7789_DISPON); //Display on
delay(120);

View File

@@ -102,9 +102,9 @@
writecommand(0xF0); //Command Set control
writedata(0x69); //Disable extension command 2 partII
spi_end();
end_tft_write();
delay(120);
spi_begin();
begin_tft_write();
writecommand(0x29); //Display on
}

View File

@@ -28,10 +28,10 @@
/***************************************************************************************
** Function name: spi_begin
** Function name: begin_tft_write (was called spi_begin)
** Description: Start SPI transaction for writes and select TFT
***************************************************************************************/
inline void TFT_eSPI::spi_begin(void){
inline void TFT_eSPI::begin_tft_write(void){
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT)
if (locked) {
locked = false;
@@ -41,14 +41,14 @@ inline void TFT_eSPI::spi_begin(void){
#else
CS_L;
#endif
SET_SPI_WRITE_MODE;
SET_BUS_WRITE_MODE;
}
/***************************************************************************************
** Function name: spi_end
** Function name: end_tft_write (was called spi_end)
** Description: End transaction for write and deselect TFT
***************************************************************************************/
inline void TFT_eSPI::spi_end(void){
inline void TFT_eSPI::end_tft_write(void){
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT)
if(!inTransaction) {
if (!locked) {
@@ -57,18 +57,18 @@ inline void TFT_eSPI::spi_end(void){
spi.endTransaction();
}
}
SET_SPI_READ_MODE;
SET_BUS_READ_MODE;
#else
if(!inTransaction) {CS_H;}
#endif
}
/***************************************************************************************
** Function name: spi_begin_read
** Description: Start SPI transaction for reads and select TFT
** Function name: begin_tft_read (was called spi_begin_read)
** Description: Start transaction for reads and select TFT
***************************************************************************************/
// Reads require a lower SPI clock rate that writes
inline void TFT_eSPI::spi_begin_read(void){
// Reads require a lower SPI clock rate than writes
inline void TFT_eSPI::begin_tft_read(void){
DMA_BUSY_CHECK; // Wait for any DMA transfer to complete before changing SPI settings
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT)
if (locked) {
@@ -82,14 +82,14 @@ inline void TFT_eSPI::spi_begin_read(void){
#endif
CS_L;
#endif
SET_SPI_READ_MODE;
SET_BUS_READ_MODE;
}
/***************************************************************************************
** Function name: spi_end_read
** Description: End SPI transaction for reads and deselect TFT
** Function name: end_tft_read (was called spi_end_read)
** Description: End transaction for reads and deselect TFT
***************************************************************************************/
inline void TFT_eSPI::spi_end_read(void){
inline void TFT_eSPI::end_tft_read(void){
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(TFT_PARALLEL_8_BIT)
if(!inTransaction) {
if (!locked) {
@@ -104,17 +104,17 @@ inline void TFT_eSPI::spi_end_read(void){
#endif
if(!inTransaction) {CS_H;}
#endif
SET_SPI_WRITE_MODE;
SET_BUS_WRITE_MODE;
}
#if defined (TOUCH_CS) && defined (SPI_TOUCH_FREQUENCY) // && !defined(TFT_PARALLEL_8_BIT)
#if defined (TOUCH_CS) && defined (SPI_TOUCH_FREQUENCY)
/***************************************************************************************
** Function name: spi_begin_touch
** Description: Start SPI transaction and select touch controller
** Function name: begin_touch_read_write - was spi_begin_touch
** Description: Start transaction and select touch controller
***************************************************************************************/
// The touch controller has a low SPI clock rate
inline void TFT_eSPI::spi_begin_touch(void){
inline void TFT_eSPI::begin_touch_read_write(void){
DMA_BUSY_CHECK;
CS_H; // Just in case it has been left low
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS)
@@ -122,22 +122,22 @@ inline void TFT_eSPI::spi_begin_touch(void){
#else
spi.setFrequency(SPI_TOUCH_FREQUENCY);
#endif
SET_SPI_READ_MODE;
SET_BUS_READ_MODE;
T_CS_L;
}
/***************************************************************************************
** Function name: spi_end_touch
** Description: End SPI transaction and deselect touch controller
** Function name: end_touch_read_write - was spi_end_touch
** Description: End transaction and deselect touch controller
***************************************************************************************/
inline void TFT_eSPI::spi_end_touch(void){
inline void TFT_eSPI::end_touch_read_write(void){
T_CS_H;
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS)
if(!inTransaction) {if (!locked) {locked = true; spi.endTransaction();}}
#else
spi.setFrequency(SPI_FREQUENCY);
#endif
SET_SPI_WRITE_MODE;
SET_BUS_WRITE_MODE;
}
#endif
@@ -348,11 +348,11 @@ void TFT_eSPI::init(uint8_t tc)
#endif
_booted = false;
spi_end();
end_tft_write();
} // end of: if just _booted
// Toggle RST low to reset
spi_begin();
begin_tft_write();
#ifdef TFT_RST
if (TFT_RST >= 0) {
@@ -367,11 +367,11 @@ void TFT_eSPI::init(uint8_t tc)
writecommand(TFT_SWRST); // Software reset
#endif
spi_end();
end_tft_write();
delay(150); // Wait for reset to complete
spi_begin();
begin_tft_write();
tc = tc; // Supress warning
@@ -392,9 +392,6 @@ void TFT_eSPI::init(uint8_t tc)
#elif defined (ST7796_DRIVER)
#include "TFT_Drivers/ST7796_Init.h"
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers/ILI9486_Init.h"
#elif defined (ILI9486_DRIVER)
#include "TFT_Drivers/ILI9486_Init.h"
@@ -429,7 +426,7 @@ void TFT_eSPI::init(uint8_t tc)
writecommand(TFT_INVOFF);
#endif
spi_end();
end_tft_write();
setRotation(rotation);
@@ -453,7 +450,7 @@ void TFT_eSPI::init(uint8_t tc)
void TFT_eSPI::setRotation(uint8_t m)
{
spi_begin();
begin_tft_write();
// This loads the driver specific rotation code <<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVERS TO THE LIST HERE <<<<<<<<<<<<<<<<<<<<<<<
#if defined (ILI9341_DRIVER)
@@ -471,9 +468,6 @@ void TFT_eSPI::setRotation(uint8_t m)
#elif defined (ST7796_DRIVER)
#include "TFT_Drivers/ST7796_Rotation.h"
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers/ILI9486_Rotation.h"
#elif defined (ILI9486_DRIVER)
#include "TFT_Drivers/ILI9486_Rotation.h"
@@ -502,7 +496,7 @@ void TFT_eSPI::setRotation(uint8_t m)
delayMicroseconds(10);
spi_end();
end_tft_write();
addr_row = 0xFFFF;
addr_col = 0xFFFF;
@@ -559,7 +553,7 @@ void TFT_eSPI::spiwrite(uint8_t c)
***************************************************************************************/
void TFT_eSPI::writecommand(uint8_t c)
{
spi_begin(); // CS_L;
begin_tft_write();
DC_C;
@@ -567,7 +561,7 @@ void TFT_eSPI::writecommand(uint8_t c)
DC_D;
spi_end(); // CS_H;
end_tft_write();
}
@@ -578,7 +572,7 @@ void TFT_eSPI::writecommand(uint8_t c)
***************************************************************************************/
void TFT_eSPI::writedata(uint8_t d)
{
spi_begin(); // CS_L;
begin_tft_write();
DC_D; // Play safe, but should already be in data mode
@@ -586,7 +580,7 @@ void TFT_eSPI::writedata(uint8_t d)
CS_L; // Allow more hold time for low VDI rail
spi_end(); // CS_H;
end_tft_write();
}
@@ -614,7 +608,7 @@ uint8_t TFT_eSPI::readcommand8(uint8_t cmd_function, uint8_t index)
#else // SPI interface
// Tested with ILI9341 set to Interface II i.e. IM [3:0] = "1101"
spi_begin_read();
begin_tft_read();
index = 0x10 + (index & 0x0F);
DC_C; tft_Write_8(0xD9);
@@ -627,7 +621,7 @@ uint8_t TFT_eSPI::readcommand8(uint8_t cmd_function, uint8_t index)
DC_D;
reg = tft_Read_8();
spi_end_read();
end_tft_read();
#endif
return reg;
}
@@ -715,9 +709,9 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
// This function can get called during antialiased font rendering
// so a transaction may be in progress
bool wasInTransaction = inTransaction;
if (inTransaction) { inTransaction= false; spi_end();}
if (inTransaction) { inTransaction= false; end_tft_write();}
spi_begin_read();
begin_tft_read();
readAddrWindow(x0, y0, 1, 1); // Sets CS low
@@ -752,10 +746,10 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
end_SDA_Read();
#endif
spi_end_read();
end_tft_read();
// Reinstate the transaction if one was in progress
if(wasInTransaction) { spi_begin(); inTransaction = true; }
if(wasInTransaction) { begin_tft_write(); inTransaction = true; }
return color565(r, g, b);
@@ -819,7 +813,7 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
#else // SPI interface
spi_begin_read();
begin_tft_read();
readAddrWindow(x, y, w, h); // Sets CS low
@@ -862,7 +856,7 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
end_SDA_Read();
#endif
spi_end_read();
end_tft_read();
#endif
}
@@ -902,7 +896,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
if (dw < 1 || dh < 1) return;
spi_begin();
begin_tft_write();
inTransaction = true;
setWindow(x, y, x + dw - 1, y + dh - 1);
@@ -921,7 +915,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
}
inTransaction = false;
spi_end();
end_tft_write();
}
/***************************************************************************************
@@ -946,7 +940,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
if (dw < 1 || dh < 1) return;
spi_begin();
begin_tft_write();
inTransaction = true;
data += dx + dy * w;
@@ -992,7 +986,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
}
inTransaction = false;
spi_end();
end_tft_write();
}
@@ -1019,7 +1013,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
if (dw < 1 || dh < 1) return;
spi_begin();
begin_tft_write();
inTransaction = true;
data += dx + dy * w;
@@ -1053,7 +1047,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
}
inTransaction = false;
spi_end();
end_tft_write();
}
@@ -1079,7 +1073,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
if (dw < 1 || dh < 1) return;
spi_begin();
begin_tft_write();
inTransaction = true;
data += dx + dy * w;
@@ -1122,7 +1116,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
}
inTransaction = false;
spi_end();
end_tft_write();
}
@@ -1148,7 +1142,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
if (dw < 1 || dh < 1) return;
spi_begin();
begin_tft_write();
inTransaction = true;
setWindow(x, y, x + dw - 1, y + dh - 1); // Sets CS low and sent RAMWR
@@ -1275,7 +1269,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
}
inTransaction = false;
spi_end();
end_tft_write();
}
@@ -1300,7 +1294,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
if (dw < 1 || dh < 1) return;
spi_begin();
begin_tft_write();
inTransaction = true;
int32_t xe = x + dw - 1, ye = y + dh - 1;
@@ -1498,9 +1492,10 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
}
inTransaction = false;
spi_end();
end_tft_write();
}
/***************************************************************************************
** Function name: setSwapBytes
** Description: Used by 16 bit pushImage() to swap byte order in colours
@@ -1520,6 +1515,7 @@ bool TFT_eSPI::getSwapBytes(void)
return _swapBytes;
}
/***************************************************************************************
** Function name: read rectangle (for SPI Interface II i.e. IM [3:0] = "1101")
** Description: Read RGB pixel colours from a defined area
@@ -1533,7 +1529,7 @@ void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_
#else // Not TFT_PARALLEL_8_BIT
spi_begin_read();
begin_tft_read();
readAddrWindow(x0, y0, w, h); // Sets CS low
@@ -1574,7 +1570,7 @@ void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_
end_SDA_Read();
#endif
spi_end_read();
end_tft_read();
#endif
}
@@ -1592,7 +1588,7 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
int32_t dy = r+r;
int32_t p = -(r>>1);
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
// These are ordered to minimise coordinate changes in x or y
@@ -1629,7 +1625,7 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1685,7 +1681,7 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
int32_t dy = r+r;
int32_t p = -(r>>1);
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
drawFastHLine(x0 - r, y0, dy+1, color);
@@ -1710,7 +1706,7 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1766,7 +1762,7 @@ void TFT_eSPI::drawEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint1
int32_t fy2 = 4 * ry2;
int32_t s;
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
for (x = 0, y = ry, s = 2*ry2+rx2*(1-2*ry); ry2*x <= rx2*y; x++) {
@@ -1799,7 +1795,7 @@ void TFT_eSPI::drawEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint1
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1818,7 +1814,7 @@ void TFT_eSPI::fillEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint1
int32_t fy2 = 4 * ry2;
int32_t s;
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
for (x = 0, y = ry, s = 2*ry2+rx2*(1-2*ry); ry2*x <= rx2*y; x++) {
@@ -1844,7 +1840,7 @@ void TFT_eSPI::fillEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint1
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1865,7 +1861,7 @@ void TFT_eSPI::fillScreen(uint32_t color)
// Draw a rectangle
void TFT_eSPI::drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
drawFastHLine(x, y, w, color);
@@ -1875,7 +1871,7 @@ void TFT_eSPI::drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col
drawFastVLine(x + w - 1, y+1, h-2, color);
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1886,7 +1882,7 @@ void TFT_eSPI::drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col
// Draw a rounded rectangle
void TFT_eSPI::drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
// smarter version
@@ -1901,7 +1897,7 @@ void TFT_eSPI::drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t
drawCircleHelper(x + r , y + h - r - 1, r, 8, color);
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1912,7 +1908,7 @@ void TFT_eSPI::drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t
// Fill a rounded rectangle, changed to horizontal lines (faster in sprites)
void TFT_eSPI::fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
// smarter version
@@ -1923,7 +1919,7 @@ void TFT_eSPI::fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t
fillCircleHelper(x + r , y + r, r, 2, w - r - r - 1, color);
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1934,7 +1930,7 @@ void TFT_eSPI::fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t
// Draw a triangle
void TFT_eSPI::drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
drawLine(x0, y0, x1, y1, color);
@@ -1942,7 +1938,7 @@ void TFT_eSPI::drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int3
drawLine(x2, y2, x0, y0, color);
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -1976,7 +1972,7 @@ void TFT_eSPI::fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, in
return;
}
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
int32_t
@@ -2023,7 +2019,7 @@ void TFT_eSPI::fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, in
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -2033,7 +2029,7 @@ void TFT_eSPI::fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, in
***************************************************************************************/
void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
int32_t i, j, byteWidth = (w + 7) / 8;
@@ -2047,7 +2043,7 @@ void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -2057,7 +2053,7 @@ void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w
***************************************************************************************/
void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
int32_t i, j, byteWidth = (w + 7) / 8;
@@ -2071,7 +2067,7 @@ void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
/***************************************************************************************
@@ -2080,7 +2076,7 @@ void TFT_eSPI::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w
***************************************************************************************/
void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
int32_t i, j, byteWidth = (w + 7) / 8;
@@ -2094,7 +2090,7 @@ void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -2104,7 +2100,7 @@ void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t
***************************************************************************************/
void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bgcolor)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
int32_t i, j, byteWidth = (w + 7) / 8;
@@ -2118,7 +2114,7 @@ void TFT_eSPI::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
@@ -2467,7 +2463,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
if ((size==1) && fillbg) {
uint8_t column[6];
uint8_t mask = 0x1;
spi_begin();
begin_tft_write();
setWindow(x, y, x+5, y+8);
@@ -2483,10 +2479,10 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
tft_Write_16(bg);
}
spi_end();
end_tft_write();
}
else {
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
for (int8_t i = 0; i < 6; i++ ) {
uint8_t line;
@@ -2510,7 +2506,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
}
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
@@ -2523,7 +2519,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
#ifdef LOAD_GFXFF
// Filter out bad characters not present in font
if ((c >= pgm_read_word(&gfxFont->first)) && (c <= pgm_read_word(&gfxFont->last ))) {
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
@@ -2572,7 +2568,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
}
inTransaction = false;
spi_end(); // Does nothing if Sprite class uses this function
end_tft_write(); // Does nothing if Sprite class uses this function
}
#endif
@@ -2592,11 +2588,11 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
// Chip select is high at the end of this function
void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t w, int32_t h)
{
spi_begin();
begin_tft_write();
setWindow(x0, y0, x0 + w - 1, y0 + h - 1);
spi_end();
end_tft_write();
}
@@ -2604,10 +2600,10 @@ void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t w, int32_t h)
** Function name: setWindow
** Description: define an area to receive a stream of pixels
***************************************************************************************/
// Chip select stays low, call spi_begin first. Use setAddrWindow() from sketches
// Chip select stays low, call begin_tft_write first. Use setAddrWindow() from sketches
void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
//spi_begin(); // Must be called before setWindow
//begin_tft_write(); // Must be called before setWindow
addr_col = 0xFFFF;
addr_row = 0xFFFF;
@@ -2631,7 +2627,7 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
DC_D;
//spi_end(); // Must be called after setWindow
//end_tft_write(); // Must be called after setWindow
}
@@ -2684,7 +2680,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
y+=rowstart;
#endif
spi_begin();
begin_tft_write();
// No need to send x if it has not changed (speeds things up)
if (addr_col != x) {
@@ -2703,7 +2699,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
DC_C; tft_Write_8(TFT_RAMWR);
DC_D; tft_Write_16(color);
spi_end();
end_tft_write();
}
/***************************************************************************************
@@ -2712,11 +2708,11 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
***************************************************************************************/
void TFT_eSPI::pushColor(uint16_t color)
{
spi_begin();
begin_tft_write();
tft_Write_16(color);
spi_end();
end_tft_write();
}
@@ -2726,11 +2722,11 @@ void TFT_eSPI::pushColor(uint16_t color)
***************************************************************************************/
void TFT_eSPI::pushColor(uint16_t color, uint32_t len)
{
spi_begin();
begin_tft_write();
pushBlock(color, len);
spi_end();
end_tft_write();
}
/***************************************************************************************
@@ -2739,7 +2735,7 @@ void TFT_eSPI::pushColor(uint16_t color, uint32_t len)
***************************************************************************************/
void TFT_eSPI::startWrite(void)
{
spi_begin();
begin_tft_write();
inTransaction = true;
}
@@ -2751,7 +2747,7 @@ void TFT_eSPI::endWrite(void)
{
inTransaction = false;
DMA_BUSY_CHECK; // Safety check - user code should have checked this!
spi_end();
end_tft_write();
}
/***************************************************************************************
@@ -2771,11 +2767,11 @@ void TFT_eSPI::writeColor(uint16_t color, uint32_t len)
// len is number of bytes, not pixels
void TFT_eSPI::pushColors(uint8_t *data, uint32_t len)
{
spi_begin();
begin_tft_write();
pushPixels(data, len>>1);
spi_end();
end_tft_write();
}
@@ -2785,13 +2781,13 @@ void TFT_eSPI::pushColors(uint8_t *data, uint32_t len)
***************************************************************************************/
void TFT_eSPI::pushColors(uint16_t *data, uint32_t len, bool swap)
{
spi_begin();
begin_tft_write();
if (swap) {swap = _swapBytes; _swapBytes = true; }
pushPixels(data, len);
_swapBytes = swap; // Restore old value
spi_end();
end_tft_write();
}
@@ -2803,7 +2799,7 @@ void TFT_eSPI::pushColors(uint16_t *data, uint32_t len, bool swap)
// an efficient FastH/V Line draw routine for line segments of 2 pixels or more
void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color)
{
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
bool steep = abs(y1 - y0) > abs(x1 - x0);
@@ -2855,7 +2851,7 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t
}
inTransaction = false;
spi_end();
end_tft_write();
}
@@ -2874,13 +2870,13 @@ void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
if (h < 1) return;
spi_begin();
begin_tft_write();
setWindow(x, y, x, y + h - 1);
pushBlock(color, h);
spi_end();
end_tft_write();
}
@@ -2899,13 +2895,13 @@ void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
if (w < 1) return;
spi_begin();
begin_tft_write();
setWindow(x, y, x + w - 1, y);
pushBlock(color, w);
spi_end();
end_tft_write();
}
@@ -2926,13 +2922,13 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col
if ((w < 1) || (h < 1)) return;
spi_begin();
begin_tft_write();
setWindow(x, y, x + w - 1, y + h - 1);
pushBlock(color, w * h);
spi_end();
end_tft_write();
}
@@ -2980,11 +2976,11 @@ uint16_t TFT_eSPI::color8to16(uint8_t color)
***************************************************************************************/
void TFT_eSPI::invertDisplay(bool i)
{
spi_begin();
begin_tft_write();
// Send the command twice as otherwise it does not always work!
writecommand(i ? TFT_INVON : TFT_INVOFF);
writecommand(i ? TFT_INVON : TFT_INVOFF);
spi_end();
end_tft_write();
}
@@ -3366,7 +3362,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
if (x + width * textsize >= (int16_t)_width) return width * textsize ;
if (textcolor == textbgcolor || textsize != 1) {
//spi_begin(); // Sprite class can use this function, avoiding spi_begin()
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
for (int32_t i = 0; i < height; i++) {
@@ -3403,10 +3399,10 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
}
inTransaction = false;
spi_end();
end_tft_write();
}
else { // Faster drawing of characters and background using block write
spi_begin();
begin_tft_write();
setWindow(x, y, x + width - 1, y + height - 1);
@@ -3426,7 +3422,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
if (pX) {tft_Write_16(textbgcolor);}
}
spi_end();
end_tft_write();
}
}
@@ -3438,7 +3434,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
#ifdef LOAD_RLE //674 bytes of code
// Font is not 2 and hence is RLE encoded
{
spi_begin();
begin_tft_write();
inTransaction = true;
w *= height; // Now w is total number of pixels in the character
@@ -3508,7 +3504,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
}
}
inTransaction = false;
spi_end();
end_tft_write();
}
// End of RLE font rendering
#endif

View File

@@ -6,17 +6,21 @@
hardware driver, the graphics functions and the
proportional fonts.
The larger fonts are Run Length Encoded to reduce
their FLASH footprint.
The built-in fonts 4, 6, 7 and 8 are Run Length
Encoded (RLE) to reduce the FLASH footprint.
Last review/edit by Bodmer: 26/01/20
****************************************************/
// Stop fonts etc being loaded multiple times
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "1.5.0"
#define TFT_ESPI_VERSION "2.0.0"
/***************************************************************************************
** Section 1: Load required header files
***************************************************************************************/
// Include header file that defines the fonts loaded, the TFT drivers
// available and the pins to be used, etc, etc
#include <User_Setup_Select.h>
@@ -26,6 +30,9 @@
#include <Print.h>
#include <SPI.h>
/***************************************************************************************
** Section 2: Load processor specific header files
***************************************************************************************/
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
@@ -45,31 +52,38 @@
#include "Processors/TFT_eSPI_Generic.h"
#endif
/***************************************************************************************
** Section 3: Interface setup
***************************************************************************************/
#ifndef TAB_COLOUR
#define TAB_COLOUR 0
#endif
// If the frequency is not defined, set a default
// If the SPI frequency is not defined, set a default
#ifndef SPI_FREQUENCY
#define SPI_FREQUENCY 20000000
#endif
// If the frequency is not defined, set a default
// If the SPI read frequency is not defined, set a default
#ifndef SPI_READ_FREQUENCY
#define SPI_READ_FREQUENCY SPI_FREQUENCY
#define SPI_READ_FREQUENCY 10000000
#endif
// Some ST7789 boards do not work with Mode 0
#if defined(ST7789_DRIVER) || defined(ST7789_2_DRIVER)
#define TFT_SPI_MODE SPI_MODE3
#else
#define TFT_SPI_MODE SPI_MODE0
#endif
// If the frequency is not defined, set a default
// If the XPT2046 SPI frequency is not defined, set a default
#ifndef SPI_TOUCH_FREQUENCY
#define SPI_TOUCH_FREQUENCY 2500000
#endif
/***************************************************************************************
** Section 4: Setup fonts
***************************************************************************************/
// Use GLCD font in error case where user requests a smooth font file
// that does not exist (this is a temporary fix to stop ESP32 reboot)
#ifdef SMOOTH_FONT
@@ -112,7 +126,7 @@
#ifndef LOAD_RLE
#define LOAD_RLE
#endif
#elif defined LOAD_FONT8N
#elif defined LOAD_FONT8N // Optional narrower version
#define LOAD_FONT8
#include <Fonts/Font72x53rle.h>
#ifndef LOAD_RLE
@@ -128,124 +142,13 @@
#include <User_Setups/User_Custom_Fonts.h>
#endif // #ifdef LOAD_GFXFF
//These enumerate the text plotting alignment (reference datum point)
#define TL_DATUM 0 // Top left (default)
#define TC_DATUM 1 // Top centre
#define TR_DATUM 2 // Top right
#define ML_DATUM 3 // Middle left
#define CL_DATUM 3 // Centre left, same as above
#define MC_DATUM 4 // Middle centre
#define CC_DATUM 4 // Centre centre, same as above
#define MR_DATUM 5 // Middle right
#define CR_DATUM 5 // Centre right, same as above
#define BL_DATUM 6 // Bottom left
#define BC_DATUM 7 // Bottom centre
#define BR_DATUM 8 // Bottom right
#define L_BASELINE 9 // Left character baseline (Line the 'A' character would sit on)
#define C_BASELINE 10 // Centre character baseline
#define R_BASELINE 11 // Right character baseline
// New color definitions use for all my libraries
#define TFT_BLACK 0x0000 /* 0, 0, 0 */
#define TFT_NAVY 0x000F /* 0, 0, 128 */
#define TFT_DARKGREEN 0x03E0 /* 0, 128, 0 */
#define TFT_DARKCYAN 0x03EF /* 0, 128, 128 */
#define TFT_MAROON 0x7800 /* 128, 0, 0 */
#define TFT_PURPLE 0x780F /* 128, 0, 128 */
#define TFT_OLIVE 0x7BE0 /* 128, 128, 0 */
#define TFT_LIGHTGREY 0xC618 /* 192, 192, 192 */
#define TFT_DARKGREY 0x7BEF /* 128, 128, 128 */
#define TFT_BLUE 0x001F /* 0, 0, 255 */
#define TFT_GREEN 0x07E0 /* 0, 255, 0 */
#define TFT_CYAN 0x07FF /* 0, 255, 255 */
#define TFT_RED 0xF800 /* 255, 0, 0 */
#define TFT_MAGENTA 0xF81F /* 255, 0, 255 */
#define TFT_YELLOW 0xFFE0 /* 255, 255, 0 */
#define TFT_WHITE 0xFFFF /* 255, 255, 255 */
#define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */
#define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */
#define TFT_PINK 0xFC9F
// Next is a special 16 bit colour value that encodes to 8 bits
// and will then decode back to the same 16 bit value.
// Convenient for 8 bit and 16 bit transparent sprites.
#define TFT_TRANSPARENT 0x0120
// Swap any type
template <typename T> static inline void
swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
#ifndef min
// Return minimum of two numbers, may already be defined
// #define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
// This structure allows sketches to retrieve the user setup parameters at runtime
// by calling getSetup(), zero impact on code size unless used, mainly for diagnostics
typedef struct
{
String version = TFT_ESPI_VERSION;
int32_t esp;
uint8_t trans;
uint8_t serial;
uint8_t overlap;
#if defined (ESP32)
#if defined (USE_HSPI_PORT)
uint8_t port = HSPI;
#else
uint8_t port = VSPI;
#endif
#endif
uint16_t tft_driver; // Hexadecimal code
uint16_t tft_width; // Rotation 0 width and height
uint16_t tft_height;
uint8_t r0_x_offset; // Offsets, not all used yet
uint8_t r0_y_offset;
uint8_t r1_x_offset;
uint8_t r1_y_offset;
uint8_t r2_x_offset;
uint8_t r2_y_offset;
uint8_t r3_x_offset;
uint8_t r3_y_offset;
int8_t pin_tft_mosi;
int8_t pin_tft_miso;
int8_t pin_tft_clk;
int8_t pin_tft_cs;
int8_t pin_tft_dc;
int8_t pin_tft_rd;
int8_t pin_tft_wr;
int8_t pin_tft_rst;
int8_t pin_tft_d0;
int8_t pin_tft_d1;
int8_t pin_tft_d2;
int8_t pin_tft_d3;
int8_t pin_tft_d4;
int8_t pin_tft_d5;
int8_t pin_tft_d6;
int8_t pin_tft_d7;
int8_t pin_tch_cs;
int16_t tft_spi_freq;
int16_t tft_rd_freq;
int16_t tch_spi_freq;
} setup_t;
// This is a structure to conveniently hold information on the default fonts
// Stores pointer to font character image address table, width table and height
// Create a null set in case some fonts not used (to prevent crash)
// Create a null default font in case some fonts not used (to prevent crash)
const uint8_t widtbl_null[1] = {0};
PROGMEM const uint8_t chr_null[1] = {0};
PROGMEM const uint8_t* const chrtbl_null[1] = {chr_null};
// This is a structure to conveniently hold information on the default fonts
// Stores pointer to font character image address table, width table and height
typedef struct {
const uint8_t *chartbl;
const uint8_t *widthtbl;
@@ -300,21 +203,169 @@ const PROGMEM fontinfo fontdata [] = {
#endif
};
/***************************************************************************************
** Section 5: Font datum enumeration
***************************************************************************************/
//These enumerate the text plotting alignment (reference datum point)
#define TL_DATUM 0 // Top left (default)
#define TC_DATUM 1 // Top centre
#define TR_DATUM 2 // Top right
#define ML_DATUM 3 // Middle left
#define CL_DATUM 3 // Centre left, same as above
#define MC_DATUM 4 // Middle centre
#define CC_DATUM 4 // Centre centre, same as above
#define MR_DATUM 5 // Middle right
#define CR_DATUM 5 // Centre right, same as above
#define BL_DATUM 6 // Bottom left
#define BC_DATUM 7 // Bottom centre
#define BR_DATUM 8 // Bottom right
#define L_BASELINE 9 // Left character baseline (Line the 'A' character would sit on)
#define C_BASELINE 10 // Centre character baseline
#define R_BASELINE 11 // Right character baseline
/***************************************************************************************
** Section 6: Colour enumeration
***************************************************************************************/
// Default color definitions
#define TFT_BLACK 0x0000 /* 0, 0, 0 */
#define TFT_NAVY 0x000F /* 0, 0, 128 */
#define TFT_DARKGREEN 0x03E0 /* 0, 128, 0 */
#define TFT_DARKCYAN 0x03EF /* 0, 128, 128 */
#define TFT_MAROON 0x7800 /* 128, 0, 0 */
#define TFT_PURPLE 0x780F /* 128, 0, 128 */
#define TFT_OLIVE 0x7BE0 /* 128, 128, 0 */
#define TFT_LIGHTGREY 0xD69A /* 211, 211, 211 */
#define TFT_DARKGREY 0x7BEF /* 128, 128, 128 */
#define TFT_BLUE 0x001F /* 0, 0, 255 */
#define TFT_GREEN 0x07E0 /* 0, 255, 0 */
#define TFT_CYAN 0x07FF /* 0, 255, 255 */
#define TFT_RED 0xF800 /* 255, 0, 0 */
#define TFT_MAGENTA 0xF81F /* 255, 0, 255 */
#define TFT_YELLOW 0xFFE0 /* 255, 255, 0 */
#define TFT_WHITE 0xFFFF /* 255, 255, 255 */
#define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */
#define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */
#define TFT_PINK 0xFE19 /* 255, 192, 203 */ //Lighter pink, was 0xFC9F
#define TFT_BROWN 0x9A60 /* 150, 75, 0 */
#define TFT_GOLD 0xFEA0 /* 255, 215, 0 */
#define TFT_SILVER 0xC618 /* 192, 192, 192 */
#define TFT_SKYBLUE 0x867D /* 135, 206, 235 */
#define TFT_VIOLET 0x915C /* 180, 46, 226 */
// Next is a special 16 bit colour value that encodes to 8 bits
// and will then decode back to the same 16 bit value.
// Convenient for 8 bit and 16 bit transparent sprites.
#define TFT_TRANSPARENT 0x0120 // This is actually a dark green
// Default palette for 4 bit colour sprites
static const uint16_t default_4bit_palette[] PROGMEM = {
TFT_BLACK, // 0 ^
TFT_BROWN, // 1 |
TFT_RED, // 2 |
TFT_ORANGE, // 3 |
TFT_YELLOW, // 4 Colours 0-9 follow the resistor colour code!
TFT_GREEN, // 5 |
TFT_BLUE, // 6 |
TFT_PURPLE, // 7 |
TFT_DARKGREY, // 8 |
TFT_WHITE, // 9 v
TFT_CYAN, // 10 Blue+green mix
TFT_MAGENTA, // 11 Blue+red mix
TFT_MAROON, // 12 Darker red colour
TFT_DARKGREEN,// 13 Darker green colour
TFT_NAVY, // 14 Darker blue colour
TFT_PINK // 15
};
/***************************************************************************************
** Section 7: Diagnostic support
***************************************************************************************/
// #define TFT_eSPI_DEBUG // Switch on debug support serial messages (not used yet)
// #define TFT_eSPI_FNx_DEBUG // Switch on debug support for function "x" (not used yet)
// This structure allows sketches to retrieve the user setup parameters at runtime
// by calling getSetup(), zero impact on code size unless used, mainly for diagnostics
typedef struct
{
String version = TFT_ESPI_VERSION;
int32_t esp; // Processor code
uint8_t trans; // SPI transaction supoort
uint8_t serial; // Serial (SPI) or parallel
uint8_t overlap; // ESP8266 overlap mode
#if defined (ESP32) // TODO: make generic for other processors
#if defined (USE_HSPI_PORT)
uint8_t port = HSPI;
#else
uint8_t port = VSPI;
#endif
#endif
uint16_t tft_driver; // Hexadecimal code
uint16_t tft_width; // Rotation 0 width and height
uint16_t tft_height;
uint8_t r0_x_offset; // Display offsets, not all used yet
uint8_t r0_y_offset;
uint8_t r1_x_offset;
uint8_t r1_y_offset;
uint8_t r2_x_offset;
uint8_t r2_y_offset;
uint8_t r3_x_offset;
uint8_t r3_y_offset;
int8_t pin_tft_mosi; // SPI pins
int8_t pin_tft_miso;
int8_t pin_tft_clk;
int8_t pin_tft_cs;
int8_t pin_tft_dc; // Control pins
int8_t pin_tft_rd;
int8_t pin_tft_wr;
int8_t pin_tft_rst;
int8_t pin_tft_d0; // Parallel port pins
int8_t pin_tft_d1;
int8_t pin_tft_d2;
int8_t pin_tft_d3;
int8_t pin_tft_d4;
int8_t pin_tft_d5;
int8_t pin_tft_d6;
int8_t pin_tft_d7;
int8_t pin_tch_cs; // Touch chip select pin
int16_t tft_spi_freq;// TFT write SPI frequency
int16_t tft_rd_freq; // TFT read SPI frequency
int16_t tch_spi_freq;// Touch controller read/write SPI frequency
} setup_t;
/***************************************************************************************
** Section 8: Class member and support functions
***************************************************************************************/
// Swap any type
template <typename T> static inline void
swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
// Callback prototype for smooth font pixel colour read
typedef uint16_t (*getColorCallback)(uint16_t x, uint16_t y);
// Class functions and variables
class TFT_eSPI : public Print {
//--------------------------------------- public ------------------------------------//
public:
TFT_eSPI(int16_t _W = TFT_WIDTH, int16_t _H = TFT_HEIGHT);
void init(uint8_t tc = TAB_COLOUR), begin(uint8_t tc = TAB_COLOUR); // Same - begin included for backwards compatibility
// init() and begin() are equivalent, begin() included for backwards compatibility
// Sketch defined tab colour option is for ST7735 displays only
void init(uint8_t tc = TAB_COLOUR), begin(uint8_t tc = TAB_COLOUR);
// These are virtual so the TFT_eSprite class can override them with sprite specific functions
virtual void drawPixel(int32_t x, int32_t y, uint32_t color),
drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size),
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color),
drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, 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),
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
@@ -324,89 +375,21 @@ class TFT_eSPI : public Print {
height(void),
width(void);
// The TFT_eSprite class inherits the following functions
void setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye),
pushColor(uint16_t color),
pushColor(uint16_t color, uint32_t len),
void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3
uint8_t getRotation(void); // Read the current rotation
void invertDisplay(bool i); // Tell TFT to invert all displayed colours
// The TFT_eSprite class inherits the following functions (not all are useful to Sprite class
void setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h), // Note: start coordinates + width and height
setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye); // Note: start + end coordinates
// Push (aka write pixel) colours to the TFT (use setAddrWindow() first)
void pushColor(uint16_t color),
pushColor(uint16_t color, uint32_t len), // Deprecated, use pushBlock()
pushColors(uint16_t *data, uint32_t len, bool swap = true), // With byte swap option
pushColors(uint8_t *data, uint32_t len),
fillScreen(uint32_t color);
void drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
drawRoundRect(int32_t x0, int32_t y0, int32_t w, int32_t h, int32_t radius, uint32_t color),
fillRoundRect(int32_t x0, int32_t y0, int32_t w, int32_t h, int32_t radius, uint32_t color),
setRotation(uint8_t r),
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),
fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color),
fillCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t cornername, int32_t delta, uint32_t color),
drawEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint16_t color),
fillEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint16_t color),
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 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),
setTextColor(uint16_t color),
setTextColor(uint16_t fgcolor, uint16_t bgcolor),
setTextSize(uint8_t size),
setTextWrap(bool wrapX, bool wrapY = false),
setTextDatum(uint8_t datum),
setTextPadding(uint16_t x_width),
#ifdef LOAD_GFXFF
setFreeFont(const GFXfont *f = NULL),
setTextFont(uint8_t font),
#else
setFreeFont(uint8_t font),
setTextFont(uint8_t font),
#endif
spiwrite(uint8_t),
writecommand(uint8_t c),
writedata(uint8_t d),
commandList(const uint8_t *addr);
uint8_t readcommand8(uint8_t cmd_function, uint8_t index = 0);
uint16_t readcommand16(uint8_t cmd_function, uint8_t index = 0);
uint32_t readcommand32(uint8_t cmd_function, uint8_t index = 0);
// Read the colour of a pixel at x,y and return value in 565 format
uint16_t readPixel(int32_t x0, int32_t y0);
void setCallback(getColorCallback getCol);
// The next functions can be used as a pair to copy screen blocks (or horizontal/vertical lines) to another location
// Read a block of pixels to a data buffer, buffer is 16 bit and the array size must be at least w * h
void readRect(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
// Write a block of pixels to the screen
void pushRect(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
// These are used to render images or sprites stored in RAM arrays
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data, uint16_t transparent);
// These are used to render images stored in FLASH (PROGMEM)
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data, uint16_t transparent);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data);
// These are used by pushSprite for 1, 4 and 8 bit colours (color map needed for 4 bit)
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data, bool bpp8 = true, uint16_t *cmap = nullptr);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true, uint16_t *cmap = nullptr);
pushColors(uint8_t *data, uint32_t len); // Deprecated, use pushPixels()
// Write a solid block of a single colour
void pushBlock(uint16_t color, uint32_t len);
@@ -414,163 +397,333 @@ class TFT_eSPI : public Print {
// 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);
// Read the colour of a pixel at x,y and return value in 565 format
uint16_t readPixel(int32_t x, int32_t y);
// Support for half duplex (bi-directional SDA) SPI bus where MOSI must be switched to input
#ifdef TFT_SDA_READ
#if defined (TFT_eSPI_ENABLE_8_BIT_READ)
uint8_t tft_Read_8(void); // Read 8 bit value from TFT command register
#endif
void begin_SDA_Read(void); // Begin a read on a half duplex (bi-directional SDA) SPI bus - sets MOSI to input
void end_SDA_Read(void); // Restore MOSI to output
#endif
// Graphics drawing
void fillScreen(uint32_t color),
drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color),
fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color);
void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color),
fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
fillCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, int32_t delta, uint32_t color),
drawEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color),
fillEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color),
// Corner 1 Corner 2 Corner 3
drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color),
fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color);
// Image rendering
// Swap the byte order for pushImage() and pushPixels() - corrects endianness
void setSwapBytes(bool swap);
bool getSwapBytes(void);
// Draw bitmap
void 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); // Define the 2 colours for 1bpp sprites
// Set TFT pivot point (use when rendering rotated sprites)
void setPivot(int16_t x, int16_t y);
int16_t getPivotX(void), // Get pivot x
getPivotY(void); // Get pivot y
// The next functions can be used as a pair to copy screen blocks (or horizontal/vertical lines) to another location
// Read a block of pixels to a data buffer, buffer is 16 bit and the size must be at least w * h
void readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
// Write a block of pixels to the screen - this is a deprecated alternative to pushImage()
void pushRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
// These are used to render images or sprites stored in RAM arrays (used by Sprite class for 16bpp Sprites)
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data, uint16_t transparent);
// These are used to render images stored in FLASH (PROGMEM)
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data, uint16_t transparent);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data);
// These are used by Sprite class pushSprite() member function for 1, 4 and 8 bits per pixel (bpp) colours
// They are not intended to be used with user sketches (but could be)
// Set bpp8 true for 8bpp sprites, false otherwise. The cmap pointer must be specified for 4bpp
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, bool bpp8 = true, uint16_t *cmap = nullptr);
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true, uint16_t *cmap = nullptr);
// This next function has been used successfully to dump the TFT screen to a PC for documentation purposes
// It reads a screen area and returns the RGB 8 bit colour values of each pixel
// It reads a screen area and returns the 3 RGB 8 bit colour values of each pixel in the buffer
// Set w and h to 1 to read 1 pixel's colour. The data buffer must be at least w * h * 3 bytes
void readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data);
void readRectRGB(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data);
uint8_t getRotation(void),
getTextDatum(void),
color16to8(uint16_t color565); // Convert 16 bit colour to 8 bits
int16_t getCursorX(void),
getCursorY(void);
int16_t getPivotX(void),
getPivotY(void);
uint16_t fontsLoaded(void),
color565(uint8_t red, uint8_t green, uint8_t blue), // Convert 8 bit red, green and blue to 16 bits
color8to16(uint8_t color332); // Convert 8 bit colour to 16 bits
int16_t drawNumber(long long_num, int32_t poX, int32_t poY, uint8_t font),
drawNumber(long long_num, int32_t poX, int32_t poY),
drawFloat(float floatNumber, uint8_t decimal, int32_t poX, int32_t poY, uint8_t font),
drawFloat(float floatNumber, uint8_t decimal, int32_t poX, int32_t poY),
// Text rendering - value returned is the pixel width of the rendered text
int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number
drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font
// Decimal is the number of decimal places to render
// Use with setTextDatum() to position values on TFT, and setTextPadding() to blank old displayed values
drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y, uint8_t font), // Draw float using specified font number
drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y), // Draw float using current font
// Handle char arrays
drawString(const char *string, int32_t poX, int32_t poY, uint8_t font),
drawString(const char *string, int32_t poX, int32_t poY),
drawCentreString(const char *string, int32_t dX, int32_t poY, uint8_t font), // Deprecated, use setTextDatum() and drawString()
drawRightString(const char *string, int32_t dX, int32_t poY, uint8_t font), // Deprecated, use setTextDatum() and drawString()
// Use with setTextDatum() to position string on TFT, and setTextPadding() to blank old displayed strings
drawString(const char *string, int32_t x, int32_t y, uint8_t font), // Draw string using specifed font number
drawString(const char *string, int32_t x, int32_t y), // Draw string using current font
drawString(const String& string, int32_t x, int32_t y, uint8_t font),// Draw string using specifed font number
drawString(const String& string, int32_t x, int32_t y), // Draw string using current font
// Handle String type
drawString(const String& string, int32_t poX, int32_t poY, uint8_t font),
drawString(const String& string, int32_t poX, int32_t poY),
drawCentreString(const String& string, int32_t dX, int32_t poY, uint8_t font), // Deprecated, use setTextDatum() and drawString()
drawRightString(const String& string, int32_t dX, int32_t poY, uint8_t font); // Deprecated, use setTextDatum() and drawString()
drawCentreString(const char *string, int32_t x, int32_t y, uint8_t font), // Deprecated, use setTextDatum() and drawString()
drawRightString(const char *string, int32_t x, int32_t y, uint8_t font), // Deprecated, use setTextDatum() and drawString()
drawCentreString(const String& string, int32_t x, int32_t y, uint8_t font),// Deprecated, use setTextDatum() and drawString()
drawRightString(const String& string, int32_t x, int32_t y, uint8_t font); // Deprecated, use setTextDatum() and drawString()
int16_t textWidth(const char *string, uint8_t font),
textWidth(const char *string),
textWidth(const String& string, uint8_t font),
textWidth(const String& string),
fontHeight(int16_t font),
fontHeight(void);
// Text rendering and font handling support funtions
void setCursor(int16_t x, int16_t y), // Set cursor for tft.print()
setCursor(int16_t x, int16_t y, uint8_t font); // Set cursor and font number for tft.print()
void setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h);
int16_t getCursorX(void), // Read current cursor x position (moves with tft.print())
getCursorY(void); // Read current cursor y position
void setTextColor(uint16_t color), // Set character (glyph) color only (background not over-written)
setTextColor(uint16_t fgcolor, uint16_t bgcolor),// Set character (glyph) foreground and backgorund colour
setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size)
// Compatibility additions
void startWrite(void); // Begin SPI transaction
void writeColor(uint16_t color, uint32_t len); // Write colours without transaction overhead Deprecated, use pushBlock()
void endWrite(void); // End SPI transaction
void setTextWrap(bool wrapX, bool wrapY = false); // Turn on/off wrapping of text in TFT width and/or height
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);
void setTextDatum(uint8_t datum); // Set text datum position (default is top left), see Section 6 above
uint8_t getTextDatum(void);
size_t write(uint8_t);
void setTextPadding(uint16_t x_width); // Set text padding (background blanking/over-write) width in pixels
#ifdef TFT_SDA_READ
#if defined (TFT_eSPI_ENABLE_8_BIT_READ)
uint8_t tft_Read_8(void);
#endif
void begin_SDA_Read(void);
void end_SDA_Read(void);
#ifdef LOAD_GFXFF
void setFreeFont(const GFXfont *f = NULL), // Select the GFX Free Font
setTextFont(uint8_t font); // Set the font number to use in future
#else
void setFreeFont(uint8_t font), // Not used, historical fix to prevent an error
setTextFont(uint8_t font); // Set the font number to use in future
#endif
// Set or get an arbitrary library attribute or configuration option
void setAttribute(uint8_t id = 0, uint8_t a = 0);
uint8_t getAttribute(uint8_t id = 0);
int16_t textWidth(const char *string, uint8_t font), // Returns pixel width of string in specified font
textWidth(const char *string), // Returns pixel width of string in current font
textWidth(const String& string, uint8_t font), // As above for String types
textWidth(const String& string),
fontHeight(int16_t font), // Returns pixel height of string in specified font
fontHeight(void); // Returns pixel width of string in current font
// Used by library and Smooth font class to extract Unicode point codes from a UTF8 encoded string
uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining),
decodeUTF8(uint8_t c);
// Support function to UTF8 decode and draw characters piped through print stream
size_t write(uint8_t);
// Used by Smooth font class to fetch a pixel colour for the anti-aliasing
void setCallback(getColorCallback getCol);
uint16_t fontsLoaded(void); // Each bit in returned value represents a font type that is loaded - used for debug/error handling only
// Low level read/write
void spiwrite(uint8_t); // legacy support only
void writecommand(uint8_t c), // Send a command, function resets DC/RS high ready for data
writedata(uint8_t d); // Send data with DC/RS set high
void commandList(const uint8_t *addr); // Send a initialisation sequence to TFT stored in FLASH
uint8_t readcommand8( uint8_t cmd_function, uint8_t index = 0); // read 8 bits from TFT
uint16_t readcommand16(uint8_t cmd_function, uint8_t index = 0); // read 16 bits from TFT
uint32_t readcommand32(uint8_t cmd_function, uint8_t index = 0); // read 32 bits from TFT
// Colour conversion
// Convert 8 bit red, green and blue to 16 bits
uint16_t color565(uint8_t red, uint8_t green, uint8_t blue);
// Convert 8 bit colour to 16 bits
uint16_t color8to16(uint8_t color332);
// Convert 16 bit colour to 8 bits
uint8_t color16to8(uint16_t color565);
// Alpha blend 2 colours, see generic "alphaBlend_Test" example
// alpha = 0 = 100% background colour
// alpha = 255 = 100% foreground colour
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
// DMA support functions - these are currently just for SPI writes whe using the STM32 processors
// Bear in mind DMA will only be of benefit in particular circumstances and can be tricky
// to manage by noobs. The functions have however been designed to be noob friendly and
// avoid a few DMA behaviour "gotchas".
//
// At best you will get a 2x TFT rendering performance improvement when using DMA because
// this library handles the SPI bus so efficiently during normal (non DMA) transfers. The best
// performance improvement scenario is the DMA transfer time is exactly the same as the time it
// takes for the processor to prepare the next image buffer and initiate another DMA transfer.
//
// DMA transfer to the TFT is done while the processor moves on to handle other tasks. Bear
// this in mind and watch out for "gotchas" like the image buffer going out of scope as the
// processor leaves a function or its content being changed while the DMA engine is reading it.
//
// The compiler MAY change the implied scope of a buffer which has been set aside by creating
// and an array. For example a buffer defined before a "for-next" loop may get de-allocated when
// the loop ends. To avoid this use, for example, malloc() and free() to take control of when
// the buffer space is available and ensure it is not released until DMA is complete.
//
// Clearly you should not modify a buffer that is being DMA'ed to the TFT until the DMA is over.
// Use the dmaBusy() function to check this. Use tft.startWrite() before invoking DMA so the
// TFT chip select stays low. If you use tft.endWrite() before DMA is complete then the endWrite
// function will wait for the DMA to complete, so this may defeat any DMA performance benefit.
//
bool initDMA(void); // Initialise the DMA engine and attach to SPI bus - typically used in setup()
void deInitDMA(void); // De-initialise the DMA engine and detach from SPI bus - typically not used
// Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image
// Use the buffer if the image data will get over-written or destroyed while DMA is in progress
// If swapping colour bytes is defined, and the double buffer option is NOT used then the bytes
// in the original data image will be swapped by the function before DMA is initiated.
// The function will wait for the last DMA to complete if it is called while a previous DMA is still
// in progress, this simplifies the sketch and helps avoid "gotchas".
void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* data, uint16_t* buffer = nullptr);
// Push a block of pixels into a window set up using setAddrWindow()
void pushPixelsDMA(uint16_t* image, uint32_t len);
// Check if the DMA is complete - use while(tft.dmaBusy); for a blocking wait
bool dmaBusy(void);
bool DMA_Enabled = false; // Flag for DMA enabled state
// Bare metal functions
void startWrite(void); // Begin SPI transaction
void writeColor(uint16_t color, uint32_t len); // Deprecated, use pushBlock()
void endWrite(void); // End SPI transaction
// Set/get an arbitrary library configuration attribute or option
// Use to switch ON/OFF capabilities such as UTF8 decoding - each attribute has a unique ID
// id = 0: reserved - may be used in fuuture to reset all attributes to a default state
// id = 1: Turn on (a=true) or off (a=false) GLCD cp437 font character error correction
// id = 2: Turn on (a=true) or off (a=false) UTF8 decoding
#define CP437_SWITCH 1
#define UTF8_SWITCH 2
void setAttribute(uint8_t id = 0, uint8_t a = 0); // Set attribute value
uint8_t getAttribute(uint8_t id = 0); // Get attribute value
// Used for diagnostic sketch to see library setup adopted by compiler, see Section 7 above
void getSetup(setup_t& tft_settings); // Sketch provides the instance to populate
// DMA support functions
bool initDMA(void);
void deInitDMA(void);
void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* data, uint16_t* buffer = nullptr);
//void pushBlockDMA(uint16_t color, uint32_t len);
void pushPixelsDMA(uint16_t* image, uint32_t len);
bool dmaBusy(void);
bool DMA_Enabled = false;
// Global variables
static SPIClass& getSPIinstance(void); // Get SPI class handle
static SPIClass& getSPIinstance(void);
int32_t cursor_x, cursor_y, padX; // Text cursor x,y and padding setting
uint32_t textcolor, textbgcolor; // Text foreground and background colours
int32_t cursor_x, cursor_y, padX;
uint32_t textcolor, textbgcolor;
uint32_t bitmap_fg, bitmap_bg; // Bitmap foreground (bit=1) and background (bit=0) colours
uint32_t bitmap_fg, bitmap_bg;
uint8_t textfont, // Current selected font
uint8_t textfont, // Current selected font number
textsize, // Current font size multiplier
textdatum, // Text reference datum
rotation; // Display rotation (0-3)
int16_t _xpivot; // x pivot point coordinate
int16_t _ypivot; // x pivot point coordinate
int16_t _xpivot; // TFT x pivot point coordinate for rotated Sprites
int16_t _ypivot; // TFT x pivot point coordinate for rotated Sprites
uint8_t decoderState = 0; // UTF8 decoder state
uint16_t decoderBuffer; // Unicode code-point buffer
uint8_t decoderState = 0; // UTF8 decoder state - not for user access
uint16_t decoderBuffer; // Unicode code-point buffer - not for user access
//--------------------------------------- private ------------------------------------//
private:
// Legacy begin and end prototypes - deprecated
void spi_begin() {begin_tft_write();}
void spi_end() { end_tft_write();}
inline void spi_begin() __attribute__((always_inline));
inline void spi_end() __attribute__((always_inline));
void spi_begin_read() {begin_tft_read(); }
void spi_end_read() { end_tft_read(); }
inline void spi_begin_read() __attribute__((always_inline));
inline void spi_end_read() __attribute__((always_inline));
// New begin and end prototypes
// begin/end a TFT write transaction
// For SPI bus the transmit clock rate is set
inline void begin_tft_write() __attribute__((always_inline));
inline void end_tft_write() __attribute__((always_inline));
// Private function, sketches must use pushPixels() with setSwapBytes(true)
// begin/end a TFT read transaction
// For SPI bus begin lowers SPI clock rate, end reinstates transmit clock rate
inline void begin_tft_read() __attribute__((always_inline));
inline void end_tft_read() __attribute__((always_inline));
// Temporary library development function TODO: remove need for this
void pushSwapBytePixels(const void* data_in, uint32_t len);
// Same as setAddrWindow but exits with CGRAM in read mode
void readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h);
// Byte read prototype
// Byte read prototype
uint8_t readByte(void);
// GPIO parallel input/output control
// GPIO parallel bus input/output direction control
void busDir(uint32_t mask, uint8_t mode);
// Single GPIO input/output direction control
// 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
// Display variant settings
uint8_t tabcolor, // ST7735 screen protector "tab" colour (now invalid)
colstart = 0, rowstart = 0; // Screen display area to CGRAM area coordinate offsets
// Port and pin masks for control signals (ESP826 only) - TODO: remove need for this
volatile uint32_t *dcport, *csport;
uint32_t cspinmask, dcpinmask, wrpinmask, sclkpinmask;
#if defined(ESP32_PARALLEL)
uint32_t xclr_mask, xdir_mask, xset_mask[256];
#endif
#if defined(ESP32_PARALLEL)
// Bit masks for ESP32 parallel bus interface
uint32_t xclr_mask, xdir_mask; // Port set/clear and direction control masks
uint32_t lastColor = 0xFFFF;
// Lookup table for ESP32 parallel bus interface uses 1kbyte RAM,
uint32_t xset_mask[256]; // Makes Sprite rendering test 33% faster, for slower macro equivalent
// see commented out #define set_mask(C) within TFT_eSPI_ESP32.h
#endif
getColorCallback getColor = nullptr;
//uint32_t lastColor = 0xFFFF; // Last colour - used to minimise bit shifting overhead
getColorCallback getColor = nullptr; // Smooth font callback function pointer
//-------------------------------------- protected ----------------------------------//
protected:
int32_t win_xe, win_ye;
//int32_t win_xe, win_ye; // Window end coords - not needed
int32_t _init_width, _init_height; // Display w/h as input, used by setRotation()
int32_t _width, _height; // Display w/h as modified by current rotation
int32_t addr_row, addr_col;
int32_t addr_row, addr_col; // Window position - used to minimise window commands
uint32_t fontsloaded;
uint32_t fontsloaded; // Bit field of fonts loaded
uint8_t glyph_ab, // glyph delta Y (height) above baseline
glyph_bb; // glyph delta Y (height) below baseline
uint8_t glyph_ab, // Smooth font glyph delta Y (height) above baseline
glyph_bb; // Smooth font glyph delta Y (height) below baseline
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 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
bool locked, inTransaction; // SPI transaction and mutex lock flags
bool _booted; // init() or begin() has already run once
// User sketch manages these via set/getAttribute()
bool _cp437; // If set, use correct CP437 charset (default is ON)
bool _utf8; // If set, use UTF-8 decoder in print stream 'write()' function (default ON)
@@ -580,22 +733,28 @@ class TFT_eSPI : public Print {
GFXfont *gfxFont;
#endif
/***************************************************************************************
** Section 9: TFT_eSPI class conditional extensions
***************************************************************************************/
// Load the Touch extension
#ifdef TOUCH_CS
#include "Extensions/Touch.h"
#include "Extensions/Touch.h" // Loaded if TOUCH_CS is defined by user
#endif
// Load the Anti-aliased font extension
#ifdef SMOOTH_FONT
#include "Extensions/Smooth_font.h"
#include "Extensions/Smooth_font.h" // Loaded if SMOOTH_FONT is defined by user
#endif
}; // End of class TFT_eSPI
/***************************************************************************************
** Section 10: Additional extension classes
***************************************************************************************/
// Load the Button Class
#include "Extensions/Button.h"
// Load the Sprite Class
#include "Extensions/Sprite.h"
#endif
#endif // ends #ifndef _TFT_eSPIH_

View File

@@ -55,6 +55,11 @@
//#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/Setup29_ILI9341_STM32.h> // Setup for Nucleo board
//#include <User_Setups/Setup30_ILI9341_Parallel_STM32.h> // Setup for Nucleo board and parallel display
//#include <User_Setups/Setup31_ST7796_Parallel_STM32.h> // Setup for Nucleo board and parallel display
//#include <User_Setups/Setup32_ILI9341_STM32F103.h> // Setup for "Blue Pill"
//#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 135 x 240 TFT
@@ -69,7 +74,7 @@
/////////////////////////////////////////////////////////////////////////////////////
// //
// DON'T TINKER WITH ANY OF THE FOLLOWING LINES, THESE ADD THE TFT DRIVERS //
// AND ESP8266 PIN DEFINITONS THEY ARE HERE FOR BODMER'S CONVENIENCE! //
// AND ESP8266 PIN DEFINITONS, THEY ARE HERE FOR BODMER'S CONVENIENCE! //
// //
/////////////////////////////////////////////////////////////////////////////////////
@@ -78,6 +83,23 @@
#define TFT_BGR 0 // Colour order Blue-Green-Red
#define TFT_RGB 1 // Colour order Red-Green-Blue
// Legacy setup support, RPI_DISPLAY_TYPE replaces RPI_DRIVER
#if defined (RPI_DRIVER)
#if !defined (RPI_DISPLAY_TYPE)
#define RPI_DISPLAY_TYPE
#endif
#endif
// Legacy setup support, RPI_ILI9486_DRIVER form is deprecated
// Instead define RPI_DISPLAY_TYPE and also define driver (e.g. ILI9486_DRIVER)
#if defined (RPI_ILI9486_DRIVER)
#if !defined (ILI9486_DRIVER)
#define ILI9486_DRIVER
#endif
#if !defined (RPI_DISPLAY_TYPE)
#define RPI_DISPLAY_TYPE
#endif
#endif
// Load the right driver definition - do not tinker here !
#if defined (ILI9341_DRIVER)
@@ -93,11 +115,8 @@
#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
#include "TFT_Drivers/ST7796_Defines.h"
#define TFT_DRIVER 0x7796
#elif defined (ILI9486_DRIVER)
#include <TFT_Drivers/ILI9486_Defines.h>
#define TFT_DRIVER 0x9486
@@ -125,7 +144,9 @@
#elif defined (RM68140_DRIVER)
#include "TFT_Drivers/RM68140_Defines.h"
#define TFT_DRIVER 0x6814
#elif defined (XYZZY_DRIVER) // <<<<<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVER HERE
// <<<<<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVER HERE
// XYZZY_init.h and XYZZY_rotation.h must also be added in TFT_eSPI.c
#elif defined (XYZZY_DRIVER)
#include "TFT_Drivers/XYZZY_Defines.h"
#define TFT_DRIVER 0x0000
#else

View File

@@ -2,9 +2,8 @@
#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS PIN_D8 // Chip select control pin D8
#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

View File

@@ -0,0 +1,52 @@
///////////////////////////////////////////////////
// Setup for Nucleo-F446/767 and ILI9341 display //
///////////////////////////////////////////////////
// See SetupX_Template.h for all options available
// Define STM32 to invoke optimised processor support
#define STM32
// Defining the board allows the library to optimise the performance
// for UNO compatible "MCUfriend" style shields
#define NUCLEO_64_TFT
//#define NUCLEO_144_TFT
// Tell the library to use 8 bit parallel mode(otherwise SPI is assumed)
#define TFT_PARALLEL_8_BIT
// Define the display driver chip type
#define ST7796_DRIVER
//#define ILI9481_DRIVER
// Define the Nucleo 64/144 pins used for the parallel interface TFT
// The pins can be changed here but these are the ones used by the
// common "MCUfriend" shields
#define TFT_CS A3 // Chip select control pin
#define TFT_DC A2 // Data Command control pin
#define TFT_RST A4 // Reset pin
#define TFT_WR A1 // Write strobe control pin
#define TFT_RD A0 // Read pin
#define TFT_D0 D8 // 8 bit parallel bus to TFT
#define TFT_D1 D9
#define TFT_D2 D2
#define TFT_D3 D3
#define TFT_D4 D4
#define TFT_D5 D5
#define TFT_D6 D6
#define TFT_D7 D7
// Fonts to be available
#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_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
// At the moment SMOOTH fonts must be disabled for STM32 processors (due to lack of SPIFFS)
// Support for smooth fonts via SD cards is planned.
//#define SMOOTH_FONT

View File

@@ -0,0 +1,62 @@
///////////////////////////////////////////////////
// Setup for Nucleo-F446/767 and ILI9341 display //
///////////////////////////////////////////////////
// Last update by Bodmer: 14/1/20
// Define STM32 to invoke STM32 optimised driver (optimised fns only tested on STM32F767 so far)
// so you may need to comment this out
#define STM32
// Define the TFT display driver
#define ILI9341_DRIVER
//#define ILI9481_DRIVER
// MOSI and SCK do not need to be defined, connect:
// - Arduino SCK (Blue Pill pin A5) to TFT SCK
// - Arduino MOSI (Blue Pill pin A7) to TFT SDI (may be marked SDA or MOSI)
// - Optional to read TFT: Arduino MISO (Blue Pill pin A6) to TFT SDO (may be marked MISO or may not exist on TFT)
// Note: not all TFT's support reads
// reminder: Blue Pill SPI pins are SCK=A5, MISO = A6, MOSI=A7
// Can use Ardiuno pin references, arbitrary allocation, TFT_eSPI controls chip select
#define TFT_CS A0 // Chip select control pin to TFT CS
#define TFT_DC A1 // Data Command control pin to TFT DC (may be labelled RS = Register Select)
#define TFT_RST A2 // Reset pin to TFT RST (or RESET)
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to processor reset
// Use an Arduino pin for initial testing as connecting to processor reset
// may not work (due to variations in display design)
#define TOUCH_CS A4 // Connect to T_CS (Touch controller chip select) if XPT2046 is connected to SPI bus
// You may need to wire the touch controller to the processor in addition to the TFT
// For example on some boards the pins are labelled:
// T_IRQ - no connection to processor
// T_DO - connect to processor MISO
// T_DIN - connect to processor MOSI
// T_CS - connect to processor pin specified by TOUCH_CS above
// T_SCK - connect to processor SCK
//*
#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_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
//*/
// At the moment SMOOTH fonts MUST be disabled for STM32 processors (due to lack of SPIFFS)
// Support for smooth fonts via SD cards is planned.
//#define SMOOTH_FONT // Must be commented out for STM32
// Assuming the processor clock is 72MHz:
#define SPI_FREQUENCY 36000000 // 36MHz SPI clock
//#define SPI_FREQUENCY 18000000 // 18MHz SPI clock
#define SPI_READ_FREQUENCY 12000000 // Reads need a slower SPI clock
#define SPI_TOUCH_FREQUENCY 2500000 // Must be very slow
// This has no effect, transactions are automatically enabled for STM32
//#define SUPPORT_TRANSACTIONS

View File

@@ -0,0 +1,194 @@
/*
This tests the alpha blending function that is used with the antialiased
fonts:
Alpha = 0 = 100% background, alpha = 255 = 100% foreground colour
blendedColor = tft.alphaBlend(alpha, fg_color, bg_color);
The alphaBlend() function operates on 16 bit colours only
A test is included where the colours are mapped to 8 bits after blending
Information on alpha blending is here
https://en.wikipedia.org/wiki/Alpha_compositing
Example for library:
https://github.com/Bodmer/TFT_eSPI
The sketch has been tested on a 320x240 ILI9341 based TFT, it
could be adapted for other screen sizes.
Created by Bodmer 10/2/18
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include <TFT_eSPI.h> // Include the graphics library
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
// -------------------------------------------------------------------------
// Setup
// -------------------------------------------------------------------------
void setup(void) {
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_DARKGREY);
}
// -------------------------------------------------------------------------
// Main loop
// -------------------------------------------------------------------------
void loop()
{
// 16 bit colours (5 bits red, 6 bits green, 5 bits blue)
// Blend from white to full spectrum
for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
{
for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.alphaBlend(a, rainbow(c), TFT_WHITE));
}
// Blend from full spectrum to black
for (int a = 255; a > 2; a-=2)
{
for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.alphaBlend(a, rainbow(c), TFT_BLACK));
}
// Blend from white to black (32 grey levels)
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
{
tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_WHITE));
tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_RED));
tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_GREEN));
tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_BLUE));
}
delay(4000);
// Blend from white to colour (32 grey levels)
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
{
//tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_WHITE));
tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_RED, TFT_WHITE));
tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_GREEN, TFT_WHITE));
tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_BLUE, TFT_WHITE));
}
delay(4000);
//*
// Decrease to 8 bit colour (3 bits red, 3 bits green, 2 bits blue)
// Blend from white to full spectrum
for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
{
// Convert blended 16 bit colour to 8 bits to reduce colour resolution, then map back to 16 bits for displaying
for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.color8to16(tft.color16to8(tft.alphaBlend(a, rainbow(c), 0xFFFF))));
}
// Blend from full spectrum to black
for (int a = 255; a > 2; a-=2)
{
// Convert blended 16 bit colour to 8 bits to reduce colour resolution, then map back to 16 bits for displaying
for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.color8to16(tft.color16to8(tft.alphaBlend(a, rainbow(c), 0))));
}
// Blend from white to black (4 grey levels - it will draw 4 more with a blue tinge due to lower blue bit count)
// Blend from black to a primary colour
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
{
tft.drawFastHLine(192, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_WHITE))));
tft.drawFastHLine(204, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_RED))));
tft.drawFastHLine(216, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_GREEN))));
tft.drawFastHLine(228, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_BLUE))));
}
delay(4000);
//*/
/*
// 16 bit colours (5 bits red, 6 bits green, 5 bits blue)
for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
{
for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.alphaBlend(a, rainbow(c), TFT_CYAN));
}
// Blend from full spectrum to cyan
for (int a = 255; a > 2; a-=2)
{
for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.alphaBlend(a, rainbow(c), TFT_YELLOW));
}
//*/
/*
// Blend other colour transitions for test purposes
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
{
tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_WHITE, TFT_WHITE)); // Should show as solid white
tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_BLACK)); // Should show as solid black
tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_YELLOW, TFT_CYAN)); // Brightness should be fairly even
tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_CYAN, TFT_MAGENTA));// Brightness should be fairly even
}
delay(4000);
//*/
}
// #########################################################################
// Return a 16 bit rainbow colour
// #########################################################################
unsigned int rainbow(byte value)
{
// If 'value' is in the range 0-159 it is converted to a spectrum colour
// from 0 = red through to 127 = blue to 159 = violet
// Extending the range to 0-191 adds a further violet to red band
value = value%192;
byte red = 0; // Red is the top 5 bits of a 16 bit colour value
byte green = 0; // Green is the middle 6 bits, but only top 5 bits used here
byte blue = 0; // Blue is the bottom 5 bits
byte sector = value >> 5;
byte amplit = value & 0x1F;
switch (sector)
{
case 0:
red = 0x1F;
green = amplit; // Green ramps up
blue = 0;
break;
case 1:
red = 0x1F - amplit; // Red ramps down
green = 0x1F;
blue = 0;
break;
case 2:
red = 0;
green = 0x1F;
blue = amplit; // Blue ramps up
break;
case 3:
red = 0;
green = 0x1F - amplit; // Green ramps down
blue = 0x1F;
break;
case 4:
red = amplit; // Red ramps up
green = 0;
blue = 0x1F;
break;
case 5:
red = 0x1F;
green = 0;
blue = 0x1F - amplit; // Blue ramps down
break;
}
return red << 11 | green << 6 | blue;
}

View File

@@ -1,9 +1,16 @@
/*
Sketch to show how a Sprite is created, how to draw pixels
Sketch to show how a 4 bit Sprite is created, how to draw pixels
and text within the Sprite and then push the Sprite onto
the display screen.
The advantage of 4 bit sprites is:
1. Small memory footprint
2. Any set of 16 colours can be specified
3. Colours can be changed without redrawing in Sprite
4. Simple animations like flashing text can be achieved
by colour palette cycling and pushing sprite to TFT:
https://en.wikipedia.org/wiki/Color_cycling
Example for library:
https://github.com/Bodmer/TFT_eSPI
@@ -14,14 +21,7 @@
any position. If there is sufficient RAM then the Sprite can
be the same size as the screen and used as a frame buffer.
A 16 bit Sprite occupies (2 * width * height) bytes in RAM.
On a ESP8266 Sprite sizes up to 126 x 160 can be accomodated,
this size requires 40kBytes of RAM for a 16 bit color depth.
When 8 bit color depth sprites are created they occupy
(width * height) bytes in RAM, so larger sprites can be
created, or the RAM required is halved.
A 4 bit Sprite occupies (width * height)/2 bytes in RAM.
*/
@@ -41,14 +41,15 @@ TFT_eSprite spr = TFT_eSprite(&tft); // Declare Sprite object "spr" with pointe
void setup()
{
Serial.begin(250000);
Serial.begin(115200);
Serial.println();
delay(500);
// Initialise the TFT registers
tft.init();
// Set the sprite colour depth to 4
spr.setColorDepth(4);
// Create a sprite of defined size
@@ -60,89 +61,72 @@ void setup()
void loop(void)
{
// Fill the whole sprite with color 5 (Sprite is in memory so not visible yet)
spr.fillSprite(10);
// Fill the whole sprite with color 0 (Sprite is in memory so not visible yet)
spr.fillSprite(0);
// create a color map with known colors
// create a color map with known colors (16 maximum for 4 bit Sprite
uint16_t cmap[16];
cmap[0] = TFT_BLACK;
cmap[1] = TFT_NAVY;
cmap[2] = TFT_DARKGREEN;
cmap[3] = TFT_DARKCYAN;
cmap[4] = TFT_MAROON;
cmap[5] = TFT_PURPLE;
cmap[6] = TFT_OLIVE;
cmap[7] = TFT_LIGHTGREY;
cmap[8] = TFT_DARKGREY;
cmap[9] = TFT_BLUE;
cmap[0] = TFT_BLACK; // We will keep this as black
cmap[1] = TFT_NAVY;
cmap[2] = TFT_DARKGREEN;
cmap[3] = TFT_DARKCYAN;
cmap[4] = TFT_MAROON;
cmap[5] = TFT_PURPLE;
cmap[6] = TFT_PINK;
cmap[7] = TFT_LIGHTGREY;
cmap[8] = TFT_YELLOW;
cmap[9] = TFT_BLUE;
cmap[10] = TFT_GREEN;
cmap[11] = TFT_CYAN;
cmap[12] = TFT_RED;
cmap[13] = TFT_MAGENTA;
cmap[14] = TFT_YELLOW;
cmap[15] = TFT_WHITE;
cmap[14] = TFT_WHITE; // Keep as white for text
cmap[15] = TFT_BLUE; // Keep as blue for sprite border
spr.createPalette(cmap, 16);
// Pass the palette to the Sprite class
spr.createPalette(cmap);
// Push Sprite parially off-screen to test cropping
spr.pushSprite(-40, -40);
spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2, 10);
spr.pushSprite(tft.width() - WIDTH + 40, tft.height() - HEIGHT + 40);
// Number of pixels to draw
uint16_t n = 100;
// Draw 100 random color pixels at random positions in sprite
while (n--)
{
uint16_t color = random(0x10); // Returns color 0 - 0x0F
int16_t x = random(WIDTH); // Random x coordinate
int16_t y = random(HEIGHT); // Random y coordinate
spr.drawPixel( x, y, color); // Draw pixel in sprite
uint16_t color = random(0x10); // Returns color 0 - 0x0F (i.e. 0-15)
int16_t x = random(WIDTH); // Random x coordinate
int16_t y = random(HEIGHT); // Random y coordinate
spr.drawPixel(x, y, color); // Draw pixel in sprite
}
spr.pushSprite(-40, -40);
spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2);
spr.pushSprite(tft.width() - WIDTH + 40, tft.height() - HEIGHT + 40);
delay(DELAY);
// Draw some lines
spr.drawLine(1, 0, WIDTH, HEIGHT-1, 6);
spr.drawLine(0, 0, WIDTH, HEIGHT, 6);
spr.drawLine(0, 1, WIDTH-1, HEIGHT, 2);
spr.drawLine(0, HEIGHT-1, WIDTH-1, 0, 2);
spr.drawLine(0, HEIGHT, WIDTH, 0, 3);
spr.drawLine(1, HEIGHT, WIDTH, 1, 3);
spr.drawLine(4, 0, 4, HEIGHT-1, 11);
spr.drawLine(0, 16, WIDTH-1, 16, 13);
// draw some circles with random colors.
spr.drawCircle(20, 60, 10, 6);
spr.drawCircle(80, 60, 15, 7);
spr.drawCircle(50, 108, 5, 9);
spr.drawCircle(45, 86, 3, 8);
spr.fillCircle(102, 56, 4, 11);
spr.fillRect(28, 32, 40, 4, 5);
//spr.fillRect(27, 42, 40, 14, 6);
//spr.fillRect(33, 55, 3, 4, 7);
//spr.fillRect(34, 32, 7, 4, 8);
spr.drawLine(1, 0, WIDTH, HEIGHT-1, 10);
spr.drawLine(0, 0, WIDTH, HEIGHT, 10);
spr.drawLine(0, 1, WIDTH-1, HEIGHT, 10);
spr.drawLine(0, HEIGHT-1, WIDTH-1, 0, 12);
spr.drawLine(0, HEIGHT, WIDTH, 0, 12);
spr.drawLine(1, HEIGHT, WIDTH, 1, 12);
// Draw some text with Middle Centre datum
spr.setTextDatum(MC_DATUM);
spr.drawString("Sprite", WIDTH / 2, HEIGHT / 2, 1);
spr.setTextColor(14); // White text
spr.drawString("Sprite", WIDTH / 2, HEIGHT / 2, 4);
// Now push the sprite to the TFT at position 0,0 on screen
// Now push the sprite to the TFT at 3 positions on screen
spr.pushSprite(-40, -40);
spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2);
spr.pushSprite(tft.width() - WIDTH + 40, tft.height() - HEIGHT + 40);
delay(DELAY * 4);
// create a new color map and use it instead
for (auto i = 0; i < 16; i++)
// create a new color map for colours 1-13 and use it instead
for (auto i = 1; i <= 13; i++)
{
cmap[i] = random(0x10000);
}
@@ -161,10 +145,9 @@ void loop(void)
// Draw a blue rectangle in sprite so when we move it 1 pixel it does not leave a trail
// on the blue screen background
cmap[14] = TFT_BLUE;
spr.createPalette(cmap, 16);
spr.createPalette(cmap);
spr.drawRect(0, 0, WIDTH, HEIGHT, 14);
spr.drawRect(0, 0, WIDTH, HEIGHT, 15); // Blue rectangle
int x = tft.width() / 2 - WIDTH / 2;
int y = tft.height() / 2 - HEIGHT / 2;
@@ -183,7 +166,15 @@ void loop(void)
if (y < -HEIGHT/2) dy = 1;
if (y >= tft.height()-HEIGHT/2) dy = -1;
// Draw it 50 time, moving in random direct or staying still
// Randomise the palette to change colours without redrawing
// the sprite
for (auto i = 1; i <= 13; i++)
{
cmap[i] = random(0x10000);
}
spr.createPalette(cmap); // Update sprite class palette
// Draw it 50 times, moving in random direct or staying still
n = 50;
int wait = random (50);
while (n)
@@ -205,4 +196,3 @@ void loop(void)
}
} // Infinite while, will not exit!
}

View File

@@ -1,7 +1,7 @@
/*
Sketch to show scrolling of the graphics in sprites.
Sketch to show scrolling of the graphics in 4 bit sprites.
Scrolling in this way moves the pixels in a defined rectangle
within the Sprite. By defalt the whole sprite is scrolled.
within the Sprite. By default the whole sprite is scrolled.
The gap left by scrolling is filled with a defined colour.
Example for library:
@@ -14,10 +14,7 @@
any position. If there is sufficient RAM then the Sprite can
be the same size as the screen and used as a frame buffer.
A 16 bit Sprite occupies (2 * width * height) bytes in RAM.
An 8 bit Sprite occupies (width * height) bytes in RAM.
A 4 bit Sprite occupies (width * height)/2 bytes in RAM.
*/
#include <TFT_eSPI.h>
@@ -35,7 +32,8 @@ int delta = 1;
int grid = 0;
int tcount = 0;
uint16_t cmap[16];
// Palette colour table
uint16_t palette[16];
//==========================================================================================
void setup() {
@@ -43,47 +41,49 @@ void setup() {
tft.init();
tft.fillScreen(TFT_BLACK);
cmap[0] = TFT_BLACK;
cmap[1] = TFT_ORANGE;
cmap[2] = TFT_DARKGREEN;
cmap[3] = TFT_DARKCYAN;
cmap[4] = TFT_MAROON;
cmap[5] = TFT_PURPLE;
cmap[6] = TFT_OLIVE;
cmap[7] = TFT_DARKGREY;
cmap[8] = TFT_ORANGE;
cmap[9] = TFT_BLUE;
cmap[10] = TFT_GREEN;
cmap[11] = TFT_CYAN;
cmap[12] = TFT_RED;
cmap[13] = TFT_NAVY;
cmap[14] = TFT_YELLOW;
cmap[15] = TFT_WHITE;
// Populate the palette table, table must have 16 entires
palette[0] = TFT_BLACK;
palette[1] = TFT_ORANGE;
palette[2] = TFT_DARKGREEN;
palette[3] = TFT_DARKCYAN;
palette[4] = TFT_MAROON;
palette[5] = TFT_PURPLE;
palette[6] = TFT_OLIVE;
palette[7] = TFT_DARKGREY;
palette[8] = TFT_ORANGE;
palette[9] = TFT_BLUE;
palette[10] = TFT_GREEN;
palette[11] = TFT_CYAN;
palette[12] = TFT_RED;
palette[13] = TFT_NAVY;
palette[14] = TFT_YELLOW;
palette[15] = TFT_WHITE;
// Create a sprite for the graph
graph1.setColorDepth(4);
graph1.createSprite(128, 61);
graph1.createPalette(cmap, 16);
graph1.fillSprite(9); // Note: Sprite is filled with black when created
graph1.createPalette(palette);
graph1.fillSprite(9); // Note: Sprite is filled with palette[0] colour when created
// The scroll area is set to the full sprite size upon creation of the sprite
// but we can change that by defining a smaller area using "setScrollRect()"if needed
// parameters are x,y,w,h,color as in drawRect(), the color fills the gap left by scrolling
//graph1.setScrollRect(64, 0, 64, 61, TFT_DARKGREY); // Try this line to change the graph scroll area
// Create a sprite for the scrolling numbers
stext1.setColorDepth(4);
stext1.createSprite(32, 64);
stext1.createPalette(cmap, 16);
stext1.fillSprite(9); // Fill sprite with blue
stext1.setScrollRect(0, 0, 32, 64, 9); // here we set scroll gap fill color to blue
stext1.setTextColor(15); // White text, no background
stext1.createPalette(palette);
stext1.fillSprite(9); // Fill sprite with palette colour 9 (blue in this example)
stext1.setScrollRect(0, 0, 32, 64, 9); // here we set scroll gap fill color to blue
stext1.setTextColor(15); // Palette colour 15 (white) text, no background
stext1.setTextDatum(BR_DATUM); // Bottom right coordinate datum
// Create a sprite for Hello World
stext2.setColorDepth(4);
stext2.createSprite(80, 16);
stext2.createPalette(cmap, 16);
stext2.createPalette(palette);
stext2.fillSprite(7);
stext2.setScrollRect(0, 0, 40, 16, 7); // Scroll the "Hello" in the first 40 pixels
stext2.setTextColor(15); // White text, no background
@@ -97,7 +97,7 @@ void loop() {
// Draw number in stext1 sprite at 31,63 (bottom right datum set)
stext1.drawNumber(graphVal, 31, 63, 2); // plot value in font 2
// Push the sprites onto the TFT at specied coordinates
// Push the sprites onto the TFT at specified coordinates
graph1.pushSprite(0, 0);
stext1.pushSprite(0, 64);
stext2.pushSprite(40, 70);
@@ -132,7 +132,7 @@ void loop() {
tcount--;
if (tcount <=0)
{ // If we have scrolled 40 pixels the redraw text
{ // If we have scrolled 40 pixels then redraw text
tcount = 40;
stext2.drawString("Hello World", 6, 0, 2); // draw at 6,0 in sprite, font 2
}

View File

@@ -0,0 +1,146 @@
/*
Sketch to show creation of a 4 bit sprite with a transparent
background, then plot it on the TFT. The palette setup and
palette update functions are also shown in this example.
Example for library:
https://github.com/Bodmer/TFT_eSPI
A Sprite is notionally an invisible graphics screen that is
kept in the processors RAM. Graphics can be drawn into the
Sprite just as it can be drawn directly to the screen. Once
the Sprite is completed it can be plotted onto the screen in
any position. If there is sufficient RAM then the Sprite can
be the same size as the screen and used as a frame buffer.
A 4 bit Sprite occupies (width * height)/2 bytes in RAM.
For example the "star" 70x80 Sprite uses 2800 bytes.
*/
// This is the default palette for 4 bit colour sprites
// which is built into the library. You can create your
// own palette (use a different array name!). The palette
// is captured and stored in RAM by the Sprite class so a
// copy does not need to be kept in the sketch.
// The default library palette is stored in FLASH and is called:
// default_4bit_palette
// To edit colours change the default_4bit_palette array name
// at line 32, then edit line 77 to match new name.
// To setup you own palette edit the next line to //*
/*
static const uint16_t default_4bit_palette[] PROGMEM = {
TFT_BLACK, // 0 ^
TFT_BROWN, // 1 |
TFT_RED, // 2 |
TFT_ORANGE, // 3 |
TFT_YELLOW, // 4 Colours 0-9 follow the resistor colour code!
TFT_GREEN, // 5 |
TFT_BLUE, // 6 |
TFT_PURPLE, // 7 |
TFT_DARKGREY, // 8 |
TFT_WHITE, // 9 v
TFT_CYAN, // 10 Blue+green mix
TFT_MAGENTA, // 11 Blue+red mix
TFT_MAROON, // 12 Darker red colour
TFT_DARKGREEN,// 13 Darker green colour
TFT_NAVY, // 14 Darker blue colour
TFT_PINK // 15
};
//*/
#include <TFT_eSPI.h> // Include the graphics library (this includes the sprite functions)
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
TFT_eSprite spr = TFT_eSprite(&tft); // Create Sprite object "spr" with pointer to "tft" object
// the pointer is used by pushSprite() to push it onto the TFT
void setup(void) {
Serial.begin(115200);
tft.init();
tft.setRotation(0);
}
void loop() {
tft.fillScreen(TFT_DARKGREY);
// Set color depth to 4 bits
spr.setColorDepth(4);
spr.createSprite(70, 80); // The Sprite MUST be created before setting the palette!
// Pass the default library palette to the Sprite class
// Edit palette array name if you use your own palette
spr.createPalette(default_4bit_palette); // <<<<<<<<<<<<<<<<<<<<<<<<< palette array name
// If <16 colours are defined then specify how many
// spr.createPalette(default_4bit_palette, 12);
// After rendering a Sprite you can change the palette to increase the range of colours
// plotted to the screen to the full 16 bit set.
// Change palette colour 11 to violet
spr.setPaletteColor(11, TFT_VIOLET);
uint16_t color15 = spr.getPaletteColor(15); // The 16 bit colour in a palette can be read back
// Draw 50 sprites containing a "transparent" colour
for (int i = 0; i < 50; i++)
{
int x = random(tft.width() - 70);
int y = random(tft.height() - 80);
int c = random(15); // Random colour 0-14 (4 bit index into color map). Leave 15 for transparent.
drawStar(x, y, c);
}
delay(2000);
// Change the palette to a 16 bit grey scale colour
for (uint8_t i = 0; i < 16; i++) {
// (i*16+i) produces a value in range 0-255 for the RGB colours
// Red Green Blue
spr.setPaletteColor(i, tft.color565(i*16+i, i*16+i, i*16+i));
}
// Now go bananas and draw 500 more
for (int i = 0; i < 500; i++)
{
int x = random(tft.width() - 70);
int y = random(tft.height() - 80);
int c = random(0x10); // Random colour
drawStar(x, y, c);
yield(); // Stop watchdog reset
}
// Delete it to free memory, the Sprite copy of the palette is also deleted
spr.deleteSprite();
delay(2000);
}
// #########################################################################
// Plot graphics to sprite using defined color and plot to screen
// #########################################################################
void drawStar(int x, int y, int star_color)
{
// star_color will be in the range 0-14 so that 15 is reserved for the
// transparent colour
// Fill Sprite with the chosen "transparent" colour
spr.fillSprite(15); // Fill with color 15
// Draw 2 triangles to create a filled in star
spr.fillTriangle(35, 0, 0, 59, 69, 59, star_color);
spr.fillTriangle(35, 79, 0, 20, 69, 20, star_color);
// Punch a star shaped hole in the middle with a smaller transparent star
spr.fillTriangle(35, 7, 6, 56, 63, 56, 15);
spr.fillTriangle(35, 73, 6, 24, 63, 24, 15);
// Push sprite to TFT screen at coordinate x,y (top left corner)
// Specify what colour from the palette is treated as transparent.
spr.pushSprite(x, y, 15);
}

View File

@@ -1,168 +0,0 @@
/*
Sketch to show creation of a sprite with a transparent
background, then plot it on the TFT.
Example for library:
https://github.com/Bodmer/TFT_eSPI
A Sprite is notionally an invisible graphics screen that is
kept in the processors RAM. Graphics can be drawn into the
Sprite just as it can be drawn directly to the screen. Once
the Sprite is completed it can be plotted onto the screen in
any position. If there is sufficient RAM then the Sprite can
be the same size as the screen and used as a frame buffer.
A 16 bit Sprite occupies (2 * width * height) bytes in RAM.
On a ESP8266 Sprite sizes up to 126 x 160 can be accomodated,
this size requires 40kBytes of RAM for a 16 bit colour depth.
When 8 bit colour depth sprites are created they occupy
(width * height) bytes in RAM, so larger sprites can be
created, or the RAM required is halved.
*/
#include <TFT_eSPI.h> // Include the graphics library (this includes the sprite functions)
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
TFT_eSprite img = TFT_eSprite(&tft); // Create Sprite object "img" with pointer to "tft" object
// the pointer is used by pushSprite() to push it onto the TFT
TFT_eSprite img2 = TFT_eSprite(&tft);
void setup(void) {
Serial.begin(250000);
tft.init();
tft.setRotation(0);
}
void loop() {
tft.fillScreen(TFT_NAVY);
img.setColorDepth(4);
// Draw 10 sprites containing a "transparent" colour
for (int i = 0; i < 10; i++)
{
int x = random(240-70);
int y = random(320-80);
int c = random(0x0F); // Random colour (4 bit index into color map). Leave 15 for transparent.
drawStar(x, y, c); // note: not random; should be c
}
delay(2000);
uint32_t dt = millis();
// Now go bananas and draw 500 nore
for (int i = 0; i < 500; i++)
{
int x = random(240-70);
int y = random(320-80);
int c = random(0x10); // Random colour
drawStar(x, y, c);
yield(); // Stop watchdog reset
}
// Show time in milliseconds to draw and then push 1 sprite to TFT screen
numberBox( 10, 10, (millis()-dt)/500.0 );
delay(2000);
}
// #########################################################################
// Create sprite, plot graphics in it, plot to screen, then delete sprite
// #########################################################################
void drawStar(int x, int y, int star_color)
{
// Create an 8 bit sprite 70x 80 pixels (uses 5600 bytes of RAM)
img.setColorDepth(4);
img.createSprite(70, 80);
uint16_t cmap[16];
cmap[0] = TFT_BLACK;
cmap[1] = TFT_ORANGE;
cmap[2] = TFT_DARKGREEN;
cmap[3] = TFT_DARKCYAN;
cmap[4] = TFT_MAROON;
cmap[5] = TFT_PURPLE;
cmap[6] = TFT_OLIVE;
cmap[7] = TFT_LIGHTGREY;
cmap[8] = TFT_DARKGREY;
cmap[9] = TFT_BLUE;
cmap[10] = TFT_GREEN;
cmap[11] = TFT_CYAN;
cmap[12] = TFT_RED;
cmap[13] = TFT_MAGENTA;
cmap[14] = TFT_YELLOW;
cmap[15] = TFT_WHITE; // this one will be transparent.
img.createPalette(cmap, 16);
// Fill Sprite with a "transparent" colour
// TFT_TRANSPARENT is already defined for convenience
// We could also fill with any colour as "transparent" and later specify that
// same colour when we push the Sprite onto the screen.
img.fillSprite(15);
// Draw 2 triangles to create a filled in star
img.fillTriangle(35, 0, 0,59, 69,59, star_color);
img.fillTriangle(35,79, 0,20, 69,20, star_color);
// Punch a star shaped hole in the middle with a smaller transparent star
// this one damages on pixel in the second triangle
img.fillTriangle(35, 7, 6,56, 63,56, 15);
img.fillTriangle(35,73, 6,24, 63,24, 15);
// Push sprite to TFT screen at coordinate x,y (top left corner)
// Specify what colour from the map is to be treated as transparent.
img.pushSprite(x, y, 15);
// Delete it to free memory
img.deleteSprite();
}
// #########################################################################
// Draw a number in a rounded rectangle with some transparent pixels
// #########################################################################
void numberBox(int x, int y, float num )
{
// Size of sprite
#define IWIDTH 80
#define IHEIGHT 35
// Create a 8 bit sprite 80 pixels wide, 35 high (2800 bytes of RAM needed)
img.setColorDepth(8);
img.createSprite(IWIDTH, IHEIGHT);
// Fill it with black (this will be the transparent colour this time)
img.fillSprite(TFT_BLACK);
// Draw a background for the numbers
img.fillRoundRect( 0, 0, 80, 35, 15, TFT_RED);
img.drawRoundRect( 0, 0, 80, 35, 15, TFT_WHITE);
// Set the font parameters
img.setTextSize(1); // Font size scaling is x1
img.setTextColor(TFT_WHITE); // White text, no background colour
// Set text coordinate datum to middle right
img.setTextDatum(MR_DATUM);
// Draw the number to 3 decimal places at 70,20 in font 4
img.drawFloat(num, 3, 70, 20, 4);
// Push sprite to TFT screen CGRAM at coordinate x,y (top left corner)
// All black pixels will not be drawn hence will show as "transparent"
img.pushSprite(x, y, TFT_BLACK);
// Delete sprite to free up the RAM
img.deleteSprite();
}

View File

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

View File

@@ -1,5 +1,5 @@
name=TFT_eSPI
version=1.5.0
version=2.0.0
author=Bodmer
maintainer=Bodmer
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32

View File

@@ -105,7 +105,7 @@ and is compatible with the GNU GPL.
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvStartvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Software License Agreement (FreeBSD License)
Copyright (c) 2017 Bodmer (https://github.com/Bodmer)
Copyright (c) 2020 Bodmer (https://github.com/Bodmer)
All rights reserved.