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

📄 ixuart.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
字号:
/*  * @file IxUART.c * @author Intel Corporation * @date 15-OCT-2001 *  * @brief UART Access driver for the Intel IXP4XX. *  *  * @par * IXP400 SW Release version 2.1 *  * -- Copyright Notice -- *  * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. *  * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the Intel Corporation nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  *  * @par * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  *  * @par * -- End of Copyright Notice --*//** * @addtogroup UART API * @{ */#include "IxOsalTypes.h"#include "IxOsal.h"#include "IxUART_p.h"#include "IxUART.h"#define IX_UART_REG_WRITE(pUART, reg, data) \(IX_OSAL_WRITE_LONG((VUINT32 *)((UINT32)(pUART)->addr + ((reg) * IX_UART_REG_DELTA)), (data)))#define IX_UART_REG_READ(pUART, reg, val) \((val) = IX_OSAL_READ_LONG((VUINT32 *)((UINT32)(pUART)->addr + ((reg) * IX_UART_REG_DELTA))))#define IX_UART_CHECK_REF	\{				\    if(pUART == NULL)		\    {				\	return (IX_FAIL);	\    }				\}/* Local prototypes */PRIVATE IX_STATUS ixUARTBaudSet(ixUARTDev* pUART, UINT32 baud);PRIVATE IX_STATUS ixUARTOptsSet(ixUARTDev* pUART, UINT32 options);PRIVATE IX_STATUS ixUARTModeSet(ixUARTDev* pUART, ixUARTMode mode);PRIVATE void ixUARTErr(ixUARTDev* pUART, char status);PUBLIC IX_STATUS ixUARTInit(ixUARTDev* pUART){    IX_UART_CHECK_REF;    /* Initialise counter statistics */    pUART->stats.rxCount = 0;    pUART->stats.txCount = 0;    pUART->stats.overrunErr = 0;    pUART->stats.parityErr = 0;    pUART->stats.framingErr = 0;    pUART->stats.breakErr = 0;    /* Set the default hardware options */    pUART->options = IX_UART_DEF_OPTS;    pUART->mode = POLLED;    pUART->fifoSize = IX_UART_DEF_XMIT;    pUART->freq = IX_UART_XTAL;    /* Enable the UART */    IX_UART_REG_WRITE(pUART, IX_IER, IX_IER_UUE);    /* Set the baud rate */    if((pUART->baudRate < IX_UART_MIN_BAUD) || (pUART->baudRate > IX_UART_MAX_BAUD))    {	pUART->baudRate = IX_UART_DEF_BAUD;    }	    if(ixUARTBaudSet(pUART, pUART->baudRate) == IX_FAIL)    {	return IX_FAIL;    }      if(ixUARTOptsSet(pUART, pUART->options) == IX_FAIL)    {	return IX_FAIL;    }    /* Enable FIFOs */    IX_UART_REG_WRITE(pUART, IX_FCR, (IX_FCR_RESETRF | IX_FCR_RESETTF | IX_FCR_TRFIFOE));        return IX_SUCCESS;}PUBLIC IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg){    int status = IX_SUCCESS;    IX_UART_CHECK_REF;    switch (cmd)    {	case IX_BAUD_SET:	    if (*(int *)arg < IX_UART_MIN_BAUD || *(int *)arg > IX_UART_MAX_BAUD)	    {		status = IX_FAIL;		/* baud rate out of range */	    }	    else	    {	        status = ixUARTBaudSet(pUART, *(int *)arg);	    }	    break;        case IX_BAUD_GET:            *(int *)arg = pUART->baudRate;            break;         case IX_MODE_SET:	    status = ixUARTModeSet(pUART, *(int *)arg);            break;                  case IX_MODE_GET:            *(ixUARTMode *)arg = pUART->mode;            break;        case IX_OPTS_SET:    	    status = ixUARTOptsSet(pUART, *(int *)arg);    	    break;        case IX_OPTS_GET:            *(int *)arg = pUART->options;            break;        case IX_STATS_GET:	    *(ixUARTStats *)arg = pUART->stats;            break;	        default:            status = IX_FAIL;    }    return status;}#ifdef _DIAB_TOOL__asm volatile void _RTODisableWait(UINT32 pRTO){ % reg pRTO;! "r1"               /* scratch registers used */     ldr r1, [pRTO];    mov r1, r1;}#endif /* #ifdef _DIAB_TOOL */    PUBLIC IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar){    char volatile lsr, ier;#ifdef _DIAB_TOOL    register UINT32 pRTO;#endif    IX_UART_CHECK_REF;    IX_UART_REG_READ(pUART, IX_LSR, lsr);    ixUARTErr(pUART, lsr);	/* Check LSR for errors */            if(lsr & IX_LSR_DR)		/* Rx FIFO requests data */    {        /* disable RTO */        IX_UART_REG_READ(pUART, IX_IER, ier);        IX_UART_REG_WRITE(pUART, IX_IER, (ier & (~IX_IER_RTOIE)));               #if CPU!=SIMSPARCSOLARIS         /* wait for RTO to be disabled - read back IER and stall */#ifdef _DIAB_TOOL        pRTO = ((UINT32)(pUART)->addr + (IX_IER * IX_UART_REG_DELTA));        _RTODisableWait(pRTO);#else        __asm__ volatile ("ldr r1, [%0]; mov r1, r1;"             : /* no outputs */             : "g" ((UINT32)(pUART)->addr + (IX_IER * IX_UART_REG_DELTA))            : "r1");#endif /* #ifdef _DIAB_TOOL */        #endif    	IX_UART_REG_READ(pUART, IX_RBR, *inChar);	pUART->stats.rxCount++;                /* enable RTO */        IX_UART_REG_READ(pUART, IX_IER, ier);        IX_UART_REG_WRITE(pUART, IX_IER, (ier | IX_IER_RTOIE));        	return IX_SUCCESS;    }    return IX_FAIL;}PUBLIC IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar){    volatile char lsr;    volatile char msr;    IX_UART_CHECK_REF;    IX_UART_REG_READ(pUART, IX_LSR, lsr);    IX_UART_REG_READ(pUART, IX_MSR, msr);    ixUARTErr(pUART, lsr);	/* Check LSR for errors */        if(!(lsr & IX_LSR_TDRQ))	/* Tx FIFO Full */    {	return IX_FAIL;    }        if (!(pUART->options & CLOCAL))	 /* hardware flow control */    {    	if (msr & IX_MSR_CTS)	{	    IX_UART_REG_WRITE(pUART, IX_THR, outChar);	}	else	{	    return IX_FAIL;	}    }    else				/* software flow (default) */    {	IX_UART_REG_WRITE(pUART, IX_THR, outChar);    }    pUART->stats.txCount++;    return IX_SUCCESS;}/** * @addtogroup UART SupportAPI * @{ *//** * @fn IX_STATUS ixUARTOptsSet(ixUARTDev* pUART, UINT32 options) * * @param pUART	- pointer to UART structure describing our device. * @param options - bitmask of hardware options * * @brief Set the hardware options for the device. * * @return IX_SUCCESS - the device options were set correctly. * @return IX_FAIL - error setting requested option. * ***************************************************************************/PRIVATE IX_STATUS ixUARTOptsSet(ixUARTDev* pUART, UINT32 options){    VUINT32 lcr = 0;    VUINT32 mcr = 0;    VUINT32 ier = 0;    IX_UART_CHECK_REF;    /* Character size */    switch (options & CSIZE)	/* bits 3,4 encode character size */    {	case CS5:	{	    IX_UART_REG_WRITE(pUART, IX_LCR, IX_CHAR_LEN_5);	    break;	}	case CS6:	{	    IX_UART_REG_WRITE(pUART, IX_LCR, IX_CHAR_LEN_6);	    break;	}	case CS7:	{	    IX_UART_REG_WRITE(pUART, IX_LCR, IX_CHAR_LEN_7);	    break;	}	case CS8:	default:	{	    IX_UART_REG_WRITE(pUART, IX_LCR, IX_CHAR_LEN_8);	    break;	}    }    /* No. of stop bits */    IX_UART_REG_READ(pUART, IX_LCR, lcr);    if (options & STOPB)    {	IX_UART_REG_WRITE(pUART, IX_LCR, (lcr | IX_LCR_STB_2));     }    else    {	IX_UART_REG_WRITE(pUART, IX_LCR, (lcr | IX_LCR_STB_1));	/* default */    }      /* Parity */    IX_UART_REG_READ(pUART, IX_LCR, lcr);    switch (options & (PARENB | PARODD))    {	case PARENB|PARODD:	{	    IX_UART_REG_WRITE(pUART, IX_LCR, (lcr | IX_LCR_PEN)); 	    break;	}	case PARENB:	{	    IX_UART_REG_WRITE(pUART, IX_LCR, (lcr | IX_LCR_PEN | IX_LCR_EPS));	    break;	}	default:	case 0:	{	    IX_UART_REG_WRITE(pUART, IX_LCR, (lcr | IX_LCR_PDIS));	    break;	}    }        /* Flow control */        /* Read Interrupt Enable Register - note that the TIE bit 2 (Transmission Interrupt Enable)       is never set by this driver and defaults to 0 (not enabled) after reset, therefore       it should never be 1 (enabled) in 'ier'. Enabling the modem status interrupt by writing       the read 'ier' value OR-ed with MIE (Modem Interrupt Enable) back to the        Interrupt Enable Register will not normally enable TIE. */    IX_UART_REG_READ(pUART, IX_IER, ier);        if (!(options & CLOCAL))	/* hardware (RTS/CTS) */    {	IX_UART_REG_READ(pUART, IX_MCR, mcr);	IX_UART_REG_WRITE(pUART, IX_MCR, (mcr | IX_MCR_RTS));    	IX_UART_REG_WRITE(pUART, IX_IER, (ier & (~IX_IER_TIE))); 	IX_UART_REG_WRITE(pUART, IX_IER, (ier |= IX_IER_MIE));  /* enable modem status interrupt */    }    else			/* software */    {        /* Read MCR status */        IX_UART_REG_READ(pUART, IX_MCR, mcr);        /* Reset RTS bit of the MCR */        IX_UART_REG_WRITE(pUART, IX_MCR, mcr & (~IX_MCR_RTS));        IX_UART_REG_WRITE(pUART, IX_IER, (ier & ~(IX_IER_MIE))); /* software flow ctrl - default */     }    pUART->options = options;    return IX_SUCCESS;}/** * @fn IX_STATUS ixUARTBaudSet(ixUARTDev* pUART, UINT32 baud) * * @param pUART - pointer to UART structure describing our device. * @param baud - baud rate to set to. * * @brief Set the baud rate for the device. * * @pre Baud must be within max/min range as defined in ixUART.h * * @return IX_SUCCESS - baud rate set successfully * @return IX_FAIL - error setting baud rate * ***************************************************************************/PRIVATE IX_STATUS ixUARTBaudSet(ixUARTDev* pUART, UINT32 baud){    VUINT32 lcr = 0;    UINT32 divisor = 0;    IX_UART_CHECK_REF;    IX_UART_REG_READ(pUART, IX_LCR, lcr);    /* Enable access to the divisor latches by setting DLAB in LCR. */    IX_UART_REG_WRITE(pUART, IX_LCR, (IX_LCR_DLAB | lcr));    /* Set divisor latches. */    divisor = pUART->freq/(16*baud);    IX_UART_REG_WRITE(pUART, IX_DLL, (divisor & 0xFF));    IX_UART_REG_WRITE(pUART, IX_DLM, ((divisor >> 8) & 0xF));    /* Restore line control register */    IX_UART_REG_WRITE(pUART, IX_LCR, lcr);    pUART->baudRate = baud;    return IX_SUCCESS;}/** * @fn IX_STATUS ixUARTModeSet(ixUARTDev* pUART, ixUARTMode mode) * * @param pUART - pointer to UART structure describing our device. * @param mode - mode to switch to. * * @brief Set the current mode for the device. * * @return IX_SUCCESS - mode set successfully * @return IX_FAIL - invalid mode * ***************************************************************************/PRIVATE IX_STATUS ixUARTModeSet(ixUARTDev* pUART, ixUARTMode mode){    int status = IX_SUCCESS;    VUINT32 mcr = 0;    VUINT32 msr = 0;    IX_UART_CHECK_REF;    switch (mode)    {	case INTERRUPT:		/* Not supported for now */	{    	    status = IX_FAIL;	    break;	}	case POLLED:	{	    IX_UART_REG_WRITE(pUART, IX_IER, IX_IER_UUE);  /* Disable interrupts */	    IX_UART_REG_READ(pUART, IX_MCR, mcr);	    IX_UART_REG_WRITE(pUART, IX_MCR, (mcr | ~IX_MCR_LOOP));  /* Ensure loopback disabled */	    IX_UART_REG_READ(pUART, IX_MSR, msr);  /* Read once to clear delta bits */	    pUART->mode = POLLED;	    break;	}	case LOOPBACK:	{	    IX_UART_REG_WRITE(pUART, IX_IER, IX_IER_UUE);  /* Ints are optional but we disable them anyways */	    IX_UART_REG_READ(pUART, IX_MCR, mcr);	    IX_UART_REG_WRITE(pUART, IX_MCR, (mcr | IX_MCR_LOOP));	    pUART->mode = LOOPBACK;	    break;	}	default:	    status = IX_FAIL;    }    return status;}/** * @fn void ixUARTErr(ixUARTDev* pUART, char status) * * @param pUART - pointer to UART structure describing our device. * @param status - current status of LSR. * * @brief UART error handler. Just increments counters for now. * * @return  N/A  ****************************************************************************/PRIVATE void ixUARTErr(ixUARTDev* pUART, char status){    if(status & IX_LSR_OE)	pUART->stats.overrunErr++;	    if(status & IX_LSR_PE)	pUART->stats.parityErr++;    if(status & IX_LSR_FE)	pUART->stats.framingErr++;    if(status & IX_LSR_BI)	pUART->stats.breakErr++;}/** * @} addtogroup UART SupportAPI */

⌨️ 快捷键说明

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