📄 usb318xcfg.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 + -