Dr A Sahu Dept of Comp Sc & Engg. IIT Guwahati. I/O Port Addressing UART Port Basic – 16500 Standardized UART UART Programming in C Loop back program.

Slides:



Advertisements
Similar presentations
Serial Interface Dr. Esam Al_Qaralleh CE Department
Advertisements

INPUT-OUTPUT ORGANIZATION
Serial Communications Interface (SCI) Michael LennardZachary PetersBao Nguyen.
11-1 ECE 424 Design of Microprocessor-Based Systems Haibo Wang ECE Department Southern Illinois University Carbondale, IL I/O System Design.
1 Homework Reading (linked from my web page) –S and S Extracts –National Semiconductor UART Data Sheet Machine Projects –mp2 due at start of class 12 Labs.
Design of Microprocessor-Based Systems Dr. Esam Al_Qaralleh CE Department Princess Sumaya University for Technology I/O System Design.
SCI: Serial Communications Interface Presented by: Sean Kline Chad Smith Jamie Cruce.
Interfacing The Serial/RS-232 Port Hardware Serial Port Registers Programming.
Serial I/O - Programmable Communication Interface
Hierarchy of I/O Control Devices
Using x86 “protected mode” on our anchor-cluster’s machines A look at some terminal emulation features utilized in the “console- redirection” mechanism.
On using ‘tasklets’ An example of the Linux kernel’s ‘tasklet’ mechanism for deferring some interrupt-handling work.
Interrupts What is an interrupt? What does an interrupt do to the “flow of control” Interrupts used to overlap computation & I/O – Examples would be console.
Asynchronous Communication Hardware  Data within a DTE is usually stored and moved in a parallel fashion.  Data sent across the channel is generally.
Implementing interrupt driven IO. Why use interrupt driven IO? Positive points –Allows asynchronous operation of IO events –Good use of resources –Leads.
Testing Communication Systems  When point-to-point communication between two DTEs is not functioning, which DTE is at fault? Or which DTE is correctly.
Serial Input/Output Interface Outline –Serial I/O –Asynchronous serial I/O –6850 ACIA –68681 DUART –Synchronous serial I/OInterface Standards –68000 Serial.
Handling a UART interrupt A look at some recent changes in the Linux kernel’s programming interface for device-interrupts.
The UART alternative Substituting input from our PC’s serial-port for local keystrokes when we do ‘single-stepping’
The UART project Applying what we’ve learned about Linux device-drivers to the PC’s serial-port controller.
PC Modem Control The 8250 UART supplied with the PC supports a limited number of RS-232-C modem functions: The UART can be programmed to interrupt the.
USART and Asynchrono us Communica tion The USART is used for synchronous and asynchronous serial communication. USART = Universal Synchronous/Asynchronous.
Computer Science 686 Spring 2007 Special Topic: Intel EM64T and VT Extensions.
7-1 Digital Serial Input/Output Two basic approaches  Synchronous shared common clock signal all devices synchronised with the shared clock signal data.
1 The 9-Pin Connector Pin abbreviations (numbers in parentheses are the 25D pin numbers): 1. CD (8) 2. RD (Rx) (3) 3. TD (Tx) (2) 4. DTR (20) 5. SG (Ground)
ECE 371- Unit 11 Introduction to Serial I/O. TWO MAJOR CLASSES OF SERIAL DATA INTERFACES ASYNCHRONOUS SERIAL I/O - USES “FRAMING BITS” (START BIT AND.
INTERRUPTS PROGRAMMING
INPUT-OUTPUT ORGANIZATION
University of Tehran 1 Interface Design Serial Communications Omid Fatemi.
Serial Peripheral Interface Module MTT M SERIAL PERIPHERAL INTERFACE (SPI)
Serial Port I/O Serial port sends and receives data one bit at a time. Serial communication devices are divided into: Data Communications Equipment (DCE),
SC200x Peripherals Broadband Entertainment Division DTV Source Applications July 2001.
UART and UART Driver B. Ramamurthy.
Lecture 7 Universal Asynchronous Receiver/Transmitter (UART) NCHUEE 720A Lab Prof. Jichiang Tsai.
Lecture Set 9 MCS-51 Serial Port.
Universal Synchronous/Asynchronous Receiver/Transmitter (USART)
Universal Asynchronous Receiver/Transmitter (UART)
Microprocessors 2 lesson Subjects lesson 7 Planning Interrupts Serial communication /USART Questions.
CHAPTER SERIAL PORT PROGRAMMING. Basics of Serial Communication Computers transfer data in two ways: ◦ Parallel  Often 8 or more lines (wire conductors)
Serial Communications
Scott Baker Will Cross Belinda Frieri March 9 th, 2005 Serial Communication Overview ME4447/6405.
Advanced Microprocessor1 I/O Interface Programmable Interval Timer: 8254 Three independent 16-bit programmable counters (timers). Each capable in counting.
 8251A is a USART (Universal Synchronous Asynchronous Receiver Transmitter) for serial data communication.  Programmable peripheral designed for synchronous.
NS Training Hardware. Serial Controller - UART.
Universal Asynchronous Receiver/Transmitter (UART)
Programming the I/O Hardware Reference: –textbook: Tanenbaum ch.5.1 – s.htmlwww.cs.umb.edu/ulab/UsingCforHardwareReg.
1 October 26, 2006ME 6405 MechatronicsSerial Communication Interface Brian Guerriero Jon Rogers Robert Thiets.
Serial Communications Interface Module Slide #1 of 19 MC68HC908GP20 Training PURPOSE -To explain how to configure and use the Serial Communications Interface.
Example 1 Program the divisor Latch for 300 baud. Assume Xin=1.8432MHz The Base Address: 0x3F8 0RX_TX / Divisor.low 1IER: Interrupt Enable Reg. / Divisor.high.
Communicating. The ATmega16 communicates through one of the following ways: Serial Peripheral Interface (SPI) Universal Synchronous and Asynchronous serial.
CE-2810 Dr. Mark L. Hornick 1 Serial Communications Sending and receiving data between devices.
8251 USART.
DEPARTMENT OF ELECTRONICS ENGINEERING
INDEX Introduction System Control Block Vectored Interrupt Controller (VIC) GPIO UART Timers.
Transmitter Interrupts Review of Receiver Interrupts How to Handle Transmitter Interrupts? Critical Regions Text: Tanenbaum
Tiva C TM4C123GH6PM UART Embedded Systems ECE 4437 Fall 2015 Team 2:
Lecture 15. Modem Controller Register 4310 DTR 0 = Polling Operator 1 = Interrupts Enabled RTS 1 =Self Test 0 =Normal.
Serial mode of data transfer
RS-232 Communications.
CS-401 Computer Architecture & Assembly Language Programming
Homework Reading (linked from my web page) Machine Projects Labs
RS-232 Communications.
E3165 DIGITAL ELECTRONIC SYSTEM
UART Serial Port Programming
Serial Communication Interface: Using 8251
Serial Communication Interface
NS Training Hardware.
Transmitter Interrupts
UART PC16550 (Universal Asynchronous Receiver/Transmitter) By Derwyn Hollobaugh
CHAPTER SERIAL PORT PROGRAMMING. Basics of Serial Communication Computers transfer data in two ways: ◦ Parallel  Often 8 or more lines (wire.
Presentation transcript:

Dr A Sahu Dept of Comp Sc & Engg. IIT Guwahati

I/O Port Addressing UART Port Basic – Standardized UART UART Programming in C Loop back program

Standardized Use command – $ cat /proc/ioports : 0000:00: : pata_atiixp 01f0-01f7 : 0000:00: f0-01f7 : pata_atiixp f : pnp 00: : pnp 00: : pnp 00: : pnp 00: : pnp 00:09 02f8-02ff : serial : 0000:00: : pata_atiixp 01f0-01f7 : 0000:00: f0-01f7 : pata_atiixp f : pnp 00: : pnp 00: : pnp 00: : pnp 00: : pnp 00:09 02f8-02ff : serial f : dma : pic : timer : timer : keyboard : keyboard : rtc f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu f : dma : pic : timer : timer : keyboard : keyboard : rtc f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu : 0000:00: : pata_atiixp a : parport : pnp 00:09 03c0-03df : vga+ 03f6-03f6 : 0000:00: f6-03f6 : pata_atiixp 03f8-03ff : serial 040b-040b : pnp 00:09 04d0-04d1 : pnp 00: : 0000:00: : pata_atiixp a : parport : pnp 00:09 03c0-03df : vga+ 03f6-03f6 : 0000:00: f6-03f6 : pata_atiixp 03f8-03ff : serial 040b-040b : pnp 00:09 04d0-04d1 : pnp 00:09

IO Privilege level – Can be set by root If set user can RW to Ios Loopback user C/C++ program can access Modem/UART at address 03F8

Synchronous – Sender and receiver must synchronize Done in hardware using phase locked loops (PLLs) – Block of data can be sent – More efficient : Less overhead than asynchronous transmission – Expensive Asynchronous – Each byte is encoded for transmission Start and stop bits – No need for sender and receiver synchronization

Sender Receiver Data a a Transmission Gaps Asynchronous transmission Synchronous transmission CLK

Character oriented Each character carried start bit and stop bits When No data are being transmitted – Receiver stay at logic 1 called mark, logic 0 is Space Framing: – Transmission begins with one start bit (low/0) – Followed by DATA (8bit) and – Stop bits (1 or 2 bits of logic high)

Asynchronous transmission 8 bit Data Start BitStart Bits LSB MSB Time 1 start bit 1 or 2 Stop bit Source data

Your device-driver module (named ‘uart.c’) is intended to allow unprivileged programs that are running on a pair of adjacent PCs to communicate via a “null-modem” cable $ echo Hello > /dev/uart $ _ $ echo Hello > /dev/uart $ _ $ cat /dev/uart Hello _ $ cat /dev/uart Hello _ Receiving…Transmitting…

The UART has a transmission-engine, and also a reception-engine, which are able to operate simultaneously (i.e., “full-duplex”) Software controls the UART’s operations by accessing several registers, using the x86 processor’s ‘in’ and ‘out’ instructions Linux provides some convenient ‘macros’ that ‘hide’ the x86 machine-code details

init exit fops function... Device-driver LKM layout registers the ‘fops’ unregisters the ‘fops’ module’s ‘payload’ is a collection of callback-functions having prescribed prototypes AND a ‘package’ of function-pointers the usual pair of module-administration functions

Our System Administrator has created the device-file needed for your driver-module: root# mknod /dev/uart c 84 0 root# chmod a+w /dev/uart Your driver-module needs to ‘register’ your package of driver-methods (i.e., functions) in its initialization routine (and ‘unregister’ them later in its cleanup routine)

The Transmitter Holding Register (8-bits) The transmitter’s internal ‘shift’ register clock 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 start bit stop bit data-bits clock-pulses trigger bit-shifts

Obviously your driver-module’s ‘payload’ will have to include ‘methods’ (functions) which perform the ‘write()’ and ‘read()’ operations that applications will invoke You may decide your driver needs also to implement certain additional ‘methods’ A little history is helpful for understanding some of the UART device’s terminology

clock input voltage clock-pulses trigger voltage-sampling and bit-shifts at regular intervals The receiver’s internal ‘shift’ register start bit stop bit data-bits The Receiver Buffer Register (8-bits) Software can input the received byte from the RBR

Data Bus Buffer Data Bus Buffer Transmit Buffer Transmit Buffer Receive Buffer Receive Buffer Transmit Control Transmit Control Receive Control Receive Control R/W Control Logic R/W Control Logic Modem Control InternalLineInternalLine InternalLineInternalLine D7-D0 RESET CLK C/D b RD b WR b CS b DSR b DTR b CTS b RTS b TXD TXRDY TXE TXC RXD RXRDY RXC SYBDET/BD

Data Buffer Register Data Buffer Register D0 D7 InternalData BusInternalData Bus InternalData BusInternalData Bus Transmitter Buffer Register Transmitter Buffer Register Receiver Buffer Register Receiver Buffer Register Out put Register Out put Register Input Register Input Register Transmitter Control Logic Transmitter Control Logic Receiver Control Logic Receiver Control Logic TxD TxC b TxRDY TxE RxD RxC b RxRDY

EH IR RTS ER SBRK RxE DTR TxE TxE:transmit enable (0/1 Enable Disable) DTR:data terminal ready (1=ENABLE DTR) RxE:receiver enable (1/0=EN/DISABLE) SBPRK: send break character 1= force TxD low ER:error reset (Reset Flags: Parity,Over run, Framing Error of Status Word) RTS:request to send (1= Enable Request to send) IR:internal reset (Reset 8251 to mode) EH:enter hunt mode (1=search for Sync Character)

DSR SYN DET SYN DET FE OE PE Tx EMPTY Tx EMPTY RxRDY TxRDY TxRDYtransmit ready (DB Buffer is empty) RxRDYreceiver ready TxEMPTYtransmitter empty PEparity error (1=when PE detected) OEoverrun error FEframing error (Aynsc only, Valid stop bit not detected) SYNDETsync. character detected DSRdata set ready (DSR set at 0 level)

Transmit Data Register Received Data Register Interrupt Enable Register Interrupt Identification Register FIFO Control Register Line Control Register Modem Control Register Line Status Register Modem Status Register Scratch Pad Register Divisor Latch Register 16-bits (R/W) 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-only) 8-bits (Read/Write) Base+0 Base+1 Base+2 Base+3 Base+4 Base+5 Base+6 Base+7 Base+0

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 /16 = 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

The ‘Divisor Latch’ may be used to slow down the UART’s 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 set to 0x0180

Transmitter clock (bit-rate times 16) DATA OUT start-bit data-bit 0 data-bit 1 … receiver detects this high-to-low transition, so it waits 24 clock-cycles, then samples the data-line’s voltage every 16 clock-cycles afterward receiver detects this high-to-low transition, so it waits 24 clock-cycles, then samples the data-line’s voltage every 16 clock-cycles afterward 24 clock-cycles 16 clock-cycles Receiver clock (bit-rate times 16) sample

RxD/TxD IER IIR/FCR LCR MCR LSR MSR SCR The PC uses eight consecutive I/O-ports to access the UART’s registers 0x03F8 0x03F9 0x03FA 0x03FB 0x03FC 0s03FD 0x03FE 0x03FF scratchpad register modem status register line status register modem control register line control register interrupt enable register interrupt identification register and FIFO control register receive buffer register and transmitter holding register (also Divisor Latch register)

LOOP BACK LOOP BACK OUT2 OUT1 RTS 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) 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)

DCD RI DSR CTS delta DCD delta DCD delta RI delta RI delta DSR delta DSR delta CTS 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] 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]

Error in Rx FIFO Error in Rx FIFO TXmitter idle TXmitter idle THR empty THR empty Break interrupt Break interrupt Framing error Framing error Parity error Parity error Overrun error Overrun error Received Data Ready Received Data Ready These status-bits indicate errors in the received data This status-bit indicates that a new byte of data has arrived (or, in FIFO-mode, that the receiver-FIFO has reached its threshold) This status-bit indicates that a new byte of data has arrived (or, in FIFO-mode, that the receiver-FIFO has reached its threshold) This status-bit indicates that the data-transmission has been completed 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 the Transmitter Holding Register is ready to accept a new data byte

Divisor Latch access Divisor Latch access set break set break stick parity stick parity even parity select even parity select parity enable parity enable number of stop bits number of stop bits word length selection word length selection = 5 bits 01 = 6 bits 10 = 7 bits 11 = 8 bits 00 = 5 bits 01 = 6 bits 10 = 7 bits 11 = 8 bits 0 = 1 stop bit 1 = 2 stop bits 0 = 1 stop bit 1 = 2 stop bits 0 = no parity bits 1 = one parity bit 0 = no parity bits 1 = one parity bit 1 = even parity 0 = ‘odd’ parity 1 = even parity 0 = ‘odd’ parity 0 = not accessible 1 = assessible 0 = not accessible 1 = assessible 0 = normal 1 = ‘break’ 0 = normal 1 = ‘break’

Modem Status change Modem Status change Rx Line Status change Rx Line Status change THR is empty THR is empty Received data is available 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

RCVR FIFO trigger-level RCVR FIFO trigger-level reserved DMA Mode select DMA Mode select XMIT FIFO reset XMIT FIFO reset RCVR FIFO reset RCVR FIFO reset FIFO enable FIFO enable Writing 0 will disable the UART’s FIFO-mode, writing 1 will enable FIFO-mode Writing 1 empties the FIFO, writing 0 has no effect 00 = 1 byte 01 = 4 bytes 10 = 8 bytes 11 = 14 bytes 00 = 1 byte 01 = 4 bytes 10 = 8 bytes 11 = 14 bytes Mode: If supported DMA

= FIFO-mode has not been enabled 11 = FIFO-mode is currently enabled 00 = FIFO-mode has not been enabled 11 = FIFO-mode is currently enabled 1 = No UART interrupts are pending 0 = At least one UART interrupt is pending 1 = No UART interrupts are pending 0 = At least one UART interrupt is pending ‘highest priority’ UART Interrupt still pending highest 011 = receiver line-status 010 = received data ready 100 = character timeout 001 = Tx Holding Reg empty 000 = modem-status change lowest highest 011 = receiver line-status 010 = received data ready 100 = character timeout 001 = Tx Holding Reg empty 000 = modem-status change lowest

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

A UART can be programmed to operate in “polled” mode or in “interrupt-driven” mode While “Polled Mode” is simple to program It does not make efficient use of the CPU in situations that require ‘multitasking’ (as the CPU is kept busy doing “polling” of the UART’s status instead of useful work

Read the Line Status Register Write byte to the Transmitter Data Register Transmit Holding Register is Empty? Transmit Holding Register is Empty? NO YES DONE

Read the Line Status Register Read byte from the Receiver Data Register Received Data is Ready? Received Data is Ready? NO YES DONE

// declare the program’s variables and constants charinch, outch = ‘A’; // Transmitting a byte // wait until the Transmitter Holding Register is empty, // then output the byte to the Transmit Data Register do { } while ( (inb( LINE_STATUS) & 0x20) == 0 ); outb( outch, TRANSMIT_DATA_REGISTER ); // Receiving a byte // wait until the Received Data Ready bit becomes true, // then input a byte from the Received Data Register do { } while ( (inb( LINE_STATUS ) & 0x01 ) == 0 ); inch = inb( RECEIVED_DATA_REGISTER ); // declare the program’s variables and constants charinch, outch = ‘A’; // Transmitting a byte // wait until the Transmitter Holding Register is empty, // then output the byte to the Transmit Data Register do { } while ( (inb( LINE_STATUS) & 0x20) == 0 ); outb( outch, TRANSMIT_DATA_REGISTER ); // Receiving a byte // wait until the Received Data Ready bit becomes true, // then input a byte from the Received Data Register do { } while ( (inb( LINE_STATUS ) & 0x01 ) == 0 ); inch = inb( RECEIVED_DATA_REGISTER );

Set the Divisor Latch Access Bit in the Line Control Register Set the Divisor Latch Access Bit in the Line Control Register Write a nonzero value to the Divisor Latch Register Clear the Divisor Latch Access Bit and specify the desired data-format in the Line Control Register 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 Set the Loopback bit in the Modem Control Register DONE

IO Privilege Level Linux provides a system-call to privileged programs which need to access I/O ports The header-file prototypes it, and the ‘iopl()’ library-function invokes it The kernel will modify the CPU’s current I/O Permission Level in cpu’s EFLAGS (if the program’s owner has ‘root’ privileges) First execute our ‘iopl3’ command Use Root mode to do this

Download and run our ‘testuart.cpp’ demo It uses the UART’s ‘loopback’ test mode to ‘receive’ each character that it ‘transmits’ TxData RxData TxShiftReg RxShiftReg UART ‘loopback’ mode The external signal-lines are bypased Output loops back to become input

#define UART_PORT0x03F8// base port-address for the UART #define DIVISOR_LATCH(UART_PORT + 0) #define TX_DATA_REG(UART_PORT + 0) #define RX_DATA_REG(UART_PORT + 0) #define LINE_CONTROL(UART_PORT + 3) #define MODEM_CONTROL(UART_PORT + 4) #define LINE_STATUS(UART_PORT + 5) char msg[] = "\n\tThis is a test of the UART's loopback mode\n"; int main( int argc, char **argv ) { // set the CPU's I/O Permission-Level to allow port-access if ( iopl( 3 ) ) { perror( "iopl" ); exit(1); } #define UART_PORT0x03F8// base port-address for the UART #define DIVISOR_LATCH(UART_PORT + 0) #define TX_DATA_REG(UART_PORT + 0) #define RX_DATA_REG(UART_PORT + 0) #define LINE_CONTROL(UART_PORT + 3) #define MODEM_CONTROL(UART_PORT + 4) #define LINE_STATUS(UART_PORT + 5) char msg[] = "\n\tThis is a test of the UART's loopback mode\n"; int main( int argc, char **argv ) { // set the CPU's I/O Permission-Level to allow port-access if ( iopl( 3 ) ) { perror( "iopl" ); exit(1); }

// establish the UART's operational parameters outb( 0x80, LINE_CONTROL );// set DLAB=1 outw( 0x0001, DIVISOR_LATCH );// set baud outb( 0x03, LINE_CONTROL );// set data-format: 8-N-1 outb( 0x10, MODEM_CONTROL );// turn on 'loopback' mode // write each message-character, read it back, and display it for (int i = 0; i < sizeof( msg ); i++) { do { } while ( (inb( LINE_STATUS )&0x20) == 0x00 ); outb( msg[i], TX_DATA_REG ); do { } while ( (inb( LINE_STATUS )&0x01) == 0x00 ); intdata = inb( RX_DATA_REG ); printf( "%c", data ); } outb( 0x00, MODEM_CONTROL );// turn off 'loopback' mode printf( "\n" ); } // establish the UART's operational parameters outb( 0x80, LINE_CONTROL );// set DLAB=1 outw( 0x0001, DIVISOR_LATCH );// set baud outb( 0x03, LINE_CONTROL );// set data-format: 8-N-1 outb( 0x10, MODEM_CONTROL );// turn on 'loopback' mode // write each message-character, read it back, and display it for (int i = 0; i < sizeof( msg ); i++) { do { } while ( (inb( LINE_STATUS )&0x20) == 0x00 ); outb( msg[i], TX_DATA_REG ); do { } while ( (inb( LINE_STATUS )&0x01) == 0x00 ); intdata = inb( RX_DATA_REG ); printf( "%c", data ); } outb( 0x00, MODEM_CONTROL );// turn off 'loopback' mode printf( "\n" ); }