unusual spi problem on mega324p

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was porting some code to the atmega324p and ran into an odd issue with the SPI. Narrowing it down to the smallest test case, I have a piece of code that just outputs a byte to the SPI, toggles a status LED, and then repeats the process (shown below). When first programmed, this code runs fine and toggles the status LED properly. When power is reset, I get the initial reset blink but then nothing after. If I then plug in the ISP connector, the SPI starts to transmit again without any problems (even if the ISP connector is later removed).

I'm running this AVR with a 16 MHz crystal, set to the following fuse settings:
BODLEVEL at 4.3V
JTAGEN disabled
CKDIV8 disabled
SUT_CKSEL set to external crystal 8.0- MHz; start-up time: 16K CK + 0 ms
There is a 10k ohm pullup resistor and a 10 nF cap to ground on the reset pin. All voltage/ground pin pairs are decoupled with 100 nF caps. I'm using WinAVR 20081205. To test this error, I modified the board so that nothing other than the isp header is attached to the SPI bus. Any idea what could be going on?

#include 
#include 
#include 

#include 

#define SPI_PORT	PORTB
#define SPI_PIN		PINB
#define SPI_DDR 	DDRB
#define SPI_SCK		PB7
#define SPI_MISO	PB6
#define SPI_MOSI	PB5

int main(void) {
	
	//setup the led
	set_bit(DDRC, PC4);
	clear_bit(PORTC, PC4);
	
	//setup the spi
	set_2_bits(SPI_DDR, SPI_MOSI, SPI_SCK);
	set_3_bits(SPCR, SPE, MSTR, SPR0);
	
	//a quick led blink to show reset
	clear_bit(PORTB, PB4);
	_delay_loop_2(0xffff);
	set_bit(PORTB, PB4);
	_delay_loop_2(0xffff);
	
	while(1) {
		//try sending some value over the SPI
		SPDR = 0b01010101;
		while (!check_bit(SPSR, SPIF));
		uint8_t value = SPDR;
		
		//toggle the led
		PORTC ^= _BV(PC4);
	}
	return 0;
}

(macros.h has definitions to simplify checking, setting, and clearing bits:
#define check_bit(port,bit) ( (port & _BV(bit)) )
#define set_2_bits(a,y,z) (a |= _BV(y) | _BV(z))
etc
)

edit: I tried this same test with another identical avr circuit, and got the same odd results.

Last Edited: Wed. Mar 4, 2009 - 05:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) Most of the LED code refers to PC4, but the initial "quick LED blink" refers to PB4.

2) PB4 was not made an output.

3) PB4 is /SS. If not an output or otherwise kept high then the SPI will revert to slave mode.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Damn, I didn't even notice that I had the ports flipped. Thanks for noticing that. It seems to be fixed now... hopefully I don't do anything else quite as retarded from here on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

3) PB4 is /SS. If not an output or otherwise kept high then the SPI will revert to slave mode.

See the datasheet. There should be a whole paragraph on it. If you don't make it an output you are gambling.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

See the datasheet. There should be a whole paragraph on it. If you don't make it an output you are gambling.

Unless something like a pull-up resistor guarantees SS is high.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do set the SPI slave select as an output, but it happened later in the initialization of my main body of code. I use that pin as a chip select line for an external ADC, but the SPI setup code was called first (which neglected to set the data direction of the slave select pin). Seems that somehow I was getting it into a weird state by allowing the SS to stay as an input which defaulted (?) to a low value, at least until it was later configured as an output to use the ADC. Setting the SS pin as an output immediately when configuring the SPI seems to have fixed it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Unless something like a pull-up resistor guarantees SS is high.

Ummm--didn't I say
Quote:

or otherwise kept high

;)

Quote:

I do set the SPI slave select as an output, but it happened later in the initialization of my main body of code.

Gees, I hate it when a [nearly--no macro definitions] complete program is posted that supposedly demonstrates a problem situation. Then we find out it isn't the real program. Is the one posted broken or not?

The posted program does not make PB4 an output, it may or may not stay high with the pullup enabled depending on what is connected, and there are SPI operations that supposedly do not work posted before the "main body of the code".

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.