⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bdislip.c

📁 BDI2000 FOR PPC860 固件程序
💻 C
📖 第 1 页 / 共 2 页
字号:
  * 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 + -