Serial Ports: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
mNo edit summary
m Bot: Replace main article with main template
 
(15 intermediate revisions by 7 users not shown)
Line 39:
The addresses for COM ports can vary depending on how they are connected to the machine and how the BIOS is configured. Some BIOS configuration utilities allow you to see and set what these are, so if you in doubt for a test machine, this might be a good place to look to get you started.
 
For the most part, the first two COM ports will be at the addresses specified, the addresses for further COM ports isare less reliable.
{| {{wikitable}}
! COM Port
Line 51:
|-
| COM4 || 0x2E8
|-
| COM5 || 0x5F8
|-
| COM6 || 0x4F8
|-
| COM7 || 0x5E8
|-
| COM8 || 0x4E8
|}
 
Line 60 ⟶ 68:
! IO Port Offset
! Setting of DLAB
! I/O Access
! Register mapped to this port
|-
| +0 || 0 || DataRead register. Reading this registers read from the|| Receive buffer. Writing to this register writes to the Transmit buffer.
|-
| +10 || 0 || InterruptWrite || EnableTransmit Registerbuffer.
|-
| +1 || 0 || Read/Write || Interrupt Enable Register.
| +0 || 1 || With DLAB set to 1, this is the least significant byte of the divisor value for setting the baud rate.
|-
| +10 || 1 || Read/Write || With DLAB set to 1, this is the mostleast significant byte of the divisor value for setting the baud rate.
|-
| +1 || 1 || Read/Write || With DLAB set to 1, this is the most significant byte of the divisor value.
| +2 || - || Interrupt Identification and FIFO control registers
|-
| +2 || - || Read || Interrupt Identification
| +3 || - || Line Control Register. The most significant bit of this register is the DLAB.
|-
| +42 || - || ModemWrite Control|| FIFO control Register.registers
|-
| +53 || - || Read/Write || Line StatusControl Register. The most significant bit of this register is the DLAB.
|-
| +64 || - || Read/Write || Modem StatusControl Register.
|-
| +75 || - || ScratchRead || Line Status Register.
|-
| +6 || - || Read || Modem Status Register.
|-
| +7 || - || Read/Write || Scratch Register.
|}
 
Line 100 ⟶ 113:
# Send the most significant byte of the divisor value to [PORT + 1].
# Clear the most significant bit of the Line Control Register.
 
====Line Control Register====
The Line Control register sets the general connection parameters.
 
{| class="wikitable"
|-
! Bit 7
! Bit 6
! Bits 5-3
! Bit 2
! Bits 1-0
|-
| Divisor Latch Access Bit
| Break Enable Bit
| Parity Bits
| Stop Bits
| Data Bits
|}
 
====Data Bits====
Line 119 ⟶ 150:
|}
 
====Stop bitsBits====
The serial controller can be configured to send a number of bits after each character of data. These reliable bits can be used to by the controller to verify that the sending and receiving devices are in phase.
 
Line 135 ⟶ 166:
|}
 
====Parity Bits====
The controller can be made to add or expect a parity bit at the end of each character of data transmitted. With this parity bit, if a single bit of data is inverted by interference, a parity error can be raised. The parity type can be NONE, EVEN, ODD, MARK or SPACE.
 
Line 145 ⟶ 176:
 
To set the port parity, set bits 3, 4 and 5 of the Line Control Register [PORT + 3].
 
