From 8e996c0257cf6a01dfa5037492ace2d5ea473ca9 Mon Sep 17 00:00:00 2001 From: Bodmer Date: Sun, 23 Apr 2017 18:50:53 +0100 Subject: [PATCH] Minor bug fixes plus faster block write function added --- TFT_Drivers/ILI9163_Init.h | 2 +- TFT_Drivers/ILI9163_Rotation.h | 8 +- TFT_eSPI.cpp | 164 ++++++++++++++++++++++++++------ TFT_eSPI.h | 149 +++++++++++++++-------------- User_Setups/User_Custom_Fonts.h | 16 ++-- library.json | 2 +- library.properties | 2 +- 7 files changed, 233 insertions(+), 110 deletions(-) diff --git a/TFT_Drivers/ILI9163_Init.h b/TFT_Drivers/ILI9163_Init.h index cc3bb56..0f2702c 100644 --- a/TFT_Drivers/ILI9163_Init.h +++ b/TFT_Drivers/ILI9163_Init.h @@ -36,6 +36,6 @@ #ifdef CGRAM_OFFSET colstart = 0; - rowstart = 32; + rowstart = 0; #endif } \ No newline at end of file diff --git a/TFT_Drivers/ILI9163_Rotation.h b/TFT_Drivers/ILI9163_Rotation.h index 2423635..a78a9c4 100644 --- a/TFT_Drivers/ILI9163_Rotation.h +++ b/TFT_Drivers/ILI9163_Rotation.h @@ -11,7 +11,7 @@ _height = TFT_HEIGHT; #ifdef CGRAM_OFFSET colstart = 0; - rowstart = 32; + rowstart = 0; #endif break; case 1: @@ -19,7 +19,7 @@ _width = TFT_HEIGHT; _height = TFT_WIDTH; #ifdef CGRAM_OFFSET - colstart = 32; + colstart = 0; rowstart = 0; #endif break; @@ -29,7 +29,7 @@ _height = TFT_HEIGHT; #ifdef CGRAM_OFFSET colstart = 0; - rowstart = 0; + rowstart = 32; #endif break; case 3: @@ -37,7 +37,7 @@ _width = TFT_HEIGHT; _height = TFT_WIDTH; #ifdef CGRAM_OFFSET - colstart = 0; + colstart = 32; rowstart = 0; #endif break; diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index dcae74a..f0cf193 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -34,6 +34,9 @@ #define CMD_BITS 8-1 #endif +// Fast SPI block write prototype +void spiWriteBlock(uint16_t color, uint32_t repeat); + // If the SPI library has transaction support, these functions // establish settings and protect from interference from other // libraries. Otherwise, they simply do nothing. @@ -1255,7 +1258,7 @@ spi_begin(); color = (color >> 8) | (color << 8); bg = (bg >> 8) | (bg << 8); uint32_t spimask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO)); - SPI1U1 = spimask | (15 << SPILMOSI) | (15 << SPILMISO); + SPI1U1 = (SPI1U1 & spimask) | (15 << SPILMOSI) | (15 << SPILMISO); for (int8_t j = 0; j < 8; j++) { for (int8_t k = 0; k < 5; k++ ) { if (column[k] & mask) { @@ -1588,7 +1591,7 @@ void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye) spi_end(); } -#else // This is for the ESP32 where we cannot use low level register access (yet) +#else #if defined (RPI_ILI9486_DRIVER) // This is for the RPi display that needs 16 bits inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) @@ -1666,7 +1669,7 @@ inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t spi_end(); } -#else +#else // This is for the ESP32 where we cannot use low level register access (yet) inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) { @@ -2113,14 +2116,12 @@ void TFT_eSPI::pushColor(uint16_t color, uint16_t len) CS_L; - uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color }; - #ifdef RPI_WRITE_STROBE + uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color }; if(len) SPI.writePattern(&colorBin[0], 2, 1); len--; while(len--) {WR_L; WR_H;} #else - while(len>32) { SPI.writePattern(&colorBin[0], 2, 32); len-=32;} - SPI.writePattern(&colorBin[0], 2, len); + spiWriteBlock(color, len); #endif CS_H; @@ -2144,8 +2145,48 @@ void TFT_eSPI::pushColors(uint16_t *data, uint8_t len) CS_L; +#if defined (ESP32) + while (len--) SPI.write16(*(data++)); +#else + + uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO)); + + SPI1U1 = (SPI1U1 & mask) | (63 << SPILMOSI) | (63 << SPILMISO); + while(len>3) + { + uint32_t color0 = (*(data) >> 8) | (uint16_t)(*(data) << 8); + data++; + color0 |= ((*(data) >> 8) | (*(data) << 8)) << 16; + data++; + uint32_t color1 = (*(data) >> 8) | (uint16_t)(*(data) << 8); + data++; + color1 |= ((*(data) >> 8) | (*(data) << 8)) << 16; + + data++; len -= 4; + while(SPI1CMD & SPIBUSY) {} + SPI1W0 = color0; + SPI1W1 = color1; + SPI1CMD |= SPIBUSY; + } + if (len) + { + while(SPI1CMD & SPIBUSY) {} + SPI1U1 = (SPI1U1 & mask) | (15 << SPILMOSI) | (15 << SPILMISO); + while(len--) + { + uint16_t color = (*(data) >> 8) | (*(data) << 8); + data++; + while(SPI1CMD & SPIBUSY) {} + SPI1W0 = color; + SPI1CMD |= SPIBUSY; + } + } + while(SPI1CMD & SPIBUSY) {} + +#endif + CS_H; spi_end(); @@ -2167,8 +2208,12 @@ void TFT_eSPI::pushColors(uint8_t *data, uint32_t len) #if defined (RPI_WRITE_STROBE) while ( len ) {SPI.writePattern(data, 2, 1); data += 2; len -= 2; } #else + #if (SPI_FREQUENCY == 80000000) while ( len >=64 ) {SPI.writePattern(data, 64, 1); data += 64; len -= 64; } if (len) SPI.writePattern(data, len, 1); + #else + SPI.writeBytes(data, len); + #endif #endif CS_H; @@ -2266,7 +2311,7 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO)); mask = (SPI1U1 & mask) | (15 << SPILMOSI) | (15 << SPILMISO); - + SPI1U = SPIUMOSI | SPIUSSE; int16_t swapped_color = (color >> 8) | (color << 8); if (steep) // y increments every iteration (y0 is x-axis, and x0 is y-axis) @@ -2286,9 +2331,9 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t setAddrWindow(y0, x0, y0, _height); SPI1U1 = mask; + SPI1W0 = swapped_color; for (; x0 <= x1; x0++) { while(SPI1CMD & SPIBUSY) {} - SPI1W0 = swapped_color; SPI1CMD |= SPIBUSY; err -= dy; @@ -2299,6 +2344,7 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t while(SPI1CMD & SPIBUSY) {} setAddrWindow(y0, x0+1, y0, _height); SPI1U1 = mask; + SPI1W0 = swapped_color; } } } @@ -2319,10 +2365,9 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t setAddrWindow(x0, y0, _width, y0); SPI1U1 = mask; - + SPI1W0 = swapped_color; for (; x0 <= x1; x0++) { while(SPI1CMD & SPIBUSY) {} - SPI1W0 = swapped_color; SPI1CMD |= SPIBUSY; err -= dy; @@ -2333,11 +2378,13 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t while(SPI1CMD & SPIBUSY) {} setAddrWindow(x0+1, y0, _width, y0); SPI1U1 = mask; + SPI1W0 = swapped_color; } } } while(SPI1CMD & SPIBUSY) {} + SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE; CS_H; spi_end(); } @@ -2359,9 +2406,8 @@ void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color) setAddrWindow(x, y, x, y + h - 1); - uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color}; - SPI.writePattern(&colorBin[0], 2, h); - + spiWriteBlock(color, h); + CS_H; spi_end(); @@ -2410,9 +2456,8 @@ void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color) setAddrWindow(x, y, x + w - 1, y); - uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color}; - SPI.writePattern(&colorBin[0], 2, w); - + spiWriteBlock(color, w); + CS_H; spi_end(); @@ -2460,10 +2505,8 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col spi_begin(); setAddrWindow(x, y, x + w - 1, y + h - 1); - uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color}; - uint32_t n = (uint32_t)w * (uint32_t)h; - SPI.writePattern(&colorBin[0], 2, n); - + spiWriteBlock(color, w * h); + CS_H; spi_end(); @@ -2888,8 +2931,7 @@ int16_t TFT_eSPI::drawChar(unsigned int uniCode, int x, int y, int font) SPI.writePattern(&textcolorBin[0], 2, 1); line--; while(line--) {WR_L; WR_H;} #else - while(line>32) { SPI.writePattern(&textcolorBin[0], 2, 32); line-=32;} - SPI.writePattern(&textcolorBin[0], 2, line); + spiWriteBlock(textcolor,line); #endif } else { @@ -2898,8 +2940,7 @@ int16_t TFT_eSPI::drawChar(unsigned int uniCode, int x, int y, int font) SPI.writePattern(&textbgcolorBin[0], 2, 1); line--; while(line--) {WR_L; WR_H;} #else - while(line>32) { SPI.writePattern(&textbgcolorBin[0], 2, 32); line-=32;} - SPI.writePattern(&textbgcolorBin[0], 2, line); + spiWriteBlock(textbgcolor,line); #endif } } @@ -3016,7 +3057,7 @@ int16_t TFT_eSPI::drawString(const char *string, int poX, int poY, int font) case C_BASELINE: poX -= cwidth/2; poY -= baseline; - //padding += 1; + padding += 1; break; case R_BASELINE: poX -= cwidth; @@ -3031,8 +3072,9 @@ int16_t TFT_eSPI::drawString(const char *string, int poX, int poY, int font) if (poY+cheight-baseline>_height) poY = _height - cheight; } -#ifdef LOAD_GFXFF + int8_t xo = 0; +#ifdef LOAD_GFXFF if ((font == 1) && (gfxFont) && (textcolor!=textbgcolor)) { cheight = (glyph_ab + glyph_bb) * textsize; @@ -3328,6 +3370,74 @@ void TFT_eSPI::setTextFont(uint8_t f) #endif +/*************************************************************************************** +** Function name: spiBlockWrite +** Description: Write a block of pixels of the same colour +***************************************************************************************/ +#if (SPI_FREQUENCY != 80000000) +void spiWriteBlock(uint16_t color, uint32_t repeat) +{ + uint16_t color16 = (color >> 8) | (color << 8); + uint32_t color32 = color16 | color16 << 16; + uint32_t mask = ~(SPIMMOSI << SPILMOSI); + mask = SPI1U1 & mask; + SPI1U = SPIUMOSI | SPIUSSE; + + SPI1W0 = color32; + SPI1W1 = color32; + SPI1W2 = color32; + SPI1W3 = color32; + if (repeat > 8) + { + SPI1W4 = color32; + SPI1W5 = color32; + SPI1W6 = color32; + SPI1W7 = color32; + } + if (repeat > 16) + { + SPI1W8 = color32; + SPI1W9 = color32; + SPI1W10 = color32; + SPI1W11 = color32; + } + if (repeat > 24) + { + SPI1W12 = color32; + SPI1W13 = color32; + SPI1W14 = color32; + SPI1W15 = color32; + } + if (repeat > 31) + { + SPI1U1 = mask | (511 << SPILMOSI); + while(repeat>31) + { + while(SPI1CMD & SPIBUSY) {} + SPI1CMD |= SPIBUSY; + repeat -= 32; + } + while(SPI1CMD & SPIBUSY) {} + } + + if (repeat) + { + repeat = (repeat << 4) - 1; + SPI1U1 = mask | (repeat << SPILMOSI); + SPI1CMD |= SPIBUSY; + while(SPI1CMD & SPIBUSY) {} + } + + SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE; +} +#else // Runing at 80MHz SPI so slow things down +void spiWriteBlock(uint16_t color, uint32_t repeat) +{ + uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color}; + SPI.writePattern(&colorBin[0], 2, repeat); +} +#endif + /*************************************************** The majority of code in this file is "FunWare", the only condition of use of those portions is that users have fun! Most of the effort has been spent on diff --git a/TFT_eSPI.h b/TFT_eSPI.h index 8b8bfaa..1131363 100644 --- a/TFT_eSPI.h +++ b/TFT_eSPI.h @@ -19,6 +19,8 @@ #ifndef _TFT_eSPIH_ #define _TFT_eSPIH_ +//#define ESP32 //Just used to test ESP32 options + // Include header file that defines the fonts loaded, the TFT drivers // available and the pins to be used #include @@ -93,83 +95,90 @@ #endif #ifdef TFT_WR - #define WR_L GPOC=wrpinmask - #define WR_H GPOS=wrpinmask + #if defined (ESP32) + #define WR_L digitalWrite(TFT_WR, LOW) + #define WR_H digitalWrite(TFT_WR, HIGH) + #else + #define WR_L GPOC=wrpinmask + #define WR_H GPOS=wrpinmask + #endif #endif -// We can include all the free fonts and they will only be built into -// the sketch if they are used +#ifdef LOAD_GFXFF + // We can include all the free fonts and they will only be built into + // the sketch if they are used -#include + #include -// Call up any user custom fonts -#include + // Call up any user custom fonts + #include -// Original Adafruit_GFX "Free Fonts" -#include // TT1 + // Original Adafruit_GFX "Free Fonts" + #include // TT1 -#include // FF1 or FM9 -#include // FF2 or FM12 -#include // FF3 or FM18 -#include // FF4 or FM24 - -#include // FF5 or FMO9 -#include // FF6 or FMO12 -#include // FF7 or FMO18 -#include // FF8 or FMO24 - -#include // FF9 or FMB9 -#include // FF10 or FMB12 -#include // FF11 or FMB18 -#include // FF12 or FMB24 - -#include // FF13 or FMBO9 -#include // FF14 or FMBO12 -#include // FF15 or FMBO18 -#include // FF16 or FMBO24 - -// Sans serif fonts -#include // FF17 or FSS9 -#include // FF18 or FSS12 -#include // FF19 or FSS18 -#include // FF20 or FSS24 - -#include // FF21 or FSSO9 -#include // FF22 or FSSO12 -#include // FF23 or FSSO18 -#include // FF24 or FSSO24 - -#include // FF25 or FSSB9 -#include // FF26 or FSSB12 -#include // FF27 or FSSB18 -#include // FF28 or FSSB24 - -#include // FF29 or FSSBO9 -#include // FF30 or FSSBO12 -#include // FF31 or FSSBO18 -#include // FF32 or FSSBO24 - -// Serif fonts -#include // FF33 or FS9 -#include // FF34 or FS12 -#include // FF35 or FS18 -#include // FF36 or FS24 - -#include // FF37 or FSI9 -#include // FF38 or FSI12 -#include // FF39 or FSI18 -#include // FF40 or FSI24 - -#include // FF41 or FSB9 -#include // FF42 or FSB12 -#include // FF43 or FSB18 -#include // FF44 or FSB24 - -#include // FF45 or FSBI9 -#include // FF46 or FSBI12 -#include // FF47 or FSBI18 -#include // FF48 or FSBI24 + #include // FF1 or FM9 + #include // FF2 or FM12 + #include // FF3 or FM18 + #include // FF4 or FM24 + #include // FF5 or FMO9 + #include // FF6 or FMO12 + #include // FF7 or FMO18 + #include // FF8 or FMO24 + + #include // FF9 or FMB9 + #include // FF10 or FMB12 + #include // FF11 or FMB18 + #include // FF12 or FMB24 + + #include // FF13 or FMBO9 + #include // FF14 or FMBO12 + #include // FF15 or FMBO18 + #include // FF16 or FMBO24 + + // Sans serif fonts + #include // FF17 or FSS9 + #include // FF18 or FSS12 + #include // FF19 or FSS18 + #include // FF20 or FSS24 + + #include // FF21 or FSSO9 + #include // FF22 or FSSO12 + #include // FF23 or FSSO18 + #include // FF24 or FSSO24 + + #include // FF25 or FSSB9 + #include // FF26 or FSSB12 + #include // FF27 or FSSB18 + #include // FF28 or FSSB24 + + #include // FF29 or FSSBO9 + #include // FF30 or FSSBO12 + #include // FF31 or FSSBO18 + #include // FF32 or FSSBO24 + + // Serif fonts + #include // FF33 or FS9 + #include // FF34 or FS12 + #include // FF35 or FS18 + #include // FF36 or FS24 + + #include // FF37 or FSI9 + #include // FF38 or FSI12 + #include // FF39 or FSI18 + #include // FF40 or FSI24 + + #include // FF41 or FSB9 + #include // FF42 or FSB12 + #include // FF43 or FSB18 + #include // FF44 or FSB24 + + #include // FF45 or FSBI9 + #include // FF46 or FSBI12 + #include // FF47 or FSBI18 + #include // FF48 or FSBI24 + +#endif // #ifdef LOAD_GFXFF //These enumerate the text plotting alignment (reference datum point) #define TL_DATUM 0 // Top left (default) diff --git a/User_Setups/User_Custom_Fonts.h b/User_Setups/User_Custom_Fonts.h index 5b02357..ef9e0ae 100644 --- a/User_Setups/User_Custom_Fonts.h +++ b/User_Setups/User_Custom_Fonts.h @@ -17,12 +17,16 @@ // The comment added is a shorthand reference but this is not essential -// New custom font file #includes -#include // CF_OL24 -#include // CF_OL32 -#include // CF_RT24 -#include // CF_S24 -#include // CF_Y32 +#ifdef LOAD_GFXFF + + // New custom font file #includes + #include // CF_OL24 + #include // CF_OL32 + #include // CF_RT24 + #include // CF_S24 + #include // CF_Y32 + +#endif // Shorthand references - any coding scheme can be used, here CF_ = Custom Font // The #defines below MUST be added to sketches to use shorthand references, so diff --git a/library.json b/library.json index 7ead2f6..8216dd9 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TFT_eSPI", - "version": "0.16.5", + "version": "0.16.6", "keywords": "TFT, ESP8266, NodeMCU, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486", "description": "A TFT SPI graphics library for ESP8266", "repository": diff --git a/library.properties b/library.properties index 3a52689..1f10121 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=0.16.5 +version=0.16.6 author=Bodmer maintainer=Bodmer sentence=A fast TFT library for ESP8266 processors and the Arduino IDE