2 Replies Latest reply on Jun 11, 2015 3:24 PM by jake.wegman

    Setting the Link Power State

    jake.wegman

      Hello,

         

      I'm a little bit new to link states in USB, so please forgive my ignorance on this topic.  I'd like to set the link state to U2.  I have the following code:

         
       if (glForceLinkU2)         {             stat = CyU3PUsbGetLinkPowerState (&curState);             while ((glForceLinkU2) && (stat == CY_U3P_SUCCESS) && (curState == CyU3PUsbLPM_U0))             {                 /* Repeatedly try to go into U2 state.*/                 CyU3PUsbSetLinkPowerState (CyU3PUsbLPM_U2);                 CyU3PThreadSleep (5);                 stat = CyU3PUsbGetLinkPowerState (&curState);             }             CyU3PGpioSetValue(LED0,LED_ON);         }
         

      ...which is essentially the same code given in the bulkauto DMA example, except that I've added code to turn on a debug LED once the loop has finished.  Unfortunately, the loop never finishes because the link power state is never U2/is always U0.  My assumption is that I'm not doing something on the host side to allow this transition, i.e. I can't just ask the device to change to U2 if the host doesn't change something as well.  Am I correct in this assumption?  What do I have to do on both sides of the interface to get this to work?

         

      Thanks!

        • 1. Re: Setting the Link Power State
          robert.kliemann

          Hi,

             

          the host needs to allow the device to initiate a U1/U2-transition by setting U1/U2_ENABLE feature in the device using the standard-request SET_FEATURE. You can request the current values of the U1/U2_ENABLE by using the standard-request GET_STATUS. Have a look in the USB3.0 specification chapter 9.4 for more details on the standard-requests and it's definitions.

             

           

             

          Best regards,

             

          Robert

          • 2. Re: Setting the Link Power State
            jake.wegman

            Hello,

               

            I've done some more work/research on this today and I'm still running into issues.  Robert, you were correct that the function wasn't being called using the explicit SET_FEATURE call for U2_ENABLE.  I had taken one of the SDK examples and modified it for my purposes, but I'm not sure that the U2 transition actually works in the example code (I couldn't get it to work as I thought it should).  I found this in the API guide:

               

            void CyU3PUsbRegisterSetupCallback ( CyU3PUSBSetupCb_t callback, CyBool_t fastEnum )

               

            Register a USB setup request handler.

               

            Description

               

            This function is used to register a USB setup request handler with the USB driver. The fastEnum parameter specifies whether this setup handler should be used only for unknown setup requests or for all USB setup requests.

               

            The example code had fastEnum set to CyTrue, which is why I couldn't initially run the code using a SET_FEATURE request.  So, I took the example cyfxlowpowertest.c and added the 'CyU3PSetPowerLink' code there.  I'm still seeing the same issue with the link state never changing from U0, even though, using debug print statements, I can see it filtering through the setup callback as expected.

               

            Is there another example in the SDK that I'm missing that reproducibly forces the various states?  On the host side, I'm running Python on top of Libusb to set in the various commands, so attempt to set the link to U2, I do the following:

               

            x.controlWrite(0x0,0x3,0x31,0,0,500)

               

            Is that right, or am I missing something?  Like I stated before, I can see via debug messages that everything is successful until the CyU3PSetPowerLink function call.

               

            Thanks,

               

            Jake