Przeglądaj źródła

usb_host: better debugging information during hcd_pipe_alloc() when usb_host_interface_claim() is being fulfiled.

Roman Leonov 2 lat temu
rodzic
commit
1be6977a9d
1 zmienionych plików z 52 dodań i 16 usunięć
  1. 52 16
      components/usb/hcd_dwc.c

+ 52 - 16
components/usb/hcd_dwc.c

@@ -13,6 +13,7 @@
 #include "esp_heap_caps.h"
 #include "esp_intr_alloc.h"
 #include "esp_err.h"
+#include "esp_log.h"
 #include "esp_rom_gpio.h"
 #include "hal/usb_dwc_hal.h"
 #include "hal/usb_types_private.h"
@@ -157,6 +158,8 @@ const fifo_mps_limits_t mps_limits_bias_ptx = {
 
 // -------------------- Convenience ------------------------
 
+const char *HCD_DWC_TAG = "HCD DWC";
+
 #define HCD_ENTER_CRITICAL_ISR()                portENTER_CRITICAL_ISR(&hcd_lock)
 #define HCD_EXIT_CRITICAL_ISR()                 portEXIT_CRITICAL_ISR(&hcd_lock)
 #define HCD_ENTER_CRITICAL()                    portENTER_CRITICAL(&hcd_lock)
@@ -1610,34 +1613,54 @@ static void buffer_block_free(dma_buffer_block_t *buffer)
     free(buffer);
 }
 
-static bool pipe_alloc_check_args(const hcd_pipe_config_t *pipe_config, usb_speed_t port_speed, const fifo_mps_limits_t *mps_limits, usb_transfer_type_t type, bool is_default_pipe)
+static bool pipe_args_usb_compliance_verification(const hcd_pipe_config_t *pipe_config, usb_speed_t port_speed, usb_transfer_type_t type)
 {
     //Check if pipe can be supported
     if (port_speed == USB_SPEED_LOW && pipe_config->dev_speed == USB_SPEED_FULL) {
-        //Low speed port does not supported full speed pipe
+        ESP_LOGE(HCD_DWC_TAG, "Low speed port does not support full speed pipe");
         return false;
     }
+
     if (pipe_config->dev_speed == USB_SPEED_LOW && (type == USB_TRANSFER_TYPE_BULK || type == USB_TRANSFER_TYPE_ISOCHRONOUS)) {
-        //Low speed does not support Bulk or Isochronous pipes
+        ESP_LOGE(HCD_DWC_TAG, "Low speed does not support Bulk or Isochronous pipes");
         return false;
     }
-    //Check interval of pipe
+
+    return true;
+}
+
+static bool pipe_alloc_hcd_support_verification(const usb_ep_desc_t * ep_desc, const fifo_mps_limits_t *mps_limits)
+{
+    assert(ep_desc != NULL);
+    usb_transfer_type_t type = USB_EP_DESC_GET_XFERTYPE(ep_desc);
+
+    //Check the pipe's interval is not zero
+    if ((type == USB_TRANSFER_TYPE_INTR || type == USB_TRANSFER_TYPE_ISOCHRONOUS) &&
+        (ep_desc->bInterval == 0)) {
+        ESP_LOGE(HCD_DWC_TAG, "bInterval value (%d) invalid for pipe type INTR/ISOC",
+                        ep_desc->bInterval);
+        return false;
+    }
+
+    //Check if the pipe's interval is compatible with the periodic frame list's length
     if (type == USB_TRANSFER_TYPE_INTR &&
-        (pipe_config->ep_desc->bInterval > 0 && pipe_config->ep_desc->bInterval > 32)) {
-        //Interval not supported for interrupt pipe
+        (ep_desc->bInterval > FRAME_LIST_LEN)) {
+        ESP_LOGE(HCD_DWC_TAG, "bInterval value (%d) of Interrupt pipe exceeds max supported limit",
+                ep_desc->bInterval);
         return false;
     }
+
     if (type == USB_TRANSFER_TYPE_ISOCHRONOUS &&
-        (pipe_config->ep_desc->bInterval > 0 && pipe_config->ep_desc->bInterval > 6)) {
-        //Interval not supported for isochronous pipe (where 0 < 2^(bInterval - 1) <= 32)
+        ((1 << (ep_desc->bInterval - 1)) > FRAME_LIST_LEN)) {
+        // (where 0 < 2^(bInterval - 1) <= FRAME_LIST_LEN)
+        ESP_LOGE(HCD_DWC_TAG, "bInterval value (%d) of Isochronous pipe exceeds max supported limit",
+                ep_desc->bInterval);
         return false;
     }
-    if (is_default_pipe) {
-        return true;
-    }
 
+    //Check if pipe MPS exceeds HCD MPS limits (due to DWC FIFO sizing)
     int limit;
-    if (USB_EP_DESC_GET_EP_DIR(pipe_config->ep_desc)) { //IN
+    if (USB_EP_DESC_GET_EP_DIR(ep_desc)) { //IN
         limit = mps_limits->in_mps;
     } else {    //OUT
         if (type == USB_TRANSFER_TYPE_CTRL || type == USB_TRANSFER_TYPE_BULK) {
@@ -1646,7 +1669,15 @@ static bool pipe_alloc_check_args(const hcd_pipe_config_t *pipe_config, usb_spee
             limit = mps_limits->periodic_out_mps;
         }
     }
-    return (pipe_config->ep_desc->wMaxPacketSize <= limit);
+
+    if (ep_desc->wMaxPacketSize > limit) {
+        ESP_LOGE(HCD_DWC_TAG, "EP MPS (%d) exceeds supported limit (%d)",
+                ep_desc->wMaxPacketSize,
+                limit);
+        return false;
+    }
+
+    return true;
 }
 
 static void pipe_set_ep_char(const hcd_pipe_config_t *pipe_config, usb_transfer_type_t type, bool is_default_pipe, int pipe_idx, usb_speed_t port_speed, usb_dwc_hal_ep_char_t *ep_char)
@@ -1828,18 +1859,23 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
     usb_transfer_type_t type;
     bool is_default;
     if (pipe_config->ep_desc == NULL) {
+        // Default CTRL pipe allocation
         type = USB_TRANSFER_TYPE_CTRL;
         is_default = true;
     } else {
         type = USB_EP_DESC_GET_XFERTYPE(pipe_config->ep_desc);
         is_default = false;
     }
+
+    esp_err_t ret;
     //Check if pipe configuration can be supported
-    if (!pipe_alloc_check_args(pipe_config, port_speed, mps_limits, type, is_default)) {
+    if (!pipe_args_usb_compliance_verification(pipe_config, port_speed, type)) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    //Default pipes have a NULL ep_desc thus should skip the HCD support verification
+    if (!is_default && !pipe_alloc_hcd_support_verification(pipe_config->ep_desc, mps_limits)) {
         return ESP_ERR_NOT_SUPPORTED;
     }
-
-    esp_err_t ret;
     //Allocate the pipe resources
     pipe_t *pipe = calloc(1, sizeof(pipe_t));
     usb_dwc_hal_chan_t *chan_obj = calloc(1, sizeof(usb_dwc_hal_chan_t));