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

📄 primecellsio.c

📁 ATMEL920T的BSP及ETH等已经设备驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:

        if ((brd < 1) || (brd > 0xFFF))
        {
            status = EIO;		/* baud rate out of range */
            break;
        }

        /* disable interrupts during chip access */

        oldlevel = intLock ();


        /* Set baud rate divisor in UART */
        /*
        	    AMBA_UART_REG_WRITE(pChan, L_UBRLCR, brd & 0xFF);
        	    AMBA_UART_REG_WRITE(pChan, M_UBRLCR, (brd >> 8) & 0xF);
        */
        brd=(pChan->xtal*10) /(arg*16);
        if ((brd % 10) >= 5)
            brd = (brd / 10) + 1;
        else
            brd /= 10;
        AMBA_UART_REG_WRITE(pChan, DBGU_BRGR, brd);	/*huxianpeng 20060104*/
        /*
         * Set word format, enable FIFOs: set 8 bits, 1 stop bit, no parity.
         * This also latches the writes to the two (sub)registers above.
         */
        /*
        	    AMBA_UART_REG_WRITE(pChan, H_UBRLCR,
        		(UINT8)(WORD_LEN_8 | ONE_STOP | PARITY_NONE | FIFO_ENABLE));
        */
        AMBA_UART_REG_WRITE(pChan, DBGU_MR,
                            AT91C_US_CHMODE_NORMAL | AT91C_US_PAR_NONE );	/*huxianpeng 20060104*/

        pChan->baudRate = arg;

        intUnlock (oldlevel);

        break;


    case SIO_BAUD_GET:

        /* Get the baud rate and return OK */

        *(int *)arg = pChan->baudRate;
        break;


    case SIO_MODE_SET:

        /*
         * Set the mode (e.g., to interrupt or polled). Return OK
         * or EIO for an unknown or unsupported mode.
         */

        if ((arg != SIO_MODE_POLL) && (arg != SIO_MODE_INT))
        {
            status = EIO;
            break;
        }

        oldlevel = intLock ();

        if (arg == SIO_MODE_INT)
        {
            /* Ensure that only Receive ints are generated. */
            /*		AMBA_UART_REG_BIT_CLR(pChan,
            				      UARTCON, 
                                                  UART_RTIE | UART_TIE | 
            				      UART_RIE | UART_MSIE );
            		AMBA_UART_REG_BIT_SET(pChan, UARTCON, UART_RIE | UART_RTIE);
            */
            AMBA_UART_REG_WRITE(pChan, DBGU_IDR, 0xFFFFFFFF);
            AMBA_UART_REG_WRITE(pChan, DBGU_IER, 0x0);
            AMBA_UART_REG_BIT_SET(pChan, DBGU_IER, (DBGU_IER_RXRDY/*|DBGU_IER_TXRDY*/));	/*huxianpeng 20060108*/
            AMBA_UART_REG_BIT_CLR(pChan, DBGU_IDR, (DBGU_IER_RXRDY/*|DBGU_IER_TXRDY*/));
            /* Enable appropriate interrupts. */
            /*intEnable (pChan->levelRx); */

            /*
             * There is no point in enabling the Tx interrupt, as it
             * will interrupt immediately and be disabled.
             */
        }
        else
        {
            /* Disable all interrupts for this UART. */

            /*intDisable (pChan->levelRx);*/
            if (pChan->levelTx != pChan->levelRx)
            {
                /*intDisable (pChan->levelTx);*/
            }

            /*		AMBA_UART_REG_BIT_CLR(pChan,
            				      UARTCON, 
                                                  UART_RTIE | UART_TIE | 
            				      UART_RIE | UART_MSIE );
            */

            AMBA_UART_REG_WRITE(pChan, DBGU_IDR, 0xFFFFFFFF);
            AMBA_UART_REG_WRITE(pChan, DBGU_IER, 0x0);
            /*
            AMBA_UART_REG_BIT_SET(pChan, DBGU_IDR, (DBGU_IER_RXRDY|DBGU_IER_TXRDY));
            AMBA_UART_REG_BIT_CLR(pChan, DBGU_IER, (DBGU_IER_RXRDY|DBGU_IER_TXRDY));
            */
        }

        pChan->channelMode = arg;

        intUnlock (oldlevel);
        break;


    case SIO_MODE_GET:

        /* Get the current mode and return OK */

        *(int *)arg = pChan->channelMode;
        break;


    case SIO_AVAIL_MODES_GET:

        /* Get the available modes and return OK */

        *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
        break;


    case SIO_HW_OPTS_SET:

        /*
         * Optional command to set the hardware options (as defined
         * in sioLib.h).
         * Return OK, or ENOSYS if this command is not implemented.
         * Note: several hardware options are specified at once.
         * This routine should set as many as it can and then return
         * OK. The SIO_HW_OPTS_GET is used to find out which options
         * were actually set.
         */
        /*
        	oldlevel = intLock ();
        		
        		AMBA_UART_REG_WRITE(pChan, DBGU_MR, arg);	
        		
        	intUnlock (oldlevel);
        */
    case SIO_HW_OPTS_GET:

        /*
         * Optional command to get the hardware options (as defined
         * in sioLib.h). Return OK or ENOSYS if this command is not
         * implemented.  Note: if this command is unimplemented, it
         * will be assumed that the driver options are CREAD | CS8
         * (e.g., eight data bits, one stop bit, no parity, ints enabled).
         */

    default:
        status = ENOSYS;
    }

    return status;

}

/*******************************************************************************
*
* primeCellSioIntTx - handle a transmitter interrupt 
*
* This routine handles write interrupts from the UART.
*
* RETURNS: N/A
*/

void primeCellSioIntTx
(
    AMBA_CHAN *	pChan	/* ptr to AMBA_CHAN describing this channel */
)
{
    char outChar;


    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
    {
        /* write char. to Transmit Holding Reg. */
        /*	AMBA_UART_REG_WRITE(pChan, UARTDR, outChar);*/
        AMBA_UART_REG_WRITE(pChan, DBGU_THR, outChar);
    }
    else
    {
        /* Disable transmit interrupts. Leave receive interrupts enabled. */
        /*
              if (pChan->levelTx != pChan->levelRx)
                  intDisable (pChan->levelTx);
        */
        /*	AMBA_UART_REG_BIT_CLR(pChan, UARTCON, UART_TIE);*/
        /*	AMBA_UART_REG_BIT_SET(pChan, DBGU_IDR, DBGU_IER_TXRDY);*/
        AMBA_UART_REG_WRITE(pChan, DBGU_IDR, DBGU_IER_TXRDY);
    }

}

/*****************************************************************************
*
* primeCellSioIntRx - handle a receiver interrupt 
*
* This routine handles read interrupts from the UART.
*
* RETURNS: N/A
*/

void primeCellSioIntRx
(
    AMBA_CHAN *	pChan	/* ptr to AMBA_CHAN describing this channel */
)
{
    char inchar;
    char flags;
    BOOL more_data = FALSE;

    /* read characters from Receive Holding Reg. */
    do
    {
        /* While RX FIFO isn't empty, we have more data to read */
        AMBA_UART_REG_READ(pChan, UARTFLG, flags);
        /*	more_data = ( (flags & FLG_URXFE) == 0);*/
        more_data = ( (flags & FLG_URXFE) != 0);

        if (more_data)
        {
            /* Read from data register. */
            /*	    AMBA_UART_REG_READ(pChan, UARTDR, inchar);*/
            AMBA_UART_REG_READ(pChan, DBGU_RHR, inchar);

            (*pChan->putRcvChar) (pChan->putRcvArg, inchar);
        }

    }
    while (more_data);

}

/******************************************************************************
*
* primeCellSioInt - handle any UART interrupt
*
* This routine handles interrupts from the UART and determines whether
* the source is a transmit interrupt or receive/receive-timeout interrupt.
*
* The Prime Cell UART generates a receive interrupt when the RX FIFO is
* half-full, and a receive-timeout interrupt after 32 bit-clocks have
* elapsed with no incoming data.
*
* RETURNS: N/A
*/

void primeCellSioInt
(
    AMBA_CHAN * pChan   /* ptr to AMBA_CHAN describing this channel */
)
{
    char intId;
    char intMsk;

    /*   AMBA_UART_REG_READ(pChan, UARTIIR, intId);*/
    AMBA_UART_REG_READ(pChan, DBGU_SR, intId);
    AMBA_UART_REG_READ(pChan, DBGU_IMR, intMsk);
    intId=intId&intMsk;

    /*    if (intId & UART_TIS)*/
    if (intId & DBGU_IER_TXRDY || intId & DBGU_IER_TXBUFE )
    {
        primeCellSioIntTx (pChan);
    }

    /*    if (intId & UART_RIS || intId & UART_RTIS)*/
    if (intId & DBGU_IER_RXRDY || intId & DBGU_IER_RXBUFF)
    {
        primeCellSioIntRx (pChan);
    }

    /*    AMBA_UART_REG_WRITE(pChan, UARTICR, intId);	*//* clear interrupts */

}


