📄 hwinit.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (C) 2005-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: hwinit.c
// This file contains the functions used to configure the MUX, CPLD and initialize
// the USB registers for the USB client driver
//
//
#pragma optimize( "", off )
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#include "bsp.h"
#include "mx31_usbname.h"
#include "mx31_usbcommon.h"
#define HIGH_SPEED 1
#define FULL_SPEED 2
//extern void SetULPIDeviceModePwr(CSP_USB_REGS*pRegs, BOOL fSuspend);
//#define FREESCALE_DEBUG
//-----------------------------------------------------------------------------
//
// Function: BSPGetUSBControllerType
//
// This is used by the public common CSP library to be used to return the USB controller
// currently using.
//
// Parameters:
// None.
//
// Returns:
// USB_SEL_OTG, USB_SEL_H2 or USB_SEL_H1. In this case, it would be USB_SEL_OTG
//
//-----------------------------------------------------------------------------
WORD BSPGetUSBControllerType(void)
{
return USB_SEL_OTG;
}
//-----------------------------------------------------------------------------
//
// Function: InitializeMux
//
// This function is to configure the IOMUX
// can safely share access.
//
// Parameters:
// speed - the speed of the device to configure as OTG can be configured as
// HS or FS . Currently only HS is used and as such the parameter is not used.
//
// Returns:
// TRUE - success, FALSE - failure.
//
//-----------------------------------------------------------------------------
static BOOL InitializeMux(int speed)
{
UNREFERENCED_PARAMETER(speed);
//RETAILMSG(1, (TEXT("InitializeMux\r\n")));
//usb_otg_iomux_connection();
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_NXT, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_STP, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DIR, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_CLK, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_USB_PWR, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: dumpCPLD
//
// This function is to dump the CPLD information
//
// Parameters:
// cpld - Pointer to Mapped CPLD Register
//
// Returns:
// None
//
//-----------------------------------------------------------------------------
void dumpCPLD(PCSP_PBC_REGS cpld)
{
RETAILMSG(1,(L"Dump PBC registers:\r\n"));
RETAILMSG(1,(L"\tVERSION=%x\r\n", INREG16(&cpld->VERSION)));
RETAILMSG(1,(L"\tBSTAT2=%x\r\n", INREG16(&cpld->BSTAT2)));
RETAILMSG(1,(L"\tBCTRL1_SET=%x\r\n", INREG16(&cpld->BCTRL1_SET)));
RETAILMSG(1,(L"\tBCTRL1_CLEAR=%x\r\n", INREG16(&cpld->BCTRL1_CLEAR)));
RETAILMSG(1,(L"\tBCTRL2_SET=%x\r\n", INREG16(&cpld->BCTRL2_SET)));
RETAILMSG(1,(L"\tBCTRL2_CLEAR=%x\r\n", INREG16(&cpld->BCTRL2_CLEAR)));
RETAILMSG(1,(L"\tBCTRL3_SET=%x\r\n", INREG16(&cpld->BCTRL3_SET)));
RETAILMSG(1,(L"\tBCTRL3_CLEAR=%x\r\n", INREG16(&cpld->BCTRL3_CLEAR)));
RETAILMSG(1,(L"\tBCTRL4_SET=%x\r\n", INREG16(&cpld->BCTRL4_SET)));
RETAILMSG(1,(L"\tBCTRL4_CLEAR=%x\r\n", INREG16(&cpld->BCTRL4_CLEAR)));
RETAILMSG(1,(L"\tBSTAT1=%x\r\n", INREG16(&cpld->BSTAT1)));
RETAILMSG(1,(L"\tINT_STATUS=%x\r\n", INREG16(&cpld->INT_STATUS)));
RETAILMSG(1,(L"\tINT_CUR_STATUS=%x\r\n", INREG16(&cpld->INT_CUR_STATUS)));
RETAILMSG(1,(L"\tINT_MASK_SET=%x\r\n", INREG16(&cpld->INT_MASK_SET)));
RETAILMSG(1,(L"\tINT_MASK_CLEAR=%x\r\n", INREG16(&cpld->INT_MASK_CLEAR)));
}
//-----------------------------------------------------------------------------
//
// Function: InitializeCPLD
//
// This function is to configure the CPLD to corresponding USB core
//
// Parameters:
// sel - the value in which USB core to configure. Since FS OTG doesn't need
// to support, this parameter is not used.
//
// Returns:
// Speed of the USB core - HIGH_SPEED or FULL_SPEED
//
//-----------------------------------------------------------------------------
static int InitializeCPLD(WORD * sel)
{
volatile PCSP_PBC_REGS cpld;
PHYSICAL_ADDRESS phyAddr;
int r;
UNREFERENCED_PARAMETER(sel);
phyAddr.QuadPart = BSP_BASE_REG_PA_PBC_BASE;
cpld = (PCSP_PBC_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_PBC_REGS), FALSE);
if (cpld == NULL)
{
return FALSE;
}
OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_OTG_HS_EN));//bit 7: OTG_HS_EN (disabled)
OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_OTG_FS_EN)); //bit 1: OTG_FS_EN (disabled)
// The configuration of Full Speed USB client is commented out and to be used
// in the future when Full Speed USB OTG client need to be supported.
// if ((INREG16(&cpld->BSTAT2))&(1<<4))
// {
// RETAILMSG(1, (L"Full speed USB client\r\n"));
// OUTREG16(&cpld->BCTRL3_CLEAR, (1<<PBC_BCTRL3_OTG_FS_EN));
// OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_OTG_FS_SEL));
// *sel=INREG16(&cpld->BCTRL3_SET)&(1<<PBC_BCTRL3_OTG_FS_SEL);
// r=FULL_SPEED;
// }
// else
{
DEBUGMSG(1, (L"High speed USB client\r\n"));
OUTREG16(&cpld->BCTRL3_CLEAR, (1<<PBC_BCTRL3_OTG_HS_EN)); //Clear_Bit_BCTRL3(7)
//OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_HSH_SEL)); //Set_Bit_BCTRL3(4); //Rev C has a bug conflict with ATA
r=HIGH_SPEED;
}
//dumpCPLD(cpld);
//OUTREG16(cpld->BCTRL3_CLEAR, 1<<PBC_BCTRL3_OTG_FS_EN);
MmUnmapIoSpace(cpld, sizeof(CSP_PBC_REGS));
return r;
}
extern BOOL Initialize1301(CSP_USB_REGS * regs);
extern void HardwarePullupDP1301(CSP_USB_REGS * regs);
extern BOOL Initialize1504(CSP_USB_REGS * regs);
extern BOOL HardwarePullupDP1504(CSP_USB_REGS * regs);
//-----------------------------------------------------------------------------
//
// Function: InitializeTransceiver
//
// This function is to configure the USB core
//
// Parameters:
// regs - pointer to the registers for all three USB core
// speed - the speed of the OTG USB Core to be configured.
// if full speed, it is using the ISP1301, otherwise it is ISP1504
//
// Returns:
// TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
static BOOL InitializeTransceiver(CSP_USB_REGS* regs, int speed)
{
DWORD r=TRUE;
//Sleep(5000); //Not work
{
USB_USBMODE_T mode;
DWORD * temp;
USB_HCSPARAMS_T hcs;
USB_USBCMD_T cmd;
USB_PORTSC_T port;
// Enable power for OTG on port 1
temp=(DWORD *)&hcs;
*temp=INREG32(®s->OTG.HCSPARAMS);
if (hcs.PPC) {
WORD USB_OTG_PORTSC1_Write_MASK = (0x1<<1)+(0x1<<3)+(0x1<<5);
*temp=INREG32(®s->OTG.PORTSC[0]);
*temp&=~USB_OTG_PORTSC1_Write_MASK;
*temp|=1<<12;
SETREG32(®s->OTG.PORTSC[0], *temp);
// note: SETREG32 reads and ORs extra bits from temp. So what's done above doesn't seem to
// do as intended (seems it wanted to leave 1, 3, and 5 as they were; they are write-to-clear)
// I haven't changed this because of code lock-down
}
//Sleep(5000); // Not work
// reset the usb otg
SETREG32(®s->OTG.USBCMD, (1<<1));
while((INREG32(®s->OTG.USBCMD) & (0x1<<1)) == (0x1<<1))
{
Sleep(100);
}
//Sleep(5000); //Work
// Set USB Mode
temp=(DWORD *)&mode;
*temp=0;
//RETAILMSG(1, (TEXT("Set USB Mode to 2\r\n")));
mode.CM=2;
mode.SLOM=1; // 2.3 hardware and later
OUTREG32(®s->OTG.USBMODE, *temp);
// otg_itc_setup(0);
temp=(DWORD *)&cmd;
*temp=INREG32(®s->OTG.USBCMD);
cmd.ITC=0;
OUTREG32(®s->OTG.USBCMD, *temp);
// otg_frindex_setup(1);
OUTREG32(®s->OTG.FRINDEX, 1);
// otg_set_configflag_on();
OUTREG32(®s->OTG.CONFIGFLAG, 1);
// Port reset
temp=(DWORD *)&port;
*temp=INREG32(®s->OTG.PORTSC[0]);
while (port.PR) {
*temp=0; port.PR=1;
CLRREG32(®s->OTG.PORTSC[0], *temp);
*temp=INREG32(®s->OTG.PORTSC[0]);
}
}
if (speed==FULL_SPEED)
r=Initialize1301(regs);
else
r=Initialize1504(regs);
//DumpULPIRegs(regs);
//DEBUGMSG(1, (TEXT("InitializeTransceiver done\r\n")));
return r;
}
//------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// Function: HardwareInitialize
//
// This function is being called by CSP code to initialize the transceiver, USB core
// and CPLD
//
// Parameters:
// regs - Pointer to the 3 USB Core registers.
//
// Returns:
// TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
BOOL HardwareInitialize(CSP_USB_REGS * regs)
{
int r;
WORD sel;
r=InitializeCPLD(&sel);
if (r==0)
return FALSE;
if (USBClockInit() &&
InitializeMux(r) && InitializeTransceiver(regs,r))
return TRUE;
else
return FALSE;
}
//-----------------------------------------------------------------------------
//
// Function: HardwarePullupDP
//
// This function is being called by CSP code to pull up the D+ if necessary.
//
// Parameters:
// regs - Pointer to the 3 USB Core registers.
//
// Returns:
// TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
BOOL HardwarePullupDP(CSP_USB_REGS * regs)
{
BOOL fSuccess = FALSE;
USB_PORTSC_T portsc;
DWORD * temp=(DWORD*)&portsc;
*temp=INREG32(®s->OTG.PORTSC[0]);
if (portsc.PTS==2) {
// Stop USB Controller first
USB_USBCMD_T cmd;
DWORD * temp = (DWORD *)&cmd;
*temp = INREG32(®s->OTG.USBCMD);
cmd.RS = 0;
OUTREG32(®s->OTG.USBCMD, *temp);
while ((INREG32(®s->OTG.USBCMD) & 0x1) == 0x1){
//RETAILMSG(1, (TEXT("USBCMD= 0x%x\r\n"), (INREG32(&(*regs)->OTG.USBCMD))));
Sleep(100);
}
fSuccess = HardwarePullupDP1504(regs);
DEBUGMSG(1, (L"ISP1504 High Speed used with success %d\r\n", fSuccess));
// Start USB Controller first
if (fSuccess)
{
temp = (DWORD *)&cmd;
*temp = INREG32(®s->OTG.USBCMD);
cmd.RS = 1;
OUTREG32(®s->OTG.USBCMD, *temp);
while ((INREG32(®s->OTG.USBCMD) & 0x1) == 0x0){
//RETAILMSG(1, (TEXT("USBCMD= 0x%x\r\n"), (INREG32(&(*regs)->OTG.USBCMD))));
Sleep(100);
}
}
}
else {
fSuccess = TRUE;
HardwarePullupDP1301(regs);
RETAILMSG(1, (L"ISP1301 Full Speed used\r\n"));
}
//DumpUSBRegs(regs, 2);
return fSuccess;
}
//-----------------------------------------------------------------------------
//
// Function: GetSysIntr
//
// This function is to return the SYSINTR value being used by OTG USB core
//
// Parameters:
// NONE
//
// Returns:
// SYSINTR being used
//
//-----------------------------------------------------------------------------
DWORD GetSysIntr(void)
{
return SYSINTR_USBOTG;
}
#pragma optimize( "", on )
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -