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_RP2040.h (21380B)

      1         ////////////////////////////////////////////////////
      2         //       TFT_eSPI generic driver functions        //
      3         ////////////////////////////////////////////////////
      4 
      5 // This is a generic driver for Arduino boards, it supports SPI interface displays
      6 // 8 bit parallel interface to TFT is not supported for generic processors
      7 
      8 #ifndef _TFT_eSPI_RP2040H_
      9 #define _TFT_eSPI_RP2040H_
     10 
     11 #ifndef ARDUINO_ARCH_MBED
     12   #include <LittleFS.h>
     13   #define FONT_FS_AVAILABLE
     14   #define SPIFFS LittleFS
     15 #endif
     16 
     17 // Required for both the official and community board packages
     18 #include "hardware/dma.h"
     19 #include "hardware/pio.h"
     20 #include "hardware/clocks.h"
     21 
     22 // Processor ID reported by getSetup()
     23 #define PROCESSOR_ID 0x2040
     24 
     25 // Transactions always supported
     26 #ifndef SUPPORT_TRANSACTIONS
     27   #define SUPPORT_TRANSACTIONS
     28 #endif
     29 
     30 // Include processor specific header
     31 // None
     32 
     33 #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RP2040_PIO_SPI)
     34   #define RP2040_PIO_INTERFACE
     35   #define RP2040_PIO_PUSHBLOCK
     36 #endif
     37 
     38 #if !defined (RP2040_PIO_INTERFACE)// SPI
     39   // Use SPI0 as default if not defined
     40   #ifndef TFT_SPI_PORT
     41     #define TFT_SPI_PORT 0
     42   #endif
     43 
     44   #if (TFT_SPI_PORT == 0)
     45     #define SPI_X spi0
     46   #else
     47     #define SPI_X spi1
     48   #endif
     49 
     50   // Processor specific code used by SPI bus transaction begin/end_tft_write functions
     51   #define SET_BUS_WRITE_MODE spi_set_format(SPI_X,  8, (spi_cpol_t)(TFT_SPI_MODE >> 1), (spi_cpha_t)(TFT_SPI_MODE & 0x1), SPI_MSB_FIRST)
     52   #define SET_BUS_READ_MODE  // spi_set_format(SPI_X,  8, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST)
     53 #else
     54   // Processor specific code used by SPI bus transaction begin/end_tft_write functions
     55   #define SET_BUS_WRITE_MODE
     56   #define SET_BUS_READ_MODE
     57 #endif
     58 
     59 // Code to check if SPI or DMA is busy, used by SPI bus transaction startWrite and/or endWrite functions
     60 #if !defined(SPI_18BIT_DRIVER)
     61   #define RP2040_DMA
     62   // Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
     63   #define DMA_BUSY_CHECK dmaWait()
     64 #else
     65   #define DMA_BUSY_CHECK
     66 #endif
     67 
     68 // Handle high performance MHS RPi display type
     69 #if  defined (MHS_DISPLAY_TYPE)  && !defined (RPI_DISPLAY_TYPE)
     70   #define RPI_DISPLAY_TYPE
     71 #endif
     72 
     73 #if !defined (RP2040_PIO_INTERFACE) // SPI
     74 
     75   #if  defined (MHS_DISPLAY_TYPE) // High speed RPi TFT type always needs 16 bit transfers
     76     // This swaps to 16 bit mode, used for commands so wait avoids clash with DC timing
     77     #define INIT_TFT_DATA_BUS hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS)
     78   #else
     79     // Initialise processor specific SPI functions, used by init()
     80     #define INIT_TFT_DATA_BUS  // Not used
     81   #endif
     82 
     83   // Wait for tx to end, flush rx FIFO, clear rx overrun
     84   #define SPI_BUSY_CHECK while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {};     \
     85                          while (spi_is_readable(SPI_X)) (void)spi_get_hw(SPI_X)->dr; \
     86                          spi_get_hw(SPI_X)->icr = SPI_SSPICR_RORIC_BITS
     87 
     88   // To be safe, SUPPORT_TRANSACTIONS is assumed mandatory
     89   #if !defined (SUPPORT_TRANSACTIONS)
     90     #define SUPPORT_TRANSACTIONS
     91   #endif
     92 #else
     93 
     94   // Different controllers have different minimum write cycle periods, so the PIO clock is changed accordingly
     95   // The PIO clock is a division of the CPU clock so scales when the processor is overclocked
     96   // PIO write frequency = (CPU clock/(4 * RP2040_PIO_CLK_DIV))
     97   // The write cycle periods below assume a 125MHz CPU clock speed
     98   #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
     99     #if defined (RP2040_PIO_CLK_DIV)
    100       #if (RP2040_PIO_CLK_DIV > 0)
    101         #define DIV_UNITS RP2040_PIO_CLK_DIV
    102         #define DIV_FRACT 0
    103       #else
    104         #define DIV_UNITS 3
    105         #define DIV_FRACT 0
    106       #endif
    107     #elif defined (TFT_PARALLEL_16_BIT)
    108       // Different display drivers have different minimum write cycle times
    109       #if defined (HX8357C_DRIVER) || defined (SSD1963_DRIVER)
    110         #define DIV_UNITS 1 // 32ns write cycle time SSD1963, HX8357C (maybe HX8357D?)
    111       #elif defined (ILI9486_DRIVER) || defined (HX8357B_DRIVER) || defined (HX8357D_DRIVER)
    112         #define DIV_UNITS 2 // 64ns write cycle time ILI9486, HX8357D, HX8357B
    113       #else // ILI9481 needs a slower cycle time
    114         #define DIV_UNITS 3 // 96ns write cycle time
    115       #endif
    116       #define DIV_FRACT 0
    117     #else // 8 bit parallel mode default 64ns write cycle time
    118       #define DIV_UNITS 2
    119       #define DIV_FRACT 0 // Note: Fractional values done with clock period dithering
    120     #endif
    121   #endif
    122 
    123   // Initialise TFT data bus
    124   #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
    125     #define INIT_TFT_DATA_BUS pioinit(DIV_UNITS, DIV_FRACT);
    126   #elif defined (RP2040_PIO_SPI)
    127     #define INIT_TFT_DATA_BUS pioinit(SPI_FREQUENCY);
    128   #endif
    129 
    130   #define SPI_BUSY_CHECK
    131 
    132   // Set the state machine clock divider (from integer and fractional parts - 16:8) 
    133   #define PARALLEL_INIT_TFT_DATA_BUS // Not used
    134 
    135 #endif
    136 
    137 
    138 // If smooth fonts are enabled the filing system may need to be loaded
    139 #if defined (SMOOTH_FONT) && !defined (ARDUINO_ARCH_MBED)
    140   // Call up the filing system for the anti-aliased fonts
    141   //#define FS_NO_GLOBALS
    142   #include <FS.h>
    143 #endif
    144 
    145 ////////////////////////////////////////////////////////////////////////////////////////
    146 // Define the DC (TFT Data/Command or Register Select (RS))pin drive code
    147 ////////////////////////////////////////////////////////////////////////////////////////
    148 #ifndef TFT_DC
    149   #define DC_C // No macro allocated so it generates no code
    150   #define DC_D // No macro allocated so it generates no code
    151 #else
    152   #if !defined (RP2040_PIO_INTERFACE)// SPI
    153     //#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC)
    154     //#define DC_D sio_hw->gpio_set = (1ul << TFT_DC)
    155     #if  defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
    156       #define DC_C digitalWrite(TFT_DC, LOW);
    157       #define DC_D digitalWrite(TFT_DC, HIGH);
    158     #else
    159       #define DC_C sio_hw->gpio_clr = (1ul << TFT_DC)
    160       #define DC_D sio_hw->gpio_set = (1ul << TFT_DC)
    161     #endif
    162   #else
    163     // PIO takes control of TFT_DC
    164     // Must wait for data to flush through before changing DC line
    165     #define DC_C  WAIT_FOR_STALL; \
    166                   tft_pio->sm[pio_sm].instr = pio_instr_clr_dc
    167 
    168     #ifndef RM68120_DRIVER
    169       // Flush has happened before this and mode changed back to 16 bit
    170       #define DC_D  tft_pio->sm[pio_sm].instr = pio_instr_set_dc
    171     #else
    172       // Need to wait for stall since RM68120 commands are 16 bit
    173       #define DC_D  WAIT_FOR_STALL; tft_pio->sm[pio_sm].instr = pio_instr_set_dc
    174     #endif
    175   #endif
    176 #endif
    177 
    178 ////////////////////////////////////////////////////////////////////////////////////////
    179 // Define the CS (TFT chip select) pin drive code
    180 ////////////////////////////////////////////////////////////////////////////////////////
    181 #ifndef TFT_CS
    182   #define CS_L // No macro allocated so it generates no code
    183   #define CS_H // No macro allocated so it generates no code
    184 #else
    185   #if !defined (RP2040_PIO_INTERFACE) // SPI
    186     #if  defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
    187       #define CS_L digitalWrite(TFT_CS, LOW);
    188       #define CS_H digitalWrite(TFT_CS, HIGH);
    189     #else
    190       #define CS_L sio_hw->gpio_clr = (1ul << TFT_CS)
    191       #define CS_H sio_hw->gpio_set = (1ul << TFT_CS)
    192     #endif
    193   #else // PIO interface display
    194     #define CS_L sio_hw->gpio_clr = (1ul << TFT_CS)
    195     #define CS_H WAIT_FOR_STALL; sio_hw->gpio_set = (1ul << TFT_CS)
    196   #endif
    197 #endif
    198 
    199 ////////////////////////////////////////////////////////////////////////////////////////
    200 // Make sure TFT_RD is defined if not used to avoid an error message
    201 ////////////////////////////////////////////////////////////////////////////////////////
    202 // At the moment read is not supported for parallel mode, tie TFT signal high
    203 #ifdef TFT_RD
    204   #if (TFT_RD >= 0)
    205     #define RD_L sio_hw->gpio_clr = (1ul << TFT_RD)
    206     //#define RD_L digitalWrite(TFT_WR, LOW)
    207     #define RD_H sio_hw->gpio_set = (1ul << TFT_RD)
    208     //#define RD_H digitalWrite(TFT_WR, HIGH)
    209   #else
    210     #define RD_L
    211     #define RD_H
    212   #endif
    213 #else
    214   #define TFT_RD -1
    215   #define RD_L
    216   #define RD_H
    217 #endif
    218 
    219 ////////////////////////////////////////////////////////////////////////////////////////
    220 // Define the WR (TFT Write) pin drive code
    221 ////////////////////////////////////////////////////////////////////////////////////////
    222 #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT) // SPI
    223   #ifdef TFT_WR
    224     #define WR_L digitalWrite(TFT_WR, LOW)
    225     #define WR_H digitalWrite(TFT_WR, HIGH)
    226   #endif
    227 #else
    228   // The PIO manages the write line
    229 #endif
    230 
    231 ////////////////////////////////////////////////////////////////////////////////////////
    232 // Define the touch screen chip select pin drive code
    233 ////////////////////////////////////////////////////////////////////////////////////////
    234 #if !defined (RP2040_PIO_INTERFACE)// SPI
    235   #if !defined TOUCH_CS || (TOUCH_CS < 0)
    236     #define T_CS_L // No macro allocated so it generates no code
    237     #define T_CS_H // No macro allocated so it generates no code
    238   #else
    239     #define T_CS_L digitalWrite(TOUCH_CS, LOW)
    240     #define T_CS_H digitalWrite(TOUCH_CS, HIGH)
    241   #endif
    242 #else
    243   #ifdef TOUCH_CS
    244     #error Touch screen not supported in parallel or SPI PIO mode, use a separate library.
    245   #endif
    246 #endif
    247 
    248 ////////////////////////////////////////////////////////////////////////////////////////
    249 // Make sure TFT_MISO is defined if not used to avoid an error message
    250 ////////////////////////////////////////////////////////////////////////////////////////
    251 #ifndef TFT_MISO
    252   #define TFT_MISO -1
    253 #endif
    254 
    255 ////////////////////////////////////////////////////////////////////////////////////////
    256 // Macros to write commands/pixel colour data to a SPI ILI948x TFT
    257 ////////////////////////////////////////////////////////////////////////////////////////
    258 #if !defined (RP2040_PIO_INTERFACE) // SPI
    259 
    260   #if  defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
    261 
    262     // Write 8 bits to TFT
    263     #define tft_Write_8(C)      spi_get_hw(SPI_X)->dr = (uint32_t)(C); \
    264                                 while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
    265 
    266     //#define tft_Write_8(C)   spi.transfer(C);
    267     #define tft_Write_8N(B)   while (!spi_is_writable(SPI_X)){}; \
    268                              spi_get_hw(SPI_X)->dr = (uint8_t)(B)
    269 
    270     // Convert 16 bit colour to 18 bit and write in 3 bytes
    271     #define tft_Write_16(C)  tft_Write_8N(((C) & 0xF800)>>8); \
    272                              tft_Write_8N(((C) & 0x07E0)>>3); \
    273                              tft_Write_8N(((C) & 0x001F)<<3)
    274 
    275     // Convert 16 bit colour to 18 bit and write in 3 bytes
    276     #define tft_Write_16N(C)  tft_Write_8N(((C) & 0xF800)>>8); \
    277                               tft_Write_8N(((C) & 0x07E0)>>3); \
    278                               tft_Write_8N(((C) & 0x001F)<<3)
    279 
    280     // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
    281     #define tft_Write_16S(C) tft_Write_8N((C) & 0xF8); \
    282                              tft_Write_8N(((C) & 0xE000)>>11 | ((C) & 0x07)<<5); \
    283                              tft_Write_8N(((C) & 0x1F00)>>5)
    284     // Write 32 bits to TFT
    285     #define tft_Write_32(C)  tft_Write_8N(C>>24); \
    286                              tft_Write_8N(C>>16); \
    287                              tft_Write_8N(C>>8);  \
    288                              tft_Write_8N(C)
    289 
    290     // Write two address coordinates
    291     #define tft_Write_32C(C,D) tft_Write_8N(C>>8); \
    292                                tft_Write_8N(C);    \
    293                                tft_Write_8N(D>>8); \
    294                                tft_Write_8N(D)
    295 
    296     // Write same value twice
    297     #define tft_Write_32D(C) tft_Write_8N(C>>8); \
    298                              tft_Write_8N(C);    \
    299                              tft_Write_8N(C>>8); \
    300                              tft_Write_8N(C)
    301 
    302   ////////////////////////////////////////////////////////////////////////////////////////
    303   // Macros to write commands/pixel colour data to other displays
    304   ////////////////////////////////////////////////////////////////////////////////////////
    305   #else
    306     #if  defined (MHS_DISPLAY_TYPE) // High speed RPi TFT type always needs 16 bit transfers
    307       // This swaps to 16 bit mode, used for commands so wait avoids clash with DC timing
    308       #define tft_Write_8(C)      while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
    309                                   hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS); \
    310                                   spi_get_hw(SPI_X)->dr = (uint32_t)((C) | ((C)<<8)); \
    311                                   while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
    312 
    313       // Note: the following macros do not wait for the end of transmission
    314 
    315       #define tft_Write_16(C)     while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    316 
    317       #define tft_Write_16N(C)    while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    318 
    319       #define tft_Write_16S(C)    while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)<<8 | (C)>>8
    320 
    321       #define tft_Write_32(C)     spi_get_hw(SPI_X)->dr = (uint32_t)((C)>>16); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    322 
    323       #define tft_Write_32C(C,D)  spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(D)
    324 
    325       #define tft_Write_32D(C)    spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    326 
    327     #elif  defined (RPI_DISPLAY_TYPE) // RPi TFT type always needs 16 bit transfers
    328       #define tft_Write_8(C)   spi.transfer(C); spi.transfer(C)
    329       #define tft_Write_16(C)  spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))
    330       #define tft_Write_16N(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))
    331       #define tft_Write_16S(C) spi.transfer((uint8_t)((C)>>0));spi.transfer((uint8_t)((C)>>8))
    332 
    333       #define tft_Write_32(C) \
    334         tft_Write_16((uint16_t) ((C)>>16)); \
    335         tft_Write_16((uint16_t) ((C)>>0))
    336 
    337       #define tft_Write_32C(C,D) \
    338         spi.transfer(0); spi.transfer((C)>>8); \
    339         spi.transfer(0); spi.transfer((C)>>0); \
    340         spi.transfer(0); spi.transfer((D)>>8); \
    341         spi.transfer(0); spi.transfer((D)>>0)
    342 
    343       #define tft_Write_32D(C) \
    344         spi.transfer(0); spi.transfer((C)>>8); \
    345         spi.transfer(0); spi.transfer((C)>>0); \
    346         spi.transfer(0); spi.transfer((C)>>8); \
    347         spi.transfer(0); spi.transfer((C)>>0)
    348 
    349     #elif  defined (ILI9225_DRIVER) // Needs gaps between commands + data bytes, so use slower transfer functions
    350 
    351       // Warning: these all end in 8 bit SPI mode!
    352       #define tft_Write_8(C)      spi.transfer(C);
    353 
    354       #define tft_Write_16(C)     spi.transfer16(C)
    355 
    356       #define tft_Write_16N(C)    spi.transfer16(C)
    357 
    358       #define tft_Write_16S(C)    spi.transfer16((C)<<8 | (C)>>8)
    359 
    360       #define tft_Write_32(C)     spi.transfer16((C)>>16); spi.transfer16(C)
    361 
    362       #define tft_Write_32C(C,D)  spi.transfer16(C); spi.transfer16(D)
    363 
    364       #define tft_Write_32D(C)    spi.transfer16(C); spi.transfer16(C)
    365 
    366     #else
    367 
    368       // This swaps to 8 bit mode, then back to 16 bit mode
    369       #define tft_Write_8(C)      while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
    370                                   hw_write_masked(&spi_get_hw(SPI_X)->cr0, (8 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS); \
    371                                   spi_get_hw(SPI_X)->dr = (uint32_t)(C); \
    372                                   while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
    373                                   hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS)
    374 
    375       // Note: the following macros do not wait for the end of transmission
    376 
    377       #define tft_Write_16(C)     while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    378 
    379       #define tft_Write_16N(C)    while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    380 
    381       #define tft_Write_16S(C)    while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)<<8 | (C)>>8
    382 
    383       #define tft_Write_32(C)     spi_get_hw(SPI_X)->dr = (uint32_t)((C)>>16); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    384 
    385       #define tft_Write_32C(C,D)  spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(D)
    386 
    387       #define tft_Write_32D(C)    spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
    388 
    389     #endif // RPI_DISPLAY_TYPE
    390   #endif
    391 
    392 #else // Parallel 8 bit or PIO SPI
    393 
    394   // Wait for the PIO to stall (SM pull request finds no data in TX FIFO)
    395   // This is used to detect when the SM is idle and hence ready for a jump instruction
    396   #define WAIT_FOR_STALL  tft_pio->fdebug = pull_stall_mask; while (!(tft_pio->fdebug & pull_stall_mask))
    397 
    398   // Wait until at least "S" locations free
    399   #define WAIT_FOR_FIFO_FREE(S) while (((tft_pio->flevel >> (pio_sm * 8)) & 0x000F) > (8-S)){}
    400 
    401   // Wait until at least 5 locations free
    402   #define WAIT_FOR_FIFO_5_FREE while ((tft_pio->flevel) & (0x000c << (pio_sm * 8))){}
    403 
    404   // Wait until at least 1 location free
    405   #define WAIT_FOR_FIFO_1_FREE while ((tft_pio->flevel) & (0x0008 << (pio_sm * 8))){}
    406 
    407   // Wait for FIFO to empty (use before swapping to 8 bits)
    408   #define WAIT_FOR_FIFO_EMPTY  while(!(tft_pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + pio_sm))))
    409 
    410   // The write register of the TX FIFO.
    411   #define TX_FIFO  tft_pio->txf[pio_sm]
    412 
    413   // Temporary - to be deleted
    414   #define GPIO_DIR_MASK 0
    415 
    416   #if  defined (SPI_18BIT_DRIVER)  || defined (SSD1963_DRIVER) // 18 bit colour (3 bytes)
    417       // This writes 8 bits, then switches back to 16 bit mode automatically
    418       // Have already waited for pio stalled (last data write complete) when DC switched to command mode
    419       // The wait for stall allows DC to be changed immediately afterwards
    420       #define tft_Write_8(C)      tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
    421                                   TX_FIFO = (C); \
    422                                   WAIT_FOR_STALL
    423 
    424       // Used to send last byte for 32 bit macros below since PIO sends 24 bits
    425       #define tft_Write_8L(C)     WAIT_FOR_STALL; \
    426                                   tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
    427                                   TX_FIFO = (C)
    428 
    429       // Note: the following macros do not wait for the end of transmission
    430 
    431       #define tft_Write_16(C)     WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF800)<<8) | (((C) & 0x07E0)<<5) | (((C) & 0x001F)<<3))
    432 
    433       #define tft_Write_16N(C)    WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF800)<<8) | (((C) & 0x07E0)<<5) | (((C) & 0x001F)<<3))
    434 
    435       #define tft_Write_16S(C)    WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF8) << 16) | (((C) & 0xE000)>>3) | (((C) & 0x07)<<13) | (((C) & 0x1F00)>>5))
    436 
    437       #define tft_Write_32(C)     WAIT_FOR_FIFO_FREE(2); TX_FIFO = ((C)>>8); WAIT_FOR_STALL; tft_Write_8(C)
    438 
    439       #define tft_Write_32C(C,D)  WAIT_FOR_FIFO_FREE(2); TX_FIFO = (((C)<<8) | ((D)>>8)); tft_Write_8L(D)
    440 
    441       #define tft_Write_32D(C)    WAIT_FOR_FIFO_FREE(2); TX_FIFO = (((C)<<8) | ((C)>>8)); tft_Write_8L(C)
    442 
    443   #else // PIO interface, SPI or parallel
    444     // This writes 8 bits, then switches back to 16 bit mode automatically
    445     // Have already waited for pio stalled (last data write complete) when DC switched to command mode
    446     // The wait for stall allows DC to be changed immediately afterwards
    447     #if defined (TFT_PARALLEL_8_BIT) || defined (RP2040_PIO_SPI)
    448       #define tft_Write_8(C)      tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
    449                                   TX_FIFO = (C); \
    450                                   WAIT_FOR_STALL
    451     #else // For 16 bit parallel 16 bits are always sent
    452       #define tft_Write_8(C)      TX_FIFO = (C); \
    453                                   WAIT_FOR_STALL
    454     #endif
    455 
    456       // Note: the following macros do not wait for the end of transmission
    457 
    458       #define tft_Write_16(C)     WAIT_FOR_FIFO_FREE(1); TX_FIFO = (C)
    459 
    460       #define tft_Write_16N(C)    WAIT_FOR_FIFO_FREE(1); TX_FIFO = (C)
    461 
    462       #define tft_Write_16S(C)    WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((C)<<8) | ((C)>>8)
    463 
    464       #define tft_Write_32(C)     WAIT_FOR_FIFO_FREE(2); TX_FIFO = ((C)>>16); TX_FIFO = (C)
    465 
    466       #define tft_Write_32C(C,D)  WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (D)
    467 
    468       #define tft_Write_32D(C)    WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (C)
    469   #endif
    470 #endif
    471 
    472 #ifndef tft_Write_16N
    473   #define tft_Write_16N tft_Write_16
    474 #endif
    475 
    476 ////////////////////////////////////////////////////////////////////////////////////////
    477 // Macros to read from display using SPI or software SPI
    478 ////////////////////////////////////////////////////////////////////////////////////////
    479 #if !defined (RP2040_PIO_INTERFACE)// SPI
    480   #if defined (TFT_SDA_READ)
    481     // Use a bit banged function call for STM32 and bi-directional SDA pin
    482     #define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8(void);
    483     #define SCLK_L digitalWrite(TFT_SCLK, LOW)
    484     #define SCLK_H digitalWrite(TFT_SCLK, LOW)
    485   #else
    486     // Use a SPI read transfer
    487     #define tft_Read_8() spi.transfer(0)
    488   #endif
    489 #endif
    490 ////////////////////////////////////////////////////////////////////////////////////////
    491 // Temporary to keep the "Arduino Mbed OS RP2040 Boards" support package happy
    492 ////////////////////////////////////////////////////////////////////////////////////////
    493 #if defined(ARDUINO_ARCH_RP2040)
    494 
    495   #define ltoa itoa
    496 
    497 #endif
    498 
    499 #endif // Header end