PC suspension wake-up with FX3

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
user_1245661
Level 2
Level 2
Welcome!

Hello Sir,

I implemented a composite device with two interfaces, one vendor specific and the other HID type. The HID interface uses a keyboard protocol.

The two interfaces (vendor and HID) work correctly, I have verified that the keyboard interface sends characters.

Now I would like the PC to be woken up by the FX3 when it goes into suspension, so I sampled an input that when it changes state generates a character towards the PC.

Unfortunately, the PC remains in suspension.

I also tried to use CyU3PUsbDoRemoteWakeup but I saw no improvement. The device is connected to USB3.

Do you have any advice on how to proceed?

Thanks in advance.

Niccolò

0 Likes
1 Solution
YashwantK_46
Moderator
Moderator
Moderator
100 solutions authored 50 solutions authored 50 likes received

Hello Niccolò,

"I also tried to use CyU3PUsbDoRemoteWakeup but I saw no improvement. The device is connected to USB3."

=> The CyU3PUsbDoRemoteWakeup() API is only effective when the device is connected to USB 2.0.

For USB3 devices, refer to CyU3PUsbSendDevNotification() API in the FX3 API Guide, page 530 present at the path: c:\program files (x86)\Cypress\EZ-USB FX3 SDK\1.3\doc\firmware\FX3APIGuide.pdf

To understand the usage of the API better, you can refer to the USBBulkSrcSink firmware present at the path: C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples\cyfxbulksrcsink


Regards,

Yashwant

View solution in original post

0 Likes
22 Replies
YashwantK_46
Moderator
Moderator
Moderator
100 solutions authored 50 solutions authored 50 likes received

Hello Niccolò,

"I also tried to use CyU3PUsbDoRemoteWakeup but I saw no improvement. The device is connected to USB3."

=> The CyU3PUsbDoRemoteWakeup() API is only effective when the device is connected to USB 2.0.

For USB3 devices, refer to CyU3PUsbSendDevNotification() API in the FX3 API Guide, page 530 present at the path: c:\program files (x86)\Cypress\EZ-USB FX3 SDK\1.3\doc\firmware\FX3APIGuide.pdf

To understand the usage of the API better, you can refer to the USBBulkSrcSink firmware present at the path: C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples\cyfxbulksrcsink


Regards,

Yashwant

0 Likes

Hello Yashwant,

thanks for the reply. I tried your advice and it works on two test PCs.  The same solution does not work on a DELL laptop.
Before sending CyU3PUsbSendDevNotification(1, 0, 0) I check the link power state and I find it in U3, so I try to put again in U0 through CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0) but it seems to be stuck on U3.

What can I do?


0 Likes

Hello,

In the DELL laptop, can you let me know if the CyU3PUsbSendDevNotification(1, 0, 0) API failed?

If the API failed, can you let me know the return code of the error?

Regards,

Yashwant

0 Likes

If I try to call the CyU3PUsbSendDevNotification this returns the value 0xFF (CY_U3P_ERROR_OPERN_DISABLED) but I think it's related to the Link power state that is CyU3PUsbLPM_U3.

0 Likes

Hello,

The CY_U3P_ERROR_OPERN_DISABLED error is thrown by the CyU3PUsbSendDevNotification() API when the link or the device are in U3 and not transitioning to U0.

So, can you let me the know error code when the CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0); API failed?

Regards,

Yashwant

0 Likes

The CyU3PUsbSetLinkPowerState return 0 and also the following CyU3PUsbGetLinkPowerState return 0.

Thanks

Niccolò

0 Likes

Hello,

The API's CyU3PUsbGetLinkPowerState() and CyU3PUsbSetLinkPowerState() return 0 when the link is already in U0 as mentioned in the typedef which is the return parameter of the above API's mentioned in cyu3usb.h as below :

typedef enum CyU3PUsbLinkPowerMode

{

    CyU3PUsbLPM_U0 = 0,                 /**< U0 (active) power state. */

    CyU3PUsbLPM_U1,                     /**< U1 power state. */

    CyU3PUsbLPM_U2,                     /**< U2 power state. */

    CyU3PUsbLPM_U3,                     /**< U3 (suspend) power state. */

    CyU3PUsbLPM_COMP,                   /**< Compliance state. */

    CyU3PUsbLPM_Unknown                 /**< The link is not in any of the Ux states. This normally

                                                                 happens while the link training is ongoing. */

} CyU3PUsbLinkPowerMode;

