📄 ppc860sccsio.c
字号:
if (arg == SIO_MODE_INT) { * CISR(pChan->regBase) = pChan->uart.intMask; /* reset the SCC's interrupt status bit */ * CIMR(pChan->regBase) |= pChan->uart.intMask; /* enable this SCC's interrupt */ pChan->uart.pSccReg->scce = SCCE_RX; /* reset the receiver status bit */ pChan->uart.pSccReg->sccm = SCC_UART_SCCX_RX | SCC_UART_SCCX_TX; /* enables receive and transmit interrupts */ } else { pChan->uart.pSccReg->sccm = 0; /* mask off the receive and transmit intrs */ * CIMR(pChan->regBase) &= (~(pChan->uart.intMask)); /* mask off this SCC's interrupt */ } pChan->channelMode = arg; intUnlock(oldlevel); break; case SIO_MODE_GET: * (int *) arg = pChan->channelMode; break; case SIO_AVAIL_MODES_GET: *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; break; default: status = ENOSYS; } return (status); }/********************************************************************************* ppc860SccInt - handle an SCC interrupt** This routine is called to handle SCC interrupts.*/void ppc860SccInt ( PPC860SCC_CHAN *pChan ) { char outChar; FAST UINT16 dataLen = 0; /* check for a receive event */ if (pChan->uart.pSccReg->scce & SCCE_RX) {rcvNums++; pChan->uart.pSccReg->scce = SCCE_RX; /* clear */ while (!(pChan->uart.rxBdBase [pChan->uart.rxBdNext].statusMode & BD_RX_EMPTY_BIT)) { /* process all filled receive buffers */ outChar = pChan->uart.rxBdBase[pChan->uart.rxBdNext].dataPointer[0]; pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode |= BD_RX_EMPTY_BIT; /* incr BD count */ pChan->uart.rxBdNext = (pChan->uart.rxBdNext + 1) % pChan->uart.rxBdNum; /* acknowledge interrupt ??? multiple events ??? */ pChan->uart.pSccReg->scce = SCCE_RX; /* clear */ (*pChan->putRcvChar) (pChan->putRcvArg,outChar); if (pChan->channelMode == SIO_MODE_POLL) break; } } /* check for a transmit event and if a character needs to be output */ if ((pChan->uart.pSccReg->scce & SCCE_TX) && (pChan->channelMode != SIO_MODE_POLL)) { sndNums++; pChan->uart.pSccReg->scce = SCCE_TX; /* clear */ if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK) { do { pChan->uart.txBdBase[pChan->uart.txBdNext].dataPointer[dataLen++] = outChar; if (pChan->channelMode == SIO_MODE_POLL) break; } while ((dataLen < pChan->uart.txBufSize) && ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK)); pChan->uart.txBdBase[pChan->uart.txBdNext].dataLength = dataLen; /* acknowledge interrupt */ pChan->uart.pSccReg->scce = SCCE_TX; /* send transmit buffer */ pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode |= BD_TX_READY_BIT; /* incr BD count */ pChan->uart.txBdNext = (pChan->uart.txBdNext+ 1) % pChan->uart.txBdNum; } } /* acknowledge all other interrupts - ignore events */ pChan->uart.pSccReg->scce = (pChan->uart.pSccReg->scce & ~(SCCE_RX | SCCE_TX)); * CISR(pChan->regBase) = pChan->uart.intMask; }/********************************************************************************* ppc860SccStartup - transmitter startup routine*/LOCAL void ppc860SccStartup ( PPC860SCC_CHAN *pChan /* ty device to start up */ ) { char outChar; FAST UINT16 dataLen = 0; if (pChan->channelMode == SIO_MODE_POLL) return; /* check if buffer is ready and if a character needs to be output */ if ((!(pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode & BD_TX_READY_BIT)) && ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK)) { do { pChan->uart.txBdBase[pChan->uart.txBdNext].dataPointer[dataLen++] = outChar; } while ((dataLen < pChan->uart.txBufSize) && ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK)); /* fill buffer */ /* send transmit buffer */ pChan->uart.txBdBase[pChan->uart.txBdNext].dataLength = dataLen; pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode |= BD_TX_READY_BIT; /* incr BD count */ pChan->uart.txBdNext = (pChan->uart.txBdNext + 1) % pChan->uart.txBdNum; } }/******************************************************************************** ppc860SccPollInput - poll the device for input.** RETURNS: OK if a character arrived, ERROR on device error, EAGAIN* if the input buffer is empty.*/LOCAL int ppc860SccPollInput ( SIO_CHAN * pSioChan, char * thisChar ) { PPC860SCC_CHAN * pChan = (PPC860SCC_CHAN *) pSioChan; if (!(pChan->uart.pSccReg->scce & SCCE_RX)) return (EAGAIN); if (pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode & BD_RX_EMPTY_BIT) return (EAGAIN); /* get a character */ *thisChar = pChan->uart.rxBdBase[pChan->uart.rxBdNext].dataPointer[0]; /* set the empty bit */ pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode |= BD_RX_EMPTY_BIT; /* incr BD count */ pChan->uart.rxBdNext = (pChan->uart.rxBdNext + 1) % pChan->uart.rxBdNum; /* only clear RX event if no more characters are ready */ if (pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode & BD_RX_EMPTY_BIT) pChan->uart.pSccReg->scce = SCCE_RX; return (OK); }/******************************************************************************** ppc860SccPollOutput - output a character in polled mode.** RETURNS: OK if a character arrived, ERROR on device error, EAGAIN* if the output buffer if full.*/LOCAL int ppc860SccPollOutput ( SIO_CHAN * pSioChan, char outChar ) { PPC860SCC_CHAN * pChan = (PPC860SCC_CHAN *) pSioChan; int i; /* wait a bit for the last character to get out */ /* because the PPC604 is a very fast processor */ /* ??? make the 10000 value a #define */ i = 0; while( (i<10000) && (pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode & BD_TX_READY_BIT) ) { i = i + 1; } /* is the transmitter ready to accept a character? */ /* if still not, we have a problem */ if (pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode & BD_TX_READY_BIT) return(EAGAIN); /* reset the transmitter status bit */ pChan->uart.pSccReg->scce = SCCE_TX; /* write out the character */ pChan->uart.txBdBase[pChan->uart.txBdNext].dataPointer[0] = outChar; pChan->uart.txBdBase[pChan->uart.txBdNext].dataLength = 1; /* send transmit buffer */ pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode |= BD_TX_READY_BIT; pChan->uart.txBdNext = (pChan->uart.txBdNext + 1) % pChan->uart.txBdNum; return (OK); }/******************************************************************************** ppc860SccCallbackInstall - install ISR callbacks to get put chars.**/LOCAL int ppc860SccCallbackInstall ( SIO_CHAN * pSioChan, int callbackType, STATUS (* callback)(), void * callbackArg ) { PPC860SCC_CHAN * pChan = (PPC860SCC_CHAN *) pSioChan; switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pChan->getTxChar = callback; pChan->getTxArg = callbackArg; return (OK); break; case SIO_CALLBACK_PUT_RCV_CHAR: pChan->putRcvChar = callback; pChan->putRcvArg = callbackArg; return (OK); break; default: return (ENOSYS); } }LOCAL int ppc860SccDummy(void){ return(ERROR);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -