11#include " Adafruit_SPIDevice.h"
22
3+ #if !defined(__AVR__)
4+ #include < array>
5+ #endif
6+
37#if !defined(SPI_INTERFACES_COUNT) || \
48 (defined (SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0 ))
59
10+ // ! constant for the buffer size for the chunked transfer
11+ constexpr size_t maxBufferSizeForChunkedTransfer = 64 ;
12+
613// #define DEBUG_SERIAL Serial
714
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+
848/* !
949 * @brief Create an SPI device with the given CS pin and settings
1050 * @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) {
160200 // Serial.print(send, HEX);
161201 for (uint8_t b = startbit; b != 0 ;
162202 b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1 ) {
163-
164203 if (bitdelay_us) {
165204 delayMicroseconds (bitdelay_us);
166205 }
@@ -326,49 +365,77 @@ void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
326365bool Adafruit_SPIDevice::write (const uint8_t *buffer, size_t len,
327366 const uint8_t *prefix_buffer,
328367 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+
329377 beginTransactionWithAssertingCS ();
330378
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++);
341389#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]);
348390 }
349391 }
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 ();
351399
352400#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
359404 }
360405 }
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
368415 }
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);
370435#endif
371436
437+ #endif // !defined(__AVR__)
438+
372439 return true ;
373440}
374441
@@ -390,16 +457,7 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
390457 endTransactionWithDeassertingCS ();
391458
392459#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);
403461#endif
404462
405463 return true ;
@@ -421,53 +479,112 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
421479bool Adafruit_SPIDevice::write_then_read (const uint8_t *write_buffer,
422480 size_t write_len, uint8_t *read_buffer,
423481 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+
424491 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++);
432503#endif
433- {
434- for (size_t i = 0 ; i < write_len; i++) {
435- transfer (write_buffer[i]);
436504 }
437505 }
438506
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 ()) {
439515#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 ();
447538 }
448539 }
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);
450554#endif
451555
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+
453576 for (size_t i = 0 ; i < read_len; i++) {
454577 read_buffer[i] = transfer (sendvalue);
455578 }
456579
580+ endTransactionWithDeassertingCS ();
581+
457582#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);
468585#endif
469586
470- endTransactionWithDeassertingCS ();
587+ # endif // !defined(__AVR__)
471588
472589 return true ;
473590}
0 commit comments