usb_host: Use USB_Host library calls for desc printing

This commit is contained in:
Tomas Rezucha 2022-02-11 20:26:35 +01:00
parent 3074981dcb
commit e3ba980d11
5 changed files with 91 additions and 53 deletions

View File

@ -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); 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) void usb_print_device_descriptor(const usb_device_desc_t *devc_desc)
{ {
if (devc_desc == NULL) { if (devc_desc == NULL) {
@ -265,15 +278,18 @@ void usb_print_config_descriptor(const usb_config_desc_t *cfg_desc, print_class_
do { do {
switch (next_desc->bDescriptorType) { 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); usbh_print_cfg_desc((const usb_config_desc_t *)next_desc);
break; break;
case USB_W_VALUE_DT_INTERFACE: case USB_B_DESCRIPTOR_TYPE_INTERFACE:
usbh_print_intf_desc((const usb_intf_desc_t *)next_desc); usbh_print_intf_desc((const usb_intf_desc_t *)next_desc);
break; break;
case USB_W_VALUE_DT_ENDPOINT: case USB_B_DESCRIPTOR_TYPE_ENDPOINT:
print_ep_desc((const usb_ep_desc_t *)next_desc); print_ep_desc((const usb_ep_desc_t *)next_desc);
break; break;
case USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION:
print_iad_desc((const usb_iad_desc_t*)next_desc);
break;
default: default:
if(class_specific_cb) { if(class_specific_cb) {
class_specific_cb(next_desc); class_specific_cb(next_desc);

View File

@ -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. 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 ## Example Output
After the flashing you should see the output at idf monitor: After the flashing you should see the output at idf monitor:
``` ```
...
I (256) USB-CDC: USB Host installed I (256) USB-CDC: USB Host installed
I (256) USB-CDC: Opening CDC ACM device 0x303A:0x4001 I (256) USB-CDC: Opening CDC ACM device 0x303A:0x4001
CDC Header Descriptor: ...
bcdCDC: 1.20 Device descriptor is printed here
CDC Call Descriptor: ...
bmCapabilities: 0x00
bDataInterface: 1
CDC ACM Descriptor:
bmCapabilities: 0x02
CDC Union Descriptor:
bControlInterface: 0
bSubordinateInterface[0]: 1
I (1666) USB-CDC: Data received I (1666) USB-CDC: Data received
I (1666) USB-CDC: 0x3ffc4c20 41 54 0d |AT.| I (1666) USB-CDC: 0x3ffc4c20 41 54 0d |AT.|
I (2666) USB-CDC: Data received I (2666) USB-CDC: Data received

View File

@ -16,7 +16,7 @@
#define EXAMPLE_USB_HOST_PRIORITY 20 #define EXAMPLE_USB_HOST_PRIORITY 20
#define EXAMPLE_USB_DEVICE_VID 0x303A // 0x303A:0x4001 (TinyUSB CDC device) #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"; static const char *TAG = "USB-CDC";

View File

@ -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; const usb_standard_desc_t *cdc_desc = (usb_standard_desc_t *)cdc_dev->notif.intf_desc;
do { do {
cdc_desc = usb_parse_next_descriptor(cdc_desc, config_desc->wTotalLength, &desc_offset); 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 break; // We found all CDC specific descriptors
cdc_dev->num_cdc_intf_desc++; cdc_dev->num_cdc_intf_desc++;
cdc_dev->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; 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) void cdc_acm_host_desc_print(cdc_acm_dev_hdl_t cdc_hdl)
{ {
assert(cdc_hdl); assert(cdc_hdl);
cdc_dev_t *cdc_dev = (cdc_dev_t *)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"); const usb_device_desc_t *device_desc;
const usb_config_desc_t *config_desc;
for (int i = 0; i < cdc_dev->num_cdc_intf_desc; i++) { ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_device_descriptor(cdc_dev->dev_hdl, &device_desc));
switch (((cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i])->bDescriptorSubtype) { ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_active_config_descriptor(cdc_dev->dev_hdl, &config_desc));
case CDC_DESC_SUBTYPE_HEADER: { usb_print_device_descriptor(device_desc);
cdc_header_desc_t *desc = (cdc_header_desc_t *)cdc_dev->cdc_intf_desc[i]; usb_print_config_descriptor(config_desc, cdc_acm_print_desc);
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;
}
}
} }
/** /**

View File

@ -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); 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. * Device and full Configuration descriptors are printed in human readable format to stdout.
* Intended for debugging and for CDC-ACM compliant devices only.
* *
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open() * @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
*/ */