@@ -609,6 +609,11 @@ static esp_err_t hid_host_resume_interface(hid_iface_t *iface, bool resume_ep)
609609 ESP_ERR_NOT_FOUND ,
610610 "Interface handle not found" );
611611
612+ if (HID_INTERFACE_STATE_ACTIVE == iface -> state ) {
613+ // Interface already auto-resumed by hid_host_device_start(), return early and continue to resume event delivery
614+ return ESP_OK ;
615+ }
616+
612617 HID_RETURN_ON_FALSE ((HID_INTERFACE_STATE_SUSPENDED == iface -> state ),
613618 ESP_ERR_INVALID_STATE ,
614619 "Interface wrong state" );
@@ -618,14 +623,19 @@ static esp_err_t hid_host_resume_interface(hid_iface_t *iface, bool resume_ep)
618623 usb_host_endpoint_clear (iface -> parent -> dev_hdl , iface -> ep_in );
619624 }
620625
626+ // Use the last device state before the device went to suspended state as the current state
621627 iface -> state = iface -> last_state ;
622628
623629 if (iface -> in_xfer == NULL ) {
624630 return ESP_OK ;
625631 }
626632
627- // start data transfer
628- HID_RETURN_ON_ERROR ( usb_host_transfer_submit (iface -> in_xfer ), "Unable to start data transfer" );
633+ // If the last state before the device went to suspended state was active state, start the data transfer
634+ if (iface -> last_state == HID_INTERFACE_STATE_ACTIVE ) {
635+ // start data transfer
636+ HID_RETURN_ON_ERROR ( usb_host_transfer_submit (iface -> in_xfer ), "Unable to start data transfer" );
637+ }
638+
629639 return ESP_OK ;
630640}
631641
@@ -653,8 +663,15 @@ static esp_err_t hid_host_device_suspended(usb_device_handle_t dev_hdl)
653663 HID_EXIT_CRITICAL ();
654664
655665 if (hid_iface_curr -> parent && (hid_iface_curr -> parent -> dev_addr == hid_device -> dev_addr )) {
656- hid_host_suspend_interface (hid_iface_curr , false);
657- hid_host_user_interface_callback (hid_iface_curr , HID_HOST_INTERFACE_EVENT_SUSPENDED );
666+ esp_err_t ret = hid_host_suspend_interface (hid_iface_curr , false);
667+
668+ // Make sure the device is connected and the interface is found otherwise don't deliver suspend event
669+ if (ret != ESP_ERR_NOT_FOUND ) {
670+
671+ // We will deliver the suspend event, if the hid_host_suspend_interface fails with other errors,
672+ // as the usb_host_lib has already suspended the root port anyway
673+ hid_host_user_interface_callback (hid_iface_curr , HID_HOST_INTERFACE_EVENT_SUSPENDED );
674+ }
658675 }
659676 HID_ENTER_CRITICAL ();
660677 hid_iface_curr = hid_iface_next ;
@@ -688,8 +705,15 @@ static esp_err_t hid_host_device_resumed(usb_device_handle_t dev_hdl)
688705 HID_EXIT_CRITICAL ();
689706
690707 if (hid_iface_curr -> parent && (hid_iface_curr -> parent -> dev_addr == hid_device -> dev_addr )) {
691- hid_host_resume_interface (hid_iface_curr , false);
692- hid_host_user_interface_callback (hid_iface_curr , HID_HOST_INTERFACE_EVENT_RESUMED );
708+ esp_err_t ret = hid_host_resume_interface (hid_iface_curr , false);
709+
710+ // Make sure the device is connected and the interface is found otherwise don't deliver resume event
711+ if (ret != ESP_ERR_NOT_FOUND ) {
712+
713+ // We will deliver the resume event, if the hid_host_resume_interface fails with other errors,
714+ // as the usb_host_lib has already resumed the root port anyway
715+ hid_host_user_interface_callback (hid_iface_curr , HID_HOST_INTERFACE_EVENT_RESUMED );
716+ }
693717 }
694718 HID_ENTER_CRITICAL ();
695719 hid_iface_curr = hid_iface_next ;
@@ -1487,7 +1511,7 @@ esp_err_t hid_host_device_start(hid_host_device_handle_t hid_dev_handle)
14871511 ESP_ERR_NOT_FOUND ,
14881512 "Interface handle not found" );
14891513
1490- HID_RETURN_ON_FALSE ((HID_INTERFACE_STATE_READY == iface -> state ),
1514+ HID_RETURN_ON_FALSE ((HID_INTERFACE_STATE_READY == iface -> state || HID_INTERFACE_STATE_SUSPENDED == iface -> state ),
14911515 ESP_ERR_INVALID_STATE ,
14921516 "Interface wrong state" );
14931517
@@ -1511,6 +1535,15 @@ esp_err_t hid_host_device_stop(hid_host_device_handle_t hid_dev_handle)
15111535
15121536 HID_RETURN_ON_INVALID_ARG (iface );
15131537
1538+ HID_RETURN_ON_FALSE (is_interface_in_list (iface ), ESP_ERR_NOT_FOUND , "Interface handle not found" );
1539+
1540+ if (iface -> state == HID_INTERFACE_STATE_SUSPENDED ) {
1541+ // If interface is suspended, mark the last state as READY,
1542+ // as if the interface was stopped before entering suspended state
1543+ iface -> last_state = HID_INTERFACE_STATE_READY ;
1544+ return ESP_OK ;
1545+ }
1546+
15141547 return hid_host_disable_interface (iface );
15151548}
15161549
0 commit comments