mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/usb_hs_support_v5.1' into 'release/v5.1'
feat(usb/host): Add High Speed enumeration types (backport v5.1) See merge request espressif/esp-idf!28059
This commit is contained in:
commit
bbb7c4c756
@ -19,7 +19,7 @@ NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "soc/usb_dwc_struct.h"
|
#include "soc/usb_dwc_struct.h"
|
||||||
#include "hal/usb_dwc_ll.h"
|
#include "hal/usb_dwc_ll.h"
|
||||||
#include "hal/usb_types_private.h"
|
#include "hal/usb_dwc_types.h"
|
||||||
#include "hal/assert.h"
|
#include "hal/assert.h"
|
||||||
|
|
||||||
#if SOC_USB_OTG_SUPPORTED
|
#if SOC_USB_OTG_SUPPORTED
|
||||||
@ -28,6 +28,30 @@ NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
|
|||||||
|
|
||||||
// ----------------------- Configs -------------------------
|
// ----------------------- Configs -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Possible FIFO biases
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
USB_HAL_FIFO_BIAS_DEFAULT, /**< Default (balanced) FIFO sizes */
|
||||||
|
USB_HAL_FIFO_BIAS_RX, /**< Bigger RX FIFO for IN transfers */
|
||||||
|
USB_HAL_FIFO_BIAS_PTX, /**< Bigger periodic TX FIFO for ISOC OUT transfers */
|
||||||
|
} usb_hal_fifo_bias_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPS limits based on FIFO configuration
|
||||||
|
*
|
||||||
|
* In bytes
|
||||||
|
*
|
||||||
|
* The resulting values depend on
|
||||||
|
* 1. FIFO total size (chip specific)
|
||||||
|
* 2. Set FIFO bias
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int in_mps; /**< Maximum packet size of IN packet */
|
||||||
|
unsigned int non_periodic_out_mps; /**< Maximum packet size of BULK and CTRL OUT packets */
|
||||||
|
unsigned int periodic_out_mps; /**< Maximum packet size of INTR and ISOC OUT packets */
|
||||||
|
} usb_hal_fifo_mps_limits_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief FIFO size configuration structure
|
* @brief FIFO size configuration structure
|
||||||
*/
|
*/
|
||||||
@ -104,7 +128,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
usb_priv_xfer_type_t type: 2; /**< The type of endpoint */
|
usb_dwc_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 */
|
||||||
@ -135,9 +159,9 @@ typedef struct {
|
|||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} flags; /**< Flags regarding channel's status and information */
|
} flags; /**< Flags regarding channel's status and information */
|
||||||
usb_dwc_host_chan_regs_t *regs; /**< Pointer to the channel's register set */
|
usb_dwc_host_chan_regs_t *regs; /**< Pointer to the channel's register set */
|
||||||
usb_dwc_hal_chan_error_t error; /**< The last error that occurred on the channel */
|
usb_dwc_hal_chan_error_t error; /**< The last error that occurred on the channel */
|
||||||
usb_priv_xfer_type_t type; /**< The transfer type of the channel */
|
usb_dwc_xfer_type_t type; /**< The transfer type of the channel */
|
||||||
void *chan_ctx; /**< Context variable for the owner of the channel */
|
void *chan_ctx; /**< Context variable for the owner of the channel */
|
||||||
} usb_dwc_hal_chan_t;
|
} usb_dwc_hal_chan_t;
|
||||||
|
|
||||||
@ -148,8 +172,10 @@ typedef struct {
|
|||||||
//Context
|
//Context
|
||||||
usb_dwc_dev_t *dev; /**< Pointer to base address of DWC_OTG registers */
|
usb_dwc_dev_t *dev; /**< Pointer to base address of DWC_OTG registers */
|
||||||
//Host Port related
|
//Host Port related
|
||||||
uint32_t *periodic_frame_list; /**< Pointer to scheduling frame list */
|
uint32_t *periodic_frame_list; /**< Pointer to scheduling frame list */
|
||||||
usb_hal_frame_list_len_t frame_list_len; /**< Length of the periodic scheduling frame list */
|
usb_hal_frame_list_len_t frame_list_len; /**< Length of the periodic scheduling frame list */
|
||||||
|
//FIFO related
|
||||||
|
const usb_dwc_hal_fifo_config_t *fifo_config; /**< FIFO sizes configuration */
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
|
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
|
||||||
@ -218,21 +244,28 @@ void usb_dwc_hal_deinit(usb_dwc_hal_context_t *hal);
|
|||||||
void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal);
|
void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set FIFO sizes
|
* @brief Set FIFO bias
|
||||||
*
|
*
|
||||||
* This function will set the sizes of each of the FIFOs (RX FIFO, Non-periodic TX FIFO, Periodic TX FIFO) and must be
|
* This function will set the sizes of each of the FIFOs (RX FIFO, Non-periodic TX FIFO, Periodic TX FIFO) and must be
|
||||||
* called at least once before allocating the channel. Based on the type of endpoints (and the endpionts' MPS), there
|
* called at least once before allocating the channel. Based on the type of endpoints (and the endpoints' MPS), there
|
||||||
* may be situations where this function may need to be called again to resize the FIFOs. If resizing FIFOs dynamically,
|
* may be situations where this function may need to be called again to resize the FIFOs. If resizing FIFOs dynamically,
|
||||||
* it is the user's responsibility to ensure there are no active channels when this function is called.
|
* it is the user's responsibility to ensure there are no active channels when this function is called.
|
||||||
*
|
*
|
||||||
* @note The totol size of all the FIFOs must be less than or equal to USB_DWC_FIFO_TOTAL_USABLE_LINES
|
|
||||||
* @note After a port reset, the FIFO size registers will reset to their default values, so this function must be called
|
* @note After a port reset, the FIFO size registers will reset to their default values, so this function must be called
|
||||||
* again post reset.
|
* again post reset.
|
||||||
*
|
*
|
||||||
* @param hal Context of the HAL layer
|
* @param[in] hal Context of the HAL layer
|
||||||
* @param fifo_config FIFO configuration
|
* @param[in] fifo_bias FIFO bias configuration
|
||||||
*/
|
*/
|
||||||
void usb_dwc_hal_set_fifo_size(usb_dwc_hal_context_t *hal, const usb_dwc_hal_fifo_config_t *fifo_config);
|
void usb_dwc_hal_set_fifo_bias(usb_dwc_hal_context_t *hal, const usb_hal_fifo_bias_t fifo_bias);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get MPS limits
|
||||||
|
*
|
||||||
|
* @param[in] hal Context of the HAL layer
|
||||||
|
* @param[out] mps_limits MPS limits
|
||||||
|
*/
|
||||||
|
void usb_dwc_hal_get_mps_limits(usb_dwc_hal_context_t *hal, usb_hal_fifo_mps_limits_t *mps_limits);
|
||||||
|
|
||||||
// ---------------------------------------------------- Host Port ------------------------------------------------------
|
// ---------------------------------------------------- Host Port ------------------------------------------------------
|
||||||
|
|
||||||
@ -465,14 +498,14 @@ static inline bool usb_dwc_hal_port_check_if_connected(usb_dwc_hal_context_t *ha
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check the speed (LS/FS) of the device connected to the host port
|
* @brief Check the speed of the device connected to the host port
|
||||||
*
|
*
|
||||||
* @note This function should only be called after confirming that a device is connected to the host port
|
* @note This function should only be called after confirming that a device is connected to the host port
|
||||||
*
|
*
|
||||||
* @param hal Context of the HAL layer
|
* @param hal Context of the HAL layer
|
||||||
* @return usb_priv_speed_t Speed of the connected device (FS or LS only on the esp32-s2 and esp32-s3)
|
* @return usb_dwc_speed_t Speed of the connected device
|
||||||
*/
|
*/
|
||||||
static inline usb_priv_speed_t usb_dwc_hal_port_get_conn_speed(usb_dwc_hal_context_t *hal)
|
static inline usb_dwc_speed_t usb_dwc_hal_port_get_conn_speed(usb_dwc_hal_context_t *hal)
|
||||||
{
|
{
|
||||||
return usb_dwc_ll_hprt_get_speed(hal->dev);
|
return usb_dwc_ll_hprt_get_speed(hal->dev);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ extern "C" {
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "soc/usb_dwc_struct.h"
|
#include "soc/usb_dwc_struct.h"
|
||||||
#include "hal/usb_types_private.h"
|
#include "hal/usb_dwc_types.h"
|
||||||
#include "hal/misc.h"
|
#include "hal/misc.h"
|
||||||
|
|
||||||
|
|
||||||
@ -33,6 +33,67 @@ Todo: Check sizes again and express this macro in terms of DWC config options (I
|
|||||||
------------------------------ DWC Configuration -------------------------------
|
------------------------------ DWC Configuration -------------------------------
|
||||||
----------------------------------------------------------------------------- */
|
----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default FIFO sizes (see 2.1.2.4 for programming guide)
|
||||||
|
*
|
||||||
|
* RXFIFO
|
||||||
|
* - Recommended: ((LPS/4) * 2) + 2
|
||||||
|
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 48 - 48 = 104
|
||||||
|
* - Worst case can accommodate two packets of 204 bytes, or one packet of 408
|
||||||
|
* NPTXFIFO
|
||||||
|
* - Recommended: (LPS/4) * 2
|
||||||
|
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
|
||||||
|
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
|
||||||
|
* PTXFIFO
|
||||||
|
* - Recommended: (LPS/4) * 2
|
||||||
|
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
|
||||||
|
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
|
||||||
|
*/
|
||||||
|
#define USB_DWC_FIFO_RX_LINES_DEFAULT 104
|
||||||
|
#define USB_DWC_FIFO_NPTX_LINES_DEFAULT 48
|
||||||
|
#define USB_DWC_FIFO_PTX_LINES_DEFAULT 48
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FIFO sizes that bias to giving RX FIFO more capacity
|
||||||
|
*
|
||||||
|
* RXFIFO
|
||||||
|
* - Recommended: ((LPS/4) * 2) + 2
|
||||||
|
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 32 - 16 = 152
|
||||||
|
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
||||||
|
* NPTXFIFO
|
||||||
|
* - Recommended: (LPS/4) * 2
|
||||||
|
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
|
||||||
|
* - Worst case can accommodate one packet of 64 bytes
|
||||||
|
* PTXFIFO
|
||||||
|
* - Recommended: (LPS/4) * 2
|
||||||
|
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 2 = 32
|
||||||
|
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
|
||||||
|
*/
|
||||||
|
#define USB_DWC_FIFO_RX_LINES_BIASRX 152
|
||||||
|
#define USB_DWC_FIFO_NPTX_LINES_BIASRX 16
|
||||||
|
#define USB_DWC_FIFO_PTX_LINES_BIASRX 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FIFO sizes that bias to giving Periodic TX FIFO more capacity (i.e., ISOC OUT)
|
||||||
|
*
|
||||||
|
* RXFIFO
|
||||||
|
* - Recommended: ((LPS/4) * 2) + 2
|
||||||
|
* - Actual: Assume LPS is 64, and 2 packets: ((64/4) * 2) + 2 = 34
|
||||||
|
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
|
||||||
|
* NPTXFIFO
|
||||||
|
* - Recommended: (LPS/4) * 2
|
||||||
|
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
|
||||||
|
* - Worst case can accommodate one packet of 64 bytes
|
||||||
|
* PTXFIFO
|
||||||
|
* - Recommended: (LPS/4) * 2
|
||||||
|
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 34 - 16 = 150
|
||||||
|
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
||||||
|
*/
|
||||||
|
#define USB_DWC_FIFO_RX_LINES_BIASTX 34
|
||||||
|
#define USB_DWC_FIFO_NPTX_LINES_BIASTX 16
|
||||||
|
#define USB_DWC_FIFO_PTX_LINES_BIASTX 150
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List of relevant DWC configurations. See DWC OTG databook Chapter 3 for more
|
* List of relevant DWC configurations. See DWC OTG databook Chapter 3 for more
|
||||||
* details.
|
* details.
|
||||||
@ -446,7 +507,7 @@ static inline void usb_dwc_ll_hcfg_set_fsls_pclk_sel(usb_dwc_dev_t *hw)
|
|||||||
* @param hw Start address of the DWC_OTG registers
|
* @param hw Start address of the DWC_OTG registers
|
||||||
* @param speed Speed to initialize the host port at
|
* @param speed Speed to initialize the host port at
|
||||||
*/
|
*/
|
||||||
static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_priv_speed_t speed)
|
static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_dwc_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 support only
|
hw->hcfg_reg.fslssupp = 1; //FS/LS support only
|
||||||
@ -455,13 +516,13 @@ static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_priv_spee
|
|||||||
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_PRIV_SPEED_FULL) ? 1 : 2; //PHY clock on esp32-sx for FS/LS-only
|
hw->hcfg_reg.fslspclksel = (speed == USB_DWC_SPEED_FULL) ? 1 : 2; //PHY clock on esp32-sx for FS/LS-only
|
||||||
hw->hcfg_reg.perschedena = 0; //Disable perio sched
|
hw->hcfg_reg.perschedena = 0; //Disable perio sched
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------- HFIR Register ---------------------------------
|
// ----------------------------- HFIR Register ---------------------------------
|
||||||
|
|
||||||
static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_priv_speed_t speed)
|
static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_dwc_speed_t speed)
|
||||||
{
|
{
|
||||||
usb_dwc_hfir_reg_t hfir;
|
usb_dwc_hfir_reg_t hfir;
|
||||||
hfir.val = hw->hfir_reg.val;
|
hfir.val = hw->hfir_reg.val;
|
||||||
@ -471,7 +532,7 @@ static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_priv_spee
|
|||||||
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_PRIV_SPEED_FULL) ? 48000 : 6000; //esp32-sx targets only support FS or LS
|
hfir.frint = (speed == USB_DWC_SPEED_FULL) ? 48000 : 6000; //esp32-sx targets only support FS or LS
|
||||||
hw->hfir_reg.val = hfir.val;
|
hw->hfir_reg.val = hfir.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,19 +615,9 @@ static inline uint32_t usb_dwc_ll_hflbaddr_get_base_addr(usb_dwc_dev_t *hw)
|
|||||||
|
|
||||||
// ----------------------------- HPRT Register ---------------------------------
|
// ----------------------------- HPRT Register ---------------------------------
|
||||||
|
|
||||||
static inline usb_priv_speed_t usb_dwc_ll_hprt_get_speed(usb_dwc_dev_t *hw)
|
static inline usb_dwc_speed_t usb_dwc_ll_hprt_get_speed(usb_dwc_dev_t *hw)
|
||||||
{
|
{
|
||||||
usb_priv_speed_t speed;
|
return (usb_dwc_speed_t)hw->hprt_reg.prtspd;
|
||||||
//esp32-s2 and esp32-s3 only support FS or LS
|
|
||||||
switch (hw->hprt_reg.prtspd) {
|
|
||||||
case 1:
|
|
||||||
speed = USB_PRIV_SPEED_FULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
speed = USB_PRIV_SPEED_LOW;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return speed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t usb_dwc_ll_hprt_get_test_ctl(usb_dwc_dev_t *hw)
|
static inline uint32_t usb_dwc_ll_hprt_get_test_ctl(usb_dwc_dev_t *hw)
|
||||||
@ -725,24 +776,9 @@ static inline void usb_dwc_ll_hcchar_set_dev_addr(volatile usb_dwc_host_chan_reg
|
|||||||
chan->hcchar_reg.devaddr = addr;
|
chan->hcchar_reg.devaddr = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void usb_dwc_ll_hcchar_set_ep_type(volatile usb_dwc_host_chan_regs_t *chan, usb_priv_xfer_type_t type)
|
static inline void usb_dwc_ll_hcchar_set_ep_type(volatile usb_dwc_host_chan_regs_t *chan, usb_dwc_xfer_type_t type)
|
||||||
{
|
{
|
||||||
uint32_t ep_type;
|
chan->hcchar_reg.eptype = (uint32_t)type;
|
||||||
switch (type) {
|
|
||||||
case USB_PRIV_XFER_TYPE_CTRL:
|
|
||||||
ep_type = 0;
|
|
||||||
break;
|
|
||||||
case USB_PRIV_XFER_TYPE_ISOCHRONOUS:
|
|
||||||
ep_type = 1;
|
|
||||||
break;
|
|
||||||
case USB_PRIV_XFER_TYPE_BULK:
|
|
||||||
ep_type = 2;
|
|
||||||
break;
|
|
||||||
default: //USB_PRIV_XFER_TYPE_INTR
|
|
||||||
ep_type = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
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
|
||||||
@ -767,7 +803,7 @@ static inline void usb_dwc_ll_hcchar_set_mps(volatile usb_dwc_host_chan_regs_t *
|
|||||||
chan->hcchar_reg.mps = mps;
|
chan->hcchar_reg.mps = mps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void usb_dwc_ll_hcchar_init(volatile usb_dwc_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)
|
static inline void usb_dwc_ll_hcchar_init(volatile usb_dwc_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_dwc_xfer_type_t type, bool is_in, bool is_ls)
|
||||||
{
|
{
|
||||||
//Sets all persistent fields of the channel over its lifetimez
|
//Sets all persistent fields of the channel over its lifetimez
|
||||||
usb_dwc_ll_hcchar_set_dev_addr(chan, dev_addr);
|
usb_dwc_ll_hcchar_set_dev_addr(chan, dev_addr);
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// 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
|
Note: This header file contains USB2.0 related types and macros that can be used by code specific to the DWC_OTG
|
||||||
@ -28,21 +20,26 @@ extern "C"
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB speeds supported by the DWC OTG controller
|
* @brief USB speeds supported by the DWC OTG controller
|
||||||
|
*
|
||||||
|
* @note usb_dwc_speed_t enum values must match the values of the DWC_OTG prtspd register field
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
USB_PRIV_SPEED_FULL,
|
USB_DWC_SPEED_HIGH = 0,
|
||||||
USB_PRIV_SPEED_LOW,
|
USB_DWC_SPEED_FULL = 1,
|
||||||
} usb_priv_speed_t;
|
USB_DWC_SPEED_LOW = 2,
|
||||||
|
} usb_dwc_speed_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB transfer types supported by the DWC OTG controller
|
* @brief USB transfer types supported by the DWC OTG controller
|
||||||
|
*
|
||||||
|
* @note usb_dwc_xfer_type_t enum values must match the values of the DWC_OTG hcchar register field
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
USB_PRIV_XFER_TYPE_CTRL,
|
USB_DWC_XFER_TYPE_CTRL = 0,
|
||||||
USB_PRIV_XFER_TYPE_ISOCHRONOUS,
|
USB_DWC_XFER_TYPE_ISOCHRONOUS = 1,
|
||||||
USB_PRIV_XFER_TYPE_BULK,
|
USB_DWC_XFER_TYPE_BULK = 2,
|
||||||
USB_PRIV_XFER_TYPE_INTR,
|
USB_DWC_XFER_TYPE_INTR = 3,
|
||||||
} usb_priv_xfer_type_t;
|
} usb_dwc_xfer_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enumeration of different possible lengths of the periodic frame list
|
* @brief Enumeration of different possible lengths of the periodic frame list
|
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "usb_types_private.h"
|
#include <stdbool.h>
|
||||||
|
#include "usb_dwc_types.h"
|
||||||
#include "usb_phy_types.h"
|
#include "usb_phy_types.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/usb_wrap_struct.h"
|
#include "soc/usb_wrap_struct.h"
|
||||||
@ -66,7 +67,7 @@ void usb_phy_hal_int_load_conf_host(usb_phy_hal_context_t *hal);
|
|||||||
* @param hal Context of the HAL layer
|
* @param hal Context of the HAL layer
|
||||||
* @param speed USB speed
|
* @param speed USB speed
|
||||||
*/
|
*/
|
||||||
void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_priv_speed_t speed);
|
void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_phy_speed_t speed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable/Disable test mode for internal PHY to mimick host-device disconnection
|
* @brief Enable/Disable test mode for internal PHY to mimick host-device disconnection
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -55,6 +55,7 @@ typedef enum {
|
|||||||
USB_PHY_SPEED_UNDEFINED,
|
USB_PHY_SPEED_UNDEFINED,
|
||||||
USB_PHY_SPEED_LOW, /**< USB Low Speed (1.5 Mbit/s) */
|
USB_PHY_SPEED_LOW, /**< USB Low Speed (1.5 Mbit/s) */
|
||||||
USB_PHY_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */
|
USB_PHY_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */
|
||||||
|
USB_PHY_SPEED_HIGH, /**< USB High Speed (480 Mbit/s) */
|
||||||
USB_PHY_SPEED_MAX,
|
USB_PHY_SPEED_MAX,
|
||||||
} usb_phy_speed_t;
|
} usb_phy_speed_t;
|
||||||
|
|
||||||
|
@ -27,6 +27,35 @@
|
|||||||
#define CORE_REG_GHWCFG3 0x00C804B5
|
#define CORE_REG_GHWCFG3 0x00C804B5
|
||||||
#define CORE_REG_GHWCFG4 0xD3F0A030
|
#define CORE_REG_GHWCFG4 0xD3F0A030
|
||||||
|
|
||||||
|
// ----------------------- Configs -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default FIFO sizes (see 2.1.2.4 for programming guide)
|
||||||
|
*/
|
||||||
|
const usb_dwc_hal_fifo_config_t fifo_config_default = {
|
||||||
|
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_DEFAULT,
|
||||||
|
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_DEFAULT,
|
||||||
|
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FIFO sizes that bias to giving RX FIFO more capacity
|
||||||
|
*/
|
||||||
|
const usb_dwc_hal_fifo_config_t fifo_config_bias_rx = {
|
||||||
|
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_BIASRX,
|
||||||
|
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_BIASRX,
|
||||||
|
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_BIASRX,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FIFO sizes that bias to giving Periodic TX FIFO more capacity (i.e., ISOC OUT)
|
||||||
|
*/
|
||||||
|
const usb_dwc_hal_fifo_config_t fifo_config_bias_ptx = {
|
||||||
|
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_BIASTX,
|
||||||
|
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_BIASTX,
|
||||||
|
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_BIASTX,
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------- Configurable -----------------------
|
// -------------------- Configurable -----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,8 +191,23 @@ void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal)
|
|||||||
memset(hal->channels.hdls, 0, sizeof(usb_dwc_hal_chan_t *) * USB_DWC_NUM_HOST_CHAN);
|
memset(hal->channels.hdls, 0, sizeof(usb_dwc_hal_chan_t *) * USB_DWC_NUM_HOST_CHAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_dwc_hal_set_fifo_size(usb_dwc_hal_context_t *hal, const usb_dwc_hal_fifo_config_t *fifo_config)
|
void usb_dwc_hal_set_fifo_bias(usb_dwc_hal_context_t *hal, const usb_hal_fifo_bias_t fifo_bias)
|
||||||
{
|
{
|
||||||
|
const usb_dwc_hal_fifo_config_t *fifo_config;
|
||||||
|
switch (fifo_bias) {
|
||||||
|
case USB_HAL_FIFO_BIAS_DEFAULT:
|
||||||
|
fifo_config = &fifo_config_default;
|
||||||
|
break;
|
||||||
|
case USB_HAL_FIFO_BIAS_RX:
|
||||||
|
fifo_config = &fifo_config_bias_rx;
|
||||||
|
break;
|
||||||
|
case USB_HAL_FIFO_BIAS_PTX:
|
||||||
|
fifo_config = &fifo_config_bias_ptx;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USB_DWC_FIFO_TOTAL_USABLE_LINES);
|
HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USB_DWC_FIFO_TOTAL_USABLE_LINES);
|
||||||
//Check that none of the channels are active
|
//Check that none of the channels are active
|
||||||
for (int i = 0; i < USB_DWC_NUM_HOST_CHAN; i++) {
|
for (int i = 0; i < USB_DWC_NUM_HOST_CHAN; i++) {
|
||||||
@ -179,9 +223,21 @@ void usb_dwc_hal_set_fifo_size(usb_dwc_hal_context_t *hal, const usb_dwc_hal_fif
|
|||||||
usb_dwc_ll_grstctl_flush_nptx_fifo(hal->dev);
|
usb_dwc_ll_grstctl_flush_nptx_fifo(hal->dev);
|
||||||
usb_dwc_ll_grstctl_flush_ptx_fifo(hal->dev);
|
usb_dwc_ll_grstctl_flush_ptx_fifo(hal->dev);
|
||||||
usb_dwc_ll_grstctl_flush_rx_fifo(hal->dev);
|
usb_dwc_ll_grstctl_flush_rx_fifo(hal->dev);
|
||||||
|
hal->fifo_config = fifo_config;
|
||||||
hal->flags.fifo_sizes_set = 1;
|
hal->flags.fifo_sizes_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usb_dwc_hal_get_mps_limits(usb_dwc_hal_context_t *hal, usb_hal_fifo_mps_limits_t *mps_limits)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(hal && mps_limits);
|
||||||
|
HAL_ASSERT(hal->flags.fifo_sizes_set);
|
||||||
|
|
||||||
|
const usb_dwc_hal_fifo_config_t *fifo_config = hal->fifo_config;
|
||||||
|
mps_limits->in_mps = (fifo_config->rx_fifo_lines - 2) * 4; // Two lines are reserved for status quadlets internally by USB_DWC
|
||||||
|
mps_limits->non_periodic_out_mps = fifo_config->nptx_fifo_lines * 4;
|
||||||
|
mps_limits->periodic_out_mps = fifo_config->ptx_fifo_lines * 4;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------- Host Port ------------------------------------------------------
|
// ---------------------------------------------------- Host Port ------------------------------------------------------
|
||||||
|
|
||||||
static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal)
|
static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal)
|
||||||
@ -193,7 +249,7 @@ static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal)
|
|||||||
|
|
||||||
void usb_dwc_hal_port_enable(usb_dwc_hal_context_t *hal)
|
void usb_dwc_hal_port_enable(usb_dwc_hal_context_t *hal)
|
||||||
{
|
{
|
||||||
usb_priv_speed_t speed = usb_dwc_ll_hprt_get_speed(hal->dev);
|
usb_dwc_speed_t speed = usb_dwc_ll_hprt_get_speed(hal->dev);
|
||||||
//Host Configuration
|
//Host Configuration
|
||||||
usb_dwc_ll_hcfg_set_defaults(hal->dev, speed);
|
usb_dwc_ll_hcfg_set_defaults(hal->dev, speed);
|
||||||
//Configure HFIR
|
//Configure HFIR
|
||||||
@ -238,7 +294,7 @@ bool usb_dwc_hal_chan_alloc(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan
|
|||||||
|
|
||||||
void usb_dwc_hal_chan_free(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj)
|
void usb_dwc_hal_chan_free(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj)
|
||||||
{
|
{
|
||||||
if (chan_obj->type == USB_PRIV_XFER_TYPE_INTR || chan_obj->type == USB_PRIV_XFER_TYPE_ISOCHRONOUS) {
|
if (chan_obj->type == USB_DWC_XFER_TYPE_INTR || chan_obj->type == USB_DWC_XFER_TYPE_ISOCHRONOUS) {
|
||||||
//Unschedule this channel
|
//Unschedule this channel
|
||||||
for (int i = 0; i < hal->frame_list_len; i++) {
|
for (int i = 0; i < hal->frame_list_len; i++) {
|
||||||
hal->periodic_frame_list[i] &= ~(1 << chan_obj->flags.chan_idx);
|
hal->periodic_frame_list[i] &= ~(1 << chan_obj->flags.chan_idx);
|
||||||
@ -271,7 +327,7 @@ void usb_dwc_hal_chan_set_ep_char(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t
|
|||||||
//Save channel type
|
//Save channel type
|
||||||
chan_obj->type = ep_char->type;
|
chan_obj->type = ep_char->type;
|
||||||
//If this is a periodic endpoint/channel, set its schedule in the frame list
|
//If this is a periodic endpoint/channel, set its schedule in the frame list
|
||||||
if (ep_char->type == USB_PRIV_XFER_TYPE_ISOCHRONOUS || ep_char->type == USB_PRIV_XFER_TYPE_INTR) {
|
if (ep_char->type == USB_DWC_XFER_TYPE_ISOCHRONOUS || ep_char->type == USB_DWC_XFER_TYPE_INTR) {
|
||||||
HAL_ASSERT((int)ep_char->periodic.interval <= (int)hal->frame_list_len); //Interval cannot exceed the length of the frame list
|
HAL_ASSERT((int)ep_char->periodic.interval <= (int)hal->frame_list_len); //Interval cannot exceed the length of the frame list
|
||||||
//Find the effective offset in the frame list (in case the phase_offset_frames > interval)
|
//Find the effective offset in the frame list (in case the phase_offset_frames > interval)
|
||||||
int offset = ep_char->periodic.phase_offset_frames % ep_char->periodic.interval;
|
int offset = ep_char->periodic.phase_offset_frames % ep_char->periodic.interval;
|
||||||
|
@ -42,10 +42,10 @@ void usb_phy_hal_int_load_conf_host(usb_phy_hal_context_t *hal)
|
|||||||
usb_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true);
|
usb_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_priv_speed_t speed)
|
void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_phy_speed_t speed)
|
||||||
{
|
{
|
||||||
// DEVICE - downstream
|
// DEVICE - downstream
|
||||||
if (speed == USB_PRIV_SPEED_LOW) {
|
if (speed == USB_PHY_SPEED_LOW) {
|
||||||
// LS: dm_pu = 1
|
// LS: dm_pu = 1
|
||||||
usb_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false);
|
usb_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,14 +12,11 @@
|
|||||||
#include "freertos/semphr.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 "soc/interrupts.h" // For interrupt index
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_rom_gpio.h"
|
|
||||||
#include "hal/usb_dwc_hal.h"
|
#include "hal/usb_dwc_hal.h"
|
||||||
#include "hal/usb_types_private.h"
|
#include "hal/usb_dwc_types.h"
|
||||||
#include "soc/gpio_pins.h"
|
|
||||||
#include "soc/gpio_sig_map.h"
|
|
||||||
#include "esp_private/periph_ctrl.h"
|
|
||||||
#include "hcd.h"
|
#include "hcd.h"
|
||||||
#include "usb_private.h"
|
#include "usb_private.h"
|
||||||
#include "usb/usb_types_ch9.h"
|
#include "usb/usb_types_ch9.h"
|
||||||
@ -36,102 +33,12 @@
|
|||||||
#define RESUME_RECOVERY_MS 20 // Resume recovery of at least 10ms. Make it 20 ms to be safe. This will include the 3 LS bit times of the EOP
|
#define RESUME_RECOVERY_MS 20 // Resume recovery of at least 10ms. Make it 20 ms to be safe. This will include the 3 LS bit times of the EOP
|
||||||
|
|
||||||
#define CTRL_EP_MAX_MPS_LS 8 // Largest Maximum Packet Size for Low Speed control endpoints
|
#define CTRL_EP_MAX_MPS_LS 8 // Largest Maximum Packet Size for Low Speed control endpoints
|
||||||
#define CTRL_EP_MAX_MPS_FS 64 // Largest Maximum Packet Size for Full Speed control endpoints
|
#define CTRL_EP_MAX_MPS_HSFS 64 // Largest Maximum Packet Size for High & Full Speed control endpoints
|
||||||
|
|
||||||
#define NUM_PORTS 1 // The controller only has one port.
|
#define NUM_PORTS 1 // The controller only has one port.
|
||||||
|
|
||||||
// ----------------------- Configs -------------------------
|
// ----------------------- Configs -------------------------
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int in_mps;
|
|
||||||
int non_periodic_out_mps;
|
|
||||||
int periodic_out_mps;
|
|
||||||
} fifo_mps_limits_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Default FIFO sizes (see 2.1.2.4 for programming guide)
|
|
||||||
*
|
|
||||||
* RXFIFO
|
|
||||||
* - Recommended: ((LPS/4) * 2) + 2
|
|
||||||
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 48 - 48 = 104
|
|
||||||
* - Worst case can accommodate two packets of 204 bytes, or one packet of 408
|
|
||||||
* NPTXFIFO
|
|
||||||
* - Recommended: (LPS/4) * 2
|
|
||||||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
|
|
||||||
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
|
|
||||||
* PTXFIFO
|
|
||||||
* - Recommended: (LPS/4) * 2
|
|
||||||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
|
|
||||||
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
|
|
||||||
*/
|
|
||||||
const usb_dwc_hal_fifo_config_t fifo_config_default = {
|
|
||||||
.rx_fifo_lines = 104,
|
|
||||||
.nptx_fifo_lines = 48,
|
|
||||||
.ptx_fifo_lines = 48,
|
|
||||||
};
|
|
||||||
|
|
||||||
const fifo_mps_limits_t mps_limits_default = {
|
|
||||||
.in_mps = 408,
|
|
||||||
.non_periodic_out_mps = 192,
|
|
||||||
.periodic_out_mps = 192,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FIFO sizes that bias to giving RX FIFO more capacity
|
|
||||||
*
|
|
||||||
* RXFIFO
|
|
||||||
* - Recommended: ((LPS/4) * 2) + 2
|
|
||||||
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 32 - 16 = 152
|
|
||||||
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
|
||||||
* NPTXFIFO
|
|
||||||
* - Recommended: (LPS/4) * 2
|
|
||||||
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
|
|
||||||
* - Worst case can accommodate one packet of 64 bytes
|
|
||||||
* PTXFIFO
|
|
||||||
* - Recommended: (LPS/4) * 2
|
|
||||||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 2 = 32
|
|
||||||
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
|
|
||||||
*/
|
|
||||||
const usb_dwc_hal_fifo_config_t fifo_config_bias_rx = {
|
|
||||||
.rx_fifo_lines = 152,
|
|
||||||
.nptx_fifo_lines = 16,
|
|
||||||
.ptx_fifo_lines = 32,
|
|
||||||
};
|
|
||||||
|
|
||||||
const fifo_mps_limits_t mps_limits_bias_rx = {
|
|
||||||
.in_mps = 600,
|
|
||||||
.non_periodic_out_mps = 64,
|
|
||||||
.periodic_out_mps = 128,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FIFO sizes that bias to giving Periodic TX FIFO more capacity (i.e., ISOC OUT)
|
|
||||||
*
|
|
||||||
* RXFIFO
|
|
||||||
* - Recommended: ((LPS/4) * 2) + 2
|
|
||||||
* - Actual: Assume LPS is 64, and 2 packets: ((64/4) * 2) + 2 = 34
|
|
||||||
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
|
|
||||||
* NPTXFIFO
|
|
||||||
* - Recommended: (LPS/4) * 2
|
|
||||||
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
|
|
||||||
* - Worst case can accommodate one packet of 64 bytes
|
|
||||||
* PTXFIFO
|
|
||||||
* - Recommended: (LPS/4) * 2
|
|
||||||
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 34 - 16 = 150
|
|
||||||
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
|
||||||
*/
|
|
||||||
const usb_dwc_hal_fifo_config_t fifo_config_bias_ptx = {
|
|
||||||
.rx_fifo_lines = 34,
|
|
||||||
.nptx_fifo_lines = 16,
|
|
||||||
.ptx_fifo_lines = 150,
|
|
||||||
};
|
|
||||||
|
|
||||||
const fifo_mps_limits_t mps_limits_bias_ptx = {
|
|
||||||
.in_mps = 128,
|
|
||||||
.non_periodic_out_mps = 64,
|
|
||||||
.periodic_out_mps = 600,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define FRAME_LIST_LEN USB_HAL_FRAME_LIST_LEN_32
|
#define FRAME_LIST_LEN USB_HAL_FRAME_LIST_LEN_32
|
||||||
#define NUM_BUFFERS 2
|
#define NUM_BUFFERS 2
|
||||||
|
|
||||||
@ -307,8 +214,7 @@ struct port_obj {
|
|||||||
} flags;
|
} flags;
|
||||||
bool initialized;
|
bool initialized;
|
||||||
// FIFO biasing related
|
// FIFO biasing related
|
||||||
const usb_dwc_hal_fifo_config_t *fifo_config;
|
usb_hal_fifo_bias_t fifo_bias; // Bias is saved so it can be reconfigured upon reset
|
||||||
const fifo_mps_limits_t *fifo_mps_limits;
|
|
||||||
// Port callback and context
|
// Port callback and context
|
||||||
hcd_port_callback_t callback;
|
hcd_port_callback_t callback;
|
||||||
void *callback_arg;
|
void *callback_arg;
|
||||||
@ -401,7 +307,7 @@ static void _buffer_exec(pipe_t *pipe);
|
|||||||
*/
|
*/
|
||||||
static inline bool _buffer_check_done(pipe_t *pipe)
|
static inline bool _buffer_check_done(pipe_t *pipe)
|
||||||
{
|
{
|
||||||
if (pipe->ep_char.type != USB_PRIV_XFER_TYPE_CTRL) {
|
if (pipe->ep_char.type != USB_DWC_XFER_TYPE_CTRL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Only control transfers need to be continued
|
// Only control transfers need to be continued
|
||||||
@ -757,6 +663,28 @@ static bool _internal_pipe_event_notify(pipe_t *pipe, bool from_isr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------- HAL <-> USB helpers --------------------
|
||||||
|
|
||||||
|
static usb_speed_t get_usb_port_speed(usb_dwc_speed_t priv)
|
||||||
|
{
|
||||||
|
switch (priv) {
|
||||||
|
case USB_DWC_SPEED_LOW: return USB_SPEED_LOW;
|
||||||
|
case USB_DWC_SPEED_FULL: return USB_SPEED_FULL;
|
||||||
|
case USB_DWC_SPEED_HIGH: return USB_SPEED_HIGH;
|
||||||
|
default: abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static usb_hal_fifo_bias_t get_hal_fifo_bias(hcd_port_fifo_bias_t public)
|
||||||
|
{
|
||||||
|
switch (public) {
|
||||||
|
case HCD_PORT_FIFO_BIAS_BALANCED: return USB_HAL_FIFO_BIAS_DEFAULT;
|
||||||
|
case HCD_PORT_FIFO_BIAS_RX: return USB_HAL_FIFO_BIAS_RX;
|
||||||
|
case HCD_PORT_FIFO_BIAS_PTX: return USB_HAL_FIFO_BIAS_PTX;
|
||||||
|
default: abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------- Interrupt Handlers --------------------
|
// ----------------- Interrupt Handlers --------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -784,7 +712,7 @@ static hcd_port_event_t _intr_hdlr_hprt(port_t *port, usb_dwc_hal_port_event_t h
|
|||||||
}
|
}
|
||||||
case USB_DWC_HAL_PORT_EVENT_ENABLED: {
|
case USB_DWC_HAL_PORT_EVENT_ENABLED: {
|
||||||
usb_dwc_hal_port_enable(port->hal); // Initialize remaining host port registers
|
usb_dwc_hal_port_enable(port->hal); // Initialize remaining host port registers
|
||||||
port->speed = (usb_dwc_hal_port_get_conn_speed(port->hal) == USB_PRIV_SPEED_FULL) ? USB_SPEED_FULL : USB_SPEED_LOW;
|
port->speed = get_usb_port_speed(usb_dwc_hal_port_get_conn_speed(port->hal));
|
||||||
port->state = HCD_PORT_STATE_ENABLED;
|
port->state = HCD_PORT_STATE_ENABLED;
|
||||||
port->flags.conn_dev_ena = 1;
|
port->flags.conn_dev_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.
|
||||||
@ -1210,7 +1138,7 @@ static esp_err_t _port_cmd_reset(port_t *port)
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
// Set FIFO sizes based on the selected biasing
|
// Set FIFO sizes based on the selected biasing
|
||||||
usb_dwc_hal_set_fifo_size(port->hal, port->fifo_config);
|
usb_dwc_hal_set_fifo_bias(port->hal, port->fifo_bias);
|
||||||
// We start periodic scheduling only after a RESET command since SOFs only start after a reset
|
// We start periodic scheduling only after a RESET command since SOFs only start after a reset
|
||||||
usb_dwc_hal_port_set_frame_list(port->hal, port->frame_list, FRAME_LIST_LEN);
|
usb_dwc_hal_port_set_frame_list(port->hal, port->frame_list, FRAME_LIST_LEN);
|
||||||
usb_dwc_hal_port_periodic_enable(port->hal);
|
usb_dwc_hal_port_periodic_enable(port->hal);
|
||||||
@ -1307,29 +1235,6 @@ esp_err_t hcd_port_init(int port_number, const hcd_port_config_t *port_config, h
|
|||||||
HCD_CHECK(port_number > 0 && port_config != NULL && port_hdl != NULL, ESP_ERR_INVALID_ARG);
|
HCD_CHECK(port_number > 0 && port_config != NULL && port_hdl != NULL, ESP_ERR_INVALID_ARG);
|
||||||
HCD_CHECK(port_number <= NUM_PORTS, ESP_ERR_NOT_FOUND);
|
HCD_CHECK(port_number <= NUM_PORTS, ESP_ERR_NOT_FOUND);
|
||||||
|
|
||||||
// Get a pointer to the correct FIFO bias constant values
|
|
||||||
const usb_dwc_hal_fifo_config_t *fifo_config;
|
|
||||||
const fifo_mps_limits_t *mps_limits;
|
|
||||||
switch (port_config->fifo_bias) {
|
|
||||||
case HCD_PORT_FIFO_BIAS_BALANCED:
|
|
||||||
fifo_config = &fifo_config_default;
|
|
||||||
mps_limits = &mps_limits_default;
|
|
||||||
break;
|
|
||||||
case HCD_PORT_FIFO_BIAS_RX:
|
|
||||||
fifo_config = &fifo_config_bias_rx;
|
|
||||||
mps_limits = &mps_limits_bias_rx;
|
|
||||||
break;
|
|
||||||
case HCD_PORT_FIFO_BIAS_PTX:
|
|
||||||
fifo_config = &fifo_config_bias_ptx;
|
|
||||||
mps_limits = &mps_limits_bias_ptx;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fifo_config = NULL;
|
|
||||||
mps_limits = NULL;
|
|
||||||
abort();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
HCD_ENTER_CRITICAL();
|
HCD_ENTER_CRITICAL();
|
||||||
HCD_CHECK_FROM_CRIT(s_hcd_obj != NULL && !s_hcd_obj->port_obj->initialized, ESP_ERR_INVALID_STATE);
|
HCD_CHECK_FROM_CRIT(s_hcd_obj != NULL && !s_hcd_obj->port_obj->initialized, ESP_ERR_INVALID_STATE);
|
||||||
// Port object memory and resources (such as the mutex) already be allocated. Just need to initialize necessary fields only
|
// Port object memory and resources (such as the mutex) already be allocated. Just need to initialize necessary fields only
|
||||||
@ -1338,8 +1243,7 @@ esp_err_t hcd_port_init(int port_number, const hcd_port_config_t *port_config, h
|
|||||||
TAILQ_INIT(&port_obj->pipes_active_tailq);
|
TAILQ_INIT(&port_obj->pipes_active_tailq);
|
||||||
port_obj->state = HCD_PORT_STATE_NOT_POWERED;
|
port_obj->state = HCD_PORT_STATE_NOT_POWERED;
|
||||||
port_obj->last_event = HCD_PORT_EVENT_NONE;
|
port_obj->last_event = HCD_PORT_EVENT_NONE;
|
||||||
port_obj->fifo_config = fifo_config;
|
port_obj->fifo_bias = get_hal_fifo_bias(port_config->fifo_bias);
|
||||||
port_obj->fifo_mps_limits = mps_limits;
|
|
||||||
port_obj->callback = port_config->callback;
|
port_obj->callback = port_config->callback;
|
||||||
port_obj->callback_arg = port_config->callback_arg;
|
port_obj->callback_arg = port_config->callback_arg;
|
||||||
port_obj->context = port_config->context;
|
port_obj->context = port_config->context;
|
||||||
@ -1431,12 +1335,7 @@ 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 device connected to the port that has been reset
|
// Device speed is only valid if there is device connected to the port that has been reset
|
||||||
HCD_CHECK_FROM_CRIT(port->flags.conn_dev_ena, ESP_ERR_INVALID_STATE);
|
HCD_CHECK_FROM_CRIT(port->flags.conn_dev_ena, ESP_ERR_INVALID_STATE);
|
||||||
usb_priv_speed_t hal_speed = usb_dwc_hal_port_get_conn_speed(port->hal);
|
*speed = get_usb_port_speed(usb_dwc_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;
|
||||||
}
|
}
|
||||||
@ -1512,37 +1411,16 @@ void *hcd_port_get_context(hcd_port_handle_t port_hdl)
|
|||||||
esp_err_t hcd_port_set_fifo_bias(hcd_port_handle_t port_hdl, hcd_port_fifo_bias_t bias)
|
esp_err_t hcd_port_set_fifo_bias(hcd_port_handle_t port_hdl, hcd_port_fifo_bias_t bias)
|
||||||
{
|
{
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
// Get a pointer to the correct FIFO bias constant values
|
usb_hal_fifo_bias_t hal_bias = get_hal_fifo_bias(bias);
|
||||||
const usb_dwc_hal_fifo_config_t *fifo_config;
|
|
||||||
const fifo_mps_limits_t *mps_limits;
|
|
||||||
switch (bias) {
|
|
||||||
case HCD_PORT_FIFO_BIAS_BALANCED:
|
|
||||||
fifo_config = &fifo_config_default;
|
|
||||||
mps_limits = &mps_limits_default;
|
|
||||||
break;
|
|
||||||
case HCD_PORT_FIFO_BIAS_RX:
|
|
||||||
fifo_config = &fifo_config_bias_rx;
|
|
||||||
mps_limits = &mps_limits_bias_rx;
|
|
||||||
break;
|
|
||||||
case HCD_PORT_FIFO_BIAS_PTX:
|
|
||||||
fifo_config = &fifo_config_bias_ptx;
|
|
||||||
mps_limits = &mps_limits_bias_ptx;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fifo_config = NULL;
|
|
||||||
mps_limits = NULL;
|
|
||||||
abort();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Configure the new FIFO sizes and store the pointers
|
// Configure the new FIFO sizes and store the pointers
|
||||||
port_t *port = (port_t *)port_hdl;
|
port_t *port = (port_t *)port_hdl;
|
||||||
xSemaphoreTake(port->port_mux, portMAX_DELAY);
|
xSemaphoreTake(port->port_mux, portMAX_DELAY);
|
||||||
HCD_ENTER_CRITICAL();
|
HCD_ENTER_CRITICAL();
|
||||||
// Check that port is in the correct state to update FIFO sizes
|
// Check that port is in the correct state to update FIFO sizes
|
||||||
if (port->initialized && !port->flags.event_pending && port->num_pipes_idle == 0 && port->num_pipes_queued == 0) {
|
if (port->initialized && !port->flags.event_pending && port->num_pipes_idle == 0 && port->num_pipes_queued == 0) {
|
||||||
usb_dwc_hal_set_fifo_size(port->hal, fifo_config);
|
usb_dwc_hal_set_fifo_bias(port->hal, hal_bias);
|
||||||
port->fifo_config = fifo_config;
|
port->fifo_bias = hal_bias;
|
||||||
port->fifo_mps_limits = mps_limits;
|
|
||||||
ret = ESP_OK;
|
ret = ESP_OK;
|
||||||
} else {
|
} else {
|
||||||
ret = ESP_ERR_INVALID_STATE;
|
ret = ESP_ERR_INVALID_STATE;
|
||||||
@ -1629,10 +1507,14 @@ static bool pipe_args_usb_compliance_verification(const hcd_pipe_config_t *pipe_
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pipe_alloc_hcd_support_verification(const usb_ep_desc_t *ep_desc, const fifo_mps_limits_t *mps_limits)
|
static bool pipe_alloc_hcd_support_verification(usb_dwc_hal_context_t *hal, const usb_ep_desc_t * ep_desc)
|
||||||
{
|
{
|
||||||
|
assert(hal != NULL);
|
||||||
assert(ep_desc != NULL);
|
assert(ep_desc != NULL);
|
||||||
usb_transfer_type_t type = USB_EP_DESC_GET_XFERTYPE(ep_desc);
|
|
||||||
|
usb_hal_fifo_mps_limits_t mps_limits = {0};
|
||||||
|
usb_dwc_hal_get_mps_limits(hal, &mps_limits);
|
||||||
|
const usb_transfer_type_t type = USB_EP_DESC_GET_XFERTYPE(ep_desc);
|
||||||
|
|
||||||
// Check the pipe's interval is not zero
|
// Check the pipe's interval is not zero
|
||||||
if ((type == USB_TRANSFER_TYPE_INTR || type == USB_TRANSFER_TYPE_ISOCHRONOUS) &&
|
if ((type == USB_TRANSFER_TYPE_INTR || type == USB_TRANSFER_TYPE_ISOCHRONOUS) &&
|
||||||
@ -1645,12 +1527,12 @@ static bool pipe_alloc_hcd_support_verification(const usb_ep_desc_t *ep_desc, co
|
|||||||
// Check if pipe MPS exceeds HCD MPS limits (due to DWC FIFO sizing)
|
// Check if pipe MPS exceeds HCD MPS limits (due to DWC FIFO sizing)
|
||||||
int limit;
|
int limit;
|
||||||
if (USB_EP_DESC_GET_EP_DIR(ep_desc)) { // IN
|
if (USB_EP_DESC_GET_EP_DIR(ep_desc)) { // IN
|
||||||
limit = mps_limits->in_mps;
|
limit = mps_limits.in_mps;
|
||||||
} else { // OUT
|
} else { // OUT
|
||||||
if (type == USB_TRANSFER_TYPE_CTRL || type == USB_TRANSFER_TYPE_BULK) {
|
if (type == USB_TRANSFER_TYPE_CTRL || type == USB_TRANSFER_TYPE_BULK) {
|
||||||
limit = mps_limits->non_periodic_out_mps;
|
limit = mps_limits.non_periodic_out_mps;
|
||||||
} else {
|
} else {
|
||||||
limit = mps_limits->periodic_out_mps;
|
limit = mps_limits.periodic_out_mps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1667,26 +1549,26 @@ static bool pipe_alloc_hcd_support_verification(const usb_ep_desc_t *ep_desc, co
|
|||||||
static void pipe_set_ep_char(const hcd_pipe_config_t *pipe_config, usb_transfer_type_t type, bool is_default_pipe, int pipe_idx, usb_speed_t port_speed, usb_dwc_hal_ep_char_t *ep_char)
|
static void pipe_set_ep_char(const hcd_pipe_config_t *pipe_config, usb_transfer_type_t type, bool is_default_pipe, int pipe_idx, usb_speed_t port_speed, usb_dwc_hal_ep_char_t *ep_char)
|
||||||
{
|
{
|
||||||
// Initialize EP characteristics
|
// Initialize EP characteristics
|
||||||
usb_priv_xfer_type_t hal_xfer_type;
|
usb_dwc_xfer_type_t hal_xfer_type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case USB_TRANSFER_TYPE_CTRL:
|
case USB_TRANSFER_TYPE_CTRL:
|
||||||
hal_xfer_type = USB_PRIV_XFER_TYPE_CTRL;
|
hal_xfer_type = USB_DWC_XFER_TYPE_CTRL;
|
||||||
break;
|
break;
|
||||||
case USB_TRANSFER_TYPE_ISOCHRONOUS:
|
case USB_TRANSFER_TYPE_ISOCHRONOUS:
|
||||||
hal_xfer_type = USB_PRIV_XFER_TYPE_ISOCHRONOUS;
|
hal_xfer_type = USB_DWC_XFER_TYPE_ISOCHRONOUS;
|
||||||
break;
|
break;
|
||||||
case USB_TRANSFER_TYPE_BULK:
|
case USB_TRANSFER_TYPE_BULK:
|
||||||
hal_xfer_type = USB_PRIV_XFER_TYPE_BULK;
|
hal_xfer_type = USB_DWC_XFER_TYPE_BULK;
|
||||||
break;
|
break;
|
||||||
default: // USB_TRANSFER_TYPE_INTR
|
default: // USB_TRANSFER_TYPE_INTR
|
||||||
hal_xfer_type = USB_PRIV_XFER_TYPE_INTR;
|
hal_xfer_type = USB_DWC_XFER_TYPE_INTR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ep_char->type = hal_xfer_type;
|
ep_char->type = hal_xfer_type;
|
||||||
if (is_default_pipe) {
|
if (is_default_pipe) {
|
||||||
ep_char->bEndpointAddress = 0;
|
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
|
||||||
ep_char->mps = (pipe_config->dev_speed == USB_SPEED_FULL) ? CTRL_EP_MAX_MPS_FS : CTRL_EP_MAX_MPS_LS;
|
ep_char->mps = (pipe_config->dev_speed == USB_SPEED_LOW) ? CTRL_EP_MAX_MPS_LS : CTRL_EP_MAX_MPS_HSFS;
|
||||||
} else {
|
} else {
|
||||||
ep_char->bEndpointAddress = pipe_config->ep_desc->bEndpointAddress;
|
ep_char->bEndpointAddress = pipe_config->ep_desc->bEndpointAddress;
|
||||||
ep_char->mps = pipe_config->ep_desc->wMaxPacketSize;
|
ep_char->mps = pipe_config->ep_desc->wMaxPacketSize;
|
||||||
@ -1780,7 +1662,7 @@ static esp_err_t _pipe_cmd_flush(pipe_t *pipe)
|
|||||||
// URBs were never executed, Update the actual_num_bytes and status
|
// URBs were never executed, Update the actual_num_bytes and status
|
||||||
urb->transfer.actual_num_bytes = 0;
|
urb->transfer.actual_num_bytes = 0;
|
||||||
urb->transfer.status = (canceled) ? USB_TRANSFER_STATUS_CANCELED : USB_TRANSFER_STATUS_NO_DEVICE;
|
urb->transfer.status = (canceled) ? USB_TRANSFER_STATUS_CANCELED : USB_TRANSFER_STATUS_NO_DEVICE;
|
||||||
if (pipe->ep_char.type == USB_PRIV_XFER_TYPE_ISOCHRONOUS) {
|
if (pipe->ep_char.type == USB_DWC_XFER_TYPE_ISOCHRONOUS) {
|
||||||
// Update the URB's isoc packet descriptors as well
|
// Update the URB's isoc packet descriptors as well
|
||||||
for (int pkt_idx = 0; pkt_idx < urb->transfer.num_isoc_packets; pkt_idx++) {
|
for (int pkt_idx = 0; pkt_idx < urb->transfer.num_isoc_packets; pkt_idx++) {
|
||||||
urb->transfer.isoc_packet_desc[pkt_idx].actual_num_bytes = 0;
|
urb->transfer.isoc_packet_desc[pkt_idx].actual_num_bytes = 0;
|
||||||
@ -1840,7 +1722,6 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
|
|||||||
// Can only allocate a pipe if the target port is initialized and connected to an enabled device
|
// Can only allocate a pipe if the target port is initialized and connected to an enabled device
|
||||||
HCD_CHECK_FROM_CRIT(port->initialized && port->flags.conn_dev_ena, ESP_ERR_INVALID_STATE);
|
HCD_CHECK_FROM_CRIT(port->initialized && port->flags.conn_dev_ena, ESP_ERR_INVALID_STATE);
|
||||||
usb_speed_t port_speed = port->speed;
|
usb_speed_t port_speed = port->speed;
|
||||||
const fifo_mps_limits_t *mps_limits = port->fifo_mps_limits;
|
|
||||||
int pipe_idx = port->num_pipes_idle + port->num_pipes_queued;
|
int pipe_idx = port->num_pipes_idle + port->num_pipes_queued;
|
||||||
HCD_EXIT_CRITICAL();
|
HCD_EXIT_CRITICAL();
|
||||||
|
|
||||||
@ -1861,7 +1742,7 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
|
|||||||
return ESP_ERR_NOT_SUPPORTED;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
// Default pipes have a NULL ep_desc thus should skip the HCD support verification
|
// Default pipes have a NULL ep_desc thus should skip the HCD support verification
|
||||||
if (!is_default && !pipe_alloc_hcd_support_verification(pipe_config->ep_desc, mps_limits)) {
|
if (!is_default && !pipe_alloc_hcd_support_verification(port->hal, pipe_config->ep_desc)) {
|
||||||
return ESP_ERR_NOT_SUPPORTED;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
// Allocate the pipe resources
|
// Allocate the pipe resources
|
||||||
@ -2230,11 +2111,11 @@ static void _buffer_fill(pipe_t *pipe)
|
|||||||
int mps = pipe->ep_char.mps;
|
int mps = pipe->ep_char.mps;
|
||||||
usb_transfer_t *transfer = &urb->transfer;
|
usb_transfer_t *transfer = &urb->transfer;
|
||||||
switch (pipe->ep_char.type) {
|
switch (pipe->ep_char.type) {
|
||||||
case USB_PRIV_XFER_TYPE_CTRL: {
|
case USB_DWC_XFER_TYPE_CTRL: {
|
||||||
_buffer_fill_ctrl(buffer_to_fill, transfer);
|
_buffer_fill_ctrl(buffer_to_fill, transfer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_ISOCHRONOUS: {
|
case USB_DWC_XFER_TYPE_ISOCHRONOUS: {
|
||||||
uint32_t start_idx;
|
uint32_t start_idx;
|
||||||
if (pipe->multi_buffer_control.buffer_num_to_exec == 0) {
|
if (pipe->multi_buffer_control.buffer_num_to_exec == 0) {
|
||||||
// There are no more previously filled buffers to execute. We need to calculate a new start index based on HFNUM and the pipe's schedule
|
// There are no more previously filled buffers to execute. We need to calculate a new start index based on HFNUM and the pipe's schedule
|
||||||
@ -2260,11 +2141,11 @@ static void _buffer_fill(pipe_t *pipe)
|
|||||||
_buffer_fill_isoc(buffer_to_fill, transfer, is_in, mps, (int)pipe->ep_char.periodic.interval, start_idx);
|
_buffer_fill_isoc(buffer_to_fill, transfer, is_in, mps, (int)pipe->ep_char.periodic.interval, start_idx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_BULK: {
|
case USB_DWC_XFER_TYPE_BULK: {
|
||||||
_buffer_fill_bulk(buffer_to_fill, transfer, is_in, mps);
|
_buffer_fill_bulk(buffer_to_fill, transfer, is_in, mps);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_INTR: {
|
case USB_DWC_XFER_TYPE_INTR: {
|
||||||
_buffer_fill_intr(buffer_to_fill, transfer, is_in, mps);
|
_buffer_fill_intr(buffer_to_fill, transfer, is_in, mps);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2290,7 +2171,7 @@ static void _buffer_exec(pipe_t *pipe)
|
|||||||
uint32_t start_idx;
|
uint32_t start_idx;
|
||||||
int desc_list_len;
|
int desc_list_len;
|
||||||
switch (pipe->ep_char.type) {
|
switch (pipe->ep_char.type) {
|
||||||
case USB_PRIV_XFER_TYPE_CTRL: {
|
case USB_DWC_XFER_TYPE_CTRL: {
|
||||||
start_idx = 0;
|
start_idx = 0;
|
||||||
desc_list_len = XFER_LIST_LEN_CTRL;
|
desc_list_len = XFER_LIST_LEN_CTRL;
|
||||||
// Set the channel's direction to OUT and PID to 0 respectively for the the setup stage
|
// Set the channel's direction to OUT and PID to 0 respectively for the the setup stage
|
||||||
@ -2298,17 +2179,17 @@ static void _buffer_exec(pipe_t *pipe)
|
|||||||
usb_dwc_hal_chan_set_pid(pipe->chan_obj, 0); // Setup stage always has a PID of DATA0
|
usb_dwc_hal_chan_set_pid(pipe->chan_obj, 0); // Setup stage always has a PID of DATA0
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_ISOCHRONOUS: {
|
case USB_DWC_XFER_TYPE_ISOCHRONOUS: {
|
||||||
start_idx = buffer_to_exec->flags.isoc.start_idx;
|
start_idx = buffer_to_exec->flags.isoc.start_idx;
|
||||||
desc_list_len = XFER_LIST_LEN_ISOC;
|
desc_list_len = XFER_LIST_LEN_ISOC;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_BULK: {
|
case USB_DWC_XFER_TYPE_BULK: {
|
||||||
start_idx = 0;
|
start_idx = 0;
|
||||||
desc_list_len = (buffer_to_exec->flags.bulk.zero_len_packet) ? XFER_LIST_LEN_BULK : 1;
|
desc_list_len = (buffer_to_exec->flags.bulk.zero_len_packet) ? XFER_LIST_LEN_BULK : 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_INTR: {
|
case USB_DWC_XFER_TYPE_INTR: {
|
||||||
start_idx = 0;
|
start_idx = 0;
|
||||||
desc_list_len = (buffer_to_exec->flags.intr.zero_len_packet) ? buffer_to_exec->flags.intr.num_qtds + 1 : buffer_to_exec->flags.intr.num_qtds;
|
desc_list_len = (buffer_to_exec->flags.intr.zero_len_packet) ? buffer_to_exec->flags.intr.num_qtds + 1 : buffer_to_exec->flags.intr.num_qtds;
|
||||||
break;
|
break;
|
||||||
@ -2329,7 +2210,7 @@ static void _buffer_exec(pipe_t *pipe)
|
|||||||
static void _buffer_exec_cont(pipe_t *pipe)
|
static void _buffer_exec_cont(pipe_t *pipe)
|
||||||
{
|
{
|
||||||
// This should only ever be called on control transfers
|
// This should only ever be called on control transfers
|
||||||
assert(pipe->ep_char.type == USB_PRIV_XFER_TYPE_CTRL);
|
assert(pipe->ep_char.type == USB_DWC_XFER_TYPE_CTRL);
|
||||||
dma_buffer_block_t *buffer_inflight = pipe->buffers[pipe->multi_buffer_control.rd_idx];
|
dma_buffer_block_t *buffer_inflight = pipe->buffers[pipe->multi_buffer_control.rd_idx];
|
||||||
bool next_dir_is_in;
|
bool next_dir_is_in;
|
||||||
int next_pid;
|
int next_pid;
|
||||||
@ -2513,19 +2394,19 @@ static void _buffer_parse(pipe_t *pipe)
|
|||||||
if (buffer_to_parse->status_flags.pipe_event == HCD_PIPE_EVENT_URB_DONE) {
|
if (buffer_to_parse->status_flags.pipe_event == HCD_PIPE_EVENT_URB_DONE) {
|
||||||
// URB was successful
|
// URB was successful
|
||||||
switch (pipe->ep_char.type) {
|
switch (pipe->ep_char.type) {
|
||||||
case USB_PRIV_XFER_TYPE_CTRL: {
|
case USB_DWC_XFER_TYPE_CTRL: {
|
||||||
_buffer_parse_ctrl(buffer_to_parse);
|
_buffer_parse_ctrl(buffer_to_parse);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_ISOCHRONOUS: {
|
case USB_DWC_XFER_TYPE_ISOCHRONOUS: {
|
||||||
_buffer_parse_isoc(buffer_to_parse, is_in);
|
_buffer_parse_isoc(buffer_to_parse, is_in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_BULK: {
|
case USB_DWC_XFER_TYPE_BULK: {
|
||||||
_buffer_parse_bulk(buffer_to_parse);
|
_buffer_parse_bulk(buffer_to_parse);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case USB_PRIV_XFER_TYPE_INTR: {
|
case USB_DWC_XFER_TYPE_INTR: {
|
||||||
_buffer_parse_intr(buffer_to_parse, is_in, mps);
|
_buffer_parse_intr(buffer_to_parse, is_in, mps);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -24,6 +24,7 @@ extern "C" {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
USB_SPEED_LOW = 0, /**< USB Low Speed (1.5 Mbit/s) */
|
USB_SPEED_LOW = 0, /**< USB Low Speed (1.5 Mbit/s) */
|
||||||
USB_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */
|
USB_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */
|
||||||
|
USB_SPEED_HIGH, /**< USB High Speed (480 Mbit/s) */
|
||||||
} usb_speed_t;
|
} usb_speed_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,13 +141,7 @@ esp_err_t usb_phy_otg_dev_set_speed(usb_phy_handle_t handle, usb_phy_speed_t spe
|
|||||||
USBPHY_TAG, "set speed not supported");
|
USBPHY_TAG, "set speed not supported");
|
||||||
|
|
||||||
handle->otg_speed = speed;
|
handle->otg_speed = speed;
|
||||||
usb_priv_speed_t hal_speed = 0;
|
usb_phy_hal_int_load_conf_dev(&(handle->hal_context), speed);
|
||||||
if (speed == USB_PHY_SPEED_LOW) {
|
|
||||||
hal_speed = USB_PRIV_SPEED_LOW;
|
|
||||||
} else if (speed == USB_PHY_SPEED_FULL) {
|
|
||||||
hal_speed = USB_PRIV_SPEED_FULL;
|
|
||||||
}
|
|
||||||
usb_phy_hal_int_load_conf_dev(&(handle->hal_context), hal_speed);
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user