📄 coldfiresio.c
字号:
return (OK); }/******************************************************************************** coldfireCallbackInstall - 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:* Returns OK on success, or ENOSYS for an unsupported callback type.*/LOCAL int coldfireCallbackInstall ( COLDFIRE_CHAN * pChan, int callbackType, STATUS (*callback)(), void * callbackArg ) { 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); } }/******************************************************************************** coldfirePollOutput - output a character in polled mode.** This routine polls the status register to see if the TxRDY bit has been set.* This signals that the transmit holding register is empty and that the* UART is ready for transmission.** RETURNS:* Returns OK if a character sent, EIO on device error, EAGAIN* if the output buffer is full.*/LOCAL int coldfirePollOutput ( COLDFIRE_CHAN *pChan, char outChar ) { char statusReg; /* is the transitter ready to accept a character? */ statusReg = COLDFIRE_READ (pChan->sr); if ((statusReg & COLDFIRE_UART_SR_TXRDY) == 0x00) return (EAGAIN); /* write out the character */ COLDFIRE_WRITE (pChan->tb, outChar); return (OK); }/******************************************************************************** coldfirePollInput - poll the device for input.** This routine polls the status register to see if the RxRDY bit is set.* This gets set when the UART receives a character and signals the* pressence of a character in the receive buffer.** RETURNS:* Returns OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty.*/LOCAL int coldfirePollInput ( COLDFIRE_CHAN *pChan, char * thisChar ) { char statusReg; statusReg = COLDFIRE_READ (pChan->sr); if ((statusReg & COLDFIRE_UART_SR_RXRDY) == 0x00) return (EAGAIN); *thisChar = COLDFIRE_READ (pChan->rb); return (OK); }/******************************************************************************** coldfireModeSet - change channel mode setting** This driver supports both polled and interrupt modes and is capable of* switching between modes dynamically. If interrupt mode is desired this* routine enables the channels receiver, transmitter interrupt and the* received break condition interrupt. If polled mode is desired the xmitrs for* the specified channel is enabled.** RETURNS:* Returns a status of OK if the mode was set else ERROR.*/LOCAL STATUS coldfireModeSet ( COLDFIRE_CHAN * pChan, UINT newMode ) { int oldlevel; if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT)) return (ERROR); oldlevel = intLock (); if ((newMode == SIO_MODE_INT) && pChan->intEnable) { /* Enable the interrupts for receiver/transmitter conditions */ coldfireImrSetClr (pChan, COLDFIRE_UART_IMR_TXRDY | COLDFIRE_UART_IMR_RXRDY, 0); } else { /* Disable interrupts and enable the transmitter for the channel */ coldfireImrSetClr (pChan, 0, COLDFIRE_UART_IMR_TXRDY | COLDFIRE_UART_IMR_RXRDY); COLDFIRE_WRITE (pChan->cr, COLDFIRE_UART_CR_TX_ENABLE); } pChan->mode = newMode; intUnlock (oldlevel); return (OK); }/******************************************************************************** coldfireBaudSet - change baud rate for channel** This routine sets the baud rate for the UART. The interrupts are disabled* during chip access.** RETURNS:* Returns a status of OK if the baud rate was set else ERROR.*/LOCAL STATUS coldfireBaudSet ( COLDFIRE_CHAN * pChan, UINT baud ) { if (!baud) return (ERROR); if (baud != pChan->baudRate) { UINT val; int oldlevel; val = ((pChan->clkRate / baud) + 16) / 32; if ((val < 2) || (val > 0xffff)) return (ERROR); oldlevel = intLock (); pChan->baudRate = baud; COLDFIRE_WRITE (pChan->bg1, val >> 8); COLDFIRE_WRITE (pChan->bg2, val); intUnlock (oldlevel); } return (OK); }/******************************************************************************** coldfireOptsSet - set the serial options** Set the channel operating mode to that specified. All sioLib options* are supported: CLOCAL, CREAD, CSIZE, PARENB, and PARODD.** Note, this routine disables the transmitter. The calling routine* may have to re-enable it.** RETURNS:* Returns OK to indicate success, otherwise ERROR is returned*/LOCAL STATUS coldfireOptsSet ( COLDFIRE_CHAN * pChan, /* ptr to channel */ UINT options /* new hardware options */ ) { int mr1Value; int mr2Value; int lvl; if ((pChan == NULL) || (options & 0xffffff00)) return (ERROR); /* Reset the transmitters & receivers */ switch (options & CSIZE) { case CS5: mr1Value = COLDFIRE_UART_MR1_BITS_CHAR_5; break; case CS6: mr1Value = COLDFIRE_UART_MR1_BITS_CHAR_6; break; case CS7: mr1Value = COLDFIRE_UART_MR1_BITS_CHAR_7; break; default: case CS8: mr1Value = COLDFIRE_UART_MR1_BITS_CHAR_8; break; } if (options & STOPB) mr2Value = COLDFIRE_UART_MR2_STOP_BITS_2; else mr2Value = COLDFIRE_UART_MR2_STOP_BITS_1; switch (options & (PARENB|PARODD)) { case PARENB|PARODD: mr1Value |= COLDFIRE_UART_MR1_ODD_PARITY; break; case PARENB: mr1Value |= COLDFIRE_UART_MR1_EVEN_PARITY; break; case PARODD: mr1Value |= COLDFIRE_UART_MR1_PAR_MODE_MULTI; break; default: case 0: mr1Value |= COLDFIRE_UART_MR1_NO_PARITY; break; } if (!(options & CLOCAL)) { /* enable hardware flow control */ mr1Value |= COLDFIRE_UART_MR1_RX_RTS; mr2Value |= COLDFIRE_UART_MR2_TX_CTS; } lvl = intLock (); /* now reset the channel mode registers */ COLDFIRE_WRITE (pChan->cr, COLDFIRE_UART_CR_RESET_MODE_PTR | COLDFIRE_UART_CR_RX_DISABLE | COLDFIRE_UART_CR_TX_DISABLE); COLDFIRE_WRITE (pChan->cr, COLDFIRE_UART_CR_RESET_TX); COLDFIRE_WRITE (pChan->cr, COLDFIRE_UART_CR_RESET_RX); COLDFIRE_WRITE (pChan->mr, mr1Value); /* mode register 1 */ COLDFIRE_WRITE (pChan->mr, mr2Value); /* mode register 2 */ if (options & CREAD) COLDFIRE_WRITE (pChan->cr, COLDFIRE_UART_CR_RX_ENABLE); pChan->options = options; intUnlock (lvl); return (OK); }/******************************************************************************** coldfireIoctl - special device control** RETURNS:* Returns OK on success, EIO on device error, ENOSYS on unsupported* request.*/LOCAL int coldfireIoctl ( COLDFIRE_CHAN * pChan, /* device to control */ int request, /* request code */ void * someArg /* some argument */ ) { STATUS result = OK; int arg = (int)someArg; switch (request) { case SIO_BAUD_SET: if (coldfireBaudSet(pChan, arg) != OK) result = EIO; break; case SIO_BAUD_GET: *(int *)arg = pChan->baudRate; return (OK); case SIO_MODE_SET: if (coldfireModeSet(pChan, arg) != OK) result = EIO; break; case SIO_MODE_GET: *(int *)arg = pChan->mode; return (OK); case SIO_AVAIL_MODES_GET: *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; return (OK); case SIO_HW_OPTS_SET: /* change options, then set mode to restart chip correctly */ if (coldfireOptsSet(pChan, arg) != OK) result = EIO; coldfireModeSet (pChan, pChan->mode); break; case SIO_HW_OPTS_GET: return (pChan->options); default: return (ENOSYS); } return (result); }/******************************************************************************** coldfireIntWr - handle a transmitter interrupt** This routine handles write interrupts from the UART. This isr is invoked* when the TxRDY bit in the interrupt status register has been set. If there* is no character to transmit the transmitter is disabled.** RETURNS: N/A*/LOCAL void coldfireIntWr ( COLDFIRE_CHAN * pChan ) { char outChar; if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR) { /* if char available, tx it */ COLDFIRE_WRITE (pChan->tb, outChar); } else { COLDFIRE_WRITE (pChan->cr, COLDFIRE_UART_CR_TX_DISABLE); } }/******************************************************************************* coldfireIntRd - handle a reciever interrupt** This routine handles read interrupts from the UART.* The UART has been programmed to generate read interrupts when the RXRDY* status bit has been set in the interrupt status register. When a character* has been received it is removed from the receive buffer.** RETURNS: N/A*/LOCAL void coldfireIntRd ( COLDFIRE_CHAN * pChan ) { UCHAR inchar; while (COLDFIRE_READ(pChan->sr) & COLDFIRE_UART_SR_RXRDY) { inchar = COLDFIRE_READ (pChan->rb); (*pChan->putRcvChar) (pChan->putRcvArg, inchar); if (pChan->mode != SIO_MODE_INT) break; } }/********************************************************************************* coldfireInt - handle all interrupts in one vector** All interrupts share a single interrupt vector.* We identify each interrupting source and service it.* We must service all interrupt sources for those systems with edge-* sensitive interrupt controllers.** RETURNS: N/A*/void coldfireInt ( COLDFIRE_CHAN * pChan ) { UCHAR intStatus; /* loop until all sources have been handled */ while (intStatus = (COLDFIRE_READ(pChan->isr) & pChan->imrCopy)) { if (intStatus & COLDFIRE_UART_ISR_TXRDY) coldfireIntWr (pChan); if (intStatus & COLDFIRE_UART_ISR_RXRDY) coldfireIntRd (pChan); if (pChan->mode != SIO_MODE_INT) break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -