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" 
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" 
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" 
432+   printBuffer (" write() buffer" 
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" 
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" 
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" 
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" 
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" 
544+                maxBufferSizeForChunkedTransfer, chunkNumber);
545+ #endif 
546+ 
547+     transfer (chunkBuffer.data (), numberByteToTransfer);
548+ 
549+ #ifdef  DEBUG_SERIAL
550+     printChunk (" write_then_read() after transmit remaining" 
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" 
582+   printBuffer (" write_then_read() read_buffer" 
468583#endif 
469584
470-    endTransactionWithDeassertingCS (); 
585+ # endif   //  !defined(__AVR__) 
471586
472587  return  true ;
473588}
0 commit comments