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);
}
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);

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.
### 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

View File

@ -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";

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;
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);
}
/**

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);
/**
* @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()
*/