SPI Transactions not working with Atmega1280

I'm working on a custom board which uses the Atmega1280. The SPI library does not seem to work when using transactions. Example code without transactions:

  pinMode(FLASH_SS, OUTPUT);
  digitalWrite(FLASH_SS, HIGH);

  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  
  digitalWrite(FLASH_SS, LOW);
  
  SPI.transfer(0x9F);
  byte id1 = SPI.transfer(0);
  byte id2 = SPI.transfer(0);
  byte id3 = SPI.transfer(0);
  
  digitalWrite(FLASH_SS, HIGH);
  
  SPI.end();
  
  Serial.begin(115200);
  Serial.println(id1, DEC);
  Serial.println(id2, DEC);
  Serial.println(id3, DEC);

This works perfectly:

EDIT: link to full size image

But when I switch to transactions:

  pinMode(FLASH_SS, OUTPUT);
  digitalWrite(FLASH_SS, HIGH);
  
  settings = SPISettings(4000000, MSBFIRST, SPI_MODE0);
  SPI.beginTransaction(settings);
  
  digitalWrite(FLASH_SS, LOW);
  
  SPI.transfer(0x9F);
  byte id1 = SPI.transfer(0);
  byte id2 = SPI.transfer(0);
  byte id3 = SPI.transfer(0);
  
  digitalWrite(FLASH_SS, HIGH);
  
  SPI.endTransaction();
  
  Serial.begin(115200);
  Serial.println(id1, DEC);
  Serial.println(id2, DEC);
  Serial.println(id3, DEC);

No activity is seen on the SPI lines. In fact, it looks like the SPI library hangs up on the transfer() call and does not return. Am I doing something wrong?

Thanks!

Josh

jhaislip:
I'm working on a custom board which uses the Atmega1280. The SPI library does not seem to work when using transactions. Example code without transactions:

No activity is seen on the SPI lines. In fact, it looks like the SPI library hangs up on the transfer() call and does not return. Am I doing something wrong?

Thanks!

Josh

Josh,

You still need to call SPI.begin().

SPI.begin() initializes the SPI Hardware, Configures the pins (MOSI,MISO,SCK)

SPI.end() releases the SPI bus hardware, clears the interrupt controller.

A normal SPI transaction is like this;

void setup(){
  pinmode(SS,OUTPUT);  // makesure the SLAVE Mode CS pin is in OUTPUT mode else the SPI
 // hardware will switch to SLAVE mode (no SCK output) if SS is INPUT and goes LOW
 
  SPI.begin();
 settings = SPISettings(4000000, MSBFIRST, SPI_MODE0);
 }

void send_stuff(uint8_t * stuff, uint8_t stufflen, uint8_t CS){
uint8_t i=0;
// beginTransaction is options, only needed if you need to change the SPI setting for this device write cycle
 SPI.beginTransaction(settings);

digitalWrite(CS,LOW);
while(i<stufflen){
   SPI.transfer(stuff[i++]);
  }

digitalWrite(CS,HIGH);

SPI.endTransaction();  // only needed if beginTransaction is used.

}

void get_stuff(uint8_t * stuff, uint8_t stufflen, uint8_t CS){
uint8_t i=0;
// beginTransaction is options, only needed if you need to change the SPI setting for this device write cycle
 SPI.beginTransaction(settings);

digitalWrite(CS,LOW);
while(i<stufflen){
   stuff[i++] = SPI.transfer(0);
  }

digitalWrite(CS,HIGH);

SPI.endTransaction();  // only needed if beginTransaction is used.

}

void sendGet_stuff(uint8_t * stuff, uint8_t stufflen, uint8_t CS){
uint8_t i=0;
// beginTransaction is options, only needed if you need to change the SPI setting for this device write cycle
 SPI.beginTransaction(settings);

digitalWrite(CS,LOW);
while(i<stufflen){
   stuff[i]=SPI.transfer(stuff[i++]);
  }

digitalWrite(CS,HIGH);

SPI.endTransaction();  // only needed if beginTransaction is used.

}

#define stufflen 20
void loop(){
uint8_t x[stufflen];

send_stuff(x,stufflen,SS);
get_stuff(x,stufflen,SS);
sendGet_stuff(x,stufflen,SS);
}

I have never needed to call SPI.end(); My hardware is never reconfigured while the code is running?

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.