{"id":521,"date":"2024-11-17T20:26:15","date_gmt":"2024-11-17T14:56:15","guid":{"rendered":"https:\/\/blog.mshafeeq.com\/?p=521"},"modified":"2024-11-17T20:27:04","modified_gmt":"2024-11-17T14:57:04","slug":"implementing-usb-as-a-custom-hid-device-using-stm32-part-2","status":"publish","type":"post","link":"https:\/\/blog.mshafeeq.com\/index.php\/2024\/11\/17\/implementing-usb-as-a-custom-hid-device-using-stm32-part-2\/","title":{"rendered":"Implementing USB as a Custom HID Device Using STM32 (Part &#8211; 2)"},"content":{"rendered":"\n<p>In the first part of this blog, we laid the groundwork by discussing the fundamentals of USB communication and the concepts behind Custom HID devices. With that foundation in place, it\u2019s time to delve deeper into the practical aspect of USB communication\u2014<strong>packet flow during HID enumeration<\/strong>.<\/p>\n\n\n\n<p>Enumeration is the process where the USB host detects, identifies, and configures a newly connected device. During this phase, various packets are exchanged between the host and the device, each serving a specific purpose. Understanding these packets, their formats, and their roles is crucial for debugging, optimizing, and creating USB devices from scratch.<\/p>\n\n\n\n<p>In this part, we\u2019ll dissect the packet flow step by step, starting with the <strong>control transfer requests<\/strong> sent by the host, followed by the device\u2019s responses. We\u2019ll explore the purpose of each packet type, analyze their structure, and explain how they contribute to the HID enumeration process. By the end of this section, you\u2019ll gain a clear understanding of how the USB host and device communicate at the protocol level, paving the way for implementing your own Custom HID device.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">USB Enumeration Process in Brief<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:50%\">\n<p>When the STM32 microcontroller powers on (POR), it initializes the USB peripheral and waits for the device to be connected. Upon plugging in, the host issues a USB reset to prepare the device for communication, followed by a series of standard requests: the <strong>Device Descriptor Request<\/strong> to identify basic device properties, the <strong>Set Address Request<\/strong> to assign a unique address, the <strong>Device Qualifier Request<\/strong> to query high-speed support (optional for full-speed devices), and the <strong>Device Configuration Request<\/strong> to activate the device. The host may also request <strong>String Descriptors<\/strong> for human-readable information(This is basically 4 requests and their responses. Language ID, Product Name, Manufacture Name and Serial number) and the <strong>Set Configuration Descriptor<\/strong> to finalize the setup. Additionally, during HID-specific enumeration, the host sends <strong>Set Idle Request <\/strong>to configure idle behavior and <strong>HID Report Descriptor Request<\/strong> to fetch the HID report format.<\/p>\n\n\n\n<p>The enumeration process, as described above, works in the sequence shown in the diagram on the right. In the diagram, I have outlined the flow of each request and its corresponding response, providing a visual representation of how the host and device communicate during enumeration. Each step, from the device descriptor request to the set configuration request, is illustrated to help you understand the sequence of interactions that occur.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:50%\"><div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"401\" height=\"862\" src=\"https:\/\/blog.mshafeeq.com\/wp-content\/uploads\/2024\/11\/USB-Flow-Chart.png\" alt=\"\" class=\"wp-image-523\" style=\"width:358px;height:auto\" srcset=\"https:\/\/blog.mshafeeq.com\/wp-content\/uploads\/2024\/11\/USB-Flow-Chart.png 401w, https:\/\/blog.mshafeeq.com\/wp-content\/uploads\/2024\/11\/USB-Flow-Chart-140x300.png 140w\" sizes=\"(max-width: 401px) 100vw, 401px\" \/><figcaption class=\"wp-element-caption\">Fig &#8211; 1: USB Enumeration Process<\/figcaption><\/figure><\/div><\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">USB 2.0 Specification<\/h3>\n\n\n\n<p>The USB specification documents are available on the official USB website, <a href=\"https:\/\/www.usb.org\">usb.org<\/a>. Since we are working with USB 2.0, I have already downloaded the document for this version(<a href=\"https:\/\/blog.mshafeeq.com\/wp-content\/uploads\/2024\/11\/usb_20.pdf\">Download<\/a>). You can access it directly from the official site as well. In this document, every requests and responses are described in detail. The request I got from the host and the response I have sent for each requests are shown below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The USB Request Format<\/h3>\n\n\n\n<p>A <strong>USB request<\/strong> is sent by the host to the device during communication, particularly during the enumeration process. It consists of an 8-byte setup packet, which is the first stage of a <strong>control transfer<\/strong>. This setup packet contains important fields that help define the specific operation the host wishes to perform on the device.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Name of Field<\/th><th>Size<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td>bmRequestType<\/td><td>1 byte<\/td><td><strong>Bit 7: Data Direction<br><\/strong>0 &#8211; OUT (Host to device)<br>1 &#8211; IN (Device to host)<br><strong>Bit 6-5: Type of request<br><\/strong>00 &#8211; Standard Request<br>01 &#8211; Interface Request<br>10 &#8211; Vendor Request<br>11 &#8211; Reserved<br><strong>D4-0: Recipient<\/strong><br>0 &#8211; Device<br>1 &#8211; Interface<br>2 &#8211; Endpoint<br>3 &#8211; Other<br>4..31 &#8211; Reserved<\/td><\/tr><tr><td>bRequest<\/td><td>1 byte<\/td><td>specifies the <strong>specific request<\/strong> that the host is making to the device<\/td><\/tr><tr><td>wValue<\/td><td>2 byte<\/td><td>The meaning of this field depends on the specific request.<br>It typically holds the index of the descriptor or a value related to the request.<\/td><\/tr><tr><td>wIndex<\/td><td>2 byte<\/td><td>This field provides additional context for the request. <br>It can be used to specify an interface or endpoint, depending on the type of request.<\/td><\/tr><tr><td>wLength<\/td><td>2 byte<\/td><td>Defines the length of the data to be transferred in the response<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">More details about these field can be found in <a href=\"https:\/\/www.beyondlogic.org\/usbnutshell\/usb6.shtml\">this link<\/a>.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Type of USB requests<\/h3>\n\n\n\n<ol>\n<li><strong>GET_DESCRIPTOR<\/strong> &#8211; Retrieves descriptors such as Device, Configuration, String, Interface, Endpoint, and HID descriptors.<\/li>\n\n\n\n<li><strong>SET_ADDRESS<\/strong> &#8211; Assigns a unique address to the device for communication.<\/li>\n\n\n\n<li><strong>SET_CONFIGURATION<\/strong> &#8211; Selects a specific configuration for the device.<\/li>\n\n\n\n<li><strong>GET_CONFIGURATION<\/strong> &#8211; Retrieves the currently active configuration.<\/li>\n\n\n\n<li><strong>GET_STATUS<\/strong> &#8211; Fetches the status of the device, interface, or endpoint (e.g., self-powered or remote-wakeup support).<\/li>\n\n\n\n<li><strong>CLEAR_FEATURE<\/strong> &#8211; Clears a specific feature (e.g., endpoint halt).<\/li>\n\n\n\n<li><strong>SET_FEATURE<\/strong> &#8211; Sets a specific feature (e.g., enable remote wakeup or halt an endpoint).<\/li>\n\n\n\n<li><strong>GET_INTERFACE<\/strong> &#8211; Retrieves the currently active alternate setting for an interface.<\/li>\n\n\n\n<li><strong>SET_INTERFACE<\/strong> &#8211; Selects an alternate setting for an interface.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Requests used for custom HID device enumeration<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Device Descriptor Request<\/h4>\n\n\n\n<p>The device descriptor request is a type of <strong>GET_DESCRIPTOR<\/strong>. The device descriptor is the data structure that provides essential information about a USB device to the host during the enumeration process. This is the initial request with maximum packet size (64 bytes) that the endpoint 0 can support since the host doesn&#8217;t know about the descriptor size. The host may use some standard size during this request like 8, 16, 32.. based on the USB version. A sample request and response are shown below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,           \/\/ (0x80) Requesting an IN, standard, Device request\n  06,           \/\/ (0x06) Request is GET_DESCRIPTOR\n  00, 01,       \/\/ (0x0100) Request for Device descriptor\n  00, 00,       \/\/ (0x0000) Not used here\n  40, 00        \/\/ (0x0040) Expected length 64 bytes\n}\n\nResponse: {\n  12,           \/\/ Length of response - 18 bytes (1 byte)\n  01,           \/\/ Type of descriptor - device descriptor (1 byte)\n  00, 20,       \/\/ What version of USB supports - (0x0200) USB2.0 (2 bytes)\n  00,           \/\/ Device class - Device class defined in interface descriptor (1 byte)\n  00,           \/\/ Device subclass\n  00,           \/\/ Device protocol\n  40,           \/\/ Maximum packet size - 64 bytes (1 byte)\n  83, 04,       \/\/ Vendor ID - 16 bit number assigned for the manufacture by USB.org (2 bytes)\n  5A, 57,       \/\/ Product ID - 16 bit number model ID assigned by vendor or product (2 bytes)\n  00, 20        \/\/ Device release number - eg 0x0200 for 2.0 (2 bytes)\n  01,           \/\/ Index of string manufacture (1 byte)\n  02,           \/\/ Index of string product descriptor (1 byte)\n  03,           \/\/ index of string serial number (1 byte)\n  01            \/\/ Number of configurations - 1 (1 byte)\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Set Address Request<\/h4>\n\n\n\n<p>After receiving the device descriptor, the host assigns a unique address to the USB device using a <strong>SET_ADDRESS<\/strong> request. This is a standard USB control transfer that allows the host to communicate with the device on the USB bus. While the host does not expect any data response for this request, it ensures the device can handle subsequent requests after the address is set.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  00,           \/\/ (0x00) Requesting an OUT, standard, Device request\n  05,           \/\/ (0x05) Request is SET_ADDRESS\n  02, 00,       \/\/ (0x0002) The address to be set is 2\n  00, 00,       \/\/ (0x0000) Reserved, set as 0\n  00, 00        \/\/ (0x0000) Expected length is 0 byte\n}\n\nResponse: {}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Device Descriptor Request<\/h4>\n\n\n\n<p>During the first request, the device may respond with either a full or partial descriptor based on the request length. From this response, the USB host determines the actual size of the descriptor and issues a second request to retrieve it. In this stage, the device is expected to send the complete device descriptor. In our case, since we already sent the entire descriptor during the first request, we simply send the same response again for the second request.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,           \/\/ (0x80) Requesting an IN, standard, Device request\n  06,           \/\/ (0x06) Request is GET_DESCRIPTOR\n  00, 01,       \/\/ (0x0100) Request for Device descriptor\n  00, 00,       \/\/ (0x0000) Not used here\n  12, 00        \/\/ (0x0012) Expected length 18 bytes\n}\n\nResponse: {\n  12,           \/\/ Length of response - 18 bytes (1 byte)\n  01,           \/\/ Type of descriptor - device descriptor (1 byte)\n  00, 20,       \/\/ What version of USB supports - (0x0200) USB2.0 (2 bytes)\n  00,           \/\/ Device class - Device class defined in interface descriptor (1 byte)\n  00,           \/\/ Device subclass\n  00,           \/\/ Device protocol\n  40,           \/\/ Maximum packet size - 64 bytes (1 byte)\n  83, 04,       \/\/ Vendor ID - 16 bit number assigned for the manufacture by USB.org (2 bytes)\n  5A, 57,       \/\/ Product ID - 16 bit number model ID assigned by vendor or product (2 bytes)\n  00, 20        \/\/ Device release number - eg 0x0200 for 2.0 (2 bytes)\n  01,           \/\/ Index of string manufacture (1 byte)\n  02,           \/\/ Index of string product descriptor (1 byte)\n  03,           \/\/ index of string serial number (1 byte)\n  01            \/\/ Number of configurations - 1 (1 byte)\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Qualifier Descriptor Request<\/h4>\n\n\n\n<p>The device qualifier descriptor describes information about a high-speed capable device that would change if the device were operating at the other speed. For example, if the device is currently operating at full-speed, the device_qualifier returns information about how it would operate at high-speed and vice-versa.<\/p>\n\n\n\n<p>If a full-speed only device receives a GET_DESCRIPTOR request for a device qualifier, it must respond with a STALL handshake.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,           \/\/ (0x80) Requesting an IN, standard, Device request\n  06,           \/\/ (0x06) Request is GET_DESCRIPTOR\n  00, 06,       \/\/ (0x0600) Request for device qualifier\n  00, 00,       \/\/ (0x0000) Not used here\n  0A, 00        \/\/ (0x000A) Expected length 10 bytes\n}\n\nResponse: {\n  0A,           \/\/ (0x0A) Length of response is 10 bytes\n  06,           \/\/ (0x06) This is qualifier response\n  00, 02,       \/\/ (0x0002) USB spec version number (0x0200 for 2.0)\n  00,           \/\/ (0x00) Class code\n  00,           \/\/ (0x00) Sub class code\n  00,           \/\/ (0x00) Protocol code\n  40,           \/\/ (0x40) Maximum packet size 64 bytes\n  01,           \/\/ (0x01) Number of other speed configurations\n  00            \/\/ (0x00) Reserved\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Configuration Descriptor Request<\/h4>\n\n\n\n<p>The <strong>Standard Configuration Descriptor<\/strong> is a USB descriptor that provides information about a device&#8217;s specific configuration. It is retrieved by the host using the <strong>GET_DESCRIPTOR<\/strong> request. This descriptor includes details about the device&#8217;s power requirements and the number of interfaces and endpoints it supports in a specific configuration.<\/p>\n\n\n\n<p>This two-step process is standard in USB enumeration to handle devices with varying descriptor sizes. By first requesting 9 bytes, the host avoids retrieving unnecessary data and ensures it only requests the exact amount needed in the second step.<\/p>\n\n\n\n<p>The configuration descriptor for custom HID interface composed of 4 parts<\/p>\n\n\n\n<ol>\n<li>Configuration Descriptor (9 bytes)<\/li>\n\n\n\n<li>Interface Descriptor (9 bytes)<\/li>\n\n\n\n<li>HID Descriptor (9 bytes)<\/li>\n\n\n\n<li>Endpoint Descriptor (7 bytes x 2 endpoints)<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,           \/\/ (0x80) Requesting an IN, standard, Device request\n  06,           \/\/ (0x06) Request is GET_DESCRIPTOR\n  00, 02,           \/\/ 0x0200 configuration descriptor\n  00, 00,           \/\/ Not used\n  29, 00            \/\/ 0x0009 (9 bytes) in the first request and 0x0029 (41 bytes) in the second request\n}\n\nResponse: {\n  \/\/ Configuration Descriptor (9 bytes)\n  09,               \/\/ (0x09) Size of configuration descriptor (9 bytes)\n  02,               \/\/ (0x02) Descriptor type (Configuration)\n  29, 00            \/\/ (0x0029) Total size of all descriptors in this configurations (41 bytes)\n  01,               \/\/ (0x01) Number of interfaces (1)\n  01,               \/\/ (0x01) Value to select this configuration (1)\n  00,               \/\/ (0x00) Index of string descriptor for this configuration (0 - means no string descriptor)\n  C0,               \/\/ (0xC0) Configuration char (6th bit - self powered)\n  32,               \/\/ (0x32) Maximum power consumption of the USB device from the bus in\n                    \/\/ this specific configuration when the device is fully operational (100mA).\n\n  \/\/ Interface Descriptors (9 bytes)\n  09,               \/\/ (0x09) Size of interface descriptor (9 bytes)\n  04,               \/\/ (0x04) Descriptor type (Interface)\n  00,               \/\/ (0x00) Interface number\n  00,               \/\/ (0x00) Alternate settings\n  02,               \/\/ (0x02) Number of endpoints (2)\n  03,               \/\/ (0x03) Interface Class (3 - HID)\n  00,               \/\/ (0x00) No subclass\n  00,               \/\/ (0x00) No protocol\n  00,               \/\/ (0x00) Index of string descriptor for this interface (0 - means no string descriptor)\n\n  \/\/ HID Descriptor\n  09,               \/\/ (0x09) Length of HID descriptor\n  21,               \/\/ (0x21) Descriptor type HID\n  11, 01,           \/\/ (0x0111) HID Class specification version in BCD (1.11)\n  00,               \/\/ (0x00) Target country code (0 - not localized)\n  01,               \/\/ (0x01) Number of additional descriptor (1)\n  22,               \/\/ (0x22) Type of additional descriptor (report descriptor)\n  03, 00,           \/\/ (0x0003) Length of additional descriptor (3)\n  \/\/ Type and length of additional descriptor can be repeated multiple times upto number of additional descriptors\n\n  \/\/ Endpoint descriptors 1 (IN) (7 bytes)\n  07,               \/\/ 7 (Size of the Endpoint Descriptor).\n  05,               \/\/ 5 (Endpoint Descriptor).\n  81,               \/\/ 0x81 (Endpoint 1, IN).\n  03,               \/\/ 0x03 (Interrupt transfer).\n  02, 00,           \/\/ Maximum packet size \n  05,               \/\/ 0x05 polling interval 5ms\n\n  \/\/ Endpoint descriptors 2 (OUT) (7 bytes)\n  07,               \/\/ 7 (Size of the Endpoint Descriptor).\n  05,               \/\/ 5 (Endpoint Descriptor).\n  01,               \/\/ 0x01 (Endpoint 1, OUT).\n  03,               \/\/ 0x03 (Interrupt transfer).\n  02, 00,           \/\/ Maximum packet size \n  05                \/\/ 0x05 polling interval 5ms\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Language ID String Request<\/h4>\n\n\n\n<p>The Language ID request and response help the host identify which languages the device can use for string descriptors. After receiving the language ID(s), the host can then request additional string descriptors (e.g., manufacturer name, product name) in the appropriate language.<\/p>\n\n\n\n<p>This mechanism ensures that devices support internationalization and localization of string descriptors, allowing for a customized user experience based on the language preferences of the host system.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,           \/\/ (0x80) Requesting an IN, standard, Device request\n  06,           \/\/ (0x06) Request is GET_DESCRIPTOR\n  00, 03,           \/\/ 0x0300 String descriptor\n  00, 00,           \/\/ Index is 0 (language descriptor)\n  FF, 00            \/\/ 0x00FF maximum 255 bytes\n}\n\nResponse: {\n  04,           \/\/ Length of response (4 bytes)\n  03,           \/\/ String descriptor\n  09, 04        \/\/ 0x0409 for english\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Product String Request<\/h4>\n\n\n\n<p>The <strong>product string<\/strong> typically identifies the product name of the device (e.g., the name of a keyboard or mouse) and is part of the <strong>String descriptors<\/strong> category, which provides human-readable information about the USB device.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,                       \/\/ (0x80) Requesting an IN, standard, Device request\n  06,                       \/\/ (0x06) Request is GET_DESCRIPTOR\n  02, 03,                   \/\/ 0x0302 Product string descriptor (index 2 is mapped to product string in the device descriptor)\n  09, 04,                   \/\/ Index is 0 (language descriptor)\n  FF, 00                    \/\/ 0x00FF maximum 255 bytes\n}\n\nResponse: {\n  3A,                       \/\/ (0x3A) Total length of response \n  03,                       \/\/ (0x03) String descriptor\n  53, 00, 54,               \/\/ Corresponding to \"STM32 Custom Human Interface\"\n  00, 4D, 00, 33, 00,\n  32, 00, 20, 00, 43,\n  00, 75, 00, 73, 00,\n  74, 00, 6F, 00, 6D,\n  00, 20, 00, 48, 00,\n  75, 00, 6D, 00, 61,\n  00, 6E, 00, 20, 00,\n  69, 00, 6E, 00, 74, \n  00, 65, 00, 72, 00, \n  66, 00, 61, 00, 63, \n  00, 65, 00\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Manufacturer String Request<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,                       \/\/ (0x80) Requesting an IN, standard, Device request\n  06,                       \/\/ (0x06) Request is GET_DESCRIPTOR\n  01, 03,                   \/\/ 0x0301 Manufacture string descriptor (index 1 is mapped to manufacture string in the device descriptor)\n  09, 04,                   \/\/ Index is 0 (language descriptor)\n  FF, 00                    \/\/ 0x00FF maximum 255 bytes\n}\n\nResponse: {\n  26,                       \/\/ (0x26) Total length of response \n  03,                       \/\/ (0x03) String descriptor\n  53, 00, 54,               \/\/ Corresponding to \"STMicroelectronics\"\n  00, 4D, 00, 69, 00,\n  63, 00, 72, 00, 6F,\n  00, 65, 00, 6C, 00,\n  65, 00, 63, 00, 74,\n  00, 72, 00, 6F, 00,\n  6E, 00, 69, 00, 63,\n  00, 73, 00\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Serial Number String Request<\/h4>\n\n\n\n<p>is used to retrieve the <strong>serial number<\/strong> of a USB device. It is part of the <strong>String descriptors<\/strong> mechanism, allowing the host to request additional identifying information about a device, such as its serial number, which is often unique to each device. This is useful for identifying and distinguishing devices of the same type or model.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  80,                       \/\/ (0x80) Requesting an IN, standard, Device request\n  06,                       \/\/ (0x06) Request is GET_DESCRIPTOR\n  03, 03,                   \/\/ 0x0303 Serial number string descriptor (index 3 is mapped to serial number in the device descriptor)\n  09, 04,                   \/\/ Index is 0 (language descriptor)\n  FF, 00                    \/\/ 0x00FF maximum 255 bytes\n}\n\nResponse: {\n  10,                       \/\/ (0x10) Total length of response \n  03,                       \/\/ (0x03) String descriptor\n  31, 00, 32,               \/\/ Corresponding to \"1234567890ABCDEF\"\n  00, 33, 00, 34, 00,\n  35, 00, 36, 00, 37,\n  00, 38, 00, 39, 00,\n  30, 00, 41, 00, 42,\n  00, 43, 00, 44, 00,\n  45, 00, 46, 00\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Set Configuration Request<\/h4>\n\n\n\n<p>The <strong>Set Configuration Request<\/strong> is a standard USB request sent by the host to configure a USB device after it has been enumerated. This request allows the host to select one of the available configurations provided by the device, which defines the device&#8217;s power consumption, interfaces, and endpoint descriptors. It is crucial because the device may have multiple configurations (e.g., different modes of operation or power settings), and the host uses this request to choose the appropriate configuration for communication. The request is sent on the control endpoint using the <strong>bRequest<\/strong> value 0x09 with the <strong>wValue<\/strong> specifying the configuration index.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  00,                       \/\/ Host-to-Device, Standard, Device recipient.\n  09,                       \/\/ SET_CONFIGURATION request.\n  01, 00,                   \/\/ Configuration value (0x0001 specified in configuration descriptor) to set.\n  00, 00,                   \/\/ Not used\n  00, 00                    \/\/ No data expected\n}\n\nResponse: {}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Set Idle Request (HID Class specific)<\/h4>\n\n\n\n<p>This request is used to limit the reporting frequency of an interrupt in endpoint. Specifically, this request causes the endpoint to NAK any polls on an interrupt in endpoint while its current report remains unchanged. In the absence of a change, polling will continue to be NAKed for a given time-based duration<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  21,                       \/\/ Host-to-Device, Class, Interface recipient.\n  0A,                       \/\/ SET_IDLE request (HID-specific).\n  00, 00,                   \/\/ High byte: Idle duration (0 for infinite). Low byte: Report ID (0 for all).\n  00, 00,                   \/\/ Interface number (usually 0 for single interface devices).\n  00, 00                    \/\/ No data expected\n}\n\nResponse: {}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">HID Report Request (HID Class Specific)<\/h4>\n\n\n\n<p>If we are going to send\/receive raw data, we don&#8217;t need to define any HID report. So just define as follows<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request: {\n  81,                       \/\/ Device-to-Host, Standard, Interface recipient.\n  06,                       \/\/ GET_DESCRIPTOR request.\n  00, 22,                   \/\/ Descriptor Type (0x2200 = HID Report Descriptor).\n  00, 00,                   \/\/ Interface number (usually 0 for single interface devices).\n  03, 00                    \/\/ Expected length 3 bytes\n}\n\nResponse: {\n  A1, 01,                 \/\/ Collection (Application)\n  C0                        \/\/ End collection\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In the first part of this blog, we laid the groundwork by discussing the fundamentals of USB communication and the concepts behind Custom HID devices. With that foundation in place, it\u2019s time to delve deeper into the practical aspect of USB communication\u2014packet flow during HID enumeration. Enumeration is the process where the USB host detects, &#8230; <a title=\"Implementing USB as a Custom HID Device Using STM32 (Part &#8211; 2)\" class=\"read-more\" href=\"https:\/\/blog.mshafeeq.com\/index.php\/2024\/11\/17\/implementing-usb-as-a-custom-hid-device-using-stm32-part-2\/\" aria-label=\"Read more about Implementing USB as a Custom HID Device Using STM32 (Part &#8211; 2)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[10,15,24,27,12,48],"_links":{"self":[{"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/posts\/521"}],"collection":[{"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/comments?post=521"}],"version-history":[{"count":37,"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/posts\/521\/revisions"}],"predecessor-version":[{"id":562,"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/posts\/521\/revisions\/562"}],"wp:attachment":[{"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/media?parent=521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/categories?post=521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mshafeeq.com\/index.php\/wp-json\/wp\/v2\/tags?post=521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}