📄 z8530sio_dy4.c
字号:
/* write reg 10 - misc tx/rx control */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR10); REG_8530_WRITE(cr, zero); /* clear sync, loop, poll */ /* write reg 11 - clock mode */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR11); REG_8530_WRITE(cr, pChan->writeReg11); /* write reg 15 - disable external/status interrupts */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR15); REG_8530_WRITE(cr, zero); /* * Calculate the baud rate constant for the default baud rate * from the input clock (PCLK) frequency. This assumes that * the divide-by-16 bit is set (done in WR4 above). */ baudConstant = ((pChan->baudFreq / 32) / pChan->baudRate) - 2; /* write reg 12,13 - set baud rate */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR12); /* LSB of baud constant */ REG_8530_WRITE(cr, (char)baudConstant); REG_8530_WRITE(cr, SCC_WR0_SEL_WR13); /* MSB of baud constant */ REG_8530_WRITE(cr, (char)(baudConstant >> 8)); /* write reg 14 - misc control bits */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR14); REG_8530_WRITE(cr, pChan->writeReg14); /* reset external interrupts and errors */ REG_8530_WRITE(cr, SCC_WR0_RST_INT); REG_8530_WRITE(cr, SCC_WR0_ERR_RST); /* write reg 3 - receive params */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR3); REG_8530_WRITE(cr, (unsigned char)(SCC_WR3_RX_8_BITS | SCC_WR3_RX_EN)); /* write reg 5 - tx params */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR5); REG_8530_WRITE(cr, (unsigned char)(SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN | SCC_WR5_DTR /* | SCC_WR5_RTS */ )); /* write reg 2 - interrupt vector */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR2); REG_8530_WRITE(cr, pChan->intVec); /* write reg 1 - disable interrupts and xfer mode */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR1); REG_8530_WRITE(cr, zero); /* write reg 9 - enable master interrupt control */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR9); REG_8530_WRITE(cr, SCC_WR9_MIE | pChan->intType); /* reset Tx CRC generator and any pending ext/status interrupts */ REG_8530_WRITE(cr, (UINT8)(SCC_WR0_RST_TX_CRC)); REG_8530_WRITE(cr, SCC_WR0_RST_INT); REG_8530_WRITE(cr, SCC_WR0_RST_INT); /* reset SCC register counter */ REG_8530_WRITE(cr, zero); }/********************************************************************************* z8530Hup - hang up the modem control lines ** Resets the RTS and DTR signals.** RETURNS: OK*/LOCAL STATUS z8530Hup ( Z8530_CHAN * pChan /* pointer to channel */ ) { volatile char *cr = pChan->cr; /* SCC control reg adr */ FAST int oldlevel; /* current interrupt level mask */ pChan->writeReg5 &= (~(SCC_WR5_DTR | SCC_WR5_RTS)); oldlevel = intLock (); REG_8530_WRITE(cr, SCC_WR0_SEL_WR5); REG_8530_WRITE(cr, pChan->writeReg5); intUnlock (oldlevel); return (OK); } /********************************************************************************* z8530Open - Set the modem control lines ** Set the modem control lines(RTS, DTR) TRUE if not already set. * It also clears the receiver, transmitter and enables the fifo. ** RETURNS: OK*/LOCAL STATUS z8530Open ( Z8530_CHAN * pChan /* pointer to channel */ ) { volatile char *cr = pChan->cr; /* SCC control reg adr */ FAST int oldlevel; /* current interrupt level mask */ char mask; mask = pChan->writeReg5 & (SCC_WR5_DTR | SCC_WR5_RTS); if (mask != (char)(SCC_WR5_DTR | SCC_WR5_RTS)) { /* RTS and DTR not set yet */ pChan->writeReg5 |= (SCC_WR5_DTR | SCC_WR5_RTS); oldlevel = intLock (); /* set RTS and DTR TRUE */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR5); REG_8530_WRITE(cr, pChan->writeReg5); intUnlock (oldlevel); } return (OK); }/********************************************************************************* z8530OptsSet - set the serial options** Set the channel operating mode to that specified. All sioLib options* are supported: CLOCAL, HUPCL, CREAD, CSIZE, PARENB, and PARODD.** RETURNS:* Returns OK to indicate success, otherwise ERROR is returned*/LOCAL STATUS z8530OptsSet ( Z8530_CHAN * pChan, /* pointer to channel */ UINT options /* new hardware options */ ) { FAST int oldlevel; /* current interrupt level mask */ volatile char *cr = pChan->cr; /* SCC control reg adr */ UINT8 wreg3, wreg4, wreg5; wreg3 = wreg4 = wreg5 = 0; if (pChan == NULL || options & 0xffffff00) return ERROR; switch (options & CSIZE) { case CS5: wreg3 = SCC_WR3_RX_5_BITS; /* select receive 5 bit data size */ wreg5 = SCC_WR5_TX_5_BITS; /* select transmit 5 bit data size */ break; case CS6: wreg3 = SCC_WR3_RX_6_BITS; /* select receive 6 bit data size */ wreg5 = SCC_WR5_TX_6_BITS; /* select transmit 6 bit data size */ break; case CS7: wreg3 = SCC_WR3_RX_7_BITS; /* select receive 7 bit data size */ wreg5 = SCC_WR5_TX_7_BITS; /* select transmit 7 bit data size */ break; default: case CS8: wreg3 = SCC_WR3_RX_8_BITS; /* select receive 8 bit data size */ wreg5 = SCC_WR5_TX_8_BITS; /* select transmit 8 bit data size */ break; } if (options & STOPB) wreg4 = SCC_WR4_2_STOP; /* select 2 stop bits */ else wreg4 = SCC_WR4_1_STOP; /* select one stop bit */ switch (options & (PARENB | PARODD)) { case PARENB|PARODD: wreg4 |= SCC_WR4_PAR_EN; break; case PARENB: wreg4 |= (SCC_WR4_PAR_EN | SCC_WR4_PAR_EVEN); break; default: case 0: wreg4 &= (~SCC_WR4_PAR_EN); break; } if (!(options & CLOCAL)) { /* !clocal enables hardware flow control(DTR/DSR) */ wreg3 |= SCC_WR3_AUTO_EN; wreg5 |= (unsigned char)(SCC_WR5_DTR | SCC_WR5_RTS); } if (options & CREAD) wreg3 |= SCC_WR3_RX_EN; oldlevel = intLock (); REG_8530_WRITE(cr, SCC_WR0_SEL_WR1); /* no interrupts */ REG_8530_WRITE(cr, 0); REG_8530_WRITE(cr, SCC_WR0_ERR_RST); REG_8530_WRITE(cr, SCC_WR0_RST_INT); REG_8530_WRITE(cr, SCC_WR0_SEL_WR9); /* write register 9 - mstr int ctrl */ REG_8530_WRITE(cr, ((pChan->channel == SCC_CHANNEL_A) ? SCC_WR9_CH_A_RST : /* reset channel A */ SCC_WR9_CH_B_RST)); /* reset channel B */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR4); /* write reg 4 - misc parms & modes */ REG_8530_WRITE(cr, (wreg4 | SCC_WR4_16_CLOCK)); wreg5 |= SCC_WR5_TX_EN; REG_8530_WRITE(cr, SCC_WR0_SEL_WR5); /* tx params */ REG_8530_WRITE(cr, wreg5); if (pChan->mode == SIO_MODE_INT) { REG_8530_WRITE(cr, SCC_WR0_SEL_WR1); /* int and xfer mode */ REG_8530_WRITE(cr, (SCC_WR1_INT_ALL_RX | SCC_WR1_TX_INT_EN)); /* re-enable interrupts */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR9); /* master interrupt control */ REG_8530_WRITE(cr, (SCC_WR9_MIE | pChan->intType)); } REG_8530_WRITE(cr, SCC_WR0_SEL_WR3); /* write reg 3 - receive params */ REG_8530_WRITE(cr, (unsigned char)wreg3); intUnlock (oldlevel); pChan->options = options; /* save new options */ pChan->writeReg5 = wreg5; return OK; }/********************************************************************************* z8530Ioctl - special device control** This is a general access routine to special device- and driver-specific* functions and services.** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported request.*/static int z8530Ioctl ( SIO_CHAN * pSioChan, /* device to control */ int request, /* request code */ void * someArg /* some argument */ ) { Z8530_CHAN * pChan = (Z8530_CHAN *) pSioChan; int oldlevel; /* current interrupt level mask */ int baudConstant; volatile char * cr; /* SCC control reg adr */ int arg = (int)someArg; switch (request) { case SIO_BAUD_SET:#ifdef VME_181 if (arg < 50 || arg > 153600) /* illegal baud rate */#else if (arg < 1200 || arg > 115200) /* illegal baud rate */#endif { return (EIO); } if (pChan->baudRate == arg) /* current baud = requested baud */ { return (OK); } /* * Calculate the baud rate constant for the new baud rate * from the input clock (PCLK) frequency. This assumes that the * divide-by-16 bit is set in the Z8530 WR4 register (done in * tyCoInitChannel). */ baudConstant = ((pChan->baudFreq / 32) / arg) - 2; cr = pChan->cr; /* disable interrupts during chip access */ oldlevel = intLock (); /* set the new baud rate */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR12); /* LSB of baud constant */ REG_8530_WRITE(cr, (char)baudConstant); REG_8530_WRITE(cr, SCC_WR0_SEL_WR13); /* MSB of baud constant */ REG_8530_WRITE(cr, (char)(baudConstant >> 8)); /* record new baud rate in channel control block */ pChan->baudRate = arg; /* re-enable interrupts */ intUnlock (oldlevel); return (OK); case SIO_BAUD_GET: *(int *)arg = pChan->baudRate; /* return current baud rate */ return (OK); case SIO_MODE_SET: return (z8530ModeSet (pChan, arg) == OK ? OK : EIO); case SIO_MODE_GET: *(int *)arg = pChan->mode; /* return current SIO mode */ return (OK); case SIO_AVAIL_MODES_GET: *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; return (OK); case SIO_HW_OPTS_SET: return ((z8530OptsSet (pChan, arg) == OK) ? OK : EIO); break; case SIO_HW_OPTS_GET: *(int *)arg = pChan->options; break; case SIO_HUP: /* check if hupcl option is enabled */ if (pChan->options & HUPCL) return (z8530Hup (pChan)); break; case SIO_OPEN: /* check if hupcl option is enabled */ if (pChan->options & HUPCL) return (z8530Open (pChan)); break; default: return (ENOSYS); } return (OK); }/******************************************************************************** z8530DevInit - intialize a Z8530_DUSART** The BSP must have already initialized all the device addresses, etc in* Z8530_DUSART structure. This routine initializes some SIO_CHAN* function pointers and then resets the chip to a quiescent state.** RETURNS: N/A*/void z8530DevInit ( Z8530_DUSART * pDusart ) { /* disable interrupts during initialization */ int oldlevel = intLock(); /* initialize the driver function pointers in the SIO_CHAN's */ pDusart->portA.pDrvFuncs = &z8530SioDrvFuncs; pDusart->portB.pDrvFuncs = &z8530SioDrvFuncs; /* set the non BSP-specific constants */ pDusart->portA.baudRate = Z8530_DEFAULT_BAUD; pDusart->portA.channel = SCC_CHANNEL_A; pDusart->portA.getTxChar = z8530DummyCallback; pDusart->portA.putRcvChar = z8530DummyCallback; pDusart->portA.mode = 0; /* undefined */ pDusart->portA.options = Z8530_DEFAULT_OPTIONS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -