aboutsummaryrefslogtreecommitdiff
path: root/libraries/SPI
diff options
context:
space:
mode:
authorCristian Maglie <c.maglie@bug.st>2014-10-20 19:46:08 +0200
committerCristian Maglie <c.maglie@bug.st>2014-11-25 15:49:17 +0100
commitd4edece7e6698e7687dd8dec1831f9756c8b0017 (patch)
treeb4866effbeb5895f00ab6e620c58d9c5d27263c0 /libraries/SPI
parent7ee84bdb1eb39dde646ed1859d9fe7d37d4584bf (diff)
[avr] Improved SPI speed on 16bit transfer.
From https://github.com/arduino/Arduino/pull/2376#issuecomment-59671152 Quoting Andrew Kroll: [..this commit..] introduces a small delay that can prevent the wait loop form iterating when running at the maximum speed. This gives you a little more speed, even if it seems counter-intuitive. At lower speeds, it is unnoticed. Watch the output on an oscilloscope when running full SPI speed, and you should see closer back-to-back writes. Quoting Paul Stoffregen: I did quite a bit of experimenting with the NOP addition. The one that's in my copy gives about a 10% speedup on AVR.
Diffstat (limited to 'libraries/SPI')
-rw-r--r--libraries/SPI/SPI.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h
index b54e2df..24ebc12 100644
--- a/libraries/SPI/SPI.h
+++ b/libraries/SPI/SPI.h
@@ -184,6 +184,12 @@ public:
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
inline static uint8_t transfer(uint8_t data) {
SPDR = data;
+ /*
+ * The following NOP introduces a small delay that can prevent the wait
+ * loop form iterating when running at the maximum speed. This gives
+ * about 10% more speed, even if it seems counter-intuitive. At lower
+ * speeds it is unnoticed.
+ */
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ; // wait
return SPDR;
@@ -193,16 +199,20 @@ public:
in.val = data;
if (!(SPCR & _BV(DORD))) {
SPDR = in.msb;
+ asm volatile("nop"); // See transfer(uint8_t) function
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
SPDR = in.lsb;
+ asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
} else {
SPDR = in.lsb;
+ asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.lsb = SPDR;
SPDR = in.msb;
+ asm volatile("nop");
while (!(SPSR & _BV(SPIF))) ;
out.msb = SPDR;
}