@@ -842,10 +842,35 @@ static void out_xfer_cb(usb_transfer_t *transfer)
842842 xSemaphoreGive ((SemaphoreHandle_t )transfer -> context );
843843}
844844
845+ /**
846+ * @brief Resume CDC device
847+ *
848+ * Submit poll for BULK IN and INTR IN transfers
849+ *
850+ * @param cdc_dev
851+ * @return esp_err_t
852+ */
853+ #ifdef CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
854+ static void cdc_acm_resume (cdc_dev_t * cdc_dev )
855+ {
856+ assert (cdc_dev );
857+
858+ if (cdc_dev -> data .in_xfer ) {
859+ ESP_LOGD (TAG , "Submitting poll for BULK IN transfer" );
860+ ESP_ERROR_CHECK (usb_host_transfer_submit (cdc_dev -> data .in_xfer ));
861+ }
862+
863+ if (cdc_dev -> notif .xfer ) {
864+ ESP_LOGD (TAG , "Submitting poll for INTR IN transfer" );
865+ ESP_ERROR_CHECK (usb_host_transfer_submit (cdc_dev -> notif .xfer ));
866+ }
867+ }
868+ #endif // CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
869+
845870static void usb_event_cb (const usb_host_client_event_msg_t * event_msg , void * arg )
846871{
847872 switch (event_msg -> event ) {
848- case USB_HOST_CLIENT_EVENT_NEW_DEV :
873+ case USB_HOST_CLIENT_EVENT_NEW_DEV : {
849874 // Guard p_cdc_acm_obj->new_dev_cb from concurrent access
850875 ESP_LOGD (TAG , "New device connected" );
851876 CDC_ACM_ENTER_CRITICAL ();
@@ -861,8 +886,8 @@ static void usb_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg
861886 _new_dev_cb (new_dev );
862887 usb_host_device_close (p_cdc_acm_obj -> cdc_acm_client_hdl , new_dev );
863888 }
864-
865889 break ;
890+ }
866891 case USB_HOST_CLIENT_EVENT_DEV_GONE : {
867892 ESP_LOGD (TAG , "Device suddenly disconnected" );
868893 // Find CDC pseudo-devices associated with this USB device and close them
@@ -881,7 +906,54 @@ static void usb_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg
881906 }
882907 break ;
883908 }
909+ #ifdef CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
910+ case USB_HOST_CLIENT_EVENT_DEV_SUSPENDED : {
911+ ESP_LOGD (TAG , "Device suspended" );
912+ // Find CDC pseudo-devices associated with this USB device and deliver suspend event to the user
913+ cdc_dev_t * cdc_dev ;
914+ cdc_dev_t * tcdc_dev ;
915+ SLIST_FOREACH_SAFE (cdc_dev , & p_cdc_acm_obj -> cdc_devices_list , list_entry , tcdc_dev ) {
916+ if (cdc_dev -> dev_hdl == event_msg -> dev_suspend_resume .dev_hdl && cdc_dev -> notif .cb ) {
917+
918+ // The driver does not have to do anything to suspend the device,
919+ // the usb host lib already halted and flushed all EPs
920+
921+ // The suspended device was opened by this driver: inform user about this
922+ const cdc_acm_host_dev_event_data_t suspend_event = {
923+ .type = CDC_ACM_HOST_DEVICE_SUSPENDED ,
924+ .data .cdc_hdl = (cdc_acm_dev_hdl_t ) cdc_dev ,
925+ };
926+ cdc_dev -> notif .cb (& suspend_event , cdc_dev -> cb_arg );
927+ }
928+ }
929+ break ;
930+ }
931+ case USB_HOST_CLIENT_EVENT_DEV_RESUMED : {
932+ ESP_LOGD (TAG , "Device resumed" );
933+ // Find CDC pseudo-devices associated with this USB device and deliver resume event to the user
934+ cdc_dev_t * cdc_dev ;
935+ cdc_dev_t * tcdc_dev ;
936+ SLIST_FOREACH_SAFE (cdc_dev , & p_cdc_acm_obj -> cdc_devices_list , list_entry , tcdc_dev ) {
937+ if (cdc_dev -> dev_hdl == event_msg -> dev_suspend_resume .dev_hdl ) {
938+
939+ // Resume the pseudo-device
940+ cdc_acm_resume (cdc_dev );
941+
942+ if (cdc_dev -> notif .cb != NULL ) {
943+ // The resumed device was opened by this driver: inform user about this
944+ const cdc_acm_host_dev_event_data_t resume_event = {
945+ .type = CDC_ACM_HOST_DEVICE_RESUMED ,
946+ .data .cdc_hdl = (cdc_acm_dev_hdl_t ) cdc_dev ,
947+ };
948+ cdc_dev -> notif .cb (& resume_event , cdc_dev -> cb_arg );
949+ }
950+ }
951+ }
952+ break ;
953+ }
954+ #endif // CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
884955 default :
956+ ESP_LOGE (TAG , "Unrecognized USB Host client event" );
885957 assert (false);
886958 break ;
887959 }
0 commit comments