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 >