forked from espressif/esp-idf
Merge branch 'refactor/usb_common_and_hal_types' into 'master'
Separate USB HAL and common USB types Closes IDF-2931 See merge request espressif/esp-idf!12642
This commit is contained in:
49
components/hal/esp32s2/include/hal/usb_types_private.h
Normal file
49
components/hal/esp32s2/include/hal/usb_types_private.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note: This header file contains USB2.0 related types and macros that can be used by code specific to the DWC_OTG
|
||||||
|
controller (i.e., the HW specific layers of the USB host stack). Thus, this header is only meant to be used below (and
|
||||||
|
including) the HAL layer. For types and macros that are HW implementation agnostic (i.e., HCD layer and above), add them
|
||||||
|
to the "usb.h" header instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB speeds supported by the DWC OTG controller
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
USB_PRIV_SPEED_FULL,
|
||||||
|
USB_PRIV_SPEED_LOW,
|
||||||
|
} usb_priv_speed_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB transfer types supported by the DWC OTG controller
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
USB_PRIV_XFER_TYPE_CTRL,
|
||||||
|
USB_PRIV_XFER_TYPE_ISOCHRONOUS,
|
||||||
|
USB_PRIV_XFER_TYPE_BULK,
|
||||||
|
USB_PRIV_XFER_TYPE_INTR,
|
||||||
|
} usb_priv_xfer_type_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -28,7 +28,7 @@ NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
|
|||||||
#include "soc/usbh_struct.h"
|
#include "soc/usbh_struct.h"
|
||||||
#include "soc/usb_wrap_struct.h"
|
#include "soc/usb_wrap_struct.h"
|
||||||
#include "hal/usbh_ll.h"
|
#include "hal/usbh_ll.h"
|
||||||
#include "hal/usb_types.h"
|
#include "hal/usb_types_private.h"
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
------------------------------- Macros and Types -------------------------------
|
------------------------------- Macros and Types -------------------------------
|
||||||
@@ -121,7 +121,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
usb_xfer_type_t type: 2; /**< The type of endpoint */
|
usb_priv_xfer_type_t type: 2; /**< The type of endpoint */
|
||||||
uint32_t bEndpointAddress: 8; /**< Endpoint address (containing endpoint number and direction) */
|
uint32_t bEndpointAddress: 8; /**< Endpoint address (containing endpoint number and direction) */
|
||||||
uint32_t mps: 11; /**< Maximum Packet Size */
|
uint32_t mps: 11; /**< Maximum Packet Size */
|
||||||
uint32_t dev_addr: 8; /**< Device Address */
|
uint32_t dev_addr: 8; /**< Device Address */
|
||||||
@@ -413,9 +413,9 @@ static inline bool usbh_hal_port_check_if_connected(usbh_hal_context_t *hal)
|
|||||||
* connected to the host port
|
* connected to the host port
|
||||||
*
|
*
|
||||||
* @param hal Context of the HAL layer
|
* @param hal Context of the HAL layer
|
||||||
* @return usb_speed_t Speed of the connected device
|
* @return usb_priv_speed_t Speed of the connected device (FS or LS only on the esp32-s2)
|
||||||
*/
|
*/
|
||||||
static inline usb_speed_t usbh_hal_port_get_conn_speed(usbh_hal_context_t *hal)
|
static inline usb_priv_speed_t usbh_hal_port_get_conn_speed(usbh_hal_context_t *hal)
|
||||||
{
|
{
|
||||||
return usbh_ll_hprt_get_speed(hal->dev);
|
return usbh_ll_hprt_get_speed(hal->dev);
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ extern "C" {
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "soc/usbh_struct.h"
|
#include "soc/usbh_struct.h"
|
||||||
#include "soc/usb_wrap_struct.h"
|
#include "soc/usb_wrap_struct.h"
|
||||||
#include "hal/usb_types.h"
|
#include "hal/usb_types_private.h"
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
------------------------------- Global Registers -------------------------------
|
------------------------------- Global Registers -------------------------------
|
||||||
@@ -419,7 +419,7 @@ static inline void usbh_ll_hcfg_set_fsls_pclk_sel(usbh_dev_t *hw)
|
|||||||
*
|
*
|
||||||
* @param hw
|
* @param hw
|
||||||
*/
|
*/
|
||||||
static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
|
static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_priv_speed_t speed)
|
||||||
{
|
{
|
||||||
hw->hcfg_reg.descdma = 1; //Enable scatt/gatt
|
hw->hcfg_reg.descdma = 1; //Enable scatt/gatt
|
||||||
hw->hcfg_reg.fslssupp = 1; //FS/LS supp only
|
hw->hcfg_reg.fslssupp = 1; //FS/LS supp only
|
||||||
@@ -428,13 +428,13 @@ static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
|
|||||||
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
|
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
|
||||||
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
|
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
|
||||||
*/
|
*/
|
||||||
hw->hcfg_reg.fslspclksel = (speed == USB_SPEED_FULL) ? 1 : 2;
|
hw->hcfg_reg.fslspclksel = (speed == USB_PRIV_SPEED_FULL) ? 1 : 2; //esp32-s2 only supports FS or LS
|
||||||
hw->hcfg_reg.perschedena = 0; //Disable perio sched
|
hw->hcfg_reg.perschedena = 0; //Disable perio sched
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------- HFIR Register ---------------------------------
|
// ----------------------------- HFIR Register ---------------------------------
|
||||||
|
|
||||||
static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
|
static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_priv_speed_t speed)
|
||||||
{
|
{
|
||||||
usb_hfir_reg_t hfir;
|
usb_hfir_reg_t hfir;
|
||||||
hfir.val = hw->hfir_reg.val;
|
hfir.val = hw->hfir_reg.val;
|
||||||
@@ -444,7 +444,7 @@ static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
|
|||||||
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
|
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
|
||||||
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
|
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
|
||||||
*/
|
*/
|
||||||
hfir.frint = (speed == USB_SPEED_FULL) ? 48000 : 6000;
|
hfir.frint = (speed == USB_PRIV_SPEED_FULL) ? 48000 : 6000; //esp32-s2 only supports FS or LS
|
||||||
hw->hfir_reg.val = hfir.val;
|
hw->hfir_reg.val = hfir.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,14 +510,19 @@ static inline uint32_t usbh_ll_get_frame_list_base_addr(usbh_dev_t *hw)
|
|||||||
|
|
||||||
// ----------------------------- HPRT Register ---------------------------------
|
// ----------------------------- HPRT Register ---------------------------------
|
||||||
|
|
||||||
static inline usb_speed_t usbh_ll_hprt_get_speed(usbh_dev_t *hw)
|
static inline usb_priv_speed_t usbh_ll_hprt_get_speed(usbh_dev_t *hw)
|
||||||
{
|
{
|
||||||
int prtspd = hw->hprt_reg.prtspd;
|
usb_priv_speed_t speed;
|
||||||
if (prtspd == 1) {
|
//esp32-s2 only supports FS or LS
|
||||||
return USB_SPEED_FULL;
|
switch (hw->hprt_reg.prtspd) {
|
||||||
} else {
|
case 1:
|
||||||
return USB_SPEED_LOW;
|
speed = USB_PRIV_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
speed = USB_PRIV_SPEED_LOW;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t usbh_ll_hprt_get_test_ctl(usbh_dev_t *hw)
|
static inline uint32_t usbh_ll_hprt_get_test_ctl(usbh_dev_t *hw)
|
||||||
@@ -674,24 +679,24 @@ static inline void usbh_ll_chan_set_dev_addr(volatile usb_host_chan_regs_t *chan
|
|||||||
chan->hcchar_reg.devaddr = addr;
|
chan->hcchar_reg.devaddr = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void usbh_ll_chan_set_ep_type(volatile usb_host_chan_regs_t *chan, usb_xfer_type_t type)
|
static inline void usbh_ll_chan_set_ep_type(volatile usb_host_chan_regs_t *chan, usb_priv_xfer_type_t type)
|
||||||
{
|
{
|
||||||
|
uint32_t ep_type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case USB_XFER_TYPE_CTRL:
|
case USB_PRIV_XFER_TYPE_CTRL:
|
||||||
chan->hcchar_reg.eptype = 0x0;
|
ep_type = 0;
|
||||||
break;
|
break;
|
||||||
case USB_XFER_TYPE_ISOCHRONOUS:
|
case USB_PRIV_XFER_TYPE_ISOCHRONOUS:
|
||||||
chan->hcchar_reg.eptype = 0x1;
|
ep_type = 1;
|
||||||
break;
|
break;
|
||||||
case USB_XFER_TYPE_BULK:
|
case USB_PRIV_XFER_TYPE_BULK:
|
||||||
chan->hcchar_reg.eptype = 0x2;
|
ep_type = 2;
|
||||||
break;
|
break;
|
||||||
case USB_XFER_TYPE_INTR:
|
default: //USB_PRIV_XFER_TYPE_INTR
|
||||||
chan->hcchar_reg.eptype = 0x3;
|
ep_type = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
chan->hcchar_reg.eptype = ep_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Indicates whether channel is commuunicating with a LS device connected via a FS hub. Setting this bit to 1 will cause
|
//Indicates whether channel is commuunicating with a LS device connected via a FS hub. Setting this bit to 1 will cause
|
||||||
@@ -716,9 +721,9 @@ static inline void usbh_ll_chan_set_mps(volatile usb_host_chan_regs_t *chan, uin
|
|||||||
chan->hcchar_reg.mps = mps;
|
chan->hcchar_reg.mps = mps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void usbh_ll_chan_hcchar_init(volatile usb_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_xfer_type_t type, bool is_in, bool is_ls)
|
static inline void usbh_ll_chan_hcchar_init(volatile usb_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_priv_xfer_type_t type, bool is_in, bool is_ls)
|
||||||
{
|
{
|
||||||
//Sets all persistent fields of the channel over its lifetime
|
//Sets all persistent fields of the channel over its lifetimez
|
||||||
usbh_ll_chan_set_dev_addr(chan, dev_addr);
|
usbh_ll_chan_set_dev_addr(chan, dev_addr);
|
||||||
usbh_ll_chan_set_ep_type(chan, type);
|
usbh_ll_chan_set_ep_type(chan, type);
|
||||||
usbh_ll_chan_set_lspddev(chan, is_ls);
|
usbh_ll_chan_set_lspddev(chan, is_ls);
|
||||||
|
@@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
// -------------------------------- Constants ----------------------------------
|
// -------------------------------- Constants ----------------------------------
|
||||||
|
|
||||||
|
#define BENDPOINTADDRESS_NUM_MSK 0x0F //Endpoint number mask of the bEndpointAddress field of an endpoint descriptor
|
||||||
|
#define BENDPOINTADDRESS_DIR_MSK 0x80 //Endpoint direction mask of the bEndpointAddress field of an endpoint descriptor
|
||||||
|
|
||||||
#define CORE_REG_GSNPSID 0x4F54400A
|
#define CORE_REG_GSNPSID 0x4F54400A
|
||||||
#define CORE_REG_GHWCFG1 0x00000000
|
#define CORE_REG_GHWCFG1 0x00000000
|
||||||
#define CORE_REG_GHWCFG2 0x224DD930
|
#define CORE_REG_GHWCFG2 0x224DD930
|
||||||
@@ -193,7 +196,7 @@ static inline void debounce_lock_enable(usbh_hal_context_t *hal)
|
|||||||
|
|
||||||
void usbh_hal_port_enable(usbh_hal_context_t *hal)
|
void usbh_hal_port_enable(usbh_hal_context_t *hal)
|
||||||
{
|
{
|
||||||
usb_speed_t speed = usbh_ll_hprt_get_speed(hal->dev);
|
usb_priv_speed_t speed = usbh_ll_hprt_get_speed(hal->dev);
|
||||||
//Host Configuration
|
//Host Configuration
|
||||||
usbh_ll_hcfg_set_defaults(hal->dev, speed);
|
usbh_ll_hcfg_set_defaults(hal->dev, speed);
|
||||||
//Todo: Set frame list entries and ena per sched
|
//Todo: Set frame list entries and ena per sched
|
||||||
@@ -265,10 +268,10 @@ void usbh_hal_chan_set_ep_char(usbh_hal_chan_t *chan_obj, usbh_hal_ep_char_t *ep
|
|||||||
//Set the endpoint characteristics of the pipe
|
//Set the endpoint characteristics of the pipe
|
||||||
usbh_ll_chan_hcchar_init(chan_obj->regs,
|
usbh_ll_chan_hcchar_init(chan_obj->regs,
|
||||||
ep_char->dev_addr,
|
ep_char->dev_addr,
|
||||||
ep_char->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK,
|
ep_char->bEndpointAddress & BENDPOINTADDRESS_NUM_MSK,
|
||||||
ep_char->mps,
|
ep_char->mps,
|
||||||
ep_char->type,
|
ep_char->type,
|
||||||
ep_char->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK,
|
ep_char->bEndpointAddress & BENDPOINTADDRESS_DIR_MSK,
|
||||||
ep_char->ls_via_fs_hub);
|
ep_char->ls_via_fs_hub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,19 +13,21 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "sys/queue.h"
|
#include <sys/queue.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "esp_intr_alloc.h"
|
#include "esp_intr_alloc.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_rom_gpio.h"
|
#include "esp_rom_gpio.h"
|
||||||
#include "hal/usbh_hal.h"
|
#include "hal/usbh_hal.h"
|
||||||
|
#include "hal/usb_types_private.h"
|
||||||
#include "soc/gpio_pins.h"
|
#include "soc/gpio_pins.h"
|
||||||
#include "soc/gpio_sig_map.h"
|
#include "soc/gpio_sig_map.h"
|
||||||
#include "driver/periph_ctrl.h"
|
#include "driver/periph_ctrl.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "usb.h"
|
||||||
#include "freertos/task.h"
|
|
||||||
#include "freertos/semphr.h"
|
|
||||||
#include "hcd.h"
|
#include "hcd.h"
|
||||||
|
|
||||||
// ----------------------------------------------------- Macros --------------------------------------------------------
|
// ----------------------------------------------------- Macros --------------------------------------------------------
|
||||||
@@ -572,7 +574,7 @@ static hcd_port_event_t _intr_hdlr_hprt(port_t *port, usbh_hal_port_event_t hal_
|
|||||||
}
|
}
|
||||||
case USBH_HAL_PORT_EVENT_ENABLED: {
|
case USBH_HAL_PORT_EVENT_ENABLED: {
|
||||||
usbh_hal_port_enable(port->hal); //Initialize remaining host port registers
|
usbh_hal_port_enable(port->hal); //Initialize remaining host port registers
|
||||||
port->speed = usbh_hal_port_get_conn_speed(port->hal);
|
port->speed = (usbh_hal_port_get_conn_speed(port->hal) == USB_PRIV_SPEED_FULL) ? USB_SPEED_FULL : USB_SPEED_LOW;
|
||||||
port->state = HCD_PORT_STATE_ENABLED;
|
port->state = HCD_PORT_STATE_ENABLED;
|
||||||
port->flags.conn_devc_ena = 1;
|
port->flags.conn_devc_ena = 1;
|
||||||
//This was triggered by a command, so no event needs to be propagated.
|
//This was triggered by a command, so no event needs to be propagated.
|
||||||
@@ -665,7 +667,7 @@ static hcd_pipe_event_t _intr_hdlr_chan(pipe_t *pipe, usbh_hal_chan_t *chan_obj,
|
|||||||
}
|
}
|
||||||
case USBH_HAL_CHAN_EVENT_SLOT_HALT: {
|
case USBH_HAL_CHAN_EVENT_SLOT_HALT: {
|
||||||
//A transfer descriptor list has partially completed. This currently only happens on control pipes
|
//A transfer descriptor list has partially completed. This currently only happens on control pipes
|
||||||
assert(pipe->ep_char.type == USB_XFER_TYPE_CTRL);
|
assert(pipe->ep_char.type == USB_PRIV_XFER_TYPE_CTRL);
|
||||||
_xfer_req_continue(pipe); //Continue the transfer request.
|
_xfer_req_continue(pipe); //Continue the transfer request.
|
||||||
//We are continuing a transfer, so no event has occurred
|
//We are continuing a transfer, so no event has occurred
|
||||||
break;
|
break;
|
||||||
@@ -1200,7 +1202,12 @@ esp_err_t hcd_port_get_speed(hcd_port_handle_t port_hdl, usb_speed_t *speed)
|
|||||||
HCD_ENTER_CRITICAL();
|
HCD_ENTER_CRITICAL();
|
||||||
//Device speed is only valid if there is a resetted device connected to the port
|
//Device speed is only valid if there is a resetted device connected to the port
|
||||||
HCD_CHECK_FROM_CRIT(port->flags.conn_devc_ena, ESP_ERR_INVALID_STATE);
|
HCD_CHECK_FROM_CRIT(port->flags.conn_devc_ena, ESP_ERR_INVALID_STATE);
|
||||||
*speed = usbh_hal_port_get_conn_speed(port->hal);
|
usb_priv_speed_t hal_speed = usbh_hal_port_get_conn_speed(port->hal);
|
||||||
|
if (hal_speed == USB_PRIV_SPEED_FULL) {
|
||||||
|
*speed = USB_SPEED_FULL;
|
||||||
|
} else {
|
||||||
|
*speed = USB_SPEED_LOW;
|
||||||
|
}
|
||||||
HCD_EXIT_CRITICAL();
|
HCD_EXIT_CRITICAL();
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -1372,7 +1379,7 @@ static inline hcd_pipe_event_t pipe_decode_error_event(usbh_hal_chan_error_t cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------- Public --------------------------
|
// ----------------------- Public --------------------------
|
||||||
|
#include "esp_rom_sys.h"
|
||||||
esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pipe_config, hcd_pipe_handle_t *pipe_hdl)
|
esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pipe_config, hcd_pipe_handle_t *pipe_hdl)
|
||||||
{
|
{
|
||||||
HCD_CHECK(port_hdl != NULL && pipe_config != NULL && pipe_hdl != NULL, ESP_ERR_INVALID_ARG);
|
HCD_CHECK(port_hdl != NULL && pipe_config != NULL && pipe_hdl != NULL, ESP_ERR_INVALID_ARG);
|
||||||
@@ -1387,7 +1394,7 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
|
|||||||
|
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
//Get the type of pipe to allocate
|
//Get the type of pipe to allocate
|
||||||
usb_xfer_type_t type;
|
usb_transfer_type_t type;
|
||||||
bool is_default_pipe;
|
bool is_default_pipe;
|
||||||
if (pipe_config->ep_desc == NULL) { //A NULL ep_desc indicates we are allocating a default pipe
|
if (pipe_config->ep_desc == NULL) { //A NULL ep_desc indicates we are allocating a default pipe
|
||||||
type = USB_XFER_TYPE_CTRL;
|
type = USB_XFER_TYPE_CTRL;
|
||||||
@@ -1431,7 +1438,22 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
|
|||||||
pipe->xfer_desc_list = xfer_desc_list;
|
pipe->xfer_desc_list = xfer_desc_list;
|
||||||
pipe->flags.xfer_desc_list_len = num_xfer_desc;
|
pipe->flags.xfer_desc_list_len = num_xfer_desc;
|
||||||
pipe->chan_obj = chan_obj;
|
pipe->chan_obj = chan_obj;
|
||||||
pipe->ep_char.type = type;
|
usb_priv_xfer_type_t hal_type;
|
||||||
|
switch (type) {
|
||||||
|
case USB_XFER_TYPE_CTRL:
|
||||||
|
hal_type = USB_PRIV_XFER_TYPE_CTRL;
|
||||||
|
break;
|
||||||
|
case USB_XFER_TYPE_ISOCHRONOUS:
|
||||||
|
hal_type = USB_PRIV_XFER_TYPE_ISOCHRONOUS;
|
||||||
|
break;
|
||||||
|
case USB_XFER_TYPE_BULK:
|
||||||
|
hal_type = USB_PRIV_XFER_TYPE_ISOCHRONOUS;
|
||||||
|
break;
|
||||||
|
default: //USB_XFER_TYPE_INTR
|
||||||
|
hal_type = USB_PRIV_XFER_TYPE_INTR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pipe->ep_char.type = hal_type;
|
||||||
if (is_default_pipe) {
|
if (is_default_pipe) {
|
||||||
pipe->ep_char.bEndpointAddress = 0;
|
pipe->ep_char.bEndpointAddress = 0;
|
||||||
//Set the default pipe's MPS to the worst case MPS for the device's speed
|
//Set the default pipe's MPS to the worst case MPS for the device's speed
|
||||||
|
@@ -21,9 +21,8 @@ extern "C" {
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include "hal/usb_types.h"
|
|
||||||
#include "hal/usbh_hal.h"
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
// ------------------------------------------------- Macros & Types ----------------------------------------------------
|
// ------------------------------------------------- Macros & Types ----------------------------------------------------
|
||||||
|
|
||||||
|
@@ -12,33 +12,28 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note: This header file contains the types and macros belong/relate to the USB2.0 protocol and are HW implementation
|
||||||
|
agnostic. In other words, this header is only meant to be used in the HCD layer and above of the USB Host stack. For
|
||||||
|
types and macros that are HW implementation specific (i.e., HAL layer and below), add them to the "usb_types.h" header
|
||||||
|
instead.
|
||||||
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define USB_CTRL_REQ_ATTR __attribute__((packed))
|
#define USB_CTRL_REQ_ATTR __attribute__((packed))
|
||||||
#define USB_DESC_ATTR __attribute__((packed))
|
#define USB_DESC_ATTR __attribute__((packed))
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
// ------------------------------------------------ Common USB Types ---------------------------------------------------
|
||||||
------------------------------- Common USB Types -------------------------------
|
|
||||||
----------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
// ----------------------------- Device Related --------------------------------
|
// --------------------- Bus Related -----------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumeration of USB PHY type
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
USB_PHY_INTERNAL = 0, /**< Use the chip's internal USB PHY */
|
|
||||||
USB_PHY_EXTERNAL, /**< Use an external USB PHY */
|
|
||||||
} usb_phy_t;
|
|
||||||
|
|
||||||
// ------------------------------ Bus Related ----------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB Standard Speeds
|
* @brief USB Standard Speeds
|
||||||
@@ -48,7 +43,7 @@ typedef enum {
|
|||||||
USB_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */
|
USB_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */
|
||||||
} usb_speed_t;
|
} usb_speed_t;
|
||||||
|
|
||||||
// ---------------------------- Transfer Related -------------------------------
|
// ------------------ Transfer Related ---------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The type of USB transfer
|
* @brief The type of USB transfer
|
||||||
@@ -60,7 +55,7 @@ typedef enum {
|
|||||||
USB_XFER_TYPE_ISOCHRONOUS,
|
USB_XFER_TYPE_ISOCHRONOUS,
|
||||||
USB_XFER_TYPE_BULK,
|
USB_XFER_TYPE_BULK,
|
||||||
USB_XFER_TYPE_INTR,
|
USB_XFER_TYPE_INTR,
|
||||||
} usb_xfer_type_t;
|
} usb_transfer_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The status of a particular transfer
|
* @brief The status of a particular transfer
|
||||||
@@ -68,20 +63,20 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
USB_TRANSFER_STATUS_COMPLETED, /**< The transfer was successful (but may be short) */
|
USB_TRANSFER_STATUS_COMPLETED, /**< The transfer was successful (but may be short) */
|
||||||
USB_TRANSFER_STATUS_ERROR, /**< The transfer failed because due to excessive errors (e.g. no response or CRC error) */
|
USB_TRANSFER_STATUS_ERROR, /**< The transfer failed because due to excessive errors (e.g. no response or CRC error) */
|
||||||
USB_TRANSFER_STATUS_TIMED_OUT, /**< The transfer failed due to to a time out */
|
USB_TRANSFER_STATUS_TIMED_OUT, /**< The transfer failed due to a time out */
|
||||||
USB_TRANSFER_STATUS_CANCELLED, /**< The transfer was cancelled */
|
USB_TRANSFER_STATUS_CANCELLED, /**< The transfer was cancelled */
|
||||||
USB_TRANSFER_STATUS_STALL, /**< The transfer was stalled */
|
USB_TRANSFER_STATUS_STALL, /**< The transfer was stalled */
|
||||||
USB_TRANSFER_STATUS_NO_DEVICE, /**< The transfer failed because the device is no longer valid (e.g., disconencted */
|
USB_TRANSFER_STATUS_NO_DEVICE, /**< The transfer failed because the device is no longer valid (e.g., disconnected */
|
||||||
USB_TRANSFER_STATUS_OVERFLOW, /**< The transfer as more data was sent than was requested */
|
USB_TRANSFER_STATUS_OVERFLOW, /**< The transfer as more data was sent than was requested */
|
||||||
} usb_transfer_status_t;
|
} usb_transfer_status_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Isochronous packet descriptor
|
* @brief Isochronous packet descriptor
|
||||||
*
|
*
|
||||||
* If the number of bytes in an IRP transfer is larger than the MPS of the
|
* If the number of bytes in an IRP (I/O Request Packet, see USB2.0 Spec) is
|
||||||
* endpoint, the IRP is split over multiple packets (one packet per bInterval
|
* larger than the MPS of the endpoint, the IRP is split over multiple packets
|
||||||
* of the endpoint). An array of Isochronous packet descriptos describes how
|
* (one packet per bInterval of the endpoint). An array of Isochronous packet
|
||||||
* an IRP should be split over multiple packets.
|
* descriptors describes how an IRP should be split over multiple packets.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int length; /**< Number of bytes to transmit/receive in the packet */
|
int length; /**< Number of bytes to transmit/receive in the packet */
|
||||||
@@ -95,32 +90,34 @@ typedef struct {
|
|||||||
* An identifiable request by a software client to move data between itself (on the
|
* An identifiable request by a software client to move data between itself (on the
|
||||||
* host) and an endpoint of a device in an appropriate direction.
|
* host) and an endpoint of a device in an appropriate direction.
|
||||||
*
|
*
|
||||||
* This structure represents the barebones of the request. Different layers of
|
* This structure represents the bare-bones of the request. Different layers of
|
||||||
* USB drivers will wrap their own objects around this.
|
* USB drivers will wrap their own objects around this.
|
||||||
*
|
*
|
||||||
* See 10.5.3.1 os USB2.0 specification
|
* See 10.5.3.1 of USB2.0 specification for the full details regarding IRPs and their implications on each transfer type.
|
||||||
* Bulk: Represnts a single bulk transfer which a pipe will transparently split
|
* - Bulk: Represents a single bulk transfer where a pipe will internally split the transfer into one or more MPS
|
||||||
* into multiple MPS transactions (until the last)
|
* packets (except for the last packet) until all the bytes have been sent/received.
|
||||||
* Control: Represents a single contorl transfer with the setup packet at the
|
* Control: Represents a single control transfer with the setup packet at the first 8 bytes of the buffer. A pipe will
|
||||||
* first 8 bytes of the buffer.
|
* internally split the transfer into its Setup, Data, and Status stages.
|
||||||
* Interrupt: Represnts a single interrupt transaction
|
* Interrupt: Represents an interrupt transfer where a pipe will internally split the transfer into one or more MPS
|
||||||
* Isochronous: Represnts a buffer of a stream of bytes which the pipe will transparently
|
* packets (except for the last packet). Each packet is transmitted at the pipes established period (i.e.,
|
||||||
* transfer the stream of bytes one or more service periods
|
* the period specified by bInterval).
|
||||||
|
* Isochronous: Represents an Isochronous transfer (i.e., buffer of a stream of bytes). The pipe will internally split
|
||||||
|
* the stream into one or more packets and transmit each packet at the pipe's established period (i.e., the
|
||||||
|
* period specified by bInterval). The size of each packet is specified in its respective Isochronous
|
||||||
|
* Packet Descriptor in the IRP.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int num_bytes; /**< Number of bytes in IRP. Control should exclude size of setup. IN should be integer multiple of MPS */
|
int num_bytes; /**< Number of bytes in IRP. Control should exclude size of setup. IN should be integer multiple of MPS */
|
||||||
int actual_num_bytes; /**< Actual number of bytes transmitted/receives in the IRP */
|
int actual_num_bytes; /**< Actual number of bytes transmitted/received in the IRP */
|
||||||
uint8_t *data_buffer; /**< Pointer to data buffer. Must be DMA capable memory */
|
uint8_t *data_buffer; /**< Pointer to data buffer. Must be DMA capable memory */
|
||||||
usb_transfer_status_t status; /**< Status of the transfer */
|
usb_transfer_status_t status; /**< Status of the transfer */
|
||||||
int num_iso_packets; /**< Only relevant to isochronous. Number of service periods to transfer data buffer over. Set to 0 for non-iso transfers */
|
int num_iso_packets; /**< Only relevant to isochronous. Number of service periods to transfer data buffer over. Set to 0 for non-iso transfers */
|
||||||
usb_iso_packet_desc_t iso_packet_desc[0]; /**< Descriptors for each ISO packet */
|
usb_iso_packet_desc_t iso_packet_desc[0]; /**< Descriptors for each ISO packet */
|
||||||
} usb_irp_t;
|
} usb_irp_t;
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
// ---------------------------------------------------- Chapter 9 ------------------------------------------------------
|
||||||
----------------------------------- Chapter 9 ----------------------------------
|
|
||||||
----------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
// ------------------------------ Control Request ------------------------------
|
// ------------------- Control Request ---------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of a USB control transfer setup packet in bytes
|
* @brief Size of a USB control transfer setup packet in bytes
|
||||||
@@ -143,7 +140,7 @@ typedef union {
|
|||||||
_Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_req_t incorrect");
|
_Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_req_t incorrect");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bit masks pertaining to the bRequestType field of a setup packet
|
* @brief Bit masks belonging to the bRequestType field of a setup packet
|
||||||
*/
|
*/
|
||||||
#define USB_B_REQUEST_TYPE_DIR_OUT (0X00 << 7)
|
#define USB_B_REQUEST_TYPE_DIR_OUT (0X00 << 7)
|
||||||
#define USB_B_REQUEST_TYPE_DIR_IN (0x01 << 7)
|
#define USB_B_REQUEST_TYPE_DIR_IN (0x01 << 7)
|
||||||
@@ -159,7 +156,7 @@ _Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_re
|
|||||||
#define USB_B_REQUEST_TYPE_RECIP_MASK (0x1f << 0)
|
#define USB_B_REQUEST_TYPE_RECIP_MASK (0x1f << 0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bit masks pertaining to the bRequest field of a setup packet
|
* @brief Bit masks belonging to the bRequest field of a setup packet
|
||||||
*/
|
*/
|
||||||
#define USB_B_REQUEST_GET_STATUS 0x00
|
#define USB_B_REQUEST_GET_STATUS 0x00
|
||||||
#define USB_B_REQUEST_CLEAR_FEATURE 0x01
|
#define USB_B_REQUEST_CLEAR_FEATURE 0x01
|
||||||
@@ -174,7 +171,7 @@ _Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_re
|
|||||||
#define USB_B_REQUEST_SYNCH_FRAME 0x0C
|
#define USB_B_REQUEST_SYNCH_FRAME 0x0C
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bit masks pertaining to the wValue field of a setup packet
|
* @brief Bit masks belonging to the wValue field of a setup packet
|
||||||
*/
|
*/
|
||||||
#define USB_W_VALUE_DT_DEVICE 0x01
|
#define USB_W_VALUE_DT_DEVICE 0x01
|
||||||
#define USB_W_VALUE_DT_CONFIG 0x02
|
#define USB_W_VALUE_DT_CONFIG 0x02
|
||||||
@@ -245,7 +242,7 @@ _Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_re
|
|||||||
(ctrl_req_ptr)->wLength = 0; \
|
(ctrl_req_ptr)->wLength = 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
// ---------------------------- Device Descriptor ------------------------------
|
// ------------------ Device Descriptor --------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of a USB device descriptor in bytes
|
* @brief Size of a USB device descriptor in bytes
|
||||||
@@ -306,7 +303,7 @@ _Static_assert(sizeof(usb_desc_devc_t) == USB_DESC_DEV_SIZE, "Size of usb_desc_d
|
|||||||
*/
|
*/
|
||||||
#define USB_SUBCLASS_VENDOR_SPEC 0xff
|
#define USB_SUBCLASS_VENDOR_SPEC 0xff
|
||||||
|
|
||||||
// ----------------------- Configuration Descriptor ----------------------------
|
// -------------- Configuration Descriptor -----------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of a short USB configuration descriptor in bytes
|
* @brief Size of a short USB configuration descriptor in bytes
|
||||||
@@ -338,14 +335,14 @@ typedef union {
|
|||||||
_Static_assert(sizeof(usb_desc_cfg_t) == USB_DESC_CFG_SIZE, "Size of usb_desc_cfg_t incorrect");
|
_Static_assert(sizeof(usb_desc_cfg_t) == USB_DESC_CFG_SIZE, "Size of usb_desc_cfg_t incorrect");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bit masks pertaining to the bmAttributes field of a configuration descriptor
|
* @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_ONE (1 << 7) //Must be set
|
||||||
#define USB_BM_ATTRIBUTES_SELFPOWER (1 << 6) //Self powered
|
#define USB_BM_ATTRIBUTES_SELFPOWER (1 << 6) //Self powered
|
||||||
#define USB_BM_ATTRIBUTES_WAKEUP (1 << 5) //Can wakeup
|
#define USB_BM_ATTRIBUTES_WAKEUP (1 << 5) //Can wake-up
|
||||||
#define USB_BM_ATTRIBUTES_BATTERY (1 << 4) //Battery powered
|
#define USB_BM_ATTRIBUTES_BATTERY (1 << 4) //Battery powered
|
||||||
|
|
||||||
// ------------------------- Interface Descriptor ------------------------------
|
// ---------------- Interface Descriptor -------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of a USB interface descriptor in bytes
|
* @brief Size of a USB interface descriptor in bytes
|
||||||
@@ -371,7 +368,7 @@ typedef union {
|
|||||||
} usb_desc_intf_t;
|
} usb_desc_intf_t;
|
||||||
_Static_assert(sizeof(usb_desc_intf_t) == USB_DESC_INTF_SIZE, "Size of usb_desc_intf_t incorrect");
|
_Static_assert(sizeof(usb_desc_intf_t) == USB_DESC_INTF_SIZE, "Size of usb_desc_intf_t incorrect");
|
||||||
|
|
||||||
// ------------------------- Endpoint Descriptor -------------------------------
|
// ----------------- Endpoint Descriptor -------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of a USB endpoint descriptor in bytes
|
* @brief Size of a USB endpoint descriptor in bytes
|
||||||
@@ -379,7 +376,7 @@ _Static_assert(sizeof(usb_desc_intf_t) == USB_DESC_INTF_SIZE, "Size of usb_desc_
|
|||||||
#define USB_DESC_EP_SIZE 7
|
#define USB_DESC_EP_SIZE 7
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing a USB endp;oint descriptor
|
* @brief Structure representing a USB endpoint descriptor
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
@@ -395,13 +392,13 @@ typedef union {
|
|||||||
_Static_assert(sizeof(usb_desc_ep_t) == USB_DESC_EP_SIZE, "Size of usb_desc_ep_t incorrect");
|
_Static_assert(sizeof(usb_desc_ep_t) == USB_DESC_EP_SIZE, "Size of usb_desc_ep_t incorrect");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bit masks pertaining to the bEndpointAddress field of an endpoint descriptor
|
* @brief Bit masks belonging to the bEndpointAddress field of an endpoint descriptor
|
||||||
*/
|
*/
|
||||||
#define USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK 0x0f
|
#define USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK 0x0f
|
||||||
#define USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK 0x80
|
#define USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK 0x80
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Bit masks pertaining to the bmAttributes field of an endpoint descriptor
|
* @brief Bit masks belonging to the bmAttributes field of an endpoint descriptor
|
||||||
*/
|
*/
|
||||||
#define USB_BM_ATTRIBUTES_XFERTYPE_MASK 0x03
|
#define USB_BM_ATTRIBUTES_XFERTYPE_MASK 0x03
|
||||||
#define USB_BM_ATTRIBUTES_XFER_CONTROL (0 << 0)
|
#define USB_BM_ATTRIBUTES_XFER_CONTROL (0 << 0)
|
||||||
@@ -421,13 +418,12 @@ _Static_assert(sizeof(usb_desc_ep_t) == USB_DESC_EP_SIZE, "Size of usb_desc_ep_t
|
|||||||
/**
|
/**
|
||||||
* @brief Macro helpers to get information about an endpoint from its descriptor
|
* @brief Macro helpers to get information about an endpoint from its descriptor
|
||||||
*/
|
*/
|
||||||
#define USB_DESC_EP_GET_XFERTYPE(desc_ptr) ((usb_xfer_type_t) ((desc_ptr)->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK))
|
#define USB_DESC_EP_GET_XFERTYPE(desc_ptr) ((usb_transfer_type_t) ((desc_ptr)->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK))
|
||||||
#define USB_DESC_EP_GET_EP_NUM(desc_ptr) ((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK)
|
#define USB_DESC_EP_GET_EP_NUM(desc_ptr) ((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK)
|
||||||
#define USB_DESC_EP_GET_EP_DIR(desc_ptr) (((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) ? 1 : 0)
|
#define USB_DESC_EP_GET_EP_DIR(desc_ptr) (((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) ? 1 : 0)
|
||||||
#define USB_DESC_EP_GET_MPS(desc_ptr) ((desc_ptr)->wMaxPacketSize & 0x7FF)
|
#define USB_DESC_EP_GET_MPS(desc_ptr) ((desc_ptr)->wMaxPacketSize & 0x7FF)
|
||||||
|
|
||||||
|
// ------------------ String Descriptor --------------------
|
||||||
// --------------------------- String Descriptor -------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of a short USB string descriptor in bytes
|
* @brief Size of a short USB string descriptor in bytes
|
Reference in New Issue
Block a user