{| {{wikitable}}
! Bit 5
Line 166 ⟶ 196:
To communicate with a serial port in interrupt mode, the interrupt-enable-register (see table above) must be set correctly. To determine which interrupts should be enabled, a value with the following bits (0 = disabled, 1 = enabled) must be written to the interrupt-enable-register:
{| {{wikitable}}
! Bit 7-4
! Bit 3
! Bit 2
! Bit 1
! Bit 0
|-
| Reserved
| Modem Status
| Receiver Line Status
| Transmitter Holding Register Empty
| Received Data Available
|}
 
===First In First Out Control Register===
The First In / First Out Control Register (FCR) is for controlling the FIFO buffers. Access this register by writing to port offset +2.
{| class="wikitable"
|-
! Bits 7-6
! Bits 5-4
! Bit 3
! Bit 2
! Bit 1
! Bit 0
|-
| Interrupt Trigger Level
| Reserved
| DMA Mode Select
| Clear Transmit FIFO
| Clear Receive FIFO
| Enable FIFO's
|}
 
====Clear Transmit FIFO and Clear Receive FIFO====
Bit 2 being set clears the Transmit FIFO buffer while Bit 1 being set clears the Receive FIFO buffer. Both bits will set themselves back to 0 after they are done being cleared.
 
====Interrupt Trigger Level====
The Interrupt Trigger Level is used to configure how much data must be received in the FIFO Receive buffer before triggering a Received Data Available Interrupt.
{| {{wikitable}}
! Bit 7
! Bit 6
! Trigger Level
|-
| 0 || 0 || 1 Byte
|-
| 0 || 1 || 4 Bytes
|-
| 1 || 0 || 8 Bytes
|-
| 1 || 1 || 14 Bytes
|}
 
===Interrupt Identification Register===
The Interrupt Identification Register (IIR) is for identifying pending interrupts. Access this register by reading from port offset +2.
{| class="wikitable"
|-
! Bits 7-6
! Bits 5-4
! Bit 3
! Bit 2-1
! Bit 0
|-
| FIFO Buffer State
| Reserved
| Timeout Interrupt Pending (UART 16550) or Reserved
| Interrupt State
| Interrupt Pending
|}
 
====Interrupt State====
After Interrupt Pending is set, the Interrupt State shows the interrupt that has occurred. They have varying levels of priority, with high-value interrupts handled first, and low-value interrupts being handled last.
{| {{wikitable}}
! Bit 2
! Bit 1
! Interrupt
! Priority
|-
| 0 || 0 || Modem Status || 4 (Lowest)
| 0 || Data available
|-
| 0 || 1 || Transmitter emptyHolding Register Empty || 3
|-
| 1 || 0 || Received Data Available || 2
| 2 || Break/error
|-
| 31 || 1 || Receiver Line Status change|| 1 (Highest)
|}
 
====FIFO Buffer State====
{| {{wikitable}}
! Bit 7
! Bit 6
! State
|-
| 4-70 || Unused0 || No FIFO
|-
| 0 || 1 || FIFO Enabled but Unusable
|-
| 1 || 0 || FIFO Enabled
|}
 
===LineModem statusControl registerRegister===
The Modem Control Register is one half of the hardware handshaking registers.
While most serial devices no longer use hardware handshaking, The lines are still included in all 16550 compatible UARTS.
These can be used as general purpose output ports, or to actually perform handshaking.
By writing to the Modem Control Register, it will set those lines active.
{| {{wikitable}}
! Bit
! Name
! Meaning
|-
| 0 || Data Terminal Ready (DTR) || Controls the Data Terminal Ready Pin
|-
| 1 || Request to Send (RTS) || Controls the Request to Send Pin
|-
| 2 || Out 1 || Controls a hardware pin (OUT1) which is unused in PC implementations
|-
| 3 || Out 2 || Controls a hardware pin (OUT2) which is used to enable the IRQ in PC implementations
|-
| 4 || Loop || Provides a local loopback feature for diagnostic testing of the UART
|-
| 5 || 0 || Unused
|-
| 6 || 0 || Unused
|-
| 7 || 0 || Unused
|}
 
Most PC serial ports use OUT2 to control a circuit that disconnects (tristates) the IRQ line. This makes it possible for multiple serial ports to share a single IRQ line, as long as only one port is enabled at a time.
Loopback mode is a diagnostic feature. When bit 4 is set to logic 1,
the following occur the transmitter Serial Output (SOUT) is set to the Marking (logic 1) state; the receiver Serial
Input (SIN) is disconnected; the output of the Transmitter Shift Register is ‘‘looped back’’ into the Receiver Shift
Register input; the four MODEM Control inputs (DSR, CTS, RI, and DCD) are disconnected; and the four
MODEM Control outputs (DTR, RTS, OUT 1, and OUT 2) are internally connected to the four MODEM Control
inputs, and the MODEM Control output pins are forced to their inactive state (high). In the loopback mode, data
that is transmitted is immediately received. This feature allows the processor to verify the transmit-and received-
data paths of the UART. In the loopback mode, the receiver and transmitter interrupts are fully operational. Their sources are external to
the part. The MODEM Control Interrupts are also operational, but the interrupts’ sources are now the lower four
bits of the MODEM Control Register instead of the four MODEM Control inputs. The interrupts are still controlled
by the Interrupt Enable Register.
 
===Line Status Register===
The line status register is useful to check for errors and enable polling.
{| {{wikitable}}
Line 203 ⟶ 357:
| 7 || Impending Error || Set if there is an error with a word in the input buffer
|}
 
===Modem Status Register===
This register provides the current state of the control lines from a peripheral device.
In addition to this current-state information, four bits of the MODEM Status Register provide change information.
These bits are set to a logic 1 whenever a control input from the MODEM changes state. They are reset to logic
0 whenever the CPU reads the MODEM Status Register
{| {{wikitable}}
! Bit
! Name
! Meaning
|-
| 0 || Delta Clear to Send (DCTS) || Indicates that CTS input has changed state since the last time it was read
|-
| 1 || Delta Data Set Ready (DDSR) || Indicates that DSR input has changed state since the last time it was read
|-
| 2 || Trailing Edge of Ring Indicator (TERI) || Indicates that RI input to the chip has changed from a low to a high state
|-
| 3 || Delta Data Carrier Detect (DDCD) || Indicates that DCD input has changed state since the last time it ware read
|-
| 4 || Clear to Send (CTS) || Inverted CTS Signal
|-
| 5 || Data Set Ready (DSR) || Inverted DSR Signal
|-
| 6 || Ring Indicator (RI) || Inverted RI Signal
|-
| 7 || Data Carrier Detect (DCD) || Inverted DCD Signal
|}
 
If Bit 4 of the MCR (LOOP bit) is set, the upper 4 bits will mirror the 4 status output lines set in the Modem Control Register.
 
===Terminals===
:''{{Main article: [[|Terminals]]}}
 
Once you can send and receive bytes with confidence, you probably want to connect the serial port to a terminal (or more likely a terminal emulator these days). Those send specific byte sequences when a key is pressed, and can interpret codes to move the cursor on the screen and change color for example.
Line 212 ⟶ 395:
==Example Code==
===Initialization===
<sourcesyntaxhighlight lang="C">
#define PORT 0x3f8 // COM1
 
Line 236 ⟶ 419:
return 0;
}
</syntaxhighlight>
</source>
 
Notice that the initialization code above writes to [PORT + 1] twice with different values. This is once to write to the Divisor register along with [PORT + 0] and once to write to the Interrupt register as detailed in the previous section. The second write to the Line Control register [PORT + 3] clears the DLAB again as well as setting various other bits.
 
===Receiving data===
<sourcesyntaxhighlight lang="C">
int serial_received() {
return inb(PORT + 5) & 1;
Line 251 ⟶ 434:
return inb(PORT);
}
</syntaxhighlight>
</source>
 
===Sending data===
 
<sourcesyntaxhighlight lang="C">
int is_transmit_empty() {
return inb(PORT + 5) & 0x20;
Line 265 ⟶ 448:
outb(PORT,a);
}
</syntaxhighlight>
</source>
 
==Glossary==
 
;Baud Rate
:is theThe speed at which the serial line switches between it's two states. This is not equivalent to bps, due to the fact there are start and stop bits. On an 8/N/1 line, 10 baud = 1 byte. Modems are more complex than plain serial lines due to having multiple waveforms, but for the purposes of OSDev this is irrelevant.
:The fastest baud rate a serial port can reliably run at is generally 115200 baud.
;baud rate divisor
;Baud Rate Divisor
:fastest rate a serial port can run, the number 115200.
:The value the is used by the UART to divide its internal clock by in order to get the actual intended baud rate.
;stop bits
;Stop Bits
:the NULL bit(s) sent between each character to synchronize the transmitter and the receiver.
:The NULL bit(s) sent between each character to synchronize the transmitter and the receiver.
;UART
:forFor Universal Asynchronous Receiver/Transceiver: the chip that picks a byte a send it bit per bit on the serial line and vice versa.
 
== Related Links ==