This means that the link is in U0 and not U3.

Please try CyU3PUsbGetLinkPowerState() and if the return status is not 0, then try CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0); and share your findings.

Regards,
Yashwant

0 Likes

Hello Yashwant,

thanks for the reply. Perhaps I did not explain myself well. I use the following function (taken from a Cypress example)before sending the character:

stat0 = CyU3PUsbGetLinkPowerState (&curState);

while ((stat0 == 0) && (curState >= CyU3PUsbLPM_U1) && (curState <= CyU3PUsbLPM_U3)) {

     stat1 = CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0);

     CyU3PThreadSleep(1);

     stat0 = CyU3PUsbGetLinkPowerState(&curState);

}

stat3 = CyU3PUsbSendDevNotification(1, 0, 0);

When the PC is suspended stat0 and stat1 always return 0 but curState contains CyU3PUsbLPM_U3, so the while cycles infinitely.

If I try to force the exit from the while cycle and let the CyU3PUsbSendDevNotification call, this returns the value 255 (CY_U3P_ERROR_OPERN_DISABLED).

I also call CyU3PUsbLPMDisable after the CyU3PConnectState and when I receive the CY_U3P_USB_EVENT_SETCONF event.

Regards,

Niccolò

0 Likes

EDITED:

Hello Niccolò,

Can you please check if there is CyU3PUsbLPMEnable API, being called in the firmware?

If there is, please share (code snippets) where it is called.

Also, change the above code snippet to the following two cases and test and let me know the findings:

(1.)

stat0 = CyU3PUsbGetLinkPowerState (&curState);

while ((stat0 == 0) && (curState != CyU3PUsbLPM_U0) {

     stat1 = CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0);

//     CyU3PThreadSleep(1);

//     stat0 = CyU3PUsbGetLinkPowerState(&curState);

}

stat3 = CyU3PUsbSendDevNotification(1, 0, 0);

(2.)

stat0 = CyU3PUsbGetLinkPowerState (&curState);

CyU3PBusyWait (200);

while ((stat0 == 0) && (curState != CyU3PUsbLPM_U0) {

     stat1 = CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0);

//     CyU3PThreadSleep(1);

//     stat0 = CyU3PUsbGetLinkPowerState(&curState);

}

stat3 = CyU3PUsbSendDevNotification(1, 0, 0);

Regards,

Yashwant

0 Likes

Hello Yashwant,

in my code I never call the CyU3PUsbLPMEnable.

I'll try your code snippets and let you know the results.

0 Likes

Hello Yashwant,

I tried your modifications but without success.

In detail it's not clear to me why I had to comment on the line:

//     stat0 = CyU3PUsbGetLinkPowerState(&curState);

If I don't call this function the variable curState is never updated and the while cycle never ends.

I tried putting pauses of various lengths but the result is that curState always remains stuck in CyU3PUsbLPM_U3.

Do you have other solutions to let me try?

0 Likes

Hello,

Please confirm that you are using SDK 1.3.4 for building the project. Also, please ensure that the FX3SDKVERSION in Project Settings -> C/C++ Build -> Build Variables is set to 1_3_4.

Also, please try the following change in code and let me know the result:

stat0 = CyU3PUsbGetLinkPowerState (&curState);

stat1 = CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0);

if(stat1 == CY_U3P_SUCCESS)

{

     while ((stat0 == 0) && (curState >= CyU3PUsbLPM_U1) && (curState <= CyU3PUsbLPM_U3))

     {

          CyU3PThreadSleep(1);  

          stat0 = CyU3PUsbGetLinkPowerState(&curState);

     }

stat3 = CyU3PUsbSendDevNotification(1, 0, 0);

}

Best regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello Jayakrishna,

I confirm that I am using SDK 1.3.4.

I tried your code but I get the same results.

When the PC is suspended, in the first call of CyU3PUsbGetLinkPowerState stat0 contain 0 and curState contains CyU3PUsbLPM_U3. After CyU3PUsbSetLinkPowerState stat1 contain 0. In the while loop the situation remains the same, so stat0 = 0 and curState = CyU3PUsbLPM_U3. The while never ends. If I try to force exit (with debugger move to line) and execute CyU3PUsbSendDevNotification stat3 = 255.

Let me know if you want to do more tests.

Best Regards,

Niccolò

0 Likes

Hello,

Please share the UART traces having USB logs in it. In order to understand how to add USB logs in the UART traces, you can refer to the SDK example USBBulkSrcSink. This project can be found in the following location of FX3 SDK:

C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples\cyfxbulksrcsink

In addition to this, please let us know if you have a Lecroy analyzer to capture the USB traces?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

I'm sorry but I don't have an USB analyzer. I've added the CyU3PUsbInitEventLog, you can find below the content of buffer after suspending PC and trying to send some characters.

When the PC goes into suspend mode I receive a CY_U3P_USB_EVENT_SUSPEND event on which no action is taken (no CyU3PSysEnterSuspendMode is called).

Memory.JPG

I hope this helps you understand what's going on.

Regards,

Niccolò

0 Likes

Hello,

Thank you for the update. As we do not have Lecroy to debug the issue, we can try to debug the issue by looking into the USB logs. Can you please share the UART debug logs with the firmware modified to print USB logs as mentioned in my previous reply? As per our understanding the PC puts the device into suspend state (USB link in U3) when it goes to sleep. From the USB logs in the UART debug prints, we want to confirm following things:

1. The device goes to U3 when the PC goes to sleep.

2. Is the device coming back to U0 when the PC is still in sleep.

3. Is the device coming back to U0 only after the PC wakes up.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

unfortunately I can't use UART logging because in my code it's used to communicate with an FPGA.

I can modify my code and record events though, could you tell me what specifically you are interested in?

I saw that there is a CyU3PDebugPrint in the CyFxBulkSrcSinkApplnUSBEventCB function that might be useful.

Then there is the CyU3PDebugPrint of the gl_UsbLogBuffer (at the end of the BulkSrcSinkAppThread_Entry) that I already provided you in the previous message.

Are there any other events I need to log?

0 Likes

Hello,

Can you please try the following code and let me know if the link is still in U3 or not?

     stat0 = CyU3PUsbGetLinkPowerState (&curState);

    CyU3PDebugPrint(4,"\r\nThe current state after entering recovery is %d", curState);

    stat1 = CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0);

    if(stat1 == CY_U3P_SUCCESS)

    {

         while ((stat0 == 0) && (curState != CyU3PUsbLPM_U0))

         {

              CyU3PThreadSleep(1);

              stat0 = CyU3PUsbGetLinkPowerState(&curState);

         }

         stat3 = CyU3PUsbSendDevNotification(1, 0, 0);

         if(stat3 != CY_U3P_SUCCESS)

         {

        CyU3PDebugPrint(4,"\r\n error code for wake up is %d", stat3);

         }

    }

Please let me now if the link is still in U3 after this modification.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

If I run the example curState remains stuck in CyU3PUsbLPM_U3 and stat0 and stat1 always returns 0. The while loops endlessly.

0 Likes

Hello,

Can you please share the USB event logs with the modification mentioned in my previous response?

Also, please let me know where have you implemented the code for obtaining the USB event logs. In addition to this, can you also try removing the delay inside the while loop (CyU3PThreadSleep(1) and check if it exhibits the same behaviour or not?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

as mentioned above the log is:

USB EVENT: 2 0
The current state after entering recovery is 3

Then the firmware gets stuck in the while loop:

"while ((stat0 == 0) && (curState != CyU3PUsbLPM_U0))"

If I try to remove the CyU3PThreadSleep(1) nothing change.

To get the USB event log I store the information in an array, to extract the information I run the code in debug via JTAG so I can access the registers directly via memory.

Regards,

Niccolò

0 Likes

Hello,

As you might be knowing, the USB event Log 2 indicates USB suspend event. I am sorry for making a mistake in my previous response. Can you please share the USB logs (as that shared in your response 15) with the modifications in code that I mentioned in my response 18?

Also, did you woke up the host by some other means when you shared the snapshot of USB logs in your response 15?

In addition to this, once the device enumerates please do the following

1. Open Device Manager.

2. Right click on the device and select properties.

3. Go to Power Management Tab of the device properties.

4. Check if the option Allow this device to wake the computer is enabled or not as shown below.

pastedImage_1.png

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes