mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'refactor/usb_host_usbh_interface_v5.1' into 'release/v5.1'
USB Host: Refactor USBH interface (v5.1) See merge request espressif/esp-idf!24210
This commit is contained in:
commit
9dbefdbb41
File diff suppressed because it is too large
Load Diff
1012
components/usb/hub.c
1012
components/usb/hub.c
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@ Warning: The USB Host Library API is still a beta version and may be subject to
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
//Include the other USB Host Library headers as well
|
||||
// Include the other USB Host Library headers as well
|
||||
#include "usb/usb_helpers.h"
|
||||
#include "usb/usb_types_ch9.h"
|
||||
#include "usb/usb_types_stack.h"
|
||||
@ -34,7 +34,7 @@ extern "C" {
|
||||
*
|
||||
* @note Asynchronous API
|
||||
*/
|
||||
typedef struct usb_host_client_handle_s * usb_host_client_handle_t;
|
||||
typedef struct usb_host_client_handle_s *usb_host_client_handle_t;
|
||||
|
||||
// ----------------------- Events --------------------------
|
||||
|
||||
@ -116,7 +116,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
bool is_synchronous; /**< Whether the client is asynchronous or synchronous or not. Set to false for now. */
|
||||
int max_num_event_msg; /**< Maximum number of event messages that can be stored (e.g., 3) */
|
||||
union { //Note: Made into union or future expansion
|
||||
union { // Note: Made into union or future expansion
|
||||
struct {
|
||||
usb_host_client_event_cb_t client_event_callback; /**< Client's event callback function */
|
||||
void *callback_arg; /**< Event callback function argument */
|
||||
|
@ -346,10 +346,10 @@ ESP_STATIC_ASSERT(sizeof(usb_config_desc_t) == USB_CONFIG_DESC_SIZE, "Size of us
|
||||
/**
|
||||
* @brief Bit masks belonging to the bmAttributes field of a configuration descriptor
|
||||
*/
|
||||
#define USB_BM_ATTRIBUTES_ONE (1 << 7) //Must be set
|
||||
#define USB_BM_ATTRIBUTES_SELFPOWER (1 << 6) //Self powered
|
||||
#define USB_BM_ATTRIBUTES_WAKEUP (1 << 5) //Can wake-up
|
||||
#define USB_BM_ATTRIBUTES_BATTERY (1 << 4) //Battery powered
|
||||
#define USB_BM_ATTRIBUTES_ONE (1 << 7) /**< Must be set */
|
||||
#define USB_BM_ATTRIBUTES_SELFPOWER (1 << 6) /**< Self powered */
|
||||
#define USB_BM_ATTRIBUTES_WAKEUP (1 << 5) /**< Can wake-up */
|
||||
#define USB_BM_ATTRIBUTES_BATTERY (1 << 4) /**< Battery powered */
|
||||
|
||||
// ---------- Interface Association Descriptor -------------
|
||||
|
||||
|
@ -43,7 +43,7 @@ typedef enum {
|
||||
/**
|
||||
* @brief Handle of a USB Device connected to a USB Host
|
||||
*/
|
||||
typedef struct usb_device_handle_s * usb_device_handle_t;
|
||||
typedef struct usb_device_handle_s *usb_device_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Basic information of an enumerated device
|
||||
@ -126,7 +126,7 @@ typedef void (*usb_transfer_cb_t)(usb_transfer_t *transfer);
|
||||
* @brief USB transfer structure
|
||||
*
|
||||
*/
|
||||
struct usb_transfer_s{
|
||||
struct usb_transfer_s {
|
||||
uint8_t *const data_buffer; /**< Pointer to data buffer */
|
||||
const size_t data_buffer_size; /**< Size of the data buffer in bytes */
|
||||
int num_bytes; /**< Number of bytes to transfer.
|
||||
|
@ -116,12 +116,12 @@ typedef enum {
|
||||
/**
|
||||
* @brief Port handle type
|
||||
*/
|
||||
typedef void * hcd_port_handle_t;
|
||||
typedef void *hcd_port_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Pipe handle type
|
||||
*/
|
||||
typedef void * hcd_pipe_handle_t;
|
||||
typedef void *hcd_pipe_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Port event callback type
|
||||
@ -448,13 +448,24 @@ esp_err_t hcd_pipe_set_persist_reset(hcd_pipe_handle_t pipe_hdl);
|
||||
void *hcd_pipe_get_context(hcd_pipe_handle_t pipe_hdl);
|
||||
|
||||
/**
|
||||
* @brief Get the current sate of the pipe
|
||||
* @brief Get the current state of the pipe
|
||||
*
|
||||
* @param pipe_hdl Pipe handle
|
||||
* @return hcd_pipe_state_t Current state of the pipe
|
||||
*/
|
||||
hcd_pipe_state_t hcd_pipe_get_state(hcd_pipe_handle_t pipe_hdl);
|
||||
|
||||
/**
|
||||
* @brief Get the number of in-flight URBs in the pipe
|
||||
*
|
||||
* Returns the current number of URBs that have been enqueued (via hcd_urb_enqueue()) and have yet to be dequeued (via
|
||||
* hcd_urb_dequeue()).
|
||||
*
|
||||
* @param pipe_hdl Pipe handle
|
||||
* @return Number of in-flight URBs
|
||||
*/
|
||||
unsigned int hcd_pipe_get_num_urbs(hcd_pipe_handle_t pipe_hdl);
|
||||
|
||||
/**
|
||||
* @brief Execute a command on a particular pipe
|
||||
*
|
||||
|
@ -22,8 +22,8 @@ extern "C" {
|
||||
* @brief Hub driver configuration
|
||||
*/
|
||||
typedef struct {
|
||||
usb_notif_cb_t notif_cb; /**< Notification callback */
|
||||
void *notif_cb_arg; /**< Notification callback argument */
|
||||
usb_proc_req_cb_t proc_req_cb; /**< Processing request callback */
|
||||
void *proc_req_cb_arg; /**< Processing request callback argument */
|
||||
} hub_config_t;
|
||||
|
||||
// ---------------------------------------------- Hub Driver Functions -------------------------------------------------
|
||||
@ -77,7 +77,7 @@ esp_err_t hub_root_stop(void);
|
||||
* @brief Hub driver's processing function
|
||||
*
|
||||
* Hub driver handling function that must be called repeatdly to process the Hub driver's events. If blocking, the
|
||||
* caller can block on the notification callback of source USB_NOTIF_SOURCE_HUB to run this function.
|
||||
* caller can block on the notification callback of source USB_PROC_REQ_SOURCE_HUB to run this function.
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
|
@ -36,26 +36,38 @@ typedef struct {
|
||||
} usb_transfer_dummy_t;
|
||||
_Static_assert(sizeof(usb_transfer_dummy_t) == sizeof(usb_transfer_t), "usb_transfer_dummy_t does not match usb_transfer_t");
|
||||
|
||||
struct urb_s{
|
||||
struct urb_s {
|
||||
TAILQ_ENTRY(urb_s) tailq_entry;
|
||||
//HCD Layer: Handler pointer and variables. Must be initialized to NULL and 0 respectively
|
||||
// HCD Layer: Handler pointer and variables. Must be initialized to NULL and 0 respectively
|
||||
void *hcd_ptr;
|
||||
uint32_t hcd_var;
|
||||
//Host Lib Layer:
|
||||
void *usb_host_client; //Currently only used when submitted to shared pipes (i.e., Device default pipes)
|
||||
size_t usb_host_header_size; //USB Host may need the data buffer to have a transparent header
|
||||
bool usb_host_inflight; //Debugging variable, used to prevent re-submitting URBs already inflight
|
||||
//Public transfer structure. Must be last due to variable length array
|
||||
// Host Lib Layer:
|
||||
void *usb_host_client; // Currently only used when submitted to shared pipes (i.e., Device default pipes)
|
||||
size_t usb_host_header_size; // USB Host may need the data buffer to have a transparent header
|
||||
bool usb_host_inflight; // Debugging variable, used to prevent re-submitting URBs already inflight
|
||||
// Public transfer structure. Must be last due to variable length array
|
||||
usb_transfer_t transfer;
|
||||
};
|
||||
typedef struct urb_s urb_t;
|
||||
|
||||
/**
|
||||
* @brief Processing request source
|
||||
*
|
||||
* Enum to indicate which layer of the USB Host stack requires processing. The main handling loop should then call that
|
||||
* layer's processing function (i.e., xxx_process()).
|
||||
*/
|
||||
typedef enum {
|
||||
USB_NOTIF_SOURCE_USBH = 0x01,
|
||||
USB_NOTIF_SOURCE_HUB = 0x02,
|
||||
} usb_notif_source_t;
|
||||
USB_PROC_REQ_SOURCE_USBH = 0x01,
|
||||
USB_PROC_REQ_SOURCE_HUB = 0x02,
|
||||
} usb_proc_req_source_t;
|
||||
|
||||
typedef bool (*usb_notif_cb_t)(usb_notif_source_t source, bool in_isr, void *context);
|
||||
/**
|
||||
* @brief Processing request callback
|
||||
*
|
||||
* Callback function provided to each layer of the USB Host stack so that each layer can request calls to their
|
||||
* processing function.
|
||||
*/
|
||||
typedef bool (*usb_proc_req_cb_t)(usb_proc_req_source_t source, bool in_isr, void *context);
|
||||
|
||||
// --------------------------------------------------- Allocation ------------------------------------------------------
|
||||
|
||||
|
@ -20,6 +20,13 @@ extern "C" {
|
||||
|
||||
// ------------------------------------------------------ Types --------------------------------------------------------
|
||||
|
||||
// ----------------------- Handles -------------------------
|
||||
|
||||
/**
|
||||
* @brief Handle of a allocated endpoint
|
||||
*/
|
||||
typedef struct usbh_ep_handle_s *usbh_ep_handle_t;
|
||||
|
||||
// ----------------------- Events --------------------------
|
||||
|
||||
typedef enum {
|
||||
@ -29,16 +36,18 @@ typedef enum {
|
||||
} usbh_event_t;
|
||||
|
||||
/**
|
||||
* @brief Hub driver requests
|
||||
* @brief Endpoint events
|
||||
*
|
||||
* Various requests of the Hub driver that the USBH can make.
|
||||
* @note Optimization: Keep this identical to hcd_pipe_event_t
|
||||
*/
|
||||
typedef enum {
|
||||
USBH_HUB_REQ_PORT_DISABLE, /**< Request that the Hub driver disable a particular port (occurs after a device
|
||||
has been freed). Hub driver should respond with a USBH_HUB_EVENT_PORT_DISABLED */
|
||||
USBH_HUB_REQ_PORT_RECOVER, /**< Request that the Hub driver recovers a particular port (occurs after a gone
|
||||
device has been freed). */
|
||||
} usbh_hub_req_t;
|
||||
USBH_EP_EVENT_NONE, /**< The EP has no events (used to indicate no events when polling) */
|
||||
USBH_EP_EVENT_URB_DONE, /**< The EP has completed a URB. The URB can be dequeued */
|
||||
USBH_EP_EVENT_ERROR_XFER, /**< The EP encountered excessive errors when transferring a URB i.e., three three consecutive transaction errors (e.g., no ACK, bad CRC etc) */
|
||||
USBH_EP_EVENT_ERROR_URB_NOT_AVAIL, /**< The EP tried to execute a transfer but no URB was available */
|
||||
USBH_EP_EVENT_ERROR_OVERFLOW, /**< The EP received more data than requested. Usually a Packet babble error (i.e., an IN packet has exceeded the EP's MPS) */
|
||||
USBH_EP_EVENT_ERROR_STALL, /**< EP received a STALL response */
|
||||
} usbh_ep_event_t;
|
||||
|
||||
/**
|
||||
* @brief Hub driver events for the USBH
|
||||
@ -63,6 +72,31 @@ typedef enum {
|
||||
USBH_HUB_EVENT_PORT_DISABLED, /**< Previous USBH_HUB_REQ_PORT_DISABLE request completed */
|
||||
} usbh_hub_event_t;
|
||||
|
||||
// ------------------ Requests/Commands --------------------
|
||||
|
||||
/**
|
||||
* @brief Hub driver requests
|
||||
*
|
||||
* Various requests of the Hub driver that the USBH can make.
|
||||
*/
|
||||
typedef enum {
|
||||
USBH_HUB_REQ_PORT_DISABLE, /**< Request that the Hub driver disable a particular port (occurs after a device
|
||||
has been freed). Hub driver should respond with a USBH_HUB_EVENT_PORT_DISABLED */
|
||||
USBH_HUB_REQ_PORT_RECOVER, /**< Request that the Hub driver recovers a particular port (occurs after a gone
|
||||
device has been freed). */
|
||||
} usbh_hub_req_t;
|
||||
|
||||
/**
|
||||
* @brief Endpoint commands
|
||||
*
|
||||
* @note Optimization: Keep this identical to hcd_pipe_cmd_t
|
||||
*/
|
||||
typedef enum {
|
||||
USBH_EP_CMD_HALT, /**< Halt an active endpoint. Any currently executing URB will be canceled. Enqueued URBs are left untouched */
|
||||
USBH_EP_CMD_FLUSH, /**< Can only be called when halted. Will cause all enqueued URBs to be canceled */
|
||||
USBH_EP_CMD_CLEAR, /**< Causes a halted endpoint to become active again. Any enqueued URBs will being executing.*/
|
||||
} usbh_ep_cmd_t;
|
||||
|
||||
// ---------------------- Callbacks ------------------------
|
||||
|
||||
/**
|
||||
@ -87,29 +121,37 @@ typedef void (*usbh_event_cb_t)(usb_device_handle_t dev_hdl, usbh_event_t usbh_e
|
||||
*/
|
||||
typedef void (*usbh_hub_req_cb_t)(hcd_port_handle_t port_hdl, usbh_hub_req_t hub_req, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Callback used to indicate an event on an endpoint
|
||||
*
|
||||
* Return whether to yield or not if called from an ISR. Always return false if not called from an ISR
|
||||
*/
|
||||
typedef bool (*usbh_ep_cb_t)(usbh_ep_handle_t ep_hdl, usbh_ep_event_t ep_event, void *arg, bool in_isr);
|
||||
|
||||
// ----------------------- Objects -------------------------
|
||||
|
||||
/**
|
||||
* @brief Configuration for an endpoint being allocated using usbh_ep_alloc()
|
||||
*/
|
||||
typedef struct {
|
||||
const usb_ep_desc_t *ep_desc; /**< Endpoint descriptor */
|
||||
hcd_pipe_callback_t pipe_cb; /**< Endpoint's pipe callback */
|
||||
void *pipe_cb_arg; /**< Pipe callback argument */
|
||||
void *context; /**< Pipe context */
|
||||
uint8_t bInterfaceNumber; /**< Interface number */
|
||||
uint8_t bAlternateSetting; /**< Alternate setting number of the interface */
|
||||
uint8_t bEndpointAddress; /**< Endpoint address */
|
||||
usbh_ep_cb_t ep_cb; /**< Endpoint event callback */
|
||||
void *ep_cb_arg; /**< Endpoint callback argument */
|
||||
void *context; /**< Endpoint context */
|
||||
} usbh_ep_config_t;
|
||||
|
||||
/**
|
||||
* @brief USBH configuration used in usbh_install()
|
||||
*/
|
||||
typedef struct {
|
||||
usb_notif_cb_t notif_cb; /**< Notification callback */
|
||||
void *notif_cb_arg; /**< Notification callback argument */
|
||||
usb_proc_req_cb_t proc_req_cb; /**< Processing request callback */
|
||||
void *proc_req_cb_arg; /**< Processing request callback argument */
|
||||
usbh_ctrl_xfer_cb_t ctrl_xfer_cb; /**< Control transfer callback */
|
||||
void *ctrl_xfer_cb_arg; /**< Control transfer callback argument */
|
||||
usbh_event_cb_t event_cb; /**< USBH event callback */
|
||||
void *event_cb_arg; /**< USBH event callback argument */
|
||||
hcd_config_t hcd_config; /**< HCD configuration */
|
||||
} usbh_config_t;
|
||||
|
||||
// ------------------------------------------------- USBH Functions ----------------------------------------------------
|
||||
@ -143,8 +185,8 @@ esp_err_t usbh_uninstall(void);
|
||||
* @brief USBH processing function
|
||||
*
|
||||
* - USBH processing function that must be called repeatedly to process USBH events
|
||||
* - If blocking, the caller can block until a USB_NOTIF_SOURCE_USBH notification is received before running this
|
||||
* function
|
||||
* - If blocking, the caller can block until the proc_req_cb() is called with USB_PROC_REQ_SOURCE_USBH as the request
|
||||
* source. The USB_PROC_REQ_SOURCE_USBH source indicates that this function should be called.
|
||||
*
|
||||
* @note This function can block
|
||||
* @return esp_err_t
|
||||
@ -271,31 +313,84 @@ esp_err_t usbh_dev_submit_ctrl_urb(usb_device_handle_t dev_hdl, urb_t *urb);
|
||||
/**
|
||||
* @brief Allocate an endpoint on a device
|
||||
*
|
||||
* Clients that have opened a device must call this function to allocate all endpoints in an interface that is claimed.
|
||||
* The pipe handle of the endpoint is returned so that clients can use and control the pipe directly.
|
||||
* This function allows clients to allocate a non-default endpoint (i.e., not EP0) on a connected device
|
||||
*
|
||||
* - A client must have opened the device using usbh_dev_open() before attempting to allocate an endpoint on the device
|
||||
* - A client should call this function to allocate all endpoints in an interface that the client has claimed.
|
||||
* - A client must allocate an endpoint using this function before attempting to communicate with it
|
||||
* - Once the client allocates an endpoint, the client is now owns/manages the endpoint. No other client should use or
|
||||
* deallocate the endpoint.
|
||||
*
|
||||
* @note This function can block
|
||||
* @note Default pipes are owned by the USBH. For control transfers, use usbh_dev_submit_ctrl_urb() instead
|
||||
* @note Device must be opened by the client first
|
||||
* @note Default endpoints (EP0) are owned by the USBH. For control transfers, use usbh_dev_submit_ctrl_urb() instead
|
||||
*
|
||||
* @param[in] dev_hdl Device handle
|
||||
* @param[in] ep_config
|
||||
* @param[out] pipe_hdl_ret Pipe handle
|
||||
* @param[in] ep_config Endpoint configuration
|
||||
* @param[out] ep_hdl_ret Endpoint handle
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t usbh_ep_alloc(usb_device_handle_t dev_hdl, usbh_ep_config_t *ep_config, hcd_pipe_handle_t *pipe_hdl_ret);
|
||||
esp_err_t usbh_ep_alloc(usb_device_handle_t dev_hdl, usbh_ep_config_t *ep_config, usbh_ep_handle_t *ep_hdl_ret);
|
||||
|
||||
/**
|
||||
* @brief Free and endpoint on a device
|
||||
*
|
||||
* Free an endpoint previously opened by usbh_ep_alloc()
|
||||
* This function frees an endpoint previously allocated by the client using usbh_ep_alloc()
|
||||
*
|
||||
* - Only the client that allocated the endpoint should free it
|
||||
* - The client must have halted and flushed the endpoint using usbh_ep_command() before attempting to free it
|
||||
* - The client must ensure that there are no more function calls to the endpoint before freeing it
|
||||
*
|
||||
* @note This function can block
|
||||
* @param[in] dev_hdl Device handle
|
||||
* @param[in] bEndpointAddress Endpoint's address
|
||||
* @param[in] ep_hdl Endpoint handle
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t usbh_ep_free(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress);
|
||||
esp_err_t usbh_ep_free(usbh_ep_handle_t ep_hdl);
|
||||
|
||||
/**
|
||||
* @brief Get the handle of an endpoint using its address
|
||||
*
|
||||
* The endpoint must have been previously allocated using usbh_ep_alloc()
|
||||
*
|
||||
* @param[in] dev_hdl Device handle
|
||||
* @param[in] bEndpointAddress Endpoint address
|
||||
* @param[out] ep_hdl_ret Endpoint handle
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t usbh_ep_get_handle(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress, usbh_ep_handle_t *ep_hdl_ret);
|
||||
|
||||
/**
|
||||
* @brief Enqueue a URB to an endpoint
|
||||
*
|
||||
* The URB will remain enqueued until it completes (successfully or errors out). Use usbh_ep_dequeue_urb() to dequeue
|
||||
* a completed URB.
|
||||
*
|
||||
* @param[in] ep_hdl Endpoint handle
|
||||
* @param[in] urb URB to enqueue
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb);
|
||||
|
||||
/**
|
||||
* @brief Dequeue a URB from an endpoint
|
||||
*
|
||||
* Dequeue a completed URB from an endpoint. The USBH_EP_EVENT_URB_DONE indicates that URBs can be dequeued
|
||||
*
|
||||
* @param[in] ep_hdl Endpoint handle
|
||||
* @param[out] urb_ret Dequeued URB, or NULL if no more URBs to dequeue
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t usbh_ep_dequeue_urb(usbh_ep_handle_t ep_hdl, urb_t **urb_ret);
|
||||
|
||||
/**
|
||||
* @brief Execute a command on a particular endpoint
|
||||
*
|
||||
* Endpoint commands allows executing a certain action on an endpoint (e.g., halting, flushing, clearing etc)
|
||||
*
|
||||
* @param[in] ep_hdl Endpoint handle
|
||||
* @param[in] command Endpoint command
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t usbh_ep_command(usbh_ep_handle_t ep_hdl, usbh_ep_cmd_t command);
|
||||
|
||||
/**
|
||||
* @brief Get the context of an endpoint
|
||||
@ -303,12 +398,10 @@ esp_err_t usbh_ep_free(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress);
|
||||
* Get the context variable assigned to and endpoint on allocation.
|
||||
*
|
||||
* @note This function can block
|
||||
* @param[in] dev_hdl Device handle
|
||||
* @param[in] bEndpointAddress Endpoint's address
|
||||
* @param[out] context_ret Context variable
|
||||
* @return esp_err_t
|
||||
* @param[in] ep_hdl Endpoint handle
|
||||
* @return Endpoint context
|
||||
*/
|
||||
esp_err_t usbh_ep_get_context(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress, void **context_ret);
|
||||
void *usbh_ep_get_context(usbh_ep_handle_t ep_hdl);
|
||||
|
||||
// -------------------------------------------------- Hub Functions ----------------------------------------------------
|
||||
|
||||
@ -396,7 +489,7 @@ esp_err_t usbh_hub_enum_fill_config_desc(usb_device_handle_t dev_hdl, const usb_
|
||||
* @note Must call in sequence
|
||||
* @param dev_hdl Device handle
|
||||
* @param str_desc Pointer to string descriptor
|
||||
* @param select Select which string descriptor. 0/1/2 for Manufacturer/Product/Serial Number string descriptors respecitvely
|
||||
* @param select Select which string descriptor. 0/1/2 for Manufacturer/Product/Serial Number string descriptors respectively
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t usbh_hub_enum_fill_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select);
|
||||
|
@ -21,12 +21,12 @@ const usb_standard_desc_t *usb_parse_next_descriptor(const usb_standard_desc_t *
|
||||
{
|
||||
assert(cur_desc != NULL && offset != NULL);
|
||||
if (*offset >= wTotalLength) {
|
||||
return NULL; //We have traversed the entire configuration descriptor
|
||||
return NULL; // We have traversed the entire configuration descriptor
|
||||
}
|
||||
if (*offset + cur_desc->bLength >= wTotalLength) {
|
||||
return NULL; //Next descriptor is out of bounds
|
||||
return NULL; // Next descriptor is out of bounds
|
||||
}
|
||||
//Return the next descriptor, update offset
|
||||
// Return the next descriptor, update offset
|
||||
const usb_standard_desc_t *ret_desc = (const usb_standard_desc_t *)(((uint32_t)cur_desc) + cur_desc->bLength);
|
||||
*offset += cur_desc->bLength;
|
||||
return ret_desc;
|
||||
@ -35,8 +35,8 @@ const usb_standard_desc_t *usb_parse_next_descriptor(const usb_standard_desc_t *
|
||||
const usb_standard_desc_t *usb_parse_next_descriptor_of_type(const usb_standard_desc_t *cur_desc, uint16_t wTotalLength, uint8_t bDescriptorType, int *offset)
|
||||
{
|
||||
assert(cur_desc != NULL && offset != NULL);
|
||||
int offset_temp = *offset; //We only want to update offset if we've actually found a descriptor
|
||||
//Keep stepping over descriptors until we find one of bDescriptorType or until we go out of bounds
|
||||
int offset_temp = *offset; // We only want to update offset if we've actually found a descriptor
|
||||
// Keep stepping over descriptors until we find one of bDescriptorType or until we go out of bounds
|
||||
const usb_standard_desc_t *ret_desc = usb_parse_next_descriptor(cur_desc, wTotalLength, &offset_temp);
|
||||
while (ret_desc != NULL) {
|
||||
if (ret_desc->bDescriptorType == bDescriptorType) {
|
||||
@ -45,7 +45,7 @@ const usb_standard_desc_t *usb_parse_next_descriptor_of_type(const usb_standard_
|
||||
ret_desc = usb_parse_next_descriptor(ret_desc, wTotalLength, &offset_temp);
|
||||
}
|
||||
if (ret_desc != NULL) {
|
||||
//We've found a descriptor. Update the offset
|
||||
// We've found a descriptor. Update the offset
|
||||
*offset = offset_temp;
|
||||
}
|
||||
return ret_desc;
|
||||
@ -55,10 +55,10 @@ int usb_parse_interface_number_of_alternate(const usb_config_desc_t *config_desc
|
||||
{
|
||||
assert(config_desc != NULL);
|
||||
int offset = 0;
|
||||
//Find the first interface descriptor of bInterfaceNumber
|
||||
// Find the first interface descriptor of bInterfaceNumber
|
||||
const usb_intf_desc_t *first_intf_desc = usb_parse_interface_descriptor(config_desc, bInterfaceNumber, 0, &offset);
|
||||
if (first_intf_desc == NULL) {
|
||||
return -1; //bInterfaceNumber not found
|
||||
return -1; // bInterfaceNumber not found
|
||||
}
|
||||
|
||||
int num_alt_setting = 0;
|
||||
@ -77,31 +77,31 @@ const usb_intf_desc_t *usb_parse_interface_descriptor(const usb_config_desc_t *c
|
||||
{
|
||||
assert(config_desc != NULL);
|
||||
|
||||
//Walk to first interface descriptor of bInterfaceNumber
|
||||
// Walk to first interface descriptor of bInterfaceNumber
|
||||
int offset_temp = 0;
|
||||
const usb_intf_desc_t *next_intf_desc = (const usb_intf_desc_t *)usb_parse_next_descriptor_of_type((const usb_standard_desc_t *)config_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset_temp);
|
||||
while (next_intf_desc != NULL) {
|
||||
if (next_intf_desc->bInterfaceNumber == bInterfaceNumber) {
|
||||
break; //We found the first interface descriptor with matching bInterfaceNumber
|
||||
break; // We found the first interface descriptor with matching bInterfaceNumber
|
||||
}
|
||||
next_intf_desc = (const usb_intf_desc_t *)usb_parse_next_descriptor_of_type((const usb_standard_desc_t *)next_intf_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset_temp);
|
||||
}
|
||||
if (next_intf_desc == NULL) {
|
||||
return NULL; //Couldn't find a interface with bInterfaceNumber
|
||||
return NULL; // Couldn't find a interface with bInterfaceNumber
|
||||
}
|
||||
|
||||
//Keep walking until an interface descriptor matching bInterfaceNumber and bAlternateSetting is found
|
||||
// Keep walking until an interface descriptor matching bInterfaceNumber and bAlternateSetting is found
|
||||
while (next_intf_desc != NULL) {
|
||||
if (next_intf_desc->bInterfaceNumber == bInterfaceNumber + 1) {
|
||||
//We've walked past our target bInterfaceNumber
|
||||
// We've walked past our target bInterfaceNumber
|
||||
next_intf_desc = NULL;
|
||||
break;
|
||||
}
|
||||
if (next_intf_desc->bAlternateSetting == bAlternateSetting) {
|
||||
//We've found our target interface descriptor
|
||||
// We've found our target interface descriptor
|
||||
break;
|
||||
}
|
||||
//Get the next interface descriptor
|
||||
// Get the next interface descriptor
|
||||
next_intf_desc = (const usb_intf_desc_t *)usb_parse_next_descriptor_of_type((const usb_standard_desc_t *)next_intf_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset_temp);
|
||||
}
|
||||
if (next_intf_desc != NULL && offset != NULL) {
|
||||
@ -114,9 +114,9 @@ const usb_ep_desc_t *usb_parse_endpoint_descriptor_by_index(const usb_intf_desc_
|
||||
{
|
||||
assert(intf_desc != NULL && offset != NULL);
|
||||
if (index >= intf_desc->bNumEndpoints) {
|
||||
return NULL; //Index is out of range
|
||||
return NULL; // Index is out of range
|
||||
}
|
||||
//Walk to the Nth endpoint descriptor we find
|
||||
// Walk to the Nth endpoint descriptor we find
|
||||
int offset_temp = *offset;
|
||||
bool ep_found = true;
|
||||
const usb_standard_desc_t *next_desc = (const usb_standard_desc_t *)intf_desc;
|
||||
@ -138,14 +138,14 @@ const usb_ep_desc_t *usb_parse_endpoint_descriptor_by_address(const usb_config_d
|
||||
{
|
||||
assert(config_desc != NULL);
|
||||
|
||||
//Find the interface descriptor
|
||||
// Find the interface descriptor
|
||||
int offset_intf;
|
||||
const usb_intf_desc_t *intf_desc = usb_parse_interface_descriptor(config_desc, bInterfaceNumber, bAlternateSetting, &offset_intf);
|
||||
if (intf_desc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Walk endpoint descriptors until one matching bEndpointAddress is found
|
||||
// Walk endpoint descriptors until one matching bEndpointAddress is found
|
||||
int offset_ep;
|
||||
bool ep_found = false;
|
||||
const usb_ep_desc_t *ep_desc = NULL;
|
||||
@ -174,21 +174,21 @@ static void print_ep_desc(const usb_ep_desc_t *ep_desc)
|
||||
int type = ep_desc->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK;
|
||||
|
||||
switch (type) {
|
||||
case USB_BM_ATTRIBUTES_XFER_CONTROL:
|
||||
ep_type_str = "CTRL";
|
||||
break;
|
||||
case USB_BM_ATTRIBUTES_XFER_ISOC:
|
||||
ep_type_str = "ISOC";
|
||||
break;
|
||||
case USB_BM_ATTRIBUTES_XFER_BULK:
|
||||
ep_type_str = "BULK";
|
||||
break;
|
||||
case USB_BM_ATTRIBUTES_XFER_INT:
|
||||
ep_type_str = "INT";
|
||||
break;
|
||||
default:
|
||||
ep_type_str = NULL;
|
||||
break;
|
||||
case USB_BM_ATTRIBUTES_XFER_CONTROL:
|
||||
ep_type_str = "CTRL";
|
||||
break;
|
||||
case USB_BM_ATTRIBUTES_XFER_ISOC:
|
||||
ep_type_str = "ISOC";
|
||||
break;
|
||||
case USB_BM_ATTRIBUTES_XFER_BULK:
|
||||
ep_type_str = "BULK";
|
||||
break;
|
||||
case USB_BM_ATTRIBUTES_XFER_INT:
|
||||
ep_type_str = "INT";
|
||||
break;
|
||||
default:
|
||||
ep_type_str = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\t\t*** Endpoint descriptor ***\n");
|
||||
@ -277,23 +277,23 @@ void usb_print_config_descriptor(const usb_config_desc_t *cfg_desc, print_class_
|
||||
|
||||
do {
|
||||
switch (next_desc->bDescriptorType) {
|
||||
case USB_B_DESCRIPTOR_TYPE_CONFIGURATION:
|
||||
usbh_print_cfg_desc((const usb_config_desc_t *)next_desc);
|
||||
break;
|
||||
case USB_B_DESCRIPTOR_TYPE_INTERFACE:
|
||||
usbh_print_intf_desc((const usb_intf_desc_t *)next_desc);
|
||||
break;
|
||||
case USB_B_DESCRIPTOR_TYPE_ENDPOINT:
|
||||
print_ep_desc((const usb_ep_desc_t *)next_desc);
|
||||
break;
|
||||
case USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION:
|
||||
print_iad_desc((const usb_iad_desc_t*)next_desc);
|
||||
break;
|
||||
default:
|
||||
if(class_specific_cb) {
|
||||
class_specific_cb(next_desc);
|
||||
}
|
||||
break;
|
||||
case USB_B_DESCRIPTOR_TYPE_CONFIGURATION:
|
||||
usbh_print_cfg_desc((const usb_config_desc_t *)next_desc);
|
||||
break;
|
||||
case USB_B_DESCRIPTOR_TYPE_INTERFACE:
|
||||
usbh_print_intf_desc((const usb_intf_desc_t *)next_desc);
|
||||
break;
|
||||
case USB_B_DESCRIPTOR_TYPE_ENDPOINT:
|
||||
print_ep_desc((const usb_ep_desc_t *)next_desc);
|
||||
break;
|
||||
case USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION:
|
||||
print_iad_desc((const usb_iad_desc_t *)next_desc);
|
||||
break;
|
||||
default:
|
||||
if (class_specific_cb) {
|
||||
class_specific_cb(next_desc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
next_desc = usb_parse_next_descriptor(next_desc, wTotalLength, &offset);
|
||||
@ -307,7 +307,7 @@ void usb_print_string_descriptor(const usb_str_desc_t *str_desc)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < str_desc->bLength/2; i++) {
|
||||
for (int i = 0; i < str_desc->bLength / 2; i++) {
|
||||
/*
|
||||
USB String descriptors of UTF-16.
|
||||
Right now We just skip any character larger than 0xFF to stay in BMP Basic Latin and Latin-1 Supplement range.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -85,7 +85,7 @@ static esp_err_t phy_external_iopins_configure(const usb_phy_ext_io_conf_t *ext_
|
||||
{ext_io_conf->vmo_io_num, usb_otg_periph_signal.extphy_vmo_out, true},
|
||||
};
|
||||
|
||||
return phy_iopins_configure(usb_periph_iopins, sizeof(usb_periph_iopins)/sizeof(usb_iopin_dsc_t));
|
||||
return phy_iopins_configure(usb_periph_iopins, sizeof(usb_periph_iopins) / sizeof(usb_iopin_dsc_t));
|
||||
}
|
||||
|
||||
static esp_err_t phy_otg_iopins_configure(const usb_phy_otg_io_conf_t *otg_io_conf)
|
||||
@ -103,7 +103,7 @@ static esp_err_t phy_otg_iopins_configure(const usb_phy_otg_io_conf_t *otg_io_co
|
||||
{otg_io_conf->chrgvbus_io_num, usb_otg_periph_signal.srp_chrgvbus_out, true},
|
||||
{otg_io_conf->dischrgvbus_io_num, usb_otg_periph_signal.srp_dischrgvbus_out, true},
|
||||
};
|
||||
return phy_iopins_configure(usb_periph_iopins, sizeof(usb_periph_iopins)/sizeof(usb_iopin_dsc_t));
|
||||
return phy_iopins_configure(usb_periph_iopins, sizeof(usb_periph_iopins) / sizeof(usb_iopin_dsc_t));
|
||||
}
|
||||
|
||||
esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode)
|
||||
@ -114,17 +114,17 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode)
|
||||
|
||||
handle->otg_mode = mode;
|
||||
if (mode == USB_OTG_MODE_HOST) {
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_OTG_IDDIG_IN_IDX, false); //connected connector is A side
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_OTG_IDDIG_IN_IDX, false); // connected connector is A side
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_SRP_BVALID_IN_IDX, false);
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); //receiving a valid Vbus from host
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_AVALID_IN_IDX, false); //HIGH to force USB host mode
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); // receiving a valid Vbus from host
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_AVALID_IN_IDX, false); // HIGH to force USB host mode
|
||||
if (handle->target == USB_PHY_TARGET_INT) {
|
||||
usb_phy_hal_int_load_conf_host(&(handle->hal_context));
|
||||
}
|
||||
} else if (mode == USB_OTG_MODE_DEVICE) {
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_IDDIG_IN_IDX, false); //connected connector is mini-B side
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_SRP_BVALID_IN_IDX, false); //HIGH to force USB device mode
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); //receiving a valid Vbus from device
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_IDDIG_IN_IDX, false); // connected connector is mini-B side
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_SRP_BVALID_IN_IDX, false); // HIGH to force USB device mode
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); // receiving a valid Vbus from device
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_OTG_AVALID_IN_IDX, false);
|
||||
}
|
||||
|
||||
@ -160,37 +160,37 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
switch (action) {
|
||||
case USB_PHY_ACTION_HOST_ALLOW_CONN:
|
||||
if (handle->target == USB_PHY_TARGET_INT) {
|
||||
usb_phy_hal_int_mimick_disconn(&(handle->hal_context), false);
|
||||
} else {
|
||||
if (!handle->iopins) {
|
||||
ret = ESP_FAIL;
|
||||
ESP_LOGE(USBPHY_TAG, "no I/O pins provided for connection");
|
||||
break;
|
||||
}
|
||||
/*
|
||||
Allow for connections on the external PHY by connecting the VP and VM signals to the external PHY.
|
||||
*/
|
||||
esp_rom_gpio_connect_in_signal(handle->iopins->vp_io_num, USB_EXTPHY_VP_IDX, false);
|
||||
esp_rom_gpio_connect_in_signal(handle->iopins->vm_io_num, USB_EXTPHY_VM_IDX, false);
|
||||
case USB_PHY_ACTION_HOST_ALLOW_CONN:
|
||||
if (handle->target == USB_PHY_TARGET_INT) {
|
||||
usb_phy_hal_int_mimick_disconn(&(handle->hal_context), false);
|
||||
} else {
|
||||
if (!handle->iopins) {
|
||||
ret = ESP_FAIL;
|
||||
ESP_LOGE(USBPHY_TAG, "no I/O pins provided for connection");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
Allow for connections on the external PHY by connecting the VP and VM signals to the external PHY.
|
||||
*/
|
||||
esp_rom_gpio_connect_in_signal(handle->iopins->vp_io_num, USB_EXTPHY_VP_IDX, false);
|
||||
esp_rom_gpio_connect_in_signal(handle->iopins->vm_io_num, USB_EXTPHY_VM_IDX, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_PHY_ACTION_HOST_FORCE_DISCONN:
|
||||
if (handle->target == USB_PHY_TARGET_INT) {
|
||||
usb_phy_hal_int_mimick_disconn(&(handle->hal_context), true);
|
||||
} else {
|
||||
/*
|
||||
Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal.
|
||||
*/
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_EXTPHY_VP_IDX, false);
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_EXTPHY_VM_IDX, false);
|
||||
}
|
||||
break;
|
||||
case USB_PHY_ACTION_HOST_FORCE_DISCONN:
|
||||
if (handle->target == USB_PHY_TARGET_INT) {
|
||||
usb_phy_hal_int_mimick_disconn(&(handle->hal_context), true);
|
||||
} else {
|
||||
/*
|
||||
Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal.
|
||||
*/
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_EXTPHY_VP_IDX, false);
|
||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, USB_EXTPHY_VM_IDX, false);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -15,8 +15,8 @@ urb_t *urb_alloc(size_t data_buffer_size, size_t header_size, int num_isoc_packe
|
||||
if (urb == NULL || data_buffer == NULL) {
|
||||
goto err;
|
||||
}
|
||||
urb->usb_host_header_size = header_size; //Indicate that this URB's data_buffer has a header in front of it.
|
||||
//Case as dummy transfer to write to initialize const fields
|
||||
urb->usb_host_header_size = header_size; // Indicate that this URB's data_buffer has a header in front of it.
|
||||
// Case as dummy transfer to write to initialize const fields
|
||||
usb_transfer_dummy_t *dummy_transfer = (usb_transfer_dummy_t *)&urb->transfer;
|
||||
dummy_transfer->data_buffer = (uint8_t *)(data_buffer + header_size);
|
||||
dummy_transfer->data_buffer_size = data_buffer_size;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user