📄 ixp425sio.c
字号:
status = ixp425SioBaudSet (pChan, arg); break; case SIO_BAUD_GET: *(int *)arg = pChan->baudRate; break; case SIO_MODE_SET: status = (ixp425SioModeSet (pChan, arg) == OK) ? OK : EIO; break; case SIO_MODE_GET: *(int *)arg = pChan->channelMode; break; case SIO_AVAIL_MODES_GET: *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; break; case SIO_HW_OPTS_SET: status = (ixp425SioOptsSet (pChan, arg) == OK) ? OK : EIO; break; case SIO_HW_OPTS_GET: *(int *)arg = pChan->options; break; case SIO_HUP: /* Does nothing for now */ break; case SIO_OPEN: /* Does nothing for now */ break; default: status = ENOSYS; } return (status); }/********************************************************************************* ixp425SioIntWr - handle a transmitter interrupt ** This routine handles write interrupts from the UART. It reads a character* and puts it in the transmit holding register of the device for transfer.* If there are no more characters to transmit, transmission is disabled by * clearing the transmit interrupt enable bit in the IER(int enable register).* Any pending recieve data is also serviced.** RETURNS: N/A**/void ixp425SioIntWr ( IXP425_SIO_CHAN * pChan /* pointer to channel */ ) { char outChar; unsigned int charCnt = 0; while( (charCnt < IXP425_SIO_MAX_TX_CNT) ) { if((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR) { /* * At the time of this writing the TDRQ bit of the LSR is not working so we * can't check for character overuns. We get around this by making sure we only ever * write less then the size of the FIFO per ISR as represented by IXP425_SIO_MAX_CNT. */ REG(THR, pChan) = (unsigned int)outChar;#ifdef IXP425_SIO_DEBUG pChan->txCount++;#endif charCnt++; } else { break; } } if (charCnt == 0) pChan->ier &= (~IER_TIE); /* disable Tx Int */ /* Service any pending receive characters */ /* ixp425SioIntRd(pChan); */ }/********************************************************************************* ixp425SioIntRd - handle a receiver interrupt ** This routine handles read interrupts from the UART.** RETURNS: N/A**/LOCAL void ixp425SioIntRd ( IXP425_SIO_CHAN * pChan /* pointer to channel */ ) { char inchar; volatile char lsr; unsigned int charCnt = IXP425_SIO_MAX_RX_CNT; lsr = REG(LSR, pChan); while( (lsr & LSR_DR) && (charCnt != 0) ) { inchar = REG(RBR, pChan); if (lsr & LSR_FIFOE){ break; } (*pChan->putRcvChar)(pChan->putRcvArg, inchar);#ifdef IXP425_SIO_DEBUG pChan->rxCount++;#endif --charCnt; lsr = REG(LSR, pChan); } }#ifdef IXP425_SIO_DEBUG/********************************************************************************* ixp425SioIntErr - handle an error interrupt ** This routine handles error interrupts from the UART. ** RETURNS: N/A**/void ixp425SioIntErr ( IXP425_SIO_CHAN * pChan, /* pointer to channel */ char intErr ) { if(intErr & LSR_OE) pChan->overrunErr++; if(intErr & LSR_PE) pChan->parityErr++; if(intErr & LSR_FE) pChan->framingErr++; if(intErr & LSR_BI) pChan->breakErr++; }#endif/********************************************************************************* ixp425SioInt - interrupt level processing** This function handles four sources of interrupts from the UART. They are* prioritized in the following order by the Interrupt Identification Register* 'Receiver Line Status', 'Received Data Ready', 'Transmit Holding Register Empty'* and 'Modem Status'.** When a modem status interrupt occurs, the transmit interrupt is enabled if* the CTS signal is TRUE.** RETURNS: N/A*/void ixp425SioInt ( IXP425_SIO_CHAN * pChan /* pointer to channel */ ) { FAST volatile char intStatus; /* read the Interrrupt Identification Register */ intStatus = (char)((REG(IIR, pChan)) & 0x0f); pChan->ier = (char)(REG(IER, pChan)); REG(IER, pChan) = (unsigned int) (pChan->ier & 0xE0); /* disable interrupts 0x1f */ switch (intStatus) { case IIR_RLS: /* overrun,parity error and break interrupt */ intStatus = REG(LSR, pChan); /* read LSR to reset interrupt */#ifdef IXP425_SIO_DEBUG ixp425SioIntErr (pChan, intStatus);#endif break; case IIR_RDA: /* received data available */ case IIR_TIMEOUT: ixp425SioIntRd (pChan); break; case IIR_THRE: /* transmitter holding register empty */ ixp425SioIntWr (pChan); break; case IIR_MSTAT: /* modem status register */ { char msr; msr = REG(MSR, pChan); /* if CTS is asserted by modem, enable tx interrupt */ if ((msr & MSR_CTS) && (msr & MSR_DCTS)) pChan->ier |= IER_TIE; else pChan->ier &= (~IER_TIE); } break; default: break; } REG(IER, pChan) = (unsigned int) pChan->ier; /* re-enable interrupts */ }/********************************************************************************* ixp425SioTxStartup - transmitter startup routine** Call interrupt level character output routine and enable interrupt if it is* in interrupt mode with no hardware flow control.* If the option for hardware flow control is enabled and CTS is set TRUE,* then the Tx interrupt is enabled.* * RETURNS: N/A*/LOCAL void ixp425SioTxStartup ( IXP425_SIO_CHAN * pChan /* pointer to channel */ ) { char mask; if (pChan->channelMode == SIO_MODE_INT) { if (pChan->options & CLOCAL) /* Software flow control */ { pChan->ier |= IER_TIE; REG(IER, pChan) = (unsigned int) pChan->ier; } else { mask = REG(MSR, pChan) & MSR_CTS; if (mask & MSR_CTS) pChan->ier |= IER_TIE; else pChan->ier &= (~IER_TIE); REG(IER, pChan) = (unsigned int) pChan->ier; } } }/******************************************************************************** ixp425SioPollOutput - output a character in polled mode. Used by the * Windriver debug agent.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the output buffer if full.*/LOCAL int ixp425SioPollOutput ( IXP425_SIO_CHAN * pChan, /* pointer to channel */ char outChar /* char to send */ ) { char pollStatus = REG(LSR, pChan); char msr = REG(MSR, pChan); if (!(pollStatus & LSR_TDRQ)) return (EAGAIN); if (!(pChan->options & CLOCAL)) /* hardare flow control */ { if (msr & MSR_CTS) { REG(THR, pChan) = outChar;#ifdef IXP425_SIO_DEBUG pChan->txCount++;#endif } else return (EAGAIN); } else { REG(THR, pChan) = outChar; /* transmit character */#ifdef IXP425_SIO_DEBUG pChan->txCount++;#endif } return (OK); }/******************************************************************************** ixp425SioPollInput - poll the device for input. Used by the Windriver* debug agent.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty.*/LOCAL int ixp425SioPollInput ( IXP425_SIO_CHAN * pChan, /* pointer to channel */ char * pChar /* pointer to char */ ) { char pollStatus = REG(LSR, pChan); if (!(pollStatus & LSR_DR)) return (EAGAIN); *pChar = REG(RBR, pChan);#ifdef IXP425_SIO_DEBUG pChan->rxCount++;#endif return (OK); }/******************************************************************************** ixp425SioCallbackInstall - install ISR callbacks to get/put chars.** This routine installs the callback functions for the driver** RETURNS: OK on success or ENOSYS on unsupported callback type.*/LOCAL int ixp425SioCallbackInstall ( SIO_CHAN * pSioChan, /* pointer to device to control */ int callbackType, /* callback type(tx or receive) */ STATUS (*callback)(), /* pointer to callback function */ void * callbackArg /* callback function argument */ ) { IXP425_SIO_CHAN * pChan = (IXP425_SIO_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); } }/******************************************************************************** ixp425SioStatsShow - display UART error statistics.** PRE: This routine requires that printf() is available.** RETURNS: N/A*/void ixp425SioStatsShow ( IXP425_SIO_CHAN * pChan ) { printf("\nIXP425 UART Statistics:");#ifdef IXP425_SIO_DEBUG printf("\nrxCount:\t%u", pChan->rxCount); printf("\ntxCount:\t%u", pChan->txCount); printf("\noverrun Errors:\t%u", pChan->overrunErr); printf("\nparity Errors:\t%u", pChan->parityErr); printf("\nframing Errors:\t%u", pChan->framingErr); printf("\nbreak Errors:\t%u\n", pChan->breakErr);#else printf("\nUART statistics not available\n");#endif /* IXP425_SIO_DEBUG */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -