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_STM32.h (51263B)

      1         ////////////////////////////////////////////////////
      2         // TFT_eSPI driver functions for STM32 processors //
      3         ////////////////////////////////////////////////////
      4 
      5 #ifndef _TFT_eSPI_STM32H_
      6 #define _TFT_eSPI_STM32H_
      7 
      8 // Processor ID reported by getSetup()
      9 #define PROCESSOR_ID 0x32F
     10 
     11 // Include processor specific header
     12 // None
     13 
     14 // RPi support not tested - Fast RPi not supported
     15 
     16 // Processor specific code used by SPI bus transaction startWrite and endWrite functions
     17 #define SET_BUS_WRITE_MODE // Not used
     18 #define SET_BUS_READ_MODE  // Not used
     19 
     20 // SUPPORT_TRANSACTIONS is mandatory for STM32
     21 #if !defined (SUPPORT_TRANSACTIONS)
     22   #define SUPPORT_TRANSACTIONS
     23 #endif
     24 
     25 ////////////////////////////////////////////////////////////////////////////////////////
     26 // Define the parallel bus interface chip pin drive code
     27 ////////////////////////////////////////////////////////////////////////////////////////
     28 #if defined(TFT_PARALLEL_8_BIT)
     29 
     30   // The STM32 processors can toggle pins fast, TFTs need setup and hold times
     31   // for writes so here twc can be extended  with delays:
     32   //
     33   //                       0 1 2 3 4 5     Extra high periods
     34   // TFT_WR ¯|_ _ _ _ _ _ |¯ ¯ ¯ ¯ ¯ ¯ ¯|
     35   //            5 4 3 2 1 0                Extra low periods
     36   //        xxxx=======================xxxx
     37   //         |<---------- twc --------->|
     38   //           |<- tdst ->|<-- tdht -->|
     39   //
     40   // Data is placed bit by bit on bus during period xxxx and TFT_WR driven low
     41   // Period xxxx depends on D0-D7 pin allocations and bit manipulation needed
     42   // Data stable during period ===
     43   // Most TFTs can be "overclocked" and run >2x faster than data sheet figures
     44 
     45 ////////////////////////////////////////////////////////////////////////////////////////
     46 // Write strobe timing setup
     47 ////////////////////////////////////////////////////////////////////////////////////////
     48   #if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER) || defined (ST7796_DRIVER)   || defined (ILI9486_DRIVER) // WRX twc spec is <=66ns = 15.15MHz
     49 
     50     // Extra write pulse low time (delay for data setup)
     51     #if defined (STM32F1xx)
     52       #define WR_TWRL_0       // Change to WR_TWRL_1 if overclocking processor
     53     #elif defined (STM32F2xx) || defined (STM32F4xx)
     54       #define WR_TWRL_0       // Tested with STM32F446 - 27.6MHz when WR_TWRH_1 defined
     55       //#define WR_TWRL_3     // STM32F446 - 15.6MHz when WR_TWRH_3 defined
     56     #elif defined (STM32F7xx)
     57       #define WR_TWRL_1       //Tested with STM32F767
     58     #else
     59       #define WR_TWRL_5
     60     #endif
     61 
     62     // Extra write pulse high time (data hold time, delays next write cycle start)
     63     #if defined (STM32F1xx)
     64       #define WR_TWRH_0
     65     #elif defined (STM32F2xx) || defined (STM32F4xx)
     66       #define WR_TWRH_0       // Tested with STM32F446
     67       //#define WR_TWRL_3
     68     #elif defined (STM32F7xx)
     69       #define WR_TWRH_1       //Tested with STM32F767
     70     #else
     71       #define WR_TWRH_5
     72     #endif
     73 
     74   #elif defined (ILI9481_DRIVER) // WRX twc spec is 100ns = 10MHz
     75 
     76     // Extra write pulse low time (delay for data setup)
     77     #if defined (STM32F1xx)
     78       #define WR_TWRL_0
     79     #elif defined (STM32F2xx) || defined (STM32F4xx)
     80       //#define WR_TWRL_0    // STM32F446 - ~30MHz when WR_TWRH_0 defined
     81       //#define WR_TWRL_1    // STM32F446 - ~25MHz when WR_TWRH_0 defined
     82       #define WR_TWRL_2      // STM32F446 - ~20MHz when WR_TWRH_2 defined
     83       //#define WR_TWRL_3    // STM32F446 - ~16MHz when WR_TWRH_3 defined
     84       //#define WR_TWRL_4
     85       //#define WR_TWRL_5    // STM32F446 - ~12MHz when WR_TWRH_5 defined
     86     #elif defined (STM32F7xx)
     87       //#define WR_TWRL_0
     88       //#define WR_TWRL_1
     89       //#define WR_TWRL_2
     90       #define WR_TWRL_3
     91     #else
     92       //#define WR_TWRH_0    // Fastest
     93       //#define WR_TWRH_1
     94       //#define WR_TWRH_2
     95       #define WR_TWRH_3      // Slowest
     96     #endif
     97 
     98     // Extra write pulse high time (data hold time, delays next write cycle start)
     99     #if defined (STM32F1xx)
    100       #define WR_TWRH_0
    101     #elif defined (STM32F2xx) || defined (STM32F4xx)
    102       //#define WR_TWRH_0
    103       //#define WR_TWRH_1
    104       #define WR_TWRH_2
    105       //#define WR_TWRH_3
    106     #elif defined (STM32F7xx)
    107       //#define WR_TWRH_0
    108       //#define WR_TWRH_1
    109       //#define WR_TWRH_2
    110       #define WR_TWRH_3
    111       //#define WR_TWRH_4
    112       //#define WR_TWRH_5
    113     #else
    114       //#define WR_TWRH_0     // Fastest
    115       //#define WR_TWRH_1
    116       //#define WR_TWRH_2
    117       #define WR_TWRH_3       // Slowest
    118     #endif
    119 
    120   #else // Default display slow settings
    121     #if defined (STM32F1xx)
    122       // STM32F1xx series can run at full speed (unless overclocked)
    123       #define WR_TWRL_0
    124       #define WR_TWRH_0
    125     #else
    126       // Extra write pulse low time (delay for data setup)
    127       //#define WR_TWRL_0
    128       //#define WR_TWRL_1
    129       //#define WR_TWRL_2
    130       #define WR_TWRL_3
    131       //#define WR_TWRL_4
    132       //#define WR_TWRL_5
    133 
    134       // Extra write pulse high time (data hold time, delays next write cycle start)
    135       //#define WR_TWRH_0
    136       //#define WR_TWRH_1
    137       //#define WR_TWRH_2
    138       //#define WR_TWRH_3
    139       //#define WR_TWRH_4
    140       #define WR_TWRH_5
    141     #endif
    142   #endif
    143 
    144 ////////////////////////////////////////////////////////////////////////////////////////
    145 // Macros for all other SPI displays
    146 ////////////////////////////////////////////////////////////////////////////////////////
    147 #else
    148 
    149   // Use SPI1 as default if not defined
    150   #ifndef TFT_SPI_PORT
    151     #define TFT_SPI_PORT 1
    152   #endif
    153 
    154   // Global define is _VARIANT_ARDUINO_STM32_, see board package stm32_def.h for specific variants
    155   #if defined (STM32F2xx) || defined (STM32F4xx) || defined (STM32F7xx)
    156 
    157     #define STM32_DMA // DMA is available with these processors
    158 
    159     #if (TFT_SPI_PORT == 1)
    160       // Initialise processor specific SPI and DMA instances - used by init()
    161       #define INIT_TFT_DATA_BUS spiHal.Instance = SPI1; \
    162                                 dmaHal.Instance = DMA2_Stream3
    163       // The DMA hard-coding for SPI1 is in TFT_eSPI_STM32.c as follows:
    164       //     DMA_CHANNEL_3
    165       //     DMA2_Stream3_IRQn and DMA2_Stream3_IRQHandler()
    166     #elif (TFT_SPI_PORT == 2)
    167       // Initialise processor specific SPI and DMA instances - used by init()
    168       #define INIT_TFT_DATA_BUS spiHal.Instance = SPI2; \
    169                                 dmaHal.Instance = DMA1_Stream4
    170       // The DMA hard-coding for SPI2 is in TFT_eSPI_STM32.c as follows:
    171       //     DMA_CHANNEL_4
    172       //     DMA1_Stream4_IRQn and DMA1_Stream4_IRQHandler()
    173     #elif (TFT_SPI_PORT == 3)
    174       // Initialise processor specific SPI and DMA instances - used by init()
    175       #define INIT_TFT_DATA_BUS spiHal.Instance = SPI3; \
    176                                 dmaHal.Instance = DMA1_Stream5
    177       // The DMA hard-coding for SPI3 is in TFT_eSPI_STM32.c as follows:
    178       //     DMA_CHANNEL_4
    179       //     DMA1_Stream5_IRQn and DMA1_Stream5_IRQHandler()
    180     #endif
    181 
    182   #elif defined (STM32F1xx)
    183     // For Blue Pill and STM32F1xx processors with DMA support
    184     #define STM32_DMA // DMA is available with these processors
    185     #if (TFT_SPI_PORT == 1)
    186       #define INIT_TFT_DATA_BUS spiHal.Instance = SPI1; \
    187                                 dmaHal.Instance = DMA1_Channel3
    188     #elif (TFT_SPI_PORT == 2)
    189       #define INIT_TFT_DATA_BUS spiHal.Instance = SPI2; \
    190                                 dmaHal.Instance = DMA1_Channel5
    191     #endif
    192   #else
    193     // For STM32 processor with no implemented DMA support (yet)
    194     #if (TFT_SPI_PORT == 1)
    195       #define INIT_TFT_DATA_BUS spiHal.Instance = SPI1
    196     #elif (TFT_SPI_PORT == 2)
    197       #define INIT_TFT_DATA_BUS spiHal.Instance = SPI2
    198     #endif
    199   #endif
    200 
    201 #endif
    202 
    203 #ifdef STM32_DMA
    204   // Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
    205   #define DMA_BUSY_CHECK { if (DMA_Enabled) while(dmaBusy()); }
    206 #else
    207   #define DMA_BUSY_CHECK
    208 #endif
    209 
    210 // If smooth fonts are enabled the filing system may need to be loaded
    211 #ifdef SMOOTH_FONT
    212   // Call up the filing system for the anti-aliased fonts                                    <<<==== TODO
    213   //#define FS_NO_GLOBALS
    214   //#include <FS.h>
    215 #endif // end of parallel/SPI selection
    216 
    217 ////////////////////////////////////////////////////////////////////////////////////////
    218 // Define the DC (TFT Data/Command or Register Select (RS))pin drive code
    219 ////////////////////////////////////////////////////////////////////////////////////////
    220 #if !defined (TFT_DC) || (TFT_DC < 0)
    221   #define DC_C // No macro allocated so it generates no code
    222   #define DC_D // No macro allocated so it generates no code
    223   #undef  TFT_DC
    224 #else
    225   // Convert Arduino pin reference Dn or STM pin reference PXn to port and mask
    226   #define DC_PORT     digitalPinToPort(TFT_DC)
    227   #define DC_PIN_MASK digitalPinToBitMask(TFT_DC)
    228   // Use bit set reset register
    229   #define DC_C DC_PORT->BSRR = DC_PIN_MASK<<16
    230   #define DC_D DC_PORT->BSRR = DC_PIN_MASK
    231 #endif
    232 
    233 ////////////////////////////////////////////////////////////////////////////////////////
    234 // Define the CS (TFT chip select) pin drive code
    235 ////////////////////////////////////////////////////////////////////////////////////////
    236 #if !defined (TFT_CS) || (TFT_CS < 0)
    237   #define CS_L // No macro allocated so it generates no code
    238   #define CS_H // No macro allocated so it generates no code
    239   #undef  TFT_CS
    240 #else
    241   // Convert Arduino pin reference Dx or STM pin reference PXn to port and mask
    242   #define CS_PORT      digitalPinToPort(TFT_CS)
    243   #define CS_PIN_MASK  digitalPinToBitMask(TFT_CS)
    244   // Use bit set reset register
    245   #define CS_L CS_PORT->BSRR = CS_PIN_MASK<<16
    246   #define CS_H CS_PORT->BSRR = CS_PIN_MASK
    247 #endif
    248 
    249 ////////////////////////////////////////////////////////////////////////////////////////
    250 // Define the RD (TFT Read) pin drive code
    251 ////////////////////////////////////////////////////////////////////////////////////////
    252 #ifdef TFT_RD
    253   #if (TFT_RD >= 0)
    254     // Convert Arduino pin reference Dx or STM pin reference PXn to port and mask
    255     #define RD_PORT      digitalPinToPort(TFT_RD)
    256     #define RD_PIN_MASK  digitalPinToBitMask(TFT_RD)
    257     // Use bit set reset register
    258     #define RD_L RD_PORT->BSRR = RD_PIN_MASK<<16
    259     #define RD_H RD_PORT->BSRR = RD_PIN_MASK
    260   #else
    261     #define RD_L
    262     #define RD_H
    263   #endif
    264 #else
    265   #define TFT_RD -1
    266   #define RD_L
    267   #define RD_H
    268 #endif
    269 
    270 ////////////////////////////////////////////////////////////////////////////////////////
    271 // Define the WR (TFT Write) pin drive code
    272 ////////////////////////////////////////////////////////////////////////////////////////
    273 #ifdef TFT_WR
    274   // Convert Arduino pin reference Dx or STM pin reference PXn to port and mask
    275   #define WR_PORT      digitalPinToPort(TFT_WR)
    276   #define WR_PIN_MASK  digitalPinToBitMask(TFT_WR)
    277   // Use bit set reset register
    278   #define WR_L WR_PORT->BSRR = WR_PIN_MASK<<16
    279   #define WR_H WR_PORT->BSRR = WR_PIN_MASK
    280 #endif
    281 
    282 ////////////////////////////////////////////////////////////////////////////////////////
    283 // Define the touch screen chip select pin drive code
    284 ////////////////////////////////////////////////////////////////////////////////////////
    285 #if !defined (TOUCH_CS) || (TOUCH_CS < 0)
    286   #define T_CS_L // No macro allocated so it generates no code
    287   #define T_CS_H // No macro allocated so it generates no code
    288 #else
    289   // Speed is not important for this signal
    290   #define T_CS_L digitalWrite(TOUCH_CS, LOW)
    291   #define T_CS_H digitalWrite(TOUCH_CS, HIGH)
    292 #endif
    293 
    294 ////////////////////////////////////////////////////////////////////////////////////////
    295 // Make sure TFT_MISO is defined if not used to avoid an error message
    296 ////////////////////////////////////////////////////////////////////////////////////////
    297 #if !defined (TFT_PARALLEL_8_BIT)
    298   #ifndef TFT_MISO
    299     #define TFT_MISO -1
    300   #endif
    301 #endif
    302 
    303 ////////////////////////////////////////////////////////////////////////////////////////
    304 // Define the parallel bus interface chip pin drive code
    305 ////////////////////////////////////////////////////////////////////////////////////////
    306 #if defined (TFT_PARALLEL_8_BIT)
    307 
    308   // Mask for the 8 data bits to set pin directions (not used)
    309   #define GPIO_DIR_MASK 0
    310 
    311   #define PARALLEL_INIT_TFT_DATA_BUS // None
    312 
    313   #define INIT_TFT_DATA_BUS // Setup built into TFT_eSPI.cpp
    314 
    315 ////////////////////////////////////////////////////////////////////////////////////////
    316 // Define the TFT_WR drive cycle timing
    317 ////////////////////////////////////////////////////////////////////////////////////////
    318   // Write low extra setup time
    319   #if   defined WR_TWRL_0
    320     #define     WR_TWRL
    321   #elif defined WR_TWRL_1 // 1 extra low period
    322     #define     WR_TWRL WR_L
    323   #elif defined WR_TWRL_2 // 2 extra low periods
    324     #define     WR_TWRL WR_L; WR_L
    325   #elif defined WR_TWRL_3 // 3 extra low periods
    326     #define     WR_TWRL WR_L; WR_L; WR_L
    327   #elif defined WR_TWRL_4 // 4 extra low periods
    328     #define     WR_TWRL WR_L; WR_L; WR_L; WR_L
    329   #elif defined WR_TWRL_5 // 5 extra low periods
    330     #define     WR_TWRL WR_L; WR_L; WR_L; WR_L; WR_L
    331   #endif
    332 
    333   // Write high extra hold time
    334   #if   defined WR_TWRH_0
    335     #define     WR_TWRH WR_H
    336   #elif defined WR_TWRH_1 // 1 extra high period
    337     #define     WR_TWRH  WR_H; WR_H
    338   #elif defined WR_TWRH_2 // 2 extra high periods
    339     #define     WR_TWRH  WR_H; WR_H; WR_H
    340   #elif defined WR_TWRH_3 // 3 extra high periods
    341     #define     WR_TWRH  WR_H; WR_H; WR_H; WR_H
    342   #elif defined WR_TWRH_4 // 4 extra high periods
    343     #define     WR_TWRH  WR_H; WR_H; WR_H; WR_H; WR_H
    344   #elif defined WR_TWRH_5 // 5 extra high periods
    345     #define     WR_TWRH  WR_H; WR_H; WR_H; WR_H; WR_H; WR_H
    346   #endif
    347 
    348   #define WR_STB WR_TWRL; WR_TWRH // Rising edge write strobe
    349 
    350 ////////////////////////////////////////////////////////////////////////////////////////
    351 // Nucleo 64: hard-coded pins
    352 ////////////////////////////////////////////////////////////////////////////////////////
    353   #ifdef NUCLEO_64_TFT
    354 
    355     // Convert Arduino pin reference Dx or STM pin reference PXn to port and mask
    356     #define D0_PIN_NAME  digitalPinToPinName(TFT_D0)
    357     #define D1_PIN_NAME  digitalPinToPinName(TFT_D1)
    358     #define D2_PIN_NAME  digitalPinToPinName(TFT_D2)
    359     #define D3_PIN_NAME  digitalPinToPinName(TFT_D3)
    360     #define D4_PIN_NAME  digitalPinToPinName(TFT_D4)
    361     #define D5_PIN_NAME  digitalPinToPinName(TFT_D5)
    362     #define D6_PIN_NAME  digitalPinToPinName(TFT_D6)
    363     #define D7_PIN_NAME  digitalPinToPinName(TFT_D7)
    364 
    365     // Pin port bit number 0-15 (not used for Nucleo)
    366     #define D0_PIN_BIT  (D0_PIN_NAME & 0xF)
    367     #define D1_PIN_BIT  (D1_PIN_NAME & 0xF)
    368     #define D2_PIN_BIT  (D2_PIN_NAME & 0xF)
    369     #define D3_PIN_BIT  (D3_PIN_NAME & 0xF)
    370     #define D4_PIN_BIT  (D4_PIN_NAME & 0xF)
    371     #define D5_PIN_BIT  (D5_PIN_NAME & 0xF)
    372     #define D6_PIN_BIT  (D6_PIN_NAME & 0xF)
    373     #define D7_PIN_BIT  (D7_PIN_NAME & 0xF)
    374 
    375     // Pin port - better than get_GPIO_Port() which seems to be slow...
    376     #define D0_PIN_PORT GPIOA
    377     #define D1_PIN_PORT GPIOC
    378     #define D2_PIN_PORT GPIOA
    379     #define D3_PIN_PORT GPIOB
    380     #define D4_PIN_PORT GPIOB
    381     #define D5_PIN_PORT GPIOB
    382     #define D6_PIN_PORT GPIOB
    383     #define D7_PIN_PORT GPIOA
    384 
    385     // Pin masks for set/clear
    386     #define D0_PIN_MASK (1UL<< 9) // Set/clear mask for PA9
    387     #define D1_PIN_MASK (1UL<< 7) // Set/clear mask for PC7
    388     #define D2_PIN_MASK (1UL<<10) // Set/clear mask for PA10
    389     #define D3_PIN_MASK (1UL<< 3) // Set/clear mask for PB3
    390     #define D4_PIN_MASK (1UL<< 5) // Set/clear mask for PB5
    391     #define D5_PIN_MASK (1UL<< 4) // Set/clear mask for PB4
    392     #define D6_PIN_MASK (1UL<<10) // Set/clear mask for PB10
    393     #define D7_PIN_MASK (1UL<< 8) // Set/clear mask for PA8
    394 
    395     // Create bit set/reset mask based on LS byte of value B
    396     #define  D0_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)<< 4)&0x10))
    397     #define  D1_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)<< 3)&0x10))
    398     #define  D2_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)<< 2)&0x10))
    399     #define  D3_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)<< 1)&0x10))
    400     #define  D4_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)<< 0)&0x10))
    401     #define  D5_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 1)&0x10))
    402     #define  D6_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>> 2)&0x10))
    403     #define  D7_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>> 3)&0x10))
    404     // Create bit set/reset mask for top byte of 16 bit value B
    405     #define  D8_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)>> 4)&0x10))
    406     #define  D9_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)>> 5)&0x10))
    407     #define D10_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)>> 6)&0x10))
    408     #define D11_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)>> 7)&0x10))
    409     #define D12_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)>> 8)&0x10))
    410     #define D13_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 9)&0x10))
    411     #define D14_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>>10)&0x10))
    412     #define D15_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>>11)&0x10))
    413 
    414     // Write 8 bits to TFT
    415     #define tft_Write_8(C)   GPIOA->BSRR = D0_BSR_MASK(C) | D2_BSR_MASK(C) | D7_BSR_MASK(C); \
    416                              WR_L; \
    417                              GPIOC->BSRR = D1_BSR_MASK(C); \
    418                              GPIOB->BSRR = D3_BSR_MASK(C) | D4_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    419                              WR_STB // Need to slow down strobe
    420 
    421     #if defined (SSD1963_DRIVER)
    422 
    423       // Write 18 bit color to TFT (untested)
    424       #define tft_Write_16(C)  r6 = (((C) & 0xF800)>> 8); g6 = (((C) & 0x07E0)>> 3); b6 = (((C) & 0x001F)<< 3); \
    425                                GPIOA->BSRR = D0_BSR_MASK(r6) | D2_BSR_MASK(r6) | D7_BSR_MASK(r6); \
    426                                WR_L; \
    427                                GPIOC->BSRR = D1_BSR_MASK(r6); \
    428                                GPIOB->BSRR = D3_BSR_MASK(r6) | D4_BSR_MASK(r6) | D5_BSR_MASK(r6) | D6_BSR_MASK(r6); \
    429                                WR_STB; \
    430                                GPIOA->BSRR = D0_BSR_MASK(g6) | D2_BSR_MASK(g6) | D7_BSR_MASK(g6); \
    431                                WR_L; \
    432                                GPIOC->BSRR = D1_BSR_MASK(g6); \
    433                                GPIOB->BSRR = D3_BSR_MASK(g6) | D4_BSR_MASK(g6) | D5_BSR_MASK(g6) | D6_BSR_MASK(g6); \
    434                                WR_STB; \
    435                                GPIOA->BSRR = D0_BSR_MASK(b6) | D2_BSR_MASK(b6) | D7_BSR_MASK(b6); \
    436                                WR_L; \
    437                                GPIOC->BSRR = D1_BSR_MASK(b6); \
    438                                GPIOB->BSRR = D3_BSR_MASK(b6) | D4_BSR_MASK(b6) | D5_BSR_MASK(b6) | D6_BSR_MASK(b6); \
    439                                WR_STB // Need to slow down strobe
    440 
    441       // 18 bit color write with swapped bytes
    442       #define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
    443 
    444     #else
    445       // Write 16 bits to TFT
    446       #define tft_Write_16(C)  GPIOA->BSRR = D8_BSR_MASK(C) | D10_BSR_MASK(C) | D15_BSR_MASK(C); \
    447                                WR_L; \
    448                                GPIOC->BSRR = D9_BSR_MASK(C); \
    449                                GPIOB->BSRR = D11_BSR_MASK(C) | D12_BSR_MASK(C) | D13_BSR_MASK(C) | D14_BSR_MASK(C); \
    450                                WR_STB; \
    451                                GPIOA->BSRR = D0_BSR_MASK(C) | D2_BSR_MASK(C) | D7_BSR_MASK(C); \
    452                                WR_L; \
    453                                GPIOC->BSRR = D1_BSR_MASK(C); \
    454                                GPIOB->BSRR = D3_BSR_MASK(C) | D4_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    455                                WR_STB // Need to slow down strobe
    456 
    457       // 16 bit write with swapped bytes
    458       #define tft_Write_16S(C) GPIOA->BSRR = D0_BSR_MASK(C) | D2_BSR_MASK(C) | D7_BSR_MASK(C); \
    459                                WR_L; \
    460                                GPIOC->BSRR = D1_BSR_MASK(C); \
    461                                GPIOB->BSRR = D3_BSR_MASK(C) | D4_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    462                                WR_STB; \
    463                                GPIOA->BSRR = D8_BSR_MASK(C) | D10_BSR_MASK(C) | D15_BSR_MASK(C); \
    464                                WR_L; \
    465                                GPIOC->BSRR = D9_BSR_MASK(C); \
    466                                GPIOB->BSRR = D11_BSR_MASK(C) | D12_BSR_MASK(C) | D13_BSR_MASK(C) | D14_BSR_MASK(C); \
    467                                WR_STB
    468     #endif
    469 
    470     #define tft_Write_32(C)    tft_Write_16((uint16_t)((C)>>16)); tft_Write_16((uint16_t)(C))
    471 
    472     #define tft_Write_32C(C,D) tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(D))
    473 
    474     #define tft_Write_32D(C)   tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(C))
    475 
    476     // Read a data bit
    477     #define RD_TFT_D0 (((GPIOA->IDR)&(D0_PIN_MASK))>>( 9-0)) // Read pin PA9
    478     #define RD_TFT_D1 (((GPIOC->IDR)&(D1_PIN_MASK))>>( 7-1)) // Read pin PC7
    479     #define RD_TFT_D2 (((GPIOA->IDR)&(D2_PIN_MASK))>>(10-2)) // Read pin PA10
    480     #define RD_TFT_D3 (((GPIOB->IDR)&(D3_PIN_MASK))>>( 3-3)) // Read pin PB3
    481     #define RD_TFT_D4 (((GPIOB->IDR)&(D4_PIN_MASK))>>( 5-4)) // Read pin PB5
    482     #define RD_TFT_D5 (((GPIOB->IDR)&(D5_PIN_MASK))<<(-4+5)) // Read pin PB4
    483     #define RD_TFT_D6 (((GPIOB->IDR)&(D6_PIN_MASK))>>(10-6)) // Read pin PB10
    484     #define RD_TFT_D7 (((GPIOA->IDR)&(D7_PIN_MASK))>>( 8-7)) // Read pin PA8
    485 
    486 ////////////////////////////////////////////////////////////////////////////////////////
    487 // Nucleo 144: hard-coded pins
    488 ////////////////////////////////////////////////////////////////////////////////////////
    489   #elif defined (NUCLEO_144_TFT)
    490 
    491     // Convert Arduino pin reference Dx or STM pin reference PXn to port and mask
    492     // (diagnostic only - not used for Nucleo)
    493     #define D0_PIN_NAME  digitalPinToPinName(TFT_D0)
    494     #define D1_PIN_NAME  digitalPinToPinName(TFT_D1)
    495     #define D2_PIN_NAME  digitalPinToPinName(TFT_D2)
    496     #define D3_PIN_NAME  digitalPinToPinName(TFT_D3)
    497     #define D4_PIN_NAME  digitalPinToPinName(TFT_D4)
    498     #define D5_PIN_NAME  digitalPinToPinName(TFT_D5)
    499     #define D6_PIN_NAME  digitalPinToPinName(TFT_D6)
    500     #define D7_PIN_NAME  digitalPinToPinName(TFT_D7)
    501 
    502     // Pin port bit number 0-15 (diagnostic only - not used for Nucleo)
    503     #define D0_PIN_BIT  (D0_PIN_NAME & 0xF)
    504     #define D1_PIN_BIT  (D1_PIN_NAME & 0xF)
    505     #define D2_PIN_BIT  (D2_PIN_NAME & 0xF)
    506     #define D3_PIN_BIT  (D3_PIN_NAME & 0xF)
    507     #define D4_PIN_BIT  (D4_PIN_NAME & 0xF)
    508     #define D5_PIN_BIT  (D5_PIN_NAME & 0xF)
    509     #define D6_PIN_BIT  (D6_PIN_NAME & 0xF)
    510     #define D7_PIN_BIT  (D7_PIN_NAME & 0xF)
    511 
    512 
    513     #if !defined (STM32H7xx)
    514 
    515       // Ports associated with pins - get_GPIO_Port() seems to be slow...
    516       #define D0_PIN_PORT GPIOF
    517       #define D1_PIN_PORT GPIOD
    518       #define D2_PIN_PORT GPIOF
    519       #define D3_PIN_PORT GPIOE
    520       #define D4_PIN_PORT GPIOF
    521       #define D5_PIN_PORT GPIOE
    522       #define D6_PIN_PORT GPIOE
    523       #define D7_PIN_PORT GPIOF
    524 
    525       // Pin masks for set/clear
    526       #define D0_PIN_MASK (1UL<<12) // Set/clear mask for PF12 PF3
    527       #define D1_PIN_MASK (1UL<<15) // Set/clear mask for PD15
    528       #define D2_PIN_MASK (1UL<<15) // Set/clear mask for PF15 PG14
    529       #define D3_PIN_MASK (1UL<<13) // Set/clear mask for PE13
    530       #define D4_PIN_MASK (1UL<<14) // Set/clear mask for PF14
    531       #define D5_PIN_MASK (1UL<<11) // Set/clear mask for PE11
    532       #define D6_PIN_MASK (1UL<< 9) // Set/clear mask for PE9
    533       #define D7_PIN_MASK (1UL<<13) // Set/clear mask for PF13 PG12
    534 
    535       // Create bit set/reset mask based on LS byte of value B
    536       #define  D0_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)<< 4)&0x10))
    537       #define  D1_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)<< 3)&0x10))
    538       #define  D2_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)<< 2)&0x10))
    539       #define  D3_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)<< 1)&0x10))
    540       #define  D4_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)<< 0)&0x10))
    541       #define  D5_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 1)&0x10))
    542       #define  D6_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>> 2)&0x10))
    543       #define  D7_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>> 3)&0x10))
    544       // Create bit set/reset mask for top byte of 16 bit value B
    545       #define  D8_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)>> 4)&0x10))
    546       #define  D9_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)>> 5)&0x10))
    547       #define D10_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)>> 6)&0x10))
    548       #define D11_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)>> 7)&0x10))
    549       #define D12_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)>> 8)&0x10))
    550       #define D13_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 9)&0x10))
    551       #define D14_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>>10)&0x10))
    552       #define D15_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>>11)&0x10))
    553 
    554 
    555       // Write 8 bits to TFT
    556       #define tft_Write_8(C)   GPIOF->BSRR = D0_BSR_MASK(C) | D2_BSR_MASK(C) | D4_BSR_MASK(C) | D7_BSR_MASK(C); \
    557                                WR_L; \
    558                                GPIOD->BSRR = D1_BSR_MASK(C); \
    559                                GPIOE->BSRR = D3_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    560                                WR_STB
    561 
    562       #if defined (SSD1963_DRIVER)
    563 
    564         // Write 18 bit color to TFT (untested)
    565         #define tft_Write_16(C)  r6 = (((C) & 0xF800)>> 8); g6 = (((C) & 0x07E0)>> 3); b6 = (((C) & 0x001F)<< 3); \
    566                                  GPIOF->BSRR = D0_BSR_MASK(r6) | D2_BSR_MASK(r6) | D4_BSR_MASK(r6) | D7_BSR_MASK(r6); \
    567                                  WR_L; \
    568                                  GPIOD->BSRR = D1_BSR_MASK(r6); \
    569                                  GPIOE->BSRR = D3_BSR_MASK(r6) | D5_BSR_MASK(r6) | D6_BSR_MASK(r6); \
    570                                  WR_STB; \
    571                                  GPIOF->BSRR = D0_BSR_MASK(g6) | D2_BSR_MASK(g6) | D4_BSR_MASK(g6) | D7_BSR_MASK(g6); \
    572                                  WR_L; \
    573                                  GPIOD->BSRR = D1_BSR_MASK(g6); \
    574                                  GPIOE->BSRR = D3_BSR_MASK(g6) | D5_BSR_MASK(g6) | D6_BSR_MASK(g6); \
    575                                  WR_STB; \
    576                                  GPIOF->BSRR = D0_BSR_MASK(b6) | D2_BSR_MASK(b6) | D4_BSR_MASK(b6) | D7_BSR_MASK(b6); \
    577                                  WR_L; \
    578                                  GPIOD->BSRR = D1_BSR_MASK(b6); \
    579                                  GPIOE->BSRR = D3_BSR_MASK(b6) | D5_BSR_MASK(b6) | D6_BSR_MASK(b6); \
    580                                  WR_STB // Need to slow down strobe
    581 
    582         // 18 bit color write with swapped bytes
    583         #define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
    584 
    585       #else
    586 
    587         // Write 16 bits to TFT
    588         #define tft_Write_16(C)  GPIOF->BSRR = D8_BSR_MASK(C) | D10_BSR_MASK(C) | D12_BSR_MASK(C) | D15_BSR_MASK(C); \
    589                                  WR_L; \
    590                                  GPIOD->BSRR = D9_BSR_MASK(C); \
    591                                  GPIOE->BSRR = D11_BSR_MASK(C) | D13_BSR_MASK(C) | D14_BSR_MASK(C); \
    592                                  WR_STB;\
    593                                  GPIOF->BSRR = D0_BSR_MASK(C) | D2_BSR_MASK(C) | D4_BSR_MASK(C) | D7_BSR_MASK(C); \
    594                                  WR_L; \
    595                                  GPIOD->BSRR = D1_BSR_MASK(C); \
    596                                  GPIOE->BSRR = D3_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    597                                  WR_STB
    598 
    599         // 16 bit write with swapped bytes
    600         #define tft_Write_16S(C) GPIOF->BSRR = D0_BSR_MASK(C) | D2_BSR_MASK(C) | D4_BSR_MASK(C) | D7_BSR_MASK(C); \
    601                                  WR_L; \
    602                                  GPIOD->BSRR = D1_BSR_MASK(C); \
    603                                  GPIOE->BSRR = D3_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    604                                  WR_STB; \
    605                                  GPIOF->BSRR = D8_BSR_MASK(C) | D10_BSR_MASK(C) | D12_BSR_MASK(C) | D15_BSR_MASK(C); \
    606                                  WR_L; \
    607                                  GPIOD->BSRR = D9_BSR_MASK(C); \
    608                                  GPIOE->BSRR = D11_BSR_MASK(C) | D13_BSR_MASK(C) | D14_BSR_MASK(C); \
    609                                  WR_STB
    610 
    611       #endif
    612 
    613       #define tft_Write_32(C)    tft_Write_16((uint16_t)((C)>>16)); tft_Write_16((uint16_t)(C))
    614 
    615       #define tft_Write_32C(C,D) tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(D))
    616 
    617       #define tft_Write_32D(C)   tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(C))
    618 
    619       // Read a data bit
    620       #define RD_TFT_D0 (((GPIOF->IDR)&(D0_PIN_MASK))>>(12-0)) // Read pin PF12
    621       #define RD_TFT_D1 (((GPIOD->IDR)&(D1_PIN_MASK))>>(15-1)) // Read pin PD15
    622       #define RD_TFT_D2 (((GPIOF->IDR)&(D2_PIN_MASK))>>(15-2)) // Read pin PF15
    623       #define RD_TFT_D3 (((GPIOE->IDR)&(D3_PIN_MASK))>>(13-3)) // Read pin PE13
    624       #define RD_TFT_D4 (((GPIOF->IDR)&(D4_PIN_MASK))>>(14-4)) // Read pin PF14
    625       #define RD_TFT_D5 (((GPIOE->IDR)&(D5_PIN_MASK))>>(11-5)) // Read pin PE11
    626       #define RD_TFT_D6 (((GPIOE->IDR)&(D6_PIN_MASK))>>( 9-6)) // Read pin PE9
    627       #define RD_TFT_D7 (((GPIOF->IDR)&(D7_PIN_MASK))>>(13-7)) // Read pin PF13
    628 
    629     #else
    630 
    631       // Test setup for STM32H743 - starts to run, slow and then crashes! Board support bug?
    632 
    633       // Ports associated with pins - get_GPIO_Port() seems to be slow...
    634       #define D0_PIN_PORT GPIOF
    635       #define D1_PIN_PORT GPIOD
    636       #define D2_PIN_PORT GPIOG
    637       #define D3_PIN_PORT GPIOE
    638       #define D4_PIN_PORT GPIOE
    639       #define D5_PIN_PORT GPIOE
    640       #define D6_PIN_PORT GPIOE
    641       #define D7_PIN_PORT GPIOG
    642 
    643       // Pin masks for set/clear
    644       #define D0_PIN_MASK (1UL<< 3) // Set/clear mask for PF3
    645       #define D1_PIN_MASK (1UL<<15) // Set/clear mask for PD15
    646       #define D2_PIN_MASK (1UL<<14) // Set/clear mask for PG14
    647       #define D3_PIN_MASK (1UL<<13) // Set/clear mask for PE13
    648       #define D4_PIN_MASK (1UL<<14) // Set/clear mask for PE14
    649       #define D5_PIN_MASK (1UL<<11) // Set/clear mask for PE11
    650       #define D6_PIN_MASK (1UL<< 9) // Set/clear mask for PE9
    651       #define D7_PIN_MASK (1UL<<12) // Set/clear mask for PG12
    652 
    653       // Create bit set/reset mask based on LS byte of value B
    654       #define  D0_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)<< 4)&0x10))
    655       #define  D1_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)<< 3)&0x10))
    656       #define  D2_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)<< 2)&0x10))
    657       #define  D3_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)<< 1)&0x10))
    658       #define  D4_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)<< 0)&0x10))
    659       #define  D5_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 1)&0x10))
    660       #define  D6_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>> 2)&0x10))
    661       #define  D7_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>> 3)&0x10))
    662       // Create bit set/reset mask for top byte of 16 bit value B
    663       #define  D8_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)>> 4)&0x10))
    664       #define  D9_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)>> 5)&0x10))
    665       #define D10_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)>> 6)&0x10))
    666       #define D11_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)>> 7)&0x10))
    667       #define D12_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)>> 8)&0x10))
    668       #define D13_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 9)&0x10))
    669       #define D14_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>>10)&0x10))
    670       #define D15_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>>11)&0x10))
    671 
    672 
    673       // Write 8 bits to TFT
    674       #define tft_Write_8(C)   GPIOF->BSRR = D0_BSR_MASK(C); \
    675                                GPIOG->BSRR = D2_BSR_MASK(C) | D7_BSR_MASK(C); \
    676                                WR_L; \
    677                                GPIOD->BSRR = D1_BSR_MASK(C); \
    678                                GPIOE->BSRR = D3_BSR_MASK(C) | D4_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    679                                WR_STB
    680 
    681       // Write 16 bits to TFT
    682       #define tft_Write_16(C)  GPIOF->BSRR = D8_BSR_MASK(C); \
    683                                GPIOG->BSRR = D10_BSR_MASK(C) | D15_BSR_MASK(C); \
    684                                WR_L; \
    685                                GPIOD->BSRR = D9_BSR_MASK(C); \
    686                                GPIOE->BSRR = D11_BSR_MASK(C) | D12_BSR_MASK(C) | D13_BSR_MASK(C) | D14_BSR_MASK(C); \
    687                                WR_STB;\
    688                                GPIOF->BSRR = D0_BSR_MASK(C); \
    689                                GPIOG->BSRR = D2_BSR_MASK(C) | D7_BSR_MASK(C); \
    690                                WR_L; \
    691                                GPIOD->BSRR = D1_BSR_MASK(C); \
    692                                GPIOE->BSRR = D3_BSR_MASK(C) | D4_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    693                                WR_STB
    694 
    695       // 16 bit write with swapped bytes
    696       #define tft_Write_16S(C) GPIOF->BSRR = D0_BSR_MASK(C); \
    697                                GPIOG->BSRR = D2_BSR_MASK(C) | D7_BSR_MASK(C); \
    698                                WR_L; \
    699                                GPIOD->BSRR = D1_BSR_MASK(C); \
    700                                GPIOE->BSRR = D3_BSR_MASK(C) | D4_BSR_MASK(C) | D5_BSR_MASK(C) | D6_BSR_MASK(C); \
    701                                WR_STB; \
    702                                GPIOF->BSRR = D8_BSR_MASK(C); \
    703                                GPIOG->BSRR = D10_BSR_MASK(C) | D15_BSR_MASK(C); \
    704                                WR_L; \
    705                                GPIOD->BSRR = D9_BSR_MASK(C); \
    706                                GPIOE->BSRR = D11_BSR_MASK(C) | D12_BSR_MASK(C) | D13_BSR_MASK(C) | D14_BSR_MASK(C); \
    707                                WR_STB
    708 
    709       #define tft_Write_32(C)    tft_Write_16((uint16_t)((C)>>16)); tft_Write_16((uint16_t)(C))
    710 
    711       #define tft_Write_32C(C,D) tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(D))
    712 
    713       #define tft_Write_32D(C)   tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(C))
    714 
    715       // Read a data bit
    716       #define RD_TFT_D0 (((GPIOF->IDR)&(D0_PIN_MASK))>>( 3-0)) // Read pin PF3
    717       #define RD_TFT_D1 (((GPIOD->IDR)&(D1_PIN_MASK))>>(15-1)) // Read pin PD15
    718       #define RD_TFT_D2 (((GPIOG->IDR)&(D2_PIN_MASK))>>(14-2)) // Read pin PG14
    719       #define RD_TFT_D3 (((GPIOE->IDR)&(D3_PIN_MASK))>>(13-3)) // Read pin PE13
    720       #define RD_TFT_D4 (((GPIOE->IDR)&(D4_PIN_MASK))>>(14-4)) // Read pin PE14
    721       #define RD_TFT_D5 (((GPIOE->IDR)&(D5_PIN_MASK))>>(11-5)) // Read pin PE11
    722       #define RD_TFT_D6 (((GPIOE->IDR)&(D6_PIN_MASK))>>( 9-6)) // Read pin PE9
    723       #define RD_TFT_D7 (((GPIOG->IDR)&(D7_PIN_MASK))>>(12-7)) // Read pin PG12
    724 
    725     #endif
    726 ////////////////////////////////////////////////////////////////////////////////////////
    727 // Support for other STM32 boards (not optimised!)
    728 ////////////////////////////////////////////////////////////////////////////////////////
    729   #else
    730     #if defined (STM_PORTA_DATA_BUS) || defined (STM_PORTB_DATA_BUS) || defined (STM_PORTC_DATA_BUS) || defined (STM_PORTD_DATA_BUS)
    731       #if defined (STM_PORTA_DATA_BUS)
    732         #define GPIOX GPIOA
    733       #elif defined (STM_PORTB_DATA_BUS)
    734         #define GPIOX GPIOB
    735       #elif defined (STM_PORTC_DATA_BUS)
    736         #define GPIOX GPIOC
    737       #elif defined (STM_PORTD_DATA_BUS)
    738         #define GPIOX GPIOD
    739       #endif
    740 
    741       // Write 8 bits to TFT
    742       #define tft_Write_8(C)   GPIOX->BSRR = (0x00FF0000 | (uint8_t)(C)); WR_L; WR_STB
    743 
    744       #if defined (SSD1963_DRIVER)
    745 
    746         // Write 18 bit color to TFT (untested)
    747 
    748         #define tft_Write_16(C)  r6 = (((C) & 0xF800)>> 8); g6 = (((C) & 0x07E0)>> 3); b6 = (((C) & 0x001F)<< 3); \
    749                              GPIOX->BSRR = (0x00FF0000 | (uint8_t)(r6)); WR_L; WR_STB; \
    750                              GPIOX->BSRR = (0x00FF0000 | (uint8_t)(g6)); WR_L; WR_STB; \
    751                              GPIOX->BSRR = (0x00FF0000 | (uint8_t)(b6)); WR_L; WR_STB
    752 
    753         // 18 bit color write with swapped bytes
    754         #define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
    755 
    756       #else
    757 
    758           // Write 16 bits to TFT
    759           #define tft_Write_16(C)  GPIOX->BSRR = (0x00FF0000 | (uint8_t)(C>>8)); WR_L; WR_STB; \
    760                                    GPIOX->BSRR = (0x00FF0000 | (uint8_t)(C>>0)); WR_L; WR_STB
    761 
    762           // 16 bit write with swapped bytes
    763           #define tft_Write_16S(C) GPIOX->BSRR = (0x00FF0000 | (uint8_t)(C>>0)); WR_L; WR_STB; \
    764                                    GPIOX->BSRR = (0x00FF0000 | (uint8_t)(C>>8)); WR_L; WR_STB
    765       #endif
    766 
    767       #define tft_Write_32(C)    tft_Write_16((uint16_t)((C)>>16)); tft_Write_16((uint16_t)(C))
    768 
    769       #define tft_Write_32C(C,D) tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(D))
    770 
    771       #define tft_Write_32D(C)   tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(C))
    772 
    773       // Read a data bit
    774       #define RD_TFT_D0 ((GPIOX->IDR) & 0x01) // Read pin TFT_D0
    775       #define RD_TFT_D1 ((GPIOX->IDR) & 0x02) // Read pin TFT_D1
    776       #define RD_TFT_D2 ((GPIOX->IDR) & 0x04) // Read pin TFT_D2
    777       #define RD_TFT_D3 ((GPIOX->IDR) & 0x08) // Read pin TFT_D3
    778       #define RD_TFT_D4 ((GPIOX->IDR) & 0x10) // Read pin TFT_D4
    779       #define RD_TFT_D5 ((GPIOX->IDR) & 0x20) // Read pin TFT_D5
    780       #define RD_TFT_D6 ((GPIOX->IDR) & 0x40) // Read pin TFT_D6
    781       #define RD_TFT_D7 ((GPIOX->IDR) & 0x80) // Read pin TFT_D7
    782 
    783     #else
    784       // This will work with any STM32 to parallel TFT pin mapping but will be slower
    785 
    786       // Convert Arduino pin reference Dx or STM pin reference PXn to port and mask
    787       #define D0_PIN_NAME  digitalPinToPinName(TFT_D0)
    788       #define D1_PIN_NAME  digitalPinToPinName(TFT_D1)
    789       #define D2_PIN_NAME  digitalPinToPinName(TFT_D2)
    790       #define D3_PIN_NAME  digitalPinToPinName(TFT_D3)
    791       #define D4_PIN_NAME  digitalPinToPinName(TFT_D4)
    792       #define D5_PIN_NAME  digitalPinToPinName(TFT_D5)
    793       #define D6_PIN_NAME  digitalPinToPinName(TFT_D6)
    794       #define D7_PIN_NAME  digitalPinToPinName(TFT_D7)
    795 
    796       // Pin port bit number 0-15
    797       #define D0_PIN_BIT  (D0_PIN_NAME & 0xF)
    798       #define D1_PIN_BIT  (D1_PIN_NAME & 0xF)
    799       #define D2_PIN_BIT  (D2_PIN_NAME & 0xF)
    800       #define D3_PIN_BIT  (D3_PIN_NAME & 0xF)
    801       #define D4_PIN_BIT  (D4_PIN_NAME & 0xF)
    802       #define D5_PIN_BIT  (D5_PIN_NAME & 0xF)
    803       #define D6_PIN_BIT  (D6_PIN_NAME & 0xF)
    804       #define D7_PIN_BIT  (D7_PIN_NAME & 0xF)
    805 
    806       // Pin port
    807       #define D0_PIN_PORT  digitalPinToPort(TFT_D0)
    808       #define D1_PIN_PORT  digitalPinToPort(TFT_D1)
    809       #define D2_PIN_PORT  digitalPinToPort(TFT_D2)
    810       #define D3_PIN_PORT  digitalPinToPort(TFT_D3)
    811       #define D4_PIN_PORT  digitalPinToPort(TFT_D4)
    812       #define D5_PIN_PORT  digitalPinToPort(TFT_D5)
    813       #define D6_PIN_PORT  digitalPinToPort(TFT_D6)
    814       #define D7_PIN_PORT  digitalPinToPort(TFT_D7)
    815 
    816       // Pin masks for set/clear
    817       #define D0_PIN_MASK  digitalPinToBitMask(TFT_D0)
    818       #define D1_PIN_MASK  digitalPinToBitMask(TFT_D1)
    819       #define D2_PIN_MASK  digitalPinToBitMask(TFT_D2)
    820       #define D3_PIN_MASK  digitalPinToBitMask(TFT_D3)
    821       #define D4_PIN_MASK  digitalPinToBitMask(TFT_D4)
    822       #define D5_PIN_MASK  digitalPinToBitMask(TFT_D5)
    823       #define D6_PIN_MASK  digitalPinToBitMask(TFT_D6)
    824       #define D7_PIN_MASK  digitalPinToBitMask(TFT_D7)
    825 
    826       // Create bit set/reset mask based on LS byte of value B
    827       #define  D0_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)<< 4)&0x10))
    828       #define  D1_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)<< 3)&0x10))
    829       #define  D2_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)<< 2)&0x10))
    830       #define  D3_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)<< 1)&0x10))
    831       #define  D4_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)<< 0)&0x10))
    832       #define  D5_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 1)&0x10))
    833       #define  D6_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>> 2)&0x10))
    834       #define  D7_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>> 3)&0x10))
    835       // Create bit set/reset mask for top byte of 16 bit value B
    836       #define  D8_BSR_MASK(B) ((D0_PIN_MASK<<16)>>(((B)>> 4)&0x10))
    837       #define  D9_BSR_MASK(B) ((D1_PIN_MASK<<16)>>(((B)>> 5)&0x10))
    838       #define D10_BSR_MASK(B) ((D2_PIN_MASK<<16)>>(((B)>> 6)&0x10))
    839       #define D11_BSR_MASK(B) ((D3_PIN_MASK<<16)>>(((B)>> 7)&0x10))
    840       #define D12_BSR_MASK(B) ((D4_PIN_MASK<<16)>>(((B)>> 8)&0x10))
    841       #define D13_BSR_MASK(B) ((D5_PIN_MASK<<16)>>(((B)>> 9)&0x10))
    842       #define D14_BSR_MASK(B) ((D6_PIN_MASK<<16)>>(((B)>>10)&0x10))
    843       #define D15_BSR_MASK(B) ((D7_PIN_MASK<<16)>>(((B)>>11)&0x10))
    844 
    845 
    846       // Write 8 bits to TFT
    847       #define tft_Write_8(C)   D0_PIN_PORT->BSRR = D0_BSR_MASK(C); \
    848                                D1_PIN_PORT->BSRR = D1_BSR_MASK(C); \
    849                                D2_PIN_PORT->BSRR = D2_BSR_MASK(C); \
    850                                D3_PIN_PORT->BSRR = D3_BSR_MASK(C); \
    851                                WR_L; \
    852                                D4_PIN_PORT->BSRR = D4_BSR_MASK(C); \
    853                                D5_PIN_PORT->BSRR = D5_BSR_MASK(C); \
    854                                D6_PIN_PORT->BSRR = D6_BSR_MASK(C); \
    855                                D7_PIN_PORT->BSRR = D7_BSR_MASK(C); \
    856                                WR_STB
    857 
    858       #if defined (SSD1963_DRIVER)
    859 
    860         // Write 18 bit color to TFT (untested)
    861         #define tft_Write_16(C)  r6 = (((C) & 0xF800)>> 8); g6 = (((C) & 0x07E0)>> 3); b6 = (((C) & 0x001F)<< 3); \
    862                                  D0_PIN_PORT->BSRR = D8_BSR_MASK(r6);  \
    863                                  D1_PIN_PORT->BSRR = D9_BSR_MASK(r6);  \
    864                                  D2_PIN_PORT->BSRR = D10_BSR_MASK(r6); \
    865                                  D3_PIN_PORT->BSRR = D11_BSR_MASK(r6); \
    866                                  WR_L; \
    867                                  D4_PIN_PORT->BSRR = D12_BSR_MASK(r6); \
    868                                  D5_PIN_PORT->BSRR = D13_BSR_MASK(r6); \
    869                                  D6_PIN_PORT->BSRR = D14_BSR_MASK(r6); \
    870                                  D7_PIN_PORT->BSRR = D15_BSR_MASK(r6); \
    871                                  WR_STB;\
    872                                  D0_PIN_PORT->BSRR = D8_BSR_MASK(g6);  \
    873                                  D1_PIN_PORT->BSRR = D9_BSR_MASK(g6);  \
    874                                  D2_PIN_PORT->BSRR = D10_BSR_MASK(g6); \
    875                                  D3_PIN_PORT->BSRR = D11_BSR_MASK(g6); \
    876                                  WR_L; \
    877                                  D4_PIN_PORT->BSRR = D12_BSR_MASK(g6); \
    878                                  D5_PIN_PORT->BSRR = D13_BSR_MASK(g6); \
    879                                  D6_PIN_PORT->BSRR = D14_BSR_MASK(g6); \
    880                                  D7_PIN_PORT->BSRR = D15_BSR_MASK(g6); \
    881                                  WR_STB;\
    882                                  D0_PIN_PORT->BSRR = D0_BSR_MASK(b6); \
    883                                  D1_PIN_PORT->BSRR = D1_BSR_MASK(b6); \
    884                                  D2_PIN_PORT->BSRR = D2_BSR_MASK(b6); \
    885                                  D3_PIN_PORT->BSRR = D3_BSR_MASK(b6); \
    886                                  WR_L; \
    887                                  D4_PIN_PORT->BSRR = D4_BSR_MASK(b6); \
    888                                  D5_PIN_PORT->BSRR = D5_BSR_MASK(b6); \
    889                                  D6_PIN_PORT->BSRR = D6_BSR_MASK(b6); \
    890                                  D7_PIN_PORT->BSRR = D7_BSR_MASK(b6); \
    891                                  WR_STB
    892 
    893         // 18 bit color write with swapped bytes
    894         #define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
    895 
    896       #else
    897 
    898         // Write 16 bits to TFT
    899         #define tft_Write_16(C)  D0_PIN_PORT->BSRR = D8_BSR_MASK(C);  \
    900                                  D1_PIN_PORT->BSRR = D9_BSR_MASK(C);  \
    901                                  D2_PIN_PORT->BSRR = D10_BSR_MASK(C); \
    902                                  D3_PIN_PORT->BSRR = D11_BSR_MASK(C); \
    903                                  WR_L; \
    904                                  D4_PIN_PORT->BSRR = D12_BSR_MASK(C); \
    905                                  D5_PIN_PORT->BSRR = D13_BSR_MASK(C); \
    906                                  D6_PIN_PORT->BSRR = D14_BSR_MASK(C); \
    907                                  D7_PIN_PORT->BSRR = D15_BSR_MASK(C); \
    908                                  WR_STB;\
    909                                  D0_PIN_PORT->BSRR = D0_BSR_MASK(C); \
    910                                  D1_PIN_PORT->BSRR = D1_BSR_MASK(C); \
    911                                  D2_PIN_PORT->BSRR = D2_BSR_MASK(C); \
    912                                  D3_PIN_PORT->BSRR = D3_BSR_MASK(C); \
    913                                  WR_L; \
    914                                  D4_PIN_PORT->BSRR = D4_BSR_MASK(C); \
    915                                  D5_PIN_PORT->BSRR = D5_BSR_MASK(C); \
    916                                  D6_PIN_PORT->BSRR = D6_BSR_MASK(C); \
    917                                  D7_PIN_PORT->BSRR = D7_BSR_MASK(C); \
    918                                  WR_STB
    919 
    920         // 16 bit write with swapped bytes
    921         #define tft_Write_16S(C) D0_PIN_PORT->BSRR = D0_BSR_MASK(C); \
    922                                  D1_PIN_PORT->BSRR = D1_BSR_MASK(C); \
    923                                  D2_PIN_PORT->BSRR = D2_BSR_MASK(C); \
    924                                  D3_PIN_PORT->BSRR = D3_BSR_MASK(C); \
    925                                  WR_L; \
    926                                  D4_PIN_PORT->BSRR = D4_BSR_MASK(C); \
    927                                  D5_PIN_PORT->BSRR = D5_BSR_MASK(C); \
    928                                  D6_PIN_PORT->BSRR = D6_BSR_MASK(C); \
    929                                  D7_PIN_PORT->BSRR = D7_BSR_MASK(C); \
    930                                  WR_STB; \
    931                                  D0_PIN_PORT->BSRR = D8_BSR_MASK(C);  \
    932                                  D1_PIN_PORT->BSRR = D9_BSR_MASK(C);  \
    933                                  D2_PIN_PORT->BSRR = D10_BSR_MASK(C); \
    934                                  D3_PIN_PORT->BSRR = D11_BSR_MASK(C); \
    935                                  WR_L; \
    936                                  D4_PIN_PORT->BSRR = D12_BSR_MASK(C); \
    937                                  D5_PIN_PORT->BSRR = D13_BSR_MASK(C); \
    938                                  D6_PIN_PORT->BSRR = D14_BSR_MASK(C); \
    939                                  D7_PIN_PORT->BSRR = D15_BSR_MASK(C); \
    940                                  WR_STB
    941       #endif
    942 
    943       #define tft_Write_32(C)    tft_Write_16((uint16_t)((C)>>16)); tft_Write_16((uint16_t)(C))
    944 
    945       #define tft_Write_32C(C,D) tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(D))
    946 
    947       #define tft_Write_32D(C)   tft_Write_16((uint16_t)(C)); tft_Write_16((uint16_t)(C))
    948 
    949       // Read a data bit
    950       #define RD_TFT_D0 ((((D0_PIN_PORT->IDR) >> (D0_PIN_BIT))&1)<<0) // Read pin TFT_D0
    951       #define RD_TFT_D1 ((((D1_PIN_PORT->IDR) >> (D1_PIN_BIT))&1)<<1) // Read pin TFT_D1
    952       #define RD_TFT_D2 ((((D2_PIN_PORT->IDR) >> (D2_PIN_BIT))&1)<<2) // Read pin TFT_D2
    953       #define RD_TFT_D3 ((((D3_PIN_PORT->IDR) >> (D3_PIN_BIT))&1)<<3) // Read pin TFT_D3
    954       #define RD_TFT_D4 ((((D4_PIN_PORT->IDR) >> (D4_PIN_BIT))&1)<<4) // Read pin TFT_D4
    955       #define RD_TFT_D5 ((((D5_PIN_PORT->IDR) >> (D5_PIN_BIT))&1)<<5) // Read pin TFT_D5
    956       #define RD_TFT_D6 ((((D6_PIN_PORT->IDR) >> (D6_PIN_BIT))&1)<<6) // Read pin TFT_D6
    957       #define RD_TFT_D7 ((((D7_PIN_PORT->IDR) >> (D7_PIN_BIT))&1)<<7) // Read pin TFT_D7
    958     #endif
    959   #endif
    960 ////////////////////////////////////////////////////////////////////////////////////////
    961 // Macros to write commands/pixel colour data to a SPI ILI948x TFT
    962 ////////////////////////////////////////////////////////////////////////////////////////
    963 #elif  defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
    964 
    965   // Write 8 bits to TFT
    966   #define tft_Write_8(C) \
    967   { spiBuffer[0] = C; \
    968   HAL_SPI_Transmit(&spiHal, spiBuffer, 1, 10); }
    969 
    970   // Convert 16 bit colour to 18 bit and write in 3 bytes
    971   #define tft_Write_16(C) \
    972   { spiBuffer[0] = ((C) & 0xF800)>>8; spiBuffer[1] = ((C) & 0x07E0)>>3; spiBuffer[2] = ((C) & 0x001F)<<3; \
    973   HAL_SPI_Transmit(&spiHal, spiBuffer, 3, 10); }
    974 
    975   // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
    976   #define tft_Write_16S(C) \
    977   { spiBuffer[0] = (C) & 0xF8; spiBuffer[1] = ((C) & 0xE000)>>11 | ((C) & 0x07)<<5; spiBuffer[2] = ((C) & 0x1F00)>>5; \
    978   HAL_SPI_Transmit(&spiHal, spiBuffer, 3, 10); }
    979 
    980   // Write 32 bits to TFT
    981   #define tft_Write_32(C) \
    982   { spiBuffer[0] = (C)>>24; spiBuffer[1] = (C)>>16; spiBuffer[2] = (C)>>8; spiBuffer[3] = C; \
    983   HAL_SPI_Transmit(&spiHal, spiBuffer, 4, 10); }
    984 
    985   // Write two address coordinates
    986   #define tft_Write_32C(C,D) \
    987   { spiBuffer[0] = (C)>>8; spiBuffer[1] = C; spiBuffer[2] = (D)>>8; spiBuffer[3] = D; \
    988   HAL_SPI_Transmit(&spiHal, spiBuffer, 4, 10); }
    989 
    990   // Write same value twice
    991   #define tft_Write_32D(C) \
    992   { spiBuffer[0] = spiBuffer[2] = (C)>>8; spiBuffer[1] = spiBuffer[3] = C; \
    993   HAL_SPI_Transmit(&spiHal, spiBuffer, 4, 10); }
    994 
    995 ////////////////////////////////////////////////////////////////////////////////////////
    996 // Macros to write commands/pixel colour data to a SPI Raspberry Pi TFT
    997 ////////////////////////////////////////////////////////////////////////////////////////
    998 #elif  defined (RPI_DISPLAY_TYPE)
    999 
   1000   #define tft_Write_8(C) \
   1001   { spiBuffer[0] = 0; spiBuffer[1] = C; \
   1002   HAL_SPI_Transmit(&spiHal, spiBuffer, 2, 10); }
   1003 
   1004   #define tft_Write_16(C) \
   1005   { spiBuffer[0] = (C)>>8; spiBuffer[1] = C; \
   1006   HAL_SPI_Transmit(&spiHal, spiBuffer, 2, 10); }
   1007 
   1008   #define tft_Write_16S(C) \
   1009   { spiBuffer[0] = C; spiBuffer[1] = (C)>>8; \
   1010   HAL_SPI_Transmit(&spiHal, spiBuffer, 2, 10); }
   1011 
   1012   #define tft_Write_32(C) \
   1013   { spiBuffer[0] = (C)>>24; spiBuffer[1] = (C)>>16; spiBuffer[2] = (C)>>8; spiBuffer[3] = C; \
   1014   HAL_SPI_Transmit(&spiHal, spiBuffer, 4, 10); }
   1015 
   1016   #define tft_Write_32C(C,D) \
   1017   { spiBuffer[1] = ((C)>>8); spiBuffer[3] = (C); spiBuffer[5] = ((D)>>8); spiBuffer[7] = D; \
   1018   HAL_SPI_Transmit(&spiHal, spiBuffer, 8, 10); }
   1019 
   1020   #define tft_Write_32D(C) \
   1021   { spiBuffer[1] = ((C)>>8); spiBuffer[3] = (C); spiBuffer[5] = ((C)>>8); spiBuffer[7] = C; \
   1022   HAL_SPI_Transmit(&spiHal, spiBuffer, 8, 10); }
   1023 
   1024 ////////////////////////////////////////////////////////////////////////////////////////
   1025 // Macros for all other SPI displays
   1026 ////////////////////////////////////////////////////////////////////////////////////////
   1027 
   1028 #else
   1029 
   1030   #if defined(ST7789_DRIVER) || defined(ST7789_2_DRIVER)
   1031     // Temporary workaround for issue #510 part 2
   1032     #define tft_Write_8(C)   spi.transfer(C)
   1033   #else
   1034     #define tft_Write_8(C) \
   1035     { spiBuffer[0] = C; \
   1036     HAL_SPI_Transmit(&spiHal, spiBuffer, 1, 10); delayMicroseconds(1);}
   1037   #endif
   1038 
   1039   #define tft_Write_16(C) \
   1040   { spiBuffer[0] = (C)>>8; spiBuffer[1] = C; \
   1041   HAL_SPI_Transmit(&spiHal, spiBuffer, 2, 10); }
   1042 
   1043   #define tft_Write_16S(C) \
   1044   { spiBuffer[0] = C; spiBuffer[1] = (C)>>8; \
   1045   HAL_SPI_Transmit(&spiHal, spiBuffer, 2, 10); }
   1046 
   1047   #define tft_Write_32(C) \
   1048   { spiBuffer[0] = (C)>>24; spiBuffer[1] = (C)>>16; spiBuffer[2] = (C)>>8; spiBuffer[3] = C; \
   1049   HAL_SPI_Transmit(&spiHal, spiBuffer, 4, 10); }
   1050 
   1051   #define tft_Write_32C(C,D) \
   1052   { spiBuffer[0] = (C)>>8; spiBuffer[1] = C; spiBuffer[2] = (D)>>8; spiBuffer[3] = D; \
   1053   HAL_SPI_Transmit(&spiHal, spiBuffer, 4, 10); }
   1054 
   1055   #define tft_Write_32D(C) \
   1056   { spiBuffer[0] = spiBuffer[2] = (C)>>8; spiBuffer[1] = spiBuffer[3] = C; \
   1057   HAL_SPI_Transmit(&spiHal, spiBuffer, 4, 10); }
   1058 
   1059 #endif
   1060 
   1061 #ifndef tft_Write_16N
   1062   #define tft_Write_16N tft_Write_16
   1063 #endif
   1064 
   1065 ////////////////////////////////////////////////////////////////////////////////////////
   1066 // Macros to read from display using SPI or software SPI
   1067 ////////////////////////////////////////////////////////////////////////////////////////
   1068 #if defined (TFT_SDA_READ)
   1069   // Macros to support a bit banged function call for STM32 and bi-directional SDA pin
   1070   #define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8();
   1071   #define SCLK_L digitalWrite(TFT_SCLK, LOW)
   1072   #define SCLK_H digitalWrite(TFT_SCLK, HIGH)
   1073 #elif !defined (TFT_PARALLEL_8_BIT)
   1074   // Use a SPI read transfer
   1075   #define tft_Read_8() spi.transfer(0)
   1076 #endif
   1077 
   1078 #endif // Header end