11#include " Adafruit_SPIDevice.h"
22
3+ #include < array>
4+
35#if !defined(SPI_INTERFACES_COUNT) || \
46 (defined (SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0 ))
57
8+ // ! constant for the buffer size for the chunked transfer
9+ constexpr size_t maxBufferSizeForChunkedTransfer = 64 ;
10+
611// #define DEBUG_SERIAL Serial
712
13+ #ifdef DEBUG_SERIAL
14+ static printChunk (char *title, uint8_t buffer, uint8_t size,
15+ uint16_t chunkNumber) {
16+ DEBUG_SERIAL.print (F (" \t " ));
17+ DEBUG_SERIAL.print (title);
18+ DEBUG_SERIAL.print (F (" Chunk #" ));
19+ DEBUG_SERIAL.print (chunkNumber);
20+ DEBUG_SERIAL.print (F (" , size " ));
21+ DEBUG_SERIAL.println (size);
22+
23+ for (uint8_t i = 0 ; i < size; ++i) {
24+ DEBUG_SERIAL.print (F (" 0x" ));
25+ DEBUG_SERIAL.print (buffer[i], HEX);
26+ DEBUG_SERIAL.print (F (" , " ));
27+ }
28+ DEBUG_SERIAL.println ();
29+ }
30+
31+ static printBuffer (char *title, uint8_t buffer, size_t len) {
32+ DEBUG_SERIAL.print (F (" \t " ));
33+ DEBUG_SERIAL.println (title);
34+ for (size_t i = 0 ; i < len; i++) {
35+ DEBUG_SERIAL.print (F (" 0x" ));
36+ DEBUG_SERIAL.print (buffer[i], HEX);
37+ DEBUG_SERIAL.print (F (" , " ));
38+ if (read_len % 32 == 31 ) {
39+ DEBUG_SERIAL.println ();
40+ }
41+ }
42+ DEBUG_SERIAL.println ();
43+ }
44+ #endif
45+
846/* !
947 * @brief Create an SPI device with the given CS pin and settings
1048 * @param cspin The arduino pin number to use for chip select
@@ -160,7 +198,6 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
160198 // Serial.print(send, HEX);
161199 for (uint8_t b = startbit; b != 0 ;
162200 b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1 ) {
163-
164201 if (bitdelay_us) {
165202 delayMicroseconds (bitdelay_us);
166203 }
@@ -326,49 +363,77 @@ void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
326363bool Adafruit_SPIDevice::write (const uint8_t *buffer, size_t len,
327364 const uint8_t *prefix_buffer,
328365 size_t prefix_len) {
366+ #if !defined(__AVR__)
367+ std::array<uint8_t , maxBufferSizeForChunkedTransfer> chunkBuffer;
368+
369+ auto chunkBufferIterator = chunkBuffer.begin ();
370+
371+ #ifdef DEBUG_SERIAL
372+ uint8_t chunkNumber = 1 ;
373+ #endif
374+
329375 beginTransactionWithAssertingCS ();
330376
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
377+ for ( size_t i = 0 ; i < prefix_len; ++i) {
378+ *chunkBufferIterator++ = prefix_buffer[i];
379+
380+ if (chunkBufferIterator == chunkBuffer. end () ) {
381+ transfer (chunkBuffer. data (), maxBufferSizeForChunkedTransfer );
382+ chunkBufferIterator = chunkBuffer. begin ();
383+
384+ # ifdef DEBUG_SERIAL
385+ printChunk ( " write() Wrote " , chunkBuffer, maxBufferSizeForChunkedTransfer,
386+ chunkNumber++);
341387#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]);
348388 }
349389 }
350- endTransactionWithDeassertingCS ();
390+
391+ for (size_t i = 0 ; i < len; ++i) {
392+ *chunkBufferIterator++ = buffer[i];
393+
394+ if (chunkBufferIterator == chunkBuffer.end ()) {
395+ transfer (chunkBuffer.data (), maxBufferSizeForChunkedTransfer);
396+ chunkBufferIterator = chunkBuffer.begin ();
351397
352398#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 (" , " ));
399+ printChunk (" write() Wrote" , chunkBuffer, maxBufferSizeForChunkedTransfer,
400+ chunkNumber++);
401+ #endif
359402 }
360403 }
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- }
404+
405+ if (chunkBufferIterator != chunkBuffer.begin ()) {
406+ auto numberByteToTransfer = chunkBufferIterator - chunkBuffer.begin ();
407+ transfer (chunkBuffer.data (), numberByteToTransfer);
408+
409+ #ifdef DEBUG_SERIAL
410+ printChunk (" write() Wrote remaining" , mpBuffer, numberByteToTransfer,
411+ chunkNumber++);
412+ #endif
368413 }
369- DEBUG_SERIAL.println ();
414+
415+ endTransactionWithDeassertingCS ();
416+
417+ #else // !defined(__AVR__)
418+
419+ beginTransactionWithAssertingCS ();
420+
421+ for (size_t i = 0 ; i < prefix_len; i++) {
422+ transfer (prefix_buffer[i]);
423+ }
424+ for (size_t i = 0 ; i < len; i++) {
425+ transfer (buffer[i]);
426+ }
427+
428+ endTransactionWithDeassertingCS ();
429+
430+ #ifdef DEBUG_SERIAL
431+ printBuffer (" write() prefix_buffer" , prefix_buffer, prefix_len);
432+ printBuffer (" write() buffer" , buffer, len);
370433#endif
371434
435+ #endif // !defined(__AVR__)
436+
372437 return true ;
373438}
374439
@@ -390,16 +455,7 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
390455 endTransactionWithDeassertingCS ();
391456
392457#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 ();
458+ printBuffer (" read() buffer" , buffer, len);
403459#endif
404460
405461 return true ;
@@ -421,53 +477,112 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
421477bool Adafruit_SPIDevice::write_then_read (const uint8_t *write_buffer,
422478 size_t write_len, uint8_t *read_buffer,
423479 size_t read_len, uint8_t sendvalue) {
480+ #if !defined(__AVR__)
481+ std::array<uint8_t , maxBufferSizeForChunkedTransfer> chunkBuffer;
482+
483+ auto chunkBufferIterator = chunkBuffer.begin ();
484+
485+ #ifdef DEBUG_SERIAL
486+ uint8_t chunkNumber = 1 ;
487+ #endif
488+
424489 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
490+
491+ for (size_t i = 0 ; i < write_len; ++i) {
492+ *chunkBufferIterator++ = write_buffer[i];
493+
494+ if (chunkBufferIterator == chunkBuffer.end ()) {
495+ transfer (chunkBuffer.data (), maxBufferSizeForChunkedTransfer);
496+ chunkBufferIterator = chunkBuffer.begin ();
497+
498+ #ifdef DEBUG_SERIAL
499+ printChunk (" write_then_read() Wrote" , chunkBuffer,
500+ maxBufferSizeForChunkedTransfer, chunkNumber++);
432501#endif
433- {
434- for (size_t i = 0 ; i < write_len; i++) {
435- transfer (write_buffer[i]);
436502 }
437503 }
438504
505+ auto readBufferIterator = read_buffer;
506+ auto readFromIterator = chunkBufferIterator;
507+ size_t readBufferLen = read_len;
508+
509+ for (size_t i = 0 ; i < read_len; ++i) {
510+ *chunkBufferIterator++ = sendvalue;
511+
512+ if (chunkBufferIterator == chunkBuffer.end ()) {
439513#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 ();
514+ printChunk (" write_then_read() before transmit" , chunkBuffer,
515+ maxBufferSizeForChunkedTransfer, chunkNumber);
516+ #endif
517+
518+ transfer (chunkBuffer.data (), maxBufferSizeForChunkedTransfer);
519+
520+ while (readBufferLen) {
521+ if (readFromIterator != chunkBuffer.end ()) {
522+ *readBufferIterator++ = *readFromIterator++;
523+ --readBufferLen;
524+ } else {
525+ break ;
526+ }
527+ }
528+
529+ #ifdef DEBUG_SERIAL
530+ printChunk (" write_then_read() after transmit" , chunkBuffer,
531+ maxBufferSizeForChunkedTransfer, chunkNumber++);
532+ #endif
533+
534+ chunkBufferIterator = chunkBuffer.begin ();
535+ readFromIterator = chunkBuffer.begin ();
447536 }
448537 }
449- DEBUG_SERIAL.println ();
538+
539+ if (chunkBufferIterator != chunkBuffer.begin ()) {
540+ auto numberByteToTransfer = chunkBufferIterator - chunkBuffer.begin ();
541+
542+ #ifdef DEBUG_SERIAL
543+ printChunk (" write_then_read() before transmit remaining" , chunkBuffer,
544+ maxBufferSizeForChunkedTransfer, chunkNumber);
545+ #endif
546+
547+ transfer (chunkBuffer.data (), numberByteToTransfer);
548+
549+ #ifdef DEBUG_SERIAL
550+ printChunk (" write_then_read() after transmit remaining" , chunkBuffer,
551+ numberByteToTransfer, chunkNumber);
450552#endif
451553
452- // do the reading
554+ while (readBufferLen) {
555+ if (readFromIterator != chunkBuffer.end ()) {
556+ *readBufferIterator++ = *readFromIterator++;
557+ --readBufferLen;
558+ } else {
559+ break ;
560+ }
561+ }
562+ }
563+
564+ endTransactionWithDeassertingCS ();
565+
566+ #else // !defined(__AVR__)
567+
568+ beginTransactionWithAssertingCS ();
569+
570+ for (size_t i = 0 ; i < write_len; i++) {
571+ transfer (write_buffer[i]);
572+ }
573+
453574 for (size_t i = 0 ; i < read_len; i++) {
454575 read_buffer[i] = transfer (sendvalue);
455576 }
456577
578+ endTransactionWithDeassertingCS ();
579+
457580#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 ();
581+ printBuffer (" write_then_read() write_buffer" , write_buffer, write_len);
582+ printBuffer (" write_then_read() read_buffer" , read_buffer, read_len);
468583#endif
469584
470- endTransactionWithDeassertingCS ();
585+ # endif // !defined(__AVR__)
471586
472587 return true ;
473588}
0 commit comments