Content originally posted in LPCWare by jdurand on Mon Aug 06 08:56:17 MST 2012
There are a few things with UARTs that catch people:
1) What do you do in the TX interrupt when the last bite has already been sent?
2) How do you get the TX interrupted started again when there's more data to send?
3) If you have a half-duplex system or have to send a BREAK between frames, how do you know when the last byte has left the UART so you don't clip it off with the BREAK or direction change?
One way I've solved #1 & #2 above using the OS timer tick (typically 10mS) (solution depends on the system). In case #1 when there's no more data to send the interrupt sets a UART_IDLE flag and returns from the interrupt. In the OS timer tick hook I check the idle flag and if set and there's data available, I generate a UART TX interrupt to restart the transmission.
For systems with BREAK I usually have a timer running since the frames often have to go out at a set rate.
A sometimes harder thing to deal with is having a receive buffer while allowing the user to backspace. I've used a single linear buffer and sometimes add a ring buffer between the UART and the linear one to allow faster transfers. This is easy to handle filling/backspacing and when a RETURN buffer parsing starts. Not the most efficient but if dealing with a human typing it works quite well. Handshaking to the host is controlled by either the start/end of parsing, the UART itself, or the ring buffer handler.