ATMEGA128 SPI Interface

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

Hi!

I just thought i'd post my problem here and hopefully one of you would be albe to help me out. PLEASE.

I have a mega128 and am using a 5001, 501 combo for the evaluation.
Currently i am also using TI 7844 A/D chip for which i intend to use the SPI bus to gather data.

This is what i've done so far
I initialized the SPI bus as follows

//initialize the clock
//XDIV = XDIV | (1<<XDIVEN) | (1<<XDIV0)|(1<<XDIV4);
//PORTE = PORTE | (1<<PORTE7);
PORTB |= (1 << PORTB1);
/*----------------------------------
Set MISO Input, all other pins as output for Master Mode
PORTB Pin 0, 1, 2
------------------------------------*/
DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2);
DDRE = 0x00;
//Clear SPCR
SPCR = 0x00;

//Clear SPI Status Register
SPSR = 0x00;
/*----------------------------------
Enable SPI in the Slave Mode
SPE:- Enable SPI
SPIE:- Enable SPI Interrupts
MSTR:- Master/Slave Mode
DORD:- Xmit MSB first
CPOL:- Falling Edge Clock
CPHA:- Leading Edge Clock
SPR:- F(osc)/4 SPR1 and SPR2 0
------------------------------------*/
SPCR = ((1<<SPIE) | (1 << SPE) | (1 << MSTR)) /*| (1 << CPOL) */| (1<<SPR0);

//Enable external interrupt 7
// this interrupt is controlled by the busy signal from the A/D

EIMSK = 0x00; /* Disable external interrupts */
EICRB = (1 << ISC71) | (0 << ISC70);
EIMSK = (1 << INT7);;
EIFR |= (1<<INTF7);//0xFF; /* Clear all flags */
__enable_interrupt();

I am trying to use the SPI interrupt to send the data
and external interrupt7 to receive data.
I am not able to interrupt the internal interrupt.

and also can never see any changes to the SPDR when i put the value in the register.

am i missing something. PLEASE help

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

I'm not a Mega64/128 person, so I cannot address your particular situation.

Forst, I have never seen the need for the SPI interrupt in any of my applications. When I calculate the time needed to service the interrupt, perform the action (load next byte, etc.), and do the foreground-background housekeeping, it is less cycles to just stay in a loop and wait for completion of each byte.

I'm not saying there is NEVER a case for it, just that with a few bytes out/in it never made sense in my apps--DS1305/1306 RTCs, 25xxx EEPROM/FRAM, etc.

Secondly, what do you mean by "and external interrupt7 to receive data"? Are you trying to get the MISO stream on interrupt7? or is this an unrelated part of your application?

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

Hi ruchirabajaj,

You can interrupt an interrupt, but normal execution prevents it. When an interrupt is triggered on an AVR, the global interrupts flag is disabled, which in turn prevents any other interrupts from "interrupting" the currently executing interrupt handler. The global interrupt flag is automatically re-enabled after the interrupt returns (RETI execs).

To allow an interrupt to be interrupted, just enable the global interrupt flag in the beginning of your handler, in whichever way suits your code (__enable_interrupt() or SEI instruction). You may want to save the SREG register first, then restore it after your handler is done. That's one thing the AVR doesn't preserve during interrupts.

All this is expensive, though, as theusch mentioned. An interrupt handler saves then restores lots of data, and another interruption will double that amount.

Cheers

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

Hi

Thanks for posting a reply, and yes it makes sense when u guys say that interrupting an interrupt is quite expensive.

So here keeping that in mind i've removed the external interrupt and will.

So now as soon as i put the data in SPDR, and wait for transmistion. The SPI interrupt occurs. Now i am just reading the SPDR register and storing the data in my buffer.
However I am expecting 12bits of data...so now how do i get that since SPDR stores only 8. Do I too have to send dummy value to be able to get the second byte to the A/D converter?
Does the SPI interrupt stop once the data is transmitted or it gets done once the data is received?

Thanks guys for all ur help.

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

Hi

Thanks for posting a reply, and yes it makes sense when u guys say that interrupting an interrupt is quite expensive.

So here keeping that in mind i've removed the external interrupt and will.

So now as soon as i put the data in SPDR, and wait for transmistion. The SPI interrupt occurs. Now i am just reading the SPDR register and storing the data in my buffer.
However I am expecting 12bits of data...so now how do i get that since SPDR stores only 8. Do I too have to send dummy value to be able to get the second byte to the A/D converter?
Does the SPI interrupt stop once the data is transmitted or it gets done once the data is received?

Thanks guys for all ur help.

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

Hi

Thanks for posting a reply, and yes it makes sense when u guys say that interrupting an interrupt is quite expensive.

So here keeping that in mind i've removed the external interrupt and will.

So now as soon as i put the data in SPDR, and wait for transmistion. The SPI interrupt occurs. Now i am just reading the SPDR register and storing the data in my buffer.
However I am expecting 12bits of data...so now how do i get that since SPDR stores only 8. Do I too have to send dummy value to be able to get the second byte to the A/D converter?
Does the SPI interrupt stop once the data is transmitted or it gets done once the data is received?

Thanks guys for all ur help.

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

SPDR = 0; // Initiate first byte of transfer
while(!(SPSR & 0x80)); //wait for transfer complete, poll SPIF-flag
low_byte = SPDR; // retrieve low order byte
SPDR = 0; // Initiate second byte of transfer
while(!(SPSR & 0x80)); //wait for transfer complete, poll SPIF-flag
high_byte = SPDR; // retrieve high order byte

as previousl;y indicated, its a wast of time using interurutps.

Lachlan