@@ -40,15 +40,26 @@ typedef struct usb_host_client_handle_s *usb_host_client_handle_t;
4040
4141#define USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS 0x01 /**< All clients have been deregistered from the USB Host Library */
4242#define USB_HOST_LIB_EVENT_FLAGS_ALL_FREE 0x02 /**< The USB Host Library has freed all devices */
43+ #define USB_HOST_LIB_EVENT_FLAGS_AUTO_SUSPEND 0x04 /**< Timer for automatic suspend has expired */
4344
4445/**
4546 * @brief The type event in a client event message
4647 */
4748typedef enum {
4849 USB_HOST_CLIENT_EVENT_NEW_DEV , /**< A new device has been enumerated and added to the USB Host Library */
4950 USB_HOST_CLIENT_EVENT_DEV_GONE , /**< A device opened by the client is now gone */
51+ USB_HOST_CLIENT_EVENT_DEV_SUSPENDED , /**< A device opened by the client is now suspended */
52+ USB_HOST_CLIENT_EVENT_DEV_RESUMED , /**< A device opened by the client is now resumed */
5053} usb_host_client_event_t ;
5154
55+ /**
56+ * @brief USB Host lib power management timer type
57+ */
58+ typedef enum {
59+ USB_HOST_LIB_PM_SUSPEND_ONE_SHOT , /**< USB Host lib power management -> Auto suspend one-shot timer */
60+ USB_HOST_LIB_PM_SUSPEND_PERIODIC , /**< USB Host lib power management -> Auto suspend periodic timer */
61+ } usb_host_lib_pm_t ;
62+
5263/**
5364 * @brief Client event message
5465 *
@@ -69,6 +80,9 @@ typedef struct {
6980 struct {
7081 usb_device_handle_t dev_hdl ; /**< The handle of the device that was gone */
7182 } dev_gone ; /**< Gone device info */
83+ struct {
84+ usb_device_handle_t dev_hdl ; /**< The handle of the device that was suspended/resumed */
85+ } dev_suspend_resume ; /**< Suspend/Resume device info */
7286 };
7387} usb_host_client_event_msg_t ;
7488
@@ -78,8 +92,9 @@ typedef struct {
7892 * @brief Current information about the USB Host Library obtained via usb_host_lib_info()
7993 */
8094typedef struct {
81- int num_devices ; /**< Current number of connected (and enumerated) devices */
82- int num_clients ; /**< Current number of registered clients */
95+ int num_devices ; /**< Current number of connected (and enumerated) devices */
96+ int num_clients ; /**< Current number of registered clients */
97+ bool root_port_suspended ; /**< Current status of the root port (suspended/resumed) */
8398} usb_host_lib_info_t ;
8499
85100// ---------------------- Callbacks ------------------------
@@ -243,6 +258,61 @@ esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret);
243258 */
244259esp_err_t usb_host_lib_set_root_port_power (bool enable );
245260
261+ /**
262+ * @brief Suspend the root port
263+ *
264+ * - The function checks, if a device is connected and if a transfer is submitted
265+ * - Then halts and flushes all endpoints of all the connected devices and suspends the root port
266+ * - Finally, it notifies all the clients which opened the device, that the device is now suspended
267+ *
268+ * @note Remote wakeup from device is not implemented yet
269+ * @note The root port and the devices are not suspended immediately after returning from this function, this function
270+ * only sets actions for devices and root port, which are handled by the usb_host_lib_handle_events() in separate task.
271+ * @return
272+ * - ESP_OK: Root port marked to be suspended, or already issuing a suspend sequence
273+ * - ESP_ERR_NOT_FOUND: No device is connected
274+ * - ESP_ERR_INVALID_STATE: Root port is not in correct state to be suspended
275+ */
276+ esp_err_t usb_host_lib_root_port_suspend (void );
277+
278+ /**
279+ * @brief Resume the root port from suspended state
280+ *
281+ * - The function resumes the root port from suspended state
282+ * - Then resumes all the endpoints of all the connected devices
283+ * - Finally, it notifies all the clients which opened the device, that the device is now resumed
284+ *
285+ * @note The root port and the devices are not resumed immediately after returning from this function, this function
286+ * only sets actions for devices and root port, which are handled by the usb_host_lib_handle_events() in separate task.
287+ * @return
288+ * - ESP_OK: Root port marked to be resumed, or already issuing a resume sequence
289+ * - ESP_ERR_NOT_FOUND: No device is connected
290+ * - ESP_ERR_INVALID_STATE: Root port is not in correct state to be resumed
291+ */
292+ esp_err_t usb_host_lib_root_port_resume (void );
293+
294+ /**
295+ * @brief Set auto power management timer
296+ *
297+ * - The function sets the auto suspend timer, used for global suspend of the root port
298+ * - The timer is either one-shot or periodic
299+ * - The timerexpires after the set period, only if there is no activity on the USB Bus
300+ * - The timer resets (if enabled) every time, the usb_host_client_handle_events() handles any client events,
301+ * or the usb_host_lib_handle_events() handles any host lib events, thus checking any activity on all the
302+ * registered clients or inside the host lib
303+ * - Once the timer expires, an auto_pm_timer_cb() is called, which delivers USB Host lib event flags
304+ *
305+ * @note set the timer interval to 0, to disable the timer (in case NO auto suspend functionality is required anymore)
306+ * @note this function is not ISR safe
307+ * @param[in] timer_type Power management timer type (periodic/one-shot)
308+ * @param[in] timer_interval_ms Interval after which a usb_host lib event flag is delivered (0 to disable running timer)
309+ * @return
310+ * - ESP_OK: Timer set or stopped
311+ * - ESP_ERR_INVALID_STATE: USB Host lib is not installed
312+ * - ESP_FAIL: Timer was not configured correctly
313+ */
314+ esp_err_t usb_host_lib_set_auto_pm (usb_host_lib_pm_t timer_type , size_t timer_interval_ms );
315+
246316// ------------------------------------------------ Client Functions ---------------------------------------------------
247317
248318/**
@@ -628,7 +698,7 @@ esp_err_t usb_host_transfer_free(usb_transfer_t *transfer);
628698 * - ESP_ERR_INVALID_ARG: Invalid argument
629699 * - ESP_ERR_NOT_FINISHED: Transfer already in-flight
630700 * - ESP_ERR_NOT_FOUND: Endpoint address not found
631- * - ESP_ERR_INVALID_STATE: Endpoint pipe is not in a correct state to submit transfer
701+ * - ESP_ERR_INVALID_STATE: Endpoint pipe or root port is not in a correct state to submit transfer, or to resume the root port
632702 */
633703esp_err_t usb_host_transfer_submit (usb_transfer_t * transfer );
634704
@@ -647,8 +717,7 @@ esp_err_t usb_host_transfer_submit(usb_transfer_t *transfer);
647717 * - ESP_OK: Control transfer submitted successfully
648718 * - ESP_ERR_INVALID_ARG: Invalid argument
649719 * - ESP_ERR_NOT_FINISHED: Transfer already in-flight
650- * - ESP_ERR_NOT_FOUND: Endpoint address not found
651- * - ESP_ERR_INVALID_STATE: Endpoint pipe is not in a correct state to submit transfer
720+ * - ESP_ERR_INVALID_STATE: Endpoint pipe or root port is not in a correct state to submit transfer, or to resume the root port
652721 */
653722esp_err_t usb_host_transfer_submit_control (usb_host_client_handle_t client_hdl , usb_transfer_t * transfer );
654723
0 commit comments