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

📄 smc8260sio.c

📁 Embedded Planet公司的ep8260单板计算机的BSP包(VxWorks)
💻 C
📖 第 1 页 / 共 2 页
字号:
				/* 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 + -