ATmega128 SPI - Interrupt based problem

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

Hi,
Hardware details :Atmega128, 8MHz, 3.3v operation)
I am using spi to interface memory.

I am using spi interrupt with following settings.

SPCR=0xD0;
SPSR=0x00;

I am using portb.4 as chip select for my memory.
My problem is

1) When I am loading the data in SPDR resistor the interrupt is invoked only if there is delay of 4 microsecond or more.
2) If delay is removed then program doesn't invoke the interrupt for next SPDR loading.
3) I have checked SPSR, if delay is not provided, wcol bit( SPSR.6) is set. Why?
4) I tried to clear it by setting it and reading spsr & spdr.How to clear it?
4)I don't want to include this delay. How to solve it ?
5) After sending a command(0x9f is command) to memory, I need to receive bytes from memory. But I am always getting 1st byte as 0 & actual byte is received in next cycle. Why?

pls see the following code.

PORTB=0xef; // portb.4=0 asserting chip select

SPDR = 0x9f; //send read id command to memory
delay_us(4); // want to remove it

SPDR=0; // to receive 1st data byte
byt=spi_data; // 1st byte received
delay_us(4);

PORTB.4=1; // de-assert chip select

// following is interrupt routine

interrupt [SPI_STC] void spi_isr(void)
{
spi_data=SPDR; // store received byte from memory
cnt++; // to check intr invoked or not

}

please help me

:(

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

The reason it fails is because you are writing SPDR again immediately after, thus overwriting the first one. You have to wait for the operation to complete first. With the way your code is written/organized, you're better off using polled mode, and forget the interrupt altogether. (also, unless you're using some of the slower SPI speeds, there is no good reason not to poll the SPI, as the interrupt rate on the faster modes will consume nearly all the CPU, as well as the overhead will actually make the transfers slower)

If you want to use the ISR, do both the read & write in the ISR. Set up a transfer buffer with your data, and then write the first character to SPDR, and let the interrupt do the rest of the work. In addition to the buffer, you will need a flag to indicate completion. Wait for the completion flag to be set, and then you can read your result back from the buffer.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.