📄 ppc860sioscc.c
字号:
if ((pChan->channelMode == SIO_MODE_POLL) && (arg == SIO_MODE_INT))
{
int i;
for (i=0; i < pChan->uart.txBdNum; i++)
while (pChan->uart.txBdBase
[(pChan->uart.txBdNext + i) % pChan->uart.txBdNum].
statusMode & SCC_UART_TX_BD_READY);
}
if (arg == SIO_MODE_INT)
{
*CISR(pChan->regBase) = pChan->uart.intMask
; /* reset the SCC's interrupt status bit */
*CIMR(pChan->regBase) |= pChan->uart.intMask
; /* enable this SCC's interrupt */
pChan->uart.pSccReg->scce = SCC_UART_SCCX_RX
; /* reset the receiver status bit */
pChan->uart.pSccReg->sccm = SCC_UART_SCCX_RX | SCC_UART_SCCX_TX
; /* enables the receive and transmit interrupts */
}
else
{
pChan->uart.pSccReg->sccm = 0
; /* mask off the receive and transmit interrupts */
*CIMR(pChan->regBase) &= (~(pChan->uart.intMask));
; /* mask off this SCC's interrupt */
}
pChan->channelMode = arg;
intUnlock(oldlevel);
break;
case SIO_MODE_GET:
*(int *)arg = pChan->channelMode;
return (OK);
case SIO_AVAIL_MODES_GET:
*(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
return (OK);
default:
status = ENOSYS;
}
return (status);
}
/*******************************************************************************
*
* ppc860SccInt - handle an SCC interrupt
*
* This routine gets called to handle SCC interrupts.
*/
void ppc860SccInt
(
PPC860SCC_CHAN *pChan
)
{
char outChar;
FAST UINT16 dataLen = 0;
/* check for a receive event */
if (pChan->uart.pSccReg->scce & SCC_UART_SCCX_RX)
{
pChan->uart.pSccReg->scce = SCC_UART_SCCX_RX;
while (!(pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode &
SCC_UART_RX_BD_EMPTY))
{
/* process all filled receive buffers */
outChar = pChan->uart.rxBdBase[pChan->uart.rxBdNext].dataPointer[0];
pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode |=
SCC_UART_RX_BD_EMPTY;
/* incr BD count */
pChan->uart.rxBdNext = (pChan->uart.rxBdNext + 1) %
pChan->uart.rxBdNum;
/* acknowledge interrupt */
pChan->uart.pSccReg->scce = SCC_UART_SCCX_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.pSccReg->scce & SCC_UART_SCCX_TX) &&
(pChan->channelMode != SIO_MODE_POLL) )
{
pChan->uart.pSccReg->scce = SCC_UART_SCCX_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.pSccReg->scce = SCC_UART_SCCX_TX;
/* send transmit buffer */
pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode |=
SCC_UART_TX_BD_READY;
/* incr BD count */
pChan->uart.txBdNext = (pChan->uart.txBdNext+ 1) % pChan->uart.txBdNum;
}
}
/* acknowledge all other interrupts - ignore events */
pChan->uart.pSccReg->scce = (pChan->uart.pSccReg->scce & ~(SCC_UART_SCCX_RX |
SCC_UART_SCCX_TX));
*CISR(pChan->regBase) = pChan->uart.intMask;
}
/*******************************************************************************
*
* ppc860SccStartup - transmitter startup routine
*/
static void ppc860SccStartup
(
PPC860SCC_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 &
SCC_UART_TX_BD_READY)) &&
((*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 |=
SCC_UART_TX_BD_READY;
/* incr BD count */
pChan->uart.txBdNext = (pChan->uart.txBdNext + 1) % pChan->uart.txBdNum;
}
}
/******************************************************************************
*
* ppc860SccPollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, ERROR on device error, EAGAIN
* if the input buffer is empty.
*/
static int ppc860SccPollInput
(
SIO_CHAN * pSioChan,
char * thisChar
)
{
PPC860SCC_CHAN * pChan = (PPC860SCC_CHAN *)pSioChan;
if ( !(pChan->uart.pSccReg->scce & SCC_UART_SCCX_RX) )
return (EAGAIN);
if (pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode &
SCC_UART_RX_BD_EMPTY)
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 |=
SCC_UART_RX_BD_EMPTY;
/* 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 &
SCC_UART_RX_BD_EMPTY)
pChan->uart.pSccReg->scce = SCC_UART_SCCX_RX;
return (OK);
}
/******************************************************************************
*
* ppc860SccPollOutput - output a character in polled mode.
*
* RETURNS: OK if a character arrived, ERROR on device error, EAGAIN
* if the output buffer if full.
*/
static int ppc860SccPollOutput
(
SIO_CHAN * pSioChan,
char outChar
)
{
PPC860SCC_CHAN * pChan = (PPC860SCC_CHAN *)pSioChan;
/* is the transmitter ready to accept a character? */
if (pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode &
SCC_UART_TX_BD_READY)
return(EAGAIN);
/* reset the transmitter status bit */
pChan->uart.pSccReg->scce = SCC_UART_SCCX_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 |=
SCC_UART_TX_BD_READY;
pChan->uart.txBdNext = (pChan->uart.txBdNext + 1) % pChan->uart.txBdNum;
return (OK);
}
/******************************************************************************
*
* ppc860SccCallbackInstall - install ISR callbacks to get put chars.
*/
static int ppc860SccCallbackInstall
(
SIO_CHAN * pSioChan,
int callbackType,
STATUS (*callback)(),
void * callbackArg
)
{
PPC860SCC_CHAN * pChan = (PPC860SCC_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 + -