This implements an stdio-compatible RS-232 driver using an AVR's standard UART (or USART in asynchronous operation mode). Both, character output as well as character input operations are implemented. Character output takes care of converting the internal newline \n into its external representation carriage return/line feed (\r\n).

Character input is organized as a line-buffered operation that allows to minimally edit the current line until it is "sent" to the application when either a carriage return (\r) or newline (\n) character is received from the terminal. The line editing functions implemented are:

The function uart_init() takes care of all hardware initialization that is required to put the UART into a mode with 8 data bits, no parity, one stop bit (commonly referred to as 8N1) at the baud rate configured in defines.h. At low CPU clock frequencies, the U2X bit in the UART is set, reducing the oversampling from 16x to 8x, which allows for a 9600 Bd rate to be achieved with tolerable error using the default 1 MHz RC oscillator.

The public function uart_putchar() again has suitable arguments for direct use by the stdio stream interface. It performs the \n into \r\n translation by recursively calling itself when it sees a \n character. Just for demonstration purposes, the \a (audible bell, ASCII BEL) character is implemented by sending a string to stderr, so it will be displayed on the LCD.

The public function uart_getchar() implements the line editor. If there are characters available in the line buffer (variable rxp is not NULL), the next character will be returned from the buffer without any UART interaction.

If there are no characters inside the line buffer, the input loop will be entered. Characters will be read from the UART, and processed accordingly. If the UART signalled a framing error (FE bit set), typically caused by the terminal sending a line break condition (start condition held much longer than one character period), the function will return an end-of-file condition using _FDEV_EOF. If there was a data overrun condition on input (DOR bit set), an error condition will be returned as _FDEV_ERR.

Line editing characters are handled inside the loop, potentially modifying the buffer status. If characters are attempted to be entered beyond the size of the line buffer, their reception is refused, and a \a character is sent to the terminal. If a \r or \n character is seen, the variable rxp (receive pointer) is set to the beginning of the buffer, the loop is left, and the first character of the buffer will be returned to the application. (If no other characters have been entered, this will just be the newline character, and the buffer is marked as being exhausted immediately again.)