Dein Problem ist, dass du uart_puts im Receive-Interrupt aufrufst.
Wenn der Puffer nämlich voll ist, wartet die Funktion, bis wieder Platz im Puffer ist. Es wird aber kein Platz frei, wenn nichts gesendet wird, und das wird es nicht, so lange der Receive-Interrupt noch bearbeitet wird. Wenn du also mehr Zeichen versuchst zu senden, als der Sendepuffer groß ist, hast du einen schönen Dead-Lock.

Es ist überhaupt eine reichlich schlechte Idee, das ganze Geraffel in den Receive-Interrupt zu stopfen.