Hi freaks,
I'd like to hear some suggestions how you have implemented a SPI slave with a microcontroller.
I need to replace a current slave chip with a MCU and be mostly compatible with it so the master does not really see any difference to the original slave.
Basically the SPI hardware in microcontrollers can use blazing-fast SPI clocks to transfer a byte, but most microcontrollers don't have any DMA capability so each byte must be received in the SPI data interrupt.
Sometimes, the slave MCU must serve other interrupts and so it has a varying response time to SPI data interrupt. So the host cannot send bytes back to back or the slave will miss them if there is not enough time between each byte transferred.
Fortunately I can use one extra GPIO pin for syncronization, in the interrupt I first set a pin to indicate "slave busy do not send any more" and when the byte is fetched from SPI hardware and stored into buffer, I set the pin to indicate "slave ready for more stuff" at the end of the interrupt. I know some DSPs have this kind of extra wire for busy indication as well.
Then there is also the problem of SS or CS. The SPI hardware will handle the SS so that I get bytes when it is low and everything is ignored when SS is high. But how should I detect where SPI frames/packets start/end? Mostly the slave must execute commands sent to it after the SS goes high so it knows the transmission was complete and it can be executed and the next received byte will be the first byte of the next packet. So have you also connected the SS pin to external interrupt pin to generate interrupts when SS pin goes high (or low, whatever), or does some microcontroller have SPI hardware to handle the SS in some kind of interrupt too?
Then there is the problem of the slave sending responses back to master. If the first byte of packet signals whether the command is a read or write command, then the response byte must be loaded before it is transferred back. Now, the host could read any amount of bytes as a response so how will SPI hardware usually handle such a case if a byte is loaded to SPDR in SPI interrupt, but never transferred, and then as there is SS going high interrupt to signal end of transmission, I have to reload SPDR again so that the first byte in the next packet going back to host is not garbage from previous read. Will the SPDR write update the shift register if it is loaded two times or does it ignore the second write, setting some overrun status bit?