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_mbedSPI.cpp (4107B)

      1 /*
      2  * start rewrite from:
      3  * https://github.com/arduino/ArduinoCore-mbed/blob/master/libraries/SPI/SPI.cpp
      4  */
      5 #ifdef ARDUINO_ARCH_NRF52840
      6 
      7 #include "Arduino_mbedSPI.h"
      8 
      9 Arduino_mbedSPI::Arduino_mbedSPI(int8_t dc, int8_t cs /* = GFX_NOT_DEFINED */)
     10     : _dc(dc), _cs(cs)
     11 {
     12 }
     13 
     14 bool Arduino_mbedSPI::begin(int32_t speed, int8_t dataMode)
     15 {
     16   _speed = (speed == GFX_NOT_DEFINED) ? SPI_DEFAULT_FREQ : speed;
     17   _dataMode = (dataMode == GFX_NOT_DEFINED) ? SPI_MODE2 : dataMode;
     18 
     19   uint32_t pin = digitalPinToPinName((pin_size_t)_dc);
     20   NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin);
     21   nrf_gpio_cfg_output(pin);
     22   _dcPortSet = &reg->OUTSET;
     23   _dcPortClr = &reg->OUTCLR;
     24   _dcPinMask = 1UL << pin;
     25   if (_cs != GFX_NOT_DEFINED)
     26   {
     27     pin = digitalPinToPinName((pin_size_t)_cs);
     28     reg = nrf_gpio_pin_port_decode(&pin);
     29     nrf_gpio_cfg_output(pin);
     30     _csPortSet = &reg->OUTSET;
     31     _csPortClr = &reg->OUTCLR;
     32     _csPinMask = 1UL << pin;
     33   }
     34 
     35   if (_dataMode == GFX_NOT_DEFINED)
     36   {
     37     _dataMode = SPI_MODE0;
     38   }
     39   _dev = new mbed::SPI((PinName)SPI_MOSI, (PinName)SPI_MISO, (PinName)SPI_SCK);
     40 
     41   return true;
     42 }
     43 
     44 void Arduino_mbedSPI::beginWrite()
     45 {
     46   _dev->lock();
     47   _dev->format(8, _dataMode);
     48   _dev->frequency(_speed);
     49 
     50   DC_HIGH();
     51 
     52   CS_LOW();
     53 }
     54 
     55 void Arduino_mbedSPI::endWrite()
     56 {
     57   CS_HIGH();
     58   _dev->unlock();
     59 }
     60 
     61 void Arduino_mbedSPI::writeCommand(uint8_t c)
     62 {
     63   DC_LOW();
     64 
     65   WRITE(c);
     66 
     67   DC_HIGH();
     68 }
     69 
     70 void Arduino_mbedSPI::writeCommand16(uint16_t c)
     71 {
     72   DC_LOW();
     73 
     74   WRITE16(c);
     75 
     76   DC_HIGH();
     77 }
     78 
     79 void Arduino_mbedSPI::write(uint8_t d)
     80 {
     81   WRITE(d);
     82 }
     83 
     84 void Arduino_mbedSPI::write16(uint16_t d)
     85 {
     86   WRITE16(d);
     87 }
     88 
     89 void Arduino_mbedSPI::writeRepeat(uint16_t p, uint32_t len)
     90 {
     91   MSB_16_SET(p, p);
     92   uint32_t bufLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE;
     93   uint32_t xferLen;
     94   for (uint32_t i = 0; i < bufLen; i++)
     95   {
     96     _buffer16[i] = p;
     97   }
     98 
     99   while (len)
    100   {
    101     xferLen = (bufLen < len) ? bufLen : len;
    102     WRITEBUF(_buffer, xferLen * 2);
    103     len -= xferLen;
    104   }
    105 }
    106 
    107 void Arduino_mbedSPI::writePixels(uint16_t *data, uint32_t len)
    108 {
    109   uint32_t xferLen;
    110   uint8_t *p;
    111   union
    112   {
    113     uint16_t val;
    114     struct
    115     {
    116       uint8_t lsb;
    117       uint8_t msb;
    118     };
    119   } t;
    120   while (len)
    121   {
    122     xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE;
    123     p = _buffer;
    124     for (uint32_t i = 0; i < xferLen; i++)
    125     {
    126       t.val = *data++;
    127       *p++ = t.msb;
    128       *p++ = t.lsb;
    129     }
    130     len -= xferLen;
    131 
    132     xferLen += xferLen; // uint16_t to uint8_t, double length
    133     WRITEBUF(_buffer, xferLen);
    134   }
    135 }
    136 
    137 void Arduino_mbedSPI::writeC8D8(uint8_t c, uint8_t d)
    138 {
    139   DC_LOW();
    140 
    141   WRITE(c);
    142 
    143   DC_HIGH();
    144 
    145   WRITE(d);
    146 }
    147 
    148 void Arduino_mbedSPI::writeC8D16(uint8_t c, uint16_t d)
    149 {
    150   DC_LOW();
    151 
    152   WRITE(c);
    153 
    154   DC_HIGH();
    155 
    156   WRITE16(d);
    157 }
    158 
    159 void Arduino_mbedSPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2)
    160 {
    161   DC_LOW();
    162 
    163   _dev->write((const char *)&c, 1, NULL, 0);
    164 
    165   DC_HIGH();
    166 
    167   uint32_t d;
    168   MSB_32_16_16_SET(d, d1, d2);
    169   _dev->write((const char *)&d, 4, NULL, 0);
    170 }
    171 
    172 void Arduino_mbedSPI::writeBytes(uint8_t *data, uint32_t len)
    173 {
    174   WRITEBUF(data, len);
    175 }
    176 
    177 void Arduino_mbedSPI::writePattern(uint8_t *data, uint8_t len, uint32_t repeat)
    178 {
    179   while (repeat--)
    180   {
    181     for (uint8_t i = 0; i < len; i++)
    182     {
    183       write(data[i]);
    184     }
    185   }
    186 }
    187 
    188 INLINE void Arduino_mbedSPI::WRITE(uint8_t d)
    189 {
    190   _dev->write((const char *)&d, 1, NULL, 0);
    191 }
    192 
    193 INLINE void Arduino_mbedSPI::WRITE16(uint16_t d)
    194 {
    195   MSB_16_SET(d, d);
    196   _dev->write((const char *)&d, 2, NULL, 0);
    197 }
    198 
    199 INLINE void Arduino_mbedSPI::WRITEBUF(uint8_t *buf, size_t count)
    200 {
    201   _dev->write((const char *)buf, count, NULL, 0);
    202 }
    203 
    204 /******** low level bit twiddling **********/
    205 
    206 INLINE void Arduino_mbedSPI::DC_HIGH(void)
    207 {
    208   *_dcPortSet = _dcPinMask;
    209 }
    210 
    211 INLINE void Arduino_mbedSPI::DC_LOW(void)
    212 {
    213   *_dcPortClr = _dcPinMask;
    214 }
    215 
    216 INLINE void Arduino_mbedSPI::CS_HIGH(void)
    217 {
    218   if (_cs != GFX_NOT_DEFINED)
    219   {
    220     *_csPortSet = _csPinMask;
    221   }
    222 }
    223 
    224 INLINE void Arduino_mbedSPI::CS_LOW(void)
    225 {
    226   if (_cs != GFX_NOT_DEFINED)
    227   {
    228     *_csPortClr = _csPinMask;
    229   }
    230 }
    231 
    232 #endif // #ifdef ARDUINO_ARCH_NRF52840