📄 m8260sccsio.c
字号:
* This also clears the bit in SIPNR
*/
* pSCCE = M8260_SCC_UART_SCCX_RX;
CACHE_PIPE_FLUSH ();
/*
* as long as there is a character:
* 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 empty (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))
{
/* get the character from receive buffer */
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 */
/* check for a Tx event */
CACHE_PIPE_FLUSH ();
if ((* pSCCE & M8260_SCC_UART_SCCX_TX ) &&
(pSccChan->channelMode != SIO_MODE_POLL)) /* ...and we're not polling */
{
SCC_ISR_TX_ADD;
SCC_LOG(0, "m8260SioInt: Tx(%d). SCC%d.\n", numIsrEntriesTx, pSccChan->sccNum, 3,4,5,6);
/*
* 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
*
* This routine initiate a transmit cycle.
*
* 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 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 |= M8260_SCC_UART_TX_BD_READY);
}
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 */
VINT16 *pSCCE = (VINT16 *) (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 = 0;
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 */
VINT16 *pSCCE = (VINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCE_OFFSET +
(scc * M8260_SCC_OFFSET_NEXT_SCC));
CACHE_PIPE_FLUSH ();
/* get BD status */
M8260_SCC_16_RD((pSccChan->pBdBase +
M8260_SCC_TX_BD_OFF +
M8260_SCC_BD_STAT_OFF), bdStatus);
/* wait a bit for the last character to get out */
/* the PPC603 is a very fast processor */
while((i < M8260_SCC_POLL_OUT_DELAY) &&
(bdStatus & M8260_SCC_UART_TX_BD_READY))
{
i++;
M8260_SCC_16_RD((pSccChan->pBdBase +
M8260_SCC_TX_BD_OFF +
M8260_SCC_BD_STAT_OFF), bdStatus);
}
/*
* is the transmitter ready to accept a character?
* if still not, we have a problem
*/
if (bdStatus & M8260_SCC_UART_TX_BD_READY)
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/put chars.
*
* Install the indicated ISR callback functions that are used to get and
* put characters
*
* RETURNS: OK, or ENOSYS if <callbackType> is invalid.
*
*/
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 + -