This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TPS65930 USB OTG suspend and resume problem

Other Parts Discussed in Thread: TPS65930, OMAP3530

Hi, All

Our board use TPS65930 OTG PHY with OMAP3530 OTG Controller to support OTG USB port and we run WinCE 6.0 (WinCE_BSP_01_00_00 from ti website) on our board.

I connect one usb disk to this usb otg port, it can be recognized, then I pressed the pwron button to make the system go to sleep,after a few minutes, I pressed pwron button again to wakeup the system, now the usb disk can not be recognized.

Someone here met same problem?

Would  you someone give some advices?

 

Thanks & Best Regards,

Stephen Zhang

  • Stephen,

     

    I took a quick look at your issue, using the current release and did not see a problem.  As it appears you are using an older release/custom board, we are planning on having a new release available within about a week or so. The release should be labeled WinCE_BSP_01_01_00 and available from the same location where you obtained the prior release.

    If you should find the same problem in the new release, please provide a more detailed setup scenario and I'll take another look at it here.

     

    Regards,

    Ken

  • Stephen,

    Check your register settings if they are restored back to what they were before you went to sleep. If your custom board behaves the way TI EVM does, then on pressing PWRON button, the board goes to suspend state in which all power domains except WKUP go to OFF mode. As a result, most of the register settings are reset and one needs to restore them back on resume. All of our drivers are designed to handle this - check if the same is happening for your OTG driver when using TPS PHY.

    -Madhvi

  • Hi, Ken

    Thanks for your reply.

    You tried on TI EVM or some other board, in fact, TI EVM3530 uses ISP1507 as USB OTG PHY. Can you make sure you test the TPS65930 OTG PHY, and the bsp release you used is WinCE_BSP_01_00_00 or WinCE_BSP_01_01_00.?

    I will try the newest bsp when it is released.

    Thanks a lot.

     

    Hi,Madhvi

    thanks.

    I will check the registers.

     

     

     

  • Hi Stephen,

     

    My testing was performed on the TI EVM board (Rev G) using the OMAP3530 SOC. Unfortunately, our board does not use the TPS65930 OTG PHY, so there is no way for me to validate it at this time. Hopefully, the suggestions by Madhvi will work.

    The code I used is what will be known as WinCE_BSP_01_01_00 when it is released.

     

    Regards,

    Ken

     


  •  Hi Stephen,

    I have also met the same problem, you can try moving the code in the power handler to the SetPowerState function, it works in my board, but I don't know why. the OTG driver is written so badly.

    Best Regards

    Jack Chen

  • Hi, Jack

    Thanks for your reply.

    Would you pls give me more information about how to move the code in power handler to the setPowerState Function, which part code to move ?

    BTW:

    I am not sure about the power handler, where is it?

     

    Thanks 

     

    Stephen Zhang

  • Hi, Stephen

    For the OTG driver , the power handler is the menber function PowerUp and PowerDown of OMAPMHSUSBOTG.

    Best Regards.

    Jack

  • Hi,Jack

    I modified the otg.cpp file SetPowerState function:

    OMAPMHSUSBOTG::SetPowerState(CEDEVICE_POWER_STATE reqDx)
    {
        PCSP_MUSB_GEN_REGS pGen;
        BOOL isHostMode = FALSE;
        pGen = m_pOTG->pUsbGenRegs;

        //RETAILMSG(1, (L"+OTG SetPowerState D%d, bClockStatus %d\r\n", reqDx, m_pOTG->bClockStatus));
       
        switch (reqDx)
        {
            case D0:
            case D1:
            case D2:
            {
                BOOL bIncCount = m_bIncCount;
                BOOL a_device_present;
                BOOL b_device_present;
                PowerUp();  // ADD HERE
                if (m_pTransceiver->SupportsTransceiverWakeWithoutClock())
                {
                    // *** Transceiver in TWL4030/TPS659xx ***

                    a_device_present = m_pTransceiver->IsADeviceConnected();
                    b_device_present = m_pTransceiver->IsBDeviceConnected();

                    m_bIncCount = FALSE;
                    m_pOTG->dwPwrMgmt = MODE_SYSTEM_RESUME;

                    StartUSBClock(TRUE);

                    if (m_disconnected)
                    {
                        if(a_device_present)
                        {
                            OUTREG8(&pGen->IntrUSBE, INTRUSB_ALL&~INTRUSB_SOF);
                            OUTREG16(&pGen->IntrTxE, 0xffff);
                            OUTREG16(&pGen->IntrRxE, 0xfffe);

                            if (m_OTGRegCfg.DisableHighSpeed)
                            {
                                CLRREG8(&m_pOTG->pUsbGenRegs->Power, POWER_HSENABLE);
                                SETREG8(&m_pOTG->pUsbGenRegs->Power, POWER_SOFTCONN);
                            }
                            else
                                SETREG8(&m_pOTG->pUsbGenRegs->Power, POWER_HSENABLE|POWER_SOFTCONN);
                        }
                        else if(b_device_present)
                        {
                            OUTREG8(&pGen->IntrUSBE, INTRUSB_ALL&~INTRUSB_SOF);
                            OUTREG16(&pGen->IntrTxE, 0xffff);
                            OUTREG16(&pGen->IntrRxE, 0xfffe);

                            m_dwStatus = STATUS_SESSION_RESTART;
                            CLRREG8(&m_pOTG->pUsbGenRegs->Power, POWER_SUSPENDM);
                            m_pTransceiver->SetVBusSource(TRUE);
                        }
                        else
                        {
                            StopUSBClock();

                            m_pOTG->bClockStatus = FALSE;
                            UpdateDevicePower(m_hParent, D4, NULL);
                            m_pTransceiver->EnableWakeupInterrupt(TRUE);
                        }
                    }
                    else
                    {
                        StopUSBClock();

                        CLRREG8(&m_pOTG->pUsbGenRegs->Power, POWER_SUSPENDM);
                        m_pTransceiver->SetVBusSource(TRUE);

                        m_pOTG->bClockStatus = FALSE;
                        UpdateDevicePower(m_hParent, D4, NULL);

                        m_pTransceiver->EnableWakeupInterrupt(TRUE);
                    }
                }
                else
                {
                    // *** Transceiver is pure ULPI interface ***

                    // clock control moved to PowerUp

                    // resume transceiver configuration (may restore external VBUS control)
                    m_pTransceiver->Resume();

                    //RETAILMSG(1, (L"OTG SetPowerState D0, unmask interrupts\r\n"));
                    OUTREG8(&pGen->IntrUSBE, INTRUSB_ALL&~INTRUSB_SOF);
                    OUTREG16(&pGen->IntrTxE, 0xffff);
                    OUTREG16(&pGen->IntrRxE, 0xfffe);

                    m_pOTG->dwPwrMgmt = MODE_SYSTEM_RESUME;
                   
                    SetInterruptEvent(m_dwSysIntr);
                }
            }
            break;

            case D3:
            case D4:
            {

                pGen = m_pOTG->pUsbGenRegs;
                if (!m_disconnected)
                {
                    m_pOTG->dwPwrMgmt = MODE_SYSTEM_SUSPEND;
                    DEBUGMSG(ZONE_OTG_FUNCTION, (TEXT("OTG Power Down\r\n")));

                    if(m_pOTG->bClockStatus != TRUE)
                        goto cleanUp;

                    if (m_pOTG->pUsbGenRegs->DevCtl & DEVCTL_HOSTMODE)
                    {
                        DEBUGMSG(ZONE_OTG_INFO, (TEXT("OTG Power Down SetDevicePowerState D3\r\n")));

                        CLRREG8(&m_pOTG->pUsbGenRegs->DevCtl, DEVCTL_SESSION);
                        SETREG8(&m_pOTG->pUsbGenRegs->Power, POWER_EN_SUSPENDM);
                        SETREG8(&m_pOTG->pUsbGenRegs->Power, POWER_SUSPENDM);

                        Sleep(100);

                        // clock control moved to PowerDown
                                    PowerDown();//ADD HERE

                    }
                    else
                    {
                        DEBUGMSG(ZONE_OTG_INFO, (TEXT("OTG Power Down SetDevicePowerState D4\r\n")));

                        OUTREG8(&pGen->IntrUSBE, 0);
                        OUTREG16(&pGen->IntrTxE, 0);
                        OUTREG16(&pGen->IntrRxE, 0);

                        // Simulate disconnect.
                        CLRREG8(&m_pOTG->pUsbGenRegs->Power, POWER_SOFTCONN);

                        // Read Interrupt status registers to clear outstanding interrupts
                        INREG8(&pGen->IntrUSB);
                        INREG16(&pGen->IntrTx);
                        INREG16(&pGen->IntrRx);

                        SessionRequest(FALSE, FALSE);

                        PowerDownDisconnect();

                        Sleep(100);

                        // clock control moved to PowerDown
                        PowerDown();//ADD HERE
                    }
                }
                else
                {
                    if (m_pOTG->bClockStatus == TRUE)
                    {
                        m_pOTG->dwPwrMgmt = MODE_SYSTEM_SUSPEND;
                        // clock control moved to PowerDown
                        PowerDown();//ADD HERE
                    }

                    m_pOTG->dwPwrMgmt = MODE_SYSTEM_SUSPEND;
                }
                m_pTransceiver->EnableWakeupInterrupt(TRUE);
            }
            break;
        }
    cleanUp:
        RETAILMSG(1, (L"-OTG SetPowerState\r\n"));
        return TRUE;
    }

    red code above is added according to your last post.

    But I fail to resume it. Is the code added placed wrong?

     

    Thanks

     

  •  

    Dear Phoenixtju and experts,

     

    I have the same situation:

    "I connect one usb disk to this usb otg port, it can be recognized, then I pressed the pwron button to make the system go to sleep,after a few minutes, I pressed pwron button again to wakeup the system, now the usb disk can not be recognized."

    I try to add those codes in otg.cpp, but comes with following errors when suspend:

    ===========================

    -OTG SetPowerState

    Exception 'Data Abort' (4): Thread-Id=07ea0006(pth=9010c6ec), Proc-Id=00400002(pprc=8c011308)

    'NK.EXE', VM-active=049e000a(pprc=921f806c) 'explorer.exe' PC=d3ff4b54(musbhcd.dll+0x00004b54)

    RA=d3ff7428(musbhcd.dll+0x00007428) SP=d3e4fa60, BVA=00000000

     

    OID_PNP_SET_POWER:

    OID_PNP_SET_POWER: 4

    SVC_PowerDown() entered.

    OAL::+OEMPowerOff(...)

    ===========================

    Have any idea to solve the ''OTG usb disck will disappear during suspend and resume" ?