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 |
Arduino_ESP32SPI.cpp (24632B)
1 /* 2 * start rewrite from: 3 * https://github.com/espressif/arduino-esp32.git 4 */ 5 #include "Arduino_ESP32SPI.h" 6 7 #if defined(ESP32) 8 9 #define WAIT_SPI_NOT_BUSY while (_spi->dev->cmd.usr) 10 11 struct spi_struct_t 12 { 13 spi_dev_t *dev; 14 #if !CONFIG_DISABLE_HAL_LOCKS 15 xSemaphoreHandle lock; 16 #endif 17 uint8_t num; 18 }; 19 20 #if CONFIG_DISABLE_HAL_LOCKS 21 #define SPI_MUTEX_LOCK() 22 #define SPI_MUTEX_UNLOCK() 23 24 static spi_t _spi_bus_array[] = { 25 #if CONFIG_IDF_TARGET_ESP32S2 26 {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0}, 27 {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1}, 28 {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2} 29 #elif CONFIG_IDF_TARGET_ESP32S3 30 {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0}, 31 {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1} 32 #else 33 {(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0}, 34 {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1}, 35 {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 2}, 36 {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3} 37 #endif 38 }; 39 #else // !CONFIG_DISABLE_HAL_LOCKS 40 #define SPI_MUTEX_LOCK() \ 41 do \ 42 { \ 43 } while (xSemaphoreTake(_spi->lock, portMAX_DELAY) != pdPASS) 44 #define SPI_MUTEX_UNLOCK() xSemaphoreGive(_spi->lock) 45 46 static spi_t _spi_bus_array[] = { 47 #if CONFIG_IDF_TARGET_ESP32S2 48 {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0}, 49 {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1}, 50 {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2} 51 #elif CONFIG_IDF_TARGET_ESP32S3 52 {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0}, 53 {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1} 54 #elif CONFIG_IDF_TARGET_ESP32C3 55 {(volatile spi_dev_t *)(&GPSPI2), NULL, FSPI} 56 #else 57 {(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0}, 58 {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1}, 59 {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2}, 60 {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3} 61 #endif 62 }; 63 #endif // CONFIG_DISABLE_HAL_LOCKS 64 65 Arduino_ESP32SPI::Arduino_ESP32SPI(int8_t dc /* = GFX_NOT_DEFINED */, int8_t cs /* = GFX_NOT_DEFINED */, int8_t sck /* = GFX_NOT_DEFINED */, int8_t mosi /* = GFX_NOT_DEFINED */, int8_t miso /* = GFX_NOT_DEFINED */, uint8_t spi_num /* = VSPI for ESP32, FSPI for S2 & C3 */, bool is_shared_interface /* = true */) 66 : _dc(dc), _spi_num(spi_num), _is_shared_interface(is_shared_interface) 67 { 68 #if CONFIG_IDF_TARGET_ESP32 69 if ( 70 sck == GFX_NOT_DEFINED && miso == GFX_NOT_DEFINED && mosi == GFX_NOT_DEFINED && cs == GFX_NOT_DEFINED) 71 { 72 _sck = (_spi_num == VSPI) ? SCK : 14; 73 _miso = (_spi_num == VSPI) ? MISO : 12; 74 _mosi = (_spi_num == VSPI) ? MOSI : 13; 75 _cs = (_spi_num == VSPI) ? SS : 15; 76 } 77 else 78 { 79 _sck = sck; 80 _miso = miso; 81 _mosi = mosi; 82 _cs = cs; 83 } 84 #else 85 if (sck == GFX_NOT_DEFINED && miso == GFX_NOT_DEFINED && mosi == GFX_NOT_DEFINED && cs == GFX_NOT_DEFINED) 86 { 87 _sck = SCK; 88 _miso = MISO; 89 _mosi = MOSI; 90 _cs = SS; 91 } 92 else 93 { 94 _sck = sck; 95 _miso = miso; 96 _mosi = mosi; 97 _cs = cs; 98 } 99 #endif 100 } 101 102 static void _on_apb_change(void *arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb) 103 { 104 spi_t *_spi = (spi_t *)arg; 105 if (ev_type == APB_BEFORE_CHANGE) 106 { 107 SPI_MUTEX_LOCK(); 108 WAIT_SPI_NOT_BUSY; 109 } 110 else 111 { 112 _spi->dev->clock.val = spiFrequencyToClockDiv(old_apb / ((_spi->dev->clock.clkdiv_pre + 1) * (_spi->dev->clock.clkcnt_n + 1))); 113 SPI_MUTEX_UNLOCK(); 114 } 115 } 116 117 static void spiInitBus(spi_t *spi) 118 { 119 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 120 spi->dev->slave.trans_done = 0; 121 #endif 122 spi->dev->slave.val = 0; 123 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 124 spi->dev->misc.val = 0; 125 #else 126 spi->dev->pin.val = 0; 127 #endif 128 spi->dev->user.val = 0; 129 spi->dev->user1.val = 0; 130 spi->dev->ctrl.val = 0; 131 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 132 spi->dev->ctrl1.val = 0; 133 spi->dev->ctrl2.val = 0; 134 #else 135 spi->dev->clk_gate.val = 0; 136 spi->dev->dma_conf.val = 0; 137 spi->dev->dma_conf.rx_afifo_rst = 1; 138 spi->dev->dma_conf.buf_afifo_rst = 1; 139 #endif 140 spi->dev->clock.val = 0; 141 } 142 143 bool Arduino_ESP32SPI::begin(int32_t speed, int8_t dataMode) 144 { 145 // set SPI parameters 146 _speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed; 147 _dataMode = (dataMode == GFX_NOT_DEFINED) ? SPI_MODE0 : dataMode; 148 149 if (!_div) 150 { 151 _div = spiFrequencyToClockDiv(_speed); 152 } 153 154 // set pin mode 155 if (_dc != GFX_NOT_DEFINED) 156 { 157 pinMode(_dc, OUTPUT); 158 digitalWrite(_dc, HIGH); // Data mode 159 } 160 if (_cs != GFX_NOT_DEFINED) 161 { 162 pinMode(_cs, OUTPUT); 163 digitalWrite(_cs, HIGH); // disable chip select 164 } 165 166 #if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3) 167 // set fastIO variables 168 if (_dc >= 32) 169 { 170 _dcPinMask = digitalPinToBitMask(_dc); 171 _dcPortSet = (PORTreg_t)&GPIO.out1_w1ts.val; 172 _dcPortClr = (PORTreg_t)&GPIO.out1_w1tc.val; 173 } 174 else 175 #endif 176 if (_dc != GFX_NOT_DEFINED) 177 { 178 _dcPinMask = digitalPinToBitMask(_dc); 179 _dcPortSet = (PORTreg_t)&GPIO.out_w1ts; 180 _dcPortClr = (PORTreg_t)&GPIO.out_w1tc; 181 } 182 183 #if (CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3) 184 if (_cs >= 32) 185 { 186 _csPinMask = digitalPinToBitMask(_cs); 187 _csPortSet = (PORTreg_t)&GPIO.out1_w1ts.val; 188 _csPortClr = (PORTreg_t)&GPIO.out1_w1tc.val; 189 } 190 else 191 #endif 192 if (_cs != GFX_NOT_DEFINED) 193 { 194 _csPinMask = digitalPinToBitMask(_cs); 195 _csPortSet = (PORTreg_t)&GPIO.out_w1ts; 196 _csPortClr = (PORTreg_t)&GPIO.out_w1tc; 197 } 198 199 // SPI.begin(_sck, _miso, _mosi); 200 // _spi = spiStartBus(_spi_num, _div, SPI_MODE0, SPI_MSBFIRST); 201 _spi = &_spi_bus_array[_spi_num]; 202 203 #if !CONFIG_DISABLE_HAL_LOCKS 204 if (_spi->lock == NULL) 205 { 206 _spi->lock = xSemaphoreCreateMutex(); 207 } 208 #endif 209 210 #if CONFIG_IDF_TARGET_ESP32S2 211 if (_spi_num == FSPI) 212 { 213 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN); 214 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI2_RST); 215 } 216 else if (_spi_num == HSPI) 217 { 218 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN); 219 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST); 220 } 221 else 222 { 223 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN); 224 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST); 225 } 226 #elif CONFIG_IDF_TARGET_ESP32S3 227 if (_spi_num == FSPI) 228 { 229 periph_module_reset(PERIPH_SPI2_MODULE); 230 periph_module_enable(PERIPH_SPI2_MODULE); 231 } 232 else if (_spi_num == HSPI) 233 { 234 periph_module_reset(PERIPH_SPI3_MODULE); 235 periph_module_enable(PERIPH_SPI3_MODULE); 236 } 237 #elif CONFIG_IDF_TARGET_ESP32 238 if (_spi_num == HSPI) 239 { 240 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN); 241 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI2_RST); 242 } 243 else if (_spi_num == VSPI) 244 { 245 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN); 246 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST); 247 } 248 else 249 { 250 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN); 251 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST); 252 } 253 #elif CONFIG_IDF_TARGET_ESP32C3 254 periph_module_reset(PERIPH_SPI2_MODULE); 255 periph_module_enable(PERIPH_SPI2_MODULE); 256 #endif 257 258 SPI_MUTEX_LOCK(); 259 spiInitBus(_spi); 260 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 261 _spi->dev->clk_gate.clk_en = 1; 262 _spi->dev->clk_gate.mst_clk_sel = 1; 263 _spi->dev->clk_gate.mst_clk_active = 1; 264 _spi->dev->dma_conf.tx_seg_trans_clr_en = 1; 265 _spi->dev->dma_conf.rx_seg_trans_clr_en = 1; 266 _spi->dev->dma_conf.dma_seg_trans_en = 0; 267 #endif 268 _spi->dev->user.usr_mosi = 1; 269 if (_miso < 0) 270 { 271 _spi->dev->user.usr_miso = 0; 272 _spi->dev->user.doutdin = 0; 273 } 274 else 275 { 276 _spi->dev->user.usr_miso = 1; 277 _spi->dev->user.doutdin = 1; 278 } 279 280 for (uint8_t i = 0; i < 16; i++) 281 { 282 _spi->dev->data_buf[i] = 0x00000000; 283 } 284 SPI_MUTEX_UNLOCK(); 285 286 spiSetDataMode(_spi, _dataMode); 287 spiSetBitOrder(_spi, _bitOrder); 288 spiSetClockDiv(_spi, _div); 289 290 addApbChangeCallback(_spi, _on_apb_change); 291 292 spiAttachSCK(_spi, _sck); 293 294 if (_miso != GFX_NOT_DEFINED) 295 { 296 spiAttachMISO(_spi, _miso); 297 } 298 299 spiAttachMOSI(_spi, _mosi); 300 301 if (!_is_shared_interface) 302 { 303 spiTransaction(_spi, _div, _dataMode, _bitOrder); 304 } 305 306 return true; 307 } 308 309 void Arduino_ESP32SPI::beginWrite() 310 { 311 _data_buf_bit_idx = 0; 312 _buffer[0] = 0; 313 314 if (_is_shared_interface) 315 { 316 spiTransaction(_spi, _div, _dataMode, _bitOrder); 317 } 318 319 if (_dc != GFX_NOT_DEFINED) 320 { 321 DC_HIGH(); 322 } 323 CS_LOW(); 324 } 325 326 void Arduino_ESP32SPI::endWrite() 327 { 328 if (_data_buf_bit_idx > 0) 329 { 330 flush_data_buf(); 331 } 332 333 if (_is_shared_interface) 334 { 335 spiEndTransaction(_spi); 336 } 337 338 CS_HIGH(); 339 } 340 341 void Arduino_ESP32SPI::writeCommand(uint8_t c) 342 { 343 if (_dc < 0) // 9-bit SPI 344 { 345 WRITE9BIT(c); 346 } 347 else 348 { 349 if (_data_buf_bit_idx > 0) 350 { 351 flush_data_buf(); 352 } 353 354 DC_LOW(); 355 356 MOSI_BIT_LEN = 7; 357 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 358 MISO_BIT_LEN = 0; 359 #endif 360 _spi->dev->data_buf[0] = c; 361 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 362 _spi->dev->cmd.update = 1; 363 while (_spi->dev->cmd.update) 364 ; 365 #endif 366 _spi->dev->cmd.usr = 1; 367 WAIT_SPI_NOT_BUSY; 368 369 DC_HIGH(); 370 } 371 } 372 373 void Arduino_ESP32SPI::writeCommand16(uint16_t c) 374 { 375 if (_dc < 0) // 9-bit SPI 376 { 377 _data16.value = c; 378 WRITE9BIT(_data16.msb); 379 WRITE9BIT(_data16.lsb); 380 } 381 else 382 { 383 if (_data_buf_bit_idx > 0) 384 { 385 flush_data_buf(); 386 } 387 388 DC_LOW(); 389 390 MOSI_BIT_LEN = 15; 391 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 392 MISO_BIT_LEN = 0; 393 #endif 394 MSB_16_SET(_spi->dev->data_buf[0], c); 395 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 396 _spi->dev->cmd.update = 1; 397 while (_spi->dev->cmd.update) 398 ; 399 #endif 400 _spi->dev->cmd.usr = 1; 401 WAIT_SPI_NOT_BUSY; 402 403 DC_HIGH(); 404 } 405 } 406 407 void Arduino_ESP32SPI::write(uint8_t d) 408 { 409 if (_dc < 0) // 9-bit SPI 410 { 411 WRITE9BIT(0x100 | d); 412 } 413 else 414 { 415 WRITE8BIT(d); 416 } 417 } 418 419 void Arduino_ESP32SPI::write16(uint16_t d) 420 { 421 _data16.value = d; 422 if (_dc < 0) // 9-bit SPI 423 { 424 WRITE9BIT(0x100 | _data16.msb); 425 WRITE9BIT(0x100 | _data16.lsb); 426 } 427 else 428 { 429 WRITE8BIT(_data16.msb); 430 WRITE8BIT(_data16.lsb); 431 } 432 } 433 434 void Arduino_ESP32SPI::writeRepeat(uint16_t p, uint32_t len) 435 { 436 if (_data_buf_bit_idx > 0) 437 { 438 flush_data_buf(); 439 } 440 441 if (_dc < 0) // 9-bit SPI 442 { 443 _data16.value = p; 444 uint32_t hi = 0x100 | _data16.msb; 445 uint32_t lo = 0x100 | _data16.lsb; 446 uint16_t idx; 447 uint8_t shift; 448 uint32_t l; 449 uint16_t bufLen = (len <= 28) ? len : 28; 450 int16_t xferLen; 451 for (uint32_t t = 0; t < bufLen; t++) 452 { 453 idx = _data_buf_bit_idx >> 3; 454 shift = (_data_buf_bit_idx % 8); 455 if (shift) 456 { 457 _buffer[idx++] |= hi >> (shift + 1); 458 _buffer[idx] = hi << (7 - shift); 459 } 460 else 461 { 462 _buffer[idx++] = hi >> 1; 463 _buffer[idx] = hi << 7; 464 } 465 _data_buf_bit_idx += 9; 466 467 idx = _data_buf_bit_idx >> 3; 468 shift = (_data_buf_bit_idx % 8); 469 if (shift) 470 { 471 _buffer[idx++] |= lo >> (shift + 1); 472 _buffer[idx] = lo << (7 - shift); 473 } 474 else 475 { 476 _buffer[idx++] = lo >> 1; 477 _buffer[idx] = lo << 7; 478 } 479 _data_buf_bit_idx += 9; 480 } 481 482 if (_miso < 0) 483 { 484 l = (_data_buf_bit_idx + 31) / 32; 485 for (uint32_t i = 0; i < l; i++) 486 { 487 _spi->dev->data_buf[i] = _buffer32[i]; 488 } 489 } 490 491 // Issue pixels in blocks from temp buffer 492 while (len) // While pixels remain 493 { 494 xferLen = (bufLen < len) ? bufLen : len; // How many this pass? 495 _data_buf_bit_idx = xferLen * 18; 496 MOSI_BIT_LEN = _data_buf_bit_idx - 1; 497 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 498 MISO_BIT_LEN = 0; 499 #endif 500 if (_miso != GFX_NOT_DEFINED) 501 { 502 l = (_data_buf_bit_idx + 31) / 32; 503 for (uint32_t i = 0; i < l; i++) 504 { 505 _spi->dev->data_buf[i] = _buffer32[i]; 506 } 507 } 508 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 509 _spi->dev->cmd.update = 1; 510 while (_spi->dev->cmd.update) 511 ; 512 #endif 513 _spi->dev->cmd.usr = 1; 514 WAIT_SPI_NOT_BUSY; 515 516 len -= xferLen; 517 } 518 } 519 else // 8-bit SPI 520 { 521 uint16_t bufLen = (len < 32) ? len : 32; 522 int16_t xferLen, l; 523 uint32_t c32; 524 MSB_32_16_16_SET(c32, p, p); 525 526 if (_miso < 0) 527 { 528 l = (bufLen + 1) / 2; 529 for (uint32_t i = 0; i < l; i++) 530 { 531 _spi->dev->data_buf[i] = c32; 532 } 533 } 534 535 // Issue pixels in blocks from temp buffer 536 while (len) // While pixels remain 537 { 538 xferLen = (bufLen <= len) ? bufLen : len; // How many this pass? 539 MOSI_BIT_LEN = (xferLen * 16) - 1; 540 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 541 MISO_BIT_LEN = 0; 542 #endif 543 if (_miso != GFX_NOT_DEFINED) 544 { 545 l = (xferLen + 1) / 2; 546 for (uint32_t i = 0; i < l; i++) 547 { 548 _spi->dev->data_buf[i] = c32; 549 } 550 } 551 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 552 _spi->dev->cmd.update = 1; 553 while (_spi->dev->cmd.update) 554 ; 555 #endif 556 _spi->dev->cmd.usr = 1; 557 WAIT_SPI_NOT_BUSY; 558 559 len -= xferLen; 560 } 561 } 562 563 _data_buf_bit_idx = 0; 564 } 565 566 void Arduino_ESP32SPI::writePixels(uint16_t *data, uint32_t len) 567 { 568 if (_dc < 0) // 9-bit SPI 569 { 570 while (len--) 571 { 572 write16(*data++); 573 } 574 } 575 else // 8-bit SPI 576 { 577 uint16_t p1, p2; 578 if (len >= 32) 579 { 580 if (_data_buf_bit_idx > 0) 581 { 582 flush_data_buf(); 583 } 584 585 MOSI_BIT_LEN = 511; 586 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 587 MISO_BIT_LEN = 0; 588 #endif 589 while (len >= 32) 590 { 591 for (uint8_t i = 0; i < 16; i++) 592 { 593 p1 = *data++; 594 p2 = *data++; 595 MSB_32_16_16_SET(_spi->dev->data_buf[i], p1, p2); 596 } 597 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 598 _spi->dev->cmd.update = 1; 599 while (_spi->dev->cmd.update) 600 ; 601 #endif 602 _spi->dev->cmd.usr = 1; 603 WAIT_SPI_NOT_BUSY; 604 605 len -= 32; 606 } 607 } 608 609 if ((len > 0) && ((len % 2) == 0)) 610 { 611 if (_data_buf_bit_idx > 0) 612 { 613 flush_data_buf(); 614 } 615 616 MOSI_BIT_LEN = (len * 16) - 1; 617 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 618 MISO_BIT_LEN = 0; 619 #endif 620 len >>= 1; // 2 pixels to a 32-bit data 621 for (uint32_t i = 0; i < len; i++) 622 { 623 p1 = *data++; 624 p2 = *data++; 625 MSB_32_16_16_SET(_spi->dev->data_buf[i], p1, p2); 626 } 627 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 628 _spi->dev->cmd.update = 1; 629 while (_spi->dev->cmd.update) 630 ; 631 #endif 632 _spi->dev->cmd.usr = 1; 633 WAIT_SPI_NOT_BUSY; 634 } 635 else 636 { 637 while (len--) 638 { 639 write16(*data++); 640 } 641 } 642 } 643 } 644 645 void Arduino_ESP32SPI::writeC8D8(uint8_t c, uint8_t d) 646 { 647 if (_dc < 0) // 9-bit SPI 648 { 649 WRITE9BIT(c); 650 WRITE9BIT(0x100 | d); 651 } 652 else 653 { 654 if (_data_buf_bit_idx > 0) 655 { 656 flush_data_buf(); 657 } 658 659 DC_LOW(); 660 661 MOSI_BIT_LEN = 7; 662 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 663 MISO_BIT_LEN = 0; 664 #endif 665 _spi->dev->data_buf[0] = c; 666 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 667 _spi->dev->cmd.update = 1; 668 while (_spi->dev->cmd.update) 669 ; 670 #endif 671 _spi->dev->cmd.usr = 1; 672 WAIT_SPI_NOT_BUSY; 673 674 DC_HIGH(); 675 676 MOSI_BIT_LEN = 7; 677 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 678 MISO_BIT_LEN = 0; 679 #endif 680 _spi->dev->data_buf[0] = d; 681 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 682 _spi->dev->cmd.update = 1; 683 while (_spi->dev->cmd.update) 684 ; 685 #endif 686 _spi->dev->cmd.usr = 1; 687 WAIT_SPI_NOT_BUSY; 688 } 689 } 690 691 void Arduino_ESP32SPI::writeC8D16(uint8_t c, uint16_t d) 692 { 693 if (_dc < 0) // 9-bit SPI 694 { 695 WRITE9BIT(c); 696 _data16.value = d; 697 WRITE9BIT(0x100 | _data16.msb); 698 WRITE9BIT(0x100 | _data16.lsb); 699 } 700 else 701 { 702 if (_data_buf_bit_idx > 0) 703 { 704 flush_data_buf(); 705 } 706 707 DC_LOW(); 708 709 MOSI_BIT_LEN = 7; 710 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 711 MISO_BIT_LEN = 0; 712 #endif 713 _spi->dev->data_buf[0] = c; 714 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 715 _spi->dev->cmd.update = 1; 716 while (_spi->dev->cmd.update) 717 ; 718 #endif 719 _spi->dev->cmd.usr = 1; 720 WAIT_SPI_NOT_BUSY; 721 722 DC_HIGH(); 723 724 MOSI_BIT_LEN = 15; 725 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 726 MISO_BIT_LEN = 0; 727 #endif 728 MSB_16_SET(_spi->dev->data_buf[0], d); 729 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 730 _spi->dev->cmd.update = 1; 731 while (_spi->dev->cmd.update) 732 ; 733 #endif 734 _spi->dev->cmd.usr = 1; 735 WAIT_SPI_NOT_BUSY; 736 } 737 } 738 739 void Arduino_ESP32SPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) 740 { 741 if (_dc < 0) // 9-bit SPI 742 { 743 WRITE9BIT(c); 744 _data16.value = d1; 745 WRITE9BIT(0x100 | _data16.msb); 746 WRITE9BIT(0x100 | _data16.lsb); 747 _data16.value = d2; 748 WRITE9BIT(0x100 | _data16.msb); 749 WRITE9BIT(0x100 | _data16.lsb); 750 } 751 else 752 { 753 if (_data_buf_bit_idx > 0) 754 { 755 flush_data_buf(); 756 } 757 758 DC_LOW(); 759 760 MOSI_BIT_LEN = 7; 761 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 762 MISO_BIT_LEN = 0; 763 #endif 764 _spi->dev->data_buf[0] = c; 765 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 766 _spi->dev->cmd.update = 1; 767 while (_spi->dev->cmd.update) 768 ; 769 #endif 770 _spi->dev->cmd.usr = 1; 771 WAIT_SPI_NOT_BUSY; 772 773 DC_HIGH(); 774 775 MOSI_BIT_LEN = 31; 776 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 777 MISO_BIT_LEN = 0; 778 #endif 779 MSB_32_16_16_SET(_spi->dev->data_buf[0], d1, d2); 780 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 781 _spi->dev->cmd.update = 1; 782 while (_spi->dev->cmd.update) 783 ; 784 #endif 785 _spi->dev->cmd.usr = 1; 786 WAIT_SPI_NOT_BUSY; 787 } 788 } 789 790 void Arduino_ESP32SPI::writeBytes(uint8_t *data, uint32_t len) 791 { 792 if (_dc < 0) // 9-bit SPI 793 { 794 while (len--) 795 { 796 write(*data++); 797 } 798 } 799 else // 8-bit SPI 800 { 801 uint32_t *p = (uint32_t *)data; 802 if (len >= 64) 803 { 804 if (_data_buf_bit_idx > 0) 805 { 806 flush_data_buf(); 807 } 808 MOSI_BIT_LEN = 511; 809 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 810 MISO_BIT_LEN = 0; 811 #endif 812 while (len >= 64) 813 { 814 for (uint32_t i = 0; i < 16; i++) 815 { 816 _spi->dev->data_buf[i] = *p++; 817 } 818 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 819 _spi->dev->cmd.update = 1; 820 while (_spi->dev->cmd.update) 821 ; 822 #endif 823 _spi->dev->cmd.usr = 1; 824 WAIT_SPI_NOT_BUSY; 825 826 len -= 64; 827 data += 64; 828 } 829 } 830 831 if ((len > 0) && ((len % 4) == 0)) 832 { 833 if (_data_buf_bit_idx > 0) 834 { 835 flush_data_buf(); 836 } 837 838 MOSI_BIT_LEN = (len * 8) - 1; 839 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 840 MISO_BIT_LEN = 0; 841 #endif 842 len >>= 2; // 4 bytes to a 32-bit data 843 for (uint32_t i = 0; i < len; i++) 844 { 845 _spi->dev->data_buf[i] = *p++; 846 } 847 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 848 _spi->dev->cmd.update = 1; 849 while (_spi->dev->cmd.update) 850 ; 851 #endif 852 _spi->dev->cmd.usr = 1; 853 WAIT_SPI_NOT_BUSY; 854 } 855 else 856 { 857 while (len--) 858 { 859 write(*data++); 860 } 861 } 862 } 863 } 864 865 void Arduino_ESP32SPI::writePattern(uint8_t *data, uint8_t len, uint32_t repeat) 866 { 867 while (repeat--) 868 { 869 writeBytes(data, len); 870 } 871 } 872 873 void Arduino_ESP32SPI::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len) 874 { 875 if (_dc < 0) // 9-bit SPI 876 { 877 while (len--) 878 { 879 write16(idx[*data++]); 880 } 881 } 882 else // 8-bit SPI 883 { 884 uint16_t p1, p2; 885 if (len >= 32) 886 { 887 if (_data_buf_bit_idx > 0) 888 { 889 flush_data_buf(); 890 } 891 892 MOSI_BIT_LEN = 511; 893 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 894 MISO_BIT_LEN = 0; 895 #endif 896 while (len >= 32) 897 { 898 for (uint8_t i = 0; i < 16; i++) 899 { 900 p1 = idx[*data++]; 901 p2 = idx[*data++]; 902 MSB_32_16_16_SET(_spi->dev->data_buf[i], p1, p2); 903 } 904 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 905 _spi->dev->cmd.update = 1; 906 while (_spi->dev->cmd.update) 907 ; 908 #endif 909 _spi->dev->cmd.usr = 1; 910 WAIT_SPI_NOT_BUSY; 911 912 len -= 32; 913 } 914 } 915 916 if ((len > 0) && ((len % 2) == 0)) 917 { 918 if (_data_buf_bit_idx > 0) 919 { 920 flush_data_buf(); 921 } 922 923 MOSI_BIT_LEN = (len * 16) - 1; 924 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 925 MISO_BIT_LEN = 0; 926 #endif 927 len >>= 1; // 2 pixels to a 32-bit data 928 for (uint32_t i = 0; i < len; i++) 929 { 930 p1 = *data++; 931 p2 = *data++; 932 MSB_32_16_16_SET(_spi->dev->data_buf[i], p1, p2); 933 } 934 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 935 _spi->dev->cmd.update = 1; 936 while (_spi->dev->cmd.update) 937 ; 938 #endif 939 _spi->dev->cmd.usr = 1; 940 WAIT_SPI_NOT_BUSY; 941 } 942 else 943 { 944 while (len--) 945 { 946 write16(*data++); 947 } 948 } 949 } 950 } 951 952 void Arduino_ESP32SPI::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len) 953 { 954 uint16_t p; 955 if (_dc < 0) // 9-bit SPI 956 { 957 uint16_t hi, lo; 958 while (len--) 959 { 960 _data16.value = idx[*data++]; 961 hi = 0x100 | _data16.msb; 962 lo = 0x100 | _data16.lsb; 963 WRITE9BIT(hi); 964 WRITE9BIT(lo); 965 WRITE9BIT(hi); 966 WRITE9BIT(lo); 967 } 968 } 969 else // 8-bit SPI 970 { 971 if (len >= 16) 972 { 973 if (_data_buf_bit_idx > 0) 974 { 975 flush_data_buf(); 976 } 977 978 MOSI_BIT_LEN = 511; 979 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 980 MISO_BIT_LEN = 0; 981 #endif 982 while (len >= 16) 983 { 984 for (uint8_t i = 0; i < 16; i++) 985 { 986 p = idx[*data++]; 987 MSB_32_16_16_SET(_spi->dev->data_buf[i], p, p); 988 } 989 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 990 _spi->dev->cmd.update = 1; 991 while (_spi->dev->cmd.update) 992 ; 993 #endif 994 _spi->dev->cmd.usr = 1; 995 WAIT_SPI_NOT_BUSY; 996 997 len -= 16; 998 } 999 } 1000 1001 if ((len > 0) && ((len % 2) == 0)) 1002 { 1003 if (_data_buf_bit_idx > 0) 1004 { 1005 flush_data_buf(); 1006 } 1007 1008 MOSI_BIT_LEN = (len * 16) - 1; 1009 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 1010 MISO_BIT_LEN = 0; 1011 #endif 1012 for (uint32_t i = 0; i < len; i++) 1013 { 1014 p = idx[*data++]; 1015 MSB_32_16_16_SET(_spi->dev->data_buf[i], p, p); 1016 } 1017 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 1018 _spi->dev->cmd.update = 1; 1019 while (_spi->dev->cmd.update) 1020 ; 1021 #endif 1022 _spi->dev->cmd.usr = 1; 1023 WAIT_SPI_NOT_BUSY; 1024 } 1025 else 1026 { 1027 while (len--) 1028 { 1029 write16(*data++); 1030 } 1031 } 1032 } 1033 } 1034 1035 void Arduino_ESP32SPI::flush_data_buf() 1036 { 1037 MOSI_BIT_LEN = _data_buf_bit_idx - 1; 1038 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 1039 MISO_BIT_LEN = 0; 1040 #endif 1041 uint32_t len = (_data_buf_bit_idx + 31) / 32; 1042 for (uint32_t i = 0; i < len; i++) 1043 { 1044 _spi->dev->data_buf[i] = _buffer32[i]; 1045 } 1046 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 1047 _spi->dev->cmd.update = 1; 1048 while (_spi->dev->cmd.update) 1049 ; 1050 #endif 1051 _spi->dev->cmd.usr = 1; 1052 WAIT_SPI_NOT_BUSY; 1053 1054 _data_buf_bit_idx = 0; 1055 } 1056 1057 INLINE void Arduino_ESP32SPI::WRITE8BIT(uint8_t d) 1058 { 1059 uint16_t idx = _data_buf_bit_idx >> 3; 1060 _buffer[idx] = d; 1061 _data_buf_bit_idx += 8; 1062 if (_data_buf_bit_idx >= 512) 1063 { 1064 flush_data_buf(); 1065 } 1066 } 1067 1068 INLINE void Arduino_ESP32SPI::WRITE9BIT(uint32_t d) 1069 { 1070 uint16_t idx = _data_buf_bit_idx >> 3; 1071 uint8_t shift = (_data_buf_bit_idx % 8); 1072 if (shift) 1073 { 1074 _buffer[idx++] |= d >> (shift + 1); 1075 _buffer[idx] = d << (7 - shift); 1076 } 1077 else 1078 { 1079 _buffer[idx++] = d >> 1; 1080 _buffer[idx] = d << 7; 1081 } 1082 _data_buf_bit_idx += 9; 1083 if (_data_buf_bit_idx >= 504) // 56 bytes * 9 bits 1084 { 1085 flush_data_buf(); 1086 } 1087 } 1088 1089 /******** low level bit twiddling **********/ 1090 1091 INLINE void Arduino_ESP32SPI::DC_HIGH(void) 1092 { 1093 *_dcPortSet = _dcPinMask; 1094 } 1095 1096 INLINE void Arduino_ESP32SPI::DC_LOW(void) 1097 { 1098 *_dcPortClr = _dcPinMask; 1099 } 1100 1101 INLINE void Arduino_ESP32SPI::CS_HIGH(void) 1102 { 1103 if (_cs != GFX_NOT_DEFINED) 1104 { 1105 *_csPortSet = _csPinMask; 1106 } 1107 } 1108 1109 INLINE void Arduino_ESP32SPI::CS_LOW(void) 1110 { 1111 if (_cs != GFX_NOT_DEFINED) 1112 { 1113 *_csPortClr = _csPinMask; 1114 } 1115 } 1116 1117 #endif // #if defined(ESP32)