Skip to content

Commit 721c79c

Browse files
feat(usb_host): Remote wakeup WIP
1 parent 7b1bc3f commit 721c79c

File tree

4 files changed

+70
-33
lines changed

4 files changed

+70
-33
lines changed

host/usb/src/hcd_dwc.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,7 @@ static hcd_port_event_t _intr_hdlr_hprt(port_t *port, usb_dwc_hal_port_event_t h
833833
}
834834
case USB_DWC_HAL_PORT_EVENT_REMOTE_WAKEUP: {
835835
ESP_EARLY_LOGI(HCD_DWC_TAG, "WAKE");
836+
//port->state = HCD_PORT_STATE_ENABLED;
836837
port_event = HCD_PORT_EVENT_REMOTE_WAKEUP;
837838
break;
838839
}
@@ -1236,6 +1237,8 @@ static esp_err_t _port_cmd_power_on(port_t *port)
12361237
} else {
12371238
ret = ESP_ERR_INVALID_STATE;
12381239
}
1240+
//esp_rom_printf("power on: HPRT = %lx\n", usb_dwc_hal_port_get_hprt_val(port->hal));
1241+
//esp_rom_printf("power on: GINTSTS = %lx\n", usb_dwc_hal_port_get_gintsts_val(port->hal));
12391242
return ret;
12401243
}
12411244

@@ -1373,11 +1376,17 @@ static esp_err_t _port_cmd_bus_resume(port_t *port)
13731376
ret = ESP_ERR_INVALID_STATE;
13741377
goto exit;
13751378
}
1379+
HCD_EXIT_CRITICAL();
1380+
//vTaskDelay(pdMS_TO_TICKS(RESUME_HOLD_MS));
1381+
vTaskDelay(pdMS_TO_TICKS(500));
1382+
HCD_ENTER_CRITICAL();
1383+
13761384
// Put and hold the bus in the K state.
13771385
usb_dwc_hal_port_toggle_resume(port->hal, true);
13781386
port->state = HCD_PORT_STATE_RESUMING;
13791387
HCD_EXIT_CRITICAL();
1380-
vTaskDelay(pdMS_TO_TICKS(RESUME_HOLD_MS));
1388+
//vTaskDelay(pdMS_TO_TICKS(RESUME_HOLD_MS));
1389+
vTaskDelay(pdMS_TO_TICKS(500));
13811390
HCD_ENTER_CRITICAL();
13821391
// Return and hold the bus to the J state (as port of the LS EOP)
13831392
usb_dwc_hal_port_toggle_resume(port->hal, false);
@@ -1387,7 +1396,8 @@ static esp_err_t _port_cmd_bus_resume(port_t *port)
13871396
goto exit;
13881397
}
13891398
HCD_EXIT_CRITICAL();
1390-
vTaskDelay(pdMS_TO_TICKS(RESUME_RECOVERY_MS));
1399+
//vTaskDelay(pdMS_TO_TICKS(RESUME_RECOVERY_MS));
1400+
vTaskDelay(pdMS_TO_TICKS(500));
13911401
HCD_ENTER_CRITICAL();
13921402
if (port->state != HCD_PORT_STATE_RESUMING || !port->flags.conn_dev_ena) {
13931403
// Port state unexpectedly changed
@@ -1396,7 +1406,14 @@ static esp_err_t _port_cmd_bus_resume(port_t *port)
13961406
}
13971407
port->state = HCD_PORT_STATE_ENABLED;
13981408

1409+
if (usb_dwc_hal_port_check_if_suspended(port->hal)) {
1410+
printf("Again suspended\n");
1411+
}
1412+
13991413
ret = ESP_OK;
1414+
// esp_rom_printf("resume: HPRT = %lx\n", usb_dwc_hal_port_get_hprt_val(port->hal));
1415+
// esp_rom_printf("power on: GINTSTS = %lx\n", usb_dwc_hal_port_get_gintsts_val(port->hal));
1416+
14001417
exit:
14011418
return ret;
14021419
}
@@ -1490,8 +1507,11 @@ esp_err_t hcd_port_deinit(hcd_port_handle_t port_hdl)
14901507
return ESP_OK;
14911508
}
14921509

1510+
static port_t *s_port;
1511+
14931512
esp_err_t hcd_port_command(hcd_port_handle_t port_hdl, hcd_port_cmd_t command)
14941513
{
1514+
s_port = (port_t *)port_hdl;
14951515
esp_err_t ret = ESP_ERR_INVALID_STATE;
14961516
port_t *port = (port_t *)port_hdl;
14971517
xSemaphoreTake(port->port_mux, portMAX_DELAY);
@@ -2693,6 +2713,8 @@ static inline bool _check_port_pipe_state(pipe_t *pipe, bool *submit_urb)
26932713

26942714
esp_err_t hcd_urb_enqueue(hcd_pipe_handle_t pipe_hdl, urb_t *urb)
26952715
{
2716+
//esp_rom_printf("HPRT: %lx\n", usb_dwc_hal_port_get_hprt_val(s_port->hal));
2717+
//esp_rom_printf("power on: GINTSTS = %lx\n", usb_dwc_hal_port_get_gintsts_val(s_port->hal));
26962718
// Check that URB has not already been enqueued
26972719
HCD_CHECK(urb->hcd_ptr == NULL && urb->hcd_var == URB_HCD_STATE_IDLE, ESP_ERR_INVALID_STATE);
26982720
pipe_t *pipe = (pipe_t *)pipe_hdl;

host/usb/src/hub.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,14 @@ static void root_port_handle_events(hcd_port_handle_t root_port_hdl)
444444
case HCD_PORT_EVENT_REMOTE_WAKEUP:
445445
// Root port, including all the connected devices were resumed (global resume)
446446
// Clear all EPs and propagate the resumed event to clients
447-
usbh_devs_set_pm_actions_all(USBH_DEV_RESUME | USBH_DEV_RESUME_EVT);
447+
//usbh_devs_set_pm_actions_all(USBH_DEV_RESUME | USBH_DEV_RESUME_EVT);
448+
//esp_rom_printf("p_hub_driver_obj->dynamic.root_port_state = %d\n", p_hub_driver_obj->dynamic.root_port_state);
449+
450+
// Change Port state
451+
//HUB_DRIVER_ENTER_CRITICAL();
452+
//p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_ENABLED;
453+
//HUB_DRIVER_EXIT_CRITICAL();
454+
hub_root_mark_resume();
448455
break;
449456
default:
450457
abort(); // Should never occur
@@ -484,7 +491,7 @@ static void root_port_req(hcd_port_handle_t root_port_hdl)
484491
}
485492
}
486493
if (port_reqs & PORT_REQ_SUSPEND) {
487-
ESP_LOGD(HUB_DRIVER_TAG, "Suspending the root port");
494+
ESP_LOGI(HUB_DRIVER_TAG, "Suspending the root port");
488495

489496
HUB_DRIVER_ENTER_CRITICAL();
490497
const root_port_state_t root_state = p_hub_driver_obj->dynamic.root_port_state;
@@ -507,7 +514,7 @@ static void root_port_req(hcd_port_handle_t root_port_hdl)
507514
usbh_devs_set_pm_actions_all(USBH_DEV_SUSPEND_EVT);
508515
}
509516
if (port_reqs & PORT_REQ_RESUME) {
510-
ESP_LOGD(HUB_DRIVER_TAG, "Resuming the root port");
517+
ESP_LOGI(HUB_DRIVER_TAG, "Resuming the root port");
511518

512519
HUB_DRIVER_ENTER_CRITICAL();
513520
const root_port_state_t root_state = p_hub_driver_obj->dynamic.root_port_state;

host/usb/src/usb_host.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,14 @@ static bool endpoint_callback(usbh_ep_handle_t ep_hdl, usbh_ep_event_t ep_event,
486486
return yield;
487487
}
488488

489-
static void get_config_desc_transfer_cb(usb_transfer_t *transfer)
489+
/**
490+
* @brief Control transfer callback
491+
*
492+
* This callback is used in ctrl transfers for remote wakeup feature and multiconfig feature
493+
*
494+
* @param[in] transfer Pointer to ctrl transfer
495+
*/
496+
static void ctrl_transfer_cb(usb_transfer_t *transfer)
490497
{
491498
SemaphoreHandle_t transfer_done = (SemaphoreHandle_t)transfer->context;
492499
xSemaphoreGive(transfer_done);
@@ -1333,7 +1340,9 @@ esp_err_t usb_host_get_active_config_descriptor(usb_device_handle_t dev_hdl, con
13331340
static usb_transfer_status_t wait_for_transmission_done(usb_transfer_t *transfer)
13341341
{
13351342
SemaphoreHandle_t transfer_done = (SemaphoreHandle_t)transfer->context;
1343+
esp_rom_printf("Transfer wait\n");
13361344
xSemaphoreTake(transfer_done, portMAX_DELAY);
1345+
esp_rom_printf("Transfer done\n");
13371346
usb_transfer_status_t status = transfer->status;
13381347

13391348
// EP0 halt->flush->clear is managed by USBH and lower layers
@@ -1409,7 +1418,7 @@ esp_err_t usb_host_get_config_desc(usb_host_client_handle_t client_hdl, usb_devi
14091418

14101419
ctrl_transfer->device_handle = dev_hdl;
14111420
ctrl_transfer->bEndpointAddress = 0;
1412-
ctrl_transfer->callback = get_config_desc_transfer_cb;
1421+
ctrl_transfer->callback = ctrl_transfer_cb;
14131422
ctrl_transfer->context = (void *)transfer_done;
14141423

14151424
// Initiate control transfer for short config descriptor
@@ -1460,7 +1469,7 @@ esp_err_t usb_host_free_config_desc(const usb_config_desc_t *config_desc)
14601469
}
14611470

14621471
/**
1463-
* @brief Do control transfer
1472+
* @brief Do control transfer to get/set remote wakeup feature
14641473
*
14651474
* This function: allocates transfer, sets the transfer params, submits the transfer and evaluates it
14661475
*
@@ -1474,10 +1483,12 @@ esp_err_t usb_host_free_config_desc(const usb_config_desc_t *config_desc)
14741483
*
14751484
* @return
14761485
* - ESP_OK: Transfer successful
1477-
* TODO
1486+
* - ESP_ERR_NO_MEM: Not enough memory
1487+
* - ESP_ERR_INVALID_STATE: Control transfer failed
1488+
* - ESP_ERR_INVALID_RESPONSE: Invalid number of bytest returned by IN transfer stage
14781489
*/
1479-
static esp_err_t do_control_transfer(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl,
1480-
usb_setup_packet_t *setup_packet, void *data_buf, size_t data_len)
1490+
static esp_err_t remote_wake_do_control_transfer(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl,
1491+
usb_setup_packet_t *setup_packet, void *data_buf, size_t data_len)
14811492
{
14821493
esp_err_t ret;
14831494
usb_transfer_t *ctrl_transfer = NULL;
@@ -1494,7 +1505,7 @@ static esp_err_t do_control_transfer(usb_host_client_handle_t client_hdl, usb_de
14941505

14951506
ctrl_transfer->device_handle = dev_hdl;
14961507
ctrl_transfer->bEndpointAddress = 0;
1497-
ctrl_transfer->callback = get_config_desc_transfer_cb;
1508+
ctrl_transfer->callback = ctrl_transfer_cb;
14981509
ctrl_transfer->context = (void *)transfer_done;
14991510

15001511
// Copy setup packet
@@ -1512,15 +1523,9 @@ static esp_err_t do_control_transfer(usb_host_client_handle_t client_hdl, usb_de
15121523
goto transfer_error;
15131524
}
15141525

1515-
// Wait for completion
1516-
//wait_for_transmission_done(ctrl_transfer);
1517-
if (xSemaphoreTake(transfer_done, portMAX_DELAY) != pdTRUE) {
1518-
ret = ESP_ERR_TIMEOUT; // should not happen, but just in case
1519-
goto transfer_error;
1520-
}
1521-
1522-
// Check transfer status
1523-
if (ctrl_transfer->status != USB_TRANSFER_STATUS_COMPLETED) {
1526+
// Wait for transfer to finish
1527+
const usb_transfer_status_t status_short_desc = wait_for_transmission_done(ctrl_transfer);
1528+
if (status_short_desc != USB_TRANSFER_STATUS_COMPLETED) {
15241529
ESP_LOGE(USB_HOST_TAG, "Control transfer failed, status=%d", ctrl_transfer->status);
15251530
ret = ESP_ERR_INVALID_STATE;
15261531
goto transfer_error;
@@ -1602,7 +1607,6 @@ static esp_err_t validate_device_remote_wakeup(usb_host_client_handle_t client_h
16021607
esp_err_t usb_host_device_remote_wakeup_enable(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, bool enable)
16031608
{
16041609
HOST_CHECK(client_hdl != NULL && dev_hdl != NULL, ESP_ERR_INVALID_ARG);
1605-
esp_err_t ret;
16061610
ESP_RETURN_ON_ERROR(validate_device_remote_wakeup(client_hdl, dev_hdl), USB_HOST_TAG, "Device remote wakeup validation failed");
16071611

16081612
usb_setup_packet_t setup_packet = {0};
@@ -1615,25 +1619,22 @@ esp_err_t usb_host_device_remote_wakeup_enable(usb_host_client_handle_t client_h
16151619
}
16161620

16171621
// Send ctrl transfer enabling/disabling the remote wakeup
1618-
ESP_RETURN_ON_ERROR(do_control_transfer(client_hdl, dev_hdl, &setup_packet, NULL, 0), USB_HOST_TAG, "CTRL transfer failed");
1622+
ESP_RETURN_ON_ERROR(remote_wake_do_control_transfer(client_hdl, dev_hdl, &setup_packet, NULL, 0), USB_HOST_TAG, "CTRL transfer failed");
16191623

16201624
return ESP_OK;
16211625
}
16221626

16231627
esp_err_t usb_host_device_remote_wakeup_check(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, bool *enabled)
16241628
{
1625-
HOST_CHECK(client_hdl != NULL && dev_hdl != NULL, ESP_ERR_INVALID_ARG);
1626-
esp_err_t ret;
1629+
HOST_CHECK(client_hdl != NULL && dev_hdl != NULL && enabled != NULL, ESP_ERR_INVALID_ARG);
16271630
ESP_RETURN_ON_ERROR(validate_device_remote_wakeup(client_hdl, dev_hdl), USB_HOST_TAG, "Device remote wakeup validation failed");
16281631

16291632
usb_setup_packet_t setup_packet = {0};
16301633
usb_device_status_t device_status;
16311634
USB_SETUP_PACKET_INIT_GET_STATUS(&setup_packet);
16321635

16331636
// Send ctrl transfer checking the remote wakeup
1634-
ESP_RETURN_ON_ERROR(
1635-
do_control_transfer(client_hdl, dev_hdl, &setup_packet, &device_status, sizeof(device_status)),
1636-
USB_HOST_TAG, "CTRL transfer failed");
1637+
ESP_RETURN_ON_ERROR(remote_wake_do_control_transfer(client_hdl, dev_hdl, &setup_packet, &device_status, sizeof(device_status)), USB_HOST_TAG, "CTRL transfer failed");
16371638

16381639
// Check current status of remote wakeup
16391640
*enabled = device_status.remote_wakeup;
@@ -2063,7 +2064,7 @@ esp_err_t usb_host_transfer_submit_control(usb_host_client_handle_t client_hdl,
20632064
// Check if the root port is suspended (global suspend)
20642065
if (hub_root_is_suspended()) {
20652066
// Root port is suspended at the time we are submitting a ctrl transfer
2066-
ESP_LOGD(USB_HOST_TAG, "Resuming the root port");
2067+
ESP_LOGI(USB_HOST_TAG, "Resuming the root port");
20672068

20682069
ret = usb_host_lib_root_port_resume();
20692070
if (ret != ESP_OK) {

host/usb/test/target_test/usb_host/main/test_usb_host_async.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,12 +702,19 @@ TEST_CASE("Test USB Host remote wakeup setup", "[usb_host][low_speed][full_speed
702702

703703
printf("Remote wake enabled\n");
704704
usb_host_lib_root_port_suspend();
705-
vTaskDelay(1000);
705+
vTaskDelay(pdMS_TO_TICKS(5000));
706+
// usb_host_lib_root_port_resume();
706707

707-
// // Disable remote wakeup on the device
708-
// test_remote_wake_disable();
708+
709+
// // Read the current remote wakeup state from the device, expect it to be enabled from the previous operation
710+
// test_remote_wake_check(true);
709711
// TEST_ASSERT_EQUAL_MESSAGE(
710-
// pdTRUE, xSemaphoreTake(dev_ready_smp, TEST_REMOTE_WAKE_SMP_WAIT_MS), "Remote wake not disabled on time");
712+
// pdTRUE, xSemaphoreTake(dev_ready_smp, TEST_REMOTE_WAKE_SMP_WAIT_MS), "Remote wake not checked on time");
713+
714+
// Disable remote wakeup on the device
715+
test_remote_wake_disable();
716+
TEST_ASSERT_EQUAL_MESSAGE(
717+
pdTRUE, xSemaphoreTake(dev_ready_smp, TEST_REMOTE_WAKE_SMP_WAIT_MS), "Remote wake not disabled on time");
711718
//
712719
// // Read the current remote wakeup state from the device, expect it to be disabled from the previous operation
713720
// test_remote_wake_check(false);

0 commit comments

Comments
 (0)