Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3cc12b1

Browse files
d-a-vdevyte
authored andcommitted
arduino API's SPI::transfer(void*, size) (optimized) (#4925)
* SPI::transfer(void*, size) (optimized) * spi: transfer(): fix checking size * spi: transferBytes_: 32bits miso transfer * spi: transferBytes_: fix declaration * spi: transferBytes: add comments, reduce diff
1 parent 9c846bd commit 3cc12b1

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

libraries/SPI/SPI.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,25 @@ uint16_t SPIClass::transfer16(uint16_t data) {
323323
return out.val;
324324
}
325325

326+
void SPIClass::transfer(void *buf, uint16_t count) {
327+
uint8_t *cbuf = reinterpret_cast<uint8_t*>(buf);
328+
329+
// cbuf may not be 32bits-aligned
330+
for (; (((unsigned long)cbuf) & 3) && count; cbuf++, count--)
331+
*cbuf = transfer(*cbuf);
332+
333+
// cbuf is now aligned
334+
// count may not be a multiple of 4
335+
uint16_t count4 = count & ~3;
336+
transferBytes(cbuf, cbuf, count4);
337+
338+
// finish the last <4 bytes
339+
cbuf += count4;
340+
count -= count4;
341+
for (; count; cbuf++, count--)
342+
*cbuf = transfer(*cbuf);
343+
}
344+
326345
void SPIClass::write(uint8_t data) {
327346
while(SPI1CMD & SPIBUSY) {}
328347
// reset to 8Bit mode
@@ -511,6 +530,14 @@ void SPIClass::transferBytes(const uint8_t * out, uint8_t * in, uint32_t size) {
511530
}
512531
}
513532

533+
/**
534+
* Note:
535+
* in and out need to be aligned to 32Bit
536+
* or you get an Fatal exception (9)
537+
* @param out uint8_t *
538+
* @param in uint8_t *
539+
* @param size uint8_t (max 64)
540+
*/
514541
void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) {
515542
while(SPI1CMD & SPIBUSY) {}
516543
// Set in/out Bits to transfer
@@ -539,12 +566,13 @@ void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) {
539566
while(SPI1CMD & SPIBUSY) {}
540567

541568
if(in) {
542-
volatile uint8_t * fifoPtr8 = (volatile uint8_t *) &SPI1W0;
543-
dataSize = size;
569+
uint32_t * dataPtr = (uint32_t*) in;
570+
fifoPtr = &SPI1W0;
571+
dataSize = ((size + 3) / 4);
544572
while(dataSize--) {
545-
*in = *fifoPtr8;
546-
in++;
547-
fifoPtr8++;
573+
*dataPtr = *fifoPtr;
574+
dataPtr++;
575+
fifoPtr++;
548576
}
549577
}
550578
}

libraries/SPI/SPI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class SPIClass {
6464
void beginTransaction(SPISettings settings);
6565
uint8_t transfer(uint8_t data);
6666
uint16_t transfer16(uint16_t data);
67+
void transfer(void *buf, uint16_t count);
6768
void write(uint8_t data);
6869
void write16(uint16_t data);
6970
void write16(uint16_t data, bool msb);

0 commit comments

Comments
 (0)