[comp.os.minix] Know your UART

cgs@umd5.umd.edu (Chris G. Sylvain) (11/19/89)

----------------------cut here----------------------
echo x - uartident.c
sed '/^X/s///' > uartident.c << '/'
X#include <stdio.h>
X
X/*
X	   The information for identifying the asyncronous serial I/O chips
X	was obtained from an article appearing in the July/August 1989 issue
X	of _Programmer's Journal_. The article was entitled "PC Communications
X	and Protocols", written by M. Steven Baker.
X
X	   The chip part numbers given are for the devices produced by National
X	Semiconductor. Other part numbers can be cross-referenced from the
X	Nat'l Semi. part numbers.
X
X	   Those with access to the AT(*) Technical Reference manual may
X	observe numerous 'JMP $+2' in the serial I/O code to generate delays
X	between a read and write access of the same serial I/O chip register.
X
X	   Those with access to the Nat'l Semi. data sheets on the chips may
X	observe the read-write delays required for the INS8250 and INS8250-B
X	are approximately 1755 nanoseconds. The INS8250A and INS82C50A (an
X	improved and debugged(!) version) offers a read-write cycle time of
X	about 585 nsec. The NS16540 and NS16C540 are faster still, with read-
X	write cycle times of less than 170 nsec. The NS16550A is an improved
X	16540 chip, with the addition of separate 16 character transmit	and
X	receive FIFO buffers, and a still faster read-write cycle.
X
X	In summary:
X
X	   The NS16550A supports the highest baud rates (9600 and up) when both
X	transmit and receive FIFO buffers are enabled.
X
X	   The INS8250A, INS82C50A, NS16540, NS16C540, and NS16550A chips are
X	the fastest serial I/O chips, and do not require 'JMP $+2' (sic) delays
X	for back-to-back port I/O operations.
X
X	   The INS8250, and INS8250-B chips are slower serial I/O chips, and
X	require delays for back-to-back port I/O operations.
X
X	Additional notes:
X
X	   IIR ::= Interrupt Identification Register
X	   IER ::= Interrupt Enable Register
X
X	   The scratchpad register can be used to store anything you like, as
X	it is otherwise unused by the chip.
X
X
X   (*) AT is a registered trademark of International Business Machines, Inc.
X
X-- coded by Chris Sylvain 11/18/89. Use it in good health!
X*/
X
X#define  FIFO		2
X#define  NODELAY	1
X#define  DELAY		0
X
X#define  TESTVAL	0xd9
X#define  SCRATCH1	0x3ff	/* Scratch pad register for COM1 */
X#define  SCRATCH2	0x2ff	/*     -^-     register for COM2 */
X#define  IIROFFS	-5	/* offset from scratchpad to IIR reg */
X#define  IEROFFS	-6	/* offset from    -^-     to IER reg */
X
Xint uart_id();
Xint onOK;
X
Xmain()
X{
X   printf( "\nTesting tty port 1 [COM1:] serial I/O chip:\n" );
X   uart_msg( uart_id( SCRATCH1 ) );
X
X   printf( "\nTesting tty port 2 [COM2:] serial I/O chip:\n" );
X   uart_msg( uart_id( SCRATCH2 ) );
X
X   putchar( '\n' );	
X}
X
Xuart_msg( id )
Xint id;
X{
X   switch (id) {
X   case FIFO:
X	printf( "\nAsync I/O chip is NS16550A. The on-chip FIFOs" );
X	printf( " %s been enabled.\n", (onOK ? "have" : "have not") );
X	break;
X   case NODELAY:
X	printf( "\nAsync I/O chip is either a INS8250A, INS82C50A," );
X	printf( " NS16540, or NS16C540.\n" );
X	break;
X   case DELAY:
X	printf( "\nAsync I/O chip is either a INS8250, or INS8250-B.\n" );
X	break;
X   default:
X	printf( "\n\uart_msg panic: Unknown chip identity\n" );
X	break;
X   }
X}
X
Xint uart_id( padaddr )
Xint padaddr;
X{ 
X   int i;
X   unsigned char val;
X
X   port_out( padaddr, TESTVAL );
X
X   /* pause before port_in(), in case of a fast machine with slowest chips */
X   for( i = 0; i < 30; i++ );
X
X   port_in( padaddr, &val );
X
X   if (val == TESTVAL) {
X	/* chip might be 16550, try to enable FIFOs by setting bit 0 of IIR */
X
X	port_in( padaddr+IIROFFS, &val );
X	port_out( padaddr+IIROFFS, (val | 0x01) );
X
X	port_in( padaddr+IEROFFS, &val );
X
X	/* If both bits 7 and 6 are set in IER, then both FIFOs are enabled */
X	/* I'm not certain which bit corresponds to which FIFO. */
X
X
X	if ( ((val & 0xc0) >> 6) == 0x03 ) {
X		onOK = 1;
X		return( FIFO );
X	}
X	else if ( (val & 0x80) || (val & 0x40) ) {
X
X		/* both FIFOs didn't get enabled, shut them off */
X
X		port_in( padaddr+IIROFFS, &val );
X		port_out( padaddr+IIROFFS, (val & 0xfe) );
X
X		onOK = 0;
X		return( FIFO );
X	}
X	else return( NODELAY );
X   }
X   else return( DELAY );
X}
X
/
----------------------cut here----------------------
-- 
--==---==---==--
Toves: They make their nests under sundials; also they live on cheese
--   ARPA: cgs@umd5.UMD.EDU     BITNET: cgs%umd5@umd2   --
--   UUCP: ..!uunet!umd5.umd.edu!cgs                    --