diff --git a/components/usb/test_apps/hcd/sdkconfig.defaults b/components/usb/test_apps/hcd/sdkconfig.defaults index 0632edf7579e..d433503fbfd7 100644 --- a/components/usb/test_apps/hcd/sdkconfig.defaults +++ b/components/usb/test_apps/hcd/sdkconfig.defaults @@ -6,3 +6,4 @@ CONFIG_HEAP_POISONING_COMPREHENSIVE=y # CONFIG_UNITY_ENABLE_FLOAT is not set # CONFIG_UNITY_ENABLE_DOUBLE is not set CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/components/usb/test_apps/usb_host/sdkconfig.defaults b/components/usb/test_apps/usb_host/sdkconfig.defaults index 0632edf7579e..d433503fbfd7 100644 --- a/components/usb/test_apps/usb_host/sdkconfig.defaults +++ b/components/usb/test_apps/usb_host/sdkconfig.defaults @@ -6,3 +6,4 @@ CONFIG_HEAP_POISONING_COMPREHENSIVE=y # CONFIG_UNITY_ENABLE_FLOAT is not set # CONFIG_UNITY_ENABLE_DOUBLE is not set CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/examples/peripherals/usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults b/examples/peripherals/usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults index 990777805d61..a3e635c9d8d5 100644 --- a/examples/peripherals/usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults +++ b/examples/peripherals/usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults @@ -2,3 +2,4 @@ # Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration # CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/examples/peripherals/usb/host/hid/sdkconfig.defaults b/examples/peripherals/usb/host/hid/sdkconfig.defaults new file mode 100644 index 000000000000..bf1b553b2388 --- /dev/null +++ b/examples/peripherals/usb/host/hid/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/examples/peripherals/usb/host/msc/main/msc_example_main.c b/examples/peripherals/usb/host/msc/main/msc_example_main.c index eb934a568103..630c95e6b157 100644 --- a/examples/peripherals/usb/host/msc/main/msc_example_main.c +++ b/examples/peripherals/usb/host/msc/main/msc_example_main.c @@ -29,6 +29,11 @@ static const char *TAG = "example"; #define APP_QUIT_PIN GPIO_NUM_0 // BOOT button on most boards #define BUFFER_SIZE 4096 // The read/write performance can be improved with larger buffer for the cost of RAM, 4kB is enough for most usecases +// IMPORTANT NOTE +// MSC Class Driver is not fully support connecting devices through external Hub. +// TODO: Remove this line after MSC Class Driver will support it +static bool dev_present = false; + /** * @brief Application Queue and its messages ID */ @@ -78,7 +83,7 @@ static void gpio_cb(void *arg) static void msc_event_cb(const msc_host_event_t *event, void *arg) { if (event->event == MSC_DEVICE_CONNECTED) { - ESP_LOGI(TAG, "MSC device connected"); + ESP_LOGI(TAG, "MSC device connected (usb_addr=%d)", event->device.address); app_message_t message = { .id = APP_DEVICE_CONNECTED, .data.new_dev_address = event->device.address, @@ -274,47 +279,56 @@ void app_main(void) xQueueReceive(app_queue, &msg, portMAX_DELAY); if (msg.id == APP_DEVICE_CONNECTED) { - // 1. MSC flash drive connected. Open it and map it to Virtual File System - ESP_ERROR_CHECK(msc_host_install_device(msg.data.new_dev_address, &msc_device)); - const esp_vfs_fat_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 3, - .allocation_unit_size = 8192, - }; - ESP_ERROR_CHECK(msc_host_vfs_register(msc_device, MNT_PATH, &mount_config, &vfs_handle)); - - // 2. Print information about the connected disk - msc_host_device_info_t info; - ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info)); - msc_host_print_descriptors(msc_device); - print_device_info(&info); - - // 3. List all the files in root directory - ESP_LOGI(TAG, "ls command output:"); - struct dirent *d; - DIR *dh = opendir(MNT_PATH); - assert(dh); - while ((d = readdir(dh)) != NULL) { - printf("%s\n", d->d_name); + if (dev_present) { + ESP_LOGW(TAG, "MSC Example handles only one device at a time"); + } else { + // 0. Change flag + dev_present = true; + // 1. MSC flash drive connected. Open it and map it to Virtual File System + ESP_ERROR_CHECK(msc_host_install_device(msg.data.new_dev_address, &msc_device)); + const esp_vfs_fat_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 3, + .allocation_unit_size = 8192, + }; + ESP_ERROR_CHECK(msc_host_vfs_register(msc_device, MNT_PATH, &mount_config, &vfs_handle)); + + // 2. Print information about the connected disk + msc_host_device_info_t info; + ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info)); + msc_host_print_descriptors(msc_device); + print_device_info(&info); + + // 3. List all the files in root directory + ESP_LOGI(TAG, "ls command output:"); + struct dirent *d; + DIR *dh = opendir(MNT_PATH); + assert(dh); + while ((d = readdir(dh)) != NULL) { + printf("%s\n", d->d_name); + } + closedir(dh); + + // 4. The disk is mounted to Virtual File System, perform some basic demo file operation + file_operations(); + + // 5. Perform speed test + speed_test(); + + ESP_LOGI(TAG, "Example finished, you can disconnect the USB flash drive"); } - closedir(dh); - - // 4. The disk is mounted to Virtual File System, perform some basic demo file operation - file_operations(); - - // 5. Perform speed test - speed_test(); - - ESP_LOGI(TAG, "Example finished, you can disconnect the USB flash drive"); } if ((msg.id == APP_DEVICE_DISCONNECTED) || (msg.id == APP_QUIT)) { - if (vfs_handle) { - ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle)); - vfs_handle = NULL; - } - if (msc_device) { - ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device)); - msc_device = NULL; + if (dev_present) { + dev_present = false; + if (vfs_handle) { + ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle)); + vfs_handle = NULL; + } + if (msc_device) { + ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device)); + msc_device = NULL; + } } if (msg.id == APP_QUIT) { // This will cause the usb_task to exit diff --git a/examples/peripherals/usb/host/msc/sdkconfig.defaults b/examples/peripherals/usb/host/msc/sdkconfig.defaults new file mode 100644 index 000000000000..bf1b553b2388 --- /dev/null +++ b/examples/peripherals/usb/host/msc/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c b/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c index 594488df5193..3b7077986f29 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c +++ b/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c @@ -13,21 +13,40 @@ #define CLIENT_NUM_EVENT_MSG 5 typedef enum { - ACTION_OPEN_DEV = 0x01, - ACTION_GET_DEV_INFO = 0x02, - ACTION_GET_DEV_DESC = 0x04, - ACTION_GET_CONFIG_DESC = 0x08, - ACTION_GET_STR_DESC = 0x10, - ACTION_CLOSE_DEV = 0x20, - ACTION_EXIT = 0x40, - ACTION_RECONNECT = 0x80, + ACTION_OPEN_DEV = (1 << 0), + ACTION_GET_DEV_INFO = (1 << 1), + ACTION_GET_DEV_DESC = (1 << 2), + ACTION_GET_CONFIG_DESC = (1 << 3), + ACTION_GET_STR_DESC = (1 << 4), + ACTION_CLOSE_DEV = (1 << 5), } action_t; +#define DEV_MAX_COUNT 128 + typedef struct { usb_host_client_handle_t client_hdl; uint8_t dev_addr; usb_device_handle_t dev_hdl; - uint32_t actions; + action_t actions; +} usb_device_t; + +typedef struct { + struct { + union { + struct { + uint8_t unhandled_devices: 1; /**< Device has unhandled devices */ + uint8_t shutdown: 1; /**< */ + uint8_t reserved6: 6; /**< Reserved */ + }; + uint8_t val; /**< Class drivers' flags value */ + } flags; /**< Class drivers' flags */ + usb_device_t device[DEV_MAX_COUNT]; /**< Class drivers' static array of devices */ + } mux_protected; /**< Mutex protected members. Must be protected by the Class mux_lock when accessed */ + + struct { + usb_host_client_handle_t client_hdl; + SemaphoreHandle_t mux_lock; /**< Mutex for protected members */ + } constant; /**< Constant members. Do not change after installation thus do not require a critical section or mutex */ } class_driver_t; static const char *TAG = "CLASS"; @@ -38,79 +57,94 @@ static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void * class_driver_t *driver_obj = (class_driver_t *)arg; switch (event_msg->event) { case USB_HOST_CLIENT_EVENT_NEW_DEV: - if (driver_obj->dev_addr == 0) { - driver_obj->dev_addr = event_msg->new_dev.address; - //Open the device next - driver_obj->actions |= ACTION_OPEN_DEV; - } + // Save the device address + xSemaphoreTake(driver_obj->constant.mux_lock, portMAX_DELAY); + driver_obj->mux_protected.device[event_msg->new_dev.address].dev_addr = event_msg->new_dev.address; + driver_obj->mux_protected.device[event_msg->new_dev.address].dev_hdl = NULL; + // Open the device next + driver_obj->mux_protected.device[event_msg->new_dev.address].actions |= ACTION_OPEN_DEV; + // Set flag + driver_obj->mux_protected.flags.unhandled_devices = 1; + xSemaphoreGive(driver_obj->constant.mux_lock); break; case USB_HOST_CLIENT_EVENT_DEV_GONE: - if (driver_obj->dev_hdl != NULL) { - //Cancel any other actions and close the device next - driver_obj->actions = ACTION_CLOSE_DEV; + // Cancel any other actions and close the device next + xSemaphoreTake(driver_obj->constant.mux_lock, portMAX_DELAY); + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + if (driver_obj->mux_protected.device[i].dev_hdl == event_msg->dev_gone.dev_hdl) { + driver_obj->mux_protected.device[i].actions = ACTION_CLOSE_DEV; + // Set flag + driver_obj->mux_protected.flags.unhandled_devices = 1; + } } + xSemaphoreGive(driver_obj->constant.mux_lock); break; default: - //Should never occur + // Should never occur abort(); } } -static void action_open_dev(class_driver_t *driver_obj) +static void action_open_dev(usb_device_t *device_obj) { - assert(driver_obj->dev_addr != 0); - ESP_LOGI(TAG, "Opening device at address %d", driver_obj->dev_addr); - ESP_ERROR_CHECK(usb_host_device_open(driver_obj->client_hdl, driver_obj->dev_addr, &driver_obj->dev_hdl)); - //Get the device's information next - driver_obj->actions &= ~ACTION_OPEN_DEV; - driver_obj->actions |= ACTION_GET_DEV_INFO; + assert(device_obj->dev_addr != 0); + ESP_LOGI(TAG, "Opening device at address %d", device_obj->dev_addr); + ESP_ERROR_CHECK(usb_host_device_open(device_obj->client_hdl, device_obj->dev_addr, &device_obj->dev_hdl)); + // Get the device's information next + device_obj->actions |= ACTION_GET_DEV_INFO; } -static void action_get_info(class_driver_t *driver_obj) +static void action_get_info(usb_device_t *device_obj) { - assert(driver_obj->dev_hdl != NULL); + assert(device_obj->dev_hdl != NULL); ESP_LOGI(TAG, "Getting device information"); usb_device_info_t dev_info; - ESP_ERROR_CHECK(usb_host_device_info(driver_obj->dev_hdl, &dev_info)); + ESP_ERROR_CHECK(usb_host_device_info(device_obj->dev_hdl, &dev_info)); ESP_LOGI(TAG, "\t%s speed", (char *[]) { "Low", "Full", "High" }[dev_info.speed]); - ESP_LOGI(TAG, "\tbConfigurationValue %d", dev_info.bConfigurationValue); + ESP_LOGI(TAG, "\tParent info:"); + if (dev_info.parent.dev_hdl) { + usb_device_info_t parent_dev_info; + ESP_ERROR_CHECK(usb_host_device_info(dev_info.parent.dev_hdl, &parent_dev_info)); + ESP_LOGI(TAG, "\t\tBus addr: %d", parent_dev_info.dev_addr); + ESP_LOGI(TAG, "\t\tPort: %d", dev_info.parent.port_num); - //Get the device descriptor next - driver_obj->actions &= ~ACTION_GET_DEV_INFO; - driver_obj->actions |= ACTION_GET_DEV_DESC; + } else { + ESP_LOGI(TAG, "\t\tPort: ROOT"); + } + ESP_LOGI(TAG, "\tbConfigurationValue %d", dev_info.bConfigurationValue); + // Get the device descriptor next + device_obj->actions |= ACTION_GET_DEV_DESC; } -static void action_get_dev_desc(class_driver_t *driver_obj) +static void action_get_dev_desc(usb_device_t *device_obj) { - assert(driver_obj->dev_hdl != NULL); + assert(device_obj->dev_hdl != NULL); ESP_LOGI(TAG, "Getting device descriptor"); const usb_device_desc_t *dev_desc; - ESP_ERROR_CHECK(usb_host_get_device_descriptor(driver_obj->dev_hdl, &dev_desc)); + ESP_ERROR_CHECK(usb_host_get_device_descriptor(device_obj->dev_hdl, &dev_desc)); usb_print_device_descriptor(dev_desc); - //Get the device's config descriptor next - driver_obj->actions &= ~ACTION_GET_DEV_DESC; - driver_obj->actions |= ACTION_GET_CONFIG_DESC; + // Get the device's config descriptor next + device_obj->actions |= ACTION_GET_CONFIG_DESC; } -static void action_get_config_desc(class_driver_t *driver_obj) +static void action_get_config_desc(usb_device_t *device_obj) { - assert(driver_obj->dev_hdl != NULL); + assert(device_obj->dev_hdl != NULL); ESP_LOGI(TAG, "Getting config descriptor"); const usb_config_desc_t *config_desc; - ESP_ERROR_CHECK(usb_host_get_active_config_descriptor(driver_obj->dev_hdl, &config_desc)); + ESP_ERROR_CHECK(usb_host_get_active_config_descriptor(device_obj->dev_hdl, &config_desc)); usb_print_config_descriptor(config_desc, NULL); - //Get the device's string descriptors next - driver_obj->actions &= ~ACTION_GET_CONFIG_DESC; - driver_obj->actions |= ACTION_GET_STR_DESC; + // Get the device's string descriptors next + device_obj->actions |= ACTION_GET_STR_DESC; } -static void action_get_str_desc(class_driver_t *driver_obj) +static void action_get_str_desc(usb_device_t *device_obj) { - assert(driver_obj->dev_hdl != NULL); + assert(device_obj->dev_hdl != NULL); usb_device_info_t dev_info; - ESP_ERROR_CHECK(usb_host_device_info(driver_obj->dev_hdl, &dev_info)); + ESP_ERROR_CHECK(usb_host_device_info(device_obj->dev_hdl, &dev_info)); if (dev_info.str_desc_manufacturer) { ESP_LOGI(TAG, "Getting Manufacturer string descriptor"); usb_print_string_descriptor(dev_info.str_desc_manufacturer); @@ -123,25 +157,59 @@ static void action_get_str_desc(class_driver_t *driver_obj) ESP_LOGI(TAG, "Getting Serial Number string descriptor"); usb_print_string_descriptor(dev_info.str_desc_serial_num); } - //Nothing to do until the device disconnects - driver_obj->actions &= ~ACTION_GET_STR_DESC; } -static void action_close_dev(class_driver_t *driver_obj) +static void action_close_dev(usb_device_t *device_obj) { - ESP_ERROR_CHECK(usb_host_device_close(driver_obj->client_hdl, driver_obj->dev_hdl)); - driver_obj->dev_hdl = NULL; - driver_obj->dev_addr = 0; - //We need to connect a new device - driver_obj->actions &= ~ACTION_CLOSE_DEV; - driver_obj->actions |= ACTION_RECONNECT; + ESP_ERROR_CHECK(usb_host_device_close(device_obj->client_hdl, device_obj->dev_hdl)); + device_obj->dev_hdl = NULL; + device_obj->dev_addr = 0; +} + +static void class_driver_device_handle(usb_device_t *device_obj) +{ + uint8_t actions = device_obj->actions; + device_obj->actions = 0; + + while (actions) { + if (actions & ACTION_OPEN_DEV) { + action_open_dev(device_obj); + } + if (actions & ACTION_GET_DEV_INFO) { + action_get_info(device_obj); + } + if (actions & ACTION_GET_DEV_DESC) { + action_get_dev_desc(device_obj); + } + if (actions & ACTION_GET_CONFIG_DESC) { + action_get_config_desc(device_obj); + } + if (actions & ACTION_GET_STR_DESC) { + action_get_str_desc(device_obj); + } + if (actions & ACTION_CLOSE_DEV) { + action_close_dev(device_obj); + } + + actions = device_obj->actions; + device_obj->actions = 0; + } } void class_driver_task(void *arg) { class_driver_t driver_obj = {0}; + usb_host_client_handle_t class_driver_client_hdl = NULL; ESP_LOGI(TAG, "Registering Client"); + + SemaphoreHandle_t mux_lock = xSemaphoreCreateMutex(); + if (mux_lock == NULL) { + ESP_LOGE(TAG, "Unable to create class driver mutex"); + vTaskDelete(NULL); + return; + } + usb_host_client_config_t client_config = { .is_synchronous = false, //Synchronous clients currently not supported. Set this to false .max_num_event_msg = CLIENT_NUM_EVENT_MSG, @@ -150,52 +218,62 @@ void class_driver_task(void *arg) .callback_arg = (void *) &driver_obj, }, }; - ESP_ERROR_CHECK(usb_host_client_register(&client_config, &driver_obj.client_hdl)); + ESP_ERROR_CHECK(usb_host_client_register(&client_config, &class_driver_client_hdl)); + + driver_obj.constant.mux_lock = mux_lock; + driver_obj.constant.client_hdl = class_driver_client_hdl; + + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + driver_obj.mux_protected.device[i].client_hdl = class_driver_client_hdl; + } + s_driver_obj = &driver_obj; while (1) { - if (driver_obj.actions == 0) { - usb_host_client_handle_events(driver_obj.client_hdl, portMAX_DELAY); - } else { - if (driver_obj.actions & ACTION_OPEN_DEV) { - action_open_dev(&driver_obj); + // Driver has unhandled devices, handle all devices first + if (driver_obj.mux_protected.flags.unhandled_devices) { + xSemaphoreTake(driver_obj.constant.mux_lock, portMAX_DELAY); + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + if (driver_obj.mux_protected.device[i].actions) { + class_driver_device_handle(&driver_obj.mux_protected.device[i]); + } } - if (driver_obj.actions & ACTION_GET_DEV_INFO) { - action_get_info(&driver_obj); - } - if (driver_obj.actions & ACTION_GET_DEV_DESC) { - action_get_dev_desc(&driver_obj); - } - if (driver_obj.actions & ACTION_GET_CONFIG_DESC) { - action_get_config_desc(&driver_obj); - } - if (driver_obj.actions & ACTION_GET_STR_DESC) { - action_get_str_desc(&driver_obj); - } - if (driver_obj.actions & ACTION_CLOSE_DEV) { - action_close_dev(&driver_obj); - } - if (driver_obj.actions & ACTION_EXIT) { + driver_obj.mux_protected.flags.unhandled_devices = 0; + xSemaphoreGive(driver_obj.constant.mux_lock); + } else { + // Driver is active, handle client events + if (driver_obj.mux_protected.flags.shutdown == 0) { + usb_host_client_handle_events(class_driver_client_hdl, portMAX_DELAY); + } else { + // Shutdown the driver break; } - if (driver_obj.actions & ACTION_RECONNECT) { - driver_obj.actions = 0; - } } } - ESP_LOGI(TAG, "Deregistering Client"); - ESP_ERROR_CHECK(usb_host_client_deregister(driver_obj.client_hdl)); - vTaskSuspend(NULL); + ESP_LOGI(TAG, "Deregistering Class Client"); + ESP_ERROR_CHECK(usb_host_client_deregister(class_driver_client_hdl)); + if (mux_lock != NULL) { + vSemaphoreDelete(mux_lock); + } + vTaskDelete(NULL); } void class_driver_client_deregister(void) { - if (s_driver_obj->dev_hdl != NULL) { - s_driver_obj->actions = ACTION_CLOSE_DEV; + // Mark all opened devices + xSemaphoreTake(s_driver_obj->constant.mux_lock, portMAX_DELAY); + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + if (s_driver_obj->mux_protected.device[i].dev_hdl != NULL) { + // Mark device to close + s_driver_obj->mux_protected.device[i].actions |= ACTION_CLOSE_DEV; + // Set flag + s_driver_obj->mux_protected.flags.unhandled_devices = 1; + } } - s_driver_obj->actions |= ACTION_EXIT; + s_driver_obj->mux_protected.flags.shutdown = 1; + xSemaphoreGive(s_driver_obj->constant.mux_lock); // Unblock, exit the loop and proceed to deregister client - ESP_ERROR_CHECK(usb_host_client_unblock(s_driver_obj->client_hdl)); + ESP_ERROR_CHECK(usb_host_client_unblock(s_driver_obj->constant.client_hdl)); } diff --git a/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c b/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c index e6c2a8df92dd..f1a2dc348a53 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c +++ b/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -120,26 +120,26 @@ static void usb_host_lib_task(void *arg) xTaskNotifyGive(arg); bool has_clients = true; - bool has_devices = true; - while (has_clients || has_devices) { + bool has_devices = false; + while (has_clients) { uint32_t event_flags; ESP_ERROR_CHECK(usb_host_lib_handle_events(portMAX_DELAY, &event_flags)); if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { - ESP_LOGI(TAG, "No more clients"); - has_clients = false; + ESP_LOGI(TAG, "Get FLAGS_NO_CLIENTS"); if (ESP_OK == usb_host_device_free_all()) { - ESP_LOGI(TAG, "All devices marked as free"); + ESP_LOGI(TAG, "All devices marked as free, no need to wait FLAGS_ALL_FREE event"); + has_clients = false; } else { - ESP_LOGI(TAG, "Wait for the ALL FREE EVENT"); + ESP_LOGI(TAG, "Wait for the FLAGS_ALL_FREE"); + has_devices = true; } } - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - ESP_LOGI(TAG, "No more devices"); - has_devices = false; + if (has_devices && event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "Get FLAGS_ALL_FREE"); + has_clients = false; } - } - ESP_LOGI(TAG, "No more clients and devices"); + ESP_LOGI(TAG, "No more clients and devices, uninstall USB Host library"); //Uninstall the USB Host Library ESP_ERROR_CHECK(usb_host_uninstall()); @@ -167,7 +167,7 @@ void app_main(void) TaskHandle_t host_lib_task_hdl, class_driver_task_hdl; - //Create usb host lib task + // Create usb host lib task BaseType_t task_created; task_created = xTaskCreatePinnedToCore(usb_host_lib_task, "usb_host", @@ -178,19 +178,20 @@ void app_main(void) 0); assert(task_created == pdTRUE); - //Wait unit the USB host library is installed + // Wait unit the USB host library is installed ulTaskNotifyTake(false, 1000); - //Create class driver task + // Create class driver task task_created = xTaskCreatePinnedToCore(class_driver_task, "class", - 4096, + 5 * 1024, NULL, CLASS_TASK_PRIORITY, &class_driver_task_hdl, 0); assert(task_created == pdTRUE); - vTaskDelay(10); //Add a short delay to let the tasks run + // Add a short delay to let the tasks run + vTaskDelay(10); while (1) { if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) { @@ -198,22 +199,20 @@ void app_main(void) // User pressed button usb_host_lib_info_t lib_info; ESP_ERROR_CHECK(usb_host_lib_info(&lib_info)); - if (lib_info.num_devices == 0) { - // End while cycle - break; - } else { - ESP_LOGW(TAG, "To shutdown example, remove all USB devices and press button again."); - // Keep polling + if (lib_info.num_devices != 0) { + ESP_LOGW(TAG, "Shutdown with attached devices."); } + // End while cycle + break; } } } - //Deregister client + // Deregister client class_driver_client_deregister(); vTaskDelay(10); - //Delete the tasks + // Delete the tasks vTaskDelete(class_driver_task_hdl); vTaskDelete(host_lib_task_hdl); diff --git a/examples/peripherals/usb/host/usb_host_lib/sdkconfig.defaults b/examples/peripherals/usb/host/usb_host_lib/sdkconfig.defaults new file mode 100644 index 000000000000..bf1b553b2388 --- /dev/null +++ b/examples/peripherals/usb/host/usb_host_lib/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_USB_HOST_HUBS_SUPPORTED=y