@@ -546,20 +546,18 @@ void SPIClass::transferBytesAligned_(const uint8_t * out, uint8_t * in, uint8_t
546
546
setDataBits (size * 8 );
547
547
548
548
volatile uint32_t *fifoPtr = &SPI1W0;
549
- uint8_t dataSize = ((size + 3 ) / 4 );
550
549
551
550
if (out) {
551
+ uint8_t outSize = ((size + 3 ) / 4 );
552
552
uint32_t *dataPtr = (uint32_t *) out;
553
- while (dataSize--) {
554
- *fifoPtr = *dataPtr;
555
- dataPtr++;
556
- fifoPtr++;
553
+ while (outSize--) {
554
+ *(fifoPtr++) = *(dataPtr++);
557
555
}
558
556
} else {
557
+ uint8_t outSize = ((size + 3 ) / 4 );
559
558
// no out data only read fill with dummy data!
560
- while (dataSize--) {
561
- *fifoPtr = 0xFFFFFFFF ;
562
- fifoPtr++;
559
+ while (outSize--) {
560
+ *(fifoPtr++) = 0xFFFFFFFF ;
563
561
}
564
562
}
565
563
@@ -569,14 +567,15 @@ void SPIClass::transferBytesAligned_(const uint8_t * out, uint8_t * in, uint8_t
569
567
if (in) {
570
568
uint32_t *dataPtr = (uint32_t *) in;
571
569
fifoPtr = &SPI1W0;
572
- dataSize = size;
573
- while (dataSize >= 4 ) {
570
+ int inSize = size;
571
+ // Unlike outSize above, inSize tracks *bytes* since we must transfer only the requested bytes to the app to avoid overwriting other vars.
572
+ while (inSize >= 4 ) {
574
573
*(dataPtr++) = *(fifoPtr++);
575
- dataSize -= 4 ;
574
+ inSize -= 4 ;
576
575
in += 4 ;
577
576
}
578
577
volatile uint8_t *fifoPtrB = (volatile uint8_t *)fifoPtr;
579
- while (dataSize --) {
578
+ while (inSize --) {
580
579
*(in++) = *(fifoPtrB++);
581
580
}
582
581
}
@@ -587,33 +586,28 @@ void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) {
587
586
if (!((uint32_t )out & 3 ) && !((uint32_t )in & 3 )) {
588
587
// Input and output are both 32b aligned or NULL
589
588
transferBytesAligned_ (out, in, size);
590
- } else if (!out && (( uint32_t )in & 3 ) ) {
589
+ } else if (!out) {
591
590
// Input only and misaligned, do bytewise until in aligned
592
591
while (size && ((uint32_t )in & 3 )) {
593
592
*(in++) = transfer (0xff );
594
- size--;
593
+ size--;
595
594
}
596
595
transferBytesAligned_ (out, in, size);
597
- } else if (!in && (( uint32_t )out & 3 ) ) {
596
+ } else if (!in) {
598
597
// Output only and misaligned, bytewise xmit until aligned
599
598
while (size && ((uint32_t )out & 3 )) {
600
599
transfer (*(out++));
601
- size--;
600
+ size--;
602
601
}
603
602
transferBytesAligned_ (out, in, size);
604
603
} else {
605
- // HW FIFO has 64b limit, so just align in RAM and then send to FIFO aligned
606
- uint8_t outAligned[64 ]; // Stack vars will be 32b aligned
607
- uint8_t inAligned[64 ]; // Stack vars will be 32b aligned
608
- if (out) {
609
- memcpy (outAligned, out, size);
610
- } else {
611
- memset (outAligned, 0xff , size); // 0xff = no xmit data
612
- }
613
- transferBytesAligned_ (outAligned, inAligned, size);
614
- if (in) {
615
- memcpy (in, inAligned, size);
616
- }
604
+ // HW FIFO has 64b limit and ::transferBytes breaks up large xfers into 64byte chunks before calling this function
605
+ // We know at this point it is a bidirectional transfer
606
+ uint8_t aligned[64 ]; // Stack vars will be 32b aligned
607
+ // No need for separate out and in aligned copies, we can overwrite our out copy with the input data safely
608
+ memcpy (aligned, out, size);
609
+ transferBytesAligned_ (aligned, aligned, size);
610
+ memcpy (in, aligned, size);
617
611
}
618
612
}
619
613
0 commit comments