Implementing remote wakeup per USB 2.0 spec

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
aneves
Experienced Member
Posts: 93
Joined: Wed Sep 16, 2015 2:38 pm

Implementing remote wakeup per USB 2.0 spec

Post by aneves »

Hello,

While browsing the example code in lib_usb, I noticed this snippet from the included function USB_StandardRequests:

Code: Select all

    case USB_CLEAR_FEATURE:

        /* Device Features than could potenially be cleared are as follows (See Figure 9-4)
         * Self Powered: Cannot be changed by SetFeature() or ClearFeature()
         * Remote Wakeup: Indicates if the device is currently enabled to request remote wakeup.
               by default not implemented
         */
        break;
If I wanted to support the remote wakeup feature in my device, how would I go about using lib_usb to actually wake the host per the USB 2.0 spec? In other words, how can I tell if my device has been suspended by the host and an event has occurred where I need to wake the host to transmit data between my device and the host?

Thanks.
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1140
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Hi, from USB made simple (http://www.usbmadesimple.co.uk/ums_3.htm):
It is also possible for a device with its remote wakeup feature set, to initiate a resume itself. It must have been in the idle state for at least 5ms, and must apply the wakeup K condition for between 1 and 15 ms. The host takes over the driving of the resume signal within 1 ms.

So you would need to apply the K condition. The best place to work out how to do this is by looking at:

Code: Select all

XUD_Manager.xc
which is where you can find the signalling manager code. Eg. function

Code: Select all

XUD_UIFM_PwrSigFlags()/code] around line 350
Engineer at XMOS
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1140
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Ok - seems that code I pointed to you is about configuring the PHY to detect (not assert) K-state.

Looking at the datasheet, it is not entirely obvious how to assert a K. However, XUD_TestMode.xc might help:

Code: Select all

        case WINDEX_TEST_K:
            //Function Control Reg. Suspend: 1 Opmode 10
#if defined(ARCH_S) || defined(ARCH_X200)
            write_periph_word(USB_TILE_REF, XS1_GLX_PERIPH_USB_ID, XS1_UIFM_FUNC_CONTROL_REG, 0b1000);
#else
            XUD_UIFM_RegWrite(reg_write_port, UIFM_REG_PHYCON, 0x11);
#endif

            while(1)
            {
                p_usb_txd <: 0;
            }
            break;
Engineer at XMOS
User avatar
aneves
Experienced Member
Posts: 93
Joined: Wed Sep 16, 2015 2:38 pm

Post by aneves »

Thanks for the reply, but how can I detect that my device has been suspended by the host?
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1140
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

There's a pair of callbacks called void XUD_UserSuspend() and void XUD_UserResume(). They are weak functions so just go ahead and define your own to override them. They are called from the XUD (USB) thread so you may want to set a shared memory flag or perhaps output over a channel end (perhaps use a pointer to global channel end to avoid passing a chanend all the way through the xud API).
Engineer at XMOS
User avatar
aneves
Experienced Member
Posts: 93
Joined: Wed Sep 16, 2015 2:38 pm

Post by aneves »

Cool, thanks!
User avatar
jb123
Member
Posts: 13
Joined: Mon Oct 09, 2023 9:45 pm

Post by jb123 »

infiniteimprobability wrote: Tue Feb 07, 2017 1:19 pm There's a pair of callbacks called void XUD_UserSuspend() and void XUD_UserResume(). They are weak functions so just go ahead and define your own to override them. They are called from the XUD (USB) thread so you may want to set a shared memory flag or perhaps output over a channel end (perhaps use a pointer to global channel end to avoid passing a chanend all the way through the xud API).
I was confused about these but now I understand. The weak ones are defined in

Code: Select all

sc_usb_audio\module_usb_audio\xuduser\xuduser.c
and are overridden by the ones in

Code: Select all

sw_usb_audio\app_usb_aud_xk_216_mc\src\extensions\xuduser.xc
for example. The latter is masked out by

Code: Select all

#ifdef USB_SEL_A
, which confused me, because that's for some kind of USB Host mode or something, but you can just ignore that and write your own XUD_UserSuspend() and XUD_UserResume() outside of that macro mask and make them do whatever you want.
User avatar
Ross
Verified
XCore Legend
Posts: 1077
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

The above relates to the device being able to perform an action based on the bus state determined by the host.

Remote wake up is something different and currently not implemented.
Technical Director @ XMOS. Opinions expressed are my own