home *** CD-ROM | disk | FTP | other *** search
- FIFO Asynchronous Communication Test Software for NS16550/16552 UARTs
- =====================================================================
-
- National Semiconductor Corporation
- Greg DeJager February 8, 1989
-
- Adapted from LBT.C -- Loopback Test Rev 1.1
- Developed by: Brian A. Berg
- BERG SOFTWARE DESIGN
-
-
- Summary of Files
- --------------------------
-
- FACT.C C source code: main program, subroutines and interrupt handler
- SERIO.H header file containing UART definitions for C code use
- STDHDR.H header file containing "standard" definitions for C code use
- FACT.EXE executable FACT program; only this file is needed to run the FACT
-
-
- Intro, Hardware Setup and Program Operation
- ===========================================
-
- This test was developed to run on all IBM AT or AT compatible architectures
- as well as IBM PS/2 Model 30 - 80 machines. System requirements include
- two separate machines with an NS16550 or NS16552 UART located at COM1, 2 or 3
- and an RS-232 DTE to DTE interface between them. The DTE-DTE interface must
- have the following connections:
- Tx----------------------------Rx
- Rx----------------------------Tx
- RTS--------------------------CTS
- CTS--------------------------RTS
- GND--------------------------GND
-
- The executable software is titled FACT.EXE. To run the test, the above
- hardware must be set up and after entering the proper directory, the user
- must type FACT <enter> on both machines. The program will prompt the user
- to start both machines and then hit a key to begin the test. This procedure
- is necessary to ensure that all modem control outputs are deasserted before
- program start-up so that a machine won't begin transmitting before the
- other is ready to receive. Full duplex transmission begins after a key is
- hit on both machines and each machine has exchanged initial RTS signals.
- Proper test operation is indicated by a '$' and '*' character being printed
- to the screen every 2560 characters received.
-
- All operations are interrupt driven. UART line status, receiver and transmitter
- interrupts are enabled. When not servicing interrupts, the CPU sits in a
- loop checking for a keyboard hit (means for user to stop test) and for errors
- produced within the interrupt service routines. A transmitter interrupt is
- generated whenever the transmitter FIFO empties. The CPU services the interrupt
- by filling the FIFO with the next 16 characters to be transmitted. Transmit
- data is written to the FIFO only as long as CTS remains asserted. A receiver
- interrupt is generated when 14 characters have entered the receiver FIFO.
- The CPU immediately deasserts RTS to stop any further transmission from the
- other machine. It then reads bytes out of the FIFO, comparing each of them to
- an expected value. Data transmitted and received sequences between 00 and FFH.
- If a mismatch occurs, the expected and received data are displayed and the
- program stops. A line status interrupt results from an Overrun, Framing or
- Parity error and Break condition. Upon receiving the status interrupt, the
- program prints the corrupted data and the line status register value and exits
- the program. Inconsistencies between the Interrupt ID and Line Status Registers
- also cause error messages to be printed and the program to stop.
-
- There is a restriction associated with porgram operation. The maximum baudrate
- that can be selected is 56k; however, this baudrate is limited by the processor
- speed and the host system. A 10Mhz AT compatible and 12Mhz PS/2 Model 30
- operate reliably at a maximum of 19.2k baud. At higher baud rates operation
- is system dependent due to the overhead involved with processing the interrupts.
-
- The default com port is COM1 and default baudrate is 9600. However, the user
- can control these options by specifying arguments on the command line. Arguments
- must be separated by spaces. The first argument is a selection of COM1, COM2
- or COM3 (eg. FACT 2 selects COM2). The second argument is a decimal
- divisor from 2 through 2304 which specifies a baudrate from 56k to 50 (the
- default is 12, 9600 baud). The baudrate arguement must be proceeded on the
- command line by the COM port designation. Again, specifying no arguments
- causes a default of COM1, 9600 baud to be used. A command line which causes
- the program to use COM3 and 19.2k baud is: FACT 3 6. A help screen is printed
- if any improper argument is used or if FACT H is entered.
-
-
- Programmer's Guide for FACT.C -- Rev 1.0
-
- Help Screen for FACT
- -------------------
-
- NOTE: The following is displayed if any incorrect arguments are supplied
- to the FACT (this includes entering "fact help")
-
-
- HELP Screen for NS16550/NS16552 FIFO Asynchronous Communications Test (FACT)
-
- USAGE: fact [<COM-number> [<baudrate-divisor>]]
- arg1 arg2
- ('fact' may be followed by no args, arg1 or arg1+2)
-
- ARGUMENT MINIMUM VALUE MAXIMUM VALUE DEFAULT VALUE
- ============ =============== =============== ==============
- COM-number 1 (for COM1) 3 (for COM3) 1
- (serial line 0) (serial line 2) (COM1)
-
- baudrate- 2 (56000 baud) 2304 (50 baud) 12
- divisor (based on 1.8432 MHz crystal) (9600 baud)
- * Sample baudrate divisors: for baud= 1200, use 96 *
- * 2400 48 *
- * 4800 24 *
- * 9600 12 *
- * 19200 6 *
-
- Page 2 of 4
-
-
- Programmer's Guide for FACT
- ===========================
-
-
- Summary of FACT.C Subroutines
- -----------------------------
-
- NOTE: As the code itself is heavily commented, it should be inspected if
- further clarification is necessary.
-
- The following subroutines are contained in this file:
-
- void main(int, char **); /* main program */
- void interrupt far serint(void); /* serial interrupt handler */
- void procarg(int, char **); /* process invocation arguments */
- void savepar(void); /* save our environment parameters */
- void rstrpar(void); /* restore our environment parameters */
- void dspstr(UCHAR *); /* display a string on the console */
- void usage(void); /* display usage info and exit */
-
-
- 1. main(): main program
-
- The main program initializes the system as follows:
- processes invocation arguments by calling procarg(),
- uses the CLEAR_REGS() macro to clear the RBR, LSR, IIR, MCR and FCR registers,
- saves environment parameters by calling savepar(),
- sets the requested (or default) baud rate and LCR register,
- prints name of test to screen
- prints "Hit a key when other program has been started" and waits for keyboard hit,
- clears FIFOs, sets receiver trigger level and verifies existence of FIFOs,
- enables IRQ by setting OUT2,
- enables UART receiver and line status interrupts,
- asserts RTS and after receiving CTS (RTS from other machine),
- it prompts the operator to "Hit any non-control key to stop" the program.
-
- It then starts full duplex communication by enabling transmitter interrupts
- and then loops until either the global variable "errflag" changes from
- FALSE (0) to TRUE (a specific error code), or the operator strikes any
- non-control keyboard key. The errflag variable is set by the interrupt
- handler as described for serint().
- While this loop is active, the global variable "tick" is inspected. If it is
- non-zero, either "$" or "*" is displayed at one place on the screen in order
- to inform the operator that the program is active. This is facilitated by
- use of a flip-flop variable to index one of two ASCII strings. The character
- is changed every 2560 bytes received.
- After exiting this loop, the program waits for the TEMT bit in the LSR to be
- set to indicate an empty transmitter FIFO. The CLEAR_REGS() macro is again
- invoked. An 'End of program' message is printed and, if the interrupt
- handler found an error, an error message corresponding to the code in the
- variable errflag is output.
-
- Page 3 of 4
-
-
- Programmer's Guide for the FACT
- ===============================
-
-
- Summary of FACT.C Subroutines (continued)
- ----------------------------------------
-
- 2. serint(): serial port interrupt handler
-
- The interrupt handler first checks if the global "errflag" is TRUE. If so,
- the interrupt is ignored by disabling UART interrupts and by sending the
- PIC an EOI and exiting.
- Then the IIR is read and each interrupt type is handled:
- NO Interrupt Pending:
- errflag <- False Interrupt error message code
-
- Receiver Line STatus interrupt:
- read and store LSR
- read and store RBR
- errflag <- Status error message code
-
- Received Data AVailable (RDAV):
- clear RTS
- while bytes still in Receiver FIFO and no mismatches found:
- read a byte and compare to expected value
- if mismatch is found, errflag <- Mismatch Error code
- else increment byte counter variable and set 'tick if
- 2560 characters were received
- after receiver FIFO is emptied,if no errors were found,
- RTS is reasserted
- Transmitter Holding Register Empty:
- the LSR is read
- verify THRE bit set, errflag <- Tx Error message code if not
- while CTS is asserted and transmitter FIFO not full (16 bytes):
- write next byte to transmitter FIFO
- Receiver FIFO Character Timeout:
- errflag <- Timeout error code
- if Data Ready bit not set, errflag <- Timeout error code
- else while bytes still in Receiver FIFO:
- read a byte and compare to expected value
- if mismatch found, errflag <- Mismatch Error code
-
- any other value for the IIR:
- errflag <- IIR Error code
-
- All UART interrupts are disabled (IER <- 0)
- If no errors were found, all interrupts are reenabled. This creates an edge
- on the INTR line if multiple interrupts are pending.
-
- An EOI is sent to the PIC.
- (NOTE: an IRET instruction is automatically generated to exit this int. handler)
-
- Page 4 of 4
-
-
- Programmer's Guide for FACT
- ===========================
-
- Summary of FACT.C Subroutines (concluded)
- ----------------------------------------
-
- 3. procarg(): process invocation arguments
-
- The invocation arguments as defined in the help screen are validated
- by this routine. The help screen itself is displayed by calling
- usage() if any illegal arguments are found.
- Based on the COM argument (or its default), the interrupt vector number
- and UART base address are set up for global use. The existence of
- the requested COM port is verified; its non-existence causes program
- termination.
-
-
- 4. savepar(): save our environment parameters
-
- This routine saves the original interrupt vector, ctrl-break/ctrl-c
- status and PIC mask, and then sets these up as required for FACT use.
- It also saves some of the UART register values.
-
-
- 5. rstrpar(): restore our environment parameters
-
- This routine is the complement for savepar(): it restores the saved
- registers, interrupt vector, ctrl-break/ctrl-c status and PIC mask.
-
-
- 6. dspstr(): display a string of characters on the console
-
- This routine uses the INT 10H software interrupt to display a string a
- character at a time.
-
-
- 7. usage(): display program usage information and terminate (never return)
-
- This routine displays the help screen and terminates the program.