1Introduction
Resume can be initiated by the host or the device. When initiated by the device, it is called remote wakeup. This article will share content related to remote wakeup, using the mouse as an example.
2Related Descriptors and Requests
To support remote wakeup, besides sending the resume signal, some protocol handling is also required. First, the configuration descriptor must report that the device supports remote wakeup. Then, the host enables and disables DEVICE_REMOTE_WAKEUP through Set Feature and Clear Feature requests. The Get Status request returns a 2-byte status where bit 1 indicates whether remote wakeup is enabled. Now, let's introduce the related descriptors and requests.
2.1Descriptors
Bit 5 of the bmAttributes field in the configuration descriptor must be set to 1 to indicate support for Remote Wakeup.
The Set Feature and Clear Feature requests are used to enable and disable wakeup, respectively. The bit 1 of the status obtained by the Get Status request indicates whether wakeup is currently enabled.
The general process is as follows:
- Before going to sleep, the HOST sends Set Feature DEVICE_REMOTE_WAKEUP to enable wakeup.
- The HOST stops bus data transmission and SOF, putting the device into the SUSPEND state.
- When DEVICE_REMOTE_WAKEUP is enabled and the device is in the suspend state, the device sends a resume signal to wake up the host.
- After waking up the host, the host resumes data transmission and sends Clear Feature DEVICE_REMOTE_WAKEUP to disable wakeup.
The related requests are as follows:
2.2.1 Get Status Requeststatus
When the Feature Selector is 1, it indicates DEVICE_REMOTE_WAKEUP.
To test the entire remote wakeup process, a specific device that supports wakeup is required. Here, we will conduct the test under Windows. Not all devices support wakeup; commonly, devices that do are mice and keyboards. Therefore, we will use a simulated mouse for testing.
The descriptors and requests related to the mouse example are as follows. For detailed information, please refer to the HID specification. Content beyond the scope of this article will not be elaborated.
3.1 Descriptors:Device Descriptorstatic const uint8_t s_dev_desc[] = {
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, 0x02, /* bcdUSB */
0x00, /* bDeviceClass https://www.usb.org/defined-class-codes */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize0 */
0x6C, 0x04, /* idVendor */
0x42, 0xC5, /* idProduct */
0x03, 0x02, /* bcdDevice */
0x01, /* iManufacturer */
0x02, /* iProduct */
0x00, /* iSerialNumber */
0x01, /* bNumConfigurations */
};
static const uint8_t s_cfg_desc[] = {
0x09, /* bLength */
0x02, /* bDescriptorType 0x02 */
0x22, 0x00, /* wTotalLength */
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0xA0, /* bmAttributes D5: Remote Wakeup=1 */
0x19, /* bMaxPower 50mA */
/* Interface 0:0 */
0x09, /* bLength */
0x04, /* bDescriptorType 0x04*/
MOUSE_DEMO_ITF_ID, /* bInterfaceNumber */
MOUSE_DEMO_ITF_ALT_ID, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass (HID - Human Interface Device) */
0x01, /* bInterfaceSubClass (Boot Interface) */
0x02, /* bInterfaceProtocol (Mouse) */
0x00, /* iInterface */
/* HID Descriptor */
0x09, /* bLength */
0x21, /* bDescriptorType : 0x21 (HID Descriptor) */
0x11, 0x01, /* bcdHID : 0x0111 (HID Version 1.11) */
0x21, /* bCountryCode : 0x21 (33 = US) */
0x01, /* bNumDescriptors : 0x01 */
REPORT_DESC,
0x5A, 0x00,
/* IN Endpoint */
0x07, /* bLength */
0x05, /* bDescriptorType 0x05*/
MOUSE_DEMO_INEP1, /* bEndpointAddress IN */
0x03, /* bmAttributes TransferType=Interrupt) */
MOUSE_DEMO_MAKE_WORD(MOUSE_DEMO_MPS), /* wMaxPacketSize */
0x04, /* bInterval */
};
uint8_t hid_desc[0x5A] = {
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x05, // Usage Maximum (0x05)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x16, 0x01, 0x80, // Logical Minimum (-32767)
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38, // Usage (Wheel)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x00, // Usage (Undefined)
0xA1, 0x01, // Collection (Application)
0x85, 0x05, // Report ID (5)
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01, // Usage (0x01)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x65, 0x08, // Unit (None)
0x95, 0x07, // Report Count (7)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
// 90 bytes
};
3.2 Enumeration ProcessThe enumeration process begins with the standard enumeration steps:
- Get the configuration descriptor
- Set the address
- Get the configuration descriptor again
- Get the string descriptor
The steps are as follows:
The next are two related HID requests: the Set_Idle request and the Get_Descriptor request (HID report descriptor request), as shown below:
3.2.1 Set_Idle Request
hid1_11.pdf 7.2.4 Set_Idle Request P62
Refer to hid1_11.pdf 7.1.1 Get_Descriptor Request on page 59.
The HID report descriptor specified in the HID descriptor in the configuration descriptor has a length of 0x005A and a type of 0x22.
The meaning of the descriptor is as follows: You can search online for parsing tools to analyze it. For more details, please refer to the HID specification book. I won't go into further detail here as it's beyond the scope of this document.
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x05, // Usage Maximum (0x05)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x16, 0x01, 0x80, // Logical Minimum (-32767)
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38, // Usage (Wheel)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x00, // Usage (Undefined)
0xA1, 0x01, // Collection (Application)
0x85, 0x05, // Report ID (5)
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01, // Usage (0x01)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x65, 0x08, // Unit (None)
0x95, 0x07, // Report Count (7)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
// 90 bytes
Afterward, it proceeds to the process of obtaining other string descriptors.
Upon completion of enumeration, the returned data consists of mouse data. Every 4 milliseconds, 7 bytes of data are returned. If the mouse status remains unchanged, the host's IN request is NAK.
Upon completion of enumeration, the returned data consists of mouse data. Every 4 milliseconds, 7 bytes of data are returned. If the mouse status remains unchanged, the host's IN request is NAK.
Comments
Please log in or sign up to comment.