📄 cd2400sio.c
字号:
intUnlock(oldlevel); status = OK; break; case SIO_MODE_GET: *(int *)arg = ((CD2400_CHAN *)pSioChan)->channelMode; return (OK); case SIO_AVAIL_MODES_GET: *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; return (OK); default: status = ENOSYS; break; } return (status); }/********************************************************************************* cd2400IntRx - handle receiver interrupts** This routine handles the interrupts for all channels for a Receive* Data Interrupt.*/void cd2400IntRx ( CD2400_CHAN * pChan ) { CD2400_QUSART * pQusart = pChan->pQusart; char thisChar; if (pChan->created && pChan->putRcvChar ) { thisChar = *MPCC_RDR; /* grab the character */ *MPCC_REOIR = EOIR_TRANSFER; /* clear the interrupt */ (*pChan->putRcvChar) (pChan->putRcvArg, thisChar); } else *MPCC_REOIR = EOIR_NO_TRANSFER; /* just clear interrupt */ }/********************************************************************************* cd2400IntTx - handle transmitter interrupts** This routine handles transmitter interrupts from the MPCC.*/void cd2400IntTx ( CD2400_CHAN * pChan ) { CD2400_QUSART * pQusart = pChan->pQusart; char outChar; /* Tx Buffer Empty */ if (pChan->created && pChan->getTxChar && ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK)) { *MPCC_TDR = outChar; *MPCC_TEOIR = EOIR_TRANSFER; } else { /* no more chars to xmit now. reset the tx int, * so the SCC doesn't keep interrupting us. */ *MPCC_IER &= ~(IER_TXEMPTY | IER_TXDATA); *MPCC_TEOIR = EOIR_NO_TRANSFER; } }/********************************************************************************* cd2400Int - handle special status interrupts** This routine handles special status interrupts from the MPCC.*/void cd2400Int ( CD2400_CHAN * pChan ) { CD2400_QUSART * pQusart = pChan->pQusart; *MPCC_REOIR = EOIR_NO_TRANSFER; /* just clear interrupt */ }/******************************************************************************** cd2400PTxChar - transmit a character in poll mode.** RETURNS: N/A*/static int cd2400PTxChar ( SIO_CHAN * pSioChan, char ch /* character to output */ ) { CD2400_QUSART * pQusart = ((CD2400_CHAN *)pSioChan)->pQusart; if (!(*pQusart->txReady)(pQusart)) return (EAGAIN); *MPCC_TDR = ch; /* transmit a character */ *MPCC_TEOIR = EOIR_TRANSFER; /* complete the transfer */ return(OK); }/******************************************************************************** cd2400PRxChar - wait for and read a character from input.** RETURNS: A character from input.** NOMANUAL*/static int cd2400PRxChar ( SIO_CHAN * pSioChan, char * ch ) { CD2400_QUSART * pQusart = ((CD2400_CHAN *)pSioChan)->pQusart; if (!(*pQusart->rxReady)(pQusart)) return (EAGAIN); *ch = * MPCC_RDR; /* read a character */ *MPCC_REOIR = EOIR_TRANSFER; /* complete the transfer */ return (OK); }/********************************************************************************* cd2400Startup - transmitter startup routine** Call interrupt level character output routine.*/static int cd2400Startup ( SIO_CHAN * pSioChan /* device to start up */ ) { int oldLevel; CD2400_QUSART * pQusart; oldLevel = intLock (); pQusart = ((CD2400_CHAN *)pSioChan)->pQusart; if (((CD2400_CHAN *)pSioChan)->channelMode != SIO_MODE_POLL) { *MPCC_CAR = ((CD2400_CHAN *)pSioChan)->chan_num; /* set up channel */ /* only need to enable interrupt */ *MPCC_IER = IER_TXEMPTY | IER_TXDATA | IER_RXDATA; } intUnlock (oldLevel); return (OK); }/************************************************************************** * cd2400SetMode - switch between two modes: SIO_MODE_INT and SIO_MODE_POLL** Since only one channel is allowed when device is in polling mode, the * other three channels must be disabled when the device is set to POLL * mode; and enabled when the device is set back to INT mode from POLL mode.**/static void cd2400SetMode ( CD2400_CHAN * pChan, int mode ) { int i; int pollChannel; CD2400_QUSART * pQusart = pChan->pQusart; if (mode == SIO_MODE_POLL) { if (!pQusart->devMode) /* device is not in poll mode */ { /* enables and disables the respective channels */ for (i=0;i<pQusart->numChannels;i++) { if (pQusart->channel[i].created == TRUE && pChan->chan_num != i) cd2400ChanIntEnDisable(&pQusart->channel[i], FALSE); else if (pChan->chan_num == i) cd2400ChanIntEnDisable(&pQusart->channel[i], TRUE); } pQusart->devMode = pChan->chan_num + 1; } } /* end of if (mode == SIO_MODE_POLL) */ if (mode == SIO_MODE_INT) { if ( (pChan->chan_num+1) == pQusart->devMode) { /* ** device is in poll mode ** check if other channels need to be in polling mode */ for (i=0;i<pQusart->numChannels;i++) { if (pQusart->channel[i].created == TRUE && (pChan->chan_num != i) && pQusart->channel[i].channelMode == SIO_MODE_POLL ) break; } pollChannel = i; /* no other channels in polling mode, enable interrupts */ if (pollChannel == pQusart->numChannels) { for (i=0;i<pQusart->numChannels;i++) { if (pQusart->channel[i].created == TRUE) cd2400ChanIntEnDisable (&pQusart->channel[i], TRUE); } pQusart->devMode = 0; } else /* There is a channel need to be in polling mode */ { for (i=0;i<pQusart->numChannels;i++) { if (pQusart->channel[i].created == TRUE && i != pollChannel) cd2400ChanIntEnDisable (&pQusart->channel[i], FALSE); else if (i == pollChannel) cd2400ChanIntEnDisable (&pQusart->channel[i], TRUE); } pQusart->devMode = pollChannel + 1; } } } /* enable or disable device interrupt */ mode = pQusart->devMode ? SIO_MODE_POLL: SIO_MODE_INT; if (pChan->intEnDisable) (*pChan->intEnDisable)(mode); }/********************************************************************* * cd2400ChanIntEnDisable - enable or disable a channel**/static void cd2400ChanIntEnDisable ( CD2400_CHAN * pChan, int intEnable ) { CD2400_QUSART * pQusart = pChan->pQusart; *MPCC_CAR = pChan->chan_num; /* channel number */ while (*MPCC_CCR); if (intEnable == TRUE) *MPCC_IER = IER_RXDATA |IER_TXEMPTY; else *MPCC_IER = 0; /* disable interrupt */ }/******************************************************************************** cd2400CallbackInstall - install ISR callbacks to get put chars.*/static int cd2400CallbackInstall ( SIO_CHAN * pSioChan, int callbackType, STATUS (*callback)(), void * callbackArg ) { CD2400_CHAN * pChan = (CD2400_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); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -