Hi folks!
After experiencing some difficulties with programming the serial interface
(not standard stuff. that should be explained sufficient in the Serial
HOWTO and the Serial Programming HOWTO.)
and to take into account the growing importance of home automation with
its 'unusual' interfaces, I thought it is now necessary to describe UART
hardware in a small HOWTO-manual.
I have attached a proposal. Any comments are highly appreciated!
Think of I'm not a native english speaker :-)
Michael
The Linux Serial Hardware HOWTO
By Michael Harig <[EMAIL PROTECTED]>
January 2000
Version 0.01 No flames please :-)
TODO:
- less references to Serial Programming HOWTO
means: more programming related stuff here
(or including this in the SP HOWTO?)
- add some nice pictures
- the chapter: RS485 through RS232
- describe asynchronous comm
This document describes some common serial (RS232) hardware.
1. Introduction
This HOWTO attempts to explain serial communication hardware and, very short,
how to access it. See Serial-HOWTO and Serial-Programming-HOWTO for more
details.
blablabla
2. Asynchronous communication
to be written
3. RS232
3.1 RS232 physical
EIA (Electronic Industries Association) RS232 is a system independent standard,
controlling the physical sizes of
plugs, the number of pins and the electrical parameters for an asynchronous
serial communication. It was split by the CCITT (Comite Consultatif
International Telegraphic et Telefonique) into the norms V.24 and V.28.
It describes about 20 lines, but only 9 lines have to be implemented to agree
with RS232:
Name Short Pin(9) Pin(25)
Ground GND 5 7
Transmitted Data TxD 3 2
Received Data RxD 2 3
These are necessary for a primitive full-duplex communication. The following 4
lines enable handshaking between DTE (Data Terminal Equipment, e.g. PC) and
DCE (Data Communication Equipment, e.g. Modem):
Request to send RTS 7 4
Clear to send CTS 8 5
Data set ready DSR 6 6
Data terminal ready DTR 4 20
The next 2 lines make it possible to detect incoming 'calls' and to signal that
the partner DCE is a modem.
Ring indicator RI 9 22
Received Line Signal
Detector (Carrier Detect) RLSD (CD) 1 8
3.2 RS232 hardware handshaking
DTE wants to send data:
1. DTE sets DTR high to signal 'ready for transmitting/receiving'.
2. DCE then sets DSR high.
Both lines have to rest high during communication.
3. DTE sets RTS high.
4. DCE then sets CTS high, if ready. Now DTE may send bytes as long as CTS
remains high. If CTS drops, DTE has to suspend transmitting 'til CTS is
again high.
5. DTE sets RTS low to signal end of transmitting.
6. DCE drops CTS.
DCE wants to send data:
1. DCE checks if DTR is high
2. DCE sends all data it gets or generates!
You see, DTE is responsible for the handshaking!
4. Uuups. Chapter 4 vanished.
5. Universal Asynchronous Receiver Transmitter (UART)
To convert the bytes to/from serial signals (and doing some other stuff) there
is one chip, the UART, in a PC original the INS8250, later the NS16450 (since
AT) and its successors, the 16550, 16550A, 16650 etc.
It has 10 8 Bit registers accessible by software (but not all from linux user
space!), and a few with internal-only access, like the Receiver Shift Register
(RSR) and the Transmitter Shift Register (TSR).
Scheme of 8250 UART hardware:
First try:
IRQ line
^
|
------------------------|--------------------------------
| | |
| Receiver | Receiver |
<---- Buffer <--------|-------------- Shift <---------- RxD
| Register - | �> Register | (from DCE)
| \ | | |
| Interrupt ------\ | | |
----> Enable | v | | |
| Register / Interrupt �> Receive |
| / ->Logic Logic |
| Line <- / | ^ ^^ ^ |
<---- Status ---- | | || | |
| Register <- | | || | |
| \ | | || | |
| Interrupt | / | || | |
<---- ID <----- | || | |
| Register | | || | |
| | | || | |
| Divisor | | / | | |
DTE ----> Latch -------------------------- | | |
| Register | | | | |
| | | | | |
| Line | | / | |
----> Control --------------------------- | |
| Register | | | |
| | / | |
| Modem ---------- | |
----> Control ----------------------------------------------> RTS
| Register ----------------------------------------------> DTR
| | | |
| Modem | | | RSLD,
<---- Status <---------------------------------------------- CTS,DSR,
| Register | | | RI
| | v |
| Transmitter | Transmitter |
----> Holding ------------------------- Shift -------> TxD
| Register Register | (to DCE)
| |
---------------------------------------------------------
(this is definitely ugly. next version will be latex. :-)
5.1 Byte flow
The RSR is directly connected to RxD and, accordingly, the TSR is connected to
TxD.
Incoming bits get collected in RSR till the byte is full, then, after error
checking, the RSR is reached to the Receiver Buffer Register (RBR), where it
may be read by software.
In the other direction, a byte is written to the Transmitter Holding Register
(THR), and then reached to the TSR, where it is send bit for bit over TxD.
5.2 FIFO buffering
You did see in chapter 3.2 that the DTE has no way to control receive speed,
except by turning down the baudrate.
...<16 byte input and 16 byte output buffer>
5.3 User space accessible registers
May be accessed by ioctl-calls or tc*-calls. See Serial-Programming-HOWTO and
the man-pages to tcsetattr, ioctl & ioctl_list for more details.
5.3.1 Line control register (LCR) and line status register (LSR)
These control the communication between two UART's.
LCR:
bit 0&1: length of word: 00=5; 01=6; 10=7; 11=8 bit
bit 2: stop-bits: 0=1; 1=1.5 bit if word-length=5; else 2 bit
bit 3: parity check: 1=on
bit 4: 0=odd parity; 1=even parity
bit 5: 0=no constant parity; 1=parity bit is always 0 or 1,
0 if bit 4=1, otherwise 1
bit 6: 1=spacing condition; set TxD durable (til bit 6=0) to logical 0
bit 7: determines register access (some registers have same port
address): 0=THR,RBR,IER;1=DLL,DLM (depends on port)
LSR:
bit 0: 1=a byte waits in RBR
bit 1: 1=overrun error. a new byte has been transmitted to RBR before
the old one has been read out.
bit 2: 1=parity error while receiving last byte
bit 3: 1=framing error while receiving last byte
bit 4: 1=partner switched to spacing condition
bit 5: 0=THR has 1 byte; 1=THR is empty
bit 6: 0=TSR has 1 byte; 1=TSR is empty (see section 6!)
bit 7: unused
The role of LCR will get clear if you read the Serial-Programming-HOWTO.
Spacing condition is used to alert partner that some data is lost or corrupted
and must be resend.
LSR may be read this way:
int aLSR;
ioctl(fd,TIOCSERGETLSR,&aLSR);
See section 6 for a possible use.
5.3.2 Modem status register (MSR) and modem control register (MCR)
MSR and MCR control communication between UART and modem.
MCR:
bit 0: 0=set DTR to 1; 1=set DTR to 0
bit 1: 0=set RTS to 1; 1=set RTS to 0
bit 2: unused
bit 3: 0=UART generates no interrupt (->polling);1=(guess it :-)
bit 4: 1=loopback: THR goes directly to RBR; for testing without
attached device
bit 5-7: unused; always 0
MSR:
bit 0: 1=change on CTS since last read-out of MSR
bit 1: 1=change on DSR ...
bit 2: 1=change on RI ...
bit 3: 1=change on RLSD (CD) ...
bit 4: 1=CTS high
bit 5: 1=DSR high
bit 6: 1=RI high
bit 7: 1=carrier detect (RLSD high)
< mostly self-explanatory with Serial-Programming-HOWTO. few words about
interrupt/polling. explanation of what linux kernel does.>
6. RS485 via RS232
< my experiences + code >