Skip to content

Commit 042aa83

Browse files
feat(cdc_acm_host): Add global suspend/resume
1 parent 8899063 commit 042aa83

File tree

5 files changed

+452
-7
lines changed

5 files changed

+452
-7
lines changed

host/class/cdc/usb_host_cdc_acm/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## [unreleased]
2+
3+
- Added global suspend/resume support
4+
15
## 2.1.0
26

37
- Added option to implement custom CDC-ACM like devices with C API

host/class/cdc/usb_host_cdc_acm/cdc_acm_host.c

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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_LOGI(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_LOGI(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+
845870
static 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,50 @@ 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_gone.dev_hdl && cdc_dev->notif.cb) {
917+
// The suspended device was opened by this driver: inform user about this
918+
const cdc_acm_host_dev_event_data_t disconn_event = {
919+
.type = CDC_ACM_HOST_DEVICE_SUSPENDED,
920+
.data.cdc_hdl = (cdc_acm_dev_hdl_t) cdc_dev,
921+
};
922+
cdc_dev->notif.cb(&disconn_event, cdc_dev->cb_arg);
923+
}
924+
}
925+
break;
926+
}
927+
case USB_HOST_CLIENT_EVENT_DEV_RESUMED: {
928+
ESP_LOGD(TAG, "Device resumed");
929+
// Find CDC pseudo-devices associated with this USB device and deliver resume event to the user
930+
cdc_dev_t *cdc_dev;
931+
cdc_dev_t *tcdc_dev;
932+
SLIST_FOREACH_SAFE(cdc_dev, &p_cdc_acm_obj->cdc_devices_list, list_entry, tcdc_dev) {
933+
if (cdc_dev->dev_hdl == event_msg->dev_gone.dev_hdl) {
934+
935+
// Resume the pseudo-device
936+
cdc_acm_resume(cdc_dev);
937+
938+
if (cdc_dev->notif.cb != NULL) {
939+
// The resumed device was opened by this driver: inform user about this
940+
const cdc_acm_host_dev_event_data_t disconn_event = {
941+
.type = CDC_ACM_HOST_DEVICE_RESUMED,
942+
.data.cdc_hdl = (cdc_acm_dev_hdl_t) cdc_dev,
943+
};
944+
cdc_dev->notif.cb(&disconn_event, cdc_dev->cb_arg);
945+
}
946+
}
947+
}
948+
break;
949+
}
950+
#endif // CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
884951
default:
952+
ESP_LOGE(TAG, "Unrecognized USB Host client event");
885953
assert(false);
886954
break;
887955
}

host/class/cdc/usb_host_cdc_acm/include/usb/cdc_acm_host.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#define CDC_HOST_ANY_VID (0)
1818
#define CDC_HOST_ANY_PID (0)
1919

20+
#ifdef USB_HOST_LIB_EVENT_FLAGS_AUTO_SUSPEND
21+
#define CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
22+
#endif
23+
2024
#ifdef __cplusplus
2125
extern "C" {
2226
#endif

host/class/cdc/usb_host_cdc_acm/include/usb/cdc_host_types.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,26 @@
99
#include <stdint.h>
1010
#include <stdbool.h>
1111
#include "usb/usb_types_cdc.h"
12+
#include "usb/usb_host.h" // For USB Host suspend/resume API
1213

1314
typedef struct cdc_dev_s *cdc_acm_dev_hdl_t;
1415

16+
#ifdef USB_HOST_LIB_EVENT_FLAGS_AUTO_SUSPEND
17+
#define CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
18+
#endif
19+
1520
/**
1621
* @brief CDC-ACM Device Event types to upper layer
1722
*/
1823
typedef enum {
1924
CDC_ACM_HOST_ERROR,
2025
CDC_ACM_HOST_SERIAL_STATE,
2126
CDC_ACM_HOST_NETWORK_CONNECTION,
22-
CDC_ACM_HOST_DEVICE_DISCONNECTED
27+
CDC_ACM_HOST_DEVICE_DISCONNECTED,
28+
#ifdef CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
29+
CDC_ACM_HOST_DEVICE_SUSPENDED,
30+
CDC_ACM_HOST_DEVICE_RESUMED,
31+
#endif // CDC_HOST_SUSPEND_RESUME_API_SUPPORTED
2332
} cdc_acm_host_dev_event_t;
2433

2534
/**

0 commit comments

Comments
 (0)