Skip to content

Commit

Permalink
ref(esp_tinyusb): 2/2 Prerequisite for HS/FS Hosts
Browse files Browse the repository at this point in the history
Made global descriptor pointers struct allocatable

Merged parse configuration and set decriptors function in one
  • Loading branch information
roma-jam committed Feb 6, 2024
1 parent c448264 commit df864be
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 61 deletions.
96 changes: 49 additions & 47 deletions device/esp_tinyusb/descriptors_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
#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 const tusb_desc_device_t *s_device_descriptor;
static const uint8_t *s_configuration_descriptor;
static const char *s_str_descriptor[USB_STRING_DESCRIPTOR_ARRAY_SIZE]; // Array of pointers (strings). Statically allocated, can be made dynamic in the future.
static tinyusb_descriptor_config_t *s_desc_cfg;

// =============================================================================
// CALLBACKS
Expand All @@ -31,7 +29,8 @@ static const char *s_str_descriptor[USB_STRING_DESCRIPTOR_ARRAY_SIZE]; // Array
*/
uint8_t const *tud_descriptor_device_cb(void)
{
return (uint8_t const *)s_device_descriptor;
assert(s_desc_cfg);
return (uint8_t const *)s_desc_cfg->dev;
}

/**
Expand All @@ -44,7 +43,8 @@ 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
return s_configuration_descriptor;
assert(s_desc_cfg);
return s_desc_cfg->cfg;
}

/**
Expand All @@ -57,24 +57,25 @@ uint8_t const *tud_descriptor_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);
uint8_t chr_count;
static uint16_t _desc_str[MAX_DESC_BUF_SIZE];

if (index == 0) {
memcpy(&_desc_str[1], s_str_descriptor[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_str_descriptor[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_str_descriptor[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 @@ -92,33 +93,37 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid)
// =============================================================================
// Driver functions
// =============================================================================
esp_err_t tinyusb_prepare_descriptors_config(const tinyusb_config_t *config, tinyusb_descriptor_config_t *desc_cfg)
esp_err_t tinyusb_set_descriptors(const tinyusb_config_t *config)
{
assert(config);
assert(desc_cfg);
// Create descriptor struct
s_desc_cfg = calloc(1, sizeof(tinyusb_descriptor_config_t));
assert(s_desc_cfg);
s_desc_cfg->str = calloc(1, USB_STRING_DESCRIPTOR_ARRAY_SIZE);
assert(s_desc_cfg->str);
// 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.");
}
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)
// High Speed
if (NULL == config->hs_cfg_desc) {
// Default configuration descriptor is provided only for CDC, MSC and NCM classes
#if (CFG_TUD_HID > 0 || CFG_TUD_MIDI > 0 || CFG_TUD_CUSTOM_CLASS > 0 || CFG_TUD_ECM_RNDIS > 0 || CFG_TUD_DFU > 0 || CFG_TUD_DFU_RUNTIME > 0 || CFG_TUD_BTH > 0)
ESP_RETURN_ON_FALSE(config->configuration_descriptor, ESP_ERR_INVALID_ARG, TAG, "Configuration descriptor must be provided for this device");
ESP_RETURN_ON_FALSE(config->hs_cfg_desc, ESP_ERR_INVALID_ARG, TAG, "Configuration descriptor must be provided for this device");
#else
ESP_LOGW(TAG, "The device's configuration descriptor is not provided by user, using default.");
#endif
}
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
// TODO:
Expand All @@ -131,33 +136,24 @@ esp_err_t tinyusb_prepare_descriptors_config(const tinyusb_config_t *config, tin
ESP_LOGW(TAG, "The device's configuration descriptor is not provided by user, using default.");
#endif
}
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) {
desc_cfg->str = config->string_descriptor;
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 = 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!
} else {
desc_cfg->str = descriptor_str_kconfig;
while (descriptor_str_kconfig[++desc_cfg->str_count] != NULL);
s_desc_cfg->str = descriptor_str_kconfig;
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.");
}

return ESP_OK;
}

void tinyusb_set_descriptors(const tinyusb_descriptor_config_t *desc_cfg)
{
assert(desc_cfg);
assert(desc_cfg->dev);
assert(desc_cfg->cfg);
assert(desc_cfg->str);
assert(desc_cfg->str_count <= USB_STRING_DESCRIPTOR_ARRAY_SIZE);
assert(s_desc_cfg->str_count <= USB_STRING_DESCRIPTOR_ARRAY_SIZE);

ESP_LOGI(TAG, "\n"
"┌─────────────────────────────────┐\n"
Expand Down Expand Up @@ -185,20 +181,26 @@ void tinyusb_set_descriptors(const tinyusb_descriptor_config_t *desc_cfg)
"├───────────────────┼─────────────┤\n"
"│bNumConfigurations │ %-#10x │\n"
"└───────────────────┴─────────────┘",
desc_cfg->dev->bDeviceClass, desc_cfg->dev->bDeviceSubClass,
desc_cfg->dev->bDeviceProtocol, desc_cfg->dev->bMaxPacketSize0,
desc_cfg->dev->idVendor, desc_cfg->dev->idProduct, desc_cfg->dev->bcdDevice,
desc_cfg->dev->iManufacturer, desc_cfg->dev->iProduct, desc_cfg->dev->iSerialNumber,
desc_cfg->dev->bNumConfigurations);

// Save passed descriptors pointers(!)
s_device_descriptor = desc_cfg->dev;
s_configuration_descriptor = desc_cfg->cfg;
memcpy(s_str_descriptor, desc_cfg->str, desc_cfg->str_count * sizeof(desc_cfg->str[0]));
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;
}

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

void tinyusb_free_desctiptors(void)
{
assert(s_desc_cfg);
assert(s_desc_cfg->str);
free(s_desc_cfg->str);
free(s_desc_cfg);
}
21 changes: 10 additions & 11 deletions device/esp_tinyusb/include_private/descriptors_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,11 @@ typedef struct {
* @attention All descriptors passed to this function must exist for the duration of USB device lifetime
*
* @param[in] config tinyusb stack specific configuration
* @param[out] desc_cfg Descriptor configuration for tinyusb
* @retval ESP_ERR_INVALID_ARG
* @retval ESP_FAIL
* @retval ESP_OK Descriptor configured without error
*/
esp_err_t tinyusb_prepare_descriptors_config(const tinyusb_config_t *config, tinyusb_descriptor_config_t *desc_cfg);

/**
* @brief Set descriptors for this driver
*
* @attention All descriptors passed to this function must exist for the duration of USB device lifetime
*
* @param[in] desc_cfg Descriptor configuration for tinyusb
*/
void tinyusb_set_descriptors(const tinyusb_descriptor_config_t *desc_cfg);
esp_err_t tinyusb_set_descriptors(const tinyusb_config_t *config);

/**
* @brief Set specific string descriptor
Expand All @@ -53,6 +46,12 @@ void tinyusb_set_descriptors(const tinyusb_descriptor_config_t *desc_cfg);
*/
void tinyusb_set_str_descriptor(const char *str, int str_idx);

/**
* @brief Free memory allocated during tinyusb_set_descriptors
*
*/
void tinyusb_free_desctiptors(void);

#ifdef __cplusplus
}
#endif
4 changes: 1 addition & 3 deletions device/esp_tinyusb/tinyusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
ESP_RETURN_ON_ERROR(usb_new_phy(&phy_conf, &phy_hdl), TAG, "Install USB PHY failed");

// Descriptors config
tinyusb_descriptor_config_t tinyusb_desc_cfg = { 0 };
ESP_RETURN_ON_ERROR(tinyusb_prepare_descriptors_config(config, &tinyusb_desc_cfg), TAG, "Prepare descriptors configuration failed");
tinyusb_set_descriptors(&tinyusb_desc_cfg);
ESP_RETURN_ON_ERROR(tinyusb_set_descriptors(config), TAG, "Descriptors config failed");

// Init
#if !CONFIG_TINYUSB_INIT_IN_DEFAULT_TASK
Expand Down

0 comments on commit df864be

Please sign in to comment.