📄 ppc555scisio.c
字号:
PPC555SCI_REG_WRITE(pChan, sccr1, temp); /* set QTE bit and queue size */ PPC555SCI_REG_READ(pChan, qsccr, temp); temp &= ~QSM_QSCCR_QTSZ_MSK; temp |= QSM_QSCCR_QTE; temp |= (byteCount-1); PPC555SCI_REG_WRITE(pChan, qsccr, temp); /* clear top half empty and bottom half empty if needed */ if (byteCount > 8) qscsrVal &= ~(QSM_QSCSR_QTHE | QSM_QSCSR_QBHE); else qscsrVal &= ~QSM_QSCSR_QTHE; } else { /* disable transmit interrupts */ PPC555SCI_REG_READ(pChan, sccr1, temp); temp &= ~QSM_SCCR1_TCIE; PPC555SCI_REG_WRITE(pChan, sccr1, temp); } } /* update queued SCI status register. Clear overrun, just in case */ qscsrVal &= ~QSM_QSCSR_QOR; PPC555SCI_REG_WRITE(pChan, qscsr, qscsrVal); /* clear error conditions with dummy reads */ PPC555SCI_REG_READ(pChan, scsr, scsrVal); if (scsrVal & (QSM_SCSR_OR | QSM_SCSR_NF | QSM_SCSR_FE | QSM_SCSR_PF)) { PPC555SCI_REG_READ(pChan, scdr, temp); ioChar = PPC555SCI_SCRQ(pChan)[0]; } /* * Make sure receive is enabled because error conditions and idle line * clear these; re-enable transmit. */ PPC555SCI_REG_READ(pChan, qsccr, temp); temp |= QSM_QSCCR_QRE; PPC555SCI_REG_WRITE(pChan, qsccr, temp); PPC555SCI_REG_READ(pChan, sccr1, temp); temp |= (QSM_SCCR1_RE | QSM_SCCR1_TE); PPC555SCI_REG_WRITE(pChan, sccr1, temp); }/******************************************************************************** ppc555SciTxStartup - start the interrupt transmitter** RETURNS: OK on success, ENOSYS if the device is polled-only.*/LOCAL int ppc555SciTxStartup ( SIO_CHAN * pSioChan /* channel to start */ ) { PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan; char outChar; FAST UINT16 status; FAST UINT16 temp; if (pChan->mode == SIO_MODE_INT) { if (pChan->options & QUEUED) { PPC555SCI_REG_READ(pChan, sccr1, temp); temp |= QSM_SCCR1_TCIE; PPC555SCI_REG_WRITE(pChan, sccr1, temp); } else { PPC555SCI_REG_READ(pChan, scsr, status); /* send if transmit register empty and have character to send */ if ((status & QSM_SCSR_TDRE) && ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK)) { PPC555SCI_REG_WRITE(pChan, scdr, outChar); /* enable transmit interrupts */ PPC555SCI_REG_READ(pChan, sccr1, temp); temp |= QSM_SCCR1_TIE; PPC555SCI_REG_WRITE(pChan, sccr1, temp); } } return (OK); } else return (ENOSYS); }/******************************************************************************** ppc555SciCallbackInstall - install ISR callbacks to get/put chars** This driver allows interrupt callbacks for transmitting characters* and receiving characters. In general, drivers may support other* types of callbacks too.** RETURNS: OK on success, or ENOSYS for an unsupported callback type.*/ LOCAL int ppc555SciCallbackInstall ( SIO_CHAN * pSioChan, /* channel */ int callbackType, /* type of callback */ STATUS (*callback)(), /* callback */ void * callbackArg /* parameter to callback */ ) { PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan; switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pChan->getTxChar = callback; pChan->getTxArg = callbackArg; return (OK); case SIO_CALLBACK_PUT_RCV_CHAR: pChan->putRcvChar = callback; pChan->putRcvArg = callbackArg; return (OK); default: return (ENOSYS); } }/********************************************************************************* ppc555SciPollOutput - output a character in polled mode** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the output buffer if full. ENOSYS if the device is* interrupt-only.*/LOCAL int ppc555SciPollOutput ( SIO_CHAN * pSioChan, char outChar ) { PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan; UINT16 status; /* is the transmitter ready to accept a character? */ PPC555SCI_REG_READ(pChan, scsr, status); if ((status & QSM_SCSR_TDRE) == 0x00) return (EAGAIN); /* write out the character */ PPC555SCI_REG_WRITE(pChan, scdr, outChar); return (OK); }/******************************************************************************** ppc555SciPollInput - poll the device for input** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty, ENOSYS if the device is* interrupt-only.*/LOCAL int ppc555SciPollInput ( SIO_CHAN * pSioChan, char * thisChar ) { PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan; UINT16 status; PPC555SCI_REG_READ(pChan, scsr, status); if ((status & QSM_SCSR_RDRF) == 0x00) return (EAGAIN); /* no input available at this time */ /* got a character */ PPC555SCI_REG_READ(pChan, scdr, *thisChar); return (OK); }/******************************************************************************** ppc555SciModeSet - toggle between interrupt and polled mode** RETURNS: OK on success, EIO on unsupported mode.*/LOCAL int ppc555SciModeSet ( PPC555SCI_CHAN * pChan, /* channel */ uint_t newMode /* new mode */ ) { FAST UINT16 temp; FAST int oldlevel; /* current interrupt level mask */ if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT)) return (EIO); /* Don't enter interrupt mode unless it is allowed. */ if ((newMode == SIO_MODE_INT) && (!ppc555SciIntrMode)) return (EIO); oldlevel = intLock(); /* set the new mode */ pChan->mode = newMode; if (pChan->mode == SIO_MODE_INT) if (pChan->options & QUEUED) { /* enable SCI in queued mode */ temp = (QSM_QSCCR_QTHFI | QSM_QSCCR_QBHFI | QSM_QSCCR_QTE | QSM_QSCCR_QRE); PPC555SCI_REG_WRITE(pChan, qsccr, temp); /* enable Rx, Tx and enable idle line detection int */ temp = (QSM_SCCR1_RE | QSM_SCCR1_TE | QSM_SCCR1_TCIE | QSM_SCCR1_ILIE | QSM_SCCR1_ILT); PPC555SCI_REG_WRITE(pChan, sccr1, temp); } else { /* enable SCI receive interrupts */ temp = QSM_SCCR1_RE | QSM_SCCR1_TE | QSM_SCCR1_RIE; PPC555SCI_REG_WRITE(pChan, sccr1, temp); } else /* polled mode */ if (pChan->options & QUEUED) { /* polled mode is not queued */ PPC555SCI_REG_WRITE(pChan, qsccr, 0); PPC555SCI_REG_WRITE(pChan, sccr1, (QSM_SCCR1_RE | QSM_SCCR1_TE)); } else { /* enable rx and tx without interrupts */ PPC555SCI_REG_WRITE(pChan, sccr1, (QSM_SCCR1_RE | QSM_SCCR1_TE)); } intUnlock(oldlevel); return (OK); }/********************************************************************************* ppc555SciIoctl - special device control** This routine handles the IOCTL messages from the user. It supports commands * to get/set baud rate, mode(INT,POLL).** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/LOCAL int ppc555SciIoctl ( SIO_CHAN * pSioChan, /* device to control */ int request, /* request code */ void * someArg /* some argument */ ) { PPC555SCI_CHAN *pChan = (PPC555SCI_CHAN *) pSioChan; int baudScratch; int arg = (int)someArg; FAST int oldlevel; /* current interrupt level mask */ switch (request) { case SIO_BAUD_SET: if (arg < PPC555SCI_BAUD_MIN || arg > PPC555SCI_BAUD_MAX) { return (EIO); } baudScratch = (pChan->clockRate + 16 * arg) / (32 * arg); if ((baudScratch < 1) && (baudScratch > 8191)) { return (EIO); } oldlevel = intLock(); PPC555SCI_REG_WRITE(pChan, sccr0, baudScratch); intUnlock (oldlevel); pChan->baudRate = arg; return (OK); case SIO_BAUD_GET: *(int *)arg = pChan->baudRate; return (OK); case SIO_MODE_SET: /* * Set the mode (e.g., to interrupt or polled). Return OK * or EIO for an unknown or unsupported mode. */ return (ppc555SciModeSet (pChan, arg)); case SIO_MODE_GET: /* Get the current mode and return OK. */ *(int *)arg = pChan->mode; return (OK); case SIO_AVAIL_MODES_GET: /* Get the available modes and return OK. */ *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; return (OK); default: return (ENOSYS); } }/********************************************************************************* dummyCallback - dummy callback routine** RETURNS: ERROR.*/LOCAL STATUS dummyCallback (void) { return (ERROR); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -