📄 m8260sio.c
字号:
* Inspect bit 0 of the status word which is the empty flag: * 0 if buffer is full or if there was an error * 1 if buffer is not full */ M8260_SCC_16_RD((pSccChan->pBdBase + M8260_SCC_RCV_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus); /* if bit is set there is nothing */ while (!(bdStatus & M8260_SCC_UART_RX_BD_EMPTY)) { M8260_SCC_8_RD(pSccChan->rcvBufferAddr, outChar); /* * indicate that we've processed this buffer; set empty * flag to 1 indicating that the buffer is empty */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_RCV_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus |= M8260_SCC_UART_RX_BD_EMPTY); /* necessary when switching from write to read */ CACHE_PIPE_FLUSH (); /* pass the received character up to the tty driver */ (*pSccChan->putRcvChar) (pSccChan->putRcvArg,outChar); /* if driver is in polled mode, we're done */ if (pSccChan->channelMode == SIO_MODE_POLL) break; /* * If interrupt mode, read the status again; * it's possible a new char has arrived */ M8260_SCC_16_RD((pSccChan->pBdBase + M8260_SCC_RCV_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus); } } /* check for a transmit event and if a character needs to be output */ /* transmit event */ CACHE_PIPE_FLUSH (); if ((* pSCCE & M8260_SCC_UART_SCCX_TX ) && (pSccChan->channelMode != SIO_MODE_POLL)) /* ...and we're not polling */ { /* * clear transmit event bit by setting the bit in the event register. * This also clears the bit in SIPNR */ * pSCCE = M8260_SCC_UART_SCCX_TX; CACHE_PIPE_FLUSH (); if ((*pSccChan->getTxChar) (pSccChan->getTxArg, &outChar) == OK) { CACHE_PIPE_FLUSH (); /* wait for the ready bit to be 0 meaning the buffer is free */ do { M8260_SCC_16_RD((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus); } while (bdStatus & M8260_SCC_UART_TX_BD_READY); M8260_SCC_8_WR(pSccChan->txBufferAddr, outChar); /* write char */ /* set buffer length */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_LEN_OFF), 0x0001); /* set ready bit so CPM will process buffer */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus |= M8260_SCC_UART_TX_BD_READY); CACHE_PIPE_FLUSH (); } } /* * acknowledge all other interrupts - ignore events. This also clears * the bit in SIPNR */ * pSCCE &= ~(M8260_SCC_UART_SCCX_TX | M8260_SCC_UART_SCCX_RX); CACHE_PIPE_FLUSH (); }/********************************************************************************* m8260SioStartup - transmitter startup routine* * Starts transmission on the indicated channel** RETURNS: OK, or ENOSYS if in polled mode.*/LOCAL int m8260SioStartup ( M8260_SCC_CHAN *pSccChan /* ty device to start up */ ) { char outChar; UINT16 bdStatus; /* holder for the BD status */ if (pSccChan->channelMode == SIO_MODE_POLL) return (ENOSYS); /* * check if a transmit buffer is ready and if a character needs to be * output */ CACHE_PIPE_FLUSH (); /* before first read */ M8260_SCC_16_RD((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus); if (!(bdStatus & M8260_SCC_UART_TX_BD_READY)) if ((*pSccChan->getTxChar) (pSccChan->getTxArg, &outChar) == OK) { /* write char; set length; flag buffer as not empty */ M8260_SCC_8_WR(pSccChan->txBufferAddr, outChar); /* write char */ /* set buffer length */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_LEN_OFF), 0x0001); /* flag buffer as not empty */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus |= 0x8000); } CACHE_PIPE_FLUSH (); return (OK); }/******************************************************************************** m8260SioPollInput - poll the device for input.** Poll the indicated device for input characters** RETURNS: OK if a character arrived, ERROR on device error, EAGAIN* if the input buffer is empty.*/LOCAL int m8260SioPollInput ( SIO_CHAN * pSioChan, char * thisChar ) { M8260_SCC_CHAN * pSccChan = (M8260_SCC_CHAN *) pSioChan; UINT16 bdStatus; /* holder for the BD status */ UINT8 sccNum = pSccChan->sccNum; /* holder for the fcc number */ UINT8 scc = sccNum - 1; /* a convenience */ UINT32 immrVal = pSccChan->immrVal; /* holder for the immr value */ VUINT16 *pSCCE = (VUINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCE_OFFSET + (scc * M8260_SCC_OFFSET_NEXT_SCC)); CACHE_PIPE_FLUSH (); /* is there a receive event? */ if (!(* pSCCE & M8260_SCC_UART_SCCX_RX )) return (EAGAIN); /* is the buffer empty? */ M8260_SCC_16_RD((pSccChan->pBdBase + M8260_SCC_RCV_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus); /* if bit is high there is nothing */ if (bdStatus & M8260_SCC_UART_RX_BD_EMPTY) return (EAGAIN); /* get a character */ M8260_SCC_8_RD(pSccChan->rcvBufferAddr, * thisChar); /* set the empty bit */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_RCV_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus |= M8260_SCC_UART_RX_BD_EMPTY); CACHE_PIPE_FLUSH (); /* only clear RX event if no more characters are ready */ M8260_SCC_16_RD((pSccChan->pBdBase + M8260_SCC_RCV_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus); CACHE_PIPE_FLUSH (); /* if bit is high there is nothing */ if (bdStatus & M8260_SCC_UART_RX_BD_EMPTY) *pSCCE = M8260_SCC_UART_SCCX_RX; /* clear rx event bit */ CACHE_PIPE_FLUSH (); return (OK); }/******************************************************************************** m8260SioPollOutput - output a character in polled mode.** Transmit a character in polled mode** RETURNS: OK if a character is sent, ERROR on device error, EAGAIN* if the output buffer if full.*/static int m8260SioPollOutput ( SIO_CHAN * pSioChan, char outChar ) { M8260_SCC_CHAN * pSccChan = (M8260_SCC_CHAN *) pSioChan; int i; UINT16 bdStatus; /* holder for the BD status */ UINT8 sccNum = pSccChan->sccNum; /* holder for the fcc number */ UINT8 scc = sccNum - 1; /* a convenience */ UINT32 immrVal = pSccChan->immrVal; /* holder for the immr value */ VUINT16 *pSCCE = (VUINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCE_OFFSET + (scc * M8260_SCC_OFFSET_NEXT_SCC)); CACHE_PIPE_FLUSH (); /* * wait a bit for the last character to get out * because the PPC603 is a very fast processor */ for (i=0; i<M8260_SCC_POLL_OUT_DELAY; i++) ; /* * is the transmitter ready yet to accept a character? * if still not, we have a problem */ M8260_SCC_16_RD((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus); if (!(bdStatus & 0x8000)) return(EAGAIN); /* reset the transmitter status bit */ /* * clear transmit event bit by setting the bit in the event register. * This also clears the bit in SIPNR */ * pSCCE = M8260_SCC_UART_SCCX_TX; /* write char; set length; flag buffer as not empty */ M8260_SCC_8_WR(pSccChan->txBufferAddr, outChar); /* write char */ /* set buffer length */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_LEN_OFF), 0x0001); /* flag buffer as not empty */ M8260_SCC_16_WR((pSccChan->pBdBase + M8260_SCC_TX_BD_OFF + M8260_SCC_BD_STAT_OFF), bdStatus |= M8260_SCC_UART_TX_BD_READY); CACHE_PIPE_FLUSH (); return (OK); }/******************************************************************************** m8260SioCallbackInstall - install ISR callbacks to get and put chars.** Install the indicated ISR callback functions that are used to get and* put characters** RETURNS: NA**/static int m8260SioCallbackInstall ( SIO_CHAN * pSioChan, int callbackType, STATUS (* callback)(), void * callbackArg ) { M8260_SCC_CHAN * pSccChan = (M8260_SCC_CHAN *) pSioChan; CACHE_PIPE_FLUSH (); switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pSccChan->getTxChar = callback; pSccChan->getTxArg = callbackArg; return (OK); break; case SIO_CALLBACK_PUT_RCV_CHAR: pSccChan->putRcvChar = callback; pSccChan->putRcvArg = callbackArg; return (OK); break; default: return (ENOSYS); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -