Skip to content

Commit

Permalink
refactor(esp_tinyusb): Made s_desc_cfg and default qulifier descripto…
Browse files Browse the repository at this point in the history
…r static
  • Loading branch information
roma-jam committed Mar 1, 2024
1 parent d5f1bcb commit 024da71
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 141 deletions.
30 changes: 15 additions & 15 deletions device/esp_tinyusb/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
## 1.4.4 (Unreleased)
## 1.4.4

- esp_tinyusb: Configuration descriptor for HS/FS Hosts
- CDC-ACM: Remove MIN() definition if already defined
- MSC: Set EP size in configuration descriptor based on speed
- esp_tinyusb: Added possibility to set FS configuration descriptor for HS devices
- CDC-ACM: Removed MIN() definition if already defined
- MSC: Fixed EP size selecting in default configuration descriptor


## 1.4.3

- esp_tinyusb: ESP32P4 HS only support
- esp_tinyusb: Added ESP32P4 support (HS only)

## 1.4.2

- MSC: Fix maximum files open
- Add uninstall function
- MSC: Fixed maximum files open
- Added uninstall function

## 1.4.0

- MSC: Fix integer overflows
- CDC-ACM: Remove intermediate RX ringbuffer
- CDC-ACM: Increase default FIFO size to 512 bytes
- CDC-ACM: Fix Virtual File System binding
- MSC: Fixed integer overflows
- CDC-ACM: Removed intermediate RX ringbuffer
- CDC-ACM: Increased default FIFO size to 512 bytes
- CDC-ACM: Fixed Virtual File System binding

## 1.3.0

- Add NCM extension
- Added NCM extension

## 1.2.1 - 1.2.2

- Minor bugfixes

## 1.2.0

- Add MSC extension for accessing SPI Flash on memory card https://github.com/espressif/idf-extra-components/commit/a8c00d7707ba4ceeb0970c023d702c7768dba3dc
- Added MSC extension for accessing SPI Flash on memory card https://github.com/espressif/idf-extra-components/commit/a8c00d7707ba4ceeb0970c023d702c7768dba3dc

## 1.1.0

- Add support for NCM, ECM/RNDIS, DFU and Bluetooth TinyUSB drivers https://github.com/espressif/idf-extra-components/commit/79f35c9b047b583080f93a63310e2ee7d82ef17b
- Added support for NCM, ECM/RNDIS, DFU and Bluetooth TinyUSB drivers https://github.com/espressif/idf-extra-components/commit/79f35c9b047b583080f93a63310e2ee7d82ef17b

## 1.0.4

- Clean up string descriptors handling https://github.com/espressif/idf-extra-components/commit/046cc4b02f524d5c7e3e56480a473cfe844dc3d6
- Cleaned up string descriptors handling https://github.com/espressif/idf-extra-components/commit/046cc4b02f524d5c7e3e56480a473cfe844dc3d6

## 1.0.2 - 1.0.3

Expand Down
171 changes: 85 additions & 86 deletions device/esp_tinyusb/descriptors_control.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -14,7 +14,31 @@
#define MAX_DESC_BUF_SIZE 32 // Max length of string descriptor (can be extended, USB supports lengths up to 255 bytes)

static const char *TAG = "tusb_desc";
static tinyusb_descriptor_config_t *s_desc_cfg;

// =============================================================================
// STRUCTS
// =============================================================================

/**
* @brief Descriptor pointers for tinyusb descriptor requests callbacks
*
*/
typedef struct {
const tusb_desc_device_t *dev; /*!< Pointer to device descriptor */
union {
const uint8_t *cfg; /*!< Pointer to FS configuration descriptor when device one-speed only */
const uint8_t *hs_cfg; /*!< Pointer to HS configuration descriptor when device one-speed only */
};
#if (TUD_OPT_HIGH_SPEED)
const uint8_t *fs_cfg; /*!< Pointer to FS configuration descriptor when device support HS */
const tusb_desc_device_qualifier_t *qualifier; /*!< Pointer to Qualifier descriptor */
uint8_t *other_speed; /*!< Pointer for other speed configuration descriptor */
#endif // TUD_OPT_HIGH_SPEED
const char *str[USB_STRING_DESCRIPTOR_ARRAY_SIZE]; /*!< Pointer to array of UTF-8 strings */
int str_count; /*!< Number of descriptors in str */
} tinyusb_descriptor_config_t;

static tinyusb_descriptor_config_t s_desc_cfg;

// =============================================================================
// CALLBACKS
Expand All @@ -28,9 +52,8 @@ static tinyusb_descriptor_config_t *s_desc_cfg;
*/
uint8_t const *tud_descriptor_device_cb(void)
{
assert(s_desc_cfg);
assert(s_desc_cfg->dev);
return (uint8_t const *)s_desc_cfg->dev;
assert(s_desc_cfg.dev);
return (uint8_t const *)s_desc_cfg.dev;
}

/**
Expand All @@ -43,18 +66,17 @@ uint8_t const *tud_descriptor_device_cb(void)
uint8_t const *tud_descriptor_configuration_cb(uint8_t index)
{
(void)index; // Unused, this driver supports only 1 configuration
assert(s_desc_cfg);
assert(s_desc_cfg->cfg);
assert(s_desc_cfg.cfg);

#if (TUD_OPT_HIGH_SPEED)
// HINT: cfg and hs_cfg are the same, no need to assert(hs_cfg)
assert(s_desc_cfg->fs_cfg);
assert(s_desc_cfg.fs_cfg);
// Return configuration descriptor based on Host speed
return (TUSB_SPEED_HIGH == tud_speed_get())
? s_desc_cfg->hs_cfg
: s_desc_cfg->fs_cfg;
? s_desc_cfg.hs_cfg
: s_desc_cfg.fs_cfg;
#else
return s_desc_cfg->cfg;
return s_desc_cfg.cfg;
#endif // TUD_OPT_HIGH_SPEED
}

Expand All @@ -66,32 +88,29 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index)
*/
uint8_t const *tud_descriptor_device_qualifier_cb(void)
{
assert(s_desc_cfg);
assert(s_desc_cfg->qualifier);
return (uint8_t const *)s_desc_cfg->qualifier;
assert(s_desc_cfg.qualifier);
return (uint8_t const *)s_desc_cfg.qualifier;
}


/**
* @brief Invoked when received GET OTHER SPEED CONFIGURATION DESCRIPTOR request
* Descriptor contents must exist long enough for transfer to complete
* Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
*/
uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index)
{
assert(s_desc_cfg);
assert(s_desc_cfg->other_speed);
assert(s_desc_cfg.other_speed);

const uint8_t *other_speed = (TUSB_SPEED_HIGH == tud_speed_get())
? s_desc_cfg->fs_cfg
: s_desc_cfg->hs_cfg;
? s_desc_cfg.fs_cfg
: s_desc_cfg.hs_cfg;

memcpy(s_desc_cfg->other_speed,
memcpy(s_desc_cfg.other_speed,
other_speed,
((tusb_desc_configuration_t *)other_speed)->wTotalLength);

((tusb_desc_configuration_t *)s_desc_cfg->other_speed)->bDescriptorType = TUSB_DESC_OTHER_SPEED_CONFIG;
return s_desc_cfg->other_speed;
((tusb_desc_configuration_t *)s_desc_cfg.other_speed)->bDescriptorType = TUSB_DESC_OTHER_SPEED_CONFIG;
return s_desc_cfg.other_speed;
}
#endif // TUD_OPT_HIGH_SPEED

Expand All @@ -105,26 +124,25 @@ uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index)
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{
(void) langid; // Unused, this driver supports only one language in string descriptors
assert(s_desc_cfg);
assert(s_desc_cfg->str);
assert(s_desc_cfg.str);
uint8_t chr_count;
static uint16_t _desc_str[MAX_DESC_BUF_SIZE];

if (index == 0) {
memcpy(&_desc_str[1], s_desc_cfg->str[0], 2);
memcpy(&_desc_str[1], s_desc_cfg.str[0], 2);
chr_count = 1;
} else {
if (index >= USB_STRING_DESCRIPTOR_ARRAY_SIZE) {
ESP_LOGW(TAG, "String index (%u) is out of bounds, check your string descriptor", index);
return NULL;
}

if (s_desc_cfg->str[index] == NULL) {
if (s_desc_cfg.str[index] == NULL) {
ESP_LOGW(TAG, "String index (%u) points to NULL, check your string descriptor", index);
return NULL;
}

const char *str = s_desc_cfg->str[index];
const char *str = s_desc_cfg.str[index];
chr_count = strnlen(str, MAX_DESC_BUF_SIZE - 1); // Buffer len - header

// Convert ASCII string into UTF-16
Expand All @@ -147,17 +165,14 @@ esp_err_t tinyusb_set_descriptors(const tinyusb_config_t *config)
esp_err_t ret = ESP_FAIL;
assert(config);
const char **pstr_desc;
// Create descriptor struct
s_desc_cfg = calloc(1, sizeof(tinyusb_descriptor_config_t));
assert(s_desc_cfg);
// Parse configuration and save descriptors's pointer
// Select Device Descriptor
if (NULL == config->device_descriptor) {
ESP_LOGW(TAG, "The device's device descriptor is not provided by user, using default.");
}
s_desc_cfg->dev = config->device_descriptor
? config->device_descriptor
: &descriptor_dev_kconfig;
s_desc_cfg.dev = config->device_descriptor
? config->device_descriptor
: &descriptor_dev_kconfig;

// Select Configuration Descriptor
#if (TUD_OPT_HIGH_SPEED)
Expand All @@ -170,9 +185,9 @@ esp_err_t tinyusb_set_descriptors(const tinyusb_config_t *config)
ESP_LOGW(TAG, "The device's HS configuration descriptor is not provided by user, using default.");
#endif
}
s_desc_cfg->cfg = config->hs_cfg_desc
? config->hs_cfg_desc
: descriptor_cfg_kconfig;
s_desc_cfg.cfg = config->hs_cfg_desc
? config->hs_cfg_desc
: descriptor_cfg_kconfig;

// Full Speed
if (NULL == config->fs_cfg_desc) {
Expand All @@ -183,40 +198,28 @@ esp_err_t tinyusb_set_descriptors(const tinyusb_config_t *config)
ESP_LOGW(TAG, "The device's FS configuration descriptor is not provided by user, using default.");
#endif
}
s_desc_cfg->fs_cfg = config->fs_cfg_desc
? config->fs_cfg_desc
: descriptor_fs_cfg_kconfig;
s_desc_cfg.fs_cfg = config->fs_cfg_desc
? config->fs_cfg_desc
: descriptor_fs_cfg_kconfig;

// HS and FS cfg desc should be equal length
ESP_GOTO_ON_FALSE(((tusb_desc_configuration_t *)s_desc_cfg->hs_cfg)->wTotalLength ==
((tusb_desc_configuration_t *)s_desc_cfg->fs_cfg)->wTotalLength,
ESP_GOTO_ON_FALSE(((tusb_desc_configuration_t *)s_desc_cfg.hs_cfg)->wTotalLength ==
((tusb_desc_configuration_t *)s_desc_cfg.fs_cfg)->wTotalLength,
ESP_ERR_INVALID_ARG, fail, TAG, "HS and FS Configuration descriptors must be same length");

// Qualifier Descriptor
if (NULL == config->qualifier_desc) {
ESP_LOGW(TAG, "Qualifier descriptor must be provided for HighSpeed device. Create one with current Device Descriptor.");
s_desc_cfg->qualifier = calloc(1, sizeof (tusb_desc_device_qualifier_t));

// Fill up with values from Device descriptor
s_desc_cfg->qualifier->bLength = s_desc_cfg->dev->bLength;
s_desc_cfg->qualifier->bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER;
s_desc_cfg->qualifier->bcdUSB = s_desc_cfg->dev->bcdUSB;
s_desc_cfg->qualifier->bDeviceClass = s_desc_cfg->dev->bDeviceClass;
s_desc_cfg->qualifier->bDeviceSubClass = s_desc_cfg->dev->bDeviceSubClass;
s_desc_cfg->qualifier->bDeviceProtocol = s_desc_cfg->dev->bDeviceProtocol;
s_desc_cfg->qualifier->bMaxPacketSize0 = s_desc_cfg->dev->bMaxPacketSize0;
s_desc_cfg->qualifier->bNumConfigurations = s_desc_cfg->dev->bNumConfigurations;
s_desc_cfg->qualifier->bReserved = 0;

s_desc_cfg->qualifier_alloc_internally = true;
if (NULL == config->qualifier_descriptor) {
ESP_GOTO_ON_FALSE((s_desc_cfg.dev == &descriptor_dev_kconfig), ESP_ERR_INVALID_ARG, fail, TAG, "Qualifier Descriptor must be present (Device Descriptor not default).");
// Get default qualifier if device descriptor is default
ESP_LOGW(TAG, "The device's qulifier descriptor is not provided by user, using default.");
s_desc_cfg.qualifier = &descriptor_qualifier_kconfig;
} else {
s_desc_cfg->qualifier = config->qualifier_desc;
s_desc_cfg->qualifier_alloc_internally = false;
s_desc_cfg.qualifier = config->qualifier_descriptor;
}

// Other Speed buffer allocate
s_desc_cfg->other_speed = calloc(1, ((tusb_desc_configuration_t *)s_desc_cfg->hs_cfg)->wTotalLength);
ESP_GOTO_ON_FALSE(s_desc_cfg->other_speed, ESP_ERR_NO_MEM, fail, TAG, "Other speed memory allocation error");
s_desc_cfg.other_speed = calloc(1, ((tusb_desc_configuration_t *)s_desc_cfg.hs_cfg)->wTotalLength);
ESP_GOTO_ON_FALSE(s_desc_cfg.other_speed, ESP_ERR_NO_MEM, fail, TAG, "Other speed memory allocation error");
#else
if (NULL == config->configuration_descriptor) {
// Default configuration descriptor is provided only for CDC, MSC and NCM classes
Expand All @@ -226,25 +229,25 @@ esp_err_t tinyusb_set_descriptors(const tinyusb_config_t *config)
ESP_LOGW(TAG, "The device's configuration descriptor is not provided by user, using default.");
#endif
}
s_desc_cfg->cfg = config->configuration_descriptor
? config->configuration_descriptor
: descriptor_cfg_kconfig;
s_desc_cfg.cfg = config->configuration_descriptor
? config->configuration_descriptor
: descriptor_cfg_kconfig;
#endif // TUD_OPT_HIGH_SPEED

// Select String Descriptors and count them
if (config->string_descriptor) {
pstr_desc = config->string_descriptor;
s_desc_cfg->str_count = (config->string_descriptor_count != 0)
? config->string_descriptor_count
: 8; // '8' is for backward compatibility with esp_tinyusb v1.0.0. Do NOT remove!
s_desc_cfg.str_count = (config->string_descriptor_count != 0)
? config->string_descriptor_count
: 8; // '8' is for backward compatibility with esp_tinyusb v1.0.0. Do NOT remove!
} else {
pstr_desc = descriptor_str_kconfig;
while (descriptor_str_kconfig[++s_desc_cfg->str_count] != NULL);
while (descriptor_str_kconfig[++s_desc_cfg.str_count] != NULL);
ESP_LOGW(TAG, "The device's string descriptor is not provided by user, using default.");
}

ESP_GOTO_ON_FALSE(s_desc_cfg->str_count <= USB_STRING_DESCRIPTOR_ARRAY_SIZE, ESP_ERR_NOT_SUPPORTED, fail, TAG, "String descriptors exceed limit");
memcpy(s_desc_cfg->str, pstr_desc, s_desc_cfg->str_count * sizeof(pstr_desc[0]));
ESP_GOTO_ON_FALSE(s_desc_cfg.str_count <= USB_STRING_DESCRIPTOR_ARRAY_SIZE, ESP_ERR_NOT_SUPPORTED, fail, TAG, "String descriptors exceed limit");
memcpy(s_desc_cfg.str, pstr_desc, s_desc_cfg.str_count * sizeof(pstr_desc[0]));

ESP_LOGI(TAG, "\n"
"┌─────────────────────────────────┐\n"
Expand Down Expand Up @@ -272,35 +275,31 @@ esp_err_t tinyusb_set_descriptors(const tinyusb_config_t *config)
"├───────────────────┼─────────────┤\n"
"│bNumConfigurations │ %-#10x │\n"
"└───────────────────┴─────────────┘",
s_desc_cfg->dev->bDeviceClass, s_desc_cfg->dev->bDeviceSubClass,
s_desc_cfg->dev->bDeviceProtocol, s_desc_cfg->dev->bMaxPacketSize0,
s_desc_cfg->dev->idVendor, s_desc_cfg->dev->idProduct, s_desc_cfg->dev->bcdDevice,
s_desc_cfg->dev->iManufacturer, s_desc_cfg->dev->iProduct, s_desc_cfg->dev->iSerialNumber,
s_desc_cfg->dev->bNumConfigurations);
s_desc_cfg.dev->bDeviceClass, s_desc_cfg.dev->bDeviceSubClass,
s_desc_cfg.dev->bDeviceProtocol, s_desc_cfg.dev->bMaxPacketSize0,
s_desc_cfg.dev->idVendor, s_desc_cfg.dev->idProduct, s_desc_cfg.dev->bcdDevice,
s_desc_cfg.dev->iManufacturer, s_desc_cfg.dev->iProduct, s_desc_cfg.dev->iSerialNumber,
s_desc_cfg.dev->bNumConfigurations);

return ESP_OK;

fail:
free(s_desc_cfg);
#if (TUD_OPT_HIGH_SPEED)
free(s_desc_cfg.other_speed);
#endif // TUD_OPT_HIGH_SPEED
return ret;
}

void tinyusb_set_str_descriptor(const char *str, int str_idx)
{
assert(s_desc_cfg);
assert(str_idx < USB_STRING_DESCRIPTOR_ARRAY_SIZE);
s_desc_cfg->str[str_idx] = str;
s_desc_cfg.str[str_idx] = str;
}

void tinyusb_free_desctiptors(void)
void tinyusb_free_descriptors(void)
{
assert(s_desc_cfg);
#if (TUD_OPT_HIGH_SPEED)
assert(s_desc_cfg->other_speed);
free(s_desc_cfg->other_speed);
if (s_desc_cfg->qualifier_alloc_internally) {
free(s_desc_cfg->qualifier);
}
assert(s_desc_cfg.other_speed);
free(s_desc_cfg.other_speed);
#endif // TUD_OPT_HIGH_SPEED
free(s_desc_cfg);
}
Loading

0 comments on commit 024da71

Please sign in to comment.