Explanation of UART Registers


The UART appears to applications as a series of registers occupying eight consecutive I/O addresses. Most PCs place COMM1 starting at I/O address 3F8H and COMM2 at 2F8H. Normally COMM1 is on IRQ 4 and COMM2 is on IRQ 3 (although some boards allow this to be changed). The starting address is referred to as the base address. Most of this discussion applies to all of the NS8250-compatible UARTs (including NS8250, NS16450 and 16550). I will use the term UART to refer to all UARTs compatible with the 8250, and NS16550 when necessary to specifically identify that chip (for FIFO-related items).

I will use the convention of identifying the bits in a register by numbering the low order bit as 0 and the high order bit as 7, i.e., 7654 3210. I have used the following sources for reference: IBM PS/2 Technical Reference Manual; National Semiconductor Datacomm, LAN, UARTs handbook 1990 edition.

Receiver Buffer Register (RBR) — READ at base address (DLAB bit in MCR must be 0)

This register contains the last character received. If register is not read before next character is received, original character will be lost. On the NS16550, reading this register fetches the next character from the FIFO. Up to 16 characters can be in the FIFO at any time.

Transmitter Holding Register (THR) — WRITE at base address (DLAB bit in MCR must be 0)

Writing a character to this register causes it to be transmitted. If it is overwritten before the character is transmitted in its entirety, both characters will be lost. On the NS16550, writing to this register places the character in the transmit FIFO. Up to 16 characters can be in the FIFO at any time.

Divisor Latch Registers — low byte READ/WRITE at base address, high byte READ/WRITE at base address + 1 (DLAB bit in MCR must be 1 to access either of these registers)

These two registers program the baud rate generator. Some common values are shown in Table 1.

Interrupt Enable Register (IER) — READ/WRITE at base address + 1 (DLAB bit in MCR must be 0)

This register is used to enable different types of interrupts from the UART (see the IIR for a description of the interrupts). Any combination of these interrupts can be enabled by setting the corresponding bit to 1. For interrupts to be actually generated to the main CPU, you must also set Bit 3 of the MCR to turn on the OUT2 signal (this bit is used to mask the UART interrupt on most IBM and compatible serial adapters).

Interrupt Identification Register (IIR) — READ at base address + 2

When the UART generates an interrupt, the interrupt identification bits in this register are set to indicate the type of interrupt. If several conditions requiring interrupt occur simultaneously, one interrupt will be generated per condition according to the following priority scheme:

Receiver Line Status - Highest

Received Data Available - Second

Transmitter Holding Register Empty - Third

Modem Status - Last

FIFO Control Register (FCR, NS16550 only) - RITE at base address + 2

Line Control Register (LCR) - EAD/WRITE at base address + 3

Modem Control Register (MCR) — READ/WRITE at base address + 4

This register controls output signals from the UART. Bits 1 and 0 control signals going to the modem. A brief description of the normal uses of each signal has been provided, but it should be noted that some modems may not use them in this fashion, and other modems may have to be reconfigured to use the signals this way.

Line Status Register (LSR) — READ at base address + 5

This register provides information about the state of the data transfer. When a line status interrupt occurs, you should read this register and examine bits 1 - 4 to determine the cause (and clear the interrupt). For the NS16550, the FIFO contains additional bits corresponding to bits 1 - 4 of the LSR. When the FIFO is enabled, bits 1 - 4 of the LSR will be set according to the character currently being read from the FIFO (which may not be the most recently received character) allowing the modem software to handle line errors as if the FIFO did not exist.

Modem Status Register (MSR) — READ at base address + 6

Scratch Register — READ/WRITE at base address + 7

This is a general-purpose register available to the modem software for any purpose. It does not affect the UART in any way.