mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-08-07 06:34:44 +02:00
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:
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)); \
|
||||
|
@@ -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);
|
||||
|
@@ -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; \
|
||||
|
12
README.md
12
README.md
@@ -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
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
||||
|
||||
|
23
README.txt
23
README.txt
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -109,9 +109,9 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
spi_end();
|
||||
end_tft_write();
|
||||
delay(120);
|
||||
spi_begin();
|
||||
begin_tft_write();
|
||||
|
||||
writecommand(ST7789_DISPON); //Display on
|
||||
delay(120);
|
||||
|
@@ -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
|
||||
}
|
252
TFT_eSPI.cpp
252
TFT_eSPI.cpp
@@ -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
|
||||
|
765
TFT_eSPI.h
765
TFT_eSPI.h
@@ -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_
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
52
User_Setups/Setup31_ST7796_Parallel_STM32.h
Normal file
52
User_Setups/Setup31_ST7796_Parallel_STM32.h
Normal 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
|
62
User_Setups/Setup32_ILI9341_STM32F103.h
Normal file
62
User_Setups/Setup32_ILI9341_STM32F103.h
Normal 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
|
194
examples/Generic/alphaBlend_Test/alphaBlend_Test.ino
Normal file
194
examples/Generic/alphaBlend_Test/alphaBlend_Test.ino
Normal 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;
|
||||
}
|
||||
|
||||
|
@@ -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!
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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();
|
||||
}
|
||||
|
@@ -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":
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
||||
|
Reference in New Issue
Block a user