Hi bigmac, hi all,
You helped a lot. With your help and some own investigations I think I found my solution:
Because my slave device and the master have to send an arbitrary number of bytes and SPI can't send without receiving (and also vice versa), I must define a byte value that represents an 'invalid byte'.
Whenever one node has nothing to say, it sends the 'invalid byte'. To ensure that the invalid byte is not in the raw data, I use a widely known technique called 'byte stuffing'. For those who don't now what that means:
http://www.cs.umd.edu/~shankar/417-F01/Slides/chapter5c-aus/sld016.htmI also use the byte stuffing to implement flow control. My slave device tells the master if its receive FIFO gets filled up and sends a special message to the master. If the slave has enough space again, it sends another message telling the master to go on. It works like XON/XOFF. The master itself does not need flow control because it simply stops clocking when it temporarily can't receive.
My slave runs on an S12XA256, SPI is completely interrupt-driven and uses FIFOs for TX and RX. When I'm initializing the SPI module, I first put the 'invalid byte' into SPI0DR, then setting SPTIE to ensure that the first byte transmitted is not a zero but my 'invalid byte'.
....
SPI0CR1_SPIE = 1; // Enable RX interrupts
SPI0CR1_MSTR = 0; // Slave
SPI0CR1_CPOL = (spi_params & 1); // Clock polarity, 0 == active high
SPI0CR1_CPHA = !(spi_params & 2); // Sampling at even edges
SPI0CR1_LSBFE = !(spi_params & 4); // LSB first
SPI0CR2_SPC0 = 0; // Normal mode
SPI0CR1_SPE = 1; // Start SPI module
// Put dummy byte into send register on startup
while (SPI0SR_SPTEF == 0)
{
}
SPI0DR = DUMMY_BYTE;
SPI0CR1_SPTIE = 1; // Enable 'TX register free' interrupts
....
I monitor the /SS to reset the 'byte stuffer' when /SS goes high. I do this by reading the PORTS input register (PTIS_PTIS7). I don't know if it makes a difference to use PTS_PTS7 instead.
The only situation I can't detect until now is when someone switched the slave off and on again while the master is continously clocking. Although, that doesn't confuse the slave but it would be nice if the master can recognize it.
Any suggestions?