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