📄 hwinit.c
字号:
DWORD * sysintr, DWORD dwOTGSupport, TCHAR *pOTGGroup)
{
DWORD r=TRUE, speed, temp;
int off, irq;
WORD sel = USB_SEL_H2;
DEBUGMSG(1, (TEXT("InitializeTransceiver USBH2 Physical Address = 0x%x\r\n"), *phyregs));
StringCbCopy(gszOTGGroup, sizeof(gszOTGGroup), pOTGGroup);
DEBUGMSG(1, (TEXT("#### InitializeTransceiver gdwOTGSupport = 0x%x\r\n"), gdwOTGSupport));
gdwOTGSupport = dwOTGSupport;
r=InitializeCPLD(&sel);
speed=r;
gSel = sel;
off=InitializeMux(sel);
USBClockInit();
if (speed==FULL_SPEED && sel==USB_SEL_H1)
{
ConfigH1(*regs);
irq=IRQ_USBHS1;
}
else if (sel == USB_SEL_H2)
{
ConfigH2(*regs);
irq = IRQ_USBHS2;
}
else {
ConfigOTG(*regs, speed);
irq = IRQ_USBOTG;
}
//if (dwOTGSupport && irq == IRQ_USB_OTG)
if (irq == IRQ_USBOTG)
*sysintr = SYSINTR_USBOTG;
else
KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD), sysintr, sizeof(DWORD), NULL);
DEBUGMSG(1, (TEXT("InitializeTransceiver: IRQ=%d, sysIntr=%d\r\n"), irq, *sysintr));
{ //usb_bypass_inactive()
USB_CTRL_T ctrl;
DWORD * temp=(DWORD *)&ctrl;
*temp=0;
ctrl.BPE=1; // Bypass Enable bit, clear it
CLRREG32(&(*regs)->USB_CTRL, *temp);
}
{
USB_USBMODE_T mode;
DWORD * temp=(DWORD *)&mode;
// Set USB Mode
*temp=0;
mode.CM=3; // Host
if (sel == USB_SEL_H1)
OUTREG32(&(*regs)->H1.USBMODE, *temp);
else if (sel == USB_SEL_H2)
OUTREG32(&(*regs)->H2.USBMODE, *temp);
else
OUTREG32(&(*regs)->OTG.USBMODE, *temp);
}
// power on port
{
if (sel == USB_SEL_H2)
{
DWORD *temp;
USB_HCSPARAMS_T hcs;
temp=(DWORD *)&hcs;
*temp=INREG32(&(*regs)->H2.HCSPARAMS);
if (hcs.PPC)
{
USB_PORTSC_T portsc;
DWORD * temp2= (DWORD *)&portsc;
*temp2 = INREG32(&(*regs)->H2.PORTSC);
portsc.PP = 1;
SETREG32(&(*regs)->H2.PORTSC, *temp2);
}
}
else if (sel == USB_SEL_OTG)
{
DWORD *temp;
USB_HCSPARAMS_T hcs;
temp=(DWORD *)&hcs;
*temp=INREG32(&(*regs)->OTG.HCSPARAMS);
if (hcs.PPC)
{
USB_PORTSC_T portsc;
DWORD * temp2= (DWORD *)&portsc;
*temp2 = INREG32(&(*regs)->OTG.PORTSC);
portsc.PP = 1;
SETREG32(&(*regs)->OTG.PORTSC, *temp2);
}
}
else if (speed==FULL_SPEED && sel==USB_SEL_H1)
{
DWORD *temp;
USB_HCSPARAMS_T hcs;
temp=(DWORD *)&hcs;
*temp=INREG32(&(*regs)->H1.HCSPARAMS);
if (hcs.PPC)
{
USB_PORTSC_T portsc;
DWORD * temp2= (DWORD *)&portsc;
*temp2 = INREG32(&(*regs)->H1.PORTSC);
portsc.PP = 1;
SETREG32(&(*regs)->H1.PORTSC, *temp2);
}
}
}
gpRegs = (PCSP_USB_REGS)(*regs);
gSel = sel;
if (sel==USB_SEL_OTG && speed==FULL_SPEED)
{
DEBUGMSG(1, (TEXT("Initialize1301\r\n")));
r=Initialize1301(*regs);
}
else
{
if (speed==FULL_SPEED)
{
DEBUGMSG(1, (TEXT("Initialize1105 FullSpeed\r\n")));
r=Initialize1105();
}
else if (sel == USB_SEL_H2)
{
DEBUGMSG(1, (TEXT("Initialize1504 H2 HighSpeed\r\n")));
#ifdef DEBUG
DumpUSBRegs((PCSP_USB_REGS)(*regs), sel);
#endif
r=Initialize1504(*regs, sel);
}
else
{
DEBUGMSG(1, (TEXT("Initialize1504 OTG HighSpeed && Dump Regs\r\n")));
#ifdef DEBUG
DumpUSBRegs((PCSP_USB_REGS)(*regs), sel);
#endif
r=Initialize1504(*regs,sel);
}
}
#ifdef DEBUG
DumpUSBRegs((PCSP_USB_REGS)(*regs), sel);
#endif
temp=*(DWORD*)regs;
temp+=off;
*(DWORD*)regs=temp;
*phyregs+=off;
DEBUGMSG(1, (TEXT("Host offset = 0x%x *phyregs 0x%x\r\n"), off,*phyregs));
return r;
}
//-----------------------------------------------------------------------------
//
// Function: BSPUsbCheckConfigPower
//
// Check power required by specific device configuration and return whether it
// can be supported on this platform. For CEPC, this is trivial, just limit
// to the 500mA requirement of USB. For battery powered devices, this could
// be more sophisticated, taking into account current battery status or other
// info.
//
// Parameters:
// bPort
// [in] Port number
//
// dwCfgPower
// [in] Power required by configuration in mA.
//
// dwTotalPower
// [in] Total power currently in use on port in mA.
//
// Returns:
// Return TRUE if configuration can be supported, FALSE if not.
//
//-----------------------------------------------------------------------------
BOOL BSPUsbhCheckConfigPower(UCHAR bPort, DWORD dwCfgPower, DWORD dwTotalPower)
{
if ( USB_HOST_MODE == 2 || USB_HOST_MODE == 4 )
{
// for FSH1 and HSH2 ports, ADS can supply 500 mA
return ((dwCfgPower + dwTotalPower) > 500) ? FALSE : TRUE;
}
// other OTG modes can only supply 100 mA
return ((dwCfgPower + dwTotalPower) > 100) ? FALSE : TRUE;
}
#ifdef DISABLE_DETACH_WAKEUP
#undef DISABLE_DETACH_WAKEUP
#endif
//#define DISABLE_DETACH_WAKEUP 1
//-----------------------------------------------------------------------------
//
// Function: BSPUsbSetWakeUp
//
// This function is to enable/disable the wakeup interrupt bit in USBCONTROL
//
// Parameters:
// bEnable - TRUE : Enable, FALSE : Disable
//
// Returns:
// NULL
//
//-----------------------------------------------------------------------------
void BSPUsbSetWakeUp(BOOL bEnable)
{
// Access the USB Control Register
DWORD *temp;
USB_CTRL_T ctrl;
USB_PORTSC_T portsc;
CSP_USB_REG *pReg;
// still need to check it first before proceed
BSPUsbCheckWakeUp();
switch (gSel) {
case USB_SEL_H2:
pReg = (PCSP_USB_REG)(&(gpRegs->H2));
break;
case USB_SEL_H1:
pReg = (PCSP_USB_REG)(&(gpRegs->H1));
break;
case USB_SEL_OTG:
pReg = (PCSP_USB_REG)(&(gpRegs->OTG));
break;
default:
break;
}
temp = (DWORD *)&portsc;
*temp = INREG32(&pReg->PORTSC[0]);
// If Current Connect Status = 1, we should not set WKCN or it would
// wake up right away. With this we can enable wake up on attach
if ((bEnable) && (portsc.CCS == 0))
{
portsc.WKCN = 1;
portsc.WKOC = 1;
portsc.WKDC = 0;
}
else
{
portsc.WKOC = 0;
portsc.WKDC = 0;
portsc.WKCN = 0;
}
OUTREG32(&pReg->PORTSC[0], *temp);
temp = (DWORD *)&ctrl;
#ifdef DISABLE_DETACH_WAKEUP
if (bEnable)
#else
if ((bEnable) && (portsc.CCS == 0))
#endif
*temp = INREG32(&gpRegs->USB_CTRL);
else
*temp = 0;
switch (gSel) {
case 0:
ctrl.H2WIE = 1;
ctrl.H2UIE = 1;
break;
case 1:
ctrl.H1WIE = 1;
break;
case 2:
ctrl.OWIE = 1;
ctrl.OUIE = 1;
break;
default:
break;
}
#ifdef DISABLE_DETACH_WAKEUP
if (bEnable)
#else
if ((bEnable) && (portsc.CCS == 0))
#endif
SETREG32(&gpRegs->USB_CTRL, *temp);
else
CLRREG32(&gpRegs->USB_CTRL, *temp);
//DEBUGMSG(1, (TEXT("BSPUsbSetWakeUp portsc(0x%x), usbctrl(0x%x)\r\n"), INREG32(&pReg->PORTSC[0]), INREG32(&gpRegs->USB_CTRL)));
return;
}
//-----------------------------------------------------------------------------
//
// Function: BSPUsbCheckWakeUp
//
// This function is called by CSP to clear the wakeup interrupt bit in USBCONTROL. According to
// MX31 specification, disable the wake-up enable bit also clear the interrupt request bit.
// This wake-up interrupt enable should be disable after receiving a wakeup request.
//
// Parameters:
// NULL
//
// Returns:
// TRUE - there is a wakeup. FALSE - no wakeup is set.
//
//-----------------------------------------------------------------------------
BOOL BSPUsbCheckWakeUp(void)
{
// Access the USB Control Register
DWORD *temp;
USB_CTRL_T ctrl;
BOOL fWakeUp = FALSE;
temp = (DWORD *)&ctrl;
*temp = INREG32(&gpRegs->USB_CTRL);
//DEBUGMSG(1, (TEXT("BSPUsbCheckWakeUp (0x%x), gSel(%d)\r\n"), *temp, gSel));
switch (gSel) {
case USB_SEL_H2:
if (ctrl.H2WIR == 1)
{
*temp = 0;
fWakeUp = TRUE;
ctrl.H2WIE = 1;
}
break;
case USB_SEL_H1:
if (ctrl.H1WIR == 1)
{
*temp = 0;
fWakeUp = TRUE;
ctrl.H1WIE = 1;
}
break;
case USB_SEL_OTG:
if (ctrl.OWIR == 1)
{
*temp = 0;
fWakeUp = TRUE;
ctrl.OWIE = 1;
}
break;
default:
break;
}
if (fWakeUp)
CLRREG32(&gpRegs->USB_CTRL, *temp);
//DEBUGMSG(1, (TEXT("BSPUsbCheckWakeUp (0x%x) return %d\r\n"), INREG32(&gpRegs->USB_CTRL), fWakeUp));
return fWakeUp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -