From 1ac9f6efc5978365ac352b7912fa9efa9b5253cc Mon Sep 17 00:00:00 2001 From: Roman Leonov Date: Mon, 4 Mar 2024 08:58:59 +0100 Subject: [PATCH] feat(esp_tinyusb): Added hot_disconnect test (disconnect during ongoing USB IN transfer, manual) --- .../esp_tinyusb/test_app/main/CMakeLists.txt | 4 +- .../test_app/main/test_bvalid_sig.c | 2 +- .../test_app/main/test_hot_disconnect.c | 153 ++++++++++++++++++ 3 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 device/esp_tinyusb/test_app/main/test_hot_disconnect.c diff --git a/device/esp_tinyusb/test_app/main/CMakeLists.txt b/device/esp_tinyusb/test_app/main/CMakeLists.txt index d300185b..3cb6ad50 100644 --- a/device/esp_tinyusb/test_app/main/CMakeLists.txt +++ b/device/esp_tinyusb/test_app/main/CMakeLists.txt @@ -1,6 +1,6 @@ include($ENV{IDF_PATH}/tools/cmake/version.cmake) -idf_component_register(SRCS "test_esp_tinyusb.c" "test_bvalid_sig.c" "test_app_main.c" - INCLUDE_DIRS "." +idf_component_register(SRC_DIRS . + INCLUDE_DIRS . REQUIRES unity esp_tinyusb WHOLE_ARCHIVE) diff --git a/device/esp_tinyusb/test_app/main/test_bvalid_sig.c b/device/esp_tinyusb/test_app/main/test_bvalid_sig.c index ad74c52d..5e1f7476 100644 --- a/device/esp_tinyusb/test_app/main/test_bvalid_sig.c +++ b/device/esp_tinyusb/test_app/main/test_bvalid_sig.c @@ -65,7 +65,7 @@ void tud_umount_cb(void) dev_umounted++; } -TEST_CASE("bvalid_signal", "[esp_tinyusb][usb_device]") +TEST_CASE("bvalid_signal", "[manual]") { unsigned int rounds = DEVICE_DETACH_TEST_ROUNDS; diff --git a/device/esp_tinyusb/test_app/main/test_hot_disconnect.c b/device/esp_tinyusb/test_app/main/test_hot_disconnect.c new file mode 100644 index 00000000..c7c59366 --- /dev/null +++ b/device/esp_tinyusb/test_app/main/test_hot_disconnect.c @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" +#if SOC_USB_OTG_SUPPORTED + +#include +#include +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "esp_err.h" +#include "esp_rom_gpio.h" +#include "soc/gpio_sig_map.h" +#include "unity.h" +#include "tinyusb.h" +#include "tusb_cdc_acm.h" + +// TODO: make description +#define TEST_ROUNDS 2 +#define TEST_IN_PAKET_DELAY_MS 100 +#define TEST_DEVICE_STATE_CHANGE_DELAY_MS 2500 + +volatile static bool cdc_active = false; +volatile static bool end_test = false; +static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; + +// LOW to emulate disconnect USB device +static void emulate_disconnect(void) +{ + esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_SRP_BVALID_IN_IDX, false); +} + +// HIGH to emulate connect USB device +static void emulate_connect(void) +{ + esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_SRP_BVALID_IN_IDX, false); +} + +void connect_disconnect_emu(void *pvParameters) +{ + printf("\tStart Connect/Disconnect\n"); + unsigned int rounds = TEST_ROUNDS; + + while (rounds--) { + emulate_disconnect(); + vTaskDelay(pdMS_TO_TICKS(TEST_DEVICE_STATE_CHANGE_DELAY_MS)); + emulate_connect(); + vTaskDelay(pdMS_TO_TICKS(TEST_DEVICE_STATE_CHANGE_DELAY_MS)); + } + printf("\tConnect/Disconnect Complete\n"); + end_test = true; + vTaskDelete(NULL); +} + + +// Rx Callback +static void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + +} + +static void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) +{ + int dtr = event->line_state_changed_data.dtr; + int rts = event->line_state_changed_data.rts; + printf("\tCDC line state changed\n"); + cdc_active = (dtr && rts); +} + +// Invoked when device is mounted (configured) +void tud_mount_cb(void) +{ + printf("\tUSB mounted\n"); +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + printf("\tUSB unmounted\n"); +} + +// Invoked when usb bus is suspended +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + printf("\tUSB suspended\n"); +} + +/** + * @brief TinyUSB Hot Disconnect testcase + * TODO: Description + */ +TEST_CASE("hot_disconnect", "[manual]") +{ + // Default tusb_cfg + const tinyusb_config_t tusb_cfg = { 0 }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .rx_unread_buf_sz = 64, + .callback_rx = &tinyusb_cdc_rx_callback, // the first way to register a callback + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &tinyusb_cdc_line_state_changed_callback)); + + // TODO: verify task creation + xTaskCreate(&connect_disconnect_emu, "connect_disconect", 2 * 1024, NULL, 2, NULL); + + int data_count = 1; + + while (1) { + vTaskDelay(pdMS_TO_TICKS(100)); + if (cdc_active) { + if (end_test) { + buf[0] = '\n'; + tinyusb_cdcacm_write_queue(0, buf, data_count); + tinyusb_cdcacm_write_flush(0, 0); + break; + } + + if (data_count == CONFIG_TINYUSB_CDC_RX_BUFSIZE) { + data_count = 1; + } + + for (int i = 0; i <= data_count; i++) { + buf[i] = 0x41; + } + tinyusb_cdcacm_write_queue(0, buf, data_count); + tinyusb_cdcacm_write_flush(0, 0); + data_count++; + } + } + + // TODO: Uninstall TinyUSB +} + +#endif