Przeglądaj źródła

Merge pull request #711 from hathach/usbd-handle-set-interface

Usbd handle set interface
Ha Thach 5 lat temu
rodzic
commit
f9817da397
2 zmienionych plików z 59 dodań i 44 usunięć
  1. 45 38
      examples/device/webusb_serial/src/main.c
  2. 14 6
      src/device/usbd.c

+ 45 - 38
examples/device/webusb_serial/src/main.c

@@ -169,52 +169,59 @@ void tud_resume_cb(void)
 bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request)
 {
   // nothing to with DATA & ACK stage
-  if (stage != CONTROL_STAGE_SETUP ) return true;
+  if (stage != CONTROL_STAGE_SETUP) return true;
 
-  if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR) {
-    switch (request->bRequest)
-    {
-      case VENDOR_REQUEST_WEBUSB:
-        // match vendor request in BOS descriptor
-        // Get landing page url
-        return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength);
-
-      case VENDOR_REQUEST_MICROSOFT:
-        if ( request->wIndex == 7 )
+  switch (request->bmRequestType_bit.type)
+  {
+    case TUSB_REQ_TYPE_VENDOR:
+      switch (request->bRequest)
+      {
+        case VENDOR_REQUEST_WEBUSB:
+          // match vendor request in BOS descriptor
+          // Get landing page url
+          return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength);
+
+        case VENDOR_REQUEST_MICROSOFT:
+          if ( request->wIndex == 7 )
+          {
+            // Get Microsoft OS 2.0 compatible descriptor
+            uint16_t total_len;
+            memcpy(&total_len, desc_ms_os_20+8, 2);
+
+            return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len);
+          }else
+          {
+            return false;
+          }
+
+        default: break;
+      }
+    break;
+
+    case TUSB_REQ_TYPE_CLASS:
+      if (request->bRequest == 0x22)
+      {
+        // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to connect and disconnect.
+        web_serial_connected = (request->wValue != 0);
+
+        // Always lit LED if connected
+        if ( web_serial_connected )
         {
-          // Get Microsoft OS 2.0 compatible descriptor
-          uint16_t total_len;
-          memcpy(&total_len, desc_ms_os_20+8, 2);
+          board_led_write(true);
+          blink_interval_ms = BLINK_ALWAYS_ON;
 
-          return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len);
+          tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n");
         }else
         {
-          return false;
+          blink_interval_ms = BLINK_MOUNTED;
         }
 
-      default:
-        return false;
-    }
-  } else if (
-        request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS &&
-        request->bRequest == 0x22) {
-    // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to
-    // connect and disconnect.
-    web_serial_connected = (request->wValue != 0);
-
-    // Always lit LED if connected
-    if ( web_serial_connected ) {
-      board_led_write(true);
-      blink_interval_ms = BLINK_ALWAYS_ON;
-
-      tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n");
-    }else
-    {
-      blink_interval_ms = BLINK_MOUNTED;
-    }
+        // response with status OK
+        return tud_control_status(rhport, request);
+      }
+    break;
 
-    // response with status OK
-    return tud_control_status(rhport, request);
+    default: break;
   }
 
   // stall unknown request

+ 14 - 6
src/device/usbd.c

@@ -699,13 +699,21 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
       // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE
       if ( !invoke_class_control(rhport, driver, p_request) )
       {
-        // For GET_INTERFACE, it is mandatory to respond even if the class
-        // driver doesn't use alternate settings.
-        TU_VERIFY( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type &&
-                   TUSB_REQ_GET_INTERFACE == p_request->bRequest);
+        // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class
+        // driver doesn't use alternate settings or implement this
+        TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type);
 
-        uint8_t alternate = 0;
-        tud_control_xfer(rhport, p_request, &alternate, 1);
+        if (TUSB_REQ_GET_INTERFACE == p_request->bRequest)
+        {
+          uint8_t alternate = 0;
+          tud_control_xfer(rhport, p_request, &alternate, 1);
+        }else if (TUSB_REQ_SET_INTERFACE == p_request->bRequest)
+        {
+          tud_control_status(rhport, p_request);
+        } else
+        {
+          return false;
+        }
       }
     }
     break;