📄 p16c552.c
字号:
/************************************************************* * File: lib/p16C552.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 980304 Created * 990118 Added BAUDRATES */#include <mips.h>/* * Polled I/O routines for the National NS16C552 DUART on the CMA101 * Motherboard from Cogent Computer Systems, Inc. * */#include <terms.h>#include <utypes.h>/* btab = sysclk/(baudrate*N) */static long btab[] = { -1, /* B0 */ -1, /* B50 */ 3072, /* B75 */ -1, /* B110 */ -1, /* B134 */ 1536, /* B150 */ 1152, /* B200 */ 768, /* B300 */ 384, /* B600 */ 192, /* B1200 */ 128, /* B1800 */ 96, /* B2400 */ 48, /* B4800 */ 24, /* B9600 */ 12, /* B19200 */ 6, /* B38400 */ 0 };#define DEFRATE 13 /* default baudrate (9600) *//* The base address shouldn't really be hardwired like this. I should * define the value in devinfo.c, and pass the address to the driver. */#ifdef MIPSEB#define DUART_BASE 0xbe900007#else#define DUART_BASE 0xbe900000#endif#define inb(a) (*((volatile Uchar *)(a)))#define inh(a) (*((volatile Ushort *)(a)))#define outb(a,v) (*((volatile Uchar *)(a))=(v))#define outh(a,v) (*((volatile Ushort *)(a))=(v))#define outw(a,v) (*((volatile Ulong *)(a))=(v))#define RXRDY 0x01#define TXRDY 0x20/* This driver is a for a 64-bit processor. So the DUART's registers * are 8 bytes apart, rather than the usual 4 bytes for a 32-bit CPU. */#define STATUS (8*5)#define RXHR (8*0)#define TXHR (8*0)/************************************************************** p16c552(op,siodat,chan,ch)*/p16c552(op,siodat,chan,ch)int op,chan,ch;void *siodat;{int i,brate;Ulong m,v;switch (op) { case OP_RXRDY : if (inb(DUART_BASE+STATUS+((chan)?0:0x40))&RXRDY) return(1); break; case OP_RX : return inb(DUART_BASE+RXHR+((chan)?0:0x40)); case OP_TXRDY : if (inb(DUART_BASE+STATUS+((chan)?0:0x40))&TXRDY) return(1); break; case OP_TX : outb(DUART_BASE+TXHR+((chan)?0:0x40),ch); break; case OP_INIT : for (i=0;i<2;i++) { /* for each channel (2) */ /* set DLAB */ outb(DUART_BASE+(3*8)+((i)?0:0x40),0x80); /* ms baud */ outb(DUART_BASE+(1*8)+((i)?0:0x40),btab[DEFRATE]>>8); /* ls baud */ outb(DUART_BASE+(0*8)+((i)?0:0x40),btab[DEFRATE]&0xff); /* mode: 2 stopbits, no parity, 8 bitsdata */ outb(DUART_BASE+(3*8)+((i)?0:0x40),0x03); } break; case OP_BAUD : brate = ch; /* check brate <= 15 */ if (brate > 15) return(1); /* baud rate too large */ /* return if unsupported baud rate */ if (btab[brate] == -1) return(1); outb(DUART_BASE+(3*8)+((chan)?0:0x40),0x80); /* ms baud */ outb(DUART_BASE+(1*8)+((chan)?0:0x40),btab[brate]>>8); /* ls baud */ outb(DUART_BASE+(0*8)+((chan)?0:0x40),btab[brate]&0xff); /* mode: 2 stopbits, no parity, 8 bitsdata */ outb(DUART_BASE+(3*8)+((chan)?0:0x40),0x03); break; case OP_CLKINIT : break; case OP_DELAY : return(0); break; case OP_BAUDRATES : /* list the supported baudrates */ m = 1; for (i=v=0;btab[i] != 0;i++) { if (btab[i] != -1) v |= m; m <<= 1; } return(v); /* one bit per baudrate */ break; }return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -