[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.
This commit is contained in:
parent
8c4780df8c
commit
cd9ea1a371
|
@ -184,6 +184,12 @@ public:
|
||||||
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
|
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
|
||||||
inline static uint8_t transfer(uint8_t data) {
|
inline static uint8_t transfer(uint8_t data) {
|
||||||
SPDR = 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");
|
asm volatile("nop");
|
||||||
while (!(SPSR & _BV(SPIF))) ; // wait
|
while (!(SPSR & _BV(SPIF))) ; // wait
|
||||||
return SPDR;
|
return SPDR;
|
||||||
|
@ -193,16 +199,20 @@ public:
|
||||||
in.val = data;
|
in.val = data;
|
||||||
if (!(SPCR & _BV(DORD))) {
|
if (!(SPCR & _BV(DORD))) {
|
||||||
SPDR = in.msb;
|
SPDR = in.msb;
|
||||||
|
asm volatile("nop"); // See transfer(uint8_t) function
|
||||||
while (!(SPSR & _BV(SPIF))) ;
|
while (!(SPSR & _BV(SPIF))) ;
|
||||||
out.msb = SPDR;
|
out.msb = SPDR;
|
||||||
SPDR = in.lsb;
|
SPDR = in.lsb;
|
||||||
|
asm volatile("nop");
|
||||||
while (!(SPSR & _BV(SPIF))) ;
|
while (!(SPSR & _BV(SPIF))) ;
|
||||||
out.lsb = SPDR;
|
out.lsb = SPDR;
|
||||||
} else {
|
} else {
|
||||||
SPDR = in.lsb;
|
SPDR = in.lsb;
|
||||||
|
asm volatile("nop");
|
||||||
while (!(SPSR & _BV(SPIF))) ;
|
while (!(SPSR & _BV(SPIF))) ;
|
||||||
out.lsb = SPDR;
|
out.lsb = SPDR;
|
||||||
SPDR = in.msb;
|
SPDR = in.msb;
|
||||||
|
asm volatile("nop");
|
||||||
while (!(SPSR & _BV(SPIF))) ;
|
while (!(SPSR & _BV(SPIF))) ;
|
||||||
out.msb = SPDR;
|
out.msb = SPDR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue