@@ -36,6 +36,7 @@ typedef union {
36
36
SPIClass SPI;
37
37
38
38
SPIClass::SPIClass () {
39
+ useHwCs = false ;
39
40
}
40
41
41
42
void SPIClass::begin () {
@@ -54,9 +55,26 @@ void SPIClass::end() {
54
55
pinMode (SCK, INPUT);
55
56
pinMode (MISO, INPUT);
56
57
pinMode (MOSI, INPUT);
58
+ if (useHwCs) {
59
+ pinMode (SS, INPUT);
60
+ }
61
+ }
62
+
63
+ void SPIClass::setHwCs (bool use) {
64
+ if (use) {
65
+ pinMode (SS, SPECIAL); // /< GPIO15
66
+ SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
67
+ } else {
68
+ if (useHwCs) {
69
+ pinMode (SS, INPUT);
70
+ SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
71
+ }
72
+ }
73
+ useHwCs = use;
57
74
}
58
75
59
76
void SPIClass::beginTransaction (SPISettings settings) {
77
+ while (SPI1CMD & SPIBUSY) {}
60
78
setFrequency (settings._clock );
61
79
setBitOrder (settings._bitOrder );
62
80
setDataMode (settings._dataMode );
@@ -199,12 +217,10 @@ void SPIClass::setClockDivider(uint32_t clockDiv) {
199
217
}
200
218
201
219
uint8_t SPIClass::transfer (uint8_t data) {
202
- while (SPI1CMD & SPIBUSY)
203
- ;
220
+ while (SPI1CMD & SPIBUSY) {}
204
221
SPI1W0 = data;
205
222
SPI1CMD |= SPIBUSY;
206
- while (SPI1CMD & SPIBUSY)
207
- ;
223
+ while (SPI1CMD & SPIBUSY) {}
208
224
return (uint8_t ) (SPI1W0 & 0xff );
209
225
}
210
226
@@ -230,3 +246,101 @@ uint16_t SPIClass::transfer16(uint16_t data) {
230
246
return out.val ;
231
247
}
232
248
249
+ void SPIClass::write (uint8_t data) {
250
+ while (SPI1CMD & SPIBUSY) {}
251
+ SPI1W0 = data;
252
+ SPI1CMD |= SPIBUSY;
253
+ while (SPI1CMD & SPIBUSY) {}
254
+ }
255
+
256
+ void SPIClass::write16 (uint16_t data) {
257
+ write16 (data, (SPI1C & (SPICWBO | SPICRBO)));
258
+ }
259
+
260
+ void SPIClass::write16 (uint16_t data, bool msb) {
261
+ while (SPI1CMD & SPIBUSY) {}
262
+ // Set to 16Bits transfer
263
+ SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((16 - 1 ) << SPILMOSI);
264
+ if (msb) {
265
+ // MSBFIRST Byte first
266
+ SPI1W0 = (data >> 8 ) | (data << 8 );
267
+ SPI1CMD |= SPIBUSY;
268
+ } else {
269
+ // LSBFIRST Byte first
270
+ SPI1W0 = data;
271
+ SPI1CMD |= SPIBUSY;
272
+ }
273
+ while (SPI1CMD & SPIBUSY) {}
274
+ // reset to 8Bit mode
275
+ SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1 ) << SPILMOSI);
276
+ }
277
+
278
+ void SPIClass::writeBytes (uint8_t * data, uint32_t size) {
279
+ while (size) {
280
+ if (size > 64 ) {
281
+ writeBytes_ (data, 64 );
282
+ size -= 64 ;
283
+ data += 64 ;
284
+ } else {
285
+ writeBytes_ (data, size);
286
+ size = 0 ;
287
+ }
288
+ }
289
+ }
290
+
291
+ void SPIClass::writeBytes_ (uint8_t * data, uint8_t size) {
292
+ while (SPI1CMD & SPIBUSY) {}
293
+ // Set Bits to transfer
294
+ SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((size * 8 - 1 ) << SPILMOSI);
295
+
296
+ volatile uint32_t * fifoPtr = &SPI1W0;
297
+ uint32_t * dataPtr = (uint32_t *) data;
298
+ uint8_t dataSize = ((size + 3 ) / 4 );
299
+
300
+ while (dataSize--) {
301
+ *fifoPtr = *dataPtr;
302
+ dataPtr++;
303
+ fifoPtr++;
304
+ }
305
+
306
+ SPI1CMD |= SPIBUSY;
307
+ while (SPI1CMD & SPIBUSY) {}
308
+ // reset to 8Bit mode
309
+ SPI1U1 = (SPI1U1 & ~((SPIMMOSI << SPILMOSI))) | ((8 - 1 ) << SPILMOSI);
310
+ }
311
+
312
+ void SPIClass::writePattern (uint8_t * data, uint8_t size, uint32_t repeat) {
313
+ if (size > 64 ) return ; // max Hardware FIFO
314
+
315
+ uint32_t byte = (size * repeat);
316
+ uint8_t r = (64 / size);
317
+
318
+ while (byte) {
319
+ if (byte > 64 ) {
320
+ writePattern_ (data, size, r);
321
+ byte -= 64 ;
322
+ } else {
323
+ writePattern_ (data, size, (byte / size));
324
+ byte = 0 ;
325
+ }
326
+ }
327
+ }
328
+
329
+ void SPIClass::writePattern_ (uint8_t * data, uint8_t size, uint8_t repeat) {
330
+ uint8_t bytes = (size * repeat);
331
+ uint8_t buffer[64 ];
332
+ uint8_t * bufferPtr = &buffer[0 ];
333
+ uint8_t * dataPtr;
334
+ uint8_t dataSize = bytes;
335
+ for (uint8_t i = 0 ; i < repeat; i++) {
336
+ dataSize = size;
337
+ dataPtr = data;
338
+ while (dataSize--) {
339
+ *bufferPtr = *dataPtr;
340
+ dataPtr++;
341
+ bufferPtr++;
342
+ }
343
+ }
344
+
345
+ writeBytes (&buffer[0 ], bytes);
346
+ }
0 commit comments