Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions host/class/cdc/usb_host_cdc_acm/test_app/main/test_cdc_acm_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,14 +906,14 @@ TEST_CASE("suspend_resume_multiple_devs", "[cdc_acm]")
vTaskDelay(20); // Short delay to allow task to be cleaned up
}

#define TEST_CDC_ACM_PM_TIMER_INTERVAL_MS 1000
#define TEST_CDC_ACM_PM_TIMER_MARGIN_MS 50
#define TEST_CDC_ACM_SUSPEND_TIMER_INTERVAL_MS 1000
#define TEST_CDC_ACM_SUSPEND_TIMER_MARGIN_MS 50
/**
* @brief Test: Automatic suspend timer
*
* #. open the device, set One-Shot PM timer, expect one USB_HOST_CLIENT_EVENT_DEV_SUSPENDED event
* #. Set Periodic PM timer, expect multiple USB_HOST_CLIENT_EVENT_DEV_SUSPENDED events
* #. Disable Periodic PM timer, expect no event
* #. open the device, set One-Shot auto suspend timer, expect one USB_HOST_CLIENT_EVENT_DEV_SUSPENDED event
* #. Set Periodic auto suspend timer, expect multiple USB_HOST_CLIENT_EVENT_DEV_SUSPENDED events
* #. Disable Periodic auto suspend timer, expect no event
* #. disconnect the device
* #. cleanup
*/
Expand All @@ -932,23 +932,23 @@ TEST_CASE("automatic_suspend_timer", "[cdc_acm]")
TEST_ASSERT_NOT_NULL(cdc_dev);
vTaskDelay(10);

// Set One-Shot PM timer
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_set_auto_pm(USB_HOST_LIB_PM_SUSPEND_ONE_SHOT, TEST_CDC_ACM_PM_TIMER_INTERVAL_MS));
wait_for_app_event(CDC_ACM_HOST_DEVICE_SUSPENDED, pdMS_TO_TICKS(TEST_CDC_ACM_PM_TIMER_INTERVAL_MS + TEST_CDC_ACM_PM_TIMER_MARGIN_MS));
// Set One-Shot auto suspend timer
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_set_auto_suspend(USB_HOST_LIB_AUTO_SUSPEND_ONE_SHOT, TEST_CDC_ACM_SUSPEND_TIMER_INTERVAL_MS));
wait_for_app_event(CDC_ACM_HOST_DEVICE_SUSPENDED, pdMS_TO_TICKS(TEST_CDC_ACM_SUSPEND_TIMER_INTERVAL_MS + TEST_CDC_ACM_SUSPEND_TIMER_MARGIN_MS));

// Manually resume the root port and expect the resumed event
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_root_port_resume());
wait_for_app_event(CDC_ACM_HOST_DEVICE_RESUMED, 20);

// Make sure no event is delivered, since the timer is a One-Shot timer
wait_for_no_app_event(pdMS_TO_TICKS(TEST_CDC_ACM_PM_TIMER_INTERVAL_MS * 2));
wait_for_no_app_event(pdMS_TO_TICKS(TEST_CDC_ACM_SUSPEND_TIMER_INTERVAL_MS * 2));

// Set Periodic PM suspend timer
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_set_auto_pm(USB_HOST_LIB_PM_SUSPEND_PERIODIC, TEST_CDC_ACM_PM_TIMER_INTERVAL_MS));
// Set Periodic auto suspend timer
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_set_auto_suspend(USB_HOST_LIB_AUTO_SUSPEND_PERIODIC, TEST_CDC_ACM_SUSPEND_TIMER_INTERVAL_MS));

