@@ -173,7 +173,7 @@ TEST_CASE("Test HCD port suspend and resume", "[port][low_speed][full_speed][hig
173173 TEST_ASSERT_EQUAL (ESP_OK , hcd_port_command (port_hdl , HCD_PORT_CMD_SUSPEND ));
174174 TEST_ASSERT_EQUAL (HCD_PORT_STATE_SUSPENDED , hcd_port_get_state (port_hdl ));
175175 printf ("Suspended\n" );
176- vTaskDelay (pdMS_TO_TICKS (100 )); // Give some time for bus to remain suspended
176+ vTaskDelay (pdMS_TO_TICKS (5000 )); // Give some time for bus to remain suspended
177177
178178 // Resume the port
179179 TEST_ASSERT_EQUAL (ESP_OK , hcd_port_command (port_hdl , HCD_PORT_CMD_RESUME ));
@@ -392,3 +392,96 @@ TEST_CASE("Test HCD port command bailout", "[port][low_speed][full_speed][high_s
392392 vTaskDelete (task_handle );
393393 vSemaphoreDelete (sync_sem );
394394}
395+
396+ bool test_hcd_check_remote_wake (hcd_pipe_handle_t * pipe , urb_t * get_status_urb )
397+ {
398+ // Initialize with a "Get status request" USB_SETUP_PACKET_INIT_GET_STATUS
399+ get_status_urb -> transfer .num_bytes = sizeof (usb_setup_packet_t ) + sizeof (usb_device_status_t );
400+ USB_SETUP_PACKET_INIT_GET_STATUS ((usb_setup_packet_t * )get_status_urb -> transfer .data_buffer );
401+ get_status_urb -> transfer .context = URB_CONTEXT_VAL ;
402+
403+ TEST_ASSERT_EQUAL (ESP_OK , hcd_urb_enqueue (pipe , get_status_urb ));
404+ test_hcd_expect_pipe_event (pipe , HCD_PIPE_EVENT_URB_DONE );
405+ urb_t * urb = hcd_urb_dequeue (pipe );
406+ TEST_ASSERT_EQUAL (get_status_urb , urb );
407+ TEST_ASSERT_EQUAL_MESSAGE (USB_TRANSFER_STATUS_COMPLETED , urb -> transfer .status , "Transfer NOT completed" );
408+ TEST_ASSERT_EQUAL (URB_CONTEXT_VAL , urb -> transfer .context );
409+
410+ TEST_ASSERT_EQUAL (sizeof (usb_setup_packet_t ) + sizeof (usb_device_status_t ), urb -> transfer .actual_num_bytes );
411+ TEST_ASSERT_EQUAL (urb -> transfer .num_bytes , urb -> transfer .actual_num_bytes );
412+ usb_device_status_t * device_status = (usb_device_status_t * )(urb -> transfer .data_buffer + sizeof (usb_setup_packet_t ));
413+
414+ const bool enabled = device_status -> remote_wakeup ;
415+ printf ("Remote wakeup is currently %s\n" , ((enabled )) ? ("enabled" ) : ("disabled" ) );
416+ return enabled ;
417+ }
418+
419+ void test_hcd_set_remote_wake (hcd_pipe_handle_t * pipe , urb_t * set_feature_urb )
420+ {
421+ set_feature_urb -> transfer .num_bytes = sizeof (usb_setup_packet_t );
422+ USB_SETUP_PACKET_INIT_SET_FEATURE ((usb_setup_packet_t * )set_feature_urb -> transfer .data_buffer , DEVICE_REMOTE_WAKEUP );
423+ set_feature_urb -> transfer .context = URB_CONTEXT_VAL ;
424+
425+
426+ TEST_ASSERT_EQUAL (ESP_OK , hcd_urb_enqueue (pipe , set_feature_urb ));
427+ test_hcd_expect_pipe_event (pipe , HCD_PIPE_EVENT_URB_DONE );
428+ urb_t * urb = hcd_urb_dequeue (pipe );
429+ TEST_ASSERT_EQUAL (set_feature_urb , urb );
430+ TEST_ASSERT_EQUAL_MESSAGE (USB_TRANSFER_STATUS_COMPLETED , urb -> transfer .status , "Transfer NOT completed" );
431+ TEST_ASSERT_EQUAL (URB_CONTEXT_VAL , urb -> transfer .context );
432+
433+ TEST_ASSERT_EQUAL (sizeof (usb_setup_packet_t ), urb -> transfer .actual_num_bytes );
434+ TEST_ASSERT_EQUAL (urb -> transfer .num_bytes , urb -> transfer .actual_num_bytes );
435+ }
436+ #define TEST_HID_DEV_SPEED USB_SPEED_LOW
437+ TEST_CASE ("Test HCD port remote wakeup" , "[port][low_speed][full_speed][high_speed]" )
438+ {
439+ usb_speed_t port_speed = test_hcd_wait_for_conn (port_hdl ); // Trigger a connection
440+ TEST_ASSERT_EQUAL_MESSAGE (TEST_HID_DEV_SPEED , port_speed , "Connected device is not Low Speed!" );
441+ vTaskDelay (pdMS_TO_TICKS (100 )); // Short delay send of SOF (for FS) or EOPs (for LS)
442+
443+ hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc (port_hdl , NULL , 0 , port_speed ); // Create a default pipe (using a NULL EP descriptor)
444+ uint8_t dev_addr = test_hcd_enum_device (default_pipe );
445+
446+ urb_t * get_status_urb = test_hcd_alloc_urb (0 , URB_DATA_BUFF_SIZE );
447+ urb_t * set_feature_urb = test_hcd_alloc_urb (0 , URB_DATA_BUFF_SIZE );
448+
449+ test_hcd_check_remote_wake (default_pipe , get_status_urb );
450+ test_hcd_set_remote_wake (default_pipe , set_feature_urb );
451+ test_hcd_check_remote_wake (default_pipe , get_status_urb );
452+
453+ // Halt the default pipe before suspending
454+ TEST_ASSERT_EQUAL (HCD_PIPE_STATE_ACTIVE , hcd_pipe_get_state (default_pipe ));
455+ TEST_ASSERT_EQUAL (ESP_OK , hcd_pipe_command (default_pipe , HCD_PIPE_CMD_HALT ));
456+ TEST_ASSERT_EQUAL (HCD_PIPE_STATE_HALTED , hcd_pipe_get_state (default_pipe ));
457+
458+ // Suspend the port
459+ TEST_ASSERT_EQUAL (ESP_OK , hcd_port_command (port_hdl , HCD_PORT_CMD_SUSPEND ));
460+ TEST_ASSERT_EQUAL (HCD_PORT_STATE_SUSPENDED , hcd_port_get_state (port_hdl ));
461+ printf ("Suspended\n" );
462+ test_hcd_expect_port_event (port_hdl , HCD_PORT_EVENT_REMOTE_WAKEUP );
463+ TEST_ASSERT_EQUAL (HCD_PORT_EVENT_REMOTE_WAKEUP , hcd_port_handle_event (port_hdl ));
464+ //printf("Waken\n");
465+
466+ // Resume the port
467+ TEST_ASSERT_EQUAL (ESP_OK , hcd_port_command (port_hdl , HCD_PORT_CMD_RESUME ));
468+ TEST_ASSERT_EQUAL (HCD_PORT_STATE_ENABLED , hcd_port_get_state (port_hdl ));
469+ printf ("Resumed\n" );
470+
471+ vTaskDelay (pdMS_TO_TICKS (5000 ));
472+
473+ TEST_ASSERT_EQUAL (HCD_PIPE_STATE_HALTED , hcd_pipe_get_state (default_pipe ));
474+ TEST_ASSERT_EQUAL (ESP_OK , hcd_pipe_command (default_pipe , HCD_PIPE_CMD_CLEAR ));
475+ TEST_ASSERT_EQUAL (HCD_PIPE_STATE_ACTIVE , hcd_pipe_get_state (default_pipe ));
476+
477+
478+
479+ printf ("Issue check\n" );
480+ test_hcd_check_remote_wake (default_pipe , get_status_urb );
481+
482+ test_hcd_pipe_free (default_pipe );
483+ test_hcd_free_urb (get_status_urb );
484+ test_hcd_free_urb (set_feature_urb );
485+ // Cleanup
486+ test_hcd_wait_for_disconn (port_hdl , false);
487+ }
0 commit comments