📄 p16550.c
字号:
/************************************************************* * File: lib/p16550.c * Purpose: Driver for 16550D UART * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 980615 Created * 980618 Added OP_BAUDRATES * 981106 Works with "-board bdmr4102" */#include <mips.h>/* * Polled I/O routines for the National NS16550 UART * */#include <terms.h>#include <utypes.h>/* btab = sysclk/(baudrate*N) *//* btab = 14.7456MHz/(baudrate*16) */static long btab_14[] = { -1, /* B0 */ -1, /* B50 */ -1, /* B75 */ -1, /* B110 */ -1, /* B134 */ 6144, /* B150 */ 4608, /* B200 */ 3072, /* B300 */ 1536, /* B600 */ 768, /* B1200 */ 512, /* B1800 */ 384, /* B2400 */ 192, /* B4800 */ 96, /* B9600 */ 48, /* B19200 */ 24, /* B38400 */ 16, /* B57600 */ 12, /* B76800 */ 8, /* B115200 */ 6, /* B153600 */ 4, /* B230400 */ 3, /* B307200 */ 2, /* B460800 */ 1, /* B921600 */ 0 /* end */ };/* assumes a 18.432 MHz crystal is in use */static long btab_18[] = { -1, /* B0 */ 23040, /* B50 */ 15360, /* B75 */ 10473, /* B110 */ 8565, /* B134 */ 7680, /* B150 */ -1, /* B200 */ 3840, /* B300 */ 1920, /* B600 */ 960, /* B1200 */ 640, /* B1800 */ 480, /* B2400 */ 240, /* B4800 */ 120, /* B9600 */ 60, /* B19200 */ 30, /* B38400 */ 20, /* B57600 */ -1, /* B76800 */ 10, /* B115200 */ -1, /* B153600 */ 5, /* B230400 */ -1, /* B307200 */ 2, /* B460800 */ -1, /* B921600 */ 0 /* end */ };#define DEFRATE 13 /* default baudrate (9600) */#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#define STATUS (gap*5)#define RXHR (gap*0)#define TXHR (gap*0)/* ------- Registers ------------ Read Write ---------------------0 RHR THR1 --- int_enable -----2 int_ident FIFO cntrl3 ---- line cntrl ----4 ---- modem ctrl ----5 ---- line status --- 01=rxrdy 20=txrdy6 --- modem status ---7 ----- scratch ------0+dlab - ls divisor latch -1+dlab - ms divisor latch ----------------------------------- *//************************************************************** p16550(op,siodat,chan,ch)*/p16550(op,siodat,chan,ch)int op,chan,ch;void *siodat;{int i,brate;struct p16550Rec *info = siodat;Ulong base = info->base;int gap = info->gap;Ulong m,v;long *btab;#ifdef MIPSEBbase += info->beoffs;#endifif (info->baudclk == 14) btab = btab_14;else btab = btab_18;switch (op) { case OP_RXRDY : if (inb(base+STATUS)&RXRDY) return(1); break; case OP_RX : return inb(base+RXHR); case OP_TXRDY : if (inb(base+STATUS)&TXRDY) return(1); break; case OP_TX : outb(base+TXHR,ch); break; case OP_INIT : /* set DLAB */ outb(base+(3*gap),0x80); /* ms baud */ outb(base+(1*gap),btab[DEFRATE]>>8); /* ls baud */ outb(base+(0*gap),btab[DEFRATE]&0xff); /* mode: 2 stopbits, no parity, 8 bitsdata */ outb(base+(3*gap),0x03); break; case OP_BAUD : brate = ch; /* check brate <= 23 */ if (brate > 23) return(1); /* baud rate too large */ /* return if unsupported baud rate */ if (btab[brate] == -1) return(1); outb(base+(3*gap),0x80); /* ms baud */ outb(base+(1*gap),btab[brate]>>8); /* ls baud */ outb(base+(0*gap),btab[brate]&0xff); /* mode: 2 stopbits, no parity, 8 bitsdata */ outb(base+(3*gap),0x03); break; case OP_CLKINIT : break; case OP_DELAY : return(0); break; case OP_BAUDRATES : m = 1; for (i=v=0;btab[i];i++) { if (btab[i] != -1) v |= m; m <<= 1; } return(v); break; }return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -