////////////////////////////////////////////////////// // TFT_eSPI driver functions for ESP8266 processors // ////////////////////////////////////////////////////// #ifndef _TFT_eSPI_ESP8266H_ #define _TFT_eSPI_ESP8266H_ // Processor ID reported by getSetup() #define PROCESSOR_ID 0x8266 // Include processor specific header // None // Processor specific code used by SPI bus transaction startWrite and endWrite functions #define SET_BUS_WRITE_MODE SPI1U=SPI1U_WRITE #define SET_BUS_READ_MODE SPI1U=SPI1U_READ // Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions #define DMA_BUSY_CHECK // DMA not available, leave blank // Initialise processor specific SPI functions, used by init() #if (!defined (SUPPORT_TRANSACTIONS) && defined (ARDUINO_ARCH_ESP8266)) #define INIT_TFT_DATA_BUS \ spi.setBitOrder(MSBFIRST); \ spi.setDataMode(TFT_SPI_MODE); \ spi.setFrequency(SPI_FREQUENCY); #else #define INIT_TFT_DATA_BUS #endif // If smooth fonts are enabled the filing system may need to be loaded #ifdef SMOOTH_FONT // Call up the SPIFFS FLASH filing system for the anti-aliased fonts #define FS_NO_GLOBALS #include #define FONT_FS_AVAILABLE #endif // Do not allow parallel mode for ESP8266 #ifdef ESP32_PARALLEL #undef ESP32_PARALLEL #endif #ifdef TFT_PARALLEL_8_BIT #undef TFT_PARALLEL_8_BIT #endif //////////////////////////////////////////////////////////////////////////////////////// // Define the DC (TFT Data/Command or Register Select (RS))pin drive code //////////////////////////////////////////////////////////////////////////////////////// #ifndef TFT_DC #define DC_C // No macro allocated so it generates no code #define DC_D // No macro allocated so it generates no code #else #if (TFT_DC == 16) #define DC_C digitalWrite(TFT_DC, LOW) #define DC_D digitalWrite(TFT_DC, HIGH) #else #define DC_C GPOC=dcpinmask #define DC_D GPOS=dcpinmask #endif #endif //////////////////////////////////////////////////////////////////////////////////////// // Define the CS (TFT chip select) pin drive code //////////////////////////////////////////////////////////////////////////////////////// #ifndef TFT_CS #define CS_L // No macro allocated so it generates no code #define CS_H // No macro allocated so it generates no code #else #if (TFT_CS == 16) #define CS_L digitalWrite(TFT_CS, LOW) #define CS_H digitalWrite(TFT_CS, HIGH) #else #define CS_L GPOC=cspinmask #define CS_H GPOS=cspinmask #endif #endif //////////////////////////////////////////////////////////////////////////////////////// // Define the WR (TFT Write) pin drive code //////////////////////////////////////////////////////////////////////////////////////// #ifdef TFT_WR #define WR_L GPOC=wrpinmask #define WR_H GPOS=wrpinmask #endif //////////////////////////////////////////////////////////////////////////////////////// // Define the touch screen chip select pin drive code //////////////////////////////////////////////////////////////////////////////////////// #ifndef TOUCH_CS #define T_CS_L // No macro allocated so it generates no code #define T_CS_H // No macro allocated so it generates no code #else #define T_CS_L digitalWrite(TOUCH_CS, LOW) #define T_CS_H digitalWrite(TOUCH_CS, HIGH) #endif //////////////////////////////////////////////////////////////////////////////////////// // Make sure TFT_MISO is defined if not used to avoid an error message //////////////////////////////////////////////////////////////////////////////////////// #ifndef TFT_MISO #define TFT_MISO -1 #endif //////////////////////////////////////////////////////////////////////////////////////// // ESP8266 specific SPI macros //////////////////////////////////////////////////////////////////////////////////////// #if defined (TFT_SPI_OVERLAP) #undef TFT_CS #define SPI1U_WRITE (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD) #define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD | SPIUDUPLEX) #else #define SPI1U_WRITE (SPIUMOSI | SPIUSSE) #define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUDUPLEX) #endif //////////////////////////////////////////////////////////////////////////////////////// // Macros to write commands/pixel colour data to a SPI ILI948x TFT //////////////////////////////////////////////////////////////////////////////////////// #if defined (SPI_18BIT_DRIVER) // SPI 18 bit colour // Write 8 bits to TFT #define tft_Write_8(C) spi.transfer(C) // Convert 16 bit colour to 18 bit and write in 3 bytes #define tft_Write_16(C) spi.transfer(((C) & 0xF800)>>8); \ spi.transfer(((C) & 0x07E0)>>3); \ spi.transfer(((C) & 0x001F)<<3) // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes #define tft_Write_16S(C) spi.transfer((C) & 0xF8); \ spi.transfer(((C) & 0xE000)>>11 | ((C) & 0x07)<<5); \ spi.transfer(((C) & 0x1F00)>>5) // Write 32 bits to TFT #define tft_Write_32(C) spi.write32(C) // Write two address coordinates #define tft_Write_32C(C,D) spi.write32((C)<<16 | (D)) // Write same value twice #define tft_Write_32D(C) spi.write32((C)<<16 | (C)) //////////////////////////////////////////////////////////////////////////////////////// // Macros to write commands/pixel colour data to an Raspberry Pi TFT //////////////////////////////////////////////////////////////////////////////////////// #elif defined (RPI_DISPLAY_TYPE) // Command is 16 bits #define CMD_BITS 16 // ESP8266 low level SPI writes for 8, 16 and 32 bit values // to avoid the function call overhead #define TFT_WRITE_BITS(D, B) \ SPI1U1 = ((B-1) << SPILMOSI); \ SPI1W0 = D; \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {} #define tft_Write_8(C) TFT_WRITE_BITS((uint16_t)(C)<<8, CMD_BITS) #define tft_Write_16(C) TFT_WRITE_BITS((C)>>8 | (C)<<8, 16) #define tft_Write_16S(C) TFT_WRITE_BITS(C, 16) #define tft_Write_32(C) TFT_WRITE_BITS(C, 32) #define tft_Write_32C(C,D) SPI1U1 = ((64-1) << SPILMOSI); \ SPI1W0 = ((C)<<24) | (C); \ SPI1W1 = ((D)<<24) | (D); \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {;} #define tft_Write_32D(C) tft_Write_32C(C,C) //////////////////////////////////////////////////////////////////////////////////////// // Macros for all other SPI displays //////////////////////////////////////////////////////////////////////////////////////// #else // Command is 8 bits #define CMD_BITS 8 #define tft_Write_8(C) \ SPI1U1 = ((CMD_BITS-1) << SPILMOSI) | ((CMD_BITS-1) << SPILMISO); \ SPI1W0 = (C)<<(CMD_BITS - 8); \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {;} #define tft_Write_16(C) \ SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \ SPI1W0 = ((C)<<8 | (C)>>8); \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {;} #define tft_Write_16N(C) \ SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \ SPI1W0 = ((C)<<8 | (C)>>8); \ SPI1CMD |= SPIBUSY #define tft_Write_16S(C) \ SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \ SPI1W0 = C; \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {;} #define tft_Write_32(C) \ SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \ SPI1W0 = C; \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {;} #define tft_Write_32C(C,D) \ SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \ SPI1W0 = ((D)>>8 | (D)<<8)<<16 | ((C)>>8 | (C)<<8); \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {;} #define tft_Write_32D(C) \ SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \ SPI1W0 = ((C)>>8 | (C)<<8)<<16 | ((C)>>8 | (C)<<8); \ SPI1CMD |= SPIBUSY; \ while(SPI1CMD & SPIBUSY) {;} #endif #ifndef tft_Write_16N #define tft_Write_16N tft_Write_16 #endif //////////////////////////////////////////////////////////////////////////////////////// // Macros to read from display using SPI or software SPI //////////////////////////////////////////////////////////////////////////////////////// #if defined (TFT_SDA_READ) // Use a bit banged function call for ESP8266 and bi-directional SDA pin #define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8(void); #define SCLK_L GPOC=sclkpinmask #define SCLK_H GPOS=sclkpinmask #else // Use a SPI read transfer #define tft_Read_8() spi.transfer(0) #endif // Concatenate a byte sequence A,B,C,D to CDAB, P is a uint8_t pointer #define DAT8TO32(P) ( (uint32_t)P[0]<<8 | P[1] | P[2]<<24 | P[3]<<16 ) #endif // Header end