From 196e12a445689a8cf08b025af013acb9f6728046 Mon Sep 17 00:00:00 2001 From: lewis he Date: Fri, 7 Aug 2020 17:23:55 +0800 Subject: [PATCH] Add tblock ILI9488 support --- src/LilyGoWatch.h | 2 +- src/TFT_eSPI/TFT_Drivers/ILI9488_Defines.h | 42 ++ src/TFT_eSPI/TFT_Drivers/ILI9488_Init.h | 99 +++++ src/TFT_eSPI/TFT_Drivers/ILI9488_Rotation.h | 27 ++ src/TFT_eSPI/TFT_Drivers/ST7789_Rotation.h | 87 ++--- src/TFT_eSPI/TFT_eSPI.cpp | 402 +++++++++++++++++++- src/TFT_eSPI/TFT_eSPI.h | 32 +- src/TTGO.h | 13 +- 8 files changed, 637 insertions(+), 67 deletions(-) create mode 100644 src/TFT_eSPI/TFT_Drivers/ILI9488_Defines.h create mode 100644 src/TFT_eSPI/TFT_Drivers/ILI9488_Init.h create mode 100644 src/TFT_eSPI/TFT_Drivers/ILI9488_Rotation.h diff --git a/src/LilyGoWatch.h b/src/LilyGoWatch.h index 1993a04..36b312c 100644 --- a/src/LilyGoWatch.h +++ b/src/LilyGoWatch.h @@ -163,7 +163,7 @@ // #define LILYGO_EINK_TOUCHSCREEN // #define LILYGO_BLOCK_TOUCHSCREEN -#if defined(LILYGO_EINK_TOUCHSCREEN) || defined(LILYGO_BLOCK_TOUCHSCREEN) +#if defined(LILYGO_EINK_TOUCHSCREEN) || defined(LILYGO_BLOCK_TOUCHSCREEN) || defined(LILYGO_BLOCK_TOUCHSCREEN_ILI9488) #ifndef LILYGO_EINK_TOUCHSCREEN #define LILYGO_EINK_TOUCHSCREEN #endif diff --git a/src/TFT_eSPI/TFT_Drivers/ILI9488_Defines.h b/src/TFT_eSPI/TFT_Drivers/ILI9488_Defines.h new file mode 100644 index 0000000..bd5fb88 --- /dev/null +++ b/src/TFT_eSPI/TFT_Drivers/ILI9488_Defines.h @@ -0,0 +1,42 @@ +// Change the width and height if required (defined in portrait mode) +// or use the constructor to over-ride defaults +#define TFT_WIDTH 320 +#define TFT_HEIGHT 480 + + +// Delay between some initialisation commands +#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked + + +// Generic commands used by TFT_eSPI.cpp +#define TFT_NOP 0x00 +#define TFT_SWRST 0x01 + +#define TFT_SLPIN 0x10 +#define TFT_SLPOUT 0x11 + +#define TFT_INVOFF 0x20 +#define TFT_INVON 0x21 + +#define TFT_DISPOFF 0x28 +#define TFT_DISPON 0x29 + +#define TFT_CASET 0x2A +#define TFT_PASET 0x2B +#define TFT_RAMWR 0x2C + +#define TFT_RAMRD 0x2E + +#define TFT_MADCTL 0x36 + +#define TFT_MAD_MY 0x80 +#define TFT_MAD_MX 0x40 +#define TFT_MAD_MV 0x20 +#define TFT_MAD_ML 0x10 +#define TFT_MAD_RGB 0x00 +#define TFT_MAD_BGR 0x08 +#define TFT_MAD_MH 0x04 +#define TFT_MAD_SS 0x02 +#define TFT_MAD_GS 0x01 + +#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read diff --git a/src/TFT_eSPI/TFT_Drivers/ILI9488_Init.h b/src/TFT_eSPI/TFT_Drivers/ILI9488_Init.h new file mode 100644 index 0000000..c3d0b57 --- /dev/null +++ b/src/TFT_eSPI/TFT_Drivers/ILI9488_Init.h @@ -0,0 +1,99 @@ + +// This is the command sequence that initialises the ILI9488 driver +// +// This setup information uses simple 8 bit SPI writecommand() and writedata() functions +// +// See ST7735_Setup.h file for an alternative format + + +// Configure ILI9488 display + + writecommand(0xE0); // Positive Gamma Control + writedata(0x00); + writedata(0x03); + writedata(0x09); + writedata(0x08); + writedata(0x16); + writedata(0x0A); + writedata(0x3F); + writedata(0x78); + writedata(0x4C); + writedata(0x09); + writedata(0x0A); + writedata(0x08); + writedata(0x16); + writedata(0x1A); + writedata(0x0F); + + writecommand(0XE1); // Negative Gamma Control + writedata(0x00); + writedata(0x16); + writedata(0x19); + writedata(0x03); + writedata(0x0F); + writedata(0x05); + writedata(0x32); + writedata(0x45); + writedata(0x46); + writedata(0x04); + writedata(0x0E); + writedata(0x0D); + writedata(0x35); + writedata(0x37); + writedata(0x0F); + + writecommand(0XC0); // Power Control 1 + writedata(0x17); + writedata(0x15); + + writecommand(0xC1); // Power Control 2 + writedata(0x41); + + writecommand(0xC5); // VCOM Control + writedata(0x00); + writedata(0x12); + writedata(0x80); + + writecommand(TFT_MADCTL); // Memory Access Control + writedata(0x48); // MX, BGR + + writecommand(0x3A); // Pixel Interface Format +#if defined (TFT_PARALLEL_8_BIT) + writedata(0x55); // 16 bit colour for parallel +#else + writedata(0x66); // 18 bit colour for SPI +#endif + + writecommand(0xB0); // Interface Mode Control + writedata(0x00); + + writecommand(0xB1); // Frame Rate Control + writedata(0xA0); + + writecommand(0xB4); // Display Inversion Control + writedata(0x02); + + writecommand(0xB6); // Display Function Control + writedata(0x02); + writedata(0x02); + writedata(0x3B); + + writecommand(0xB7); // Entry Mode Set + writedata(0xC6); + + writecommand(0xF7); // Adjust Control 3 + writedata(0xA9); + writedata(0x51); + writedata(0x2C); + writedata(0x82); + + writecommand(TFT_SLPOUT); //Exit Sleep +delay(120); + + writecommand(TFT_DISPON); //Display on +delay(25); + +// End of ILI9488 display configuration + + + diff --git a/src/TFT_eSPI/TFT_Drivers/ILI9488_Rotation.h b/src/TFT_eSPI/TFT_Drivers/ILI9488_Rotation.h new file mode 100644 index 0000000..cdc84d2 --- /dev/null +++ b/src/TFT_eSPI/TFT_Drivers/ILI9488_Rotation.h @@ -0,0 +1,27 @@ +// This is the command sequence that rotates the ILI9488 driver coordinate frame + +writecommand(TFT_MADCTL); +rotation = m % 4; +switch (rotation) +{ +case 0: // Portrait + writedata(TFT_MAD_MX | TFT_MAD_BGR); + _width = _init_width; + _height = _init_height; + break; +case 1: // Landscape (Portrait + 90) + writedata(TFT_MAD_MV | TFT_MAD_BGR); + _width = _init_height; + _height = _init_width; + break; +case 2: // Inverter portrait + writedata(TFT_MAD_MY | TFT_MAD_BGR); + _width = _init_width; + _height = _init_height; + break; +case 3: // Inverted landscape + writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR); + _width = _init_height; + _height = _init_width; + break; +} diff --git a/src/TFT_eSPI/TFT_Drivers/ST7789_Rotation.h b/src/TFT_eSPI/TFT_Drivers/ST7789_Rotation.h index 707c775..9caccac 100644 --- a/src/TFT_eSPI/TFT_Drivers/ST7789_Rotation.h +++ b/src/TFT_eSPI/TFT_Drivers/ST7789_Rotation.h @@ -1,80 +1,69 @@ - // This is the command sequence that rotates the ST7789 driver coordinate frame +// This is the command sequence that rotates the ST7789 driver coordinate frame - writecommand(TFT_MADCTL); - rotation = m % 4; - switch (rotation) { - case 0: // Portrait +writecommand(TFT_MADCTL); +rotation = m % 4; +switch (rotation) +{ +case 0: // Portrait #ifdef CGRAM_OFFSET - if (_init_width == 135) - { + if (_init_width == 135) { colstart = 52; rowstart = 40; - } - else - { + } else { colstart = 0; rowstart = 0; - } + } #endif - writedata(TFT_MAD_COLOR_ORDER); + writedata(TFT_MAD_COLOR_ORDER); - _width = _init_width; - _height = _init_height; - break; + _width = _init_width; + _height = _init_height; + break; - case 1: // Landscape (Portrait + 90) +case 1: // Landscape (Portrait + 90) #ifdef CGRAM_OFFSET - if (_init_width == 135) - { + if (_init_width == 135) { colstart = 40; rowstart = 53; - } - else - { + } else { colstart = 0; rowstart = 0; - } + } #endif - writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER); + writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER); - _width = _init_height; - _height = _init_width; - break; + _width = _init_height; + _height = _init_width; + break; - case 2: // Inverter portrait +case 2: // Inverter portrait #ifdef CGRAM_OFFSET - if (_init_width == 135) - { + if (_init_width == 135) { colstart = 53; rowstart = 40; - } - else - { + } else { colstart = 0; rowstart = 80; - } + } #endif - writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); + writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); - _width = _init_width; - _height = _init_height; - break; - case 3: // Inverted landscape + _width = _init_width; + _height = _init_height; + break; +case 3: // Inverted landscape #ifdef CGRAM_OFFSET - if (_init_width == 135) - { + if (_init_width == 135) { colstart = 40; rowstart = 52; - } - else - { + } else { colstart = 80; rowstart = 0; - } + } #endif - writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); + writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); - _width = _init_height; - _height = _init_width; - break; - } + _width = _init_height; + _height = _init_width; + break; +} diff --git a/src/TFT_eSPI/TFT_eSPI.cpp b/src/TFT_eSPI/TFT_eSPI.cpp index 5f7a499..d211cde 100644 --- a/src/TFT_eSPI/TFT_eSPI.cpp +++ b/src/TFT_eSPI/TFT_eSPI.cpp @@ -158,7 +158,7 @@ void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode) #endif // #ifdef TFT_PARALLEL_8_BIT //////////////////////////////////////////////////////////////////////////////////////// - +#ifdef DISABLE_CONDITIONAL_MACROS //////////////////////////////////////////////////////////////////////////////////////// #if defined (RPI_WRITE_STROBE) && !defined (TFT_PARALLEL_8_BIT) // Code for RPi TFT //////////////////////////////////////////////////////////////////////////////////////// @@ -537,7 +537,378 @@ void TFT_eSPI::pushPixels(const void *data_in, uint32_t len) //////////////////////////////////////////////////////////////////////////////////////// #endif // End of display interface specific functions //////////////////////////////////////////////////////////////////////////////////////// +#else /*DISABLE_CONDITIONAL_MACROS*/ +void TFT_eSPI::ILI9488_pushBlock(uint16_t color, uint32_t len) +{ +// Split out the colours + uint32_t r = (color & 0xF800) >> 8; + uint32_t g = (color & 0x07E0) << 5; + uint32_t b = (color & 0x001F) << 19; + // Concatenate 4 pixels into three 32 bit blocks + uint32_t r0 = r << 24 | b | g | r; + uint32_t r1 = r0 >> 8 | g << 16; + uint32_t r2 = r1 >> 8 | b << 8; + if (len > 19) { + SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_PORT), SPI_USR_MOSI_DBITLEN, 479, SPI_USR_MOSI_DBITLEN_S); + + while (len > 19) { + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2); + WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2); + WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2); + WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2); + WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2); + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + len -= 20; + } + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + } + + if (len) { + SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_PORT), SPI_USR_MOSI_DBITLEN, (len * 24) - 1, SPI_USR_MOSI_DBITLEN_S); + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2); + WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2); + if (len > 8 ) { + WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2); + WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2); + WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0); + WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1); + WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2); + } + + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + } +} + +void TFT_eSPI::ILI9488_pushPixels(const void *data_in, uint32_t len) +{ + uint16_t *data = (uint16_t *)data_in; + // ILI9488 write macro is not endianess dependant, hence !_swapBytes + if (!_swapBytes) { + while ( len-- ) { + tft_Write_16S(*data); + data++; + } + } else { + while ( len-- ) { + tft_Write_16(*data); + data++; + } + } +} + +void TFT_eSPI::ILI9488_pushSwapBytePixels(const void *data_in, uint32_t len) +{ + + uint16_t *data = (uint16_t *)data_in; + // ILI9488 write macro is not endianess dependant, so swap byte macro not used here + while ( len-- ) { + tft_Write_16(*data); + data++; + } +} + +void TFT_eSPI::General_pushBlock(uint16_t color, uint32_t len) +{ + uint32_t color32 = (color << 8 | color >> 8) << 16 | (color << 8 | color >> 8); + if (len > 31) { + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511); + while (len > 31) { + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), color32); + WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), color32); + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + len -= 32; + } + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + } + + if (len) { + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1); + for (uint32_t i = 0; i <= (len << 1); i += 4) WRITE_PERI_REG(SPI_W0_REG(SPI_PORT) + i, color32); + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + } +} + +void TFT_eSPI::General_pushSwapBytePixels(const void *data_in, uint32_t len) +{ + + uint8_t *data = (uint8_t *)data_in; + uint32_t color[16]; + + if (len > 31) { + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511); + while (len > 31) { + uint32_t i = 0; + while (i < 16) { + color[i++] = DAT8TO32(data); + data += 4; + } + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]); + WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]); + WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]); + WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]); + WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]); + WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]); + WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]); + WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]); + WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), color[8]); + WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), color[9]); + WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), color[10]); + WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), color[11]); + WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), color[12]); + WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), color[13]); + WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), color[14]); + WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), color[15]); + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + len -= 32; + } + } + + if (len > 15) { + uint32_t i = 0; + while (i < 8) { + color[i++] = DAT8TO32(data); + data += 4; + } + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 255); + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]); + WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]); + WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]); + WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]); + WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]); + WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]); + WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]); + WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]); + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + len -= 16; + } + + if (len) { + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1); + for (uint32_t i = 0; i <= (len << 1); i += 4) { + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT) + i, DAT8TO32(data)); data += 4; + } + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + } + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + +} + +void TFT_eSPI::General_pushPixels(const void *data_in, uint32_t len) +{ + + if (_swapBytes) { + pushSwapBytePixels(data_in, len); + return; + } + + uint32_t *data = (uint32_t *)data_in; + + if (len > 31) { + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511); + while (len > 31) { + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), *data++); + WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), *data++); + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + len -= 32; + } + } + + if (len) { + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1); + for (uint32_t i = 0; i <= (len << 1); i += 4) WRITE_PERI_REG((SPI_W0_REG(SPI_PORT) + i), *data++); + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); + } + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); +} + +//////////////////////////////////////////////////////////////////////////////////////// + +/*************************************************************************************** +** Function name: pushBlock - for ESP32 +** Description: Write a block of pixels of the same colour +***************************************************************************************/ +void TFT_eSPI::pushBlock(uint16_t color, uint32_t len) +{ + switch (drv.tft_driver) { + case 0x9488: + ILI9488_pushBlock(color, len); + break; + default: + General_pushBlock(color, len); + break; + } +} + +/*************************************************************************************** +** Function name: pushSwapBytePixels - for ESP32 +** Description: Write a sequence of pixels with swapped bytes +***************************************************************************************/ +void TFT_eSPI::pushSwapBytePixels(const void *data_in, uint32_t len) +{ + switch (drv.tft_driver) { + case 0x9488: + ILI9488_pushSwapBytePixels(data_in, len); + break; + default: + General_pushSwapBytePixels(data_in, len); + break; + } +} + +/*************************************************************************************** +** Function name: pushPixels - for ESP32 +** Description: Write a sequence of pixels +***************************************************************************************/ +void TFT_eSPI::pushPixels(const void *data_in, uint32_t len) +{ + switch (drv.tft_driver) { + case 0x9488: + ILI9488_pushPixels(data_in, len); + break; + default: + General_pushPixels(data_in, len); + break; + } +} + + +#endif /*DISABLE_CONDITIONAL_MACROS**/ + +#if 1 + +#define TFT_WRITE_BITS(D, B) \ + WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \ + WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \ + SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \ + while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR); + +void TFT_eSPI::tft_Write_8(uint8_t C) +{ + switch (drv.tft_driver) { + case 0x9488: + spi.transfer(C); + break; + default: + TFT_WRITE_BITS(C, 8); + break; + } +} +void TFT_eSPI::tft_Write_16(uint16_t C) +{ + switch (drv.tft_driver) { + case 0x9488: + spi.transfer(((C) & 0xF800) >> 8); + spi.transfer(((C) & 0x07E0) >> 3); + spi.transfer(((C) & 0x001F) << 3); + break; + default: + TFT_WRITE_BITS((C) << 8 | (C) >> 8, 16); + break; + } +} +void TFT_eSPI::tft_Write_16S(uint16_t C) +{ + switch (drv.tft_driver) { + case 0x9488: + spi.transfer((C) & 0xF8); + spi.transfer(((C) & 0xE000) >> 11 | ((C) & 0x07) << 5); + spi.transfer(((C) & 0x1F00) >> 5); + break; + default: + TFT_WRITE_BITS(C, 16); + break; + } +} +void TFT_eSPI::tft_Write_32(uint32_t C) +{ + switch (drv.tft_driver) { + case 0x9488: + spi.write32(C); + break; + default: + TFT_WRITE_BITS(C, 32); + break; + } +} +void TFT_eSPI::tft_Write_32C(uint32_t C, uint32_t D) +{ + switch (drv.tft_driver) { + case 0x9488: + spi.write32((C) << 16 | (D)); + break; + default: + TFT_WRITE_BITS((uint16_t)((D) << 8 | (D) >> 8) << 16 | (uint16_t)((C) << 8 | (C) >> 8), 32); + break; + } +} +void TFT_eSPI::tft_Write_32D(uint32_t C) +{ + switch (drv.tft_driver) { + case 0x9488: + spi.write32((C) << 16 | (C)); + break; + default: + TFT_WRITE_BITS((uint16_t)((C) << 8 | (C) >> 8) << 16 | (uint16_t)((C) << 8 | (C) >> 8), 32); + break; + } +} +#endif //////////////////////////////////////////////////////////////////////////////////////// #if defined ESP32_DMA && !defined (TFT_PARALLEL_8_BIT) // DMA FUNCTIONS @@ -773,7 +1144,6 @@ void TFT_eSPI::deInitDMA(void) #endif - /*************************************************************************************** ** Function name: begin_tft_write (was called spi_begin) ** Description: Start SPI transaction for writes and select TFT @@ -943,6 +1313,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h) CONSTRUCTOR_INIT_TFT_DATA_BUS; #endif + drv.tft_height = _height; + drv.tft_width = _width; _init_width = _width = w; // Set by specific xxxxx_Defines.h file or by users sketch _init_height = _height = h; // Set by specific xxxxx_Defines.h file or by users sketch @@ -1058,9 +1430,9 @@ void TFT_eSPI::init(uint8_t tc) #endif #if defined (TFT_SPI_OVERLAP) && defined (ESP8266) - // Overlap mode SD0=MISO, SD1=MOSI, CLK=SCLK must use D3 as CS - // pins(int8_t sck, int8_t miso, int8_t mosi, int8_t ss); - //spi.pins( 6, 7, 8, 0); +// Overlap mode SD0=MISO, SD1=MOSI, CLK=SCLK must use D3 as CS +// pins(int8_t sck, int8_t miso, int8_t mosi, int8_t ss); +//spi.pins( 6, 7, 8, 0); spi.pins(6, 7, 8, 0); #endif @@ -1084,7 +1456,7 @@ void TFT_eSPI::init(uint8_t tc) #ifdef TFT_CS - // Set to output once again in case D6 (MISO) is used for CS +// Set to output once again in case D6 (MISO) is used for CS pinMode(TFT_CS, OUTPUT); digitalWrite(TFT_CS, HIGH); // Chip select high (inactive) #elif defined (ESP8266) && !defined (TFT_PARALLEL_8_BIT) @@ -1133,6 +1505,10 @@ void TFT_eSPI::init(uint8_t tc) break; case 0x7796:/*ST7796_DRIVER*/ #include "TFT_Drivers/ST7796_Init.h" + break; + case 0x9488:/*ILI9488_DRIVER*/ +#include "TFT_Drivers/ILI9488_Init.h" + break; default: break; } @@ -1178,6 +1554,10 @@ void TFT_eSPI::setRotation(uint8_t m) break; case 0x7796:/*ST7796_DRIVER*/ #include "TFT_Drivers/ST7796_Rotation.h" + break; + case 0x9488:/*ILI9488_DRIVER*/ +#include "TFT_Drivers/ILI9488_Rotation.h" + break; default: break; } @@ -1428,11 +1808,11 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0) /* #else - // The 6 colour bits are in MS 6 bits of each byte, but the ILI9488 needs an extra clock pulse - // so bits appear shifted right 1 bit, so mask the middle 6 bits then shift 1 place left - uint8_t r = (tft_Read_8()&0x7E)<<1; - uint8_t g = (tft_Read_8()&0x7E)<<1; - uint8_t b = (tft_Read_8()&0x7E)<<1; + // The 6 colour bits are in MS 6 bits of each byte, but the ILI9488 needs an extra clock pulse + // so bits appear shifted right 1 bit, so mask the middle 6 bits then shift 1 place left + uint8_t r = (tft_Read_8()&0x7E)<<1; + uint8_t g = (tft_Read_8()&0x7E)<<1; + uint8_t b = (tft_Read_8()&0x7E)<<1; #endif */ diff --git a/src/TFT_eSPI/TFT_eSPI.h b/src/TFT_eSPI/TFT_eSPI.h index 4383970..bc77e4f 100644 --- a/src/TFT_eSPI/TFT_eSPI.h +++ b/src/TFT_eSPI/TFT_eSPI.h @@ -37,9 +37,9 @@ #define TFT_CS 5 #define TFT_DC 27 -// #define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3 -#define SPI_FREQUENCY 40000000 - +#define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3 +// #define SPI_FREQUENCY 40000000 +// #define ILI9488_DRIVER // ST7796 is compatible with ST7789 instructions #include "TFT_Drivers/ST7789_Defines.h" @@ -310,6 +310,7 @@ //////////////////////////////////////////////////////////////////////////////////////// // Define the parallel bus interface chip pin drive code //////////////////////////////////////////////////////////////////////////////////////// +#if 0 #if defined (TFT_PARALLEL_8_BIT) // Create a bit set lookup table for data bus - wastes 1kbyte of RAM but speeds things up dramatically @@ -470,7 +471,7 @@ #define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32) #endif - +#endif /*0*/ //////////////////////////////////////////////////////////////////////////////////////// // Macros to read from display using SPI or software SPI //////////////////////////////////////////////////////////////////////////////////////// @@ -1107,6 +1108,29 @@ public: //--------------------------------------- private ------------------------------------// private: + + void inline tft_Write_8(uint8_t C); + + void inline tft_Write_16(uint16_t C); + + void inline tft_Write_16S(uint16_t C); + + void inline tft_Write_32(uint32_t C); + + void inline tft_Write_32C(uint32_t C, uint32_t D); + + void inline tft_Write_32D(uint32_t C); + + + + void ILI9488_pushBlock(uint16_t color, uint32_t len); + void ILI9488_pushPixels(const void *data_in, uint32_t len); + void ILI9488_pushSwapBytePixels(const void *data_in, uint32_t len); + void General_pushBlock(uint16_t color, uint32_t len); + void General_pushSwapBytePixels(const void *data_in, uint32_t len); + void General_pushPixels(const void *data_in, uint32_t len); + + // Legacy begin and end prototypes - deprecated TODO: delete void spi_begin(); void spi_end(); diff --git a/src/TTGO.h b/src/TTGO.h index 63e69ee..f48829d 100644 --- a/src/TTGO.h +++ b/src/TTGO.h @@ -81,7 +81,7 @@ Written by Lewis he //https://github.com/lewisxhe -#define ENABLE_LVGL_FLUSH_DMA //Use DMA for transmission by default +// #define ENABLE_LVGL_FLUSH_DMA //Use DMA for transmission by default class TTGOClass { @@ -342,7 +342,7 @@ public: lv_disp_drv_init(&disp_drv); static lv_disp_buf_t disp_buf; -#if defined(LILYGO_BLOCK_TOUCHSCREEN) && defined(LILYGO_WATCH_BLOCK) +#if (defined(LILYGO_BLOCK_TOUCHSCREEN) || defined(LILYGO_BLOCK_TOUCHSCREEN_ILI9488)) && defined(LILYGO_WATCH_BLOCK) const uint16_t buffer_size = 320 * 100; #else const uint16_t buffer_size = 240 * 100; @@ -693,6 +693,12 @@ private: h = 480; drv = 0x7796; freq = 27000000; +#elif defined(LILYGO_BLOCK_TOUCHSCREEN_ILI9488) && defined(LILYGO_WATCH_BLOCK) + w = 320; + h = 480; + drv = 0x9488; + freq = 27000000; + // freq = 20000000; #endif tft = new TFT_eSPI(w, h); @@ -891,6 +897,9 @@ protected: x = p.x; y = p.y; } +#else + x = p.x; + y = p.y; #endif return true; }