8000 [AVR] SPI atomicity fix avr (part 1/2 of #2376), second try by cmaglie · Pull Request #2449 · arduino/Arduino · GitHub
[go: up one dir, main page]

Skip to content

[AVR] SPI atomicity fix avr (part 1/2 of #2376), second try #2449

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[avr] Improved SPI speed on 16bit transfer.
From #2376 (comment)

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.
  • Loading branch information
cmaglie committed Nov 25, 2014
commit 53e25d8b5534c842a89eb62da1ab2558463c077b
10 changes: 10 additions & 0 deletions hardware/arduino/avr/libraries/SPI/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ class SPIClass {
// 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;
Expand All @@ -193,16 +199,20 @@ class SPIClass {
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;
}
Expand Down
0