OSD Home
Serial chip types
- 8250 and 8250B have no scratch register
- 8250A and 16450 have the scratch register but no FIFO
- 16550 has a FIFO but it doesn't work
- 16550A has a 16-byte FIFO
- 16650 has a 32-byte FIFO, on-chip flow control, and can run up
to 460800 baud (4x normal)
- 16750 has a 64-byte FIFO, on-chip flow control, and can run up
to 921600 baud (8x normal). This chip is NOT pin-compatible
with the others.
8250-series chips (including 8250A) have these problems:
- They can not keep up with PC/AT I/O speed, so delays must
be inserted between successive I/O instructions
- They transmit bad data when configured for 5 data bits
with 1.5 stop bits
- They can occasionally drop received characters without
posting a receive overrun error. This results in
undetected data loss.
- They can transmit a single random character at power on
There is no way to distinguish between 8250A and 16450 in software.
Serial chip registers
|
Read |
Write |
Register number |
DLAB=0 |
DLAB=1 |
DLAB=0 |
DLAB=1 |
Register name(s) |
Notes |
0 |
RBR |
DLL |
THR |
DLL |
Receiver Buffer Register
Divisor Latch LSB
Transmitter Holding Register |
1 |
IER |
DLM |
IER |
DLM |
Interrupt Enable Register
Divisor Latch MSB |
2 |
IIR |
|
Interrupt ID Register |
8250-16450 chips (no FIFO) |
IIR |
FCR |
FIFO Control Register |
16550-series chips |
IIR |
FCR |
EFR |
Enhanced FIFO control Register |
16650+ chips |
3 |
LCR |
Line Control Register |
4 |
MCR |
Modem Control Register |
5 |
LSR |
Line Status Register |
6 |
MSR |
Modem Status Register |
7 |
SCR |
SCRatch Register |
8250A and 16450+ chips |
DLAB is bit b7 in the Line Control Register (see below).
The bit rate is normally 115200 divided by the 16-bit Divisor Latch value.
According to one 16550A spec sheet, 'Using a value of 0 is not recommended.'
Reading RBR (register 0) clears the Receive Data and FIFO Timeout Interrupts.
Writing THR (register 0) clears the Transmit Holding Register Empty Interrupt.
If you have nothing more to transmit, reading the Interrupt ID Register (IIR)
will also clear this interrupt.
Register 1: Interrupt Enable Register (IER)
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
0 | 0 | 0 | 0 | EDSI | ELSI | ETBEI | ERBFI |
b3 |
EDSI |
Enable moDem Status Interrupt (DCD, RI, DSR, CTS, etc.) |
b2 |
ELSI |
Enable Line Status Interrupt (BI, FE, PE, or OE) |
b1 |
ETBEI |
Enable Transmitter Buffer Empty Interrupt (when THR is empty). |
b0 |
ERBFI |
Enable Receiver Buffer Full Interrupt. In FIFO mode, this bit
also enables the FIFO timeout interrupt. |
The receive FIFO timeout occurs automatically, when
- there is data in the receive FIFO, but
- not enough data in the FIFO to trigger a normal Receiver Buffer Full interrupt, and
- incoming data stops for a period of 4 character times or longer.
Register 2: Interrupt ID Register (IIR; read-only)
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
fe1 | fe0 | 0 | 0 | id2 | id1 | id0 | nint |
b7-b6 |
fe1-fe0 |
When FIFOs are enabled, these bits identify the serial chip:
fe1 | fe0 | chip |
0 | 0 | 8250/16450 (no FIFO) |
0 | 1 | UNKNOWN |
1 | 0 | 16550 (defective FIFO) |
1 | 1 | 16550A+ |
|
b3-b1 |
id2-id0 |
These bits identify the interrupt source:
id2 | id1 | id0 | Priority | Interrupt source |
0 | 0 | 0 | 4th | Modem status changed (DCD, RI, DSR, CTS, etc.) |
0 | 0 | 1 | 3rd | THR or transmit FIFO empty |
0 | 1 | 0 | 2nd | RBR or receive FIFO full |
0 | 1 | 1 | 1st | Line status changed (BI, FE, PE, or OE) |
1 | 0 | 0 | - | - |
1 | 0 | 1 | - | - |
1 | 1 | 0 | 2nd | (16550+ only) Receive FIFO timeout |
1 | 1 | 1 | - | - |
|
b0 |
nint |
This bit =0 if the chip is currently signalling an interrupt.
This bit is ACTIVE LOW. |
Register 2: FIFO Control Register (FCR; write-only; 16550+)
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
trig1 | trig0 | 0 | 0 | dma | rtf | rrf | fe |
b7-b6 |
trig1-trig0 |
Receiver FIFO interrupt trigger level:
| Receive FIFO size (bytes) |
trig1 | trig0 | 16550 | 16650 | 16750 |
0 | 0 | 1 | 8 | 1 |
0 | 1 | 4 | 16 | 16 |
1 | 0 | 8 | 24 | 32 |
1 | 1 | 14 | 28 | 56 |
|
b3 |
dma |
? |
b2 |
rtf |
Reset Transmit FIFO. The transmitter shift register is not affected.
This bit is self-clearing. |
b1 |
rrf |
Reset Receive FIFO. The receiver shift register is not affected.
This bit is self-clearing. |
b0 |
fe |
Enable FIFOs. Setting or clearing this bit clears the FIFOs.
b7-b1 will not be written unless b0=1 |
Register 2: Enhanced FIFO control Register (EFR; write-only; 16650+)
?
Register 3: Line Control Register (LCR)
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
DLAB | BREAK | STICK | EPS | PEN | STB | WLS1 | WLS0 |
b7 |
DLAB |
Divisor Latch Access Bit. Enables access to bit rate divisor latch
in registers 0 and 1 |
b6 |
BREAK |
Setting this bit causes the serial output to send a continuous 'space'
condition |
b5 |
STICK |
Stick parity |
b4 |
EPS |
Even Parity Select |
b3 |
PEN |
Parity ENable:
STICK | EPS | PEN | Parity |
- | - | 0 | None |
0 | 0 | 1 | Odd |
0 | 1 | 1 | Even |
1 | 0 | 1 | Stuck-at-1 (mark parity) |
1 | 1 | 1 | Stuck-at-0 (space parity) |
|
b2 |
STB |
number of STop Bits |
b1-b0 |
WLS1-WLS0 |
Word Length Select:
STB | WLS1 | WLS0 | Data bits | Stop bits |
0 | 0 | 0 | 5 | 1 |
0 | 0 | 1 | 6 | 1 |
0 | 1 | 0 | 7 | 1 |
0 | 1 | 1 | 8 | 1 |
1 | 0 | 0 | 5 | 1.5 |
1 | 0 | 1 | 6 | 2 |
1 | 1 | 0 | 7 | 2 |
1 | 1 | 1 | 8 | 2 |
|
Parity is an optional extra bit sent with each data byte. It lets
the receiver detect single-bit transmission errors.
Register 4: Modem Control Register (MCR)
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
clkx4 | iren | it/fc | LOOP | Out2 | Out1 | RTS | DTR |
b7 |
clkx4 |
[16750 only] Enables x4 clock (?) |
b6 |
iren |
[16650 only] IR enable (?) |
b5 |
it/fc |
[16650 only] Interrupt type select (?)
[16750 only] Flow control enable (?) |
b4 |
LOOP |
Loopback. Serial chip signals are disconnected from the outside world
and internally looped back as shown here:
DTR ---> DSR
RTS ---> CTS
OUT1 ---> RI
OUT2 ---> DCD
Tx ---> Rx
In some serial chips, loopback is not supported at all.
In other chips, the handshaking lines are looped back as shown,
but there is no Tx --> Rx loopback. |
b3 |
Out2 |
User-defined output bit. For most serial ports, this bit must be
set to enable interrupts from the chip. |
b2 |
Out1 |
User-defined output bit. |
b1 |
RTS |
Ready To Send handshaking output. |
b0 |
DTR |
Data Terminal Ready handshaking output. |
Register 5 (read-only): Line Status Register (LSR)
Reading this register clears the Line Status Interrupt.
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
rfe | TEMT | THRE | BI | FE | PE | OE | DR |
b7 |
rfe |
[16550+] Receive FIFO error. Indicates that at least one byte in the
receive FIFO contains a parity error, framing error, or BREAK. If the
FIFOs are disabled or the chip has no FIFOs, this bit =0 |
b6 |
TEMT |
Transmitter Empty. Indicates that the THR, FIFO, and transmit shift
register are all empty. This bit does not generate an interrupt.
If you want to use stick parity to transmit 9-bit values, you can't
change the stick parity value until the transmitter is empty, so you
must poll this bit. You must also disable the FIFOs to send 9-bit
values. |
b5 |
THRE |
Transmitter Holding Register Empty. Set when transmitter is ready
to accept a new character. |
b4 |
BI |
Break Indication. This bit is set if a BREAK is received. BREAK is
a 'space' condition that lasts for at least ??? |
b3 |
FE |
Framing error (invalid stop bit) in received data. |
b2 |
PE |
Parity error in received data. |
b1 |
OE |
Overrun error. New data was received before the old data in the
Receiver Buffer Fegister or FIFO was read. |
b0 |
DR |
Data ready. This bit is set when a complete character has been
received and transferred to the Receiver Buffer Register or FIFO.
The error bits are set when the associated byte is at the top of
the FIFO. |
Register 6: Modem Status Register (MSR)
Reading this register clears the Modem Status Interrupt.
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
DCD | RI | DSR | CTS | DDCD | TERI | DDSR | DCTS |
b7 |
DCD |
Data Carrier Detect handshaking input. |
b6 |
RI |
Ring Indication handshaking input. |
b5 |
DSR |
Data Set Ready handshaking input. |
b4 |
CTS |
Clear To Send handshaking input. |
b3 |
DDCD |
Delta DCD. Set if DCD line changed state. |
b2 |
TERI |
Trailing Edge RI. |
b1 |
DDSR |
Delta DSR. Set if DSR line changed state. |
b0 |
DCTS |
Delta CTS. Set if CTS line changed state. |
Register 7: Scratch Register (SCR)
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
- | - | - | - | - | - | - | - |
You can store whatever you want in this register. It is not present,
however, in 8250 and 8250B chips.
Code snippets
Serial port demo/driver code
Simple polled serial output (good for debugging)
Links
Specs for National Semiconductor PC16550D serial chip:
http://www.national.com/pf/PC/PC16550D.html
TO DO
- info on using DMA with serial chips (b3 in FCR)
- Enhanced FIFO control Register (EFR; 16650+ chips)
- clkx4, iren, it/fc bits in reg 4 (16650/16570 chips)