wince唤醒时,死在USB OTG驱动里面了
[复制链接]
我是用的wince6.0,和三星6410的板子,驱动中有两个,一个是USB,另外一个是OTG,USB驱动里面很简单,就只有一个C文件。
当我将系统挂起之后,所有驱动均正常。唤醒之后,大部分驱动正常,在我测试之后,发现:
1. 将OTG驱动去掉,保留USB驱动,系统能够正常唤醒,但是有一个现象:直接开机的时候可以使用鼠标,唤醒之后鼠标不能使用了。
2. 将USB驱动保留,OTG驱动保留,系统不能唤醒。
3. 将两个驱动均拿掉,开机之后USB不能使用,只能用触摸屏。挂起唤醒均正常。
于是我将OTG中的POWERUP函数加入了调试信息,进入此函数时输出,退出此函数时也输出。结果是进入退出调试均正常。代码如下:
RETAILMSG(TRUE, (TEXT("[UfnPdd] +++Power Up\r\n")));
SETFNAME();
DEBUGMSG(ZONE_POWER, (_T("%s\r\n"), pszFname));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
RETAILMSG(TRUE, (TEXT("[UfnPdd] ---Power Up\r\n"))); 复制代码
此函数应该是没有任何操作的,执行也正常,那么会死在什么地方呢。
我看了OEMPowerOff,其中挂起之前,设置了一次USBOTG寄存器,将其关闭,唤醒之后立即开启了USBOTG,这两个步骤都是在OEMPowerOff中完成。代码如下:
void OEMPowerOff()
{
volatile S3C6410_SYSCON_REG *pSysConReg;
volatile S3C6410_GPIO_REG *pGPIOReg;
volatile S3C6410_VIC_REG *pVIC0Reg;
volatile S3C6410_VIC_REG *pVIC1Reg;
volatile S3C6410_DMAC_REG *pDMAC0Reg;
volatile S3C6410_DMAC_REG *pDMAC1Reg;
volatile OTG_PHY_REG *pOtgPhyReg;
int nIndex = 0;
OALMSG(TRUE, (L"[OEM] ++OEMPowerOff()\r\n"));
#if 0 // KITL can not support Sleep
// Make sure that KITL is powered off
pArgs = (OAL_KITL_ARGS*)OALArgsQuery(OAL_ARGS_QUERY_KITL);
if ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0)
{
OALKitlPowerOff();
OALMSG(1, (L"OEMPowerOff: KITL Disabled\r\n"));
}
#endif
//-----------------------------
// Disable DVS and Set to Full Speed
//-----------------------------
#ifdef DVS_EN
ChangeDVSLevel(SYS_L0);
#endif
//-----------------------------
// Prepare Specific Actions for Sleep
//-----------------------------
BSPPowerOff();
//------------------------------
// Prepare CPU Entering Sleep Mode
//------------------------------
//----------------
// Map SFR Address
//----------------
pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE);
pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
pVIC0Reg = (S3C6410_VIC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_VIC0, FALSE);
pVIC1Reg = (S3C6410_VIC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_VIC1, FALSE);
pDMAC0Reg = (S3C6410_DMAC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DMA0, FALSE);
pDMAC1Reg = (S3C6410_DMAC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DMA1, FALSE);
pOtgPhyReg = (OTG_PHY_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_USBOTG_PHY, FALSE);
//------------------
// Save VIC Registers
//------------------
S3C6410_SaveState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC);
// Disable All Interrupt
pVIC0Reg->VICINTENCLEAR = 0xFFFFFFFF;
pVIC1Reg->VICINTENCLEAR = 0xFFFFFFFF;
pVIC0Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;
pVIC1Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;
//--------------------
// Save DMAC Registers
//--------------------
S3C6410_SaveState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0);
S3C6410_SaveState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1);
//------------------
// Save GPIO Register
//------------------
S3C6410_SaveState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO);
//--------------------
// Save SysCon Register
//--------------------
S3C6410_SaveState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon);
//-------------------------------------------------------
// Unmask Clock Gating and Block Power turn On (SW workaround)
//-------------------------------------------------------
// HCLK_IROM, HCLK_MEM1, HCLK_MEM0, HCLK_MFC Should be Always On for power Mode (Something coupled with BUS operation)
//pSysConReg->HCLK_GATE |= ((1<<25)|(1<<22)|(1<<21)|(1<<0));
pSysConReg->HCLK_GATE = 0xFFFFFFFF;
pSysConReg->PCLK_GATE = 0xFFFFFFFF;
pSysConReg->SCLK_GATE = 0xFFFFFFFF;
// Turn On All Block Block Power
pSysConReg->NORMAL_CFG = 0xFFFFFF00;
// Wait for Block Power Stable
while((pSysConReg->BLK_PWR_STAT & 0x7E) != 0x7E);
//----------------------------
// Wake Up Source Configuration
//----------------------------
S3C6410_WakeUpSource_Configure();
//-------------------------------
// Extra work for Entering Sleep Mode
//-------------------------------
// USB Power Control
pSysConReg->OTHERS &= ~(1<<16); // USB Signal Mask Clear
pGPIOReg->SPCON |= (1<<3); // USB Tranceiver PAD to Suspend
// TODO: SPCONSLP ???
//pGPIOReg->SPCONSLP; // Use Default Valie
//-------------------------------
// GPIO Configuration for Sleep State
//-------------------------------
// TODO: Configure GPIO at Sleep
//BSPConfigGPIOforPowerOff();
// Sleep Mode Pad Configuration
pGPIOReg->SLPEN = 0x2; // Controlled by SLPEN Bit (You Should Clear SLPEN Bit in Wake Up Process...)
OALMSG(TRUE, (L"[OEM] --OEMPowerOff()\r\nCPU Entering Sleep Mode\r\n"));
OALMSG(TRUE, (L"****************************************************\r\n"));
//-----------------------
// CPU Entering Sleep Mode
//-----------------------
OALCPUPowerOff(); // Now in Sleep
//----------------------------
// CPU Wake Up from Sleep Mode
//----------------------------
//----------------------------
// Wake Up Source Determine
//----------------------------
S3C6410_WakeUpSource_Detect();
// USB Power Control
InitializeOTGCLK(); // pll_powerdown, suspend mode
pGPIOReg->SPCON &= ~(1<<3); // USB Tranceiver PAD to Normal
// Restore SysCon Register
S3C6410_RestoreState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon);
// Restore GPIO Register
S3C6410_RestoreState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO);
// Sleep Mode Pad Configuration
pGPIOReg->SLPEN = 0x2; // Clear SLPEN Bit for Pad back to Normal Mode
//-----------------------
// Restore DMAC Registers
//-----------------------
S3C6410_RestoreState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0);
S3C6410_RestoreState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1);
// Restore VIC Registers
S3C6410_RestoreState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC);
//pVIC0Reg->VICADDRESS = 0x0;
//pVIC1Reg->VICADDRESS = 0x0;
// UART Debug Port Initialize
OEMInitDebugSerial();
OALMSG(TRUE, (L"****************************************************\r\n"));
OALMSG(TRUE, (L"[OEM] --OEMPowerOff() --- Wake up\r\n"));
// Disable Vectored Interrupt Mode on CP15
System_DisableVIC();
// Enable Branch Prediction on CP15
System_EnableBP();
// Enable IRQ Interrupt on CP15
System_EnableIRQ();
// Enable FIQ Interrupt on CP15
System_EnableFIQ();
if (g_oalWakeSource == SYSWAKE_UNKNOWN)
{
OALMSG(TRUE, (L"[OEM:ERR] OEMPowerOff() : SYSWAKE_UNKNOWN , WAKEUP_STAT = 0x%08x", g_LastWakeupStatus));
}
// Initialize System Timer
OEMInitializeSystemTimer(RESCHED_PERIOD, OEM_COUNT_1MS, 0);
#if 0 // KITL can not support Sleep
// Reinitialize KITL
if ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0)
{
OALKitlPowerOn();
}
#endif
//--------------------------------------
// Post Processing Specific Actions for Wake Up
//--------------------------------------
BSPPowerOn();
OALMSG(TRUE, (L"[OEM] --OEMPowerOff() --- over\r\n"));
}
复制代码
请大家帮忙分析一下,为什么唤醒之后会挂掉。是死在驱动里面了,还是OTG寄存器的设置导致了CPU死掉了。
谢谢