diff --git a/Processors/TFT_eSPI_ESP32.c b/Processors/TFT_eSPI_ESP32.c index 5534f05..b54500a 100644 --- a/Processors/TFT_eSPI_ESP32.c +++ b/Processors/TFT_eSPI_ESP32.c @@ -64,29 +64,35 @@ //////////////////////////////////////////////////////////////////////////////////////// /*************************************************************************************** -** Function name: beginSDA -** Description: Detach SPI from pin to permit software SPI +** Function name: beginSDA - VSPI port only, FPSI port only for S2 +** Description: Detach MOSI and attach MISO to SDA for reads ***************************************************************************************/ void TFT_eSPI::begin_SDA_Read(void) { - pinMatrixOutDetach(TFT_MOSI, false, false); - pinMode(TFT_MOSI, INPUT); - pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false); + gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT); + #ifdef CONFIG_IDF_TARGET_ESP32 + pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false); + #else // S2 + pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false); + #endif SET_BUS_READ_MODE; } /*************************************************************************************** -** Function name: endSDA -** Description: Attach SPI pins after software SPI +** Function name: endSDA - VSPI port only, FPSI port only for S2 +** Description: Attach MOSI to SDA and detach MISO for writes ***************************************************************************************/ void TFT_eSPI::end_SDA_Read(void) { - pinMode(TFT_MOSI, OUTPUT); - pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false); - pinMode(TFT_MISO, INPUT); - pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false); + gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT); + #ifdef CONFIG_IDF_TARGET_ESP32 + pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false); + #else // S2 + pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false); + #endif SET_BUS_WRITE_MODE; } + //////////////////////////////////////////////////////////////////////////////////////// #endif // #if defined (TFT_SDA_READ) //////////////////////////////////////////////////////////////////////////////////////// diff --git a/Processors/TFT_eSPI_ESP32_C3.c b/Processors/TFT_eSPI_ESP32_C3.c index 4e1b15b..e33a5ac 100644 --- a/Processors/TFT_eSPI_ESP32_C3.c +++ b/Processors/TFT_eSPI_ESP32_C3.c @@ -66,27 +66,24 @@ //////////////////////////////////////////////////////////////////////////////////////// /*************************************************************************************** -** Function name: beginSDA -** Description: Detach SPI from pin to permit software SPI +** Function name: beginSDA - FPSI port only +** Description: Detach MOSI and attach MISO to SDA for reads ***************************************************************************************/ void TFT_eSPI::begin_SDA_Read(void) { - pinMatrixOutDetach(TFT_MOSI, false, false); - pinMode(TFT_MOSI, INPUT); - pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false); + gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT); + pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false); SET_BUS_READ_MODE; } /*************************************************************************************** -** Function name: endSDA -** Description: Attach SPI pins after software SPI +** Function name: endSDA - FPSI port only +** Description: Attach MOSI to SDA and detach MISO for writes ***************************************************************************************/ void TFT_eSPI::end_SDA_Read(void) { - pinMode(TFT_MOSI, OUTPUT); - pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false); - pinMode(TFT_MISO, INPUT); - pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false); + gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT); + pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false); SET_BUS_WRITE_MODE; } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/Processors/TFT_eSPI_ESP32_S3.c b/Processors/TFT_eSPI_ESP32_S3.c index 9d23a7c..173ce3b 100644 --- a/Processors/TFT_eSPI_ESP32_S3.c +++ b/Processors/TFT_eSPI_ESP32_S3.c @@ -57,27 +57,24 @@ //////////////////////////////////////////////////////////////////////////////////////// /*************************************************************************************** -** Function name: beginSDA -** Description: Detach SPI from pin to permit software SPI +** Function name: beginSDA - FPSI port only +** Description: Detach MOSI and attach MISO to SDA for reads ***************************************************************************************/ void TFT_eSPI::begin_SDA_Read(void) { - pinMatrixOutDetach(TFT_MOSI, false, false); - pinMode(TFT_MOSI, INPUT); - pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false); + gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT); + pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false); SET_BUS_READ_MODE; } /*************************************************************************************** -** Function name: endSDA -** Description: Attach SPI pins after software SPI +** Function name: endSDA - FPSI port only +** Description: Attach MOSI to SDA and detach MISO for writes ***************************************************************************************/ void TFT_eSPI::end_SDA_Read(void) { - pinMode(TFT_MOSI, OUTPUT); - pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false); - pinMode(TFT_MISO, INPUT); - pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false); + gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT); + pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false); SET_BUS_WRITE_MODE; } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index ca45ee7..ec267f1 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -1181,6 +1181,13 @@ 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 @@ -1341,6 +1348,13 @@ 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 @@ -3885,7 +3899,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, int32_t startAngle, int32_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, uint32_t startAngle, uint32_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 @@ -3980,39 +3994,35 @@ 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, - int32_t startAngle, int32_t endAngle, + uint32_t startAngle, uint32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool smooth) { - 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 (endAngle > 360) endAngle = 360; + if (startAngle > 360) startAngle = 360; 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 - uint8_t alpha = 0; // alpha value for blending pixels + int32_t xs = 0; // x start position for quadrant scan + uint8_t alpha = 0; // alpha value for blending pixels uint32_t r2 = r * r; // Outer arc radius^2 - if (smooth) r++; // Outer AA zone radius + if (smooth) r++; // Outer AA zone radius uint32_t r1 = r * r; // Outer AA radius^2 - int16_t w = r - ir; // Width of arc (r - ir + 1) + int16_t w = r - ir; // Width of arc (r - ir + 1) uint32_t r3 = ir * ir; // Inner arc radius^2 - if (smooth) ir--; // Inner AA zone radius + 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 @@ -4088,38 +4098,32 @@ 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 - xst[0] = cx; // Bottom left line end - len[0]++; - } - if (slope >= startSlope[1] && slope <= endSlope[1]) { // slope lo -> hi - xst[1] = cx; // Top left line end - len[1]++; - } - if (slope <= startSlope[2] && slope >= endSlope[2]) { // slope hi -> lo - xst[2] = cx; // Bottom right line start - len[2]++; - } - if (slope <= endSlope[3] && slope >= startSlope[3]) { // slope lo -> hi - xst[3] = cx; // Top right line start - len[3]++; - } - cx++; - } while ((r - cx) * (r - cx) + dy2 >= r3 && cx < r); - cx--; + // Calculate U16.16 slope + slope = ((r - cy) << 16)/(r - cx); + if (slope <= startSlope[0] && slope >= endSlope[0]) { // slope hi -> lo + xst[0] = cx; // Bottom left line end + len[0]++; + } + if (slope >= startSlope[1] && slope <= endSlope[1]) { // slope lo -> hi + xst[1] = cx; // Top left line end + len[1]++; + } + if (slope <= startSlope[2] && slope >= endSlope[2]) { // slope hi -> lo + xst[2] = cx; // Bottom right line start + len[2]++; + } + if (slope <= endSlope[3] && slope >= startSlope[3]) { // slope lo -> hi + xst[3] = cx; // Top right line start + len[3]++; + } 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 } @@ -4191,19 +4195,12 @@ 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); @@ -4243,7 +4240,7 @@ void TFT_eSPI::drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir, { if (_vpOoB) return; if (r < ir) transpose(r, ir); // Required that r > ir - if (r <= 0 || ir < 0) return; // Invalid + if (r <= 0 || ir < 0) return; // Invalid w -= 2*r; h -= 2*r; @@ -4255,13 +4252,7 @@ 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; @@ -4274,8 +4265,6 @@ 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 @@ -4296,8 +4285,7 @@ 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); - //alpha = (uint8_t)((rf - sqrtf(hyp)) * 255); // Outer AA zone + alpha = ~sqrt_fraction(hyp); // Outer AA zone } // If within arc fill zone, get line lengths for each quadrant else if (hyp >= r3) { @@ -4307,8 +4295,7 @@ 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 = (uint8_t)((sqrtf(hyp) - irf) * 255); // Inner AA zone - alpha = sqrt_fraction(hyp); + alpha = sqrt_fraction(hyp); // Inner AA zone } if (alpha < 16) continue; // Skip low alpha pixels @@ -4379,13 +4366,7 @@ 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); diff --git a/TFT_eSPI.h b/TFT_eSPI.h index fac79a8..2fbce4e 100644 --- a/TFT_eSPI.h +++ b/TFT_eSPI.h @@ -16,7 +16,7 @@ #ifndef _TFT_eSPIH_ #define _TFT_eSPIH_ -#define TFT_ESPI_VERSION "2.5.2" +#define TFT_ESPI_VERSION "2.5.21" // Bit level feature flags // Bit 0 set: viewport capability @@ -143,6 +143,17 @@ #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 ***************************************************************************************/ @@ -528,12 +539,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, int32_t startAngle, int32_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, uint32_t startAngle, uint32_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, int32_t startAngle, int32_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, uint32_t startAngle, uint32_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 diff --git a/User_Setups/Setup70f_ESP32_S2_ST7735.h b/User_Setups/Setup70f_ESP32_S2_ST7735.h new file mode 100644 index 0000000..f0cc51d --- /dev/null +++ b/User_Setups/Setup70f_ESP32_S2_ST7735.h @@ -0,0 +1,44 @@ +// 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 diff --git a/library.json b/library.json index bac8f01..a262057 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TFT_eSPI", - "version": "2.5.2", + "version": "2.5.21", "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": diff --git a/library.properties b/library.properties index 2006074..844a69d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=2.5.2 +version=2.5.21 author=Bodmer maintainer=Bodmer sentence=TFT graphics library for Arduino processors with performance optimisation for RP2040, STM32, ESP8266 and ESP32