Professional Documents
Culture Documents
Applying what weve learned about Linux device-drivers to the PCs serial-port controller
Projects purpose
Allow you to gain experience encountering the kinds of issues that commonly arise in crafting software to operate real hardware:
Learning the hardware devices capabilities Deciding which driver-methods to implement Accommodating your platforms interfaces Exploiting the OS kernels support-functions Devising a strategy for testing and debugging
(UART)
See our CS635 course website at: <http://cs.usfca.edu/~cruse/cs635f07> for links to the UART manufacturers documentation and to an in-depth online programming tutorial
Tx and Rx
The UART has a transmission-engine, and also a reception-engine, which are able to operate simultaneously (i.e., full-duplex) Software controls the UARTs operations by accessing several registers, using the x86 processors in and out instructions Linux provides some convenient macros that hide the x86 machine-code details
PC-to-PC communications
student workstation
student workstation
KVM cable
KVM cable
rackmount PC system
rackmount PC system
ethernet cables
Kudlick Classroom
08 04 09 05 01 10 06 02 07 03 lectern 15 16 11 17 12 18 13 19 14 20 24 21 28 25 22 29 26 23 30 27
function
...
PC with a modem
computer terminal modem
serial cable
phone wire
Serial data-transmission
The Transmitter Holding Register (8-bits) 0 1 1 0 0 0 0 1 Software outputs a byte of data to the THR The bits are immediately copied into an internal shift-register The bits are shifted out, one-at-a-time, in sync with a clock-pulse
clock
1 6
Carrier Detect Data Set Ready Rx data Request To Send Tx data Clear To Send Data Terminal Ready Ring Indicator Signal Ground
1 6
9 5
9 5
Signal functions
CD: Carrier Detect The modem asserts this signal to indicate that it successfully made its connection to a remote device RI: Ring Indicator The modem asserts this signal to indicate that the phone is ringing at the other end of its connection DSR: Data Set Ready Modem to PC DTR: Data Terminal Ready PC to Modem
8-bits (Write-only) 8-bits (Read-only) 8-bits (Read/Write) 8-bits (Read-only) 8-bits (Write-only) 8-bits (Read/Write) 8-bits (Read/Write) 8-bits (Read-only) 8-bits (Read-only) 8-bits (Read/Write)
Rate of data-transfer
The standard UART clock-frequency for PCs equals 1,843,200 cycles-per-second Each data-bit consumes 16 clock-cycles So the fastest serial bit-rate in PCs would be 1843200/16 = 115200 bits-per-second With one start bit and one stop bit, ten bits are required for each byte of data Rate is too fast for teletype terminals
Divisor Latch
The Divisor Latch may be used to slow down the UARTs rate of data-transfer Clock-frequency gets divided by the value programmed in the Divisor Latch register Older terminals often were operated at a baud rate of 300 bits-per-second (which translates into 30 characters-per-second) So Divisor-Latch was set to 0x0180
data-bit 0
16 clock-cycles
data-bit 1
16 clock-cycles
sample
Programming interface
The PC uses eight consecutive I/O-ports to access the UARTs registers
0x03F8 RxD/TxD 0x03F9 0x03FA IIR/FCR 0x03FB 0x03FC 0s03FD 0x03FE 0x03FF
IER
LCR
MCR
LSR
MSR
SCR
interrupt enable register receive buffer register and transmitter holding register (also Divisor Latch register) line control register modem control register
6
0
5
0
4
LOOP BACK
3
OUT2
2
OUT1
1
RTS
0
DTR
Legend: DTR = Data Terminal Ready (1=yes, 0=no) RTS = Request To Send (1=yes, 0=no) OUT1 = not used (except in loopback mode) OUT2 = enables the UART to issue interrupts LOOPBACK-mode (1=enabled, 0=disabled)
6
RI
5
DSR
4
CTS
3
delta DCD
2
delta RI
1
delta DSR
0
delta CTS
set if the corresponding bit has changed since the last time this register was read
Legend: [---- loopback-mode ----] CTS = Clear To Send (1=yes, 0=no) [bit 0 in Modem Control] DSR = Data Set Ready (1=yes, 0=no) [bit 1 in Modem Control] RI = Ring Indicator (1=yes,0=no) [bit 2 in Modem Control] DCD = Data Carrier Detected (1=yes,0=no) [bit 3 in Modem Control]
4
Break interrupt
3
Framing error
2
Parity error
1
Overrun error
0
Received Data Ready
These status-bits indicate errors in the received data This status-bit indicates that the data-transmission has been completed
This status-bit indicates that the Transmitter Holding Register is ready to accept a new data byte
This status-bit indicates that a new byte of data has arrived (or, in FIFO-mode, that the receiver-FIFO has reached its threshold)
6
set break
5
stick parity
4
even parity select
3
parity enable
2
number of stop bits
0 = normal 1 = break
0 = not accessible 1 = assessible
0 = 1 stop bit 1 = 2 stop bits 0 = no parity bits 1 = one parity bit 1 = even parity 0 = odd parity
6
0
5
0
4
0
3
Modem Status change
2
Rx Line Status change
1
THR is empty
0
Received data is available
If enabled (by setting the bit to 1), the UART will generate an interrupt: (bit 3) whenever modem status changes (bit 2) whenever a receive-error is detected (bit 1) whenever the transmit-buffer is empty (bit 0) whenever the receive-buffer is nonempty Also, in FIFO mode, a timeout interrupt will be generated if neither FIFO has been serviced for at least four character-clock times
4
reserved
3
DMA Mode select
2
XMIT FIFO reset
1
RCVR FIFO reset
0
FIFO enable
Writing 1 empties the FIFO, writing 0 has no effect Writing 0 will disable the UARTs FIFO-mode, writing 1 will enable FIFO-mode
4
0
highest 011 = receiver line-status 010 = received data ready 100 = character timeout 001 = Tx Holding Reg empty 000 = modem-status change lowest
Responding to interrupts
You need to clear a reported interrupt by taking some action -- depending on which condition was the cause of the interrupt:
Line-Status: read the Line Status Register Rx Data Ready: read Receiver Data Register Timeout: read from Receiver Data Register THRE: read Interrupt Identification Register or write to Transmitter Data Register (or both) Modem-Status: read Modem Status Register
Usage flexibility
A UART can be programmed to operate in polled mode or in interrupt-driven mode While Polled Mode is simple to program (as we shall show on the following slides), it does not make efficient use of the CPU in situations that require multitasking (as the CPU is kept busy doing polling of the UARTs status instead of useful work
NO
Transmit Holding Register is Empty? YES Write byte to the Transmitter Data Register
DONE
NO
Received Data is Ready? YES Read byte from the Receiver Data Register
DONE
Clear the Divisor Latch Access Bit and specify the desired data-format in the Line Control Register Set the Loopback bit in the Modem Control Register DONE
In-class experiments
For learning purposes, we can write userprograms that are able to execute in and out instructions, and so control the UART But to avoid the CPUs normal segfaults we will have to acquire I/O privileges The iopl3 command (created by our CS System Administrator Alex Fedosov) will establish the permissions which we need
Experiment #1
Download and run our testuart.cpp demo It uses the UARTs loopback test mode to receive each character that it transmits
UART loopback mode TxShiftReg TxData
RxShiftReg
RxData
Experiment #2
Download and run our uartecho.cpp app (it does nothing untill you do the next step) Modify the testuart.cpp demo-program by commenting out the instruction that places the UART into loopback mode Execute those two programs on a pair of PCs that are connected by a null-modem
Experiment #3
Add a pair of counters to testuart.cpp:
Declare two integer variables (initialized to 0)
int txwait = 0, rxwait = 0;
Experiment #4
Modify the testuart.cpp demo-program to experiment with using a different baud rate and a different data-format For example, use 300 baud and 7-N-2:
output 0x0180 to the Divisor Latch register output 0x06 to the Line Control register
Then, to better observe the effect, add the statement fflush( stdout ); in the program loop immediately after printf( %c, data);