1
1
#include " Adafruit_SPIDevice.h"
2
2
3
+ #if !defined(__AVR__)
4
+ #include < array>
5
+ #endif
6
+
3
7
#if !defined(SPI_INTERFACES_COUNT) || \
4
8
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0 ))
5
9
10
+ // ! constant for the buffer size for the chunked transfer
11
+ constexpr size_t maxBufferSizeForChunkedTransfer = 64 ;
12
+
6
13
// #define DEBUG_SERIAL Serial
7
14
15
+ #ifdef DEBUG_SERIAL
16
+ #if !defined(__AVR__)
17
+ template <typename T>
18
+ static void printChunk (const char *title, const T &buffer, const uint8_t size,
19
+ const uint16_t chunkNumber) {
20
+ DEBUG_SERIAL.print (F (" \t " ));
21
+ DEBUG_SERIAL.print (title);
22
+ DEBUG_SERIAL.print (F (" Chunk #" ));
23
+ DEBUG_SERIAL.print (chunkNumber);
24
+ DEBUG_SERIAL.print (F (" , size " ));
25
+ DEBUG_SERIAL.println (size);
26
+ DEBUG_SERIAL.print (F (" \t " ));
27
+
28
+ for (uint8_t i = 0 ; i < size; ++i) {
29
+ DEBUG_SERIAL.print (F (" 0x" ));
30
+ DEBUG_SERIAL.print (buffer[i], HEX);
31
+ DEBUG_SERIAL.print (F (" , " ));
32
+ }
33
+ DEBUG_SERIAL.println ();
34
+ }
35
+ #endif
36
+
37
+ static void printBuffer (const char *title, const uint8_t *buffer,
38
+ const size_t len) {
39
+ DEBUG_SERIAL.print (F (" \t " ));
40
+ DEBUG_SERIAL.println (title);
41
+ for (size_t i = 0 ; i < len; i++) {
42
+ DEBUG_SERIAL.print (F (" 0x" ));
43
+ DEBUG_SERIAL.print (buffer[i], HEX);
44
+ DEBUG_SERIAL.print (F (" , " ));
45
+ if (i % 32 == 31 ) {
46
+ DEBUG_SERIAL.println ();
47
+ }
48
+ }
49
+ DEBUG_SERIAL.println ();
50
+ }
51
+ #endif
52
+
8
53
/* !
9
54
* @brief Create an SPI device with the given CS pin and settings
10
55
* @param cspin The arduino pin number to use for chip select
@@ -160,7 +205,6 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
160
205
// Serial.print(send, HEX);
161
206
for (uint8_t b = startbit; b != 0 ;
162
207
b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1 ) {
163
-
164
208
if (bitdelay_us) {
165
209
delayMicroseconds (bitdelay_us);
166
210
}
@@ -326,49 +370,77 @@ void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
326
370
bool Adafruit_SPIDevice::write (const uint8_t *buffer, size_t len,
327
371
const uint8_t *prefix_buffer,
328
372
size_t prefix_len) {
373
+ #if !defined(__AVR__)
374
+ std::array<uint8_t , maxBufferSizeForChunkedTransfer> chunkBuffer;
375
+
376
+ auto chunkBufferIterator = chunkBuffer.begin ();
377
+
378
+ #ifdef DEBUG_SERIAL
379
+ uint8_t chunkNumber = 1 ;
380
+ #endif
381
+
329
382
beginTransactionWithAssertingCS ();
330
383
331
- // do the writing
332
- # if defined(ARDUINO_ARCH_ESP32)
333
- if (_spi) {
334
- if (prefix_len > 0 ) {
335
- _spi-> transferBytes (prefix_buffer, nullptr , prefix_len );
336
- }
337
- if (len > 0 ) {
338
- _spi-> transferBytes (buffer, nullptr , len);
339
- }
340
- } else
384
+ for ( size_t i = 0 ; i < prefix_len; ++i) {
385
+ *chunkBufferIterator++ = prefix_buffer[i];
386
+
387
+ if (chunkBufferIterator == chunkBuffer. end () ) {
388
+ transfer (chunkBuffer. data (), maxBufferSizeForChunkedTransfer );
389
+ chunkBufferIterator = chunkBuffer. begin ();
390
+
391
+ # ifdef DEBUG_SERIAL
392
+ printChunk ( " write() Wrote " , chunkBuffer, maxBufferSizeForChunkedTransfer,
393
+ chunkNumber++);
341
394
#endif
342
- {
343
- for (size_t i = 0 ; i < prefix_len; i++) {
344
- transfer (prefix_buffer[i]);
345
- }
346
- for (size_t i = 0 ; i < len; i++) {
347
- transfer (buffer[i]);
348
395
}
349
396
}
350
- endTransactionWithDeassertingCS ();
397
+
398
+ for (size_t i = 0 ; i < len; ++i) {
399
+ *chunkBufferIterator++ = buffer[i];
400
+
401
+ if (chunkBufferIterator == chunkBuffer.end ()) {
402
+ transfer (chunkBuffer.data (), maxBufferSizeForChunkedTransfer);
403
+ chunkBufferIterator = chunkBuffer.begin ();
351
404
352
405
#ifdef DEBUG_SERIAL
353
- DEBUG_SERIAL.print (F (" \t SPIDevice Wrote: " ));
354
- if ((prefix_len != 0 ) && (prefix_buffer != nullptr )) {
355
- for (uint16_t i = 0 ; i < prefix_len; i++) {
356
- DEBUG_SERIAL.print (F (" 0x" ));
357
- DEBUG_SERIAL.print (prefix_buffer[i], HEX);
358
- DEBUG_SERIAL.print (F (" , " ));
406
+ printChunk (" write() Wrote" , chunkBuffer, maxBufferSizeForChunkedTransfer,
407
+ chunkNumber++);
408
+ #endif
359
409
}
360
410
}
361
- for (uint16_t i = 0 ; i < len; i++) {
362
- DEBUG_SERIAL.print (F (" 0x" ));
363
- DEBUG_SERIAL.print (buffer[i], HEX);
364
- DEBUG_SERIAL.print (F (" , " ));
365
- if (i % 32 == 31 ) {
366
- DEBUG_SERIAL.println ();
367
- }
411
+
412
+ if (chunkBufferIterator != chunkBuffer.begin ()) {
413
+ auto numberByteToTransfer = chunkBufferIterator - chunkBuffer.begin ();
414
+ transfer (chunkBuffer.data (), numberByteToTransfer);
415
+
416
+ #ifdef DEBUG_SERIAL
417
+ printChunk (" write() Wrote remaining" , chunkBuffer, numberByteToTransfer,
418
+ chunkNumber++);
419
+ #endif
368
420
}
369
- DEBUG_SERIAL.println ();
421
+
422
+ endTransactionWithDeassertingCS ();
423
+
424
+ #else // !defined(__AVR__)
425
+
426
+ beginTransactionWithAssertingCS ();
427
+
428
+ for (size_t i = 0 ; i < prefix_len; i++) {
429
+ transfer (prefix_buffer[i]);
430
+ }
431
+ for (size_t i = 0 ; i < len; i++) {
432
+ transfer (buffer[i]);
433
+ }
434
+
435
+ endTransactionWithDeassertingCS ();
436
+
437
+ #ifdef DEBUG_SERIAL
438
+ printBuffer (" write() prefix_buffer" , prefix_buffer, prefix_len);
439
+ printBuffer (" write() buffer" , buffer, len);
370
440
#endif
371
441
442
+ #endif // !defined(__AVR__)
443
+
372
444
return true ;
373
445
}
374
446
@@ -390,16 +462,7 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
390
462
endTransactionWithDeassertingCS ();
391
463
392
464
#ifdef DEBUG_SERIAL
393
- DEBUG_SERIAL.print (F (" \t SPIDevice Read: " ));
394
- for (uint16_t i = 0 ; i < len; i++) {
395
- DEBUG_SERIAL.print (F (" 0x" ));
396
- DEBUG_SERIAL.print (buffer[i], HEX);
397
- DEBUG_SERIAL.print (F (" , " ));
398
- if (len % 32 == 31 ) {
399
- DEBUG_SERIAL.println ();
400
- }
401
- }
402
- DEBUG_SERIAL.println ();
465
+ printBuffer (" read() buffer" , buffer, len);
403
466
#endif
404
467
405
468
return true ;
@@ -421,53 +484,112 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
421
484
bool Adafruit_SPIDevice::write_then_read (const uint8_t *write_buffer,
422
485
size_t write_len, uint8_t *read_buffer,
423
486
size_t read_len, uint8_t sendvalue) {
487
+ #if !defined(__AVR__)
488
+ std::array<uint8_t , maxBufferSizeForChunkedTransfer> chunkBuffer;
489
+
490
+ auto chunkBufferIterator = chunkBuffer.begin ();
491
+
492
+ #ifdef DEBUG_SERIAL
493
+ uint8_t chunkNumber = 1 ;
494
+ #endif
495
+
424
496
beginTransactionWithAssertingCS ();
425
- // do the writing
426
- #if defined(ARDUINO_ARCH_ESP32)
427
- if (_spi) {
428
- if (write_len > 0 ) {
429
- _spi->transferBytes (write_buffer, nullptr , write_len);
430
- }
431
- } else
497
+
498
+ for (size_t i = 0 ; i < write_len; ++i) {
499
+ *chunkBufferIterator++ = write_buffer[i];
500
+
501
+ if (chunkBufferIterator == chunkBuffer.end ()) {
502
+ transfer (chunkBuffer.data (), maxBufferSizeForChunkedTransfer);
503
+ chunkBufferIterator = chunkBuffer.begin ();
504
+
505
+ #ifdef DEBUG_SERIAL
506
+ printChunk (" write_then_read() Wrote" , chunkBuffer,
507
+ maxBufferSizeForChunkedTransfer, chunkNumber++);
432
508
#endif
433
- {
434
- for (size_t i = 0 ; i < write_len; i++) {
435
- transfer (write_buffer[i]);
436
509
}
437
510
}
438
511
512
+ auto readBufferIterator = read_buffer;
513
+ auto readFromIterator = chunkBufferIterator;
514
+ size_t readBufferLen = read_len;
515
+
516
+ for (size_t i = 0 ; i < read_len; ++i) {
517
+ *chunkBufferIterator++ = sendvalue;
518
+
519
+ if (chunkBufferIterator == chunkBuffer.end ()) {
439
520
#ifdef DEBUG_SERIAL
440
- DEBUG_SERIAL.print (F (" \t SPIDevice Wrote: " ));
441
- for (uint16_t i = 0 ; i < write_len; i++) {
442
- DEBUG_SERIAL.print (F (" 0x" ));
443
- DEBUG_SERIAL.print (write_buffer[i], HEX);
444
- DEBUG_SERIAL.print (F (" , " ));
445
- if (write_len % 32 == 31 ) {
446
- DEBUG_SERIAL.println ();
521
+ printChunk (" write_then_read() before transmit" , chunkBuffer,
522
+ maxBufferSizeForChunkedTransfer, chunkNumber);
523
+ #endif
524
+
525
+ transfer (chunkBuffer.data (), maxBufferSizeForChunkedTransfer);
526
+
527
+ while (readBufferLen) {
528
+ if (readFromIterator != chunkBuffer.end ()) {
529
+ *readBufferIterator++ = *readFromIterator++;
530
+ --readBufferLen;
531
+ } else {
532
+ break ;
533
+ }
534
+ }
535
+
536
+ #ifdef DEBUG_SERIAL
537
+ printChunk (" write_then_read() after transmit" , chunkBuffer,
538
+ maxBufferSizeForChunkedTransfer, chunkNumber++);
539
+ #endif
540
+
541
+ chunkBufferIterator = chunkBuffer.begin ();
542
+ readFromIterator = chunkBuffer.begin ();
447
543
}
448
544
}
449
- DEBUG_SERIAL.println ();
545
+
546
+ if (chunkBufferIterator != chunkBuffer.begin ()) {
547
+ auto numberByteToTransfer = chunkBufferIterator - chunkBuffer.begin ();
548
+
549
+ #ifdef DEBUG_SERIAL
550
+ printChunk (" write_then_read() before transmit remaining" , chunkBuffer,
551
+ numberByteToTransfer, chunkNumber);
552
+ #endif
553
+
554
+ transfer (chunkBuffer.data (), numberByteToTransfer);
555
+
556
+ #ifdef DEBUG_SERIAL
557
+ printChunk (" write_then_read() after transmit remaining" , chunkBuffer,
558
+ numberByteToTransfer, chunkNumber);
450
559
#endif
451
560
452
- // do the reading
561
+ while (readBufferLen) {
562
+ if (readFromIterator != chunkBuffer.end ()) {
563
+ *readBufferIterator++ = *readFromIterator++;
564
+ --readBufferLen;
565
+ } else {
566
+ break ;
567
+ }
568
+ }
569
+ }
570
+
571
+ endTransactionWithDeassertingCS ();
572
+
573
+ #else // !defined(__AVR__)
574
+
575
+ beginTransactionWithAssertingCS ();
576
+
577
+ for (size_t i = 0 ; i < write_len; i++) {
578
+ transfer (write_buffer[i]);
579
+ }
580
+
453
581
for (size_t i = 0 ; i < read_len; i++) {
454
582
read_buffer[i] = transfer (sendvalue);
455
583
}
456
584
585
+ endTransactionWithDeassertingCS ();
586
+
457
587
#ifdef DEBUG_SERIAL
458
- DEBUG_SERIAL.print (F (" \t SPIDevice Read: " ));
459
- for (uint16_t i = 0 ; i < read_len; i++) {
460
- DEBUG_SERIAL.print (F (" 0x" ));
461
- DEBUG_SERIAL.print (read_buffer[i], HEX);
462
- DEBUG_SERIAL.print (F (" , " ));
463
- if (read_len % 32 == 31 ) {
464
- DEBUG_SERIAL.println ();
465
- }
466
- }
467
- DEBUG_SERIAL.println ();
588
+ printBuffer (" write_then_read() write_buffer" , write_buffer, write_len);
589
+ printBuffer (" write_then_read() read_buffer" , read_buffer, read_len);
468
590
#endif
469
591
470
- endTransactionWithDeassertingCS ();
592
+ # endif // !defined(__AVR__)
471
593
472
594
return true ;
473
595
}
0 commit comments