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

📄 dw_16550.c

📁 Mavell AP32 无线模块驱动。VxWorks BSP BootRom源代码
💻 C
字号:
/*******************************************************************************
*                   Copyright 2002, GALILEO TECHNOLOGY, LTD.                   *
* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL.                      *
* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT  *
* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE        *
* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL.     *
* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED,       *
* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE.   *
*                                                                              *
* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL    *
* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K.  *
* (MJKK), GALILEO TECHNOLOGY LTD. (GTL) AND GALILEO TECHNOLOGY, INC. (GTI).    *
********************************************************************************
* DW_16550.c - functions for DW_16550 UART.
* 
* DESCRIPTION:
*       This is the unit driver for the DW_16550 UART - SIU unit.
*       The DW_16550 is a parameterizable, synthesizable, and programmable 
*       Universal Asynchronous Receiver/Transmitter (UART), modeled after the 
*       industry standard 16550.
*       The DW_16550 UART contains registers to control the word size, baud 
*       rate, parity generation/checking, and interrupt generation.
*
*       For calculating the baudrate we use the xtal - field in the SW data 
*       structure (DW_16550_CHAN). Xtal default value is zero and it must be 
*       changed by the user. Make sure that you insert a non-zero xtal.
*
*	    You can use this driver in two phases, the initialization phase 
*	    (dw16550InitChannel) and the operation phase (dw16550StartChannel).
*	    During the initialization phase, the default values are entered in the
*	    DW_16550_CHAN struct. During the operation phase, the values assigned
*	    during the initialization phase are written to the appropriate 
*       registers. 
*	    An intermediate phase can be added after the initialization phase, in 
*       which the default values can be changed.   
*      	Note: The initialization phase is not necessary to start this driver. 
*       The software struct can be started manually with the desired values. 
*       The function dw16550StartChannel must be called in order to work with 
*       this driver.
*        	     
*******************************************************************************/

#include "DW_16550.h"
            
            

/*******************************************************************************
* dw16550InitChannel - initialize DW_16550 UART.
*
* DESCRIPTION:
*       This routine performs initialization of the DW_16550 UART 
*       channel struct with default values. 
*       
* INPUT: 
*       *pChan - Pointer to DW_16550 struct describing channel.
*       
* OUTPUT: 
*       Set DW_16550 struct with default values.
*
* RETURN: N/A
* 
* COMMENTS:
*       After calling to this function you must call to function
*       dw16550StartChannel which put the struct default values into the  
*       relevant registers.
*
*******************************************************************************/

void dw16550InitChannel(DW_16550_CHAN *	pChan)
{
    pChan->lcr  = DEFAULT_LCR_VALUE;
    pChan->xtal = DEFAULT_XTAL_VALUE; 
    pChan->ier  = DEFAULT_IER_VALUE;

}

/*******************************************************************************
*
* dw16550StartChannel - Start UART channel with relevant values.
*
* DESCRIPTION:
*       The function takes values from DW_16550_CHAN struct and writes to the 
*       appropriate registers.
*       For calculating the baud rate divisor the function calls 
*       dw16550SetBaudrate. 
* INPUT:
*       *pChan   - Pointer to DW_16550 struct describing channel. 
*       baudrate - value of baudrate.
*       
* OUTPUT:
*       Writes registers' value' from DW_16550_CHAN struct to the actual 
*       registers. 
*              
* RETURN:
*        False for an invalid baud rate, or true on success.
             
* COMMENTS:
*       This function must to be called to enable working with DW_16550 UART. 
*       
*******************************************************************************/
bool dw16550StartChannel (DW_16550_CHAN  *pChan, unsigned int baudrate)
{
    bool	status;	  /* status to return */
    /* Reset/Enable the FIFOs */
    DW_16550_REG_WRITE(pChan, FCR, FCR_RXCLR | FCR_TXCLR | FCR_EN);
    
    DW_16550_REG_WRITE(pChan, IER, pChan->ier);
    DW_16550_REG_WRITE(pChan, LCR, pChan->lcr);
    
    status = dw16550SetBaudrate(pChan,baudrate);

    return status;
}


/*******************************************************************************
* dw16550SetBaudrate - Set baud rate of DW_16550 UART.  
*
* DESCRIPTION:
*       This function calculates the baud rate divisor and updates the divisor
*       value in the DLL and DLH registers. 
*       Baudrate divisor must be non-zero and must fit in a 16-bit register.
* INPUT:
*       *pChan   - Pointer to DW_16550 struct describing channel. 
*       baudrate - value of baudrate.
*       
* OUTPUT:
*       pChan->lcr - changed to enable access to divisor latches.
*              
* RETURN:
*       False for an invalid baud rate, or true on success.
*             
* COMMENTS:
*       NOne.
*
*******************************************************************************/
bool dw16550SetBaudrate(DW_16550_CHAN *	pChan, unsigned int baudrate)
{
    unsigned int	divisor;	  
    unsigned int    brdReal;
    unsigned int    brdDelta;
        
	if(pChan->xtal <= 0)
        return false;     /* Clock frequency invalid */
    
    divisor = pChan->xtal/(16*baudrate);	/* calculate baudrate divisor */

	if ((divisor < 1) || (divisor > 0xFFFF))
       
        return false;		/* baud rae out of range */   
    
    brdReal = ((pChan->xtal)/(16*divisor));
    brdDelta = brdReal - baudrate;

    /* Checking for maximum 1% of error in baudrate */ 
    if (((brdDelta*100)/baudrate) != 0)
        return false;
    

    /* Enable access to the divisor latches by setting DLAB in LCR. */
    DW_16550_REG_WRITE(pChan, LCR , (LCR_DLAB) | (pChan->lcr));
    /* Set divisor latches. */
    DW_16550_REG_WRITE(pChan, DLL, divisor);
    DW_16550_REG_WRITE(pChan, DLH, divisor >> 8);

    /* Disable the access to the divisor latches */
    DW_16550_REG_WRITE(pChan, LCR, pChan->lcr);

    return true;
}

/*******************************************************************************
* dw16550SetMode - Set Interrupt or polling mode.
* 
* DESCRIPTION:
*       This function writes to the IER register. It enables or disables the 
*       interrupts as defined by the user.
* INPUT:
*       *pChan      - Pointer to DW_16550 struct describing channel. 
*       channelMode - Interrupt or polling mode. See typdef enum CHAN_MODE. 
*       
* OUTPUT:
*       Writes registers' value' from DW_16550_CHAN struct into the actual 
*       registers. 
*              
* RETURN:
*       False for an invalid CHAN_MODE or true otherwise.
* COMMENTS:
*       NOne.
*
*******************************************************************************/
bool dw16550SetMode (DW_16550_CHAN *pChan,CHAN_MODE channelMode)  
{
        /* Checking for invalid CHAN_MODE */
	    if ((channelMode != CHAN_MODE_POLL) && (channelMode != CHAN_MODE_INT))
		    return false;
		
        if (channelMode == CHAN_MODE_INT)
        
		   /* Enable appropriate interrupts */
            DW_16550_REG_WRITE(pChan,IER,pChan->ier|IER_ERBFI|IER_ETHREI);
		else
		
            /* Disable the interrupts */
            DW_16550_REG_WRITE(pChan, IER, 0);
        
        /* Make a copy of IER to DW_16550 struct */
        pChan->ier = DW_16550_REGREAD(pChan,IER);  
		
		return true;
}


⌨️ 快捷键说明

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