Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.

ATMega32u4 SPI help
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

ATMega32u4 SPI help

by robodude666 on Thu Mar 31, 2011 7:00 pm

Hey guys,

I'm trying to get SPI to work on my ATMega32u4 Breakout Board+. From what I understand the registers are identical to other ATMega AVRs, but for some reason it's not working.

Code: Select all | TOGGLE FULL SIZE

#define SPI_DDR DDRB

// Select on PORT E
// SPI on PORT B

#define SS    6
#define SCK   1
#define MOSI  2
#define MISO  3

// LOW = Select; HIGH = Deselect
#define TC_SS_LOW()   PORTE &= ~_BV(SS)
#define TC_SS_HIGH()  PORTE |= _BV(SS)

sbit(SPI_DDR, SCK);
sbit(SPI_DDR, MOSI);
sbit(SPI_SS_DDR, SS);
cbit(SPI_DDR, MISO);

cbit(SPI_PORT, SCK);


SPCR = (1 << SPE) | (1 << MSTR);

delay(100); // in ms

for(int i = 0; i < 10; i++)

   SPDR = 0xD0;
   while (!(SPSR & (1 << SPIF)));


Above is my testing code. I've got the SPI lines connected to a Logic Analyzer, which is sampling 500M samples @ 24MHz -- faster than the 16MHz clock of the ATMega32u4 or the 16MHz/4 SPI clock.

I should expect to see the SS line go high and stay high for 100ms, then go low. 0xD0 should appear on MOSI. SS should go high, then go back low after 10ms, and repeat (low, data, high, delay, etc. 10 times).

What I see instead is after the 10ms delay, the SS line goes low and stays low. The clock line always remains high since the first time SS went low.

Any ideas? I'm using my logic analyzer because my real program didn't work, so I started to debug. Ground on the logic analyzer is properly connected.

Posts: 118
Joined: Sun Mar 28, 2010 12:12 am

Re: ATMega32u4 SPI help

by adafruit on Fri Apr 01, 2011 4:18 pm

did you read the SPI section of the 32u4 datasheet?

Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: ATMega32u4 SPI help

by robodude666 on Fri Apr 01, 2011 4:50 pm

Yes. The SPI Interface on the ATMega32u4 appears identical to the one on other AVRs, like the ATMega168 that I've used. Unless, of course, there are subtle differences that I didn't notice.

Page 180 of the datasheet gives an example of using the interface in master mode:

Code: Select all | TOGGLE FULL SIZE
void SPI_MasterInit(void)

   /* Set MOSI and SCK output, all others input */
   DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
   /* Enable SPI, Master, set clock rate fck/16 */
   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
void SPI_MasterTransmit(char cData)
   /* Start transmission */
   SPDR = cData;
   /* Wait for transmission complete */
   while(!(SPSR & (1<<SPIF)))

The initialization is identical to what I'm doing, except I have the clock set to fosc/4. I'm also setting the DDR for MOSI and SCK separately, but it shouldn't make a difference.

The datasheet does mention that if /SS is configured to an input and put low while in Master operation then it switches to Slave mode, but I don't think that's happening.. unless, the SPI interface expects PB0 to be the SS line. In which case, it's DDR is never actually set and defaults to an input... I'll go test that right now.


Well, what do you know? That was the problem! I setup PB0 (the 'built-in' SS) as an output and defaulted it to HIGH. Then, all of a sudden... even worked just fine.

Probably would have been easier to use PB0 at the very beginning as my select line, but it's good to know I can do multiple SPI devices on a single interface =].
Posts: 118
Joined: Sun Mar 28, 2010 12:12 am

Re: ATMega32u4 SPI help

by Richwest on Tue Oct 04, 2011 5:10 am

SPI is meant to be easy right? All my SPI reads from the MRF24J were returning 0xff.
Turns out that, even with the /SS pin disconnected, if you don’t explicitly set it as an output pin in the DDR register, the AVR falls out of SPI mode if it ever goes low.
So, even though the pin is not connected, (I’m using a general IO pin to do chip select on the radio module) nothing worked until I explicitly made it an output.
And now, presto, I can read data from the MRF24J properly now! Now we can finally move on to the rest of this bring up.
(The MRF24J40 is an 802.15.4 module, with a SPI interface. It’s about 6€, vs about 20€ for xbees, and is on a standard 2.54mm pin spacing, instead of xbee’s 2mm spacing)
Posts: 10
Joined: Mon Sep 19, 2011 4:39 am

Please be positive and constructive with your questions and comments.