Compare commits
No commits in common. "master" and "v2.5.0" have entirely different histories.
2
Kconfig
2
Kconfig
|
|
@ -215,7 +215,7 @@ menu "TFT_eSPI"
|
|||
|
||||
choice TFT_SPI_PORT
|
||||
prompt "SPI port"
|
||||
default TFT_VSPI_PORT
|
||||
default TFT_SPI_2_HOST
|
||||
help
|
||||
The ESP32 has 2 free SPI ports i.e. VSPI (SPI2) and HSPI (SPI3),
|
||||
the VSPI is the default. If the VSPI port is in use and pins are
|
||||
|
|
|
|||
|
|
@ -64,35 +64,29 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: beginSDA - VSPI port only, FPSI port only for S2
|
||||
** Description: Detach MOSI and attach MISO to SDA for reads
|
||||
** Function name: beginSDA
|
||||
** Description: Detach SPI from pin to permit software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::begin_SDA_Read(void)
|
||||
{
|
||||
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
pinMatrixOutDetach(TFT_MOSI, false, false);
|
||||
pinMode(TFT_MOSI, INPUT);
|
||||
pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false);
|
||||
#else // S2
|
||||
pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false);
|
||||
#endif
|
||||
SET_BUS_READ_MODE;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: endSDA - VSPI port only, FPSI port only for S2
|
||||
** Description: Attach MOSI to SDA and detach MISO for writes
|
||||
** Function name: endSDA
|
||||
** Description: Attach SPI pins after software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::end_SDA_Read(void)
|
||||
{
|
||||
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
pinMode(TFT_MOSI, OUTPUT);
|
||||
pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false);
|
||||
#else // S2
|
||||
pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false);
|
||||
#endif
|
||||
pinMode(TFT_MISO, INPUT);
|
||||
pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false);
|
||||
SET_BUS_WRITE_MODE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif // #if defined (TFT_SDA_READ)
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -66,24 +66,27 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: beginSDA - FPSI port only
|
||||
** Description: Detach MOSI and attach MISO to SDA for reads
|
||||
** Function name: beginSDA
|
||||
** Description: Detach SPI from pin to permit software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::begin_SDA_Read(void)
|
||||
{
|
||||
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT);
|
||||
pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false);
|
||||
pinMatrixOutDetach(TFT_MOSI, false, false);
|
||||
pinMode(TFT_MOSI, INPUT);
|
||||
pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false);
|
||||
SET_BUS_READ_MODE;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: endSDA - FPSI port only
|
||||
** Description: Attach MOSI to SDA and detach MISO for writes
|
||||
** Function name: endSDA
|
||||
** Description: Attach SPI pins after software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::end_SDA_Read(void)
|
||||
{
|
||||
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT);
|
||||
pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false);
|
||||
pinMode(TFT_MOSI, OUTPUT);
|
||||
pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false);
|
||||
pinMode(TFT_MISO, INPUT);
|
||||
pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false);
|
||||
SET_BUS_WRITE_MODE;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@
|
|||
#endif
|
||||
#else
|
||||
#ifdef USE_HSPI_PORT
|
||||
#define DMA_CHANNEL SPI_DMA_CH_AUTO
|
||||
spi_host_device_t spi_host = SPI3_HOST;
|
||||
#define DMA_CHANNEL 2
|
||||
spi_host_device_t spi_host = (spi_host_device_t) DMA_CHANNEL; // Draws once then freezes
|
||||
#else // use FSPI port
|
||||
#define DMA_CHANNEL SPI_DMA_CH_AUTO
|
||||
spi_host_device_t spi_host = SPI2_HOST;
|
||||
#define DMA_CHANNEL 1
|
||||
spi_host_device_t spi_host = (spi_host_device_t) DMA_CHANNEL; // Draws once then freezes
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -57,24 +57,27 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: beginSDA - FPSI port only
|
||||
** Description: Detach MOSI and attach MISO to SDA for reads
|
||||
** Function name: beginSDA
|
||||
** Description: Detach SPI from pin to permit software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::begin_SDA_Read(void)
|
||||
{
|
||||
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT);
|
||||
pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false);
|
||||
pinMatrixOutDetach(TFT_MOSI, false, false);
|
||||
pinMode(TFT_MOSI, INPUT);
|
||||
pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false);
|
||||
SET_BUS_READ_MODE;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: endSDA - FPSI port only
|
||||
** Description: Attach MOSI to SDA and detach MISO for writes
|
||||
** Function name: endSDA
|
||||
** Description: Attach SPI pins after software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::end_SDA_Read(void)
|
||||
{
|
||||
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT);
|
||||
pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false);
|
||||
pinMode(TFT_MOSI, OUTPUT);
|
||||
pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false);
|
||||
pinMode(TFT_MISO, INPUT);
|
||||
pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false);
|
||||
SET_BUS_WRITE_MODE;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -640,15 +643,6 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
|
|||
for (uint32_t i = 0; i < len; i++) (image[i] = image[i] << 8 | image[i] >> 8);
|
||||
}
|
||||
|
||||
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
|
||||
// small transfers are performed using a blocking call until DMA capacity is reached.
|
||||
// User sketch can prevent blocking by managing pixel count and splitting into blocks
|
||||
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
|
||||
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
|
||||
pushPixels(image, 0x400);
|
||||
len -= 0x400; image+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
static spi_transaction_t trans;
|
||||
|
||||
|
|
@ -675,20 +669,11 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
|||
{
|
||||
if ((w == 0) || (h == 0) || (!DMA_Enabled)) return;
|
||||
|
||||
uint16_t *buffer = (uint16_t*)image;
|
||||
uint32_t len = w*h;
|
||||
|
||||
dmaWait();
|
||||
|
||||
setAddrWindow(x, y, w, h);
|
||||
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
|
||||
// small transfers are performed using a blocking call until DMA capacity is reached.
|
||||
// User sketch can prevent blocking by managing pixel count and splitting into blocks
|
||||
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
|
||||
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
|
||||
pushPixels(buffer, 0x400);
|
||||
len -= 0x400; buffer+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
static spi_transaction_t trans;
|
||||
|
|
@ -696,7 +681,7 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
|||
memset(&trans, 0, sizeof(spi_transaction_t));
|
||||
|
||||
trans.user = (void *)1;
|
||||
trans.tx_buffer = buffer; //Data pointer
|
||||
trans.tx_buffer = image; //Data pointer
|
||||
trans.length = len * 16; //Data length, in bits
|
||||
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
|
||||
|
||||
|
|
@ -766,15 +751,6 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
|||
|
||||
setAddrWindow(x, y, dw, dh);
|
||||
|
||||
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
|
||||
// small transfers are performed using a blocking call until DMA capacity is reached.
|
||||
// User sketch can prevent blocking by managing pixel count and splitting into blocks
|
||||
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
|
||||
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
|
||||
pushPixels(buffer, 0x400);
|
||||
len -= 0x400; buffer+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
static spi_transaction_t trans;
|
||||
|
||||
|
|
@ -798,7 +774,7 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
|||
// The DMA functions here work with SPI only (not parallel)
|
||||
/***************************************************************************************
|
||||
** Function name: dc_callback
|
||||
** Description: Toggles DC line during transaction (not used)
|
||||
** Description: Toggles DC line during transaction
|
||||
***************************************************************************************/
|
||||
extern "C" void dc_callback();
|
||||
|
||||
|
|
@ -808,17 +784,6 @@ void IRAM_ATTR dc_callback(spi_transaction_t *spi_tx)
|
|||
else {DC_C;}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: dma_end_callback
|
||||
** Description: Clear DMA run flag to stop retransmission loop
|
||||
***************************************************************************************/
|
||||
extern "C" void dma_end_callback();
|
||||
|
||||
void IRAM_ATTR dma_end_callback(spi_transaction_t *spi_tx)
|
||||
{
|
||||
WRITE_PERI_REG(SPI_DMA_CONF_REG(spi_host), 0);
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: initDMA
|
||||
** Description: Initialise the DMA engine - returns true if init OK
|
||||
|
|
@ -834,7 +799,7 @@ bool TFT_eSPI::initDMA(bool ctrl_cs)
|
|||
.sclk_io_num = TFT_SCLK,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = 65536, // ESP32 S3 max size is 64Kbytes
|
||||
.max_transfer_sz = TFT_WIDTH * TFT_HEIGHT * 2 + 8, // TFT screen size
|
||||
.flags = 0,
|
||||
.intr_flags = 0
|
||||
};
|
||||
|
|
@ -854,9 +819,9 @@ bool TFT_eSPI::initDMA(bool ctrl_cs)
|
|||
.input_delay_ns = 0,
|
||||
.spics_io_num = pin,
|
||||
.flags = SPI_DEVICE_NO_DUMMY, //0,
|
||||
.queue_size = 1, // Not using queues
|
||||
.pre_cb = 0, //dc_callback, //Callback to handle D/C line (not used)
|
||||
.post_cb = dma_end_callback //Callback to end transmission
|
||||
.queue_size = 1,
|
||||
.pre_cb = 0, //dc_callback, //Callback to handle D/C line
|
||||
.post_cb = 0
|
||||
};
|
||||
ret = spi_bus_initialize(spi_host, &buscfg, DMA_CHANNEL);
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@
|
|||
#ifndef _TFT_eSPI_ESP32H_
|
||||
#define _TFT_eSPI_ESP32H_
|
||||
|
||||
#if !defined(DISABLE_ALL_LIBRARY_WARNINGS)
|
||||
#warning >>>>------>> DMA is not supported on the ESP32 S3 (possible future update)
|
||||
#endif
|
||||
|
||||
// Processor ID reported by getSetup()
|
||||
#define PROCESSOR_ID 0x32
|
||||
|
||||
|
|
@ -106,10 +110,6 @@ SPI3_HOST = 2
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_ALL_LIBRARY_WARNINGS) && defined (ESP32_PARALLEL)
|
||||
#warning >>>>------>> DMA is not supported in parallel mode
|
||||
#endif
|
||||
|
||||
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
|
||||
#if !defined (ESP32_PARALLEL)
|
||||
#define _spi_cmd (volatile uint32_t*)(SPI_CMD_REG(SPI_PORT))
|
||||
|
|
@ -134,7 +134,7 @@ SPI3_HOST = 2
|
|||
#if !defined(TFT_PARALLEL_8_BIT) && !defined(SPI_18BIT_DRIVER)
|
||||
#define ESP32_DMA
|
||||
// Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
|
||||
#define DMA_BUSY_CHECK dmaWait()
|
||||
#define DMA_BUSY_CHECK //dmaWait()
|
||||
#else
|
||||
#define DMA_BUSY_CHECK
|
||||
#endif
|
||||
|
|
|
|||
38
README.md
38
README.md
|
|
@ -1,24 +1,27 @@
|
|||
A ["Discussions"](https://github.com/Bodmer/TFT_eSPI/discussions) facility has been added for Q&A etc. Use the ["Issues"](https://github.com/Bodmer/TFT_eSPI/issues) tab only for problems with the library. Thanks!
|
||||
# News
|
||||
1. New functions have been added to draw smooth (antialiased) arcs, circles, and rounded rectangle outlines. New sketches are provided in the "Smooth Graphics" examples folder. Arcs can be drawn with or without anti-aliasing (which will then render faster). The arc ends can be straight or rounded. The arc drawing algorithm uses an optimised fixed point sqrt() function to improve performance on processors that do not have a hardware Floating Point Unit (e.g. RP2040). Here are two demo images, on the left smooth (anti-aliased) arcs with rounded ends, the image to the right is the same resolution (grabbed from the same 240x240 TFT) with the smoothing diasbled (no anti-aliasing):
|
||||
1. New functions have been added to draw smooth (antialiased) arcs, circles, and rounded rectangle outlines. New sketches are provided in the "Smooth Graphics" examples folder. Arcs can be drawn with or without anti-aliasing (which will then render faster). The arc ends can be straight or rounded. The arc drawing algorithm uses an optimised fixed point sqrt() function to improve performance on processors that do not have a hardware Floating Point Unit (e.g. RP2040). Here's a demo image of smooth (anti-aliased) arcs with rounded ends and increasing sweep angle:
|
||||
|
||||
 
|
||||

|
||||
|
||||
Here the smooth arcs have been used to create anti-aliased meter gauges on a 320x240 TFT:
|
||||
Here is the same resolution image (grabbed from the same TFT) with the smoothing diasbled (no anti-aliasing):
|
||||
|
||||

|
||||

|
||||
|
||||
2. An excellent new compatible library is available which can render TrueType fonts on a TFT screen (or into a sprite). This has been developed by [takkaO](https://github.com/takkaO/OpenFontRender), I have created a branch with some bug fixes [here](https://github.com/Bodmer/OpenFontRender). The library provides access to compact font files, with fully scaleable anti-aliased glyphs. Left, middle and right justified text can also be printed to the screen. I have added TFT_eSPI specific examples to the OpenFontRender library and tested on RP2040 and ESP32 processors, the ESP8266 does not have sufficient RAM due to the glyph render complexity. Here is a demo screen where a single 12kbyte font file binary was used to render fully anti-aliased glyphs of gradually increasing size on a 320x480 TFT screen:
|
||||
|
||||

|
||||
|
||||
3. New GUI examples have been added for sliders, buttons, graphs and meters. These examples require a new support library here:
|
||||
3. The following is now deprecated due to the number of issues it can cause in certain circumstances. <del>For ESP32 ONLY, the TFT configuration (user setup) can now be included inside an Arduino IDE sketch providing the instructions in the example Generic->Sketch_with_tft_setup are followed. See ReadMe tab in that sketch for the instructions. If the setup is not in the sketch then the library settings will be used. This means that "per project" configurations are possible without modifying the library setup files. Please note that ALL the other examples in the library will use the library settings unless they are adapted and the "tft_setup.h" header file included. Note: there are issues with this approach, [#2007](https://github.com/Bodmer/TFT_eSPI/discussions/2007#discussioncomment-3834755) proposes an alternative method. </del>
|
||||
|
||||
4. New GUI examples have been added for sliders, buttons, graphs and meters. These examples require a new support library here:
|
||||
|
||||
[TFT_eWidget](https://github.com/Bodmer/TFT_eWidget)
|
||||
|
||||
4. Support has been added in v2.4.70 for the RP2040 with 16 bit parallel displays. This has been tested and the screen update performance is very good (4ms to clear 320 x 480 screen with HC8357C). The use of the RP2040 PIO makes it easy to change the write cycle timing for different displays. DMA with 16 bit transfers is also supported.
|
||||
5. Support has been added in v2.4.70 for the RP2040 with 16 bit parallel displays. This has been tested and the screen update performance is very good (4ms to clear 320 x 480 screen with HC8357C). The use of the RP2040 PIO makes it easy to change the write cycle timing for different displays. DMA with 16 bit transfers is also supported.
|
||||
|
||||
5. Support for the ESP32-S2, ESP32-S3 and ESP32-C3 has been added (DMA only on ESP32 S3 at the moment). Tested with v2.0.3 RC1 of the ESP32 board package. Example setups:
|
||||
6. Support for HX8357B and HX8357C screens has been added (only tested with RP2040 and 16 bit parallel interface)
|
||||
7. Support for the ESP32-S2, ESP32-S3 and ESP32-C3 has been added (DMA not supported at the moment). Tested with v2.0.3 RC1 of the ESP32 board package. Example setups:
|
||||
|
||||
[Setup70_ESP32_S2_ILI9341.h](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup70_ESP32_S2_ILI9341.h)
|
||||
|
||||
|
|
@ -28,20 +31,20 @@ A ["Discussions"](https://github.com/Bodmer/TFT_eSPI/discussions) facility has b
|
|||
|
||||
[Setup70d_ILI9488_S3_Parallel.h](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup70d_ILI9488_S3_Parallel.h)
|
||||
|
||||
6. Smooth fonts can now be rendered direct to the TFT with very little flicker for quickly changing values. This is achieved by a line-by-line and block-by-block update of the glyph area without drawing pixels twice. This is a "breaking" change for some sketches because a new true/false parameter is needed to render the background. The default is false if the parameter is missing, Examples:
|
||||
8. Smooth fonts can now be rendered direct to the TFT with very little flicker for quickly changing values. This is achieved by a line-by-line and block-by-block update of the glyph area without drawing pixels twice. This is a "breaking" change for some sketches because a new true/false parameter is needed to render the background. The default is false if the parameter is missing, Examples:
|
||||
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLUE, true);
|
||||
spr.setTextColor(TFT_BLUE, TFT_BLACK, true);
|
||||
|
||||
Note: background rendering for Smooth fonts is also now available when using the print stream e.g. with: tft.println("Hello World");
|
||||
|
||||
7. New anti-aliased graphics functions to draw lines, wedge shaped lines, circles and rounded rectangles. [Examples are included](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/Smooth%20Graphics). Examples have also been added to [display PNG compressed images](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/PNG%20Images) (note: requires ~40kbytes RAM).
|
||||
9. New anti-aliased graphics functions to draw lines, wedge shaped lines, circles and rounded rectangles. [Examples are included](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/Smooth%20Graphics). Examples have also been added to [display PNG compressed images](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/PNG%20Images) (note: requires ~40kbytes RAM).
|
||||
|
||||
8. Frank Boesing has created an extension library for TFT_eSPI that allows a large range of ready-built fonts to be used. Frank's library (adapted to permit rendering in sprites as well as TFT) can be [downloaded here](https://github.com/Bodmer/TFT_eSPI_ext). More than 3300 additional Fonts are [available here](https://github.com/FrankBoesing/fonts/tree/master/ofl). The TFT_eSPI_ext library contains examples that demonstrate the use of the fonts.
|
||||
10. Frank Boesing has created an extension library for TFT_eSPI that allows a large range of ready-built fonts to be used. Frank's library (adapted to permit rendering in sprites as well as TFT) can be [downloaded here](https://github.com/Bodmer/TFT_eSPI_ext). More than 3300 additional Fonts are [available here](https://github.com/FrankBoesing/fonts/tree/master/ofl). The TFT_eSPI_ext library contains examples that demonstrate the use of the fonts.
|
||||
|
||||
9. Users of PowerPoint experienced with running macros may be interested in the [pptm sketch generator here](https://github.com/Bodmer/PowerPoint_to_sketch), this converts graphics and tables drawn in PowerPoint slides into an Arduino sketch that renders the graphics on a 480x320 TFT. This is based on VB macros [created by Kris Kasprzak here](https://github.com/KrisKasprzak/Powerpoint-ILI9341_t3).
|
||||
11. Users of PowerPoint experienced with running macros may be interested in the [pptm sketch generator here](https://github.com/Bodmer/PowerPoint_to_sketch), this converts graphics and tables drawn in PowerPoint slides into an Arduino sketch that renders the graphics on a 480x320 TFT. This is based on VB macros [created by Kris Kasprzak here](https://github.com/KrisKasprzak/Powerpoint-ILI9341_t3).
|
||||
|
||||
10. The library contains two new functions for rectangles filled with a horizontal or vertical coloured gradient:
|
||||
12. The library contains two new functions for rectangles filled with a horizontal or vertical coloured gradient:
|
||||
|
||||
tft.fillRectHGradient(x, y, w, h, color1, color2);
|
||||
|
||||
|
|
@ -49,12 +52,12 @@ Note: background rendering for Smooth fonts is also now available when using the
|
|||
|
||||

|
||||
|
||||
11. The RP2040 8 bit parallel interface uses the PIO. The PIO now manages the "setWindow" and "block fill" actions, releasing the processor for other tasks when areas of the screen are being filled with a colour. The PIO can optionally be used for SPI interface displays if #define RP2040_PIO_SPI is put in the setup file. Touch screens and pixel read operations are not supported when the PIO interface is used.
|
||||
13. The RP2040 8 bit parallel interface uses the PIO. The PIO now manages the "setWindow" and "block fill" actions, releasing the processor for other tasks when areas of the screen are being filled with a colour. The PIO can optionally be used for SPI interface displays if #define RP2040_PIO_SPI is put in the setup file. Touch screens and pixel read operations are not supported when the PIO interface is used.
|
||||
The RP2040 PIO features only work with [Earle Philhower's board package](https://github.com/earlephilhower/arduino-pico), NOT the Arduino Mbed version.
|
||||
|
||||
The use of PIO for SPI allows the RP2040 to be over-clocked (up to 250MHz works on my boards) in Earle's board package whilst still maintaining high SPI clock rates.
|
||||
|
||||
12. DMA can now be used with the Raspberry Pi Pico (RP2040) when used with 8/16 bit parallel and 16 bit colour SPI displays. See "Bouncy_Circles" sketch.
|
||||
14. DMA can now be used with the Raspberry Pi Pico (RP2040) when used with both 8 bit parallel and 16 bit colour SPI displays. See "Bouncy_Circles" sketch.
|
||||
|
||||
["Bouncing circles"](https://www.youtube.com/watch?v=njFXIzCTQ_Q&lc=UgymaUIwOIuihvYh-Qt4AaABAg)
|
||||
|
||||
|
|
@ -207,3 +210,10 @@ You can take this one step further and have your own setup select file and then
|
|||
#include <../TFT_eSPI_Setups/my_setup_select.h>
|
||||
```
|
||||
To select a new setup you then edit your own my_setup_select.h file (which will not get overwritten during an upgrade).
|
||||
|
||||
# ePaper displays
|
||||
|
||||
The library was intended to support only TFT displays but using a Sprite as a 1 bit per pixel screen buffer permits support for the Waveshare 2 and 3 colour SPI ePaper displays. This addition to the library is experimental and only one example is provided. Further examples will be added.
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
79
TFT_eSPI.cpp
79
TFT_eSPI.cpp
|
|
@ -1181,13 +1181,6 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
|
|||
#if defined (ST7796_DRIVER)
|
||||
// Read the 2 bytes
|
||||
color = ((tft_Read_8()) << 8) | (tft_Read_8());
|
||||
#elif defined (ST7735_DRIVER)
|
||||
// Read the 3 RGB bytes, colour is in LS 6 bits of the top 7 bits of each byte
|
||||
// as the TFT stores colours as 18 bits
|
||||
uint8_t r = tft_Read_8()<<1;
|
||||
uint8_t g = tft_Read_8()<<1;
|
||||
uint8_t b = tft_Read_8()<<1;
|
||||
color = color565(r, g, b);
|
||||
#else
|
||||
// Read the 3 RGB bytes, colour is actually only in the top 6 bits of each byte
|
||||
// as the TFT stores colours as 18 bits
|
||||
|
|
@ -1348,13 +1341,6 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
|
|||
#if defined (ST7796_DRIVER)
|
||||
// Read the 2 bytes
|
||||
color = ((tft_Read_8()) << 8) | (tft_Read_8());
|
||||
#elif defined (ST7735_DRIVER)
|
||||
// Read the 3 RGB bytes, colour is in LS 6 bits of the top 7 bits of each byte
|
||||
// as the TFT stores colours as 18 bits
|
||||
uint8_t r = tft_Read_8()<<1;
|
||||
uint8_t g = tft_Read_8()<<1;
|
||||
uint8_t b = tft_Read_8()<<1;
|
||||
color = color565(r, g, b);
|
||||
#else
|
||||
// Read the 3 RGB bytes, colour is actually only in the top 6 bits of each byte
|
||||
// as the TFT stores colours as 18 bits
|
||||
|
|
@ -3899,7 +3885,7 @@ uint16_t TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha
|
|||
** Function name: drawSmoothArc
|
||||
** Description: Draw a smooth arc clockwise from 6 o'clock
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, uint32_t startAngle, uint32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds)
|
||||
void TFT_eSPI::drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds)
|
||||
// Centre at x,y
|
||||
// r = arc outer radius, ir = arc inner radius. Inclusive so arc thickness = r - ir + 1
|
||||
// Angles in range 0-360
|
||||
|
|
@ -3994,22 +3980,22 @@ inline uint8_t TFT_eSPI::sqrt_fraction(uint32_t num) {
|
|||
// smooth is optional, default is true, smooth=false means no antialiasing
|
||||
// Note: Arc ends are not anti-aliased (use drawSmoothArc instead for that)
|
||||
void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
||||
uint32_t startAngle, uint32_t endAngle,
|
||||
int32_t startAngle, int32_t endAngle,
|
||||
uint32_t fg_color, uint32_t bg_color,
|
||||
bool smooth)
|
||||
{
|
||||
if (endAngle > 360) endAngle = 360;
|
||||
if (startAngle > 360) startAngle = 360;
|
||||
if (endAngle < startAngle) {
|
||||
// Arc sweeps through 6 o'clock so draw in two parts
|
||||
drawArc(x, y, r, ir, startAngle, 360, fg_color, bg_color, smooth);
|
||||
startAngle = 0;
|
||||
}
|
||||
|
||||
if (_vpOoB || startAngle == endAngle) return;
|
||||
if (r < ir) transpose(r, ir); // Required that r > ir
|
||||
if (r <= 0 || ir < 0) return; // Invalid r, ir can be zero (circle sector)
|
||||
if (startAngle < 0) startAngle = 0;
|
||||
if (endAngle > 360) endAngle = 360;
|
||||
|
||||
if (endAngle < startAngle) {
|
||||
// Arc sweeps through 6 o'clock so draw in two parts
|
||||
if (startAngle < 360) drawArc(x, y, r, ir, startAngle, 360, fg_color, bg_color, smooth);
|
||||
if (endAngle == 0) return;
|
||||
startAngle = 0;
|
||||
}
|
||||
inTransaction = true;
|
||||
|
||||
int32_t xs = 0; // x start position for quadrant scan
|
||||
|
|
@ -4023,6 +4009,10 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||
if (smooth) ir--; // Inner AA zone radius
|
||||
uint32_t r4 = ir * ir; // Inner AA radius^2
|
||||
|
||||
// Float variants of adjusted inner and outer arc radii
|
||||
//float irf = ir;
|
||||
//float rf = r;
|
||||
|
||||
// 1 | 2
|
||||
// ---¦--- Arc quadrant index
|
||||
// 0 | 3
|
||||
|
|
@ -4098,10 +4088,12 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||
|
||||
// If in outer zone calculate alpha
|
||||
if (hyp > r2) {
|
||||
//alpha = (uint8_t)((rf - sqrtf(hyp)) * 255);
|
||||
alpha = ~sqrt_fraction(hyp); // Outer AA zone
|
||||
}
|
||||
// If within arc fill zone, get line start and lengths for each quadrant
|
||||
else if (hyp >= r3) {
|
||||
do {
|
||||
// Calculate U16.16 slope
|
||||
slope = ((r - cy) << 16)/(r - cx);
|
||||
if (slope <= startSlope[0] && slope >= endSlope[0]) { // slope hi -> lo
|
||||
|
|
@ -4120,10 +4112,14 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||
xst[3] = cx; // Top right line start
|
||||
len[3]++;
|
||||
}
|
||||
cx++;
|
||||
} while ((r - cx) * (r - cx) + dy2 >= r3 && cx < r);
|
||||
cx--;
|
||||
continue; // Next x
|
||||
}
|
||||
else {
|
||||
if (hyp <= r4) break; // Skip inner pixels
|
||||
//alpha = (uint8_t)((sqrtf(hyp) - irf) * 255.0);
|
||||
alpha = sqrt_fraction(hyp); // Inner AA zone
|
||||
}
|
||||
|
||||
|
|
@ -4195,12 +4191,19 @@ void TFT_eSPI::fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color,
|
|||
int32_t hyp2 = (r - cx) * (r - cx) + dy2;
|
||||
if (hyp2 <= r1) break;
|
||||
if (hyp2 >= r2) continue;
|
||||
|
||||
//*
|
||||
uint8_t alpha = ~sqrt_fraction(hyp2);
|
||||
if (alpha > 246) break;
|
||||
xs = cx;
|
||||
if (alpha < 9) continue;
|
||||
|
||||
//*/
|
||||
/*
|
||||
float alphaf = (float)r - sqrtf(hyp2);
|
||||
if (alphaf > HiAlphaTheshold) break;
|
||||
xs = cx;
|
||||
if (alphaf < LoAlphaTheshold) continue;
|
||||
uint8_t alpha = alphaf * 255;
|
||||
//*/
|
||||
if (bg_color == 0x00FFFFFF) {
|
||||
drawPixel(x + cx - r, y + cy - r, color, alpha, bg_color);
|
||||
drawPixel(x - cx + r, y + cy - r, color, alpha, bg_color);
|
||||
|
|
@ -4252,7 +4255,13 @@ void TFT_eSPI::drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||
|
||||
x += r;
|
||||
y += r;
|
||||
|
||||
/*
|
||||
float alphaGain = 1.0;
|
||||
if (w != 0 || h != 0) {
|
||||
if (r - ir < 2) alphaGain = 1.5; // Boost brightness for thin lines
|
||||
if (r - ir < 1) alphaGain = 1.7;
|
||||
}
|
||||
*/
|
||||
uint16_t t = r - ir + 1;
|
||||
int32_t xs = 0;
|
||||
int32_t cx = 0;
|
||||
|
|
@ -4265,6 +4274,8 @@ void TFT_eSPI::drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||
ir--;
|
||||
int32_t r4 = ir * ir; // Inner AA zone radius^2
|
||||
|
||||
//float irf = ir;
|
||||
//float rf = r;
|
||||
uint8_t alpha = 0;
|
||||
|
||||
// Scan top left quadrant x y r ir fg_color bg_color
|
||||
|
|
@ -4285,7 +4296,8 @@ void TFT_eSPI::drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||
|
||||
// If in outer zone calculate alpha
|
||||
if (hyp > r2) {
|
||||
alpha = ~sqrt_fraction(hyp); // Outer AA zone
|
||||
alpha = ~sqrt_fraction(hyp);
|
||||
//alpha = (uint8_t)((rf - sqrtf(hyp)) * 255); // Outer AA zone
|
||||
}
|
||||
// If within arc fill zone, get line lengths for each quadrant
|
||||
else if (hyp >= r3) {
|
||||
|
|
@ -4295,7 +4307,8 @@ void TFT_eSPI::drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||
}
|
||||
else {
|
||||
if (hyp <= r4) break; // Skip inner pixels
|
||||
alpha = sqrt_fraction(hyp); // Inner AA zone
|
||||
//alpha = (uint8_t)((sqrtf(hyp) - irf) * 255); // Inner AA zone
|
||||
alpha = sqrt_fraction(hyp);
|
||||
}
|
||||
|
||||
if (alpha < 16) continue; // Skip low alpha pixels
|
||||
|
|
@ -4366,7 +4379,13 @@ void TFT_eSPI::fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, i
|
|||
if (alpha > 246) break;
|
||||
xs = cx;
|
||||
if (alpha < 9) continue;
|
||||
|
||||
/*
|
||||
float alphaf = (float)r - sqrtf(hyp2);
|
||||
if (alphaf > HiAlphaTheshold) break;
|
||||
xs = cx;
|
||||
if (alphaf < LoAlphaTheshold) continue;
|
||||
uint8_t alpha = alphaf * 255;
|
||||
*/
|
||||
drawPixel(x + cx - r, y + cy - r, color, alpha, bg_color);
|
||||
drawPixel(x - cx + r + w, y + cy - r, color, alpha, bg_color);
|
||||
drawPixel(x - cx + r + w, y - cy + r + h, color, alpha, bg_color);
|
||||
|
|
|
|||
17
TFT_eSPI.h
17
TFT_eSPI.h
|
|
@ -16,7 +16,7 @@
|
|||
#ifndef _TFT_eSPIH_
|
||||
#define _TFT_eSPIH_
|
||||
|
||||
#define TFT_ESPI_VERSION "2.5.21"
|
||||
#define TFT_ESPI_VERSION "2.5.0"
|
||||
|
||||
// Bit level feature flags
|
||||
// Bit 0 set: viewport capability
|
||||
|
|
@ -143,17 +143,6 @@
|
|||
#define SPI_BUSY_CHECK
|
||||
#endif
|
||||
|
||||
// If half duplex SDA mode is defined then MISO pin should be -1
|
||||
#ifdef TFT_SDA_READ
|
||||
#ifdef TFT_MISO
|
||||
#if TFT_MISO != -1
|
||||
#undef TFT_MISO
|
||||
#define TFT_MISO -1
|
||||
#warning TFT_MISO set to -1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/***************************************************************************************
|
||||
** Section 4: Setup fonts
|
||||
***************************************************************************************/
|
||||
|
|
@ -539,12 +528,12 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
|
|||
// By default the arc is drawn with square ends unless the "roundEnds" parameter is included and set true
|
||||
// Angle = 0 is at 6 o'clock position, 90 at 9 o'clock etc. The angles must be in range 0-360 or they will be clipped to these limits
|
||||
// The start angle may be larger than the end angle. Arcs are always drawn clockwise from the start angle.
|
||||
void drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, uint32_t startAngle, uint32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds = false);
|
||||
void drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds = false);
|
||||
|
||||
// As per "drawSmoothArc" except the ends of the arc are NOT anti-aliased, this facilitates dynamic arc length changes with
|
||||
// arc segments and ensures clean segment joints.
|
||||
// The sides of the arc are anti-aliased by default. If smoothArc is false sides will NOT be anti-aliased
|
||||
void drawArc(int32_t x, int32_t y, int32_t r, int32_t ir, uint32_t startAngle, uint32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool smoothArc = true);
|
||||
void drawArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool smoothArc = true);
|
||||
|
||||
// Draw an anti-aliased filled circle at x, y with radius r
|
||||
// Note: The thickness of line is 3 pixels to reduce the visible "braiding" effect of anti-aliasing narrow lines
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
#define INIT_SEQUENCE_3 // Using this initialisation sequence improves the display image
|
||||
|
||||
#define CGRAM_OFFSET
|
||||
#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
|
||||
//#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
|
||||
// #define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
|
||||
#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
|
||||
|
||||
#define TFT_INVERSION_ON
|
||||
// #define TFT_INVERSION_OFF
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
// Setup for the ESP32 S2 with ST7735 80x160 display
|
||||
// See SetupX_Template.h for all options available
|
||||
|
||||
#define USER_SETUP_ID 70
|
||||
|
||||
#define ST7735_DRIVER
|
||||
|
||||
#define TFT_SDA_READ // Display has a bidirectional SDA pin (no MISO)
|
||||
|
||||
#define TFT_WIDTH 80
|
||||
#define TFT_HEIGHT 160
|
||||
|
||||
#define ST7735_GREENTAB160x80
|
||||
//#define ST7735_REDTAB160x80
|
||||
|
||||
//#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
|
||||
#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
|
||||
|
||||
#define TFT_INVERSION_ON
|
||||
// #define TFT_INVERSION_OFF
|
||||
|
||||
// Typical board default pins
|
||||
#define TFT_CS 10 // 10 or 34
|
||||
|
||||
#define TFT_MOSI 11 // 11 or 35
|
||||
#define TFT_SCLK 12 // 12 or 36
|
||||
|
||||
#define TFT_DC 14
|
||||
#define TFT_RST 15
|
||||
|
||||
#define LOAD_GLCD
|
||||
#define LOAD_FONT2
|
||||
#define LOAD_FONT4
|
||||
#define LOAD_FONT6
|
||||
#define LOAD_FONT7
|
||||
#define LOAD_FONT8
|
||||
#define LOAD_GFXFF
|
||||
|
||||
#define SMOOTH_FONT
|
||||
|
||||
// FSPI port must be used for SDA reads. Do not use #define USE_HSPI_PORT
|
||||
|
||||
#define SPI_FREQUENCY 27000000
|
||||
#define SPI_READ_FREQUENCY 16000000
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "2.5.21",
|
||||
"version": "2.5.0",
|
||||
"keywords": "Arduino, tft, display, ttgo, LilyPi, WT32-SC01, ePaper, display, Pico, RP2040 Nano Connect, RP2040, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9481, ILI9486, ILI9488, ST7789, ST7796, RM68140, SSD1351, SSD1963, ILI9225, HX8357D, GC9A01, R61581",
|
||||
"description": "A TFT and ePaper (SPI or parallel interface) graphics library with optimisation for Raspberry Pi Pico, RP2040, ESP8266, ESP32 and STM32 processors",
|
||||
"repository":
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name=TFT_eSPI
|
||||
version=2.5.21
|
||||
version=2.5.0
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=TFT graphics library for Arduino processors with performance optimisation for RP2040, STM32, ESP8266 and ESP32
|
||||
|
|
|
|||
Loading…
Reference in New Issue