I think there's a logical bug in fsl_uart.c
/* If RX overrun. */
if (UART_S1_OR_MASK & base->S1) {
/* Read base->D to clear overrun flag, otherwise the RX does not work. */
while (base->S1 & UART_S1_RDRF_MASK) {
(void) base->D;
}
The "while (base->S1 & UART_S1_RDRF_MASK)" creates a problem when the routine gets preempted by another interrupt. The RDRF can be set again, causing the routine to eat up extra bytes and/or generate additional Rx OR interrupts. After removing the while loop and reading "(void) base->D;" exactly once, the problems go away.