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_NRFXSPI.cpp (5732B)
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_NRFXSPI.h" 8 9 Arduino_NRFXSPI::Arduino_NRFXSPI(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 */) 10 : _dc(dc), _cs(cs), _sck(sck), _mosi(mosi), _miso(miso) 11 { 12 } 13 14 bool Arduino_NRFXSPI::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 // init pin mask 20 uint32_t pin = digitalPinToPinName((pin_size_t)_dc); 21 NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin); 22 nrf_gpio_cfg_output(pin); 23 _dcPortSet = ®->OUTSET; 24 _dcPortClr = ®->OUTCLR; 25 _dcPinMask = 1UL << pin; 26 if (_cs != GFX_NOT_DEFINED) 27 { 28 pin = digitalPinToPinName((pin_size_t)_cs); 29 reg = nrf_gpio_pin_port_decode(&pin); 30 nrf_gpio_cfg_output(pin); 31 _csPortSet = ®->OUTSET; 32 _csPortClr = ®->OUTCLR; 33 _csPinMask = 1UL << pin; 34 } 35 36 // init SPI pins 37 _nrfxSpiConfig.sck_pin = digitalPinToPinName((pin_size_t)_sck); 38 _nrfxSpiConfig.mosi_pin = digitalPinToPinName((pin_size_t)_mosi); 39 if (_miso > 0) 40 { 41 _nrfxSpiConfig.miso_pin = digitalPinToPinName((pin_size_t)_miso); 42 } 43 else 44 { 45 _nrfxSpiConfig.miso_pin = NRFX_SPI_PIN_NOT_USED; 46 } 47 48 // init speed 49 if (_speed >= 8000000) 50 { 51 _nrfxSpiConfig.frequency = NRF_SPI_FREQ_8M; 52 } 53 else if (_speed >= 4000000) 54 { 55 _nrfxSpiConfig.frequency = NRF_SPI_FREQ_4M; 56 } 57 else if (_speed >= 2000000) 58 { 59 _nrfxSpiConfig.frequency = NRF_SPI_FREQ_2M; 60 } 61 else if (_speed >= 1000000) 62 { 63 _nrfxSpiConfig.frequency = NRF_SPI_FREQ_1M; 64 } 65 else if (_speed >= 500000) 66 { 67 _nrfxSpiConfig.frequency = NRF_SPI_FREQ_500K; 68 } 69 else if (_speed >= 250000) 70 { 71 _nrfxSpiConfig.frequency = NRF_SPI_FREQ_250K; 72 } 73 else if (_speed >= 125000) 74 { 75 _nrfxSpiConfig.frequency = NRF_SPI_FREQ_125K; 76 } 77 78 // init data mode 79 if (_dataMode == SPI_MODE1) 80 { 81 _nrfxSpiConfig.mode = NRF_SPI_MODE_1; 82 } 83 else if (_dataMode == SPI_MODE2) 84 { 85 _nrfxSpiConfig.mode = NRF_SPI_MODE_2; 86 } 87 else if (_dataMode == SPI_MODE3) 88 { 89 _nrfxSpiConfig.mode = NRF_SPI_MODE_3; 90 } 91 else 92 { 93 _dataMode = SPI_MODE0; 94 _nrfxSpiConfig.mode = NRF_SPI_MODE_0; 95 } 96 97 // init SPI 98 nrfx_spi_init(&_nrfxSpi, &_nrfxSpiConfig, NULL, NULL); 99 100 return true; 101 } 102 103 void Arduino_NRFXSPI::beginWrite() 104 { 105 DC_HIGH(); 106 107 CS_LOW(); 108 } 109 110 void Arduino_NRFXSPI::endWrite() 111 { 112 CS_HIGH(); 113 } 114 115 void Arduino_NRFXSPI::writeCommand(uint8_t c) 116 { 117 DC_LOW(); 118 119 WRITE(c); 120 121 DC_HIGH(); 122 } 123 124 void Arduino_NRFXSPI::writeCommand16(uint16_t c) 125 { 126 DC_LOW(); 127 128 WRITE16(c); 129 130 DC_HIGH(); 131 } 132 133 void Arduino_NRFXSPI::write(uint8_t d) 134 { 135 WRITE(d); 136 } 137 138 void Arduino_NRFXSPI::write16(uint16_t d) 139 { 140 WRITE16(d); 141 } 142 143 void Arduino_NRFXSPI::writeRepeat(uint16_t p, uint32_t len) 144 { 145 MSB_16_SET(p, p); 146 uint32_t bufLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE; 147 uint32_t xferLen; 148 for (uint32_t i = 0; i < bufLen; i++) 149 { 150 _buffer16[i] = p; 151 } 152 153 while (len) 154 { 155 xferLen = (bufLen < len) ? bufLen : len; 156 WRITEBUF(_buffer, xferLen * 2); 157 len -= xferLen; 158 } 159 } 160 161 void Arduino_NRFXSPI::writePixels(uint16_t *data, uint32_t len) 162 { 163 uint32_t xferLen; 164 uint8_t *p; 165 union 166 { 167 uint16_t val; 168 struct 169 { 170 uint8_t lsb; 171 uint8_t msb; 172 }; 173 } t; 174 while (len) 175 { 176 xferLen = (len < SPI_MAX_PIXELS_AT_ONCE) ? len : SPI_MAX_PIXELS_AT_ONCE; 177 p = _buffer; 178 for (uint32_t i = 0; i < xferLen; i++) 179 { 180 t.val = *data++; 181 *p++ = t.msb; 182 *p++ = t.lsb; 183 } 184 len -= xferLen; 185 186 xferLen += xferLen; // uint16_t to uint8_t, double length 187 WRITEBUF(_buffer, xferLen); 188 } 189 } 190 191 void Arduino_NRFXSPI::writeC8D8(uint8_t c, uint8_t d) 192 { 193 DC_LOW(); 194 195 WRITE(c); 196 197 DC_HIGH(); 198 199 WRITE(d); 200 } 201 202 void Arduino_NRFXSPI::writeC8D16(uint8_t c, uint16_t d) 203 { 204 DC_LOW(); 205 206 WRITE(c); 207 208 DC_HIGH(); 209 210 WRITE16(d); 211 } 212 213 void Arduino_NRFXSPI::writeC8D16D16(uint8_t c, uint16_t d1, uint16_t d2) 214 { 215 DC_LOW(); 216 217 const nrfx_spi_xfer_desc_t xfer_desc1 = NRFX_SPI_SINGLE_XFER(&c, 1, NULL, 0); 218 nrfx_spi_xfer(&_nrfxSpi, &xfer_desc1, 0); 219 220 DC_HIGH(); 221 222 uint32_t d; 223 MSB_32_16_16_SET(d, d1, d2); 224 const nrfx_spi_xfer_desc_t xfer_desc2 = NRFX_SPI_SINGLE_XFER(&d, 4, NULL, 0); 225 nrfx_spi_xfer(&_nrfxSpi, &xfer_desc2, 0); 226 } 227 228 void Arduino_NRFXSPI::writeBytes(uint8_t *data, uint32_t len) 229 { 230 WRITEBUF(data, len); 231 } 232 233 void Arduino_NRFXSPI::writePattern(uint8_t *data, uint8_t len, uint32_t repeat) 234 { 235 while (repeat--) 236 { 237 WRITEBUF(data, len); 238 } 239 } 240 241 INLINE void Arduino_NRFXSPI::WRITE(uint8_t d) 242 { 243 const nrfx_spi_xfer_desc_t xfer_desc = NRFX_SPI_SINGLE_XFER(&d, 1, NULL, 0); 244 nrfx_spi_xfer(&_nrfxSpi, &xfer_desc, 0); 245 } 246 247 INLINE void Arduino_NRFXSPI::WRITE16(uint16_t d) 248 { 249 MSB_16_SET(d, d); 250 const nrfx_spi_xfer_desc_t xfer_desc = NRFX_SPI_SINGLE_XFER(&d, 2, NULL, 0); 251 nrfx_spi_xfer(&_nrfxSpi, &xfer_desc, 0); 252 } 253 254 INLINE void Arduino_NRFXSPI::WRITEBUF(uint8_t *buf, size_t count) 255 { 256 const nrfx_spi_xfer_desc_t xfer_desc = NRFX_SPI_SINGLE_XFER(buf, count, NULL, 0); 257 nrfx_spi_xfer(&_nrfxSpi, &xfer_desc, 0); 258 } 259 260 /******** low level bit twiddling **********/ 261 262 INLINE void Arduino_NRFXSPI::DC_HIGH(void) 263 { 264 *_dcPortSet = _dcPinMask; 265 } 266 267 INLINE void Arduino_NRFXSPI::DC_LOW(void) 268 { 269 *_dcPortClr = _dcPinMask; 270 } 271 272 INLINE void Arduino_NRFXSPI::CS_HIGH(void) 273 { 274 if (_cs != GFX_NOT_DEFINED) 275 { 276 *_csPortSet = _csPinMask; 277 } 278 } 279 280 INLINE void Arduino_NRFXSPI::CS_LOW(void) 281 { 282 if (_cs != GFX_NOT_DEFINED) 283 { 284 *_csPortClr = _csPinMask; 285 } 286 } 287 288 #endif // #ifdef ARDUINO_ARCH_NRF52840