home *** CD-ROM | disk | FTP | other *** search
- /* port_id.c 1/18/89 Louis Shay
-
- National Semiconductor Corporation
- Microcomuputer Systems Division
- Microcontroller Applications Group
-
- Program to identify the presence and type of UART in a system.
- This program will query the serial port at global port address
- "int ubase", and return a value that identifies what type of UART
- is present at that address. This address is set by the calling program
- prior to the function call. The returned int values are:
-
- 0, if there is no identifiable UART at that port address.
- 1, if the port type is INS8250, INS8250-B.
- 2, if the port type is INS8250A, INS82C50A, NS16450, NS16C450.
- 3, if the port type is NS16550A.
- 4, if the port type is NS16C552.
-
- note: the main source file should include "ns16550a.h". This is the
- device header file.
- */
- #include <stdio.h>
- #include <conio.h>
- #include "ns16550a.h"
-
- int port_id()
- {
- extern int ubase; /* reference global address */
-
-
- /* 1. test general functionality. Is the core register set present? */
-
-
- wrLCR( 0xaa );
- if( rdLCR() != 0xaa ) /* test LCR register & set DLAB=1 */
- return( 0 );
-
- /* as an identifier, UART address 1 is 8-bits (DLM) when LCR7=1 (DLAB).
- UART address 1 is 4-bits (IER) when DLAB=0. */
-
- wrDLM( 0x55 ); /* test for DLM present (8-bits) */
- if( rdDLM() != 0x55 )
- return( 0 );
- wrLCR( 0x55 ); /* LCR: set DLAB = 0 */
- if( rdLCR() != 0x55 )
- return( 0 );
- wrIER( 0x55 ); /* test for IER present (4-bits) */
- if( rdIER() != 0x05 )
- return( 0 );
- wrFCR( 0 ); /* FIFOs off, if present */
- wrIER( 0 ); /* interrupts off, IIR should be 01 */
- if( rdIIR() != 1 )
- return( 0 );
-
- /* test modem control register address. Should be 5-bits wide */
-
- wrMCR( 0xf5 ); /* 8-bit write */
- if( rdMCR() != 0x15 ) /* expect 5-bit read */
- return( 0 );
-
- /* test MCR/MSR loopback functions */
-
- wrMCR( 0x10 ); /* set loop mode */
- (void)rdMSR(); /* clear out delta bits */
- if( ( rdMSR() & 0xf0 ) != 0 ) /* check state bits */
- return( 0 );
- wrMCR( 0x1f ); /* toggle modem control lines */
- if( ( rdMSR() & 0xf0 ) != 0xf0 ) /* check state bits */
- return( 0 );
- wrMCR( 0x03 ); /* exit loop mode, DTR, RTS active */
-
- /* 2. port id successful at this point. determine port type */
-
- wrSCR( 0x55 ); /* is there a scratch register? */
- if( rdSCR() != 0x55 )
- return( 1 ); /* no SCR, type = INS8250 */
-
- wrFCR( 0xcf ); /* enable FIFO's, if present */
- if( ( rdIIR() & 0xc0 ) != 0xc0 ) /* check FIFO ID bits */
- return( 2 ); /* no FIFO's, type = NS16450 */
- wrFCR( 0 ); /* turn off FIFO's */
-
- wrLCR( 0x80 ); /* set DLAB */
- wrAFR( 0x07 ); /* write to AFR */
- if ( rdAFR() != 0x07 ) { /* read AFR */
- wrLCR( 0x00 ); /* reset DLAB */
- return ( 3 ); /* if not the same, type = NS16550A */
- }
- wrAFR( 0x00); /* clear AFR */
- wrLCR( 0x00 ); /* reset DLAB */
- return ( 4 ); /* type = NS16C552 */
- }
-
-
-