📄 bdislip.c
字号:
* pPSMR = M8260_SCC_UART_PSMR_FLC | M8260_SCC_UART_PSMR_CL_8BIT;
/* wait until the CP is clear */
do {
M8260_SCC_32_RD((M8260_CPCR (immrVal)), cpcrVal);
} while (cpcrVal & M8260_CPCR_FLG) ;
/* Tell CP to initialize tx and rx parameters for SCC */
cpcrVal = ( M8260_CPCR_OP (M8260_CPCR_RT_INIT)
| M8260_CPCR_SBC (M8260_CPCR_SBC_SCC1 | (scc * 0x1))
| M8260_CPCR_PAGE (M8260_CPCR_PAGE_SCC1 | (scc * 0x1))
| M8260_CPCR_FLG);
M8260_SCC_32_WR (M8260_CPCR (immrVal), cpcrVal);
/* clear all events */
*pSCCE = M8260_SCC_UART_SCCX_ALL_EVENTS;
/* enables the transmitter and receiver */
*pGSMR_L |= (M8260_SCC_GSMRL_ENT | M8260_SCC_GSMRL_ENR);
/* unmask interrupt (Tx, Rx only) */
*pSCCM |= (M8260_SCC_UART_SCCX_RX | M8260_SCC_UART_SCCX_TX);
/* enable SCC interrupts at the SIU Interrupt Controller */
if (SCC_NUM == 1) m8260IntEnable(INUM_SCC1);
else if (SCC_NUM == 2) m8260IntEnable(INUM_SCC2);
else if (SCC_NUM == 3) m8260IntEnable(INUM_SCC3);
else if (SCC_NUM == 4) m8260IntEnable(INUM_SCC4);
intUnlock (oldlevel); /* UNLOCK INTERRUPTS */
} /* sccInit */
/*******************************************************************************
*
* sccInterrupt - handle an SCC interrupt
*
* This routine is called to handle SCC interrupts.
*/
static void sccInterrupt(WDB_FSLIP_PKT_DEV *pPktDev)
{
UINT16 sccEvent;
UINT16 rxCount;
FAST char* pChar;
FAST char rxChar;
SCC_UART_BD* pBD;
/* read and clear events */
sccEvent = *sccChan.pSCCE;
*sccChan.pSCCE = sccEvent;
/* handle receive event */
if (sccEvent & M8260_SCC_UART_SCCX_RX) {
/* process all filled receive buffers */
pBD = sccChan.uart.rxBdBase + sccChan.uart.rxBdNext;
while (!(pBD->statusMode & M8260_SCC_UART_RX_BD_EMPTY)) {
/* append to frame buffer */
if ((rxFrame.state & STATE_BUSY) == 0) {
rxCount = pBD->dataLength;
pChar = pBD->dataPointer;
while (rxCount--) {
rxChar = *pChar++;
if (rxChar == SLIP_END) {
if (rxFrame.pNext > rxFrame.data) {
struct mbuf* pMbuf = wdbMbufAlloc();;
if (pMbuf) {
wdbMbufClusterInit (pMbuf,
rxFrame.data,
rxFrame.pNext - rxFrame.data,
(int (*)())wdbPktFree,
(int)pPktDev);
(*pPktDev->wdbDrvIf.stackRcv) (pMbuf); /* invoke callback */
rxFrame.state |= STATE_BUSY;
} /* if */
else {
rxFrame.state = 0;
rxFrame.pNext = rxFrame.data;
} /* else */
break;
} /* if */
} /* if */
else if (rxChar == SLIP_ESC) {
rxFrame.state |= STATE_ESC;
} /* else if */
else {
/* check overflow */
if ((rxFrame.pNext - rxFrame.data) >= WDB_FSLIP_PKT_MTU) {
rxFrame.state = 0;
rxFrame.pNext = rxFrame.data;
break;
} /* if */
if (rxFrame.state & STATE_ESC) {
rxFrame.state &= (~STATE_ESC);
if (rxChar == SLIP_ESC_END) *rxFrame.pNext++ = SLIP_END;
else if (rxChar == SLIP_ESC_ESC) *rxFrame.pNext++ = SLIP_ESC;
} /* if */
else {
*rxFrame.pNext++ = rxChar;
} /* else */
} /* else */
} /* while */
} /* if */
/* switch to next buffer */
pBD->statusMode |= M8260_SCC_UART_RX_BD_EMPTY;
sccChan.uart.rxBdNext = (sccChan.uart.rxBdNext + 1) % sccChan.uart.rxBdNum;
pBD = sccChan.uart.rxBdBase + sccChan.uart.rxBdNext;
} /* while */
} /* if */
/* handle transmit event */
if ((sccEvent & M8260_SCC_UART_SCCX_TX) && (txFrame.length > 0)) {
/* process all empty transmit buffers */
pBD = sccChan.uart.txBdBase + sccChan.uart.txBdNext;
while (!(pBD->statusMode & M8260_SCC_UART_TX_BD_READY) && (txFrame.length > 0)) {
pBD->dataLength = 0;
pChar = pBD->dataPointer;
while ((pBD->dataLength < sccChan.uart.txBufSize) && (txFrame.length > 0)) {
*pChar++ = *txFrame.pNext++;
pBD->dataLength++;
txFrame.length--;
} /* while */
/* switch to next buffer */
pBD->statusMode |= M8260_SCC_UART_TX_BD_READY;
sccChan.uart.txBdNext = (sccChan.uart.txBdNext + 1) % sccChan.uart.txBdNum;
pBD = sccChan.uart.txBdBase + sccChan.uart.txBdNext;
} /* while */
} /* if */
} /* sccInterrupt */
/*******************************************************************************
*
* wdbFslipPktDevInit - init the fast SLIP paket driver
*
* This routine init the WDB agents paket driver.
*
* RETURNS: initialized WDB_SLIP_PKT_DEV structure
*
*/
void wdbFslipPktDevInit
(
WDB_FSLIP_PKT_DEV *pPktDev,
void (*stackRcv)()
)
{
VOIDFUNCPTR* ivec;
/* setup driver interface structure */
pPktDev->wdbDrvIf.mode = WDB_COMM_MODE_INT;
pPktDev->wdbDrvIf.mtu = WDB_FSLIP_PKT_MTU;
pPktDev->wdbDrvIf.stackRcv = stackRcv;
pPktDev->wdbDrvIf.devId = (WDB_FSLIP_PKT_DEV *)pPktDev;
pPktDev->wdbDrvIf.pollRtn = wdbPktPoll;
pPktDev->wdbDrvIf.pktTxRtn = wdbPktTx;
pPktDev->wdbDrvIf.modeSetRtn = wdbPktModeSet;
/* init receive frame */
rxFrame.state = 0;
rxFrame.pNext = rxFrame.data;
/* init transmit frame */
txFrame.length = 0;
txFrame.pNext = txFrame.data;
/* init SCC channel in CPM */
sccInit();
/* connect interrupt service */
if (SCC_NUM == 1) ivec = INUM_TO_IVEC(INUM_SCC1);
else if (SCC_NUM == 2) ivec = INUM_TO_IVEC(INUM_SCC2);
else if (SCC_NUM == 3) ivec = INUM_TO_IVEC(INUM_SCC3);
else if (SCC_NUM == 4) ivec = INUM_TO_IVEC(INUM_SCC4);
(void)intConnect (ivec, (VOIDFUNCPTR) sccInterrupt, (int)pPktDev);
} /* wdbFslipPktDevInit */
/******************************************************************************
*
* wdbPktTx - transmit a packet
*
* This routine can only be called by the WDB agent.
*
* RETURNS: OK, or ERROR if a packet is currently being transmitted, or
* the packet is too large to send.
*/
static STATUS wdbPktTx
(
void * pDev,
struct mbuf * pMbuf
)
{
int pktSize;
u_char txChar;
SCC_UART_BD* pTxBD;
u_char* pPkt;
u_char* pBuf;
static u_char pktBuf[WDB_FSLIP_PKT_MTU];
/* check if buffer free */
if (txFrame.length > 0) return (ERROR);
/* copy transmit data to local buffer */
wdbMbufDataGet(pMbuf, pktBuf, WDB_FSLIP_PKT_MTU, &pktSize);
wdbMbufChainFree(pMbuf);
/* build SLIP frame */
pPkt = pktBuf;
pBuf = txFrame.data;
while (pktSize--) {
txChar = *pPkt++;
if (txChar == SLIP_END) {
*pBuf++ = SLIP_ESC;
*pBuf++ = SLIP_ESC_END;
} /* if */
else if (txChar == SLIP_ESC) {
*pBuf++ = SLIP_ESC;
*pBuf++ = SLIP_ESC_ESC;
} /* else if */
else {
*pBuf++ = txChar;
} /* else */
} /* while */
*pBuf++ = SLIP_END; /* mark end of frame */
txFrame.length = pBuf - txFrame.data;
txFrame.pNext = txFrame.data;
/* start transmitting (send SLIP_END) */
pTxBD = sccChan.uart.txBdBase + sccChan.uart.txBdNext;
if (pTxBD->statusMode & M8260_SCC_UART_TX_BD_READY) return (ERROR);
*pTxBD->dataPointer = SLIP_END;
pTxBD->dataLength = 1;
sccChan.uart.txBdNext = (sccChan.uart.txBdNext + 1) % sccChan.uart.txBdNum;
pTxBD->statusMode |= M8260_SCC_UART_TX_BD_READY;
return (OK);
} /* wdbPktTx */
/******************************************************************************
*
* wdbPktFree - free the input buffer
*
* This is the callback used to let us know the agent is done with the
* input buffer we loaded it.
*
* RETURNS: N/A
*/
static void wdbPktFree
(
void * pDev
)
{
rxFrame.state = 0;
rxFrame.pNext = rxFrame.data;
}
/******************************************************************************
*
* wdbPktModeSet - switch driver modes
*
* RETURNS: OK for a supported mode, else ERROR
*/
static STATUS wdbPktModeSet
(
void * pDev,
uint_t newMode
)
{
WDB_FSLIP_PKT_DEV * pPktDev = pDev;
if (newMode == WDB_COMM_MODE_INT)
pPktDev->wdbDrvIf.mode = WDB_COMM_MODE_INT;
else if (newMode == WDB_COMM_MODE_POLL)
pPktDev->wdbDrvIf.mode = WDB_COMM_MODE_POLL;
else
return (ERROR);
return (OK);
}
/******************************************************************************
*
* wdbPktPoll - poll for a packet
*
* This routine polls for a packet. If a packet has arrived it invokes
* the agents callback.
*
* RETURNS: OK if a packet has arrived, else ERROR.
*/
static STATUS wdbPktPoll
(
void * pDev
)
{
WDB_FSLIP_PKT_DEV * pPktDev = pDev;
struct mbuf * pMbuf;
return (ERROR);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -