From e3ba980d113aa303fec233ea978f894b5805e0cc Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Fri, 11 Feb 2022 20:26:35 +0100 Subject: [PATCH] usb_host: Use USB_Host library calls for desc printing --- components/usb/usb_helpers.c | 22 ++++- .../usb/host/cdc/cdc_acm_host/README.md | 23 +++-- .../usb/host/cdc/cdc_acm_host/main/usb-cdc.c | 2 +- .../cdc/common/cdc_acm_host/cdc_acm_host.c | 92 +++++++++++-------- .../cdc_acm_host/include/usb/cdc_acm_host.h | 5 +- 5 files changed, 91 insertions(+), 53 deletions(-) diff --git a/components/usb/usb_helpers.c b/components/usb/usb_helpers.c index c74451c6bb..6966c03a9e 100644 --- a/components/usb/usb_helpers.c +++ b/components/usb/usb_helpers.c @@ -230,6 +230,19 @@ static void usbh_print_cfg_desc(const usb_config_desc_t *cfg_desc) printf("bMaxPower %dmA\n", cfg_desc->bMaxPower * 2); } +static void print_iad_desc(const usb_iad_desc_t *iad_desc) +{ + printf("*** Interface Association Descriptor ***\n"); + printf("bLength %d\n", iad_desc->bLength); + printf("bDescriptorType %d\n", iad_desc->bDescriptorType); + printf("bFirstInterface %d\n", iad_desc->bFirstInterface); + printf("bInterfaceCount %d\n", iad_desc->bInterfaceCount); + printf("bFunctionClass 0x%x\n", iad_desc->bFunctionClass); + printf("bFunctionSubClass 0x%x\n", iad_desc->bFunctionSubClass); + printf("bFunctionProtocol 0x%x\n", iad_desc->bFunctionProtocol); + printf("iFunction %d\n", iad_desc->iFunction); +} + void usb_print_device_descriptor(const usb_device_desc_t *devc_desc) { if (devc_desc == NULL) { @@ -265,15 +278,18 @@ void usb_print_config_descriptor(const usb_config_desc_t *cfg_desc, print_class_ do { switch (next_desc->bDescriptorType) { - case USB_W_VALUE_DT_CONFIG: + case USB_B_DESCRIPTOR_TYPE_CONFIGURATION: usbh_print_cfg_desc((const usb_config_desc_t *)next_desc); break; - case USB_W_VALUE_DT_INTERFACE: + case USB_B_DESCRIPTOR_TYPE_INTERFACE: usbh_print_intf_desc((const usb_intf_desc_t *)next_desc); break; - case USB_W_VALUE_DT_ENDPOINT: + case USB_B_DESCRIPTOR_TYPE_ENDPOINT: print_ep_desc((const usb_ep_desc_t *)next_desc); break; + case USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION: + print_iad_desc((const usb_iad_desc_t*)next_desc); + break; default: if(class_specific_cb) { class_specific_cb(next_desc); diff --git a/examples/peripherals/usb/host/cdc/cdc_acm_host/README.md b/examples/peripherals/usb/host/cdc/cdc_acm_host/README.md index 2685ffb440..b30ddb3d9e 100644 --- a/examples/peripherals/usb/host/cdc/cdc_acm_host/README.md +++ b/examples/peripherals/usb/host/cdc/cdc_acm_host/README.md @@ -33,23 +33,26 @@ idf.py -p PORT flash monitor See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. +### Running with dual USB CDC device +USB CDC device example [tusb_serial_device example](../../../device/tusb_serial_device) +can be configured to act as dual CDC device. + +In the device example project, enter command `idf.py menuconfig` and set Component config->TinyUSB Stack->Communication Device Class (CDC)->CDC channel Count to `2`. + +This settings also changes device's PID, so `EXAMPLE_USB_DEVICE_PID` in [usb-cdc.c](./main/usb-cdc.c) must be changed to `0x4002`. + + ## Example Output After the flashing you should see the output at idf monitor: ``` +... I (256) USB-CDC: USB Host installed I (256) USB-CDC: Opening CDC ACM device 0x303A:0x4001 -CDC Header Descriptor: - bcdCDC: 1.20 -CDC Call Descriptor: - bmCapabilities: 0x00 - bDataInterface: 1 -CDC ACM Descriptor: - bmCapabilities: 0x02 -CDC Union Descriptor: - bControlInterface: 0 - bSubordinateInterface[0]: 1 +... +Device descriptor is printed here +... I (1666) USB-CDC: Data received I (1666) USB-CDC: 0x3ffc4c20 41 54 0d |AT.| I (2666) USB-CDC: Data received diff --git a/examples/peripherals/usb/host/cdc/cdc_acm_host/main/usb-cdc.c b/examples/peripherals/usb/host/cdc/cdc_acm_host/main/usb-cdc.c index 8534c4416c..f0d831ce71 100644 --- a/examples/peripherals/usb/host/cdc/cdc_acm_host/main/usb-cdc.c +++ b/examples/peripherals/usb/host/cdc/cdc_acm_host/main/usb-cdc.c @@ -16,7 +16,7 @@ #define EXAMPLE_USB_HOST_PRIORITY 20 #define EXAMPLE_USB_DEVICE_VID 0x303A // 0x303A:0x4001 (TinyUSB CDC device) -#define EXAMPLE_USB_DEVICE_PID 0x4001 +#define EXAMPLE_USB_DEVICE_PID 0x4001 // Change this to 0x4002 for dual CDC device static const char *TAG = "USB-CDC"; diff --git a/examples/peripherals/usb/host/cdc/common/cdc_acm_host/cdc_acm_host.c b/examples/peripherals/usb/host/cdc/common/cdc_acm_host/cdc_acm_host.c index fb9eb26e9b..108078ebcd 100644 --- a/examples/peripherals/usb/host/cdc/common/cdc_acm_host/cdc_acm_host.c +++ b/examples/peripherals/usb/host/cdc/common/cdc_acm_host/cdc_acm_host.c @@ -673,7 +673,7 @@ static esp_err_t cdc_acm_find_intf_and_ep_desc(cdc_dev_t *cdc_dev, uint8_t intf_ const usb_standard_desc_t *cdc_desc = (usb_standard_desc_t *)cdc_dev->notif.intf_desc; do { cdc_desc = usb_parse_next_descriptor(cdc_desc, config_desc->wTotalLength, &desc_offset); - if ((cdc_desc == NULL) || (cdc_desc->bDescriptorType != ((USB_CLASS_COMM << 4) | USB_W_VALUE_DT_INTERFACE))) + if ((cdc_desc == NULL) || (cdc_desc->bDescriptorType != ((USB_CLASS_COMM << 4) | USB_B_DESCRIPTOR_TYPE_INTERFACE ))) break; // We found all CDC specific descriptors cdc_dev->num_cdc_intf_desc++; cdc_dev->cdc_intf_desc = @@ -844,46 +844,66 @@ esp_err_t cdc_acm_host_close(cdc_acm_dev_hdl_t cdc_hdl) return ESP_OK; } +/** + * @brief Print CDC specific descriptor in human readable form + * + * This is a callback function that is called from USB Host library, + * when it wants to print full configuration descriptor to stdout. + * + * @param[in] _desc CDC specific descriptor + */ +static void cdc_acm_print_desc(const usb_standard_desc_t *_desc) +{ + if (_desc->bDescriptorType != ((USB_CLASS_COMM << 4) | USB_B_DESCRIPTOR_TYPE_INTERFACE )) + { + // Quietly return in case that this descriptor is not CDC interface descriptor + return; + } + + switch (((cdc_header_desc_t *)_desc)->bDescriptorSubtype) { + case CDC_DESC_SUBTYPE_HEADER: { + cdc_header_desc_t *desc = (cdc_header_desc_t *)_desc; + printf("\t*** CDC Header Descriptor ***\n"); + printf("\tbcdCDC: %d.%d0\n", ((desc->bcdCDC >> 8) & 0xF), ((desc->bcdCDC >> 4) & 0xF)); + break; + } + case CDC_DESC_SUBTYPE_CALL: { + cdc_acm_call_desc_t *desc = (cdc_acm_call_desc_t *)_desc; + printf("\t*** CDC Call Descriptor ***\n"); + printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val); + printf("\tbDataInterface: %d\n", desc->bDataInterface); + break; + } + case CDC_DESC_SUBTYPE_ACM: { + cdc_acm_acm_desc_t *desc = (cdc_acm_acm_desc_t *)_desc; + printf("\t*** CDC ACM Descriptor ***\n"); + printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val); + break; + } + case CDC_DESC_SUBTYPE_UNION: { + cdc_union_desc_t *desc = (cdc_union_desc_t *)_desc; + printf("\t*** CDC Union Descriptor ***\n"); + printf("\tbControlInterface: %d\n", desc->bControlInterface); + printf("\tbSubordinateInterface[0]: %d\n", desc->bSubordinateInterface[0]); + break; + } + default: + ESP_LOGW(TAG, "Unsupported CDC specific descriptor"); + break; + } +} + void cdc_acm_host_desc_print(cdc_acm_dev_hdl_t cdc_hdl) { assert(cdc_hdl); cdc_dev_t *cdc_dev = (cdc_dev_t *)cdc_hdl; - ESP_RETURN_ON_FALSE(cdc_dev->num_cdc_intf_desc > 0,, TAG, "No CDC-ACM specific descriptors found"); - - for (int i = 0; i < cdc_dev->num_cdc_intf_desc; i++) { - switch (((cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i])->bDescriptorSubtype) { - case CDC_DESC_SUBTYPE_HEADER: { - cdc_header_desc_t *desc = (cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i]; - printf("CDC Header Descriptor:\n"); - printf("\tbcdCDC: %d.%d0\n", ((desc->bcdCDC >> 8) & 0xF), ((desc->bcdCDC >> 4) & 0xF)); - break; - } - case CDC_DESC_SUBTYPE_CALL: { - cdc_acm_call_desc_t *desc = (cdc_acm_call_desc_t *)cdc_dev->cdc_intf_desc[i]; - printf("CDC Call Descriptor:\n"); - printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val); - printf("\tbDataInterface: %d\n", desc->bDataInterface); - break; - } - case CDC_DESC_SUBTYPE_ACM: { - cdc_acm_acm_desc_t *desc = (cdc_acm_acm_desc_t *)cdc_dev->cdc_intf_desc[i]; - printf("CDC ACM Descriptor:\n"); - printf("\tbmCapabilities: 0x%02X\n", desc->bmCapabilities.val); - break; - } - case CDC_DESC_SUBTYPE_UNION: { - cdc_union_desc_t *desc = (cdc_union_desc_t *)cdc_dev->cdc_intf_desc[i]; - printf("CDC Union Descriptor:\n"); - printf("\tbControlInterface: %d\n", desc->bControlInterface); - printf("\tbSubordinateInterface[0]: %d\n", desc->bSubordinateInterface[0]); - break; - } - default: - ESP_LOGW(TAG, "Unsupported CDC specific descriptor"); - break; - } - } + const usb_device_desc_t *device_desc; + const usb_config_desc_t *config_desc; + ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_device_descriptor(cdc_dev->dev_hdl, &device_desc)); + ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_active_config_descriptor(cdc_dev->dev_hdl, &config_desc)); + usb_print_device_descriptor(device_desc); + usb_print_config_descriptor(config_desc, cdc_acm_print_desc); } /** diff --git a/examples/peripherals/usb/host/cdc/common/cdc_acm_host/include/usb/cdc_acm_host.h b/examples/peripherals/usb/host/cdc/common/cdc_acm_host/include/usb/cdc_acm_host.h index 2709a8b38b..3724c919c6 100644 --- a/examples/peripherals/usb/host/cdc/common/cdc_acm_host/include/usb/cdc_acm_host.h +++ b/examples/peripherals/usb/host/cdc/common/cdc_acm_host/include/usb/cdc_acm_host.h @@ -220,10 +220,9 @@ esp_err_t cdc_acm_host_set_control_line_state(cdc_acm_dev_hdl_t cdc_hdl, bool dt esp_err_t cdc_acm_host_send_break(cdc_acm_dev_hdl_t cdc_hdl, uint16_t duration_ms); /** - * @brief Print CDC-ACM specific descriptors + * @brief Print device's descriptors * - * Descriptors are printed in human readable format to stdout. - * Intended for debugging and for CDC-ACM compliant devices only. + * Device and full Configuration descriptors are printed in human readable format to stdout. * * @param cdc_hdl CDC handle obtained from cdc_acm_host_open() */