/*******************************************************************************
*
* ambaTxStartup - transmitter startup routine
*
* Enable interrupt so that interrupt-level char output routine will be called.
*
* RETURNS: OK on success, ENOSYS if the device is polled-only, or
* EIO on hardware error.
*/

LOCAL int ambaTxStartup
(
    SIO_CHAN *	pSioChan	/* ptr to SIO_CHAN describing this channel */
)
{
    AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;

    if (pChan->channelMode == SIO_MODE_INT)
    {
        intEnable (pChan->levelTx);
        /*	AMBA_UART_REG_BIT_SET(pChan, UARTCON, UART_TIE);*/
        AMBA_UART_REG_BIT_SET(pChan, DBGU_IER, DBGU_IER_TXRDY );
        return OK;
    }
    else
        return ENOSYS;
}

/******************************************************************************
*
* ambaPollOutput - output a character in polled mode.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the output buffer is full, ENOSYS if the device is interrupt-only.
*/

LOCAL int ambaPollOutput
(
    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */
    char	outChar 	/* char to output */
)
{
    AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;
    FAST UINT32 pollStatus;
    /*    AMBA_UART_REG_READ(pChan, UARTFLG, pollStatus);*/
    AMBA_UART_REG_READ(pChan, DBGU_SR, pollStatus);
    /* is the transmitter ready to accept a character? */

    /*    if ((pollStatus & FLG_UTXFF) != 0x00)*/
    if ((pollStatus & FLG_UTXFF) == 0x00)
        return EAGAIN;


    /* write out the character */
    /*    AMBA_UART_REG_WRITE(pChan, UARTDR, outChar);	*//* transmit character */
    AMBA_UART_REG_WRITE(pChan, DBGU_THR, outChar);	/* transmit character */

    return OK;
}

/******************************************************************************
*
* ambaPollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer is empty, ENOSYS if the device is interrupt-only.
*/

LOCAL int ambaPollInput
(
    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */
    char *	thisChar	/* pointer to where to return character */
)
{
    AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;
    FAST UINT32 pollStatus;

    /*    AMBA_UART_REG_READ(pChan, UARTFLG, pollStatus);*/
    AMBA_UART_REG_READ(pChan, DBGU_SR, pollStatus);


    /*    if ((pollStatus & FLG_URXFE) != 0x00)*/
    if ((pollStatus & FLG_URXFE) == 0x00)
        return EAGAIN;


    /* got a character */

    /*    AMBA_UART_REG_READ(pChan, UARTDR, *thisChar);*/
    AMBA_UART_REG_READ(pChan, DBGU_RHR, *thisChar);
    return OK;

}

/******************************************************************************
*
* ambaCallbackInstall - install ISR callbacks to get/put chars.
*
* This routine installs interrupt callbacks for transmitting characters
* and receiving characters.
*
* RETURNS: OK on success, or ENOSYS for an unsupported callback type.
*
*/

LOCAL int ambaCallbackInstall
(
    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */
    int		callbackType,	/* type of callback */
    STATUS	(*callback)(),	/* callback */
    void *	callbackArg	/* parameter to callback */

)
{
    AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;


    switch (callbackType)
    {
    case SIO_CALLBACK_GET_TX_CHAR:
        pChan->getTxChar	= callback;
        pChan->getTxArg	= callbackArg;
        return OK;

    case SIO_CALLBACK_PUT_RCV_CHAR:
        pChan->putRcvChar	= callback;
        pChan->putRcvArg	= callbackArg;
        return OK;

    default:
        return ENOSYS;
    }

}


void  comOutputTest(
    char	outChar 	/* char to output */
)
{
#if 0
    int j,k;
    /*	UINT32 * baseadd;*/
    int * baseadd;
    FAST UINT32 pollStatus;

    baseadd=(int *)UART_0_BASE_ADR;
    baseadd+=(DBGU_SR);
    pollStatus=*((volatile UINT32 *)baseadd);
    /*	pollStatus=*(baseadd+DBGU_SR);*/

    if ((pollStatus & FLG_UTXFF) == 0x00)
        return ;		/* Transmitter not ready*/


    /*	*(baseadd+DBGU_THR)=outChar;*/
    baseadd=(int *)UART_0_BASE_ADR;
    baseadd+=(DBGU_THR);
    *baseadd =outChar;
    for(j=0;j<1000;j++)
    {
        k++;
        k--;
    }
#else
    /*
    char tmp[16];
    sprintf(tmp, "%c", outChar);
    bootPrint(tmp);
    */
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -