acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

TFT_eSPI_ESP32.h (22115B)

      1         ////////////////////////////////////////////////////
      2         // TFT_eSPI driver functions for ESP32 processors //
      3         ////////////////////////////////////////////////////
      4 
      5 #ifndef _TFT_eSPI_ESP32H_
      6 #define _TFT_eSPI_ESP32H_
      7 
      8 // Processor ID reported by getSetup()
      9 #define PROCESSOR_ID 0x32
     10 
     11 // Include processor specific header
     12 #include "soc/spi_reg.h"
     13 #include "driver/spi_master.h"
     14 
     15 #if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32)
     16   #define CONFIG_IDF_TARGET_ESP32
     17 #endif
     18 
     19 // Fix IDF problems with ESP32C3
     20 #if CONFIG_IDF_TARGET_ESP32C3
     21   // Fix ESP32C3 IDF bug for missing definition
     22   #ifndef REG_SPI_BASE
     23     #define REG_SPI_BASE(i)     (DR_REG_SPI1_BASE + (((i)>1) ? (((i)* 0x1000) + 0x20000) : (((~(i)) & 1)* 0x1000 )))
     24   #endif
     25 
     26   // Fix ESP32C3 IDF bug for name change
     27   #ifndef SPI_MOSI_DLEN_REG
     28     #define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x)
     29   #endif
     30 
     31   // Fix ESP32C3 specific register reference
     32   #define out_w1tc out_w1tc.val
     33   #define out_w1ts out_w1ts.val
     34 #endif
     35 
     36 // SUPPORT_TRANSACTIONS is mandatory for ESP32 so the hal mutex is toggled
     37 #if !defined (SUPPORT_TRANSACTIONS)
     38   #define SUPPORT_TRANSACTIONS
     39 #endif
     40 
     41 /*
     42 ESP32:
     43 FSPI not defined
     44 HSPI = 2, uses SPI2
     45 VSPI = 3, uses SPI3
     46 
     47 ESP32-S2:
     48 FSPI = 1, uses SPI2
     49 HSPI = 2, uses SPI3
     50 VSPI not defined
     51 
     52 ESP32 C3:
     53 FSPI = 0, uses SPI2 ???? To be checked
     54 HSPI = 1, uses SPI3 ???? To be checked
     55 VSPI not defined
     56 
     57 For ESP32/S2/C3:
     58 SPI1_HOST = 0
     59 SPI2_HOST = 1
     60 SPI3_HOST = 2
     61 */
     62 
     63 // ESP32 specific SPI port selection
     64 #ifdef USE_HSPI_PORT
     65   #ifdef CONFIG_IDF_TARGET_ESP32
     66     #define SPI_PORT HSPI  //HSPI is port 2 on ESP32
     67   #else
     68     #define SPI_PORT 3     //HSPI is port 3 on ESP32 S2
     69   #endif
     70 #elif defined(USE_FSPI_PORT)
     71     #define SPI_PORT 2 //FSPI(ESP32 S2)
     72 #else
     73   #ifdef CONFIG_IDF_TARGET_ESP32
     74     #define SPI_PORT VSPI
     75   #else
     76     #define SPI_PORT 2 //FSPI(ESP32 S2)
     77   #endif
     78 #endif
     79 
     80 #ifdef RPI_DISPLAY_TYPE
     81   #define CMD_BITS (16-1)
     82 #else
     83   #define CMD_BITS (8-1)
     84 #endif
     85 
     86 // Initialise processor specific SPI functions, used by init()
     87 #define INIT_TFT_DATA_BUS // Not used
     88 
     89 // Define a generic flag for 8 bit parallel
     90 #if defined (ESP32_PARALLEL) // Specific to ESP32 for backwards compatibility
     91   #if !defined (TFT_PARALLEL_8_BIT)
     92     #define TFT_PARALLEL_8_BIT // Generic parallel flag
     93   #endif
     94 #endif
     95 
     96 // Ensure ESP32 specific flag is defined for 8 bit parallel
     97 #if defined (TFT_PARALLEL_8_BIT)
     98   #if !defined (ESP32_PARALLEL)
     99     #define ESP32_PARALLEL
    100   #endif
    101 #endif
    102 
    103 // Processor specific code used by SPI bus transaction startWrite and endWrite functions
    104 #if !defined (ESP32_PARALLEL)
    105   #if (TFT_SPI_MODE == SPI_MODE1) || (TFT_SPI_MODE == SPI_MODE2)
    106     #define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI | SPI_CK_OUT_EDGE
    107     #define SET_BUS_READ_MODE  *_spi_user = SPI_USR_MOSI | SPI_USR_MISO | SPI_DOUTDIN | SPI_CK_OUT_EDGE
    108   #else
    109     #define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI
    110     #define SET_BUS_READ_MODE  *_spi_user = SPI_USR_MOSI | SPI_USR_MISO | SPI_DOUTDIN
    111   #endif
    112 #else
    113     // Not applicable to parallel bus
    114     #define SET_BUS_WRITE_MODE
    115     #define SET_BUS_READ_MODE
    116 #endif
    117 
    118 // Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions
    119 #if !defined(TFT_PARALLEL_8_BIT) && !defined(SPI_18BIT_DRIVER)
    120   #define ESP32_DMA
    121   // Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
    122   #define DMA_BUSY_CHECK  dmaWait()
    123 #else
    124   #define DMA_BUSY_CHECK
    125 #endif
    126 
    127 #if defined(TFT_PARALLEL_8_BIT)
    128   #define SPI_BUSY_CHECK
    129 #else
    130   #define SPI_BUSY_CHECK while (*_spi_cmd&SPI_USR)
    131 #endif
    132 
    133 // If smooth font is used then it is likely SPIFFS will be needed
    134 #ifdef SMOOTH_FONT
    135   // Call up the SPIFFS (SPI FLASH Filing System) for the anti-aliased fonts
    136   #define FS_NO_GLOBALS
    137   #include <FS.h>
    138   #include "SPIFFS.h" // ESP32 only
    139   #define FONT_FS_AVAILABLE
    140 #endif
    141 
    142 
    143 ////////////////////////////////////////////////////////////////////////////////////////
    144 // Define the DC (TFT Data/Command or Register Select (RS))pin drive code
    145 ////////////////////////////////////////////////////////////////////////////////////////
    146 #ifndef TFT_DC
    147   #define DC_C // No macro allocated so it generates no code
    148   #define DC_D // No macro allocated so it generates no code
    149 #else
    150   #if defined (TFT_PARALLEL_8_BIT)
    151     // TFT_DC, by design, must be in range 0-31 for single register parallel write
    152     #if (TFT_DC >= 0) &&  (TFT_DC < 32)
    153       #define DC_C GPIO.out_w1tc = (1 << TFT_DC)
    154       #define DC_D GPIO.out_w1ts = (1 << TFT_DC)
    155     #elif (TFT_DC >= 32)
    156       #define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC- 32))
    157       #define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC- 32))
    158     #else
    159       #define DC_C
    160       #define DC_D
    161     #endif
    162   #else
    163     #if (TFT_DC >= 32)
    164       #ifdef RPI_DISPLAY_TYPE  // RPi displays need a slower DC change
    165         #define DC_C GPIO.out1_w1ts.val = (1 << (TFT_DC - 32)); \
    166                      GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
    167         #define DC_D GPIO.out1_w1tc.val = (1 << (TFT_DC - 32)); \
    168                      GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
    169       #else
    170         #define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
    171         #define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
    172       #endif
    173     #elif (TFT_DC >= 0)
    174       #if defined (RPI_DISPLAY_TYPE)
    175         #if defined (ILI9486_DRIVER)
    176           // RPi ILI9486 display needs a slower DC change
    177           #define DC_C GPIO.out_w1tc = (1 << TFT_DC); \
    178                        GPIO.out_w1tc = (1 << TFT_DC)
    179           #define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
    180                        GPIO.out_w1ts = (1 << TFT_DC)
    181         #else
    182           // Other RPi displays need a slower C->D change
    183           #define DC_C GPIO.out_w1tc = (1 << TFT_DC)
    184           #define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
    185                        GPIO.out_w1ts = (1 << TFT_DC)
    186         #endif
    187       #else
    188         #define DC_C GPIO.out_w1tc = (1 << TFT_DC)//;GPIO.out_w1tc = (1 << TFT_DC)
    189         #define DC_D GPIO.out_w1ts = (1 << TFT_DC)//;GPIO.out_w1ts = (1 << TFT_DC)
    190       #endif
    191     #else
    192       #define DC_C
    193       #define DC_D
    194     #endif
    195   #endif
    196 #endif
    197 
    198 ////////////////////////////////////////////////////////////////////////////////////////
    199 // Define the CS (TFT chip select) pin drive code
    200 ////////////////////////////////////////////////////////////////////////////////////////
    201 #ifndef TFT_CS
    202   #define TFT_CS -1  // Keep DMA code happy
    203   #define CS_L       // No macro allocated so it generates no code
    204   #define CS_H       // No macro allocated so it generates no code
    205 #else
    206   #if defined (TFT_PARALLEL_8_BIT)
    207     #if TFT_CS >= 32
    208         #define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
    209         #define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
    210     #elif TFT_CS >= 0
    211         #define CS_L GPIO.out_w1tc = (1 << TFT_CS)
    212         #define CS_H GPIO.out_w1ts = (1 << TFT_CS)
    213     #else
    214       #define CS_L
    215       #define CS_H
    216     #endif
    217   #else
    218     #if (TFT_CS >= 32)
    219       #ifdef RPI_DISPLAY_TYPE  // RPi display needs a slower CS change
    220         #define CS_L GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)); \
    221                      GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
    222         #define CS_H GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); \
    223                      GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
    224       #else
    225         #define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
    226         #define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
    227       #endif
    228     #elif (TFT_CS >= 0)
    229       #ifdef RPI_DISPLAY_TYPE  // RPi display needs a slower CS change
    230         #define CS_L GPIO.out_w1ts = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS)
    231         #define CS_H GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1ts = (1 << TFT_CS)
    232       #else
    233         #define CS_L GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS)
    234         #define CS_H GPIO.out_w1ts = (1 << TFT_CS)//;GPIO.out_w1ts = (1 << TFT_CS)
    235       #endif
    236     #else
    237       #define CS_L
    238       #define CS_H
    239     #endif
    240   #endif
    241 #endif
    242 
    243 ////////////////////////////////////////////////////////////////////////////////////////
    244 // Define the WR (TFT Write) pin drive code
    245 ////////////////////////////////////////////////////////////////////////////////////////
    246 #if defined (TFT_WR)
    247   #if (TFT_WR >= 32)
    248     // Note: it will be ~1.25x faster if the TFT_WR pin uses a GPIO pin lower than 32
    249     #define WR_L GPIO.out1_w1tc.val = (1 << (TFT_WR - 32))
    250     #define WR_H GPIO.out1_w1ts.val = (1 << (TFT_WR - 32))
    251   #elif (TFT_WR >= 0)
    252     // TFT_WR, for best performance, should be in range 0-31 for single register parallel write
    253     #define WR_L GPIO.out_w1tc = (1 << TFT_WR)
    254     #define WR_H GPIO.out_w1ts = (1 << TFT_WR)
    255   #else
    256     #define WR_L
    257     #define WR_H
    258   #endif
    259 #else
    260   #define WR_L
    261   #define WR_H
    262 #endif
    263 
    264 ////////////////////////////////////////////////////////////////////////////////////////
    265 // Define the touch screen chip select pin drive code
    266 ////////////////////////////////////////////////////////////////////////////////////////
    267 #ifndef TOUCH_CS
    268   #define T_CS_L // No macro allocated so it generates no code
    269   #define T_CS_H // No macro allocated so it generates no code
    270 #else // XPT2046 is slow, so use slower digitalWrite here
    271   #define T_CS_L digitalWrite(TOUCH_CS, LOW)
    272   #define T_CS_H digitalWrite(TOUCH_CS, HIGH)
    273 #endif
    274 
    275 ////////////////////////////////////////////////////////////////////////////////////////
    276 // Make sure SPI default pins are assigned if not specified by user or set to -1
    277 ////////////////////////////////////////////////////////////////////////////////////////
    278 #if !defined (TFT_PARALLEL_8_BIT)
    279 
    280   #ifdef USE_HSPI_PORT
    281 
    282     #ifndef TFT_MISO
    283       #define TFT_MISO -1
    284     #endif
    285 
    286     #ifndef TFT_MOSI
    287       #define TFT_MOSI 13
    288     #endif
    289     #if (TFT_MOSI == -1)
    290       #undef TFT_MOSI
    291       #define TFT_MOSI 13
    292     #endif
    293 
    294     #ifndef TFT_SCLK
    295       #define TFT_SCLK 14
    296     #endif
    297     #if (TFT_SCLK == -1)
    298       #undef TFT_SCLK
    299       #define TFT_SCLK 14
    300     #endif
    301 
    302   #else // VSPI port
    303 
    304     #ifndef TFT_MISO
    305       #define TFT_MISO -1
    306     #endif
    307 
    308     #ifndef TFT_MOSI
    309       #define TFT_MOSI 23
    310     #endif
    311     #if (TFT_MOSI == -1)
    312       #undef TFT_MOSI
    313       #define TFT_MOSI 23
    314     #endif
    315 
    316     #ifndef TFT_SCLK
    317       #define TFT_SCLK 18
    318     #endif
    319     #if (TFT_SCLK == -1)
    320       #undef TFT_SCLK
    321       #define TFT_SCLK 18
    322     #endif
    323 
    324     #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
    325       #if (TFT_MISO == -1)
    326         #undef TFT_MISO
    327         #define TFT_MISO TFT_MOSI
    328       #endif
    329     #endif
    330 
    331   #endif
    332 
    333 #endif
    334 
    335 ////////////////////////////////////////////////////////////////////////////////////////
    336 // Define the parallel bus interface chip pin drive code
    337 ////////////////////////////////////////////////////////////////////////////////////////
    338 #if defined (TFT_PARALLEL_8_BIT)
    339 
    340   // Create a bit set lookup table for data bus - wastes 1kbyte of RAM but speeds things up dramatically
    341   // can then use e.g. GPIO.out_w1ts = set_mask(0xFF); to set data bus to 0xFF
    342   #define PARALLEL_INIT_TFT_DATA_BUS               \
    343   for (int32_t c = 0; c<256; c++)                  \
    344   {                                                \
    345     xset_mask[c] = 0;                              \
    346     if ( c & 0x01 ) xset_mask[c] |= (1 << TFT_D0); \
    347     if ( c & 0x02 ) xset_mask[c] |= (1 << TFT_D1); \
    348     if ( c & 0x04 ) xset_mask[c] |= (1 << TFT_D2); \
    349     if ( c & 0x08 ) xset_mask[c] |= (1 << TFT_D3); \
    350     if ( c & 0x10 ) xset_mask[c] |= (1 << TFT_D4); \
    351     if ( c & 0x20 ) xset_mask[c] |= (1 << TFT_D5); \
    352     if ( c & 0x40 ) xset_mask[c] |= (1 << TFT_D6); \
    353     if ( c & 0x80 ) xset_mask[c] |= (1 << TFT_D7); \
    354   }                                                \
    355 
    356   // Mask for the 8 data bits to set pin directions
    357   #define GPIO_DIR_MASK ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7))
    358 
    359   #if (TFT_WR >= 32)
    360     // Data bits and the write line are cleared sequentially
    361     #define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK); WR_L
    362   #elif (TFT_WR >= 0)
    363     // Data bits and the write line are cleared to 0 in one step (1.25x faster)
    364     #define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK | (1 << TFT_WR))
    365   #else
    366     #define GPIO_OUT_CLR_MASK
    367   #endif
    368 
    369   // A lookup table is used to set the different bit patterns, this uses 1kByte of RAM
    370   #define set_mask(C) xset_mask[C] // 63fps Sprite rendering test 33% faster, graphicstest only 1.8% faster than shifting in real time
    371 
    372   // Real-time shifting alternative to above to save 1KByte RAM, 47 fps Sprite rendering test
    373   /*#define set_mask(C) (((C)&0x80)>>7)<<TFT_D7 | (((C)&0x40)>>6)<<TFT_D6 | (((C)&0x20)>>5)<<TFT_D5 | (((C)&0x10)>>4)<<TFT_D4 | \
    374                         (((C)&0x08)>>3)<<TFT_D3 | (((C)&0x04)>>2)<<TFT_D2 | (((C)&0x02)>>1)<<TFT_D1 | (((C)&0x01)>>0)<<TFT_D0
    375   //*/
    376 
    377   // Write 8 bits to TFT
    378   #define tft_Write_8(C)  GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t)(C)); WR_H
    379 
    380   #if defined (SSD1963_DRIVER)
    381 
    382     // Write 18 bit color to TFT
    383     #define tft_Write_16(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0xF800)>> 8)); WR_H; \
    384                             GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x07E0)>> 3)); WR_H; \
    385                             GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x001F)<< 3)); WR_H
    386 
    387     // 18 bit color write with swapped bytes
    388     #define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
    389 
    390   #else
    391 
    392     #ifdef PSEUDO_16_BIT
    393       // One write strobe for both bytes
    394       #define tft_Write_16(C)  GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
    395       #define tft_Write_16S(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
    396     #else
    397       // Write 16 bits to TFT
    398       #define tft_Write_16(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
    399                               GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
    400 
    401       // 16 bit write with swapped bytes
    402       #define tft_Write_16S(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
    403                                GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
    404     #endif
    405 
    406   #endif
    407 
    408   // Write 32 bits to TFT
    409   #define tft_Write_32(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 24)); WR_H; \
    410                           GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 16)); WR_H; \
    411                           GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >>  8)); WR_H; \
    412                           GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >>  0)); WR_H
    413 
    414   // Write two concatenated 16 bit values to TFT
    415   #define tft_Write_32C(C,D) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
    416                              GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
    417                              GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 8)); WR_H; \
    418                              GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 0)); WR_H
    419 
    420   // Write 16 bit value twice to TFT - used by drawPixel()
    421   #define tft_Write_32D(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
    422                            GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
    423                            GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
    424                            GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
    425 
    426    // Read pin
    427   #ifdef TFT_RD
    428     #if (TFT_RD >= 32)
    429       #define RD_L GPIO.out1_w1tc.val = (1 << (TFT_RD - 32))
    430       #define RD_H GPIO.out1_w1ts.val = (1 << (TFT_RD - 32))
    431     #elif (TFT_RD >= 0)
    432       #define RD_L GPIO.out_w1tc = (1 << TFT_RD)
    433       //#define RD_L digitalWrite(TFT_WR, LOW)
    434       #define RD_H GPIO.out_w1ts = (1 << TFT_RD)
    435       //#define RD_H digitalWrite(TFT_WR, HIGH)
    436     #else
    437       #define RD_L
    438       #define RD_H
    439     #endif
    440   #else
    441     #define TFT_RD -1
    442     #define RD_L
    443     #define RD_H
    444   #endif
    445 
    446 ////////////////////////////////////////////////////////////////////////////////////////
    447 // Macros to write commands/pixel colour data to a SPI ILI948x TFT
    448 ////////////////////////////////////////////////////////////////////////////////////////
    449 #elif  defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
    450 
    451   // Write 8 bits to TFT
    452   #define tft_Write_8(C)   spi.transfer(C)
    453 
    454   // Convert 16 bit colour to 18 bit and write in 3 bytes
    455   #define tft_Write_16(C)  spi.transfer(((C) & 0xF800)>>8); \
    456                            spi.transfer(((C) & 0x07E0)>>3); \
    457                            spi.transfer(((C) & 0x001F)<<3)
    458 
    459   // Future option for transfer without wait
    460   #define tft_Write_16N(C) tft_Write_16(C)
    461 
    462   // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
    463   #define tft_Write_16S(C) spi.transfer((C) & 0xF8); \
    464                            spi.transfer(((C) & 0xE000)>>11 | ((C) & 0x07)<<5); \
    465                            spi.transfer(((C) & 0x1F00)>>5)
    466 
    467   // Write 32 bits to TFT
    468   #define tft_Write_32(C)  spi.write32(C)
    469 
    470   // Write two concatenated 16 bit values to TFT
    471   #define tft_Write_32C(C,D) spi.write32((C)<<16 | (D))
    472 
    473   // Write 16 bit value twice to TFT
    474   #define tft_Write_32D(C)  spi.write32((C)<<16 | (C))
    475 
    476 ////////////////////////////////////////////////////////////////////////////////////////
    477 // Macros to write commands/pixel colour data to an Raspberry Pi TFT
    478 ////////////////////////////////////////////////////////////////////////////////////////
    479 #elif  defined (RPI_DISPLAY_TYPE)
    480 
    481   // ESP32 low level SPI writes for 8, 16 and 32 bit values
    482   // to avoid the function call overhead
    483   #define TFT_WRITE_BITS(D, B) \
    484   WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
    485   WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
    486   SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
    487   while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
    488 
    489   // Write 8 bits
    490   #define tft_Write_8(C) TFT_WRITE_BITS((C)<<8, 16)
    491 
    492   // Write 16 bits with corrected endianness for 16 bit colours
    493   #define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
    494 
    495   // Future option for transfer without wait
    496   #define tft_Write_16N(C) tft_Write_16(C)
    497 
    498   // Write 16 bits
    499   #define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
    500 
    501   // Write 32 bits
    502   #define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
    503 
    504   // Write two address coordinates
    505   #define tft_Write_32C(C,D)  TFT_WRITE_BITS((C)<<24 | (C), 32); \
    506                               TFT_WRITE_BITS((D)<<24 | (D), 32)
    507 
    508   // Write same value twice
    509   #define tft_Write_32D(C) tft_Write_32C(C,C)
    510 
    511 ////////////////////////////////////////////////////////////////////////////////////////
    512 // Macros for all other SPI displays
    513 ////////////////////////////////////////////////////////////////////////////////////////
    514 #else
    515 /* Old macros
    516   // ESP32 low level SPI writes for 8, 16 and 32 bit values
    517   // to avoid the function call overhead
    518   #define TFT_WRITE_BITS(D, B) \
    519   WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
    520   WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
    521   SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
    522   while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
    523 
    524   // Write 8 bits
    525   #define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
    526 
    527   // Write 16 bits with corrected endianness for 16 bit colours
    528   #define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
    529 
    530   // Write 16 bits
    531   #define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
    532 
    533   // Write 32 bits
    534   #define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
    535 
    536   // Write two address coordinates
    537   #define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
    538 
    539   // Write same value twice
    540   #define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
    541 //*/
    542 //* Replacement slimmer macros
    543   #define TFT_WRITE_BITS(D, B) *_spi_mosi_dlen = B-1;    \
    544                                *_spi_w = D;             \
    545                                *_spi_cmd = SPI_USR;      \
    546                         while (*_spi_cmd & SPI_USR);
    547 
    548   // Write 8 bits
    549   #define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
    550 
    551   // Write 16 bits with corrected endianness for 16 bit colours
    552   #define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
    553 
    554   // Future option for transfer without wait
    555   #define tft_Write_16N(C) *_spi_mosi_dlen = 16-1;       \
    556                            *_spi_w = ((C)<<8 | (C)>>8); \
    557                            *_spi_cmd = SPI_USR;
    558 
    559   // Write 16 bits
    560   #define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
    561 
    562   // Write 32 bits
    563   #define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
    564 
    565   // Write two address coordinates
    566   #define tft_Write_32C(C,D)  TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
    567 
    568   // Write same value twice
    569   #define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
    570 
    571 //*/
    572 #endif
    573 
    574 #ifndef tft_Write_16N
    575   #define tft_Write_16N tft_Write_16
    576 #endif
    577 
    578 ////////////////////////////////////////////////////////////////////////////////////////
    579 // Macros to read from display using SPI or software SPI
    580 ////////////////////////////////////////////////////////////////////////////////////////
    581 #if !defined (TFT_PARALLEL_8_BIT)
    582   // Read from display using SPI or software SPI
    583   // Use a SPI read transfer
    584   #define tft_Read_8() spi.transfer(0)
    585 #endif
    586 
    587 // Concatenate a byte sequence A,B,C,D to CDAB, P is a uint8_t pointer
    588 #define DAT8TO32(P) ( (uint32_t)P[0]<<8 | P[1] | P[2]<<24 | P[3]<<16 )
    589 
    590 #endif // Header end