I'm using UART0 on a K22F at 1 Mbps, and will need to go faster later. Getting an interrupt for every incoming byte is inefficient, so I've got the FIFO RX watermark set to 6 bytes with hardware flow control enabled, to account for the sending device potentially taking a byte or two before honoring RTS.
The trouble is that the FIFO will never generate an interrupt if it only fills up partway. I could poll it periodically but doing so with high frequency defeats the purpose of using the FIFO and doing it slower produces unacceptable latency, so I'm using the IDLE interrupt to notify my driver that the sender is done and that the FIFO should be read.
Clearing the IDLE flag requires reading S1 with IDLE set and then reading D. If a byte comes in after the FIFO count is read, what ought to be a dummy read to clear IDLE gets actual data and the byte is lost. To avoid that, I'm checking the FIFO RX underflow flag after reading D to find out if it was real data or not. That works, but it introduces a new problem because reading D with the FIFO empty causes the FIFO pointer to become misaligned and it needs to be flushed - again potentially losing data that might have just come in.
What is the best way to make use of the FIFO to generate the fewest possible interrupts with the lowest latency without creating the possibility of losing data due to a race condition?