Go Down

Topic: Suggested fix to SPI.begin() (Read 659 times) previous topic - next topic

Nick Gammon

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: [Select]
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: [Select]
  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: [Select]
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);
}
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Graynomad

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

_____
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Coding Badly

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


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

P18F4550

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

Nick Gammon


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).
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up