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_HWSPI.cpp (11851B)
1 /* 2 * start rewrite from: 3 * https://github.com/adafruit/Adafruit-GFX-Library.git 4 */ 5 #include "Arduino_HWSPI.h" 6 7 #if defined(SPI_HAS_TRANSACTION) 8 #define SPI_BEGIN_TRANSACTION() _spi->beginTransaction(mySPISettings) 9 #define SPI_END_TRANSACTION() _spi->endTransaction() 10 #else 11 #define SPI_BEGIN_TRANSACTION() \ 12 { \ 13 } 14 #define SPI_END_TRANSACTION() \ 15 { \ 16 } 17 #endif 18 19 #if defined(SPI_HAS_TRANSACTION) 20 static SPISettings mySPISettings; 21 #elif defined(__AVR__) || defined(CORE_TEENSY) 22 static uint8_t SPCRbackup; 23 static uint8_t mySPCR; 24 #endif 25 26 #if defined(ESP32) 27 Arduino_HWSPI::Arduino_HWSPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */, int8_t sck /* = GFX_NOT_DEFINED */, int8_t mosi /* = GFX_NOT_DEFINED */, int8_t miso /* = GFX_NOT_DEFINED */, SPIClass *spi, bool is_shared_interface /* = true */) 28 : _dc(dc), _cs(cs), _sck(sck), _mosi(mosi), _miso(miso), _spi(spi), _is_shared_interface(is_shared_interface) 29 { 30 #else 31 Arduino_HWSPI::Arduino_HWSPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */, SPIClass *spi, bool is_shared_interface /* = true */) 32 : _dc(dc), _cs(cs), _spi(spi), _is_shared_interface(is_shared_interface) 33 { 34 #endif 35 } 36 37 bool Arduino_HWSPI::begin(int32_t speed, int8_t dataMode) 38 { 39 _speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed; 40 _dataMode = dataMode; 41 42 pinMode(_dc, OUTPUT); 43 digitalWrite(_dc, HIGH); // Data mode 44 if (_cs != GFX_NOT_DEFINED) 45 { 46 pinMode(_cs, OUTPUT); 47 digitalWrite(_cs, HIGH); // Deselect 48 } 49 50 #if defined(USE_FAST_PINIO) 51 #if defined(HAS_PORT_SET_CLR) 52 #if defined(ARDUINO_ARCH_NRF52840) 53 uint32_t pin = digitalPinToPinName((pin_size_t)_dc); 54 NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin); 55 _dcPortSet = ®->OUTSET; 56 _dcPortClr = ®->OUTCLR; 57 _dcPinMask = 1UL << pin; 58 if (_cs != GFX_NOT_DEFINED) 59 { 60 pin = digitalPinToPinName((pin_size_t)_cs); 61 reg = nrf_gpio_pin_port_decode(&pin); 62 _csPortSet = ®->OUTSET; 63 _csPortClr = ®->OUTCLR; 64 _csPinMask = 1UL << pin; 65 } 66 #elif defined(TARGET_RP2040) 67 _dcPinMask = digitalPinToBitMask(_dc); 68 _dcPortSet = (PORTreg_t)&sio_hw->gpio_set; 69 _dcPortClr = (PORTreg_t)&sio_hw->gpio_clr; 70 if (_cs != GFX_NOT_DEFINED) 71 { 72 _csPinMask = digitalPinToBitMask(_cs); 73 _csPortSet = (PORTreg_t)&sio_hw->gpio_set; 74 _csPortClr = (PORTreg_t)&sio_hw->gpio_clr; 75 } 76 #elif defined(ESP32) && (CONFIG_IDF_TARGET_ESP32C3) 77 _dcPinMask = digitalPinToBitMask(_dc); 78 _dcPortSet = (PORTreg_t)&GPIO.out_w1ts; 79 _dcPortClr = (PORTreg_t)&GPIO.out_w1tc; 80 if (_cs != GFX_NOT_DEFINED) 81 { 82 _csPinMask = digitalPinToBitMask(_cs); 83 _csPortSet = (PORTreg_t)&GPIO.out_w1ts; 84 _csPortClr = (PORTreg_t)&GPIO.out_w1tc; 85 } 86 #elif defined(ESP32) 87 _dcPinMask = digitalPinToBitMask(_dc); 88 if (_dc >= 32) 89 { 90 _dcPortSet = (PORTreg_t)&GPIO.out1_w1ts.val; 91 _dcPortClr = (PORTreg_t)&GPIO.out1_w1tc.val; 92 } 93 else 94 { 95 _dcPortSet = (PORTreg_t)&GPIO.out_w1ts; 96 _dcPortClr = (PORTreg_t)&GPIO.out_w1tc; 97 } 98 if (_cs >= 32) 99 { 100 _csPinMask = digitalPinToBitMask(_cs); 101 _csPortSet = (PORTreg_t)&GPIO.out1_w1ts.val; 102 _csPortClr = (PORTreg_t)&GPIO.out1_w1tc.val; 103 } 104 else if (_cs != GFX_NOT_DEFINED) 105 { 106 _csPinMask = digitalPinToBitMask(_cs); 107 _csPortSet = (PORTreg_t)&GPIO.out_w1ts; 108 _csPortClr = (PORTreg_t)&GPIO.out_w1tc; 109 } 110 #elif defined(CORE_TEENSY) 111 #if !defined(KINETISK) 112 _dcPinMask = digitalPinToBitMask(_dc); 113 #endif 114 _dcPortSet = portSetRegister(_dc); 115 _dcPortClr = portClearRegister(_dc); 116 if (_cs != GFX_NOT_DEFINED) 117 { 118 #if !defined(KINETISK) 119 _csPinMask = digitalPinToBitMask(_cs); 120 #endif 121 _csPortSet = portSetRegister(_cs); 122 _csPortClr = portClearRegister(_cs); 123 } 124 #else // !CORE_TEENSY 125 _dcPinMask = digitalPinToBitMask(_dc); 126 _dcPortSet = &(PORT->Group[g_APinDescription[_dc].ulPort].OUTSET.reg); 127 _dcPortClr = &(PORT->Group[g_APinDescription[_dc].ulPort].OUTCLR.reg); 128 if (_cs != GFX_NOT_DEFINED) 129 { 130 _csPinMask = digitalPinToBitMask(_cs); 131 _csPortSet = &(PORT->Group[g_APinDescription[_cs].ulPort].OUTSET.reg); 132 _csPortClr = &(PORT->Group[g_APinDescription[_cs].ulPort].OUTCLR.reg); 133 } 134 #endif // end !CORE_TEENSY 135 #else // !HAS_PORT_SET_CLR 136 _dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc)); 137 _dcPinMaskSet = digitalPinToBitMask(_dc); 138 _dcPinMaskClr = ~_dcPinMaskSet; 139 if (_cs != GFX_NOT_DEFINED) 140 { 141 _csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs)); 142 _csPinMaskSet = digitalPinToBitMask(_cs); 143 } 144 _csPinMaskClr = ~_csPinMaskSet; 145 #endif // !HAS_PORT_SET_CLR 146 #endif // USE_FAST_PINIO 147 148 #if defined(ESP32) 149 _spi->begin(_sck, _miso, _mosi); 150 if (_dataMode == GFX_NOT_DEFINED) 151 { 152 _dataMode = SPI_MODE0; 153 } 154 mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode); 155 #elif defined(ESP8266) 156 _spi->begin(); 157 if (_dataMode == GFX_NOT_DEFINED) 158 { 159 _dataMode = SPI_MODE0; 160 } 161 mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode); 162 // Teensy 4.x 163 #elif defined(__IMXRT1052__) || defined(__IMXRT1062__) 164 _spi->begin(); 165 if (_dataMode == GFX_NOT_DEFINED) 166 { 167 _dataMode = SPI_MODE0; 168 } 169 mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode); 170 #elif defined(SPI_HAS_TRANSACTION) 171 _spi->begin(); 172 if (_dataMode == GFX_NOT_DEFINED) 173 { 174 _dataMode = SPI_MODE2; 175 } 176 mySPISettings = SPISettings(_speed, MSBFIRST, _dataMode); 177 #elif defined(__AVR__) || defined(CORE_TEENSY) 178 SPCRbackup = SPCR; 179 _spi->begin(); 180 _spi->setClockDivider(SPI_CLOCK_DIV2); 181 if (_dataMode == GFX_NOT_DEFINED) 182 { 183 _dataMode = SPI_MODE2; 184 } 185 _spi->setDataMode(_dataMode); 186 mySPCR = SPCR; // save our preferred state 187 SPCR = SPCRbackup; // then restore 188 #elif defined(__SAM3X8E__) 189 _spi->begin(); 190 _spi->setClockDivider(21); // 4MHz 191 if (_dataMode == GFX_NOT_DEFINED) 192 { 193 _dataMode = SPI_MODE2; 194 } 195 _spi->setDataMode(_dataMode); 196 #elif defined(__arm__) 197 if (_dataMode == GFX_NOT_DEFINED) 198 { 199 _dataMode = SPI_MODE2; 200 } 201 #endif 202 203 return true; 204 } 205 206 void Arduino_HWSPI::beginWrite() 207 { 208 if (_is_shared_interface) 209 { 210 SPI_BEGIN_TRANSACTION(); 211 } 212 213 DC_HIGH(); 214 CS_LOW(); 215 } 216 217 void Arduino_HWSPI::endWrite() 218 { 219 CS_HIGH(); 220 221 if (_is_shared_interface) 222 { 223 SPI_END_TRANSACTION(); 224 } 225 } 226 227 void Arduino_HWSPI::writeCommand(uint8_t c) 228 { 229 DC_LOW(); 230 231 WRITE(c); 232 233 DC_HIGH(); 234 } 235 236 void Arduino_HWSPI::writeCommand16(uint16_t c) 237 { 238 DC_LOW(); 239 240 #if defined(LITTLE_FOOT_PRINT) 241 _data16.value = c; 242 WRITE(_data16.msb); 243 WRITE(_data16.lsb); 244 #else // !defined(LITTLE_FOOT_PRINT) 245 WRITE16(c); 246 #endif // !defined(LITTLE_FOOT_PRINT) 247 248 DC_HIGH(); 249 } 250 251 void Arduino_HWSPI::write(uint8_t d) 252 { 253 WRITE(d); 254 } 255 256 void Arduino_HWSPI::write16(uint16_t d) 257 { 258 #if defined(LITTLE_FOOT_PRINT) 259 _data16.value = d; 260 WRITE(_data16.msb); 261 WRITE(_data16.lsb); 262 #else // !defined(LITTLE_FOOT_PRINT) 263 WRITE16(d); 264 #endif // !defined(LITTLE_FOOT_PRINT) 265 } 266 267 void Arduino_HWSPI::writeRepeat(uint16_t p, uint32_t len) 268 { 269 #if defined(LITTLE_FOOT_PRINT) 270 _data16.value = p; 271 while (len--) 272 { 273 WRITE(_data16.msb); 274 WRITE(_data16.lsb); 275 } 276 #elif defined(ESP8266) || defined(CONFIG_ARCH_CHIP_CXD56XX) 277 MSB_16_SET(p, p); 278 uint32_t xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE; 279 for (uint32_t i = 0; i < xferLen; i++) 280 { 281 _buffer.v16[i] = p; 282 } 283 284 while (len) 285 { 286 xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE; 287 len -= xferLen; 288 289 xferLen += xferLen; 290 WRITEBUF(_buffer.v8, xferLen); 291 } 292 #else // other arch 293 MSB_16_SET(p, p); 294 uint32_t xferLen; 295 296 while (len) 297 { 298 xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE; 299 for (uint32_t i = 0; i < xferLen; i++) 300 { 301 _buffer.v16[i] = p; 302 } 303 len -= xferLen; 304 305 xferLen += xferLen; 306 WRITEBUF(_buffer.v8, xferLen); 307 } 308 #endif // other arch 309 } 310 311 void Arduino_HWSPI::writePixels(uint16_t *data, uint32_t len) 312 { 313 #if defined(LITTLE_FOOT_PRINT) 314 while (len--) 315 { 316 _data16.value = *data++; 317 WRITE(_data16.msb); 318 WRITE(_data16.lsb); 319 } 320 #else // !defined(LITTLE_FOOT_PRINT) 321 uint32_t xferLen; 322 uint8_t *b; 323 union 324 { 325 uint16_t val; 326 struct 327 { 328 uint8_t lsb; 329 uint8_t msb; 330 }; 331 } t; 332 while (len) 333 { 334 xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE; 335 b = _buffer.v8; 336 for (uint32_t i = 0; i < xferLen; i++) 337 { 338 t.val = *data++; 339 *b++ = t.msb; 340 *b++ = t.lsb; 341 } 342 len -= xferLen; 343 344 xferLen += xferLen; // uint16_t to uint8_t, double length 345 WRITEBUF(_buffer.v8, xferLen); 346 } 347 #endif // !defined(LITTLE_FOOT_PRINT) 348 } 349 350 #if !defined(LITTLE_FOOT_PRINT) 351 void Arduino_HWSPI::writeBytes(uint8_t *data, uint32_t len) 352 { 353 WRITEBUF(data, len); 354 } 355 356 void Arduino_HWSPI::writePattern(uint8_t *data, uint8_t len, uint32_t repeat) 357 { 358 #if defined(ESP8266) || defined(ESP32) 359 _spi->writePattern(data, len, repeat); 360 #else // !(defined(ESP8266) || defined(ESP32)) 361 while (repeat--) 362 { 363 WRITEBUF(data, len); 364 } 365 #endif // !(defined(ESP8266) || defined(ESP32)) 366 } 367 #endif // !defined(LITTLE_FOOT_PRINT) 368 369 INLINE void Arduino_HWSPI::WRITE(uint8_t d) 370 { 371 #if defined(SPI_HAS_TRANSACTION) 372 _spi->transfer(d); 373 #elif defined(__AVR__) || defined(CORE_TEENSY) 374 SPCRbackup = SPCR; 375 SPCR = mySPCR; 376 _spi->transfer(d); 377 SPCR = SPCRbackup; 378 #elif defined(__arm__) 379 _spi->setClockDivider(21); // 4MHz 380 _spi->setDataMode(_dataMode); 381 _spi->transfer(d); 382 #endif 383 } 384 385 #if !defined(LITTLE_FOOT_PRINT) 386 387 INLINE void Arduino_HWSPI::WRITE16(uint16_t d) 388 { 389 #if defined(ESP8266) || defined(ESP32) 390 _spi->write16(d); 391 #elif defined(SPI_HAS_TRANSACTION) 392 _spi->transfer16(d); 393 #elif defined(__AVR__) || defined(CORE_TEENSY) 394 SPCRbackup = SPCR; 395 SPCR = mySPCR; 396 _spi->transfer16(d); 397 SPCR = SPCRbackup; 398 #elif defined(__arm__) 399 _spi->setClockDivider(21); // 4MHz 400 _spi->setDataMode(_dataMode); 401 _spi->transfer16(d); 402 #else 403 _spi->transfer16(d); 404 #endif 405 } 406 407 INLINE void Arduino_HWSPI::WRITEBUF(uint8_t *buf, size_t count) 408 { 409 #if defined(ESP8266) || defined(ESP32) 410 _spi->writeBytes(buf, count); 411 #elif defined(CONFIG_ARCH_CHIP_CXD56XX) 412 _spi->send(buf, count); 413 #else // other arch. 414 _spi->transfer(buf, count); 415 #endif // other arch. 416 } 417 418 #endif // !defined(LITTLE_FOOT_PRINT) 419 420 /******** low level bit twiddling **********/ 421 422 INLINE void Arduino_HWSPI::DC_HIGH(void) 423 { 424 #if defined(USE_FAST_PINIO) 425 #if defined(HAS_PORT_SET_CLR) 426 #if defined(KINETISK) 427 *_dcPortSet = 1; 428 #else // !KINETISK 429 *_dcPortSet = _dcPinMask; 430 #endif // end !KINETISK 431 #else // !HAS_PORT_SET_CLR 432 *_dcPort |= _dcPinMaskSet; 433 #endif // end !HAS_PORT_SET_CLR 434 #else // !USE_FAST_PINIO 435 digitalWrite(_dc, HIGH); 436 #endif // end !USE_FAST_PINIO 437 } 438 439 INLINE void Arduino_HWSPI::DC_LOW(void) 440 { 441 #if defined(USE_FAST_PINIO) 442 #if defined(HAS_PORT_SET_CLR) 443 #if defined(KINETISK) 444 *_dcPortClr = 1; 445 #else // !KINETISK 446 *_dcPortClr = _dcPinMask; 447 #endif // end !KINETISK 448 #else // !HAS_PORT_SET_CLR 449 *_dcPort &= _dcPinMaskClr; 450 #endif // end !HAS_PORT_SET_CLR 451 #else // !USE_FAST_PINIO 452 digitalWrite(_dc, LOW); 453 #endif // end !USE_FAST_PINIO 454 } 455 456 INLINE void Arduino_HWSPI::CS_HIGH(void) 457 { 458 if (_cs != GFX_NOT_DEFINED) 459 { 460 #if defined(USE_FAST_PINIO) 461 #if defined(HAS_PORT_SET_CLR) 462 #if defined(KINETISK) 463 *_csPortSet = 1; 464 #else // !KINETISK 465 *_csPortSet = _csPinMask; 466 #endif // end !KINETISK 467 #else // !HAS_PORT_SET_CLR 468 *_csPort |= _csPinMaskSet; 469 #endif // end !HAS_PORT_SET_CLR 470 #else // !USE_FAST_PINIO 471 digitalWrite(_cs, HIGH); 472 #endif // end !USE_FAST_PINIO 473 } 474 } 475 476 INLINE void Arduino_HWSPI::CS_LOW(void) 477 { 478 if (_cs != GFX_NOT_DEFINED) 479 { 480 #if defined(USE_FAST_PINIO) 481 #if defined(HAS_PORT_SET_CLR) 482 #if defined(KINETISK) 483 *_csPortClr = 1; 484 #else // !KINETISK 485 *_csPortClr = _csPinMask; 486 #endif // end !KINETISK 487 #else // !HAS_PORT_SET_CLR 488 *_csPort &= _csPinMaskClr; 489 #endif // end !HAS_PORT_SET_CLR 490 #else // !USE_FAST_PINIO 491 digitalWrite(_cs, LOW); 492 #endif // end !USE_FAST_PINIO 493 } 494 }