|
关于DM3730在WCE系统EHCI驱动Suspend与Resume问题
[复制链接]
WinCE6R3,BSP基于:BSP_WINCE_ARM_A8_01_02_00,CPU:DM3730,PHY:TUSB1210,连接到CPU 的USBHOST2口,ULPI模式,USB口不连接任何外设。EHCI驱动为BSP包里的标准驱动。
系统正常启动后,按待机键,系统正常的进入Suspend状态,系统电流也较低,大概在12mA左右,TUSB1210的RESET脚为低电平。然后,按待机键,系统能够正常Resume,并且功能也都正常。
再次按待机键,系统正常进入Suspend状态,但是系统电流这时候在60mA左右,TUSB1210的RESET脚为高电平,然后,按待机键期望唤醒系统,系统有时能唤醒回到界面,但是功能有问题了——例如触摸屏无效了;有时不能唤醒,系统直接死掉或是抛出Data Abort,异常位置都指向Case D0段的代码。
翻看网上的一些帖子,这个问题在CE或是Linux系统下都有类似的问题,但似乎都没有什么结果。甚至4460里也有这样的问题,但是Fix方法在3730里好像不适用。
另根据网上的一些帖子,如果在系统suspend时不执行SetDevicePowerState(pPddObject->hParentBusHandle, D4, NULL);唤醒时不执行SetDevicePowerState(pPddObject->hParentBusHandle, D0, NULL);那么系统不会死或是Data Abort。但是Suspend时,电流在50mA左右,TUSB脚为高电平,强行置低RESET,电流为36mA左右,但这个电流对我们来说,太高了。
不知道有没有什么好的解决方法?
谢谢。
相关代码片段:
case D0:
RETAILMSG(1, (L"EHCI Back to D+\r\n"));
DeviceIoControl(pPddObject->hRootBus, IOCTL_BUS_REQUEST_CLOCK, &dwClock, sizeof(dwClock), NULL, 0, NULL, NULL);
//if(pPddObject->BusSuspendResume){
SetDevicePowerState(pPddObject->hParentBusHandle, D0, NULL);
DelayMilliSeconds(200, FALSE);
//}
RegVal = pUHHRegs->SYSCONFIG & ~(UHH_SYSCONFIG_MIDLEMODE(0x03) | UHH_SYSCONFIG_SIDLEMODE(0x03));
pUHHRegs->SYSCONFIG = RegVal | UHH_SYSCONFIG_MIDLEMODE(MIDLE_SMART) | UHH_SYSCONFIG_SIDLEMODE(SIDLE_SMART);
HcdMdd_PowerUp(pPddObject->lpvEHCDMddObject);
g_fOmapEhciSuspended = FALSE;
pPddObject->dwActualPowerState = ReqDx;
#if DUMP_REGS
dumpRegs(pPddObject);
#endif
RETAILMSG(1, (L"EHCI Back to D0-\r\n"));
break;
case D4:
RETAILMSG(1, (L"EHCI Enter to D4+\r\n"));
HcdMdd_PowerDown(pPddObject->lpvEHCDMddObject);
g_fOmapEhciSuspended = TRUE;
pUHHRegs->SYSCONFIG &= ~(UHH_SYSCONFIG_MIDLEMODE(0x03) | UHH_SYSCONFIG_SIDLEMODE(0x03));
pUHHRegs->SYSCONFIG |= (UHH_SYSCONFIG_MIDLEMODE(MIDLE_FORCE) | UHH_SYSCONFIG_SIDLEMODE(SIDLE_FORCE));
pPddObject->dwActualPowerState = ReqDx;
RETAILMSG(1, (L"EHCI Enter to D4-\r\n"));
break;
}
extern void HcdPdd_PowerDown(DWORD hDeviceContext)
{
SEHCDPdd * pPddObject = (SEHCDPdd *)hDeviceContext;
DWORD dwClock = pPddObject->USBHInfo.TLLDevice;
RETAILMSG(1, (L"HcdPdd_PowerDown\r\n"));
//if(pPddObject->BusSuspendResume)
SetDevicePowerState(pPddObject->hParentBusHandle, D4, NULL);
DeviceIoControl(pPddObject->hRootBus, IOCTL_BUS_RELEASE_CLOCK, &dwClock, sizeof(dwClock), NULL, 0, NULL, NULL);
//GPIOClrBit(pPddObject->hGpio, pPddObject->Port2RstGpio);
}
|
|