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

📄 usb318xcfg.c

📁 nxp的ARM9处理器LPC3180代码,提供了几乎所有的外设示例程序.
💻 C
字号:
/*****************************************************************************
 *   usb318xcfg.c:  USB module file for Philips LPC318x Family Microprocessors
 *
 *   Copyright(C) 2006, Philips Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2005.10.01  ver 1.00    Prelimnary version, first Release
 *
******************************************************************************/
#include "LPC318x.H"                        /* LPC318x definitions */
#include "type.h"
#include "irq.h"
#include "usb318xcfg.h"

/*****************************************************************************
** Function name:	USBPLL_Config
**
** Descriptions:	This function configures the USB device's PLL, 
**			giving the device a frequency of 48 MHz.
**		
** Notes:	PLL Output frequency when in DIRECT MODE, USBCLK_CTRL[15:14] 
**		= '01', is calculated by:
**		FCLKOUT = ((FCLKIN / 13) * (M / (P * 2))) / N
**		FCLKIN = 13MHZ
**		FCLKOUT = ((13MHZ / 13) * (192 / 4)) = 48 MHZ
** parameters:		None
** Returned value:	None
** 
*****************************************************************************/
void  USBPLL_Config (void)
{
    USBCLK_CTRL = (1 << 19);	/* Set the USB Control register to its default value */

    USBCLK_CTRL |= (1 << 17);	/* Enable USBCLKEn1, Path from oscillator to USB PLL */

    USBCLK_CTRL |= (191 << 1);	/* Configure M=192 (0xC0), the USB PLL feedback divider */
    USBCLK_CTRL &= ~(3 << 9);	/* Configure N=1 to 1, the pre divider */
    USBCLK_CTRL |= (1 << 11);	/* Set the Post Divider to 2, P=2, that is, divide by 4 */
    USBCLK_CTRL &= ~(1 << 13);	/* Feed the CCO output back into the PLL */
    USBCLK_CTRL &= ~(1 << 14);	/* Post Divider output is the PLL clock output */
    USBCLK_CTRL &= ~(1 << 15);	/* CC0 Clk sent to post div, must be 0 */

    /* Set divider ratios (48 MHZ output), M=192, N=1, P=2   */
    /* [16:16] PLL Power Down = 0, PLL in power down mode   */
    /* [15:15] Bypass Control = 0, CC0 Clk sent to post div */
    /* [14:14] CCO clock = PLL CLK, bypassing post divider  */
    /* [13:13] Feedback Divider clocked by PLL_CLKOUT       */
    /* [12:11] PLL Post Divider (P)  =  0 + 1               */
    /* [10:09] PLL Pre Divider (N)   =  0 + 1               */
    /* [08:01] PLL Feedback Divider (M) = 191 + 1           */
    /* [00:00] PLL Locked Status, 1 = locked (Read Only)    */

    USBCLK_CTRL |= (1 << 16);	/* Power up the USB PLL */

    while ( !(USBCLK_CTRL & 0x01) );	/* Wait for PLL to Lock */

    USBCLK_CTRL &= ~(3 << 19); /* Clear bits [20:19], adding pullup to the data pin  */
    return;

}

/******************************************************************************
** Function name:		USB_ISP1301Suspend
**
** Descriptions:		Send I2C Cmds to ISP1301, mode control 2 and
**				Mode control 1 to suspend ISP1301.
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void USB_ISP1301Suspend( void )
{
    /* Mode Ctrl 2, bit 1, set SPD_SUSP_CTRL bit 1 first in ISP1301 */
    /* This bit is questionable during the test. Further debugging is needed. */
    Set_OTG_1301_Value( OTG_MODE_CTRL_2, 0x02 );

    /* Set SUSPEND_REG bit in Mode Control 1 register. */
    Set_OTG_1301_Value( OTG_MODE_CTRL_1, 0x02 );
    return;
}

/******************************************************************************
** Function name:		USB_ISP1301Resume
**
** Descriptions:		Send I2C Cmds to ISP1301, mode control 2 and
**				Mode control 1 to resume from ISP1301.
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void USB_ISP1301Resume( void )
{
    /* Mode Ctrl 2, bit 1, set SPD_SUSP_CTRL bit 1 first in ISP1301 */
    /* This bit is questionable during the test. Further debugging is needed. */
    Set_OTG_1301_Value( OTG_MODE_CTRL_2, 0x02 );
    /* Clear SUSPEND_REG bit in Mode Control 1 register. */
    Clr_OTG_1301_Value( OTG_MODE_CTRL_1, 0x02 );  
    return;
}

/******************************************************************************
** Function name:		USB_ISP1301Powerdown
**
** Descriptions:		Put ISP1301 into power down mode. I2C for 
**				ISP1301 is reset for precaution.				
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void USB_ISP1301Powerdown( void )
{
    /* Set I2C rate */
    I2C_CTRL |= 0x100;
    I2C_CLKL = 0x41;
    I2C_CLKH = 0x41;
      
    /* Mode Ctrl 2, bit 0, global power down mode */
    Set_OTG_1301_Value( OTG_MODE_CTRL_2, 0x01 );
    return;
}
 
