acidportal

- 😈 Worlds smallest Evil Portal on a LilyGo T-QT
git clone git://git.acid.vegas/acidportal.git
Log | Files | Refs | Archive | README | LICENSE

TFT_eSPI_ESP32_C3.h (22973B)

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