The 8250 UART In Detail

This page was last updated on 06/30/2001


General Description

The 8250 UART provides a bi-directional serial asynchronous interface with an on-board baudrate oscillator and programmable divider (divide by 16 * N, where N can range from 1 to 65535). In addition to the serial data input, serial data output and the bus interface to any of several possible microprocessor architectures, the chip has four programmable output pins and four input pins which can be assigned to the modem control and hardware handshaking signals of a standard RS-232-C interface (and are named based on the signals to which they would connect).

Bus Interface

Three address bits (A2 - A0) and three Chip Select pins (CS0 CS1 and CS2/) determine how the chip is addressed. The CS pins must all be active to select the chip and the address bits determine what on-chip register is selected. Eight bi-directional, tri-state data bits (D7 - D0) provide the data pathway. Outputs are enabled when the chip is selected and a read (DOSTR) operation is in process.

DISTR and DISTR/ allow the designer the option of active-high or active-low bus IOWrite signal; likewise DOSTR and DOSTR/ lets the designer choose between an active-high or active-low IORead.

Address strobe (ADS/), when low, latches the CS and A bits, allowing the chip to be used with bus interfaces where address and data are multiplexed on the same pins (e.g.: the 8085).

The interrupt pin (INT) goes high whenever any enabled interrupt source is active. There are four possible sources for interrupts; the chip can decide which (or even all) of these should cause an interrupt request or if software should use a polling strategy (by writing 0 to the IER to disable all interrupt sources and then reading the LSR and MSR periodically).

Serial Interface

In addition to SIN (Serial Input) and SOUT (Serial Output) which provide the receive and transmit serial data path, there are four inputs and two outputs which provide hardware handshaking and two additional outputs which can be used for unusual interface requirements. These are:

    Signal  Direction   Commonly Used as
    ------  ---------   ---------------------------------
     RTS/   Output      Request to Send
     CTS/   Input       Clear to Send
     DTR/   Output      Data Terminal Ready
     DSR/   Input       Data Set Ready
     DCD/   Input       Data Carrier Detect
     RI/    Input       Ring Indicator
     OUT1/  Output      Unassigned Programmable Output #1
     OUT2/  Output      Unassigned Programmable Output #2

All of these pins are active-low, which matches up nicely with the 1488/1489 chip family of RS-232-C converters (which are inverting).

Misc. Signals

The chip can either accept an external oscillator signal or act as a crystal oscillator for the purposes of generating the baudrate. Baudrate oscillator frequencies of up to 3.1 MHz are possible. If used as an oscillator, the UART can provide oscillator output to other circuits as well.

There are provisions for looped-back clock: the baudrate generator's output is available as an external output pin and the receiver shift register's input is brought to an external input pin. (For non-looped clock -- more common these days, one connects BAUDOUT to RXC.) The baudrate clock is sixteen times the bits-per-second rate of the serial data stream (e.g.: if the communication channel is running at 300 baud, this frequency is 4800 Hz.), with the maximum baudrate limited by the fact the BAUDOUT clock rate must be not more than 1 MHz. (This limits the UART to data rates of up to about 62,500 baud.)

Programming Information

The 8250 has eight 8-bit registers, occupying a block of six consecutive I/O addresses (two locations are overloaded):

    offset  name    Function                Use
    --------------------------------------------------------------------
      0*    RBR/THR Rx Buffer Reg.          Serial Input (buffered)
                    Tx Holding Reg.         Serial Output (buffered)
      1*    IER     Interrupt Enable Reg.   Enable Tx Empty, Rx Ready,
                                            Rx Error and/or Modem
                                            interrupts
      0*    DLL     Divisor Latch Low       Bits 7-0 of Baudrate
                                            divisor
      1*    DLH     Divisor Latch High      Bits 15-8 of Baudrate
                                            divisor
      2     IIR     Interrupt ID Reg.       ID of the highest priority
                                            interrupt source.
      3     LCR     Line Control Reg.       Data length, framing,
                                            parity computation, access
                                            to DLL/DLH and Send Break.
      4     MCR     Modem Control Reg.      DTR, RTS, OUT1, OUT2 and
                                            Loopback Mode control.
      5     LSR     Line Status Reg.        TSE, THRE, and RDR status
                                            and Rx Errors (PE, FE, OE,
                                            and BRK)
      6     MSR     Modem Status Reg.       CTS, DSR, RI, DCD & detlas.
      7     **

    (*)     Bit 7 of the LCR controls access to the DAT & IER
            (when set to 0) or access to DLL & DLH (when set to 1).
    (**)    This address is apparently not used.  I'm not sure if the
            chip's outputs are enabled when this location is read or
            not, but the data read is always 0x0FF -- either because
            that's what the chip is driving on the data bus or because
            the chip's outputs are disabled and the data bus is
            "floating" to that value.

Register Details:

RBR / THR - Receiver Buffer Register/Transmitter Holding Register

These are the transmitter holding register and the receive data register for the UART. (The UART has internal shift registers that serialize the data, but except for the TSE status bit, there's no software visibility to them.)

IER - Interrupt Enable Register

There are four sources of interrupt on the 8250 that can be enabled by setting a 1 in the corresponding bit of IER. These four sources are ORed together and drive the chip's interrupt output pin. The sources are encoded as follows:

    Bit #   Purpose                 Reason for Interrupt
    -----   ------------------------------------------------------------
      0     Rx Data Ready           A character is received
      1     THRE                    There is room for another char to
                                    be sent
      2     Rx status               PE, FE, overrun and/or BREAK
      3     Modem status            Change in state of CTS, DSR, RI
                                    or DCD
     4-7    0                       (these bits are not used.)

IIR - Interrupt ID Register (read-only)

Indicates the cause of the interrupt. Encoding is:

Bit 0 is set if there is no active Interrupt Source and is zero if one or more interrupt sources are active. An interrupt source is active when there is a condition that woudl cause the interrupt (such as THRE) and the IER bit for that interrupt source is set so that the interrupt source is able to activate the INT output pin.

Bits 1 and 2 encode the interrupt source. Since there are four possible sources for an interrupt, only the highest-priority source is encoded. Therefore, reading this register will return a three-bit code of "001" when no interrupt is active and codes of "000", "010", "100" and "110" when an interrupt is active.

Bits 3-7 are not used.

    Code        Source                  Action to Reset Interrupt
    --------------------------------------------------------------------
    000 (Lo)    Modem status            read MSR / Master Reset pin (MR)
    010         Tx Holding reg empty    write THR or read IIR / MR
    100         Rx Data Ready           read RBR /MR
    110 (Hi)    Rx line status error    read LSR /MR
                (i.e.: any of OE, FE,
                PE or Break Detected)

LCR - Line Control Register

Controls the access to the divisor latch, can force sending BREAK and sets parity and data length for both receive and transmit.

    Bit     Purpose
    --------------------------------------------------------------------
     7      DLA, Divisor Latch Access Bit: 
            1 = Access DLL and DLH at offsets zero and one,
                respectively;
            0 = Access DAT and IER instead
     6      Send Break -- Sends SPACE until this bit is reset again
    5-3     Parity Control:
                XX0 = No Parity,
                001 = Odd Parity,
                011 = Even Parity,
                101 = Stick Parity bit TRUE,
                111 = Stick Parity bit FALSE
     2      Number of stop bits sent with each character:
                0 = one stop bit;
                1 = 1.5 stop bits if the word length is five bits,
                    else two stop bits for other word lengths
    1,0     word length (bits per character, not including start bit,
            stop bits and parity bit, if any):
                11 = eight,
                10 = seven,
                01 = six
                00 = five bits per character

MCR - Modem Control Register

Controls loopback mode, two hardware handshaking signals and two general-purpose output pins (bits 5-7 are unused):

    Bit     Signal
    --------------------------------------------------------------------
    4       Set loopback mode (allows the UART to test itself)
    3       OUT2
    2       OUT1
    1       RTS
    0       DTR

LSR - Line Status Register

Six UART status bits (bit 7 is unused), encoded as follows:

    Bit     Name                              Purpose
    --------------------------------------------------------------------
     6      Tx Shift Register Empty (TSE)     Indicates that a character
                                              has been sent
     5      Tx Holding Register Empty (THRE)  Indicates that a charcater
                                              can be written into the
                                              Tx holding register (and
                                              will eventually be sent)
     4      Break received                    BREAK was received
     3      Framing Error (FE)                Wrong number of data bits
                                              received
     2      Parity Error (PE)                 Incorrect parity
     1      Overrun Error (OE)                Data received before RBR
                                              was read from a previous
                                              character (the software is
                                              not keeping up with the
                                              serial data)
     0      Rx Data ready                     A character has been read
                                              and is available to the
                                              software in the RBR

Note: This register can be written, but if you write a 1 bit into any of bits 5 - 0, you could cause an interrupt if the appropriate IER bit is set.

MSR - Modem Status Register

The four Hardware handshaking inputs, plus bits indicating that their change in state since the previous read of MSR are encoded as:

    Bit     Signal / Purpose
    --------------------------------------------------------------------
     7      DCD asserted
     6      RI asserted
     5      DSR asserted
     4      CTS asserted
     3      Delta (i.e.: a change in the state of) DCD
     2      RI trailing-Edge detect (i.e.: RI deasserted)
     1      Delta DSR
     0      Delta CTS

If any of the "delta xxx" bits are set and the Modem Status Interrupt Enable bit is set in the IER, an interrupt will be signalled.

Reset Behavior

Registers, outputs and interrupts are reset as:

Loop-Back Mode Behavior

In Loop-Back mode, the transmitter is connected to the receiver and the modem control outputs and inputs are interconnected as follows:

Send Break Behavior

When the Send Break bit is set in the LCR, the SOUT pin goes to its active (low or SPACE) state. It stays there until the LCR is re-written with a value that doesn't include a 1 in bit 6. In other words, the duration of the break is strictly up to the program. However, the rest of the transmit logic of the UART thinks it's sending a character, so THRE and TSE timing continues. Therefore, it's possible to have software arrange to make the break duration an exact number of character times by sending fake data to the THRE and counting TRE transitions (which will happen once per character time).

A way to program a break of some specific number of character durations without causing spurious or partial characters would be to begin by sending a NUL ('\0') character to the THR as soon as the THRE status is asserted, then write "x1xxxxxx"b (any byte with bit 6 set) to the LCR when the next THRE happens and also send another NUL to the THR. While watching TSE, count down the character times desired and re-send NUL to the THR until enough character times are used. On the next TSE, de-assert Send Break in the LCR ("x0xxxxxx"b) and go back to normal output.