📄 smc8260sio.c
字号:
} else { pChan->uart.pSmcReg->smcm = 0; /* mask off the receive and transmit intrs */ * M8260_SIMR_L(pChan->regBase) &= (~(pChan->uart.intMask)); /* mask off this SMC'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); }/********************************************************************************* smc8260Int - handle an SMC interrupt** This routine is called to handle SMC interrupts.** RETURNS: N/A*/void smc8260Int ( PPC8260SMC_CHAN *pChan ) { char outChar; FAST UINT16 dataLen = 0; /* check for a receive event */ if (pChan->uart.pSmcReg->smce & SMCE_RX) { pChan->uart.pSmcReg->smce = SMCE_RX; 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.pSmcReg->smce = SMCE_RX; (*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.pSmcReg->smce & SMCE_TX) && (pChan->channelMode != SIO_MODE_POLL)) { pChan->uart.pSmcReg->smce = SMCE_TX; 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.pSmcReg->smce = SMCE_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.pSmcReg->smce = (pChan->uart.pSmcReg->smce & ~(SMCE_RX | SMCE_TX)); * M8260_SIPNR_L(pChan->regBase) = pChan->uart.intMask; }/********************************************************************************* smc8260Startup - transmitter startup routine** This routine is the tranmitter startup routine.** RETURNS: N/A*/LOCAL void smc8260Startup ( PPC8260SMC_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; } }/******************************************************************************** smc8260PollInput - poll the device for input.** This routine recive data from the SMC channel in polling mode.** RETURNS: OK if a character arrived, ERROR on device error, EAGAIN* if the input buffer is empty.*/LOCAL int smc8260PollInput ( SIO_CHAN * pSioChan, char * thisChar ) { PPC8260SMC_CHAN * pChan = (PPC8260SMC_CHAN *) pSioChan; if (!(pChan->uart.pSmcReg->smce & SMCE_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.pSmcReg->smce = SMCE_RX; return (OK); }/******************************************************************************** smc8260PollOutput - output a character in polled mode.** This routine send data to the SMC channel in polling mode.** RETURNS: OK if a character arrived, ERROR on device error, EAGAIN* if the output buffer if full.*/LOCAL int smc8260PollOutput ( SIO_CHAN * pSioChan, char outChar ) { PPC8260SMC_CHAN * pChan = (PPC8260SMC_CHAN *) pSioChan; int i; /* wait a bit for the last character to get out */ /* because the PPC603 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.pSmcReg->smce = SMCE_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); }/******************************************************************************** smc8260CallbackInstall - install ISR callbacks to get put chars.** This routine is the call back install routine.** RETURNS: OK or ENOSYS*/LOCAL int smc8260CallbackInstall ( SIO_CHAN * pSioChan, int callbackType, STATUS (* callback)(), void * callbackArg ) { PPC8260SMC_CHAN * pChan = (PPC8260SMC_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); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -