?? ppc860scc.c
字號:
break;
case SIO_MODE_GET:
* (int *) arg = pChan->channelMode;
break;
case SIO_AVAIL_MODES_GET:
*(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
break;
default:
status = ENOSYS;
}
return (status);
}
/******************************************************************************
*
*
* ppc860Int - handle an SCC interrupt
*
* This routine is 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 & 0x0001)
{
pChan->uart.pSccReg->scce = 0x0001;
while (!(pChan->uart.rxBdBase [pChan->uart.rxBdNext].statusMode &
BD_RX_EMPTY_BIT))
{
/* process all filled receive buffers */
outChar = pChan->uart.rxBdBase[pChan->uart.rxBdNext].dataPointer[0];
pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode |=
BD_RX_EMPTY_BIT;
/* incr BD count */
pChan->uart.rxBdNext = (pChan->uart.rxBdNext + 1) %
pChan->uart.rxBdNum;
/* acknowledge interrupt ??? multiple events ??? */
pChan->uart.pSccReg->scce = 0x0001;
(*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 & 0x0002) &&
(pChan->channelMode != SIO_MODE_POLL))
{
pChan->uart.pSccReg->scce = 0x0002;
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 = 0x0002;
/* send transmit buffer */
pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode |=
BD_TX_READY_BIT;
/* incr BD count */
pChan->uart.txBdNext = (pChan->uart.txBdNext+ 1) %
pChan->uart.txBdNum;
}
}
/* acknowledge all other interrupts - ignore events */
pChan->uart.pSccReg->scce &= 0xfffc;
* CISR(pChan->regBase) = pChan->uart.intMask;
}
/******************************************************************************
*
*
* ppc860Startup - 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 &
BD_TX_READY_BIT)) &&
((*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 |=
BD_TX_READY_BIT;
/* incr BD count */
pChan->uart.txBdNext = (pChan->uart.txBdNext + 1) % pChan->uart.
txBdNum;
}
}
/******************************************************************************
*
* ppc860PollInput - 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 & 0x0001))
return (EAGAIN);
if (pChan->uart.rxBdBase[pChan->uart.rxBdNext].statusMode &
BD_RX_EMPTY_BIT)
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 |= BD_RX_EMPTY_BIT;
/* 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 &
BD_RX_EMPTY_BIT)
pChan->uart.pSccReg->scce = 0x0001;
return (OK);
}
/******************************************************************************
*
* ppc860PollOutput - 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;
int i;
/* wait a bit for the last character to get out */
/* because the PPC604 is a very fast processor */
/* ??? make the 10000 value a #define */
i = 0;
while( (i<10000) && (pChan->uart.txBdBase[pChan->uart.txBdNext].
statusMode & BD_TX_READY_BIT) )
{
i = i + 1;
}
/* is the transmitter ready to accept a character? */
/* if still not, we have a problem */
if (pChan->uart.txBdBase[pChan->uart.txBdNext].statusMode &
BD_TX_READY_BIT)
return(EAGAIN);
/* reset the transmitter status bit */
pChan->uart.pSccReg->scce = 0x0002;
/* 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 |= BD_TX_READY_BIT;
pChan->uart.txBdNext = (pChan->uart.txBdNext + 1) % pChan->uart.txBdNum;
return (OK);
}
/******************************************************************************
*
* ppc860CallbackInstall - 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);
break;
case SIO_CALLBACK_PUT_RCV_CHAR:
pChan->putRcvChar = callback;
pChan->putRcvArg = callbackArg;
return (OK);
break;
default:
return (ENOSYS);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -