From c85aa1579b20769b8250861fff107c6f2b4b814f Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 12 Jul 2018 23:19:35 +0200 Subject: [PATCH 1/5] SPI::transfer(void*, size) (optimized) --- libraries/SPI/SPI.cpp | 12 ++++++++++++ libraries/SPI/SPI.h | 1 + 2 files changed, 13 insertions(+) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 68be7d6c00..cab1b8a166 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -323,6 +323,18 @@ uint16_t SPIClass::transfer16(uint16_t data) { return out.val; } +void SPIClass::transfer(void *buf, uint16_t count) { + uint8_t *cbuf = reinterpret_cast(buf); + for (; ((long)cbuf) & 3; cbuf++, count--) + *cbuf = transfer(*cbuf); + uint16_t count4 = count & ~3; + transferBytes(cbuf, cbuf, count4); + cbuf += count4; + count -= count4; + for (; count; cbuf++, count--) + *cbuf = transfer(*cbuf); +} + void SPIClass::write(uint8_t data) { while(SPI1CMD & SPIBUSY) {} // reset to 8Bit mode diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index 7d1fe15592..84b619f670 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -64,6 +64,7 @@ class SPIClass { void beginTransaction(SPISettings settings); uint8_t transfer(uint8_t data); uint16_t transfer16(uint16_t data); + void transfer(void *buf, uint16_t count); void write(uint8_t data); void write16(uint16_t data); void write16(uint16_t data, bool msb); From f190e04d1c05d4e885f171ff23680e03daaa9afe Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 14 Jul 2018 00:37:41 +0200 Subject: [PATCH 2/5] spi: transfer(): fix checking size --- libraries/SPI/SPI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index cab1b8a166..093be1728f 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -325,7 +325,7 @@ uint16_t SPIClass::transfer16(uint16_t data) { void SPIClass::transfer(void *buf, uint16_t count) { uint8_t *cbuf = reinterpret_cast(buf); - for (; ((long)cbuf) & 3; cbuf++, count--) + for (; (((unsigned long)cbuf) & 3) && count; cbuf++, count--) *cbuf = transfer(*cbuf); uint16_t count4 = count & ~3; transferBytes(cbuf, cbuf, count4); From 456c8987dec601d9432bd90f5a8b6eabbf84daf9 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 14 Jul 2018 00:47:01 +0200 Subject: [PATCH 3/5] spi: transferBytes_: 32bits miso transfer --- libraries/SPI/SPI.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 093be1728f..c2d8012676 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -523,16 +523,23 @@ void SPIClass::transferBytes(const uint8_t * out, uint8_t * in, uint32_t size) { } } +/** + * Note: + * in and out need to be aligned to 32Bit + * or you get an Fatal exception (9) + * @param out uint8_t * + * @param in uint8_t * + * @param size uint8_t (max 64) + */ void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) { while(SPI1CMD & SPIBUSY) {} // Set in/out Bits to transfer setDataBits(size * 8); - - volatile uint32_t * fifoPtr = &SPI1W0; uint8_t dataSize = ((size + 3) / 4); if(out) { + volatile uint32_t * fifoPtr = &SPI1W0; uint32_t * dataPtr = (uint32_t*) out; while(dataSize--) { *fifoPtr = *dataPtr; @@ -551,12 +558,13 @@ void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) { while(SPI1CMD & SPIBUSY) {} if(in) { - volatile uint8_t * fifoPtr8 = (volatile uint8_t *) &SPI1W0; - dataSize = size; + volatile uint32_t * fifoPtr = &SPI1W0; + uint32_t * dataPtr = (uint32_t*) in; + dataSize = ((size + 3) / 4); while(dataSize--) { - *in = *fifoPtr8; - in++; - fifoPtr8++; + *dataPtr = *fifoPtr; + dataPtr++; + fifoPtr++; } } } From 67009fb08ed41c7352c79305a372f69b6bc6714b Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 14 Jul 2018 00:53:26 +0200 Subject: [PATCH 4/5] spi: transferBytes_: fix declaration --- libraries/SPI/SPI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index c2d8012676..8b5d3f2e35 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -537,9 +537,9 @@ void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) { setDataBits(size * 8); uint8_t dataSize = ((size + 3) / 4); + volatile uint32_t * fifoPtr = &SPI1W0; if(out) { - volatile uint32_t * fifoPtr = &SPI1W0; uint32_t * dataPtr = (uint32_t*) out; while(dataSize--) { *fifoPtr = *dataPtr; @@ -558,8 +558,8 @@ void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) { while(SPI1CMD & SPIBUSY) {} if(in) { - volatile uint32_t * fifoPtr = &SPI1W0; uint32_t * dataPtr = (uint32_t*) in; + fifoPtr = &SPI1W0; dataSize = ((size + 3) / 4); while(dataSize--) { *dataPtr = *fifoPtr; From e69217549725c756dd14d9ace460e2dd3e9326ed Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 14 Jul 2018 01:01:28 +0200 Subject: [PATCH 5/5] spi: transferBytes: add comments, reduce diff --- libraries/SPI/SPI.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 8b5d3f2e35..0f1786a4df 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -325,10 +325,17 @@ uint16_t SPIClass::transfer16(uint16_t data) { void SPIClass::transfer(void *buf, uint16_t count) { uint8_t *cbuf = reinterpret_cast(buf); + + // cbuf may not be 32bits-aligned for (; (((unsigned long)cbuf) & 3) && count; cbuf++, count--) *cbuf = transfer(*cbuf); + + // cbuf is now aligned + // count may not be a multiple of 4 uint16_t count4 = count & ~3; transferBytes(cbuf, cbuf, count4); + + // finish the last <4 bytes cbuf += count4; count -= count4; for (; count; cbuf++, count--) @@ -536,8 +543,9 @@ void SPIClass::transferBytes_(const uint8_t * out, uint8_t * in, uint8_t size) { // Set in/out Bits to transfer setDataBits(size * 8); - uint8_t dataSize = ((size + 3) / 4); + volatile uint32_t * fifoPtr = &SPI1W0; + uint8_t dataSize = ((size + 3) / 4); if(out) { uint32_t * dataPtr = (uint32_t*) out;