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_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 ////////////////////////////////////////////////////////////////////////////////////////