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

📄 m8260sccsio.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * 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 + -