@@ -62,12 +62,12 @@ void SPIClass::init() {
62
62
#define interruptsStatus () __interruptsStatus()
63
63
static inline unsigned char __interruptsStatus (void ) __attribute__((always_inline, unused));
64
64
static inline unsigned char __interruptsStatus (void ) {
65
- unsigned int primask, faultmask;
66
- asm volatile (" mrs %0, primask" : " =r" (primask));
67
- if (primask) return 0 ;
68
- asm volatile (" mrs %0, faultmask" : " =r" (faultmask));
69
- if (faultmask) return 0 ;
70
- return 1 ;
65
+ unsigned int primask, faultmask;
66
+ asm volatile (" mrs %0, primask" : " =r" (primask));
67
+ if (primask) return 0 ;
68
+ asm volatile (" mrs %0, faultmask" : " =r" (faultmask));
69
+ if (faultmask) return 0 ;
70
+ return 1 ;
71
71
}
72
72
#endif
73
73
@@ -182,18 +182,70 @@ byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
182
182
d |= SPI_TDR_LASTXFER;
183
183
184
184
// SPI_Write(spi, _channel, _data);
185
- while ((spi->SPI_SR & SPI_SR_TDRE) == 0 )
186
- ;
187
- spi->SPI_TDR = d;
188
-
189
- // return SPI_Read(spi);
190
- while ((spi->SPI_SR & SPI_SR_RDRF) == 0 )
191
- ;
192
- d = spi->SPI_RDR ;
185
+ while ((spi->SPI_SR & SPI_SR_TDRE) == 0 )
186
+ ;
187
+ spi->SPI_TDR = d;
188
+
189
+ // return SPI_Read(spi);
190
+ while ((spi->SPI_SR & SPI_SR_RDRF) == 0 )
191
+ ;
192
+ d = spi->SPI_RDR ;
193
193
// Reverse bit order
194
194
if (bitOrder[ch] == LSBFIRST)
195
195
d = __REV (__RBIT (d));
196
- return d & 0xFF ;
196
+ return d & 0xFF ;
197
+ }
198
+
199
+ void SPIClass::transfer (byte _pin, void *_buf, size_t _count, SPITransferMode _mode) {
200
+ if (_count == 0 )
201
+ return ;
202
+
203
+ uint8_t *buffer = (uint8_t *)_buf;
204
+ if (_count == 1 ) {
205
+ *buffer = transfer (_pin, *buffer, _mode);
206
+ return ;
207
+ }
208
+
209
+ uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL (_pin);
210
+ bool reverse = (bitOrder[ch] == LSBFIRST);
211
+
212
+ // Send the first byte
213
+ uint32_t d = *buffer;
214
+ if (reverse)
215
+ d = __REV (__RBIT (d));
216
+ while ((spi->SPI_SR & SPI_SR_TDRE) == 0 )
217
+ ;
218
+ spi->SPI_TDR = d | SPI_PCS (ch);
219
+
220
+ while (_count > 1 ) {
221
+ // Prepare next byte
222
+ d = *(buffer+1 );
223
+ if (reverse)
224
+ d = __REV (__RBIT (d));
225
+ if (_count == 2 && _mode == SPI_LAST)
226
+ d |= SPI_TDR_LASTXFER;
227
+
228
+ // Read transferred byte and send next one straight away
229
+ while ((spi->SPI_SR & SPI_SR_RDRF) == 0 )
230
+ ;
231
+ uint8_t r = spi->SPI_RDR ;
232
+ spi->SPI_TDR = d | SPI_PCS (ch);
233
+
234
+ // Save read byte
235
+ if (reverse)
236
+ r = __REV (__RBIT (r));
237
+ *buffer = r;
238
+ buffer++;
239
+ _count--;
240
+ }
241
+
242
+ // Receive the last transferred byte
243
+ while ((spi->SPI_SR & SPI_SR_RDRF) == 0 )
244
+ ;
245
+ uint8_t r = spi->SPI_RDR ;
246
+ if (reverse)
247
+ r = __REV (__RBIT (r));
248
+ *buffer = r;
197
249
}
198
250
199
251
void SPIClass::attachInterrupt (void ) {
0 commit comments