After I have 'sent some stuff' and await the answer (that shifts in at the same time) I simply wait for the receive FIFO to get 'in' as many transactions as I 'sent', and at that point I know the 'whole operation' is complete. Works, of course, only for 'transaction sets' that fit all in the receive FIFO! So I have this macro:
| #define WAIT_SPI0_TRANSMISSON_END(count) {while ((SPI0_SR & SPI_SR_RXCTR_MASK) < (count<<SPI_SR_RXCTR_SHIFT)) {}; |
I am working in a 'high performance' analog-processing system, and have SPI-connected AtoDs, much like your setup. But I can't 'waste much time' at 4K samples per second, so I have to 'intelligently' interleave SPI operations with 'other work. I do this with some other macros that make it 'look simple' to send each transaction (Bytes in my case). Each macro contains the SPI module #, the CS #, and the CTAR reg to use:
| #define WRITE_2SPI0_CMD0(byte) SPI0_PUSHR = (byte | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(4) | SPI_PUSHR_CTAS(0)) | |
| #define WRITE_2SPI0_CMD0_LAST(byte) SPI0_PUSHR = (byte /*| SPI_PUSHR_EOQ_MASK */| SPI_PUSHR_PCS(4) | SPI_PUSHR_CTAS(0)) |
| #define WRITE_2SPI0_CMD1(byte) SPI0_PUSHR = (byte | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(4) | SPI_PUSHR_CTAS(1)) //Same for 2nd CTAR | |
| #define WRITE_2SPI0_CMD1_LAST(byte) SPI0_PUSHR = (byte /*| SPI_PUSHR_EOQ_MASK */| SPI_PUSHR_PCS(4) | SPI_PUSHR_CTAS(1)) |
So to use these, my AtoD 'dummy input' bytes during a 'result read' are just 'zero', so I will get those 'going out' in one 24bit transfer like this:
| ///While we start working with the first AtoD sample, start the second channel coming in |
| WRITE_2SPI0_CMD1(0); |
| WRITE_2SPI0_CMD1(0); |
| WRITE_2SPI0_CMD1_LAST(0); | //Prompt the three data bytes to come along! |
Then I will 'do a bunch of work' for about the number of microseconds these take to shift-out, then:
//Now to finish-off the second channel!!
WAIT_SPI0_TRANSMISSON_END(2); //Spin for the first couple of the second channel to be in, should more time be needed
AtoD[1].sample.s8.hm = READ_SPI0_DATA(); // Read MSByte
if( (AtoD[1].sample.s8.hm & 0x80) == 0 )
AtoD[1].sample.s8.hh = 0;
else
AtoD[1].sample.s8.hh = -1; //Sign-extend to Q8.23
AtoD[1].sample.s8.lm = READ_SPI0_DATA(); // Read middle
WAIT_SPI0_TRANSMISSON_END(1);
AtoD[1].sample.s8.ll = READ_SPI0_DATA(); // Read LSByte