Pages: [1]   Go Down
Author Topic: Suggested fix to SPI.begin()  (Read 569 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

There is a problem in SPI initialization as discovered in this thread:

http://arduino.cc/forum/index.php/topic,100671.0.html

The problem code is here from SPI.cpp:

Code:
void SPIClass::begin() {
  // Set direction register for SCK and MOSI pin.
  // MISO pin automatically overrides to INPUT.
  // When the SS pin is set as OUTPUT, it can be used as
  // a general purpose output port (it doesn't influence
  // SPI operations).

  pinMode(SCK, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(SS, OUTPUT);
 
  digitalWrite(SCK, LOW);
  digitalWrite(MOSI, LOW);
  digitalWrite(SS, HIGH);

  // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  // automatically switches to Slave, so the data direction of
  // the SS pin MUST be kept as OUTPUT.
  SPCR |= _BV(MSTR);
  SPCR |= _BV(SPE);
}

Bearing in mind that SS (slave select) is normally active low, what the above code does is briefly bring SS low, between these lines:

Code:
  pinMode(SS, OUTPUT);
...
  digitalWrite(SS, HIGH);

Depending on the clock polarity, it may appear to the device that it has been selected, and then a bit clocked. To fix this we simply need to bring SS high before making it an output, then the pin is not driven low and immediately high again, like this:

Code:
void SPIClass::begin() {
  // Set direction register for SCK and MOSI pin.
  // MISO pin automatically overrides to INPUT.
  // When the SS pin is set as OUTPUT, it can be used as
  // a general purpose output port (it doesn't influence
  // SPI operations).

  digitalWrite(SCK, LOW);
  digitalWrite(MOSI, LOW);
  digitalWrite(SS, HIGH);

  pinMode(SCK, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(SS, OUTPUT);

  // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  // automatically switches to Slave, so the data direction of
  // the SS pin MUST be kept as OUTPUT.
  SPCR |= _BV(MSTR);
  SPCR |= _BV(SPE);
}
Logged


nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8501
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That makes sense, maybe suggest in on the developer's mailing list or the bug reporting page (wherever that is).

_____
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12853
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
maybe suggest on the bug reporting page (wherever that is).

http://code.google.com/p/arduino/issues/list
Logged

0
Offline Offline
Sr. Member
****
Karma: 7
Posts: 476
what?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I know im stil sat in the stone age but this is just one more reason im still using IDE_18 & spi.h because it works, why SPI.h was included in later versions of IDE i dont know, when got new version nothing worked
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
maybe suggest on the bug reporting page (wherever that is).

http://code.google.com/p/arduino/issues/list


Submitted as issue 888 (sort of like 666 but worse).
Logged


Pages: [1]   Go Up
Jump to: