Fact-checked by Grok 2 weeks ago

16550 UART

The 16550 UART (Universal Asynchronous Receiver/Transmitter) is an developed by as an enhanced controller, primarily designed to interface computers with devices such as and terminals, featuring 16-byte transmit and receive to reduce CPU overhead during high-speed transfers. Introduced in July 1987, the NS16550A (a key variant of the 16550 series) addressed limitations in earlier UARTs like the NS16450 by incorporating buffers, enabling baud rates up to 256 kbaud while maintaining full software and pin compatibility with its predecessor, except for two pins repurposed for signaling (RXRDY and TXRDY). This design improvement allowed for a fivefold increase in performance, mitigating overruns in multitasking environments common to PC, XT, AT, and compatible systems by buffering and providing programmable triggers at 1, 4, 8, or 14 bytes in the receive . The device supports configurable parameters, including 5- to 8-bit character lengths, odd/even/no , 1, 1.5, or 2 stop bits, and full control signals such as , DTR, DSR, DCD, and , along with independent sources for receiver, transmitter, line status, and status events. Key technical specifications include operation at 5V ±5% supply voltage, an input clock up to 8 MHz for programmable rate generation (dividing by 1 to 2¹⁶-1 to produce a 16x clock), and fabrication using National Semiconductor's advanced scaled N-channel silicon-gate (XMOS) process for low power dissipation (maximum 1W). It also includes a diagnostic mode for testing and two modes: Mode 0 for single transfers per and Mode 1 for multi-transfer operation, making it suitable for applications like multiport boards and concentrators. Widely adopted in personal computing during the late and , the 16550 UART became a for PC ports, powering asynchronous communications in and early Windows environments. Although largely superseded by USB and integrated controllers, 16550 UARTs remain available in modern PCIe serial adapter cards for legacy and industrial applications.

History

Development and Origins

The 16550 UART was invented by in the late 1980s as an to improve performance in personal computers. This development addressed the limitations of earlier UART designs, particularly in handling the growing demands of serial ports for applications such as modems and terminals in PC-compatible systems. Key motivations for the 16550 stemmed from the performance bottlenecks in predecessors like the Intel 8250 and Semiconductor's 16450, which featured only single-byte buffers. These older UARTs generated high rates and risked data overruns as CPU speeds increased and data rates rose, consuming significant processor bandwidth—for instance, up to 50% at 115 kbaud without adequate buffering. The 16550 was designed to mitigate these issues while ensuring with the established Intel 8250 standard, which had become the interface for ports since its inclusion in the original 1981 PC. Conceptual development of the 16550 occurred around 1987, with its initial release documented that same year to support higher rates up to 256 kbaud and reduce CPU intervention in handling. Production began shortly thereafter, enabling widespread integration into PC systems by 1989–1990, driven by the need for efficient serial communications in an era of expanding peripheral connectivity. The primary innovation, 16-byte buffers, allowed for batched to alleviate overhead, marking a significant from the byte-at-a-time approach of prior UARTs.

Introduction and Variants

The 16550 UART, developed by , was introduced in 1987 as an enhanced (UART) featuring integrated 16-byte buffers to address the performance bottlenecks of prior designs like the 16450, which relied on single-byte buffering and struggled with data rates beyond 9600 . This innovation enabled more efficient serial data handling in multitasking environments, maintaining full software compatibility with earlier UARTs while supporting higher throughput for applications such as modems and terminal interfaces. The chip's design emphasized CPU independence through interrupt-driven operations and support, making it suitable for emerging PC architectures. The original 16550 saw rapid adoption in personal computing, serving as the inaugural interface chip in IBM's PS/2 line of computers released in 1987, where it powered COM ports on motherboards and cards. However, early units suffered from a FIFO implementation flaw that limited its buffering effectiveness, prompting to release the revised 16550A in 1987, which resolved the issue and established it as the industry standard for reliable serial communications. By 1991–1992, the 16550A had become ubiquitous in x86-based systems, including motherboards from major vendors, facilitating stable operation at baud rates up to 115,200 bps—a common rate as a multiple of 9600 baud (×12), which traces back to 300 baud derived from 50/60 Hz mains frequencies—and reducing data overruns in high-speed scenarios like file transfers and remote access. Key variants beyond National Semiconductor's offerings include compatible implementations from other manufacturers, such as Exar Corporation's ST16C550 series, which replicated the 16-byte and register interface for drop-in in designs. National Semiconductor's licensing model spurred this proliferation, leading to widespread third-party adoption in , servers, and embedded systems throughout the 1990s.

Architecture

Compatibility with Earlier UARTs

The 16550 UART was designed to maintain pin-for-pin compatibility with its predecessors, the 16450 and 8250, utilizing the same 40-pin package to enable direct on existing printed boards without requiring modifications to layouts. Specifically, it aligns with the 16450's pinout, except for pins 24 (repurposed from CSOUT to TXRDY) and 29 (repurposed from NC to RXRDY), which were often unused in prior implementations, allowing seamless upgrades in most cards. Functionally, the 16550 retains equivalence to the 8250 family by preserving core UART operations, including serial data transmission and reception, rate generation via the same programmable divider, and handling in non-FIFO mode. It employs identical I/O port addressing schemes, such as the standard base address of 0x3F8 for COM1 in PC-compatible systems, ensuring that hardware interfaces remain unchanged. Software compatibility is achieved through no alterations to established driver application programming interfaces (APIs) or BIOS-level routines developed for earlier UARTs, as the 16550 powers up in 16450-compatible mode by default. Advanced FIFO features can be selectively enabled via configuration bits in the FIFO Control Register (FCR), preventing disruptions to legacy applications that expect single-byte buffer behavior. Additionally, setting FCR bit 0 to zero disables the FIFOs entirely, providing exact emulation of the 16450 for environments requiring strict backward compatibility and reliability in mixed hardware setups.

Register Interface

The 16550 UART features a set of eight programmable registers accessible via an 8-bit addressing scheme, typically mapped to I/O ports or locations in a . These registers control data transmission and reception, handling, serial line parameters, rate generation, signals, and diagnostic functions. The interface maintains with the base address of earlier UARTs like the 8250, allowing seamless without altering existing configurations. The register map is determined by three address lines (A2, A1, A0) and the Divisor Latch Access Bit (DLAB) in the Line Control Register (LCR). When DLAB is 0, offset 0x00 accesses the Receiver Buffer Register (RBR) for reading received data and the Transmitter Holding Register (THR) for writing data to transmit, while offset 0x01 accesses the Interrupt Enable Register (IER). Offset 0x02 provides read access to the Interrupt Identification Register (IIR) and write access to the Control Register (FCR). Other offsets include the Line Control Register (LCR) at 0x03, Modem Control Register (MCR) at 0x04, Line Status Register (LSR) at 0x05, Modem Status Register (MSR) at 0x06, and Scratch Register (SCR) at 0x07. When DLAB is set to 1 via LCR bit 7, offsets 0x00 and 0x01 instead access the low and high bytes of the Divisor Latch Registers (DLL and DLM) for baud rate configuration.
OffsetDLABRegister (Read/Write)AbbreviationDefault Value
0x000Receiver Buffer / Transmitter HoldingRBR / THRN/A
0x01X EnableIER0x00
0x02X Identification (R) / FIFO Control (W)IIR / FCRN/A
0x03XLine ControlLCR0x00
0x04XModem ControlMCR0x00
0x05XLine StatusLSR0x60
0x06XModem StatusMSR0x00
0x07XScratchSCR0x00
0x001Divisor Latch LowDLL0x00
0x011Divisor Latch HighDLM0x00
The Interrupt Enable Register (IER) at offset 0x01 configures interrupt sources with four key bits: bit 0 enables receiver data available interrupts, bit 1 enables transmitter holding empty interrupts, bit 2 enables receiver line status interrupts for errors, and bit 3 enables modem status interrupts. The FIFO Control Register (FCR) at offset 0x02 (write-only) manages operations, with bit 0 enabling both transmit and receive s, bits 1 and 2 providing self-clearing resets for the receiver and transmitter s, and bits 6-7 setting receiver FIFO trigger levels (1, 4, 8, or 14 bytes) to control when interrupts or requests occur. The Line Status Register (LSR) at offset 0x05 reports real-time status, including bit 0 for data ready, bits 1-4 for error flags such as overrun, , framing, and break detection, bit 5 for transmitter holding empty, and bit 7 for receiver FIFO error conditions when FIFOs are enabled. Baud rate configuration uses the Divisor Latch Registers (DLL and DLM), accessed at offsets 0x00 and 0x01 when DLAB=1. These form a 16-bit value, where the baud rate is calculated as input clock divided by (16 times the ), for example, a of 1 yields a baud rate of input clock / 16. Typical input clocks like 1.8432 MHz support standard rates from 50 to 115200 by selecting appropriate . The Scratch Register (SCR) at offset 0x07 serves as a general-purpose 8-bit storage location for software testing or diagnostic purposes, with no predefined function and read/write access to all bits. The Modem Control Register (MCR) at offset 0x04 handles interface signals, with bit 0 controlling Data Terminal Ready (DTR), bit 1 controlling Request to Send (RTS), bits 2 and 3 providing auxiliary outputs (OUT1 and OUT2), bit 4 enabling local loopback mode for self-testing, and bits 5–7 reserved.

Key Features

FIFO Buffers

The 16550 UART incorporates 16-byte First-In-First-Out () buffers for both the transmitter (TX) and receiver (RX), implemented as circular queues to efficiently store data bytes without overwriting unread information. These buffers enhance data handling by allowing multiple bytes to be queued before CPU intervention, contrasting with the single-byte buffering of earlier UARTs like the 16450. The RX FIFO accumulates incoming serial data from the , while the TX FIFO is loaded by the CPU and sequentially empties data to the for . Operation of the FIFOs is controlled through the FIFO Control Register (FCR), where bit 0 enables both buffers, and bits 6 and 7 set the programmable trigger level for interrupts at 1, 4, 8, or 14 bytes. The FIFO interrupt is triggered when the FIFO is empty. For the FIFO, an is generated when the fill level reaches the selected , prompting the CPU to read via the receiver . The FIFO, once enabled, accepts up to 16 bytes from the CPU before the is signaled when empty. FIFO reset is achieved by setting bit 1 (RX reset) or bit 2 (TX reset) in the FCR, which clears the respective buffer contents without disrupting other UART operations or requiring a full device reset. These self-clearing bits allow quick reinitialization during runtime. The FIFO buffers significantly reduce CPU overhead by shifting from per-byte interrupts to per-burst servicing, potentially decreasing interrupt frequency by up to 16 times when handling a full TX buffer. This efficiency enables reliable operation at baud rates exceeding 38.4 kbps on 286 and 386 processors, where interrupt latency would otherwise limit performance to lower speeds.

Interrupt Enhancements

The 16550 UART introduces an enhanced interrupt system that expands on the basic interrupt capabilities of earlier models like the 16450, incorporating six distinct interrupt sources identified through the Interrupt Identification Register (IIR). These sources include receiver line status changes (such as overruns, parity, framing, or break errors), received data availability, transmitter holding register empty, modem status changes, receiver timeout in FIFO mode, and FIFO trigger level reached. The IIR, a read-only register at offset 2, uses its lower bits to signal these conditions: bit 0 indicates an interrupt pending (0 for pending, 1 for none), bits 1–3 encode the specific source and priority (e.g., binary 011 for receiver line status, the highest priority; 110 for receiver timeout), and bits 6–7 flag when FIFO mode is active. This prioritization ensures critical events, like line errors, are handled first, followed by data availability, transmitter status, and modem changes in descending order. Interrupts are enabled or disabled via the Interrupt Enable Register (IER) at offset 1, which provides granular control over the sources. Bits 0–3 correspond to the basic interrupts: bit 0 for received data available (and timeout in mode), bit 1 for transmitter empty, bit 2 for receiver line status, and bit 3 for status; setting these to 1 activates the respective interrupts, while 0 disables them. In mode, the same bits extend functionality—bit 0 now also enables the timeout interrupt, which triggers if at least one character remains in the receive with no further activity or CPU reads for four character periods (the time to receive one full character, typically 10-12 bit times), delayed by eight receive clock cycles. Bits 4–7 of the IER are reserved and always read as 0, maintaining compatibility while allowing software to fully disable the interrupt system by writing 00h. The FIFO-specific enhancements significantly improve interrupt handling by introducing programmable trigger levels and batching, reducing unnecessary CPU interventions. In receive mode, an interrupt fires when the FIFO reaches a configurable (1, 4, 8, or 14 bytes, set via the FIFO Control Register), rather than on every single byte, allowing the CPU to process up to 16 bytes per cycle. The transmitter in FIFO mode is generated when the TX FIFO becomes empty, allowing up to 16 bytes to be loaded per cycle, with a one-character delay after the initial byte load in certain scenarios to optimize flow. The timeout feature addresses low-data-rate scenarios, preventing data from stalling in the FIFO by alerting the CPU after idle periods, thus ensuring timely servicing without constant polling. Overall, these mechanisms cut CPU overhead by a factor of up to five compared to non-FIFO UARTs, as fewer are generated for high-throughput transfers.

Operational Challenges

FIFO Implementation Bug

The original 16550 UART suffered from a hardware flaw in its implementation that rendered the buffers unusable, causing the device to function only as an equivalent to the 16450 UART with single-byte buffering. This issue affected the reliability of buffering for both incoming and outgoing data. The defect undermined the performance benefits of the feature, forcing software drivers to disable and revert to non-FIFO mode to ensure . Consequently, systems could not reliably achieve higher serial speeds beyond approximately 38.4 kbps without risking overruns or loss, negating the intended reduction in CPU overhead. The flaw was present in early production units shortly after the device's release, prompting widespread software workarounds in operating systems and applications, often detecting and treating the buggy 16550 as a 16450. National Semiconductor addressed the issue in the revised 16550A variant by correcting the FIFO design flaws, allowing reliable use of the 16-byte RX and TX FIFOs. Introduced as a , the 16550A maintained full with existing software, including detection routines that could identify the corrected version. This fix enabled reliable serial rates up to 115.2 kbps or higher in compatible systems. Software detection of the buggy original 16550 typically involved enabling the and then reading bits 6 and 7 of the Interrupt Identification (IIR); a value of "01" indicated enabled but unusable due to the flaw. These methods allowed drivers to automatically disable on affected hardware to prevent errors.

Performance Limitations

The 16550 UART is susceptible to overrun errors when the CPU fails to read data from the 16-byte receive before it fills completely, causing incoming characters to overwrite unread data; this condition sets bit 1 of the Line Status (LSR). Transmitter underrun occurs if the transmit empties without being refilled, halting ongoing transmission until new data is provided, as indicated by the Transmitter Holding Empty (THRE) flag in LSR bit 5. These risks are mitigated by the buffers but remain dependent on timely software servicing of interrupts or polling. The effective maximum baud rate of the 16550 UART is up to 500 kbps with an 8 MHz input clock, limited by the internal baud rate generator's clock division capabilities and the 16-byte depth, which provides buffering for about 1.39 ms at 115200 assuming 10 bits per character. However, achievable rates drop significantly if system latency exceeds the time required to process a full , such as in scenarios where delays surpass the buffering window at higher speeds. Error conditions including errors (LSR bit 2), framing errors (LSR bit 3), and break interrupts (LSR bit 4) are detected by the , with LSR bit 7 indicating any in the receive FIFO when enabled. The UART provides no automatic recovery mechanisms for these errors, necessitating software intervention to clear the LSR flags and handle or retransmission. Performance of the 16550 UART depends on system response times, where high can lead to buffer overflows in multitasking environments.

Legacy

Applications in Computing

The 16550 UART served as the standard interface for serial ports, known as COM1 through COM4, in x86-based personal computers during the , enabling connections to peripherals such as modems for , serial mice for input, printers for output, and debug consoles for troubleshooting. This chip's 16-byte buffers allowed reliable asynchronous at speeds up to 115,200 , which was essential for handling data bursts from high-speed modems without overwhelming the CPU in systems like the PC and its compatibles. In embedded systems, the 16550 UART found widespread adoption in industrial controllers, point-of-sale (POS) terminals, and early networking equipment, where its robust design provided dependable over , , or interfaces for tasks like machine control and data logging. These applications benefited from the UART's programmable rates and flow control, ensuring compatibility in resource-constrained environments up to 115,200 without requiring frequent CPU intervention. Supporting this hardware, operating systems developed dedicated drivers optimized for the 16550; for instance, included serial drivers that detected the chip via reads from the Control Register (FCR) to enable higher-speed operations, while Windows 3.x and later versions used the Serial.sys driver for 16550-based ports. In , the 8250/16550 serial driver (implemented in serial.c) similarly probed for 16550A variants through FCR access to configure FIFOs and interrupts, facilitating seamless integration in both desktop and embedded kernels. The 16550 UART reached peak dominance in computing through the mid-1990s, powering the majority of serial communications in and devices until the late , when USB ports began displacing them due to plug-and-play advantages and higher speeds. As of 2025, it persists in legacy hardware, industrial retrofits, and specialized add-on cards for maintaining compatibility with older peripherals.

Successors and Modern Equivalents

The 16650 UART, introduced by around 1995, served as a direct evolution of the 16550 by expanding the FIFO buffers to 32 bytes for both transmit and receive operations, which helped mitigate interrupt latency at higher baud rates. This design also incorporated enhanced capabilities, allowing for more autonomous data transfers without constant CPU involvement, thereby improving overall system efficiency in applications. Building on this progression, the 16750 and compatible 16C750 UARTs, developed in the late by and Semiconductors (now NXP), further increased FIFO depth to 64 bytes, with the 16750 supporting data rates up to 921 kbit/s and the SC16C750 up to 3 Mbit/s with a 48 MHz , while maintaining pin compatibility with earlier models. These chips added advanced features such as IrDA encoder/decoder support and flexible rate generation, making them suitable for emerging high-speed interfaces in systems. The SC16C750 variant, for instance, emphasized low-power operation at 3.3 V or 5 V, with hardware and to handle bursty data traffic reliably. In contemporary FPGA designs, 16550-compatible IP cores from vendors like (formerly ) enable soft implementations of UART functionality, often with configurable FIFO sizes extending up to 128 bytes to accommodate modern throughput demands while preserving register-level compatibility. These cores integrate seamlessly into or AXI bus architectures, facilitating custom peripherals in reconfigurable logic without requiring discrete . Modern equivalents have largely supplanted discrete UARTs through USB-to-serial bridge ICs, such as FTDI's FT232H series, which provide USB 2.0 high-speed interfaces (up to 480 Mbps USB throughput) translating to baud rates of up to 12 Mbps in UART mode, complete with integrated flow control and no need for external crystals. Similarly, integrated UART peripherals in ARM-based SoCs, like those from NXP, offer expansive 256-byte s and support for speeds exceeding 5 Mbit/s—reaching 12 Mbps in implementations such as 's Zynq processors—optimized for low-latency and embedded applications. Despite these advancements, the 16550 persists in emulated form within environments like , where PCI-wrapped 16550 models ensure legacy software compatibility, and in niche retro and scenarios, though it was predominantly phased out from mainstream consumer by the early .

References

  1. [1]
    [PDF] National Semiconductor - NS16550A Universal Asynchronous ...
    The NS16550A is an improved version of the NS16450 Uni versal Asynchronous Receiver/Transmitter (UART). The im proved specifications ensure compatibility ...
  2. [2]
    [PDF] The NS16550A: UART Design and Applications Considerations
    The NS16550A has all of the registers of its two predeces- sor parts (INS8250 and NS16450), so it can run all existing. IBM PC, XT, AT, RT and compatible serial ...
  3. [3]
    New IC Caps Two Decades of UART Development - Analog Devices
    Modern CMOS UARTs like the National Semiconductor 16550 and the Zilog 8630 are traceable to early classics like the Intel 8250 and Intersil 6402. In 1981, an ...
  4. [4]
    Putting Serial-Port Technology in Perspective, Part 2
    May 26, 1992 · The 16550 was replaced by the 16550A in the PS/2 Model 70. This fixed the bug in the FIFO section of the chip: improved versions of the Models ...
  5. [5]
    Serial HOWTO: What Are UARTs? How Do They Affect Performance?
    There is some confusion regarding 16550. Early models had a bug and worked properly only as 16450's (no FIFO). Later models with the bug fixed were named 16550A ...
  6. [6]
    [PDF] xr ST16C1550/51 - MaxLinear
    The. ST16C155X provides enhanced UART functions with. 16 byte FIFOs, a modem control interface, independent programmable baud rate generators with clock rates ...Missing: clones | Show results with:clones
  7. [7]
    [PDF] ~ Semiconductor - Bitsavers.org
    National Semiconductor is an industry leader in the manufacture of high ... UART Design and Application Considerations. . . . . . . . . . . . . . 4-57.
  8. [8]
    [PDF] A Comparison of the INS8250, NS16450 and NS16550 ... - UMBC
    It has advanced features such as on-board FIFOs, a DMA interface, faster CPU bus timings and a much higher maximum baud rate than the NS16450.<|control11|><|separator|>
  9. [9]
    Serial and UART Tutorial | FreeBSD Documentation Portal
    The 8250/16450/16550 UART occupies eight contiguous I/O port addresses. In the IBM PC, there are two defined locations for these eight ports and they are known ...
  10. [10]
    None
    ### Register Map and Descriptions for TL16C550C UART Registers (TI TL16C550C Datasheet)
  11. [11]
    None
    ### Summary of FIFO Buffers in PC16550D UART (from https://media.digikey.com/pdf/Data%20Sheets/Texas%20Instruments%20PDFs/PC16550D.pdf)
  12. [12]
    [PDF] PC16550D Universal Asynchronous Receiver/Transmitter with FIFOs²
    The UART is fabricated using National Semiconductor's ad- vanced M2CMOS process. *Can also be reset to 16450 Mode under software control. ²Note: This part ...
  13. [13]
    Serial UART, an in depth tutorial - Lammert Bies
    The 16550A which appeared soon after was the first UART which was able to use its FIFO buffers. This made it possible to increase maximum reliable communication ...
  14. [14]
    [PDF] A Comparison of the INS8250, NS16450 and NS16550 Series of ...
    NS16550AF: This is the newest member of the UART family. It powers-up in the NS16450 mode and is com- pletely compatible with all software written for the.
  15. [15]
    Asynchronous Advanced UART and USB Serial Support
    ### Summary of 16550 UART Applications and Features
  16. [16]
    The Surprising History of Serial Cables | Auvik
    Nov 2, 2021 · Even so, RS-232 ports continued to be used in personal computers until the late 1990s, when other standards, like USB, began to replace them.Missing: 16550 UART
  17. [17]
    UART 16550 IP Core - Lattice Semiconductor
    The UART 16550 IP core is for serial communication, supporting RS-232, RS-422, RS-485, and EIA standards, with separate receiver and transmitter, and 16-byte ...
  18. [18]
    UART 16550 Serial Controller - Beyond Semiconductor
    16550 Serial Controller IP core translates data between parallel and serial interfaces, and adds/removes start,stop bits, and optionally parity bit.<|control11|><|separator|>
  19. [19]
    [PDF] Device Driver for the MS-DOS Operating System Installation Guide ...
    The Hostess 550 supports a 16550 UART. Flowchart 1-1 shows an installation overview. Flowchart 1-1. Software and Hardware Installation Overview. Note: See ...<|separator|>
  20. [20]
    Serial Driver Samples - Windows drivers | Microsoft Learn
    Mar 22, 2023 · Serial, The Serial (16550-based RS-232) sample driver is a WDF version of the inbox Serial.sys driver. ; Virtual Serial, This sample demonstrates ...
  21. [21]
    The Linux 8250/16550 Serial Driver - SourceForge
    Jun 11, 2013 · Download The Linux 8250/16550 Serial Driver for free. This project contains the Linux serial driver for 8250/16550 (and compatible) UARTs.
  22. [22]
  23. [23]
    [PDF] High-speed UARTs and Bridge ICs - NXP Semiconductors
    Fastest baud rate: 5 Mbit/s. Deepest FIFO: 256 bytes SC28L202. Smallest footprint: 12.25 mm2. NXP UARTS offer exception performance, size and. FIFO depth. NXP ...
  24. [24]
  25. [25]
    QEMU PCI serial devices
    QEMU implements some PCI serial devices which are simple PCI wrappers around one or more 16550 UARTs. There is one single-port variant and two multiport- ...
  26. [26]
    2-Port PCI Express RS232 Serial Adapter Card with 16550 UART
    Product page for StarTech.com PEX2S553, a PCIe to dual RS232 serial adapter card using 16550 UART, designed for adding serial ports to modern PCs for legacy device connectivity and industrial applications.
  27. [27]
    Origin of "weird" baudrates for serial communication
    Technical discussion explaining the historical selection of baud rates like 115200 as a multiple of 9600, and the origins of 300 baud related to mains frequencies.