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 + -
显示快捷键?