Skip to content

Commit a602bef

Browse files
Dazza0espressif-bot
authored andcommitted
refactor(usb/usbh): Update USBH device creation and enumeration handling
This commit updates how the USBH handles device creation and enumeration so that upper layers (such as the Hub driver) can use the USBH API for enumeration instead of calling the HCD. USBH Updates: USBH now creates unenumerated devices set to address 0 with no device/config descriptor. A newly created device can be opened and communicated with immediately (using control transfers). This allows the Hub driver to call the USBH instead of the HCD. Summary of USBH changes: - Added new APIs to add/remove a device. Devices are now created as unenumerated and can be immediately opened and communicated with. - Added new APIs to enumerate a device (see 'usbh_dev_set_...()' functions). Device must be locked (see 'usbh_dev_enum_lock()') before enumeration functions can be called. - Added UID for each device. This allows the particular USBH without needing to use the device's handle (which implies opening the device). Hub Driver Updates: Hub driver now calls the USBH for enumeration. Summary of USBH changes: - Replace all 'hcd_pipe_...()' calls with 'usbh_dev_...()' calls - Refactored port event handling to fit with new USBH API - Updated to use UID to uniquely identify devices without opening them USB Host Updates: - Reroute USBH control transfers to clients and hub driver
1 parent df6c6f9 commit a602bef

File tree

7 files changed

+767
-521
lines changed

7 files changed

+767
-521
lines changed

components/usb/hcd_dwc.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,20 +1983,6 @@ esp_err_t hcd_pipe_update_dev_addr(hcd_pipe_handle_t pipe_hdl, uint8_t dev_addr)
19831983
return ESP_OK;
19841984
}
19851985

1986-
esp_err_t hcd_pipe_update_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_callback_t callback, void *user_arg)
1987-
{
1988-
pipe_t *pipe = (pipe_t *)pipe_hdl;
1989-
HCD_ENTER_CRITICAL();
1990-
// Check if pipe is in the correct state to be updated
1991-
HCD_CHECK_FROM_CRIT(!pipe->cs_flags.pipe_cmd_processing &&
1992-
!pipe->cs_flags.has_urb,
1993-
ESP_ERR_INVALID_STATE);
1994-
pipe->callback = callback;
1995-
pipe->callback_arg = user_arg;
1996-
HCD_EXIT_CRITICAL();
1997-
return ESP_OK;
1998-
}
1999-
20001986
void *hcd_pipe_get_context(hcd_pipe_handle_t pipe_hdl)
20011987
{
20021988
pipe_t *pipe = (pipe_t *)pipe_hdl;

components/usb/hub.c

Lines changed: 105 additions & 125 deletions
Large diffs are not rendered by default.

components/usb/private_include/hcd.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -418,22 +418,6 @@ esp_err_t hcd_pipe_update_mps(hcd_pipe_handle_t pipe_hdl, int mps);
418418
*/
419419
esp_err_t hcd_pipe_update_dev_addr(hcd_pipe_handle_t pipe_hdl, uint8_t dev_addr);
420420

421-
/**
422-
* @brief Update a pipe's callback
423-
*
424-
* This function is intended to be called on default pipes at the end of enumeration to switch to a callback that
425-
* handles the completion of regular control transfer.
426-
* - Pipe is not current processing a command
427-
* - Pipe does not have any enqueued URBs
428-
* - Port cannot be resetting
429-
*
430-
* @param pipe_hdl Pipe handle
431-
* @param callback Callback
432-
* @param user_arg Callback argument
433-
* @return esp_err_t
434-
*/
435-
esp_err_t hcd_pipe_update_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_callback_t callback, void *user_arg);
436-
437421
/**
438422
* @brief Get the context variable of a pipe from its handle
439423
*

components/usb/private_include/hub.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ typedef struct {
4242
* - Initializes the HCD root port
4343
*
4444
* @param[in] hub_config Hub driver configuration
45+
* @param[out] client_ret Unique pointer to identify the Hub as a USB Host client
4546
* @return esp_err_t
4647
*/
47-
esp_err_t hub_install(hub_config_t *hub_config);
48+
esp_err_t hub_install(hub_config_t *hub_config, void **client_ret);
4849

4950
/**
5051
* @brief Uninstall Hub driver
@@ -78,15 +79,16 @@ esp_err_t hub_root_start(void);
7879
esp_err_t hub_root_stop(void);
7980

8081
/**
81-
* @brief Indicate to the Hub driver that a device has been freed
82+
* @brief Indicate to the Hub driver that a device's port can be recycled
8283
*
83-
* Hub driver can now recover the port that the device was connected to
84+
* The device connected to the port has been freed. The Hub driver can now
85+
* recycled the port.
8486
*
85-
* @param dev_addr Device address
87+
* @param dev_uid Device's unique ID
8688
* @return
8789
* - ESP_OK: Success
8890
*/
89-
esp_err_t hub_dev_is_free(uint8_t dev_addr);
91+
esp_err_t hub_port_recycle(unsigned int dev_uid);
9092

9193
/**
9294
* @brief Hub driver's processing function

components/usb/private_include/usbh.h

Lines changed: 138 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ typedef struct {
5858
usb_device_handle_t dev_hdl;
5959
} dev_gone_data;
6060
struct {
61-
uint8_t dev_addr;
61+
unsigned int dev_uid;
6262
} dev_free_data;
6363
};
6464
} usbh_event_data_t;
@@ -195,6 +195,32 @@ esp_err_t usbh_devs_num(int *num_devs_ret);
195195
*/
196196
esp_err_t usbh_devs_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret);
197197

198+
/**
199+
* @brief Create a device and add it to the device pool
200+
*
201+
* The created device will not be enumerated where the device's address is 0,
202+
* device and config descriptor are NULL. The device will still have a default
203+
* pipe, thus allowing control transfers to be submitted.
204+
*
205+
* - Call usbh_devs_open() before communicating with the device
206+
* - Call usbh_dev_enum_lock() before enumerating the device via the various
207+
* usbh_dev_set_...() functions.
208+
*
209+
* @param[in] uid Unique ID assigned to the device
210+
* @param[in] dev_speed Device's speed
211+
* @param[in] port_hdl Handle of the port that the device is connected to
212+
* @return esp_err_t
213+
*/
214+
esp_err_t usbh_devs_add(unsigned int uid, usb_speed_t dev_speed, hcd_port_handle_t port_hdl);
215+
216+
/**
217+
* @brief Indicates to the USBH that a device is gone
218+
*
219+
* @param[in] uid Unique ID assigned to the device on creation (see 'usbh_devs_add()')
220+
* @return esp_err_t
221+
*/
222+
esp_err_t usbh_devs_remove(unsigned int uid);
223+
198224
/**
199225
* @brief Mark that all devices should be freed at the next possible opportunity
200226
*
@@ -227,6 +253,16 @@ esp_err_t usbh_devs_open(uint8_t dev_addr, usb_device_handle_t *dev_hdl);
227253
*/
228254
esp_err_t usbh_devs_close(usb_device_handle_t dev_hdl);
229255

256+
/**
257+
* @brief Trigger a USBH_EVENT_NEW_DEV event for the device
258+
*
259+
* This is typically called after a device has been fully enumerated.
260+
*
261+
* @param[in] dev_hdl Device handle
262+
* @return esp_err_t
263+
*/
264+
esp_err_t usbh_devs_new_dev_event(usb_device_handle_t dev_hdl);
265+
230266
// ------------------------------------------------ Device Functions ---------------------------------------------------
231267

232268
// ----------------------- Getters -------------------------
@@ -245,7 +281,8 @@ esp_err_t usbh_dev_get_addr(usb_device_handle_t dev_hdl, uint8_t *dev_addr);
245281
/**
246282
* @brief Get a device's information
247283
*
248-
* @note This function can block
284+
* @note It is possible that the device has not been enumerated yet, thus some
285+
* fields may be NULL.
249286
* @param[in] dev_hdl Device handle
250287
* @param[out] dev_info Device information
251288
* @return esp_err_t
@@ -257,6 +294,8 @@ esp_err_t usbh_dev_get_info(usb_device_handle_t dev_hdl, usb_device_info_t *dev_
257294
*
258295
* - The device descriptor is cached when the device is created by the Hub driver
259296
*
297+
* @note It is possible that the device has not been enumerated yet, thus the
298+
* device descriptor could be NULL.
260299
* @param[in] dev_hdl Device handle
261300
* @param[out] dev_desc_ret Device descriptor
262301
* @return esp_err_t
@@ -268,13 +307,109 @@ esp_err_t usbh_dev_get_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t
268307
*
269308
* Simply returns a reference to the internally cached configuration descriptor
270309
*
271-
* @note This function can block
310+
* @note It is possible that the device has not been enumerated yet, thus the
311+
* configuration descriptor could be NULL.
272312
* @param[in] dev_hdl Device handle
273313
* @param config_desc_ret
274314
* @return esp_err_t
275315
*/
276316
esp_err_t usbh_dev_get_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t **config_desc_ret);
277317

318+
// ----------------------- Setters -------------------------
319+
320+
/**
321+
* @brief Lock a device for enumeration
322+
*
323+
* - A device's enumeration lock must be set before any of its enumeration fields
324+
* (e.g., address, device/config descriptors) can be set/updated.
325+
* - The caller must be the sole opener of the device (see 'usbh_devs_open()')
326+
* when locking the device for enumeration.
327+
*
328+
* @param[in] dev_hdl Device handle
329+
* @return esp_err_t
330+
*/
331+
esp_err_t usbh_dev_enum_lock(usb_device_handle_t dev_hdl);
332+
333+
/**
334+
* @brief Release a device's enumeration lock
335+
*
336+
* @param[in] dev_hdl Device handle
337+
* @return esp_err_t
338+
*/
339+
esp_err_t usbh_dev_enum_unlock(usb_device_handle_t dev_hdl);
340+
341+
/**
342+
* @brief Set the maximum packet size of EP0 for a device
343+
*
344+
* Typically called during enumeration after obtaining the first 8 bytes of the
345+
* device's descriptor.
346+
*
347+
* @note The device's enumeration lock must be set before calling this function
348+
* (see 'usbh_dev_enum_lock()')
349+
* @param[in] dev_hdl Device handle
350+
* @param[in] wMaxPacketSize Maximum packet size
351+
* @return esp_err_t
352+
*/
353+
esp_err_t usbh_dev_set_ep0_mps(usb_device_handle_t dev_hdl, uint16_t wMaxPacketSize);
354+
355+
/**
356+
* @brief Set a device's address
357+
*
358+
* Typically called during enumeration after a SET_ADDRESSS request has be
359+
* sent to the device.
360+
*
361+
* @note The device's enumeration lock must be set before calling this function
362+
* (see 'usbh_dev_enum_lock()')
363+
* @param[in] dev_hdl Device handle
364+
* @param[in] dev_addr
365+
* @return esp_err_t
366+
*/
367+
esp_err_t usbh_dev_set_addr(usb_device_handle_t dev_hdl, uint8_t dev_addr);
368+
369+
/**
370+
* @brief Set a device's descriptor
371+
*
372+
* Typically called during enumeration after obtaining the device's descriptor
373+
* via a GET_DESCRIPTOR request.
374+
*
375+
* @note The device's enumeration lock must be set before calling this function
376+
* (see 'usbh_dev_enum_lock()')
377+
* @param[in] dev_hdl Device handle
378+
* @param[in] device_desc Device descriptor to copy
379+
* @return esp_err_t
380+
*/
381+
esp_err_t usbh_dev_set_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t *device_desc);
382+
383+
/**
384+
* @brief Set a device's configuration descriptor
385+
*
386+
* Typically called during enumeration after obtaining the device's configuration
387+
* descriptor via a GET_DESCRIPTOR request.
388+
*
389+
* @note The device's enumeration lock must be set before calling this function
390+
* (see 'usbh_dev_enum_lock()')
391+
* @param[in] dev_hdl Device handle
392+
* @param[in] config_desc_full Configuration descriptor to copy
393+
* @return esp_err_t
394+
*/
395+
esp_err_t usbh_dev_set_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc_full);
396+
397+
/**
398+
* @brief Set a device's string descriptor
399+
*
400+
* Typically called during enumeration after obtaining one of the device's string
401+
* descriptor via a GET_DESCRIPTOR request.
402+
*
403+
* @note The device's enumeration lock must be set before calling this function
404+
* (see 'usbh_dev_enum_lock()')
405+
* @param[in] dev_hdl Device handle
406+
* @param[in] str_desc String descriptor to copy
407+
* @param[in] select Select string descriptor. 0/1/2 for Manufacturer/Product/Serial
408+
* Number string descriptors respectively
409+
* @return esp_err_t
410+
*/
411+
esp_err_t usbh_dev_set_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select);
412+
278413
// ----------------------------------------------- Endpoint Functions -------------------------------------------------
279414

280415
/**
@@ -381,110 +516,6 @@ esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb);
381516
*/
382517
esp_err_t usbh_ep_dequeue_urb(usbh_ep_handle_t ep_hdl, urb_t **urb_ret);
383518

384-
// -------------------------------------------------- Hub Functions ----------------------------------------------------
385-
386-
// ------------------- Device Related ----------------------
387-
388-
/**
389-
* @brief Indicates to USBH the start of enumeration for a device
390-
*
391-
* - The Hub driver calls this function before it starts enumerating a new device.
392-
* - The USBH will allocate a new device that will be initialized by the Hub driver using the remaining hub enumeration
393-
* functions.
394-
* - The new device's default pipe handle is returned to all the Hub driver to be used during enumeration.
395-
*
396-
* @note Hub Driver only
397-
* @param[in] port_hdl Handle of the port that the device is connected to
398-
* @param[in] dev_speed Device's speed
399-
* @param[out] new_dev_hdl Device's handle
400-
* @param[out] default_pipe_hdl Device's default pipe handle
401-
* @return esp_err_t
402-
*/
403-
esp_err_t usbh_hub_add_dev(hcd_port_handle_t port_hdl, usb_speed_t dev_speed, usb_device_handle_t *new_dev_hdl, hcd_pipe_handle_t *default_pipe_hdl);
404-
405-
/**
406-
* @brief Indicates to the USBH that a device is gone
407-
*
408-
* @param dev_hdl Device handle
409-
* @return esp_err_t
410-
*/
411-
esp_err_t usbh_hub_dev_gone(usb_device_handle_t dev_hdl);
412-
413-
// ----------------- Enumeration Related -------------------
414-
415-
/**
416-
* @brief Assign the enumerating device's address
417-
*
418-
* @note Hub Driver only
419-
* @note Must call in sequence
420-
* @param[in] dev_hdl Device handle
421-
* @param dev_addr
422-
* @return esp_err_t
423-
*/
424-
esp_err_t usbh_hub_enum_fill_dev_addr(usb_device_handle_t dev_hdl, uint8_t dev_addr);
425-
426-
/**
427-
* @brief Fill the enumerating device's descriptor
428-
*
429-
* @note Hub Driver only
430-
* @note Must call in sequence
431-
* @param[in] dev_hdl Device handle
432-
* @param device_desc
433-
* @return esp_err_t
434-
*/
435-
esp_err_t usbh_hub_enum_fill_dev_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t *device_desc);
436-
437-
/**
438-
* @brief Fill the enumerating device's active configuration descriptor
439-
*
440-
* @note Hub Driver only
441-
* @note Must call in sequence
442-
* @note This function can block
443-
* @param[in] dev_hdl Device handle
444-
* @param config_desc_full
445-
* @return esp_err_t
446-
*/
447-
esp_err_t usbh_hub_enum_fill_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc_full);
448-
449-
/**
450-
* @brief Fill one of the string descriptors of the enumerating device
451-
*
452-
* @note Hub Driver only
453-
* @note Must call in sequence
454-
* @param dev_hdl Device handle
455-
* @param str_desc Pointer to string descriptor
456-
* @param select Select which string descriptor. 0/1/2 for Manufacturer/Product/Serial Number string descriptors respectively
457-
* @return esp_err_t
458-
*/
459-
esp_err_t usbh_hub_enum_fill_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select);
460-
461-
/**
462-
* @brief Indicate the device enumeration is completed
463-
*
464-
* This will allow the device to be opened by clients, and also trigger a USBH_EVENT_NEW_DEV event.
465-
*
466-
* @note Hub Driver only
467-
* @note Must call in sequence
468-
* @note This function can block
469-
* @param[in] dev_hdl Device handle
470-
* @return esp_err_t
471-
*/
472-
esp_err_t usbh_hub_enum_done(usb_device_handle_t dev_hdl);
473-
474-
/**
475-
* @brief Indicate that device enumeration has failed
476-
*
477-
* This will cause the enumerating device's resources to be cleaned up
478-
* The Hub Driver must guarantee that the enumerating device's default pipe is already halted, flushed, and dequeued.
479-
*
480-
* @note Hub Driver only
481-
* @note Must call in sequence
482-
* @note This function can block
483-
* @param[in] dev_hdl Device handle
484-
* @return esp_err_t
485-
*/
486-
esp_err_t usbh_hub_enum_failed(usb_device_handle_t dev_hdl);
487-
488519
#ifdef __cplusplus
489520
}
490521
#endif

0 commit comments

Comments
 (0)