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_ESP8266.c (13308B)

      1 
      2         //////////////////////////////////////////////////////
      3         // TFT_eSPI driver functions for ESP8266 processors //
      4         //////////////////////////////////////////////////////
      5 
      6 // Select the SPI port to use
      7 // ESP8266 default (FLASH port also available via overlap mode)
      8   SPIClass& spi = SPI;
      9 
     10 // Buffer for SPI transmit byte padding and byte order manipulation
     11 uint8_t   spiBuffer[8] = {0,0,0,0,0,0,0,0};
     12 
     13 ////////////////////////////////////////////////////////////////////////////////////////
     14 #if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
     15 ////////////////////////////////////////////////////////////////////////////////////////
     16 
     17 /***************************************************************************************
     18 ** Function name:           tft_Read_8
     19 ** Description:             ESP8266 software SPI to read bidirectional SDA line
     20 ***************************************************************************************/
     21 uint8_t TFT_eSPI::tft_Read_8(void)
     22 {
     23   uint8_t  ret = 0;
     24   uint32_t reg = 0;
     25 
     26   for (uint8_t i = 0; i < 8; i++) {  // read results
     27     ret <<= 1;
     28     SCLK_L;
     29     if (digitalRead(TFT_MOSI)) ret |= 1;
     30     SCLK_H;
     31   }
     32 
     33   return ret;
     34 }
     35 
     36 /***************************************************************************************
     37 ** Function name:           beginSDA
     38 ** Description:             Detach SPI from pin to permit software SPI
     39 ***************************************************************************************/
     40 void TFT_eSPI::begin_SDA_Read(void)
     41 {
     42   #ifdef TFT_SPI_OVERLAP
     43     // Reads in overlap mode not supported
     44   #else
     45     spi.end();
     46   #endif
     47 }
     48 
     49 /***************************************************************************************
     50 ** Function name:           endSDA
     51 ** Description:             Attach SPI pins after software SPI
     52 ***************************************************************************************/
     53 void TFT_eSPI::end_SDA_Read(void)
     54 {
     55   #ifdef TFT_SPI_OVERLAP
     56     spi.pins(6, 7, 8, 0);
     57   #else
     58     spi.begin();
     59   #endif
     60 }
     61 ////////////////////////////////////////////////////////////////////////////////////////
     62 #endif // #if defined (TFT_SDA_READ)
     63 ////////////////////////////////////////////////////////////////////////////////////////
     64 
     65 
     66 /***************************************************************************************
     67 ** Function name:           read byte  - supports class functions
     68 ** Description:             Parallel bus only - dummy function - not used
     69 ***************************************************************************************/
     70 uint8_t TFT_eSPI::readByte(void)
     71 {
     72   uint8_t b = 0xAA;
     73   return b;
     74 }
     75 
     76 ////////////////////////////////////////////////////////////////////////////////////////
     77 #if defined (RPI_WRITE_STROBE)
     78 ////////////////////////////////////////////////////////////////////////////////////////
     79 
     80 /***************************************************************************************
     81 ** Function name:           pushBlock - for ESP32 or ESP8266 RPi TFT
     82 ** Description:             Write a block of pixels of the same colour
     83 ***************************************************************************************/
     84 void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
     85 {
     86   uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
     87   if(len) spi.writePattern(&colorBin[0], 2, 1); len--;
     88   while(len--) {WR_L; WR_H;}
     89 }
     90 
     91 /***************************************************************************************
     92 ** Function name:           pushPixels - for ESP32 or ESP8266 RPi TFT
     93 ** Description:             Write a sequence of pixels
     94 ***************************************************************************************/
     95 void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
     96 
     97   uint8_t *data = (uint8_t*)data_in;
     98   while ( len >=64 ) {spi.writePattern(data, 64, 1); data += 64; len -= 64; }
     99   if (len) spi.writePattern(data, len, 1);
    100 }
    101 
    102 /***************************************************************************************
    103 ** Function name:           pushSwapBytePixels - for ESP32 or ESP8266 RPi TFT
    104 ** Description:             Write a sequence of pixels with swapped bytes
    105 ***************************************************************************************/
    106 void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
    107   uint16_t *data = (uint16_t*)data_in;
    108   while ( len-- ) {tft_Write_16(*data); data++;}
    109 }
    110 
    111 ////////////////////////////////////////////////////////////////////////////////////////
    112 #elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
    113 ////////////////////////////////////////////////////////////////////////////////////////
    114 
    115 /***************************************************************************************
    116 ** Function name:           pushBlock - for ESP8266 and 3 byte RGB display
    117 ** Description:             Write a block of pixels of the same colour
    118 ***************************************************************************************/
    119 void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
    120 {
    121   // Split out the colours
    122   uint8_t r = (color & 0xF800)>>8;
    123   uint8_t g = (color & 0x07E0)>>3;
    124   uint8_t b = (color & 0x001F)<<3;
    125   // Concatenate 4 pixels into three 32 bit blocks
    126   uint32_t r0 = r<<24 | b<<16 | g<<8 | r;
    127   uint32_t r1 = g<<24 | r<<16 | b<<8 | g;
    128   uint32_t r2 = b<<24 | g<<16 | r<<8 | b;
    129 
    130   SPI1W0 = r0;
    131   SPI1W1 = r1;
    132   SPI1W2 = r2;
    133 
    134   if (len > 4)
    135   {
    136     SPI1W3 = r0;
    137     SPI1W4 = r1;
    138     SPI1W5 = r2;
    139   }
    140   if (len > 8)
    141   {
    142     SPI1W6 = r0;
    143     SPI1W7 = r1;
    144     SPI1W8 = r2;
    145   }
    146   if (len > 12)
    147   {
    148     SPI1W9  = r0;
    149     SPI1W10 = r1;
    150     SPI1W11 = r2;
    151     SPI1W12 = r0;
    152     SPI1W13 = r1;
    153     SPI1W14 = r2;
    154     SPI1W15 = r0;
    155   }
    156 
    157   if (len > 20)
    158   {
    159     SPI1U1 = (503 << SPILMOSI);
    160     while(len>20)
    161     {
    162       while(SPI1CMD & SPIBUSY) {}
    163       SPI1CMD |= SPIBUSY;
    164       len -= 21;
    165     }
    166     while(SPI1CMD & SPIBUSY) {}
    167   }
    168 
    169   if (len)
    170   {
    171     len = (len * 24) - 1;
    172     SPI1U1 = (len << SPILMOSI);
    173     SPI1CMD |= SPIBUSY;
    174     while(SPI1CMD & SPIBUSY) {}
    175   }
    176 
    177 }
    178 
    179 /***************************************************************************************
    180 ** Function name:           pushPixels - for ESP8266 and 3 byte RGB display
    181 ** Description:             Write a sequence of pixels
    182 ***************************************************************************************/
    183 void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
    184 
    185   uint16_t *data = (uint16_t*)data_in;
    186 
    187   // Send groups of 4 concatenated pixels
    188   if (len > 3) {
    189     SPI1U1 = ((4 * 24 - 1) << SPILMOSI);
    190     while (len > 3) {
    191 
    192       uint8_t  r[4];
    193       uint8_t  g[4];
    194       uint8_t  b[4];
    195 
    196       if (!_swapBytes) {
    197         // Split out the colours
    198         for (uint16_t i = 0; i < 4; i++) {
    199           uint16_t col = *data++;
    200           r[i] = (col & 0xF8);
    201           g[i] = (col & 0xE000)>>11 | (col & 0x07)<<5;
    202           b[i] = (col & 0x1F00)>>5;
    203         }
    204       }
    205       else {
    206         for (uint16_t i = 0; i < 4; i++) {
    207           uint16_t col = *data++;
    208           r[i] = (col & 0xF800)>>8;
    209           g[i] = (col & 0x07E0)>>3;
    210           b[i] = (col & 0x001F)<<3;
    211         }
    212       }
    213       uint32_t r0 = r[1]<<24 | b[0]<<16 | g[0]<<8 | r[0];
    214       uint32_t r1 = g[2]<<24 | r[2]<<16 | b[1]<<8 | g[1];
    215       uint32_t r2 = b[3]<<24 | g[3]<<16 | r[3]<<8 | b[2];
    216 
    217       while(SPI1CMD & SPIBUSY) {}
    218       SPI1W0 = r0;
    219       SPI1W1 = r1;
    220       SPI1W2 = r2;
    221 
    222       SPI1CMD |= SPIBUSY;
    223       len -= 4;
    224     }
    225     while(SPI1CMD & SPIBUSY) {}
    226   }
    227 
    228   // ILI9488 write macro is not endianess dependant, hence !_swapBytes
    229   if (!_swapBytes) while ( len-- ) { tft_Write_16S(*data); data++;}
    230   else while ( len-- ) {tft_Write_16(*data); data++;}
    231 }
    232 
    233 /***************************************************************************************
    234 ** Function name:           pushSwapBytePixels - for ESP8266 and 3 byte RGB display
    235 ** Description:             Write a sequence of pixels with swapped bytes
    236 ***************************************************************************************/
    237 void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
    238 
    239   uint16_t *data = (uint16_t*)data_in;
    240   // ILI9488 write macro is not endianess dependant, so swap byte macro not used here
    241   while ( len-- ) {tft_Write_16(*data); data++;}
    242 }
    243 
    244 ////////////////////////////////////////////////////////////////////////////////////////
    245 #else
    246 ////////////////////////////////////////////////////////////////////////////////////////
    247 
    248 /***************************************************************************************
    249 ** Function name:           pushBlock - for ESP8266
    250 ** Description:             Write a block of pixels of the same colour
    251 ***************************************************************************************/
    252 //Clear screen test 76.8ms theoretical. 81.5ms TFT_eSPI, 967ms Adafruit_ILI9341
    253 //Performance 26.15Mbps@26.66MHz, 39.04Mbps@40MHz, 75.4Mbps@80MHz SPI clock
    254 //Efficiency:
    255 //       TFT_eSPI       98.06%              97.59%          94.24%
    256 //       Adafruit_GFX   19.62%              14.31%           7.94%
    257 //
    258 void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
    259 {
    260 /*
    261 while (len>1) { tft_Write_32(color<<16 | color); len-=2;}
    262 if (len) tft_Write_16(color);
    263 return;
    264 //*/
    265   uint16_t color16 = (color >> 8) | (color << 8);
    266   uint32_t color32 = color16 | color16 << 16;
    267 /*
    268   while(len--) {
    269     SPI1U1 = ((16-1) << SPILMOSI) | ((16-1) << SPILMISO);
    270     SPI1W0 = color16;
    271     SPI1CMD |= SPIBUSY;
    272     while(SPI1CMD & SPIBUSY) {}
    273   }
    274   return;
    275 //*/
    276 
    277   SPI1W0 = color32;
    278   SPI1W1 = color32;
    279   SPI1W2 = color32;
    280   SPI1W3 = color32;
    281   if (len > 8)
    282   {
    283     SPI1W4 = color32;
    284     SPI1W5 = color32;
    285     SPI1W6 = color32;
    286     SPI1W7 = color32;
    287   }
    288   if (len > 16)
    289   {
    290     SPI1W8 = color32;
    291     SPI1W9 = color32;
    292     SPI1W10 = color32;
    293     SPI1W11 = color32;
    294   }
    295   if (len > 24)
    296   {
    297     SPI1W12 = color32;
    298     SPI1W13 = color32;
    299     SPI1W14 = color32;
    300     SPI1W15 = color32;
    301   }
    302   if (len > 31)
    303   {
    304     SPI1U1 = (511 << SPILMOSI);
    305     while(len>31)
    306     {
    307 #if (defined (SPI_FREQUENCY) && (SPI_FREQUENCY == 80000000))
    308       if(SPI1CMD & SPIBUSY) // added to sync with flag change
    309 #endif
    310       while(SPI1CMD & SPIBUSY) {}
    311       SPI1CMD |= SPIBUSY;
    312       len -= 32;
    313     }
    314     while(SPI1CMD & SPIBUSY) {}
    315   }
    316 
    317   if (len)
    318   {
    319     len = (len << 4) - 1;
    320     SPI1U1 = (len << SPILMOSI);
    321     SPI1CMD |= SPIBUSY;
    322     while(SPI1CMD & SPIBUSY) {}
    323   }
    324 
    325 }
    326 
    327 /***************************************************************************************
    328 ** Function name:           pushPixels - for ESP8266
    329 ** Description:             Write a sequence of pixels
    330 ***************************************************************************************/
    331 void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
    332 
    333   if(_swapBytes) {
    334     pushSwapBytePixels(data_in, len);
    335     return;
    336   }
    337 
    338   uint16_t *data = (uint16_t*) data_in;
    339 
    340   uint32_t color[8];
    341 
    342   SPI1U1 = (255 << SPILMOSI) | (255 << SPILMISO);
    343 
    344 
    345   while(len>15)
    346   {
    347     memcpy(color,data,32);
    348     data+=16;
    349 
    350     len -= 16;
    351 
    352     // ESP8266 wait time here at 40MHz SPI is ~5.45us
    353     while(SPI1CMD & SPIBUSY) {}
    354     SPI1W0 = color[0];
    355     SPI1W1 = color[1];
    356     SPI1W2 = color[2];
    357     SPI1W3 = color[3];
    358     SPI1W4 = color[4];
    359     SPI1W5 = color[5];
    360     SPI1W6 = color[6];
    361     SPI1W7 = color[7];
    362     SPI1CMD |= SPIBUSY;
    363   }
    364 
    365   if(len)
    366   {
    367     uint32_t bits = (len*16-1); // bits left to shift - 1
    368 
    369     memcpy(color,data,len<<1);
    370 
    371     while(SPI1CMD & SPIBUSY) {}
    372     SPI1U1 = (bits << SPILMOSI) | (bits << SPILMISO);
    373     SPI1W0 = color[0];
    374     SPI1W1 = color[1];
    375     SPI1W2 = color[2];
    376     SPI1W3 = color[3];
    377     SPI1W4 = color[4];
    378     SPI1W5 = color[5];
    379     SPI1W6 = color[6];
    380     SPI1W7 = color[7];
    381     SPI1CMD |= SPIBUSY;
    382   }
    383 
    384   while(SPI1CMD & SPIBUSY) {}
    385 
    386 }
    387 
    388 /***************************************************************************************
    389 ** Function name:           pushSwapBytePixels - for ESP8266
    390 ** Description:             Write a sequence of pixels with swapped bytes
    391 ***************************************************************************************/
    392 void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
    393 
    394   uint8_t* data = (uint8_t*)data_in;
    395   //uint16_t* data = (uint16_t*)data_in;
    396 
    397   uint32_t color[8];
    398 
    399   SPI1U1 = (255 << SPILMOSI) | (255 << SPILMISO);
    400 
    401   while(len>15)
    402   {
    403     uint32_t i = 0;
    404     while(i<8) { color[i++] = DAT8TO32(data); data+=4; }
    405 
    406     len -= 16;
    407 
    408     // ESP8266 wait time here at 40MHz SPI is ~5.45us
    409     while(SPI1CMD & SPIBUSY) {}
    410     SPI1W0 = color[0];
    411     SPI1W1 = color[1];
    412     SPI1W2 = color[2];
    413     SPI1W3 = color[3];
    414     SPI1W4 = color[4];
    415     SPI1W5 = color[5];
    416     SPI1W6 = color[6];
    417     SPI1W7 = color[7];
    418     SPI1CMD |= SPIBUSY;
    419   }
    420 
    421   if(len)
    422   {
    423     uint32_t i = 0;
    424     uint32_t bits = (len*16-1); // bits left to shift - 1
    425     len = (len+1)>>1;
    426     while(len--) { color[i++] = DAT8TO32(data); data+=4; }
    427 
    428     while(SPI1CMD & SPIBUSY) {}
    429     SPI1U1 = (bits << SPILMOSI) | (bits << SPILMISO);
    430     SPI1W0 = color[0];
    431     SPI1W1 = color[1];
    432     SPI1W2 = color[2];
    433     SPI1W3 = color[3];
    434     SPI1W4 = color[4];
    435     SPI1W5 = color[5];
    436     SPI1W6 = color[6];
    437     SPI1W7 = color[7];
    438     SPI1CMD |= SPIBUSY;
    439   }
    440 
    441   while(SPI1CMD & SPIBUSY) {}
    442 
    443 }
    444 
    445 ////////////////////////////////////////////////////////////////////////////////////////
    446 #endif
    447 ////////////////////////////////////////////////////////////////////////////////////////