for (int i = 0; i < 3; i++) {
// Expect suspended event from auto suspend timer
wait_for_app_event(CDC_ACM_HOST_DEVICE_SUSPENDED, pdMS_TO_TICKS(TEST_CDC_ACM_PM_TIMER_INTERVAL_MS + TEST_CDC_ACM_PM_TIMER_MARGIN_MS));
wait_for_app_event(CDC_ACM_HOST_DEVICE_SUSPENDED, pdMS_TO_TICKS(TEST_CDC_ACM_SUSPEND_TIMER_INTERVAL_MS + TEST_CDC_ACM_SUSPEND_TIMER_MARGIN_MS));

// Resume the root port manually and expect the resume event
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_root_port_resume());
Expand All @@ -958,10 +958,10 @@ TEST_CASE("automatic_suspend_timer", "[cdc_acm]")
TEST_ASSERT_EQUAL(ESP_OK, cdc_acm_host_data_tx_blocking(cdc_dev, tx_buf, sizeof(tx_buf), 1000));
}

// Disable the Periodic PM timer
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_set_auto_pm(USB_HOST_LIB_PM_SUSPEND_PERIODIC, 0));
// Disable the Periodic auto suspend timer
TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_set_auto_suspend(USB_HOST_LIB_AUTO_SUSPEND_PERIODIC, 0));
// Make sure no event is delivered
wait_for_no_app_event(pdMS_TO_TICKS(TEST_CDC_ACM_PM_TIMER_INTERVAL_MS * 2));
wait_for_no_app_event(pdMS_TO_TICKS(TEST_CDC_ACM_SUSPEND_TIMER_INTERVAL_MS * 2));

// Clean-up
TEST_ASSERT_EQUAL(ESP_OK, cdc_acm_host_close(cdc_dev));
Expand Down
52 changes: 26 additions & 26 deletions host/class/msc/usb_host_msc/test_app/main/test_msc.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,71 +646,71 @@ TEST_CASE("suspend_resume", "[usb_msc]")
msc_teardown();
}

#define MSC_TEST_PM_TIMER_INTERVAL_MS 1000
#define MSC_TEST_PM_TIMER_MARGIN_MS 50
#define MSC_TEST_SUSPEND_TIMER_INTERVAL_MS 1000
#define MSC_TEST_SUSPEND_TIMER_MARGIN_MS 50
/**
* @brief USB MSC driver with the Power Management timer
* @brief USB MSC driver with the automatic suspend timer timer
*
* Purpose:
* - Test One-Shot and Periodic PM timer for global Suspend of the root port with MSC Driver
* - Test One-Shot and Periodic auto suspend timer for global Suspend of the root port with MSC Driver
*
* Procedure:
* - Install USB Host lib, Install MSC driver, open a device, register VFS
* - Set One-Shot PM timer to 1000ms
* - Set One-Shot auto suspend timer to 1000ms
* - Simulate some USB traffic by reading/writing a file multiple times and regularly check that no USB_HOST_LIB event is delivered
* - Once all the traffic is idle, verify the MSC_DEVICE_SUSPENDED event is delivered
* - Measure time from issuing automatic suspend until the suspend event delivery
- Set Periodic PM timer and periodically check for MSC_DEVICE_SUSPENDED event, manually resume the device and verify device functionality
* - Disable the Periodic PM timer it and make sure no other event is delivered
- Set Periodic auto suspend timer and periodically check for MSC_DEVICE_SUSPENDED event, manually resume the device and verify device functionality
* - Disable the Periodic auto suspend timer and make sure no other event is delivered
* - Teardown
*/
TEST_CASE("auto_suspend_timer", "[usb_msc]")
{
msc_setup();

// Set One-Shot PM suspend timer and start measuring ticks
ESP_OK_ASSERT(usb_host_lib_set_auto_pm(USB_HOST_LIB_PM_SUSPEND_ONE_SHOT, MSC_TEST_PM_TIMER_INTERVAL_MS));
TickType_t auto_pm_suspend_tick_start = xTaskGetTickCount();
// Set One-Shot auto suspend timer and start measuring ticks
ESP_OK_ASSERT(usb_host_lib_set_auto_suspend(USB_HOST_LIB_AUTO_SUSPEND_ONE_SHOT, MSC_TEST_SUSPEND_TIMER_INTERVAL_MS));
TickType_t auto_suspend_tick_start = xTaskGetTickCount();
msc_host_event_t peek_event, expected_event;

// Simulate some traffic, so the root port would not suspend after MSC_TEST_PM_TIMER_INTERVAL_MS from now,
// but after MSC_TEST_PM_TIMER_INTERVAL_MS, once there is no traffic
// Simulate some traffic, so the root port would not suspend after MSC_TEST_SUSPEND_TIMER_INTERVAL_MS from now,
// but after MSC_TEST_SUSPEND_TIMER_INTERVAL_MS, once there is no traffic
// Regularly check, that there is no item in queue (check that the timer did not expire)
for (int i = 0; i < 5; i++) {
write_read_file(FILE_NAME);
TEST_ASSERT_EQUAL(pdFALSE, xQueuePeek(app_queue, &peek_event, 0));
}

// Expect MSC device to be suspended, expect app queue and block for MSC_TEST_PM_TIMER_INTERVAL_MS + some margin
// Expect MSC device to be suspended, expect app queue and block for MSC_TEST_SUSPEND_TIMER_INTERVAL_MS + some margin
expected_event.event = MSC_DEVICE_SUSPENDED;
wait_for_app_event(&expected_event, pdMS_TO_TICKS(MSC_TEST_PM_TIMER_INTERVAL_MS + MSC_TEST_PM_TIMER_MARGIN_MS));
wait_for_app_event(&expected_event, pdMS_TO_TICKS(MSC_TEST_SUSPEND_TIMER_INTERVAL_MS + MSC_TEST_SUSPEND_TIMER_MARGIN_MS));

TickType_t auto_pm_suspend_tick_end = xTaskGetTickCount(); // App event received, stop measuring ticks
const uint32_t elapsed_ms = (auto_pm_suspend_tick_end - auto_pm_suspend_tick_start) * portTICK_PERIOD_MS;
TickType_t auto_suspend_tick_end = xTaskGetTickCount(); // App event received, stop measuring ticks
const uint32_t elapsed_ms = (auto_suspend_tick_end - auto_suspend_tick_start) * portTICK_PERIOD_MS;

// Check that, the time elapsed between setting the auto suspend timer and MSC_DEVICE_SUSPENDED event
// is more than MSC_TEST_PM_TIMER_INTERVAL_MS + some margin
// is more than MSC_TEST_SUSPEND_TIMER_INTERVAL_MS + some margin
TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(
MSC_TEST_PM_TIMER_INTERVAL_MS + MSC_TEST_PM_TIMER_MARGIN_MS, elapsed_ms,
MSC_TEST_SUSPEND_TIMER_INTERVAL_MS + MSC_TEST_SUSPEND_TIMER_MARGIN_MS, elapsed_ms,
"Auto suspend timer did not expire on time"
);

// Make sure that no event is delivered, since we set the timer to be One-Shot
wait_for_app_event(NULL, pdMS_TO_TICKS(MSC_TEST_PM_TIMER_INTERVAL_MS * 2));
wait_for_app_event(NULL, pdMS_TO_TICKS(MSC_TEST_SUSPEND_TIMER_INTERVAL_MS * 2));

// Resume the root port manually and expect the resume event
ESP_OK_ASSERT(usb_host_lib_root_port_resume());
expected_event.event = MSC_DEVICE_RESUMED;
wait_for_app_event(&expected_event, 20);

// Set Periodic PM suspend timer
ESP_OK_ASSERT(usb_host_lib_set_auto_pm(USB_HOST_LIB_PM_SUSPEND_PERIODIC, MSC_TEST_PM_TIMER_INTERVAL_MS));
// Set Periodic auto suspend timer
ESP_OK_ASSERT(usb_host_lib_set_auto_suspend(USB_HOST_LIB_AUTO_SUSPEND_PERIODIC, MSC_TEST_SUSPEND_TIMER_INTERVAL_MS));

for (int i = 0; i < 3; i++) {

// Expect suspended event from auto suspend timer
expected_event.event = MSC_DEVICE_SUSPENDED;
wait_for_app_event(&expected_event, pdMS_TO_TICKS(MSC_TEST_PM_TIMER_INTERVAL_MS + MSC_TEST_PM_TIMER_MARGIN_MS));
wait_for_app_event(&expected_event, pdMS_TO_TICKS(MSC_TEST_SUSPEND_TIMER_INTERVAL_MS + MSC_TEST_SUSPEND_TIMER_MARGIN_MS));

// Resume the root port manually and expect the resume event
ESP_OK_ASSERT(usb_host_lib_root_port_resume());
Expand All @@ -721,10 +721,10 @@ TEST_CASE("auto_suspend_timer", "[usb_msc]")
write_read_file(FILE_NAME);
}

// Disable Periodic PM timer
ESP_OK_ASSERT(usb_host_lib_set_auto_pm(USB_HOST_LIB_PM_SUSPEND_PERIODIC, 0));
// Test that the Periodic PM timer can be disabled and no other event is delivered
TEST_ASSERT_EQUAL(pdFALSE, xQueuePeek(app_queue, &peek_event, pdMS_TO_TICKS(MSC_TEST_PM_TIMER_INTERVAL_MS * 2)));
// Disable Periodic auto suspend timer
ESP_OK_ASSERT(usb_host_lib_set_auto_suspend(USB_HOST_LIB_AUTO_SUSPEND_PERIODIC, 0));
// Test that the Periodic auto suspend timer can be disabled and no other event is delivered
TEST_ASSERT_EQUAL(pdFALSE, xQueuePeek(app_queue, &peek_event, pdMS_TO_TICKS(MSC_TEST_SUSPEND_TIMER_INTERVAL_MS * 2)));
msc_teardown();
}

Expand Down
18 changes: 9 additions & 9 deletions host/usb/include/usb/usb_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ typedef enum {
} usb_host_client_event_t;

/**
* @brief USB Host lib power management timer type
* @brief USB Host lib automatic suspend timer
*/
typedef enum {
USB_HOST_LIB_PM_SUSPEND_ONE_SHOT, /**< USB Host lib power management -> Auto suspend one-shot timer */
USB_HOST_LIB_PM_SUSPEND_PERIODIC, /**< USB Host lib power management -> Auto suspend periodic timer */
} usb_host_lib_pm_t;
USB_HOST_LIB_AUTO_SUSPEND_ONE_SHOT, /**< Automatic suspend one-shot timer */
USB_HOST_LIB_AUTO_SUSPEND_PERIODIC, /**< Automatic suspend periodic timer */
} usb_host_lib_auto_suspend_tmr_t;

/**
* @brief Client event message
Expand Down Expand Up @@ -292,15 +292,15 @@ esp_err_t usb_host_lib_root_port_suspend(void);
esp_err_t usb_host_lib_root_port_resume(void);

/**
* @brief Set auto power management timer
* @brief Set automatic suspend timer
*
* - The function sets the auto suspend timer, used for global suspend of the root port
* - The function sets the automatic suspend timer, used for global suspend of the root port
* - The timer is either one-shot or periodic
* - The timerexpires after the set period, only if there is no activity on the USB Bus
* - The timer expires after the set period, only if there is no activity on the USB Bus
* - The timer resets (if enabled) every time, the usb_host_client_handle_events() handles any client events,
* or the usb_host_lib_handle_events() handles any host lib events, thus checking any activity on all the
* registered clients or inside the host lib
* - Once the timer expires, an auto_pm_timer_cb() is called, which delivers USB Host lib event flags
* - Once the timer expires, an auto_suspend_timer_cb() is called, which delivers USB Host lib event flags
*
* @note set the timer interval to 0, to disable the timer (in case NO auto suspend functionality is required anymore)
* @note this function is not ISR safe
Expand All @@ -311,7 +311,7 @@ esp_err_t usb_host_lib_root_port_resume(void);
* - ESP_ERR_INVALID_STATE: USB Host lib is not installed
* - ESP_FAIL: Timer was not configured correctly
*/
esp_err_t usb_host_lib_set_auto_pm(usb_host_lib_pm_t timer_type, size_t timer_interval_ms);
esp_err_t usb_host_lib_set_auto_suspend(usb_host_lib_auto_suspend_tmr_t timer_type, size_t timer_interval_ms);

// ------------------------------------------------ Client Functions ---------------------------------------------------

Expand Down
Loading
Loading