I've got a strange problem with SPI transmits on the K64F that's on the Freedom board that's got me stumped.
I've written my own bare-metal, interrupt driven driver for SPI master mode. I've initialized the SPI peripheral to generate TC interrupts when SR[TC] gets set. I'm using the FIFOs (MCR[DIS_TXF] and MCR[DIS_RXF] are both set to 0).
My strategy for writes is as follows:
1) Check if the SR[TFFF] is set indicating the TX FIFO is not full.
2) Write the data to PUSHR.
3) Wait for the interrupt, and if SR[RFDF] is 1, then read the data in the RX FIFO from POPR. Clear SR[TC] by writing a 1 to SR[TC] at the end of the interrupt handler.
When I do multiple transfers, I only see N+1 interrupts, where N is the depth of the TX FIFO, despite the fact that I'm doing more than N+1 writes to PUSHR. So, for SPI0, which has a 4 deep FIFO, I see five transfers on the SPI bus and five interrupts. For SPI1, which has a 1 deep FIFO, I see two transfers on the SPI bus and two interrupts.
If I try to do 7 writes on SPI0, for example, I see only five transfers on the SPI bus and only five interrupts. The last two writes don't generate any SPI bus activity nor any interrupts. The TCR register stays set to 5. When I do writes #6 and #7, the SR[TFFF] bit is set to 1 indicating the TX FIFO is not full, so it should accept the writes to PUSHR and transfer the data on the SPI bus, but it doesn't.
This seems to be related to something subtle in the timing of the requests. When I write new data to PUSHR, I check first that SR[TFFF] = 1 indicating the FIFO is not full. If I put a small delay after writing the first 5 (N+1 on SPI0 with its 4-deep FIFO) times to PUSHR before writing additional times, I do see the expected number of interrupts. I suspect that the delay is giving the FIFO time to drain. It seems that the SR[TFFF] flag is not being cleared when the FIFO is full and my writes to PUSHR beyond the first 5 are being ignored. The reference manual says that SR[TFFF] can be cleared by writing a 1 to it, but why would one have to do this? Wouldn't the SPI peripheral clear it automatically when the FIFO is full? Am I missing something here?
Can anyone give me a clue? What should I look for? Is there something I'm not configuring right?