📄 p8251.c
字号:
/************************************************************* * File: lib/p8251.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history * 980618 Added OP_BAUDRATES */#include <mips.h>/* * Polled I/O routines for the LSI 8251-compatable MegaCore * * Because the registers for these devices are scattered all over the * address map, I have created a pseudo device L8251rec that contains * all the information for a channel. Each chip that uses this device * has an array of these structures (eg. l08_sio for the 64008). * * Each 8251 has the following registers: * * SIOAn Attribute Register * SIOMn Mode Register * SIOBn Baudrate Register (write only) * SIODn Data Register * SIOCn Command (write only) * SIOSn Status Register (read only) */#include <terms.h>#include <utypes.h>#ifdef LR64008/* This is the pseudo device for the L64008 */L8251rec l08_sio[] = { {M_08_SIOA1,M_08_SIOM1,M_08_SIOB1,M_08_SIOD1,M_08_SIOC1,M_08_SIOS1}, {M_08_SIOA2,M_08_SIOM2,M_08_SIOB2,M_08_SIOD2,M_08_SIOC2,M_08_SIOS2}, {M_08_SIOA0,M_08_SIOM0,M_08_SIOB0,M_08_SIOD0,M_08_SIOC0,M_08_SIOS0}, {0}};#endif/* btab = sysclk/(baudrate*N) *//* assumes a sysclk of 27 MHz and N=16 */static long btab[] = { -1, /* B0 */ 33750, /* B50 */ 22500, /* B75 */ 15340, /* B110 */ 12593, /* B134 */ 11250, /* B150 */ 8437, /* B200 */ 5625, /* B300 */ 2813, /* B600 */ 1406, /* B1200 */ 937, /* B1800 */ 703, /* B2400 */ 352, /* B4800 */ 176, /* B9600 */ 88, /* B19200 */ 44, /* B38400 */ 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 TXEMPTY 0x03 #define RXRDY 0x02#define TXRDY 0x01/************************************************************** p8251(op,siodat,chan,ch)*/p8251(op,siodat,chan,ch)int op,chan,ch;struct p8251info *siodat;{int i,brate;L8251rec *p;Ulong m,v;p = (L8251rec *) l08_sio; /* siodat->siobase; we have one 8251 only anyhow */switch (op) { case OP_RXRDY : if (inb(p[chan].status)&RXRDY) return(1); break; case OP_RX : return inb(p[chan].data); case OP_TXRDY : if (inb(p[chan].status)&TXRDY) return(1); break; case OP_TX : outb(p[chan].data,ch); break; case OP_INIT : for (i=0;p[i].attribute;i++) { outh(p[i].attribute,5); /* 16-bit */ /* mode: 2 stopbits, no parity, 8 bitsdata, 16x */ if (inh(p[i].baudrate) == 0xffff) outh(p[i].mode,0x4e00); outh(p[i].baudrate,btab[DEFRATE]); /* cmd: enable rx & tx */ outb(p[i].cmd,0x27); } 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); outh(p[chan].baudrate,btab[brate]); 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 + -