Interrupt driven slave SPI

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

Hey, i'm bit uncertain about this as i have never done interrupt driven SPI with AVR's.

 

Is this interrupt handler about right?

ISR(SPI_vect){
	
	//Check if buffer got free space
	if(!RingBuffer_IsFull(&SPI_ReceiveBuff)){
		 RingBuffer_Insert(&SPI_ReceiveBuff, SPDR);
	}
	else
		uint8_t damn = SPDR; // No space in buffer, well bad luck.
			
	SPDR = dataToSend;	//Do i load data i want to send into SPDR here or?

}

 

what makes me wonder is the atmel's application note, which suggest disabling SPI interrupt, but why would i want to do that when master can send data again in any point.

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

The usual problem with SPI slave is that as soon as the master has sent the "send me something" command byte he almost immediately then sends the "clock out the requested data" byte with so little gap that your slave doesn't have time to get the response byte ready for it. So slowing this down further by using interrupts and then calls to functions to access ring buffers may only exacerbate the problem.
.
Perhaps the master can hold off for a few ticks after sending the command but before clocking the data. Or maybe it could give an interrupt warning that it's going to ask for data in the near future?

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

clawson wrote:
Or maybe it could give an interrupt warning that it's going to ask for data in the near future?

 

i think this could work, if i got the consept right in my mind.

 

Slave -> 

  1. interrupt enabled
  2. gets random byte, which tells data is coming soon, disable interrupt
  3. enters state where it waits for Master to initiate communication again.
  4. get data ready
  5. sends the data
  6. start from 1 again.

 

So basically for this to work i needed to know the longest loop in the code which the slave device might be executing and add little extra.

 

E: but same could basically be archieved, by coding a loop into the ISR directly, without leaving from there before all data is gathered? (Ye, i know loops in ISR is not what you usually want)

 

clawson wrote:
The usual problem with SPI slave is that as soon as the master has sent the "send me something" command byte he almost immediately then sends the "clock out the requested data" byte with so little gap that your slave doesn't have time to get the response byte ready for it.

 

i suppose this means i also want to disable all the other interrupts i have while sending the data out to master? 

Last Edited: Tue. Aug 29, 2017 - 06:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JoniS wrote:

what makes me wonder is the atmel's application note, which suggest disabling SPI interrupt, but why would i want to do that when master can send data again in any point.

That ISR looks like it is supposed to receive only one zero-terminated string ever, so after that the interrupt can be disabled.

 

IMHO that is typically not the case - you usually leave the associated interrupt enabled in the ISR. It's more common to disable or enable specific interrupts in the main loop should it ever be required. But even more common is to manipulate the global interrupt enabled/disabled state (e.g. using the ATOMIC_BLOCK macros)

/Jakob Selbing