home *** CD-ROM | disk | FTP | other *** search
- /* ififo.c 11/4/88 Louis Shay
- This function is used to test basic FIFO functions of a NS16550A
- or compatible UART channel at the system base address " int ubase ".
- This address must be defined in the calling program.
- Program requirements.
-
- 1. #include <stdio.h>
- #include <conio.h>
- #include "ns16550a.h" must be in the main() source file.
- 2. Integer variables ubase and fatal_error must be declared as
- global values in the main() source program.
- 3. The caller must set ubase to the device's base address before
- calling ififo().
- 4. This program assumes basic 450-mode functionality, therefore
- i450() should first be run and the fatal_error flag clear before
- calling ififo(). The calling sequence in main() should be:
-
- 1. Call i450() - this tests basic functionality
- 2. IF ( fatal_error == 0 )
- call ififo()
- ELSE
- quit testing this UART channel.
-
- Hardware Requirements:
- 1. The UART I/O input pins SIN, CTS, DCD, DSR, RI, must
- be pulled high and not driven by external sources during
- this test, otherwise false errors may be generated.
-
- Error messages printed will be in the form " Error (n)...", where
- n refers to the section of this source program.
- */
-
- #include <stdio.h>
- #include <conio.h>
- #include "ns16550a.h"
-
- #define TIMEOUT 10000
-
- int ififo()
- {
- extern int ubase, fatal_error;
- int rbrval, iirval, lsrval, tx_data = 0, rx_data = 0;
- int error_count = 0, count_a, count_b, trigger, x=0;
-
- /* 0. start test */
- printf("\nNS16550A FIFO functions test...\n");
-
- /* 1. Initialize FIFO mode and check FIFO init. state */
-
- wrLCR( 0x80 ); /* LCR = 80h, set DLAB */
- wrDLL( 0x9c ); /* DLL, 9600 baud @ 1.8MHz input */
- wrDLM( 0 );
- wrLCR( 0x03 ); /* LCR: 8 data, 1 stop, no pty. */
- wrMCR( 0x10 ); /* MCR: internal loopback mode */
- wrFCR( 0xcf ); /* FCR: fifo mode 1, reset, trigger=14 */
- wrIER( 0x0f ); /* IER: interrupts on */
-
- iirval = rdIIR(); /* check ID bits */
- lsrval = rdLSR(); /* check THRE and DR */
- rbrval = rdRBR(); /* check rbr = 00h */
-
- if( ( iirval & 0xc0 ) != 0xc0 ) { /* no ID bits - fatal error */
- printf(" Error (1)..FIFO ID bits not set! IIR = %2x\n", iirval );
- error_count += 1;
- goto ABORT;
- }
- if( lsrval != 0x60 ) {
- printf(" Error (1)..FIFO init. error : LSR = %2x\n", lsrval );
- error_count += 1;
- }
- if( rbrval != 0 ) {
- printf(" Error (1)..FIFO init. error : RBR = %2x\n", rbrval );
- error_count += 1;
- }
- if( ( iirval & 0x0f ) != 2 ) {
- printf(" Error (1)..FIFO init. error : IIR = %2x\n", iirval );
- error_count += 1;
- }
-
-
- /* 2. Test basic FIFO functions - loop a character */
-
- wrTHR( 0x55 ); /* send a byte */
- while( !( rdLSR() & 0x40 )) ; /* poll LSR until TEMT is set */
- lsrval = rdLSR(); /* test for rx data and lsr clean */
- rbrval = rdRBR();
- if(((lsrval & 0x01 ) == 0 )||(( lsrval & 0x1e ) != 0 )||( rbrval != 0x55 ))
- { /* if DR = 0, or OE/PE/FE/BI set, or rbr not 55h, then error */
- printf(" Error (2)..Tx / Rx 1st read: LSR = %2x RBR = %2x (55H)\n",
- lsrval, rbrval );
- error_count += 1;
- }
- lsrval = rdLSR(); /* test for FIFO empty condition - read again */
- rbrval = rdRBR();
- if((( lsrval & 0x01 ) == 1 )||(( lsrval & 0x9e ) != 0 )||( rbrval != 0x00 ))
- { /* if DR = 1, or OE/PE/FE/BI/EIF set, or RBR not 00h, then error */
- printf(" Error (2)..Tx / Rx 2nd read: LSR = %2x RBR = %2x (00H)\n",
- lsrval, rbrval );
- error_count += 1;
- }
-
-
- /* 3. Test FIFO reset functions - FCR & LSR */
-
- for( count_a = 1 ; count_a <= 16 ; count_a++ ) /* fill tx FIFO */
- wrTHR( count_a );
-
- wrFCR( 0xcd ); /* reset tx fifo but not rx fifo */
- lsrval = rdLSR();
- if( ( lsrval & 0x20 ) == 0 ) { /* if reset, THRE = 1 */
- printf(" Error (3)..Tx FIFO reset : LSR = %2x\n", lsrval );
- error_count += 1;
- }
-
- wrFCR( 0 ); /* reinitialize fifo's */
- wrFCR( 0xcf ); /* trigger=14, cleared, mode 1 */
-
- while ( !( rdLSR() & 0x40 )) ; /* poll TEMT until set */
- wrFCR( 0xcf ); /* reset FIFO */
- lsrval = rdLSR(); /* read status */
- rbrval = rdRBR();
- if( (( lsrval & 0x01 ) == 1 ) || ( rbrval != 0 ) ) {
- printf(" Error (3)..Rx FIFO reset : LSR = %2x RBR = %2x\n", lsrval,
- rbrval );
- error_count += 1;
- }
-
-
- /* 4. Test FIFO-mode loop transfers 00 to ff (16 byte blocks)
- This section sends 16 blocks of 16 bytes each, and compares
- receiver data to transmitted data. LSR values for each byte received
- are also checked. At the end of each 16 bytes received, the RBR
- is read a 17th time to check for a FIFO empty condition.*/
-
- wrLCR( 0x80 ); /* init. UART */
- wrDLL( 0x0c ); /* 9600 baud */
- wrDLM( 0 );
- wrLCR( 0x0f ); /* LCR : 8 data, 2 stops, odd pty */
- wrFCR( 0 );
- wrFCR( 0xcf ); /* FCR : trigger=14, mode 1, cleared */
- wrIER( 0 ); /* interrupts off */
- (void)rdRBR(); /* clear registers */
- (void)rdLSR();
- (void)rdMSR();
- tx_data = 0; /* init tx data byte */
- rx_data = 0; /* init rx comparitor byte */
-
- /* loopback test loop 16 x 16 = 256 bytes sent */
- for( count_a = 1 ; count_a <= 16 ; count_a++ ) {
- (void)rdRBR(); /* dummy read */
- for( count_b = 1 ; count_b <= 16 ; count_b++ ) {
- wrTHR( tx_data++ ); /* load tx FIFO with counter data */
- }
- while( !( rdLSR() & 0x40 )) ; /* wait for TEMT set */
- for( count_b = 1 ; count_b <= 16 ; count_b++ ) {
- lsrval = rdLSR(); /* check rx FIFO contents */
- rbrval = rdRBR();
- if( (( lsrval & 0x9f ) != 1 ) || ( rbrval != ( rx_data & 0xff )) )
- { /* if DR = 0, or OE/PE/FE/BI/EIF set, or rbrval != Tx_data, then..*/
- printf(" Error (4)..FIFO data: read=%d LSR=%2x RBR=%2x TX=%2x\n",
- count_b, lsrval, rbrval, rx_data );
- error_count += 1;
- }
- rx_data += 1; /* increment comparator */
- }
- lsrval = rdLSR(); /* check for FIFOs empty */
- rbrval = rdRBR();
- if( ( lsrval != 0x60 ) || ( rbrval != 0 ) ) {
- printf(" Error (4)..FIFO not empty: read=17 LSR=%2x RBR=%2x\n",
- lsrval, rbrval );
- error_count += 1;
- }
- }
-
- /* 5. Test IIR / Rx FIFO trigger levels
- For each of the four trigger levels, this test will:
- 1. Fill the Rx FIFO to trigger - 1.
- check for NO interrupt.
- 2. Send one byte. Reach receiver trigger level.
- check for DR interrupt set.
- 3. Read a byte from RBR - drop below trigger level.
- check for interrupt clear. */
-
- for( count_a = 0 ; count_a <= 3 ; count_a++ )
- { /* test each of the four trigger levels for IIR set & reset */
-
- wrFCR( 0 ); /* reset FIFOs to char mode */
- wrIER( 0 ); /* reset interrupts */
- wrIER( 0x05 ); /* IER : enable RDAI, LSI */
- while( !( rdLSR() & 0x40 )) ; /* poll TEMT until set */
- /* fill rx FIFO to 1 byte under trigger level */
- switch( count_a ) {
- case 0: wrFCR( 0x0f ); /* trigger = 1 */
- trigger = 1;
- break; /* send 0 bytes */
-
- case 1: wrFCR( 0x4f ); /* trigger = 4 */
- trigger = 4;
- for( count_b = 1 ; count_b <= 3 ; count_b++ )
- wrTHR( count_b ); /* send 3 bytes */
- break;
-
- case 2: wrFCR( 0x8f ); /* trigger = 8 */
- trigger = 8;
- for( count_b = 1 ; count_b <= 7 ; count_b++ )
- wrTHR( count_b ); /* send 7 bytes */
- break;
-
- case 3: wrFCR( 0xcf ); /* trigger = 14 */
- trigger = 14;
- for( count_b = 1 ; count_b <= 13 ; count_b++ )
- wrTHR( count_b ); /* send 13 bytes */
- break;
- }
- while( ( rdLSR() & 0x60 ) != 0x60 ) ; /* wait for TEMT */
- iirval = rdIIR(); /* check for no Intr. */
- lsrval = rdLSR(); /* read status */
- if( iirval != 0xc1 ) { /* intr should not yet be set */
- printf(" Error (5)..IIR set below trigger: IIR=%2x LSR=%2x T=%d\n",
- iirval, lsrval, trigger );
- error_count += 1;
- }
- wrTHR( 0x55 ); /* send a byte - trigger INTR. */
- while( ( rdLSR() & 0x60 ) != 0x60 ) ; /* wait for TEMT */
- iirval = rdIIR();
- lsrval = rdLSR();
- if( iirval != 0xc4 ) { /* INTR should trigger here */
- printf(" Error (5)..Trigger failed: IIR=%2x LSR=%2x T=%d\n",
- iirval, lsrval, trigger );
- error_count += 1;
- }
- rbrval = rdRBR(); /* read a byte - clear interrupt. */
- iirval = rdIIR(); /* check IIR register */
- lsrval = rdLSR();
- if( iirval != 0xc1 ) { /* interrupt should be cleared here */
- printf(" Error (5)..INTR not cleared: IIR=%2x LSR=%2x T=%d\n",
- iirval, lsrval, trigger );
- error_count += 1;
- }
- }
-
-
- /* 6. Test Reciever Data Timeout interrupt function.
- This test will load one byte into the Rx FIFO via loopback. Then
- four bytes will be transmitted when NOT in loopback so that the
- receiver will be inactive for four character times. The Rx FIFO
- timeout interrupt should occur at this point. */
-
- /* initialize */
- wrLCR( 0x80 ); /* LCR: set baud */
- wrDLL( 0x4e ); /* 9600 w/ 1.8 MHz clock */
- wrDLM( 0 );
- wrLCR( 0x03 ); /* LCR: 8 data, 1 stop, no pty */
- wrIER( 0 ); /* interrupts off */
- wrFCR( 0 ); /* FIFO's off */
- wrMCR( 0x10 ); /* internal loopback mode */
- (void)rdRBR(); /* clear data buffer */
- (void)rdLSR(); /* clear status */
- (void)rdMSR();
- wrIER( 0x01 ); /* enable RDAI */
-
- /* send a byte */
- while( !( rdLSR() & 0x40 )) ; /* wait for TEMT */
- wrFCR( 0xcf ); /* set FIFO mode 1, Trigger = 14 */
- wrTHR( 0x55 ); /* load 55H into tx FIFO */
- while( !( rdLSR() & 0x01 )) ; /* wait for DR set */
- iirval = rdIIR(); /* check intr status */
- if( iirval != 0xc1 ) { /* expecting no interrupt at this time */
- printf(" Error (6).. illegal interrupt error: IIR = %2x LSR = %2x\n",
- iirval , lsrval );
- error_count += 1;
- }
-
- wrMCR( 0 ); /* disable loopback mode */
-
- wrTHR( 0 ); /* send five bytes */
- wrTHR( 0 );
- wrTHR( 0 );
- wrTHR( 0 );
- wrTHR( 0 );
- /* at this point, the receiver will sit idle without taking in the
- five characters that were sent. This should cause a timeout interrupt */
-
- while( !(( lsrval = rdLSR() ) & 0x40 )) ; /* wait for TEMT */
- iirval = rdIIR();
- if( iirval != 0xcc ) { /* expecting Rx timeout interrupt */
- printf(" Error (6)..Timeout interrupt failed: IIR = %2x LSR = %2x\n",
- iirval, lsrval );
- error_count += 1;
- }
-
- /* 7. Test FIFO-mode LSR functions. This segment will exercise the
- BI, FE, EIF, and bits in FIFO mode. PE bit is not tested.*/
-
- /* initialize */
- wrFCR( 0 ); /* clear FCR */
- wrMCR( 0x10 ); /* loop mode */
- wrLCR( 0x03 ); /* 8 bit data */
- wrIER( 0x04 ); /* enable LSI */
-
- /* Test EIF, BI, and FE - receive a byte, set break, watch LSR FIFO */
- while( !( rdLSR() & 0x60 )) ; /* poll TEMT until empty */
- wrFCR( 0xcf ); /* enable FIFO mode */
- wrTHR( 0x55 ); /* send a byte around */
- while( !( rdLSR() & 0x60 )) ; /* poll TEMT until empty */
- wrTHR( 0 ); /* load a 0 byte for timing purposes */
- wrLCR ( 0x43 ); /* set a break */
- while( !(( lsrval = rdLSR() ) & 0x40 )) ; /* wait for TEMT */
- iirval = rdIIR(); /* read IIR - should be c1H */
- lsrval = rdLSR(); /* read LSR - should be e1H */
- if( ( lsrval != 0xe1 ) || ( iirval != 0xc1 ) ) {
- printf(" Error (7).. EIF test: IIR = %2x LSR = %2x\n",
- iirval, lsrval );
- error_count += 1;
- }
- rbrval = rdRBR(); /* read RBR - error bits at top of FIFO */
- iirval = rdIIR(); /* should cause LSI interrupt -- IIR = c6H */
- lsrval = rdLSR(); /* LSR: BI, FE, EIF expected -- LSR = f9H */
- if( ( lsrval != 0xf9 ) || ( iirval != 0xc6 ) ) {
- printf(" Error (7)..BI/FE/EIF test: IIR = %2x LSR = %2x\n",
- iirval, lsrval );
- error_count += 1;
- }
- iirval = rdIIR(); /* expecting IIR = c1H */
- lsrval = rdLSR(); /* check if clear */
- if( ( lsrval != 0x61 ) || ( iirval != 0xc1 ) ) {
- printf(" Error (7)..IIR/LSR not cleared: IIR = %2x LSR = %2x\n",
- iirval, lsrval );
- error_count += 1;
- }
-
- /* test OE bit in FIFO mode - load 16 bytes, check, load 1 more, check. */
- wrFCR( 0 ); /* init. */
- wrLCR( 0x03 ); /* 8 data bits */
- wrMCR( 0x10 ); /* loop mode */
- wrFCR( 0xcf ); /* fifo's on, trigger = 14 */
- wrIER( 0x04 ); /* enable LSI */
- for( count_a = 1 ; count_a <= 16 ; count_a++ ) /* load 16 bytes */
- wrTHR( count_a );
- while( !( rdLSR() & 0x60 )); /* wait for TEMT */
- wrTHR( 0x55 ); /* load 17th byte - overrun FIFO */
- while( !((rdIIR() & 0x0f) == 0x06) )
- if (x++ > TIMEOUT)
- {
- printf("Error: OE interrupt never indicated");
- break;
- }
-
- goto END;
- ABORT: printf(" -- fatal error -- test aborted.\n");
- fatal_error = 1;
- END: return( error_count );
- }
-