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_ESP8266SPI.cpp (7250B)

      1 /*
      2  * start rewrite from:
      3  * https://github.com/Bodmer/TFT_eSPI.git
      4  */
      5 #ifdef ESP8266
      6 
      7 #include <SPI.h>
      8 #include "Arduino_ESP8266SPI.h"
      9 
     10 #define WAIT_SPI_NOT_BUSY while (SPI1CMD & SPIBUSY)
     11 
     12 Arduino_ESP8266SPI::Arduino_ESP8266SPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */)
     13     : _dc(dc), _cs(cs)
     14 {
     15 }
     16 
     17 bool Arduino_ESP8266SPI::begin(int32_t speed, int8_t dataMode)
     18 {
     19   _speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed;
     20   _dataMode = (dataMode == GFX_NOT_DEFINED) ? SPI_MODE0 : dataMode;
     21 
     22   pinMode(_dc, OUTPUT);
     23   digitalWrite(_dc, HIGH); // Data mode
     24   if (_cs != GFX_NOT_DEFINED)
     25   {
     26     pinMode(_cs, OUTPUT);
     27     digitalWrite(_cs, HIGH); // Deselect
     28   }
     29 
     30   _dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_dc));
     31   _dcPinMaskSet = digitalPinToBitMask(_dc);
     32   if (_cs != GFX_NOT_DEFINED)
     33   {
     34     _csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(_cs));
     35     _csPinMaskSet = digitalPinToBitMask(_cs);
     36   }
     37   _csPinMaskClr = ~_csPinMaskSet;
     38   _dcPinMaskClr = ~_dcPinMaskSet;
     39 
     40   SPI.begin();
     41   if (_dataMode == GFX_NOT_DEFINED)
     42   {
     43     _dataMode = SPI_MODE0;
     44   }
     45   SPI.setBitOrder(MSBFIRST);
     46   SPI.setDataMode(_dataMode);
     47   SPI.setFrequency(_speed);
     48 
     49   return true;
     50 }
     51 
     52 void Arduino_ESP8266SPI::beginWrite()
     53 {
     54   DC_HIGH();
     55 
     56   CS_LOW();
     57 }
     58 
     59 void Arduino_ESP8266SPI::endWrite()
     60 {
     61   CS_HIGH();
     62 }
     63 
     64 void Arduino_ESP8266SPI::writeCommand(uint8_t c)
     65 {
     66   DC_LOW();
     67 
     68   WRITE(c);
     69 
     70   DC_HIGH();
     71 }
     72 
     73 void Arduino_ESP8266SPI::writeCommand16(uint16_t c)
     74 {
     75   DC_LOW();
     76 
     77   WRITE16(c);
     78 
     79   DC_HIGH();
     80 }
     81 
     82 void Arduino_ESP8266SPI::write(uint8_t d)
     83 {
     84   WRITE(d);
     85 }
     86 
     87 void Arduino_ESP8266SPI::write16(uint16_t d)
     88 {
     89   WRITE16(d);
     90 }
     91 
     92 void Arduino_ESP8266SPI::writeRepeat(uint16_t p, uint32_t len)
     93 {
     94   _data16.value = p;
     95   static uint8_t temp[2];
     96   temp[0] = _data16.msb;
     97   temp[1] = _data16.lsb;
     98   SPI.writePattern((uint8_t *)temp, 2, len);
     99 }
    100 
    101 void Arduino_ESP8266SPI::writePixels(uint16_t *data, uint32_t len)
    102 {
    103   uint8_t *data8 = (uint8_t *)data;
    104   uint8_t i;
    105 
    106   if (len > 31)
    107   {
    108     SPI1U1 = (511 << SPILMOSI);
    109 
    110     while (len > 31)
    111     {
    112       i = 0;
    113       while (i < 16)
    114       {
    115         MSB_32_8_ARRAY_SET(twoPixelBuf[i++], data8);
    116         data8 += 4;
    117       }
    118 
    119       len -= 32;
    120 
    121       // ESP8266 wait time here at 40MHz SPI is ~5.45us
    122       WAIT_SPI_NOT_BUSY;
    123       SPI1W0 = twoPixelBuf[0];
    124       SPI1W1 = twoPixelBuf[1];
    125       SPI1W2 = twoPixelBuf[2];
    126       SPI1W3 = twoPixelBuf[3];
    127       SPI1W4 = twoPixelBuf[4];
    128       SPI1W5 = twoPixelBuf[5];
    129       SPI1W6 = twoPixelBuf[6];
    130       SPI1W7 = twoPixelBuf[7];
    131       SPI1W8 = twoPixelBuf[8];
    132       SPI1W9 = twoPixelBuf[9];
    133       SPI1W10 = twoPixelBuf[10];
    134       SPI1W11 = twoPixelBuf[11];
    135       SPI1W12 = twoPixelBuf[12];
    136       SPI1W13 = twoPixelBuf[13];
    137       SPI1W14 = twoPixelBuf[14];
    138       SPI1W15 = twoPixelBuf[15];
    139       SPI1CMD |= SPIBUSY;
    140     }
    141   }
    142 
    143   if (len)
    144   {
    145     uint32_t bits = ((len << 4) - 1); // bits left to shift - 1
    146     i = 0;
    147     len = (len + 1) >> 1;
    148 
    149     WAIT_SPI_NOT_BUSY;
    150     SPI1U1 = (bits << SPILMOSI);
    151     while (len--)
    152     {
    153       MSB_32_8_ARRAY_SET(spi1Reg32[i++], data8);
    154       data8 += 4;
    155     }
    156     SPI1CMD |= SPIBUSY;
    157   }
    158 
    159   WAIT_SPI_NOT_BUSY;
    160 }
    161 
    162 void Arduino_ESP8266SPI::writeC8D8(uint8_t c, uint8_t d)
    163 {
    164   DC_LOW();
    165 
    166   WRITE(c);
    167 
    168   DC_HIGH();
    169 
    170   WRITE(d);
    171 }
    172 
    173 void Arduino_ESP8266SPI::writeC8D16(uint8_t c, uint16_t d)
    174 {
    175   DC_LOW();
    176 
    177   WRITE(c);
    178 
    179   DC_HIGH();
    180 
    181   WRITE16(d);
    182 }
    183 
    184 void Arduino_ESP8266SPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
    185 {
    186   DC_LOW();
    187 
    188   WRITE(c);
    189 
    190   DC_HIGH();
    191 
    192   uint32_t d;
    193   MSB_32_16_16_SET(d, d1, d2);
    194 
    195   SPI1U1 = (31 << SPILMOSI);
    196   SPI1W0 = d;
    197   SPI1CMD |= SPIBUSY;
    198   WAIT_SPI_NOT_BUSY;
    199 }
    200 
    201 void Arduino_ESP8266SPI::writeBytes(uint8_t *data, uint32_t len)
    202 {
    203   SPI.writeBytes(data, len);
    204 }
    205 
    206 void Arduino_ESP8266SPI::writePattern(uint8_t *data, uint8_t len, uint32_t repeat)
    207 {
    208   SPI.writePattern(data, len, repeat);
    209 }
    210 
    211 void Arduino_ESP8266SPI::writeIndexedPixels(uint8_t *data, uint16_t *idx, uint32_t len)
    212 {
    213   uint16_t p1, p2;
    214   uint8_t i;
    215 
    216   if (len > 31)
    217   {
    218     SPI1U1 = (511 << SPILMOSI);
    219 
    220     while (len > 31)
    221     {
    222       i = 0;
    223       while (i < 16)
    224       {
    225         p1 = idx[*data++];
    226         p2 = idx[*data++];
    227         MSB_32_16_16_SET(twoPixelBuf[i++], p1, p2);
    228       }
    229 
    230       len -= 32;
    231 
    232       // ESP8266 wait time here at 40MHz SPI is ~5.45us
    233       WAIT_SPI_NOT_BUSY;
    234       SPI1W0 = twoPixelBuf[0];
    235       SPI1W1 = twoPixelBuf[1];
    236       SPI1W2 = twoPixelBuf[2];
    237       SPI1W3 = twoPixelBuf[3];
    238       SPI1W4 = twoPixelBuf[4];
    239       SPI1W5 = twoPixelBuf[5];
    240       SPI1W6 = twoPixelBuf[6];
    241       SPI1W7 = twoPixelBuf[7];
    242       SPI1W8 = twoPixelBuf[8];
    243       SPI1W9 = twoPixelBuf[9];
    244       SPI1W10 = twoPixelBuf[10];
    245       SPI1W11 = twoPixelBuf[11];
    246       SPI1W12 = twoPixelBuf[12];
    247       SPI1W13 = twoPixelBuf[13];
    248       SPI1W14 = twoPixelBuf[14];
    249       SPI1W15 = twoPixelBuf[15];
    250       SPI1CMD |= SPIBUSY;
    251     }
    252   }
    253 
    254   if (len)
    255   {
    256     uint32_t bits = ((len << 4) - 1); // bits left to shift - 1
    257     i = 0;
    258     len = (len + 1) >> 1;
    259 
    260     WAIT_SPI_NOT_BUSY;
    261     SPI1U1 = (bits << SPILMOSI);
    262     while (len--)
    263     {
    264       p1 = idx[*data++];
    265       p2 = idx[*data++];
    266       MSB_32_16_16_SET(spi1Reg32[i++], p1, p2);
    267     }
    268     SPI1CMD |= SPIBUSY;
    269   }
    270 
    271   WAIT_SPI_NOT_BUSY;
    272 }
    273 
    274 void Arduino_ESP8266SPI::writeIndexedPixelsDouble(uint8_t *data, uint16_t *idx, uint32_t len)
    275 {
    276   uint16_t p;
    277   uint8_t i;
    278 
    279   if (len > 15)
    280   {
    281     SPI1U1 = (511 << SPILMOSI);
    282     while (len > 15)
    283     {
    284       i = 0;
    285       while (i < 16)
    286       {
    287         p = idx[*data++];
    288         MSB_32_16_16_SET(twoPixelBuf[i++], p, p);
    289       }
    290 
    291       len -= 16;
    292 
    293       // ESP8266 wait time here at 40MHz SPI is ~5.45us
    294       WAIT_SPI_NOT_BUSY;
    295       SPI1W0 = twoPixelBuf[0];
    296       SPI1W1 = twoPixelBuf[1];
    297       SPI1W2 = twoPixelBuf[2];
    298       SPI1W3 = twoPixelBuf[3];
    299       SPI1W4 = twoPixelBuf[4];
    300       SPI1W5 = twoPixelBuf[5];
    301       SPI1W6 = twoPixelBuf[6];
    302       SPI1W7 = twoPixelBuf[7];
    303       SPI1W8 = twoPixelBuf[8];
    304       SPI1W9 = twoPixelBuf[9];
    305       SPI1W10 = twoPixelBuf[10];
    306       SPI1W11 = twoPixelBuf[11];
    307       SPI1W12 = twoPixelBuf[12];
    308       SPI1W13 = twoPixelBuf[13];
    309       SPI1W14 = twoPixelBuf[14];
    310       SPI1W15 = twoPixelBuf[15];
    311       SPI1CMD |= SPIBUSY;
    312     }
    313   }
    314 
    315   if (len)
    316   {
    317     uint32_t bits = ((len << 5) - 1); // bits left to shift - 1
    318     i = 0;
    319 
    320     WAIT_SPI_NOT_BUSY;
    321     SPI1U1 = (bits << SPILMOSI);
    322     while (len--)
    323     {
    324       p = idx[*data++];
    325       MSB_32_16_16_SET(spi1Reg32[i++], p, p);
    326     }
    327     SPI1CMD |= SPIBUSY;
    328   }
    329 
    330   WAIT_SPI_NOT_BUSY;
    331 }
    332 
    333 INLINE void Arduino_ESP8266SPI::WRITE(uint8_t d)
    334 {
    335   SPI1U1 = (7 << SPILMOSI);
    336   SPI1W0 = d;
    337   SPI1CMD |= SPIBUSY;
    338   WAIT_SPI_NOT_BUSY;
    339 }
    340 
    341 INLINE void Arduino_ESP8266SPI::WRITE16(uint16_t d)
    342 {
    343   MSB_16_SET(d, d);
    344 
    345   SPI1U1 = (15 << SPILMOSI);
    346   SPI1W0 = d;
    347   SPI1CMD |= SPIBUSY;
    348   WAIT_SPI_NOT_BUSY;
    349 }
    350 
    351 /******** low level bit twiddling **********/
    352 
    353 INLINE void Arduino_ESP8266SPI::DC_HIGH(void)
    354 {
    355   *_dcPort |= _dcPinMaskSet;
    356 }
    357 
    358 INLINE void Arduino_ESP8266SPI::DC_LOW(void)
    359 {
    360   *_dcPort &= _dcPinMaskClr;
    361 }
    362 
    363 INLINE void Arduino_ESP8266SPI::CS_HIGH(void)
    364 {
    365   if (_cs != GFX_NOT_DEFINED)
    366   {
    367     *_csPort |= _csPinMaskSet;
    368   }
    369 }
    370 
    371 INLINE void Arduino_ESP8266SPI::CS_LOW(void)
    372 {
    373   if (_cs != GFX_NOT_DEFINED)
    374   {
    375     *_csPort &= _csPinMaskClr;
    376   }
    377 }
    378 
    379 #endif // #ifdef ESP8266