/******************************************************************************
** Function name:		USB_OTGPreset
**
** Descriptions:	In the USB device initialization. The initialization 
**			sequence is crucial. Here is the correct sequence to 
**			initialize the USB block:
**			(1) Initialize USB external tranceiver, ISP1301, the 
**			setting includes
**				(i) set PSW_SE bit and BI-DI(default) bits in the 
**				Mode Control 2.
**				(ii) set USB to DAT_SE0 mode in Mode Control 1.
**			(2) Setup USB PLL ( call USBPLL_Config() ).
**			(3) Enable USB clock going to the USB block. ( call 
**			USB_DevEnable() ).
**			(4) Add pull-up on DP (set DP_PULLUP bit ) and set 
**			VBUS_DRV bit in the OTG control register of ISP 1301.
**			
**			This is the first step to initialize ISP1301.
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void USB_OTGPreset( void )
{
    DWORD regValue;

    USBCLK_CTRL |= (1 << 24);
    regValue = OTG_clock_status;		
    OTG_clock_control = 0x1E;	/* This module is sent for USB device compliance 
				test. Host is not enabled. If needed, set to 0x1F. */
    while ( !(OTG_clock_status & 0x1E) );

    if ( (regValue = OTG_module_id) == 0x3506000B )
    { 
	USB_ISP1301Config();	/* Setup External USB Tranciever, ISP1301 */
    }
    return;
}

/******************************************************************************
** Function name:		USB_ISP1301Config
**
** Descriptions:		ISP1301 configuration, called by USB_OTGPreset()
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void USB_ISP1301Config( void )
{
    /* This module is called at the very beginning of the initialization, 
    even before USB PLL configuration. */

    /* Set I2C rate */
    I2C_CTRL |= 0x100;
    I2C_CLKL = 0x41;
    I2C_CLKH = 0x41;

    /* Mode Ctrl 2, bit 6, PSW_OE, and bit 2, BI_DI, are set */
    Set_OTG_1301_Value( OTG_MODE_CTRL_2, 0x0044 );

    /* Mode Ctrl 1, bit 2, DAT_SE0, is set */
    Set_OTG_1301_Value( OTG_MODE_CTRL_1, 0x04 );

    /* Be very careful when to do this, once pull-up is added on DP, the
    USB device will act as if it's connected. If the USB device is
    not initialized and pull-up has been added already, the USB device 
    initialization will fail. Below line needs to be called after USB 
    device initialization. */

    /* OTG Ctrl, bit 7, charge VBus to 3.3V, drive VBus through charge 
    pump, connect pull-up on DP  */
//    Set_OTG_1301_Value( OTG_CTRL, 0x0021 );
    return;
}
 
/******************************************************************************
** Function name:		USB_DevEnable
**
** Descriptions:		Enable USB HCLK, enable path from USB PLL
**				to USB device block, enable USB Device clock.
**				This module is called after USBPLL_Config()
**				before adding pull-up on DP on ISP1301.
**				See comment in USB_ISP1301Config().	
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void USB_DevEnable( void )
{
    PWR_CTRL &= ~(1 << 6);	/* Enable USB HCLK, same clock as CPU PLL HCLK */
    USBCLK_CTRL |= (1 << 18);	/* Enable USBCLKEn2, Path from USB PLL to USB Block */
    while ( (USBCLK_CTRL & ( 1 << 18 )) != ( 1 << 18 ) );
    USBCLK_CTRL |= (1 << 24);	/* This should be set before OTG configuration,
				doesn't hurt to set again */		
    USBCLK_CTRL|= (1 << 22);	/* Enable USB Device Clock */
    while ( (USBCLK_CTRL & ( 1 << 22 )) != ( 1 << 22 ) );
    return;
}

/******************************************************************************
** Function name:		Set_OTG_1301_Value
**
** Descriptions:		Set bit(s) in ISP1301 register
**
** parameters:			register number, register value
** Returned value:		None
** 
******************************************************************************/
void Set_OTG_1301_Value( DWORD RegNum, DWORD RegValue )
{
    I2C_TX = 0x00000100 | OTG_1301_DEV_ADDR;	/* Send ISP1301 address, 
						R/W=0 with I2C start */
    I2C_TX = (DWORD)(RegNum | SET_BIT);
    I2C_TX = 0x00000200 | RegValue;		/* Data with I2C stop */
    while ( (I2C_STS & 0x01) != 0x1 );		/* Wait for TDI bit to set */
    I2C_STS |= 0x1;    
    return;
}

/******************************************************************************
** Function name:		Clr_OTG_1301_Value
**
** Descriptions:		Clear bit(s) in ISP1301 register
**
** parameters:			register number, register value
** Returned value:		None
** 
******************************************************************************/
void Clr_OTG_1301_Value( DWORD RegNum, DWORD RegValue )
{
    I2C_TX = 0x00000100 | OTG_1301_DEV_ADDR;	/* Send ISP1301 address, R/W=0 
						with I2C start */
    I2C_TX = (DWORD)(RegNum | CLR_BIT);
    I2C_TX = 0x00000200 | RegValue;		/* Data with I2C stop */
    while ( (I2C_STS & 0x01) != 0x1 );		/* Wait for TDI bit to set */
    I2C_STS |= 0x1;    
    return;
}

/******************************************************************************
** Function name:		Get_OTG_1301_Value
**
** Descriptions:		Read ISP1301 register value, I2C reading
**
** parameters:			register number
** Returned value:		register value
** 
******************************************************************************/
DWORD Get_OTG_1301_Value( DWORD RegNum )
{
    I2C_TX = 0x00000100 | OTG_1301_DEV_ADDR;	/* Send ISP1301 address, R/W=0 
						with I2C start */
    I2C_TX = (DWORD)RegNum;

    /* Send ISP1301 address, R/W=1 with I2C start( repeated start ). */
    I2C_TX = 0x00000100 | OTG_1301_DEV_ADDR | RD_BIT; 
    I2C_TX = 0x00000200 | DUMMY_BYTE;		/* write dummy byte for read 
						with I2C stop */ 
    while ( (I2C_STS & 0x01) != 0x1 );		/* Wait for TDI bit to set */
    I2C_STS |= 0x1;

    /* Read data from I2C_RX and return. */
    return ( I2C_RX );
}

/*********************************************************************************
**                            End Of File
*********************************************************************************/

⌨️ 快捷键说明

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