📄 smc8260sio.c
字号:
/* enable this SMC's interrupt */
pChan->uart.pSmcReg->smce = SMCE_RX;
/* reset the receiver status bit */
pChan->uart.pSmcReg->smcm = SMCM_RX_MSK | SMCM_TX_MSK;
/* enables receive and transmit interrupts */
}
else
{
pChan->uart.pSmcReg->smcm = 0;
/* mask off the receive and transmit intrs */
* M8260_SIMR_L(pChan->regBase) &= (~(pChan->uart.intMask));
/* mask off this SMC's interrupt */
}
pChan->channelMode = arg;
intUnlock(oldlevel);
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);
}
/*******************************************************************************
*
* smc8260Int - handle an SMC interrupt
*
* This routine is called to handle SMC interrupts.
*/
void smc8260Int
(
PPC8260SMC_CHAN *pChan
)
{
char outChar;
FAST UINT16 dataLen = 0;
/* check for a receive event */
if (pChan->uart.pSmcReg->smce & SMCE_RX)
{
pChan->uart.pSmcReg->smce = SMCE_RX;
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.pSmcReg->smce = SMCE_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.pSmcReg->smce & SMCE_TX) &&
(pChan->channelMode != SIO_MODE_POLL))
{
pChan->uart.pSmcReg->smce = SMCE_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.pSmcReg->smce = SMCE_TX;
/* 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.pSmcReg->smce = (pChan->uart.pSmcReg->smce &
~(SMCE_RX | SMCE_TX));
* M8260_SIPNR_L(pChan->regBase) = pChan->uart.intMask;
}
/*******************************************************************************
*
* smc8260Startup - transmitter startup routine
*/
static void smc8260Startup
(
PPC8260SMC_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;
}
}
/******************************************************************************
*
* smc8260PollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, ERROR on device error, EAGAIN
* if the input buffer is empty.
*/
static int smc8260PollInput
(
SIO_CHAN * pSioChan,
char * thisChar
)
{
PPC8260SMC_CHAN * pChan = (PPC8260SMC_CHAN *) pSioChan;
if (!(pChan->uart.pSmcReg->smce & SMCE_RX))
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.pSmcReg->smce = SMCE_RX;
return (OK);
}
/******************************************************************************
*
* smc8260PollOutput - 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 smc8260PollOutput
(
SIO_CHAN * pSioChan,
char outChar
)
{
PPC8260SMC_CHAN * pChan = (PPC8260SMC_CHAN *) pSioChan;
int i;
/* wait a bit for the last character to get out */
/* because the PPC603 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.pSmcReg->smce = SMCE_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 |= BD_TX_READY_BIT;
pChan->uart.txBdNext = (pChan->uart.txBdNext + 1) % pChan->uart.txBdNum;
return (OK);
}
/******************************************************************************
*
* smc8260CallbackInstall - install ISR callbacks to get put chars.
*
*/
static int smc8260CallbackInstall
(
SIO_CHAN * pSioChan,
int callbackType,
STATUS (* callback)(),
void * callbackArg
)
{
PPC8260SMC_CHAN * pChan = (PPC8260SMC_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 + -