Merge branch 'refactor/usb_device_examples_prereq_for_hs' into 'master'

USB Device examples: Added HS and FS configuration

Closes IDF-9048

See merge request espressif/esp-idf!29580
This commit is contained in:
Roman Leonov 2024-03-29 03:26:50 +08:00
commit ca201b83ec
7 changed files with 123 additions and 20 deletions

View File

@ -84,19 +84,42 @@ Multiple aspects of the Device Stack can be configured using menuconfig. These i
Descriptor Configuration
^^^^^^^^^^^^^^^^^^^^^^^^
The :cpp:type:`tinyusb_config_t` structure provides the following USB descriptor related fields that should be initialized:
The :cpp:type:`tinyusb_config_t` structure provides USB descriptor related fields that should be initialized.
The following descriptors should be initialized for both full-speed and high-speed devices:
- :cpp:member:`device_descriptor`
- :cpp:member:`configuration_descriptor`
- :cpp:member:`string_descriptor`
Full-speed devices should initialize the following field to provide their configuration descriptor:
- :cpp:member:`configuration_descriptor`
High-speed devices should initialize the following fields to provide configuration descriptors at each speed:
- :cpp:member:`fs_configuration_descriptor`
- :cpp:member:`hs_configuration_descriptor`
- :cpp:member:`qualifier_descriptor`
.. note::
When Device Stack supports high-speed, both :cpp:member:`fs_configuration_descriptor` and :cpp:member:`hs_configuration_descriptor` should be present to comply with usb2.0 specification.
The Device Stack will instantiate a USB device based on the descriptors provided in the fields described above when :cpp:func:`tinyusb_driver_install` is called.
The Device Stack also provides default descriptors that can be installed by setting the corresponding field in :cpp:func:`tinyusb_driver_install` to ``NULL``. Default descriptors include:
- Default device descriptor: Enabled by setting :cpp:member:`device_descriptor` to ``NULL``. Default device descriptor will use the values set by the corresponding menuconfig options (e.g., PID, VID, bcdDevice etc).
- Default string descriptor: Enabled by setting :cpp:member:`string_descriptor` to ``NULL``. Default string descriptors will use the value set by corresponding menuconfig options (e.g., manufacturer, product, and serial string descriptor options).
- Default configuration descriptor. Some classes that rarely require custom configuration (such as CDC and MSC) will provide default configuration descriptors. These can be enabled by setting :cpp:member:`configuration_descriptor` to ``NULL``.
- Default configuration descriptor. Some classes that rarely require custom configuration (such as CDC and MSC) will provide default configuration descriptors. These can be enabled by setting associated configuration descriptor field to ``NULL``:
- :cpp:member:`configuration_descriptor` full-speed descriptor for full-speed devices only
- :cpp:member:`fs_configuration_descriptor` full-speed descriptor for high-speed devices
- :cpp:member:`hs_configuration_descriptor` high-speed descriptor for high-speed devices
.. note::
Backward compatibility: when Device Stack supports high-speed, field :cpp:member:`configuration_descriptor` could be used instead of :cpp:member:`fs_configuration_descriptor` for full-speed configuration descriptor.
Installation
------------
@ -113,7 +136,14 @@ To install the Device Stack, please call :cpp:func:`tinyusb_driver_install`. The
.device_descriptor = NULL, // Use the default device descriptor specified in Menuconfig
.string_descriptor = NULL, // Use the default string descriptors specified in Menuconfig
.external_phy = false, // Use internal USB PHY
.configuration_descriptor = NULL, // Use the default configuration descriptor according to settings in Menuconfig
#if (TUD_OPT_HIGH_SPEED)
.fs_configuration_descriptor = NULL, // Use the default full-speed configuration descriptor according to settings in Menuconfig
.hs_configuration_descriptor = NULL, // Use the default high-ppeed configuration descriptor according to settings in Menuconfig
.qualifier_descriptor = NULL, // Use the default qualifier descriptor, with values from default device descriptor
#else
.configuration_descriptor = NULL, // Use the default configuration descriptor according to settings in Menuconfig
#endif // TUD_OPT_HIGH_SPEED
};
.. _self-powered-device:

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -125,7 +125,13 @@ void app_main(void)
.string_descriptor = NULL,
.string_descriptor_count = 0,
.external_phy = false,
#if (TUD_OPT_HIGH_SPEED)
.fs_configuration_descriptor = NULL,
.hs_configuration_descriptor = NULL,
.qualifier_descriptor = NULL,
#else
.configuration_descriptor = NULL,
#endif // TUD_OPT_HIGH_SPEED
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -31,7 +31,13 @@ void app_main(void)
.device_descriptor = NULL,
.string_descriptor = NULL,
.external_phy = false, // In the most cases you need to use a `false` value
#if (TUD_OPT_HIGH_SPEED)
.fs_configuration_descriptor = NULL,
.hs_configuration_descriptor = NULL,
.qualifier_descriptor = NULL,
#else
.configuration_descriptor = NULL,
#endif // TUD_OPT_HIGH_SPEED
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -169,7 +169,13 @@ void app_main(void)
.string_descriptor = hid_string_descriptor,
.string_descriptor_count = sizeof(hid_string_descriptor) / sizeof(hid_string_descriptor[0]),
.external_phy = false,
#if (TUD_OPT_HIGH_SPEED)
.fs_configuration_descriptor = hid_configuration_descriptor, // HID configuration descriptor for full-speed and high-speed are the same
.hs_configuration_descriptor = hid_configuration_descriptor,
.qualifier_descriptor = NULL,
#else
.configuration_descriptor = hid_configuration_descriptor,
#endif // TUD_OPT_HIGH_SPEED
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));

View File

@ -61,9 +61,24 @@ static const uint8_t s_midi_cfg_desc[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_COUNT, 0, TUSB_DESCRIPTOR_TOTAL_LEN, 0, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 4, EPNUM_MIDI, (0x80 | EPNUM_MIDI), TUD_OPT_HIGH_SPEED ? 512 : 64),
TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 4, EPNUM_MIDI, (0x80 | EPNUM_MIDI), 64),
};
#if (TUD_OPT_HIGH_SPEED)
/**
* @brief High Speed configuration descriptor
*
* This is a simple configuration descriptor that defines 1 configuration and a MIDI interface
*/
static const uint8_t s_midi_hs_cfg_desc[] = {
// Configuration number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_COUNT, 0, TUSB_DESCRIPTOR_TOTAL_LEN, 0, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 4, EPNUM_MIDI, (0x80 | EPNUM_MIDI), 512),
};
#endif // TUD_OPT_HIGH_SPEED
static void midi_task_read_example(void *arg)
{
// The MIDI interface always creates input and output port/jack descriptors
@ -139,7 +154,13 @@ void app_main(void)
.string_descriptor = s_str_desc,
.string_descriptor_count = sizeof(s_str_desc) / sizeof(s_str_desc[0]),
.external_phy = false,
#if (TUD_OPT_HIGH_SPEED)
.fs_configuration_descriptor = s_midi_cfg_desc, // HID configuration descriptor for full-speed and high-speed are the same
.hs_configuration_descriptor = s_midi_hs_cfg_desc,
.qualifier_descriptor = NULL,
#else
.configuration_descriptor = s_midi_cfg_desc,
#endif // TUD_OPT_HIGH_SPEED
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
@ -158,7 +179,7 @@ void app_main(void)
ESP_ERROR_CHECK(esp_timer_create(&periodic_midi_args, &periodic_midi_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_midi_timer, tempo * 1000));
// Read recieved MIDI packets
// Read received MIDI packets
ESP_LOGI(TAG, "MIDI read task init");
xTaskCreate(midi_task_read_example, "midi_task_read_example", 2 * 1024, NULL, 5, NULL);
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -44,14 +44,6 @@ enum {
EDPT_MSC_IN = 0x81,
};
static uint8_t const desc_configuration[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64),
};
static tusb_desc_device_t descriptor_config = {
.bLength = sizeof(descriptor_config),
.bDescriptorType = TUSB_DESC_DEVICE,
@ -69,6 +61,36 @@ static tusb_desc_device_t descriptor_config = {
.bNumConfigurations = 0x01
};
static uint8_t const msc_fs_configuration_desc[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, 64),
};
#if (TUD_OPT_HIGH_SPEED)
static const tusb_desc_device_qualifier_t device_qualifier = {
.bLength = sizeof(tusb_desc_device_qualifier_t),
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.bNumConfigurations = 0x01,
.bReserved = 0
};
static uint8_t const msc_hs_configuration_desc[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, 512),
};
#endif // TUD_OPT_HIGH_SPEED
static char const *string_desc_arr[] = {
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"TinyUSB", // 1: Manufacturer
@ -374,7 +396,13 @@ void app_main(void)
.string_descriptor = string_desc_arr,
.string_descriptor_count = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]),
.external_phy = false,
.configuration_descriptor = desc_configuration,
#if (TUD_OPT_HIGH_SPEED)
.fs_configuration_descriptor = msc_fs_configuration_desc,
.hs_configuration_descriptor = msc_hs_configuration_desc,
.qualifier_descriptor = &device_qualifier,
#else
.configuration_descriptor = msc_fs_configuration_desc,
#endif // TUD_OPT_HIGH_SPEED
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
ESP_LOGI(TAG, "USB MSC initialization DONE");

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -48,7 +48,13 @@ void app_main(void)
.device_descriptor = NULL,
.string_descriptor = NULL,
.external_phy = false,
#if (TUD_OPT_HIGH_SPEED)
.fs_configuration_descriptor = NULL,
.hs_configuration_descriptor = NULL,
.qualifier_descriptor = NULL,
#else
.configuration_descriptor = NULL,
#endif // TUD_OPT_HIGH_SPEED
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));