cronyx.c

来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 1,061 行 · 第 1/2 页

C
1,061
字号
		c->opt = chan_opt_dflt;		c->aopt = opt_async_dflt;		c->hopt = opt_hdlc_dflt;		c->bopt = opt_bisync_dflt;		c->xopt = opt_x21_dflt;	}}/* * Set up the board. */void cx_setup_board (cx_board_t *b){	int i;	/* Disable DMA channel. */	outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);	/* Reset the controller. */	outb (BCR0(b->port), 0);	if (b->chip[2].port || b->chip[3].port)		outb (BCR0(b->port+0x10), 0);	/*	 * Set channels 0 and 8 to RS232 async. mode.	 * Enable DMA and IRQ.	 */	outb (BCR0(b->port), b->bcr0);	if (b->chip[2].port || b->chip[3].port)		outb (BCR0(b->port+0x10), b->bcr0b);	/* Clear DTR[0..3] and DTR[8..12]. */	outw (BCR1(b->port), b->bcr1);	if (b->chip[2].port || b->chip[3].port)		outw (BCR1(b->port+0x10), b->bcr1b);	/* Initialize all controllers. */	for (i=0; i<NCHIP; ++i)		if (b->chip[i].port)			cx_setup_chip (b->chip + i);	/* Set up DMA channel to master mode. */	outb (DMA_MODE, (b->dma & 3) | DMA_MODE_MASTER);	/* Enable DMA channel. */	outb (DMA_MASK, b->dma & 3);	/* Initialize all channels. */	for (i=0; i<NCHAN; ++i)		if (b->chan[i].type != T_NONE)			cx_setup_chan (b->chan + i);}/* * Initialize the board. */static void cx_setup_chip (cx_chip_t *c){	/* Reset the chip. */	cx_reset (c->port);	/*	 * Set all interrupt level registers to the same value.	 * This enables the internal CD2400 priority scheme.	 */	outb (RPILR(c->port), BRD_INTR_LEVEL);	outb (TPILR(c->port), BRD_INTR_LEVEL);	outb (MPILR(c->port), BRD_INTR_LEVEL);	/* Set bus error count to zero. */	outb (BERCNT(c->port), 0);	/* Set 16-bit DMA mode. */	outb (DMR(c->port), 0);	/* Set timer period register to 1 msec (approximately). */	outb (TPR(c->port), 10);}/* * Initialize the CD2400 channel. */void cx_setup_chan (cx_chan_t *c){	unsigned short port = c->chip->port;	int clock, period;	if (c->num == 0) {		c->board->bcr0 &= ~BCR0_UMASK;		if (c->mode != M_ASYNC)			c->board->bcr0 |= BCR0_UM_SYNC;		if (c->board->if0type &&		    (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))			c->board->bcr0 |= BCR0_UI_RS449;		outb (BCR0(c->board->port), c->board->bcr0);	} else if (c->num == 8) {		c->board->bcr0b &= ~BCR0_UMASK;		if (c->mode != M_ASYNC)			c->board->bcr0b |= BCR0_UM_SYNC;		if (c->board->if8type &&		    (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))			c->board->bcr0b |= BCR0_UI_RS449;		outb (BCR0(c->board->port+0x10), c->board->bcr0b);	}	/* set current channel number */	outb (CAR(port), c->num & 3);	/* reset the channel */	cx_cmd (port, CCR_CLRCH);	/* set LIVR to contain the board and channel numbers */	outb (LIVR(port), c->board->num << 6 | c->num << 2);	/* clear DTR, RTS, set TXCout/DTR pin */	outb (MSVR_RTS(port), 0);	outb (MSVR_DTR(port), c->mode==M_ASYNC ? 0 : MSV_TXCOUT);	switch (c->mode) {	/* initialize the channel mode */	case M_ASYNC:		/* set receiver timeout register */		outw (RTPR(port), 10);          /* 10 msec, see TPR */		outb (CMR(port), CMR_RXDMA | CMR_TXDMA | CMR_ASYNC);		outb (COR1(port), BYTE c->aopt.cor1);		outb (COR2(port), BYTE c->aopt.cor2);		outb (COR3(port), BYTE c->aopt.cor3);		outb (COR6(port), BYTE c->aopt.cor6);		outb (COR7(port), BYTE c->aopt.cor7);		outb (SCHR1(port), c->aopt.schr1);		outb (SCHR2(port), c->aopt.schr2);		outb (SCHR3(port), c->aopt.schr3);		outb (SCHR4(port), c->aopt.schr4);		outb (SCRL(port), c->aopt.scrl);		outb (SCRH(port), c->aopt.scrh);		outb (LNXT(port), c->aopt.lnxt);		break;	case M_HDLC:		outb (CMR(port), CMR_RXDMA | CMR_TXDMA | CMR_HDLC);		outb (COR1(port), BYTE c->hopt.cor1);		outb (COR2(port), BYTE c->hopt.cor2);		outb (COR3(port), BYTE c->hopt.cor3);		outb (RFAR1(port), c->hopt.rfar1);		outb (RFAR2(port), c->hopt.rfar2);		outb (RFAR3(port), c->hopt.rfar3);		outb (RFAR4(port), c->hopt.rfar4);		outb (CPSR(port), c->hopt.cpsr);		break;	case M_BISYNC:		outb (CMR(port), CMR_RXDMA | CMR_TXDMA | CMR_BISYNC);		outb (COR1(port), BYTE c->bopt.cor1);		outb (COR2(port), BYTE c->bopt.cor2);		outb (COR3(port), BYTE c->bopt.cor3);		outb (COR6(port), BYTE c->bopt.cor6);		outb (CPSR(port), c->bopt.cpsr);		break;	case M_X21:		outb (CMR(port), CMR_RXDMA | CMR_TXDMA | CMR_X21);		outb (COR1(port), BYTE c->xopt.cor1);		outb (COR2(port), BYTE c->xopt.cor2);		outb (COR3(port), BYTE c->xopt.cor3);		outb (COR6(port), BYTE c->xopt.cor6);		outb (SCHR1(port), c->xopt.schr1);		outb (SCHR2(port), c->xopt.schr2);		outb (SCHR3(port), c->xopt.schr3);		break;	}	/* set mode-independent options */	outb (COR4(port), BYTE c->opt.cor4);	outb (COR5(port), BYTE c->opt.cor5);	/* set up receiver clock values */	if (c->mode == M_ASYNC || c->opt.rcor.dpll) {		cx_clock (c->chip->oscfreq, c->rxbaud, &clock, &period);		c->opt.rcor.clk = clock;	} else {		c->opt.rcor.clk = CLK_EXT;		period = 1;	}	outb (RCOR(port), BYTE c->opt.rcor);	outb (RBPR(port), period);	/* set up transmitter clock values */	if (c->mode == M_ASYNC || !c->opt.tcor.ext1x) {		unsigned ext1x = c->opt.tcor.ext1x;		c->opt.tcor.ext1x = 0;		cx_clock (c->chip->oscfreq, c->txbaud, &clock, &period);		c->opt.tcor.clk = clock;		c->opt.tcor.ext1x = ext1x;	} else {		c->opt.tcor.clk = CLK_EXT;		period = 1;	}	outb (TCOR(port), BYTE c->opt.tcor);	outb (TBPR(port), period);	/* set receiver A buffer physical address */	c->arphys = vtophys (c->arbuf);	outw (ARBADRU(port), (unsigned short) (c->arphys>>16));	outw (ARBADRL(port), (unsigned short) c->arphys);	/* set receiver B buffer physical address */	c->brphys = vtophys (c->brbuf);	outw (BRBADRU(port), (unsigned short) (c->brphys>>16));	outw (BRBADRL(port), (unsigned short) c->brphys);	/* set transmitter A buffer physical address */	c->atphys = vtophys (c->atbuf);	outw (ATBADRU(port), (unsigned short) (c->atphys>>16));	outw (ATBADRL(port), (unsigned short) c->atphys);	/* set transmitter B buffer physical address */	c->btphys = vtophys (c->btbuf);	outw (BTBADRU(port), (unsigned short) (c->btphys>>16));	outw (BTBADRL(port), (unsigned short) c->btphys);	c->dtr = 0;	c->rts = 0;}/* * Control DTR signal for the channel. * Turn it on/off. */void cx_chan_dtr (cx_chan_t *c, int on){	c->dtr = on ? 1 : 0;	if (c->mode == M_ASYNC) {		outb (CAR(c->chip->port), c->num & 3);		outb (MSVR_DTR(c->chip->port), on ? MSV_DTR : 0);		return;	}	switch (c->num) {	default:		/* Channels 4..7 and 12..15 in syncronous mode		 * have no DTR signal. */		break;	case 1: case 2:  case 3:		if (c->type == T_UNIV_RS232)			break;	case 0:		if (on)			c->board->bcr1 |= 0x100 << c->num;		else			c->board->bcr1 &= ~(0x100 << c->num);		outw (BCR1(c->board->port), c->board->bcr1);		break;	case 9: case 10: case 11:		if (c->type == T_UNIV_RS232)			break;	case 8:		if (on)			c->board->bcr1b |= 0x100 << (c->num & 3);		else			c->board->bcr1b &= ~(0x100 << (c->num & 3));		outw (BCR1(c->board->port+0x10), c->board->bcr1b);		break;	}}/* * Control RTS signal for the channel. * Turn it on/off. */void cx_chan_rts (cx_chan_t *c, int on){	c->rts = on ? 1 : 0;	outb (CAR(c->chip->port), c->num & 3);	outb (MSVR_RTS(c->chip->port), on ? MSV_RTS : 0);}/* * Get the state of DSR signal of the channel. */int cx_chan_dsr (cx_chan_t *c){	unsigned char sigval;	if (c->mode == M_ASYNC) {		outb (CAR(c->chip->port), c->num & 3);		return (inb (MSVR(c->chip->port)) & MSV_DSR ? 1 : 0);	}	/*	 * Channels 4..7 and 12..15 don't have DSR signal available.	 */	switch (c->num) {	default:		return (1);	case 1: case 2:  case 3:		if (c->type == T_UNIV_RS232)			return (1);	case 0:		sigval = inw (BSR(c->board->port)) >> 8;		break;	case 9: case 10: case 11:		if (c->type == T_UNIV_RS232)			return (1);	case 8:		sigval = inw (BSR(c->board->port+0x10)) >> 8;		break;	}	return (~sigval >> (c->num & 3) & 1);}/* * Get the state of CARRIER signal of the channel. */int cx_chan_cd (cx_chan_t *c){	unsigned char sigval;	if (c->mode == M_ASYNC) {		outb (CAR(c->chip->port), c->num & 3);		return (inb (MSVR(c->chip->port)) & MSV_CD ? 1 : 0);	}	/*	 * Channels 4..7 and 12..15 don't have CD signal available.	 */	switch (c->num) {	default:		return (1);	case 1: case 2:  case 3:		if (c->type == T_UNIV_RS232)			return (1);	case 0:		sigval = inw (BSR(c->board->port)) >> 8;		break;	case 9: case 10: case 11:		if (c->type == T_UNIV_RS232)			return (1);	case 8:		sigval = inw (BSR(c->board->port+0x10)) >> 8;		break;	}	return (~sigval >> 4 >> (c->num & 3) & 1);}/* * Compute CD2400 clock values. */void cx_clock (long hz, long ba, int *clk, int *div){	static short clocktab[] = { 8, 32, 128, 512, 2048, 0 };	for (*clk=0; clocktab[*clk]; ++*clk) {		long c = ba * clocktab[*clk];		if (hz <= c*256) {			*div = (2 * hz + c) / (2 * c) - 1;			return;		}	}	/* Incorrect baud rate.  Return some meaningful values. */	*clk = 0;	*div = 255;}void cx_disable_dma (cx_board_t *b){	/* Disable DMA channel. */	outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);}cx_chan_opt_t chan_opt_dflt = { /* mode-independent options */	{			/* cor4 */		7,		/* FIFO threshold, odd is better */		0,		0,              /* don't detect 1 to 0 on CTS */		1,		/* detect 1 to 0 on CD */		0,              /* detect 1 to 0 on DSR */	},	{			/* cor5 */		0,		/* receive flow control FIFO threshold */		0,		0,              /* don't detect 0 to 1 on CTS */		1,		/* detect 0 to 1 on CD */		0,              /* detect 0 to 1 on DSR */	},	{			/* rcor */		0,		/* dummy clock source */		ENCOD_NRZ,      /* NRZ mode */		0,              /* disable DPLL */		0,		0,		/* transmit line value */	},	{			/* tcor */		0,		0,		/* local loopback mode */		0,		1,		/* external 1x clock mode */		0,		0,		/* dummy transmit clock source */	},};cx_opt_async_t opt_async_dflt = { /* default async options */	{			/* cor1 */		8-1,		/* 8-bit char length */		0,		/* don't ignore parity */		PARM_NOPAR,	/* no parity */		PAR_EVEN,	/* even parity */	},	{			/* cor2 */		0,              /* disable automatic DSR */		1,              /* enable automatic CTS */		0,              /* disable automatic RTS */		0,		/* no remote loopback */		0,		0,              /* disable embedded cmds */		0,		/* disable XON/XOFF */		0,		/* disable XANY */	},	{			/* cor3 */		STOPB_1,	/* 1 stop bit */		0,		0,		/* disable special char detection */		FLOWCC_PASS,	/* pass flow ctl chars to the host */		0,		/* range detect disable */		0,		/* disable extended spec. char detect */	},	{			/* cor6 */		PERR_INTR,	/* generate exception on parity errors */		BRK_INTR,	/* generate exception on break condition */		0,		/* don't translate NL to CR on input */		0,		/* don't translate CR to NL on input */		0,		/* don't discard CR on input */	},	{			/* cor7 */		0,		/* don't translate CR to NL on output */		0,		/* don't translate NL to CR on output */		0,		0,		/* don't process flow ctl err chars */		0,		/* disable LNext option */		0,		/* don't strip 8 bit on input */	},	0, 0, 0, 0, 0, 0, 0,	/* clear schr1-4, scrl, scrh, lnxt */};cx_opt_hdlc_t opt_hdlc_dflt = { /* default hdlc options */	{			/* cor1 */		2,              /* 2 inter-frame flags */		0,		/* no-address mode */		CLRDET_DISABLE,	/* disable clear detect */		AFLO_1OCT,	/* 1-byte address field length */	},	{			/* cor2 */		0,		/* disable automatic DSR */		0,              /* disable automatic CTS */		0,              /* disable automatic RTS */		0,		CRC_INVERT,	/* use CRC V.41 */		0,		FCS_NOTPASS,	/* don't pass received CRC to the host */		0,	},	{			/* cor3 */		0,              /* 0 pad characters sent */		IDLE_FLAG,	/* idle in flag */		0,		/* enable FCS */		FCSP_ONES,	/* FCS preset to all ones (V.41) */		SYNC_AA,	/* use AAh as sync char */		0,              /* disable pad characters */	},	0, 0, 0, 0,		/* clear rfar1-4 */	POLY_V41,		/* use V.41 CRC polynomial */};cx_opt_bisync_t opt_bisync_dflt = { /* default bisync options */	{			/* cor1 */		8-1,            /* 8-bit char length */		0,		/* don't ignore parity */		PARM_NOPAR,	/* no parity */		PAR_EVEN,	/* even parity */	},	{			/* cor2 */		3-2,            /* send three SYN chars */		CRC_DONT_INVERT,/* don't invert CRC (CRC-16) */		0,		/* use ASCII, not EBCDIC */		0,		/* disable bcc append */		BCC_CRC16,	/* user CRC16, not LRC */	},	{			/* cor3 */		0,              /* send 0 pad chars */		IDLE_FLAG,	/* idle in SYN */		0,		/* enable FCS */		FCSP_ZEROS,	/* FCS preset to all zeros (CRC-16) */		PAD_AA,		/* use AAh as pad char */		0,		/* disable pad characters */	},	{			/* cor6 */		10,		/* DLE - disable special termination char */	},	POLY_16,		/* use CRC-16 polynomial */};cx_opt_x21_t opt_x21_dflt = {   /* default x21 options */	{			/* cor1 */		8-1,            /* 8-bit char length */		0,		/* don't ignore parity */		PARM_NOPAR,	/* no parity */		PAR_EVEN,	/* even parity */	},	{			/* cor2 */		0,		0,		/* disable embedded transmitter cmds */		0,	},	{			/* cor3 */		0,		0,		/* disable special character detect */		0,		/* don't treat SYN as special condition */		0,		/* disable steady state detect */		X21SYN_2,	/* 2 SYN chars on receive are required */	},	{			/* cor6 */		16,		/* SYN - standard SYN character */	},	0, 0, 0,		/* clear schr1-3 */};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?