first commit for chrg
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# Note
|
||||
|
||||
Please note that host must support dma mode.
|
||||
|
||||
## Support Chip List
|
||||
|
||||
### STM32
|
||||
|
||||
**有且仅有 PB14/PB15 引脚支持 host 模式, 部分 F7/H7 可能 PA11/PA12 也支持**。
|
||||
|
||||
- STM32F105xc、STM32F107xc
|
||||
- STM32F205xx、STM32F207xx、STM32F215xx、STM32F217xx
|
||||
- STM32F401xc、STM32F401xe、STM32F405xx、STM32F407xx、STM32F411xe、STM32F412cx、STM32F412rx、STM32F412vx、STM32F412zx、STM32F413xx、STM32F415xx、STM32F417xx、STM32F423xx、STM32F423xx、STM32F429xx、STM32F437xx、STM32F439xx、STM32F446xx、STM32F469xx、STM32F479xx
|
||||
- STM32F7xx
|
||||
- STM32H7xx
|
||||
- STM32L4xx
|
||||
- STM32U5xx
|
||||
|
||||
### AT32
|
||||
|
||||
**有且仅有 AT32F405xx PB14/PB15引脚支持 host 模式**。
|
||||
|
||||
- AT32F402xx、AT32F405xx、AT32F415xx、AT32F423xx、AT32F425xx、AT32F435xx、AT32F437xx
|
||||
|
||||
### GD32
|
||||
|
||||
**由于无法读取 DWC2 配置信息,并且有部分寄存器是非标准的,因此暂时无法支持 GD 系列**。
|
||||
|
||||
- GD32F30X_CL
|
||||
- GD32F405、GD32F407
|
||||
- GD32F350、GD32F450
|
||||
|
||||
### HC32
|
||||
|
||||
- HC32F4A0
|
||||
|
||||
### Espressif
|
||||
|
||||
- ESP32S2、ESP32S3、ESP32P4
|
||||
|
||||
### Sophgo
|
||||
|
||||
- CV18xx
|
||||
|
||||
### Kendryte
|
||||
|
||||
- K230
|
||||
|
||||
### Nationstech
|
||||
|
||||
- N32H4X
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef __USB_DWC2_PARAM_H__
|
||||
#define __USB_DWC2_PARAM_H__
|
||||
|
||||
/* Maximum number of Endpoints/HostChannels */
|
||||
#define MAX_EPS_CHANNELS 16
|
||||
|
||||
#define HSOTG_REG(x) (x)
|
||||
|
||||
#define dwc2_readl(addr) \
|
||||
(*(volatile uint32_t *)(addr))
|
||||
|
||||
#define GUID_OFFSET HSOTG_REG(0x003C)
|
||||
|
||||
#define GSNPSID_OFFSET HSOTG_REG(0x0040)
|
||||
#define GSNPSID_ID_MASK (0xFFFF0000UL)
|
||||
|
||||
#define GHWCFG1_OFFSET HSOTG_REG(0x0044)
|
||||
|
||||
#define GHWCFG2_OFFSET HSOTG_REG(0x0048)
|
||||
#define GHWCFG2_OTG_ENABLE_IC_USB (0x01UL << 31U)
|
||||
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1FUL << 26U)
|
||||
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT (26U)
|
||||
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x03UL << 24U)
|
||||
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT (24U)
|
||||
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x03UL << 22U)
|
||||
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT (22U)
|
||||
#define GHWCFG2_MULTI_PROC_INT (0x01UL << 20U)
|
||||
#define GHWCFG2_DYNAMIC_FIFO (0x01UL << 19U)
|
||||
#define GHWCFG2_PERIO_EP_SUPPORTED (0x01UL << 18U)
|
||||
#define GHWCFG2_NUM_HOST_CHAN_MASK (0x0FUL << 14U)
|
||||
#define GHWCFG2_NUM_HOST_CHAN_SHIFT (14U)
|
||||
#define GHWCFG2_NUM_DEV_EP_MASK (0x0FUL << 10U)
|
||||
#define GHWCFG2_NUM_DEV_EP_SHIFT (10U)
|
||||
#define GHWCFG2_FS_PHY_TYPE_MASK (0x03UL << 8U)
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHIFT (8U)
|
||||
#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED (0x00UL)
|
||||
#define GHWCFG2_FS_PHY_TYPE_DEDICATED (0x01UL)
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI (0x02UL)
|
||||
#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI (0x03UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_MASK (0x03UL << 6U)
|
||||
#define GHWCFG2_HS_PHY_TYPE_SHIFT (6U)
|
||||
#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED (0x00UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_UTMI (0x01UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_ULPI (0x02UL)
|
||||
#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI (0x03UL)
|
||||
#define GHWCFG2_POINT2POINT (0x01UL << 5U)
|
||||
#define GHWCFG2_ARCHITECTURE_MASK (0x03UL << 3U)
|
||||
#define GHWCFG2_ARCHITECTURE_SHIFT (3U)
|
||||
#define GHWCFG2_SLAVE_ONLY_ARCH (0x00UL)
|
||||
#define GHWCFG2_EXT_DMA_ARCH (0x01UL)
|
||||
#define GHWCFG2_INT_DMA_ARCH (0x02UL)
|
||||
#define GHWCFG2_OP_MODE_MASK (0x07UL << 0U)
|
||||
#define GHWCFG2_OP_MODE_SHIFT (0U)
|
||||
#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE (0x00UL)
|
||||
#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE (0x01UL)
|
||||
#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE (0x02UL)
|
||||
#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE (0x03UL)
|
||||
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE (0x04UL)
|
||||
#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST (0x05UL)
|
||||
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST (0x06UL)
|
||||
#define GHWCFG2_OP_MODE_UNDEFINED (0x07UL)
|
||||
|
||||
#define GHWCFG3_OFFSET HSOTG_REG(0x004C)
|
||||
#define GHWCFG3_DFIFO_DEPTH_MASK (0xFFFFUL << 16U)
|
||||
#define GHWCFG3_DFIFO_DEPTH_SHIFT (16U)
|
||||
#define GHWCFG3_OTG_LPM_EN (0x0001UL << 15U)
|
||||
#define GHWCFG3_BC_SUPPORT (0x0001UL << 14U)
|
||||
#define GHWCFG3_OTG_ENABLE_HSIC (0x0001UL << 13U)
|
||||
#define GHWCFG3_ADP_SUPP (0x0001UL << 12U)
|
||||
#define GHWCFG3_SYNCH_RESET_TYPE (0x0001UL << 11U)
|
||||
#define GHWCFG3_OPTIONAL_FEATURES (0x0001UL << 10U)
|
||||
#define GHWCFG3_VENDOR_CTRL_IF (0x0001UL << 9U)
|
||||
#define GHWCFG3_I2C (0x0001UL << 8U)
|
||||
#define GHWCFG3_OTG_FUNC (0x0001UL << 7U)
|
||||
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x0007UL << 4U)
|
||||
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT (4U)
|
||||
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0x000FUL << 0U)
|
||||
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT (0U)
|
||||
|
||||
#define GHWCFG4_OFFSET HSOTG_REG(0x0050)
|
||||
#define GHWCFG4_DESC_DMA_DYN (0x1UL << 31U)
|
||||
#define GHWCFG4_DESC_DMA (0x1UL << 30U)
|
||||
#define GHWCFG4_NUM_IN_EPS_MASK (0xFUL << 26U)
|
||||
#define GHWCFG4_NUM_IN_EPS_SHIFT (26U)
|
||||
#define GHWCFG4_DED_FIFO_EN (0x1UL << 25U)
|
||||
#define GHWCFG4_DED_FIFO_SHIFT (25U)
|
||||
#define GHWCFG4_SESSION_END_FILT_EN (0x1UL << 24U)
|
||||
#define GHWCFG4_B_VALID_FILT_EN (0x1UL << 23U)
|
||||
#define GHWCFG4_A_VALID_FILT_EN (0x1UL << 22U)
|
||||
#define GHWCFG4_VBUS_VALID_FILT_EN (0x1UL << 21U)
|
||||
#define GHWCFG4_IDDIG_FILT_EN (0x1UL << 20U)
|
||||
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xFUL << 16U)
|
||||
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT (16U)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3UL << 14U)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT (14U)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 (0x0UL)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 (0x1UL)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 (0x2UL)
|
||||
#define GHWCFG4_ACG_SUPPORTED (0x1UL << 12U)
|
||||
#define GHWCFG4_IPG_ISOC_SUPPORTED (0x1UL << 11U)
|
||||
#define GHWCFG4_SERVICE_INTERVAL_SUPPORTED (0x1UL << 10U)
|
||||
#define GHWCFG4_XHIBER (0x1UL << 7U)
|
||||
#define GHWCFG4_HIBER (0x1UL << 6U)
|
||||
#define GHWCFG4_MIN_AHB_FREQ (0x1UL << 5U)
|
||||
#define GHWCFG4_POWER_OPTIMIZ (0x1UL << 4U)
|
||||
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xFUL << 0U)
|
||||
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT (0U)
|
||||
|
||||
/**
|
||||
* struct dwc2_hw_params - Autodetected parameters.
|
||||
*
|
||||
* These parameters are the various parameters read from hardware
|
||||
* registers during initialization. They typically contain the best
|
||||
* supported or maximum value that can be configured in the
|
||||
* corresponding dwc2_core_params value.
|
||||
*
|
||||
* The values that are not in dwc2_core_params are documented below.
|
||||
*
|
||||
* @snpsid: Value from SNPSID register
|
||||
* @dev_ep_dirs: Direction of device endpoints (GHWCFG1)
|
||||
*
|
||||
* @op_mode: Mode of Operation
|
||||
* 0 - HNP- and SRP-Capable OTG (Host & Device)
|
||||
* 1 - SRP-Capable OTG (Host & Device)
|
||||
* 2 - Non-HNP and Non-SRP Capable OTG (Host & Device)
|
||||
* 3 - SRP-Capable Device
|
||||
* 4 - Non-OTG Device
|
||||
* 5 - SRP-Capable Host
|
||||
* 6 - Non-OTG Host
|
||||
* @arch: Architecture
|
||||
* 0 - Slave only
|
||||
* 1 - External DMA
|
||||
* 2 - Internal DMA
|
||||
* @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters
|
||||
* 1 - Allow dynamic FIFO sizing (default, if available)
|
||||
* @host_channels: The number of host channel registers to use
|
||||
* 1 to 16
|
||||
* @hs_phy_type: High-speed PHY interface type
|
||||
* 0 - High-speed interface not supported
|
||||
* 1 - UTMI+
|
||||
* 2 - ULPI
|
||||
* 3 - UTMI+ and ULPI
|
||||
* @fs_phy_type: Full-speed PHY interface type
|
||||
* 0 - Full speed interface not supported
|
||||
* 1 - Dedicated full speed interface
|
||||
* 2 - FS pins shared with UTMI+ pins
|
||||
* 3 - FS pins shared with ULPI pins
|
||||
* @num_dev_ep: Number of device endpoints available
|
||||
* @nperio_tx_q_depth:
|
||||
* Non-Periodic Request Queue Depth
|
||||
* 2, 4 or 8
|
||||
* @dev_token_q_depth: Device Mode IN Token Sequence Learning Queue
|
||||
* Depth
|
||||
* 0 to 30
|
||||
* @host_perio_tx_q_depth:
|
||||
* Host Mode Periodic Request Queue Depth
|
||||
* 2, 4 or 8
|
||||
*
|
||||
* @max_transfer_size: The maximum transfer size supported, in bytes
|
||||
* 2047 to 65,535
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @max_packet_count: The maximum number of packets in a transfer
|
||||
* 15 to 511
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @i2c_enable: Specifies whether to use the I2Cinterface for a full
|
||||
* speed PHY. This parameter is only applicable if phy_type
|
||||
* is FS.
|
||||
* 0 - No (default)
|
||||
* 1 - Yes
|
||||
* @total_fifo_size: Total internal RAM for FIFOs (bytes)
|
||||
* @lpm_mode: For enabling Link Power Management in the controller
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
*
|
||||
* @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs
|
||||
* are enabled for non-periodic IN endpoints in device
|
||||
* mode.
|
||||
* @num_dev_in_eps: Number of device IN endpoints available
|
||||
* @num_dev_perio_in_ep: Number of device periodic IN endpoints
|
||||
* available
|
||||
* @dma_desc_enable: When DMA mode is enabled, specifies whether to use
|
||||
* address DMA mode or descriptor DMA mode for accessing
|
||||
* the data FIFOs. The driver will automatically detect the
|
||||
* value for this if none is specified.
|
||||
* 0 - Address DMA
|
||||
* 1 - Descriptor DMA (default, if available)
|
||||
|
||||
* @power_optimized: Are power optimizations enabled?
|
||||
* @hibernation: Is hibernation enabled?
|
||||
* @utmi_phy_data_width: UTMI+ PHY data width
|
||||
* 0 - 8 bits
|
||||
* 1 - 16 bits
|
||||
* 2 - 8 or 16 bits
|
||||
|
||||
* @acg_enable: For enabling Active Clock Gating in the controller
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
* @ipg_isoc_en: This feature indicates that the controller supports
|
||||
* the worst-case scenario of Rx followed by Rx
|
||||
* Interpacket Gap (IPG) (32 bitTimes) as per the utmi
|
||||
* specification for any token following ISOC OUT token.
|
||||
* 0 - Don't support
|
||||
* 1 - Support
|
||||
* @service_interval_mode: For enabling service interval based scheduling in the
|
||||
* controller.
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
*/
|
||||
struct dwc2_hw_params {
|
||||
uint32_t snpsid;
|
||||
uint32_t dev_ep_dirs;
|
||||
|
||||
unsigned op_mode : 3;
|
||||
unsigned arch : 2;
|
||||
unsigned enable_dynamic_fifo : 1;
|
||||
unsigned host_channels : 5;
|
||||
unsigned hs_phy_type : 2;
|
||||
unsigned fs_phy_type : 2;
|
||||
unsigned num_dev_ep : 4;
|
||||
unsigned nperio_tx_q_depth : 3;
|
||||
unsigned host_perio_tx_q_depth : 3;
|
||||
unsigned dev_token_q_depth : 5;
|
||||
|
||||
unsigned max_transfer_size : 26;
|
||||
unsigned max_packet_count : 11;
|
||||
unsigned i2c_enable : 1;
|
||||
unsigned total_fifo_size : 16;
|
||||
unsigned lpm_mode : 1;
|
||||
|
||||
unsigned en_multiple_tx_fifo : 1;
|
||||
unsigned num_dev_in_eps : 4;
|
||||
unsigned num_dev_perio_in_ep : 4;
|
||||
unsigned dma_desc_enable : 1;
|
||||
unsigned power_optimized : 1;
|
||||
unsigned hibernation : 1;
|
||||
unsigned utmi_phy_data_width : 2;
|
||||
unsigned acg_enable : 1;
|
||||
unsigned ipg_isoc_en : 1;
|
||||
unsigned service_interval_mode : 1;
|
||||
};
|
||||
|
||||
#define DWC2_PHY_TYPE_PARAM_FS 0
|
||||
#define DWC2_PHY_TYPE_PARAM_UTMI 1
|
||||
#define DWC2_PHY_TYPE_PARAM_ULPI 2
|
||||
|
||||
struct dwc2_user_params {
|
||||
uint8_t phy_type;
|
||||
uint8_t phy_utmi_width;
|
||||
|
||||
bool device_dma_enable;
|
||||
bool device_dma_desc_enable;
|
||||
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
|
||||
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
|
||||
*/
|
||||
uint16_t device_rx_fifo_size;
|
||||
/* IN Endpoints Max packet Size / 4 */
|
||||
uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS];
|
||||
|
||||
bool host_dma_desc_enable;
|
||||
/*
|
||||
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
|
||||
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
|
||||
*/
|
||||
uint16_t host_rx_fifo_size;
|
||||
/* largest non-periodic USB packet used / 4 */
|
||||
uint16_t host_nperio_tx_fifo_size;
|
||||
/* largest periodic USB packet used / 4 */
|
||||
uint16_t host_perio_tx_fifo_size;
|
||||
|
||||
uint32_t device_gccfg;
|
||||
uint32_t host_gccfg;
|
||||
|
||||
bool b_session_valid_override;
|
||||
uint32_t total_fifo_size;
|
||||
};
|
||||
|
||||
struct usb_dwc2_user_fifo_config {
|
||||
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
|
||||
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
|
||||
*/
|
||||
uint16_t device_rx_fifo_size;
|
||||
/* IN Endpoints Max packet Size / 4 */
|
||||
uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS];
|
||||
};
|
||||
|
||||
static inline void dwc2_get_hwparams(uint32_t reg_base, struct dwc2_hw_params *hw)
|
||||
{
|
||||
unsigned int width;
|
||||
uint32_t snpsid, hwcfg1, hwcfg2, hwcfg3, hwcfg4;
|
||||
|
||||
snpsid = dwc2_readl(reg_base + GSNPSID_OFFSET);
|
||||
|
||||
hwcfg1 = dwc2_readl(reg_base + GHWCFG1_OFFSET);
|
||||
hwcfg2 = dwc2_readl(reg_base + GHWCFG2_OFFSET);
|
||||
hwcfg3 = dwc2_readl(reg_base + GHWCFG3_OFFSET);
|
||||
hwcfg4 = dwc2_readl(reg_base + GHWCFG4_OFFSET);
|
||||
|
||||
/* snpsid */
|
||||
hw->snpsid = snpsid;
|
||||
|
||||
/* hwcfg1 */
|
||||
hw->dev_ep_dirs = hwcfg1;
|
||||
|
||||
/* hwcfg2 */
|
||||
hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
|
||||
GHWCFG2_OP_MODE_SHIFT;
|
||||
hw->arch = (hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >>
|
||||
GHWCFG2_ARCHITECTURE_SHIFT;
|
||||
hw->enable_dynamic_fifo = !!(hwcfg2 & GHWCFG2_DYNAMIC_FIFO);
|
||||
hw->host_channels = 1 + ((hwcfg2 & GHWCFG2_NUM_HOST_CHAN_MASK) >>
|
||||
GHWCFG2_NUM_HOST_CHAN_SHIFT);
|
||||
hw->hs_phy_type = (hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >>
|
||||
GHWCFG2_HS_PHY_TYPE_SHIFT;
|
||||
hw->fs_phy_type = (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >>
|
||||
GHWCFG2_FS_PHY_TYPE_SHIFT;
|
||||
hw->num_dev_ep = (hwcfg2 & GHWCFG2_NUM_DEV_EP_MASK) >>
|
||||
GHWCFG2_NUM_DEV_EP_SHIFT;
|
||||
hw->nperio_tx_q_depth =
|
||||
(hwcfg2 & GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK) >>
|
||||
GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT << 1;
|
||||
hw->host_perio_tx_q_depth =
|
||||
(hwcfg2 & GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK) >>
|
||||
GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT << 1;
|
||||
hw->dev_token_q_depth =
|
||||
(hwcfg2 & GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK) >>
|
||||
GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT;
|
||||
|
||||
/* hwcfg3 */
|
||||
width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >>
|
||||
GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT;
|
||||
hw->max_transfer_size = (1 << (width + 11)) - 1;
|
||||
width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >>
|
||||
GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT;
|
||||
hw->max_packet_count = (1 << (width + 4)) - 1;
|
||||
hw->i2c_enable = !!(hwcfg3 & GHWCFG3_I2C);
|
||||
hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH_MASK) >>
|
||||
GHWCFG3_DFIFO_DEPTH_SHIFT;
|
||||
hw->lpm_mode = !!(hwcfg3 & GHWCFG3_OTG_LPM_EN);
|
||||
|
||||
/* hwcfg4 */
|
||||
hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
|
||||
hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
|
||||
GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
|
||||
hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >>
|
||||
GHWCFG4_NUM_IN_EPS_SHIFT;
|
||||
hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
|
||||
hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
|
||||
hw->hibernation = !!(hwcfg4 & GHWCFG4_HIBER);
|
||||
hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
|
||||
GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
|
||||
hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED);
|
||||
hw->ipg_isoc_en = !!(hwcfg4 & GHWCFG4_IPG_ISOC_SUPPORTED);
|
||||
hw->service_interval_mode = !!(hwcfg4 &
|
||||
GHWCFG4_SERVICE_INTERVAL_SUPPORTED);
|
||||
}
|
||||
|
||||
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params);
|
||||
void dwc2_get_user_fifo_config(uint32_t reg_base, struct usb_dwc2_user_fifo_config *config);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usb_dwc2_param.h"
|
||||
|
||||
extern unsigned int system_core_clock;
|
||||
|
||||
uint32_t SystemCoreClock;
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
#ifdef AT32F415xx
|
||||
.device_gccfg = ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21)),
|
||||
#else
|
||||
.device_gccfg = ((1 << 16) | (1 << 21)),
|
||||
#endif
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
#if __has_include("at32f402_405.h")
|
||||
#include "at32f402_405.h"
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
.device_dma_enable = true,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (1008 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 624,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
|
||||
.device_gccfg = ((1 << 16) | (1 << 21)),
|
||||
.host_gccfg = ((1 << 16) | (1 << 21))
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
|
||||
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
|
||||
{
|
||||
SystemCoreClock = system_core_clock;
|
||||
|
||||
#if __has_include("at32f402_405.h")
|
||||
if (reg_base == OTGHS_BASE) {
|
||||
memcpy(params, ¶m_pb14_pb15, sizeof(struct dwc2_user_params));
|
||||
} else {
|
||||
memcpy(params, ¶m_pa11_pa12, sizeof(struct dwc2_user_params));
|
||||
}
|
||||
#else
|
||||
memcpy(params, ¶m_pa11_pa12, sizeof(struct dwc2_user_params));
|
||||
#endif
|
||||
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
|
||||
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
|
||||
|
||||
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
|
||||
|
||||
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
|
||||
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) {
|
||||
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
uint32_t count = SystemCoreClock / 1000 * ms;
|
||||
while (count--) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_idf_version.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_private/usb_phy.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usb_dwc2_param.h"
|
||||
|
||||
#define GET_USB_INDEX(reg_base) 0
|
||||
#define GET_USB_INTR_SOURCE(reg_base) ETS_USB_INTR_SOURCE
|
||||
#define GET_USB_PHY_TARGET(reg_base) USB_PHY_TARGET_INT
|
||||
#define GET_USB_PHY_SPEED(reg_base) USB_PHY_SPEED_UNDEFINED
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#undef GET_USB_INDEX
|
||||
#define GET_USB_INDEX(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? 0 : 1)
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ
|
||||
#define DEFAULT_USB_INTR_SOURCE ETS_USB_OTG_INTR_SOURCE
|
||||
#define USB_FS_INTR_SOURCE ETS_USB_OTG11_CH0_INTR_SOURCE
|
||||
#undef GET_USB_INTR_SOURCE
|
||||
#define GET_USB_INTR_SOURCE(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? DEFAULT_USB_INTR_SOURCE : USB_FS_INTR_SOURCE)
|
||||
#undef GET_USB_PHY_TARGET
|
||||
#define GET_USB_PHY_TARGET(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? USB_PHY_TARGET_UTMI : USB_PHY_TARGET_INT)
|
||||
#undef GET_USB_PHY_SPEED
|
||||
#define GET_USB_PHY_SPEED(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? USB_PHY_SPEED_HIGH : USB_PHY_SPEED_FULL)
|
||||
#else
|
||||
#define DEFAULT_CPU_FREQ_MHZ 160
|
||||
#endif
|
||||
|
||||
uint32_t SystemCoreClock = (DEFAULT_CPU_FREQ_MHZ * 1000 * 1000);
|
||||
static usb_phy_handle_t s_phy_handle[SOC_USB_OTG_PERIPH_NUM] = {NULL};
|
||||
static intr_handle_t s_interrupt_handle[SOC_USB_OTG_PERIPH_NUM] = {NULL};
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
const struct dwc2_user_params param_fs = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = true,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (200 - 16 * 7),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 16, // 64 byte
|
||||
[5] = 16, // 64 byte
|
||||
[6] = 16, // 64 byte
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 80,
|
||||
.host_nperio_tx_fifo_size = 60, // 240 byte
|
||||
.host_perio_tx_fifo_size = 60, // 240 byte
|
||||
};
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
const struct dwc2_user_params param_fs = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = true,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (200 - 16 * 7),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 16, // 64 byte
|
||||
[5] = 16, // 64 byte
|
||||
[6] = 16, // 64 byte
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = (200 - 60 - 60),
|
||||
.host_nperio_tx_fifo_size = 60, // 240 byte
|
||||
.host_perio_tx_fifo_size = 60, // 240 byte
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_hs = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
.device_dma_enable = true,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (896 - 16 - 128 - 128 - 128 - 128 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 128, // 512 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 16, // 64 byte
|
||||
[6] = 16, // 64 byte
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = (896 - 128 - 128),
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 128, // 512 byte
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usb_dc_interrupt_cb(void *arg_pv)
|
||||
{
|
||||
extern void USBD_IRQHandler(uint8_t busid);
|
||||
uint8_t busid = (uintptr_t)arg_pv;
|
||||
USBD_IRQHandler(busid);
|
||||
}
|
||||
|
||||
void usb_dc_low_level_init(uint8_t busid)
|
||||
{
|
||||
esp_err_t ret;
|
||||
void *reg_base = (void*)g_usbdev_bus[busid].reg_base;
|
||||
(void)reg_base;
|
||||
usb_phy_config_t phy_config = {
|
||||
.controller = USB_PHY_CTRL_OTG,
|
||||
.otg_mode = USB_OTG_MODE_DEVICE,
|
||||
};
|
||||
phy_config.target = GET_USB_PHY_TARGET(reg_base);
|
||||
phy_config.otg_speed = GET_USB_PHY_SPEED(reg_base);
|
||||
|
||||
ret = usb_new_phy(&phy_config, &s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Phy Init Failed!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uintptr_t arg = busid;
|
||||
// TODO: Check when to enable interrupt
|
||||
ret = esp_intr_alloc(GET_USB_INTR_SOURCE(reg_base), ESP_INTR_FLAG_LOWMED, usb_dc_interrupt_cb, (void *)arg, &s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
|
||||
return;
|
||||
}
|
||||
USB_LOG_INFO("cherryusb, version: " CHERRYUSB_VERSION_STR "\r\n");
|
||||
}
|
||||
|
||||
void usb_dc_low_level_deinit(uint8_t busid)
|
||||
{
|
||||
void *reg_base = (void*)g_usbdev_bus[busid].reg_base;
|
||||
(void)reg_base;
|
||||
if (s_interrupt_handle[GET_USB_INDEX(reg_base)]) {
|
||||
esp_intr_free(s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_interrupt_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
if (s_phy_handle[GET_USB_INDEX(reg_base)]) {
|
||||
usb_del_phy(s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_phy_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_hc_interrupt_cb(void *arg_pv)
|
||||
{
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
uint8_t busid = (uintptr_t)arg_pv;
|
||||
USBH_IRQHandler(busid);
|
||||
}
|
||||
|
||||
void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
void *reg_base = (void*)bus->hcd.reg_base;
|
||||
(void)reg_base;
|
||||
// Host Library defaults to internal PHY
|
||||
usb_phy_config_t phy_config = {
|
||||
.controller = USB_PHY_CTRL_OTG,
|
||||
.otg_mode = USB_OTG_MODE_HOST,
|
||||
.otg_speed = USB_PHY_SPEED_UNDEFINED, // In Host mode, the speed is determined by the connected device
|
||||
.ext_io_conf = NULL,
|
||||
.otg_io_conf = NULL,
|
||||
};
|
||||
phy_config.target = GET_USB_PHY_TARGET(reg_base);
|
||||
|
||||
esp_err_t ret = usb_new_phy(&phy_config, &s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Phy Init Failed!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uintptr_t arg = bus->busid;
|
||||
// TODO: Check when to enable interrupt
|
||||
ret = esp_intr_alloc(GET_USB_INTR_SOURCE(reg_base), ESP_INTR_FLAG_LOWMED, usb_hc_interrupt_cb, (void*)(arg), &s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
if (ret != ESP_OK) {
|
||||
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
|
||||
return;
|
||||
}
|
||||
USB_LOG_INFO("cherryusb, version: " CHERRYUSB_VERSION_STR "\r\n");
|
||||
}
|
||||
|
||||
void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
void *reg_base = (void*)bus->hcd.reg_base;
|
||||
(void)reg_base;
|
||||
if (s_interrupt_handle[GET_USB_INDEX(reg_base)]) {
|
||||
esp_intr_free(s_interrupt_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_interrupt_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
if (s_phy_handle[GET_USB_INDEX(reg_base)]) {
|
||||
usb_del_phy(s_phy_handle[GET_USB_INDEX(reg_base)]);
|
||||
s_phy_handle[GET_USB_INDEX(reg_base)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
memcpy(params, ¶m_fs, sizeof(struct dwc2_user_params));
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
if (reg_base == ESP_USB_HS0_BASE) {
|
||||
memcpy(params, ¶m_hs, sizeof(struct dwc2_user_params));
|
||||
} else {
|
||||
memcpy(params, ¶m_fs, sizeof(struct dwc2_user_params));
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
|
||||
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
|
||||
|
||||
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
|
||||
|
||||
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
|
||||
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++)
|
||||
{
|
||||
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(ms));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
#include "esp_cache.h"
|
||||
|
||||
void usb_dcache_clean(uintptr_t addr, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
esp_cache_msync((void *)addr, size, ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
}
|
||||
|
||||
void usb_dcache_invalidate(uintptr_t addr, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
esp_cache_msync((void *)addr, size, ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_M2C);
|
||||
}
|
||||
|
||||
void usb_dcache_flush(uintptr_t addr, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
esp_cache_msync((void *)addr, size, ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_DIR_M2C);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usb_config.h"
|
||||
#include "stdint.h"
|
||||
#include "usb_dwc2_reg.h"
|
||||
|
||||
#if 1
|
||||
#error you need to modify some usb register values then use this chip
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBDEV_EP_NUM != 4 && CONFIG_USBDEV_EP_NUM != 6
|
||||
#error "gd32 only has 4 endpoints for pa11/pa12 and 6 endpoints for pb14/pb15"
|
||||
#endif
|
||||
|
||||
/* you can find this config in function:usb_core_init, file:drv_usb_core.c, for example:
|
||||
*
|
||||
* usb_regs->gr->GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN;
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USB_HS
|
||||
return 0;
|
||||
#else
|
||||
return ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21));
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USB_HS
|
||||
return 0;
|
||||
#else
|
||||
return ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21));
|
||||
#endif
|
||||
}
|
||||
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
uint32_t count = SystemCoreClock / 1000 * ms;
|
||||
while (count--) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usb_config.h"
|
||||
#include "usb_dwc2_reg.h"
|
||||
|
||||
/* When using [GPIO_SetFunc(USBF_VBUS_PORT, USBF_VBUS_PIN, USBF_VBUS_FUNC);], there is no need to configure GOTGCTL */
|
||||
|
||||
#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(reg_base))
|
||||
|
||||
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
|
||||
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
|
||||
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN;
|
||||
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
uint32_t count = SystemCoreClock / 1000 * ms;
|
||||
while (count--) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usb_dwc2_param.h"
|
||||
|
||||
#include <riscv_io.h>
|
||||
#include "sysctl_rst.h"
|
||||
#include "ioremap.h"
|
||||
#include "mmu.h"
|
||||
#include "cache.h"
|
||||
|
||||
extern rt_mmu_info mmu_info;
|
||||
|
||||
#if defined(ENABLE_CHERRY_USB) || defined(PKG_USING_CHERRYUSB) || defined(RT_USING_CHERRYUSB)
|
||||
#define DEFAULT_USB_HCLK_FREQ_MHZ 200
|
||||
|
||||
uint32_t SystemCoreClock = (DEFAULT_USB_HCLK_FREQ_MHZ * 1000 * 1000);
|
||||
|
||||
const uintptr_t usb_dev_addr[2] = { 0x91500000UL, 0x91540000UL };
|
||||
|
||||
#define USB_IDPULLUP0 (1 << 4)
|
||||
#define USB_DMPULLDOWN0 (1 << 8)
|
||||
#define USB_DPPULLDOWN0 (1 << 9)
|
||||
|
||||
const struct dwc2_user_params param_common = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (3016 - 16 - 256 * 8),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 512, // 1024 byte, double buffer
|
||||
[2] = 256, // 1024 byte
|
||||
[3] = 512, // 1024 byte, double buffer
|
||||
[4] = 256, // 1024 byte
|
||||
[5] = 256, // 1024 byte
|
||||
[6] = 256, // 1024 byte
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 3016 - 128 * 2 - 256 * 2,
|
||||
.host_nperio_tx_fifo_size = 128 * 2, // 512 byte, double buffer
|
||||
.host_perio_tx_fifo_size = 256 * 2, // 1024 byte, double buffer
|
||||
|
||||
.device_gccfg = 0,
|
||||
.host_gccfg = 0
|
||||
};
|
||||
|
||||
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
|
||||
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
|
||||
{
|
||||
memcpy(params, ¶m_common, sizeof(struct dwc2_user_params));
|
||||
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
|
||||
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
|
||||
|
||||
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
|
||||
|
||||
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
|
||||
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) {
|
||||
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// USB Host
|
||||
#if defined(ENABLE_CHERRY_USB_HOST) || defined(PKG_CHERRYUSB_HOST) || defined(RT_CHERRYUSB_HOST)
|
||||
static void usb_hc_interrupt_cb(int irq, void *arg_pv)
|
||||
{
|
||||
USBH_IRQHandler((uint8_t)(uintptr_t)arg_pv);
|
||||
}
|
||||
|
||||
void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
uint32_t *hs_reg;
|
||||
uint32_t usb_ctl3;
|
||||
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)bus->hcd.reg_base) == usb_dev_addr[0]) {
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB0)) {
|
||||
USB_LOG_ERR("reset usb0 fail\n");
|
||||
}
|
||||
|
||||
hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
|
||||
usb_ctl3 = *hs_reg | USB_IDPULLUP0;
|
||||
|
||||
*hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0);
|
||||
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(173, usb_hc_interrupt_cb, (void *)(uintptr_t)bus->hcd.hcd_id, "usbh0");
|
||||
rt_hw_interrupt_umask(173);
|
||||
|
||||
} else {
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB1)) {
|
||||
USB_LOG_ERR("reset usb1 fail\n");
|
||||
}
|
||||
|
||||
hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
|
||||
usb_ctl3 = *hs_reg | USB_IDPULLUP0;
|
||||
|
||||
*hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0);
|
||||
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(174, usb_hc_interrupt_cb, (void *)(uintptr_t)bus->hcd.hcd_id, "usbh1");
|
||||
rt_hw_interrupt_umask(174);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)bus->hcd.reg_base) == usb_dev_addr[0]) {
|
||||
rt_hw_interrupt_mask(173);
|
||||
} else {
|
||||
rt_hw_interrupt_mask(174);
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_CHERRY_USB_HOST
|
||||
|
||||
// USB Device
|
||||
#if defined(ENABLE_CHERRY_USB_DEVICE) || defined(PKG_CHERRYUSB_DEVICE) || defined(RT_CHERRYUSB_DEVICE)
|
||||
static void usb_dc_interrupt_cb(int irq, void *arg_pv)
|
||||
{
|
||||
USBD_IRQHandler((uint8_t)(uintptr_t)arg_pv);
|
||||
}
|
||||
|
||||
void usb_dc_low_level_init(uint8_t busid)
|
||||
{
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)g_usbdev_bus[busid].reg_base) == usb_dev_addr[0]) {
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB0)) {
|
||||
USB_LOG_ERR("reset usb0 fail\n");
|
||||
}
|
||||
|
||||
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
|
||||
*hs_reg = 0x37;
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(173, usb_dc_interrupt_cb, (void *)(uintptr_t)busid, "usbd0");
|
||||
rt_hw_interrupt_umask(173);
|
||||
} else {
|
||||
if (!sysctl_reset(SYSCTL_RESET_USB1)) {
|
||||
USB_LOG_ERR("reset usb1 fail\n");
|
||||
}
|
||||
|
||||
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
|
||||
*hs_reg = 0x37;
|
||||
rt_iounmap(hs_reg);
|
||||
|
||||
rt_hw_interrupt_install(174, usb_dc_interrupt_cb, (void *)(uintptr_t)busid, "usbd1");
|
||||
rt_hw_interrupt_umask(174);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_dc_low_level_deinit(uint8_t busid)
|
||||
{
|
||||
if ((uintptr_t)rt_hw_mmu_v2p(&mmu_info, (void *)g_usbdev_bus[busid].reg_base) == usb_dev_addr[0]) {
|
||||
rt_hw_interrupt_mask(173);
|
||||
} else {
|
||||
rt_hw_interrupt_mask(174);
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_CHERRY_USB_DEVICE
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
rt_thread_mdelay(ms);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
void usb_dcache_clean(uintptr_t addr, size_t size)
|
||||
{
|
||||
rt_hw_cpu_dcache_clean((void *)addr, size);
|
||||
}
|
||||
|
||||
void usb_dcache_invalidate(uintptr_t addr, size_t size)
|
||||
{
|
||||
rt_hw_cpu_dcache_invalidate((void *)addr, size);
|
||||
}
|
||||
|
||||
void usb_dcache_flush(uintptr_t addr, size_t size)
|
||||
{
|
||||
rt_hw_cpu_dcache_clean_flush((void *)addr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_CHERRY_USB
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
__WEAK void USBD_IRQHandler(uint8_t busid)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void USBH_IRQHandler(uint8_t busid)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(N32H473) || defined(N32H474) || defined(N32H475) || defined(N32H482) || defined(N32H487)
|
||||
#include "n32h47x_48x_rcc.h"
|
||||
#include "n32h47x_48x_gpio.h"
|
||||
#include "n32h47x_48x_exti.h"
|
||||
#include "misc.h"
|
||||
|
||||
typedef void (*usb_dwc2_irq)(uint8_t busid);
|
||||
|
||||
static usb_dwc2_irq g_usb_dwc2_irq;
|
||||
static volatile uint8_t g_usb_dwc2_busid = 0;
|
||||
|
||||
static void usbhs_common_init(void)
|
||||
{
|
||||
RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA | RCC_AHB_PERIPHEN_GPIOB, ENABLE);
|
||||
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
|
||||
/* PLL= 240MHz */
|
||||
#if (HSE_VALUE == 8000000)
|
||||
/* Select PLL clock as USBHS clock source , clock 15 divisions = 16M */
|
||||
RCC_ConfigUSBPLLPresClk(RCC_USBPLLCLK_SRC_PLL, RCC_USBPLLCLK_DIV15);
|
||||
|
||||
/* Select the corresponding bandwidth and frequency*/
|
||||
RCC_ConfigUSBHSBandwidth(RCC_USBHS_BW_16M);
|
||||
|
||||
/* Select USBHS clock source frequency */
|
||||
RCC_ConfigUSBHSFrequency(RCC_USBHS_FREQ_16_OR_32M);
|
||||
|
||||
/* Select PLL as USBHS clock */
|
||||
RCC_ConfigUSBHSClk(RCC_USBHS_CLKSRC_PLLPRES);
|
||||
#else //HSE 16M
|
||||
RCC_ConfigUSBHSBandwidth(RCC_USBHS_BW_16M);
|
||||
RCC_ConfigUSBHSFrequency(RCC_USBHS_FREQ_16_OR_32M);
|
||||
RCC_ConfigUSBHSClk(RCC_USBHS_CLKSRC_HSE);
|
||||
#endif
|
||||
/* Reset the USBHS phy clock*/
|
||||
RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST);
|
||||
/* Enables the USBHS peripheral clock*/
|
||||
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, ENABLE);
|
||||
|
||||
NVIC_InitType NVIC_InitStructure;
|
||||
// EXTI_InitType EXTI_InitStructure;
|
||||
|
||||
// NVIC_InitStructure.NVIC_IRQChannel = USB_HS_WKUP_IRQn;
|
||||
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
||||
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
// NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USB_HS_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
/* Configure the EXTI line 23 connected internally to the USBHS IP */
|
||||
// EXTI_ClrITPendBit(EXTI_LINE23);
|
||||
// EXTI_InitStructure.EXTI_Line = EXTI_LINE23;
|
||||
// EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
// EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||||
// EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
// EXTI_InitPeripheral(&EXTI_InitStructure);
|
||||
}
|
||||
|
||||
static void usbhs_gpio_init(void)
|
||||
{
|
||||
GPIO_InitType GPIO_InitStructure;
|
||||
|
||||
RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA | RCC_AHB_PERIPHEN_GPIOB | RCC_AHB_PERIPHEN_GPIOE, ENABLE);
|
||||
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
|
||||
GPIO_ConfigPinRemap(0, 0, GPIO_RMP_SWJ_SWD);
|
||||
|
||||
GPIO_InitStruct(&GPIO_InitStructure);
|
||||
#ifdef USBHS_HOST
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitPeripheral(GPIOE, &GPIO_InitStructure);
|
||||
GPIO_ResetBits(GPIOE, GPIO_PIN_1);
|
||||
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_3;
|
||||
GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
|
||||
GPIO_ResetBits(GPIOB, GPIO_PIN_3);
|
||||
#endif
|
||||
// VBUS
|
||||
// GPIO_InitStructure.Pin = GPIO_PIN_13;
|
||||
// GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT;
|
||||
// GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// // SOF
|
||||
// GPIO_InitStructure.Pin = GPIO_PIN_4;
|
||||
// GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
|
||||
// GPIO_InitStructure.GPIO_Alternate = 8; // SOF
|
||||
// GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
// // ID
|
||||
// GPIO_InitStructure.Pin = GPIO_PIN_12;
|
||||
// GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
|
||||
// GPIO_InitStructure.GPIO_Alternate = 14; // ID
|
||||
// GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
void usb_dc_low_level_init(uint8_t busid)
|
||||
{
|
||||
g_usb_dwc2_irq = USBD_IRQHandler;
|
||||
g_usb_dwc2_busid = busid;
|
||||
|
||||
usbhs_common_init();
|
||||
|
||||
RCC->USBHSCTRL2 |= (uint32_t)0x01 << 19;
|
||||
RCC->USBHSCTRL1 |= (uint32_t)0x01 << 31;
|
||||
}
|
||||
|
||||
void usb_dc_low_level_deinit(uint8_t busid)
|
||||
{
|
||||
NVIC_InitType NVIC_InitStructure;
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USB_HS_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST);
|
||||
/* Enables the USBHS peripheral clock*/
|
||||
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, DISABLE);
|
||||
}
|
||||
|
||||
void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
g_usb_dwc2_irq = USBH_IRQHandler;
|
||||
g_usb_dwc2_busid = 0;
|
||||
|
||||
usbhs_common_init();
|
||||
|
||||
RCC->USBHSCTRL2 &= ~(uint32_t)0x01 << 19;
|
||||
RCC->USBHSCTRL1 |= (uint32_t)0x01 << 31;
|
||||
}
|
||||
|
||||
void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
NVIC_InitType NVIC_InitStructure;
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USB_HS_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST);
|
||||
/* Enables the USBHS peripheral clock*/
|
||||
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, DISABLE);
|
||||
}
|
||||
|
||||
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USB_HS_IRQHandler(void)
|
||||
{
|
||||
g_usb_dwc2_irq(g_usb_dwc2_busid);
|
||||
}
|
||||
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
uint32_t count = SystemCoreClock / 1000 * ms;
|
||||
while (count--) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,750 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usb_dwc2_param.h"
|
||||
|
||||
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
|
||||
|
||||
#if __has_include("stm32f1xx_hal.h")
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = { 0 }; // do not support
|
||||
#if defined(HAL_HCD_MODULE_ENABLED)
|
||||
#error "HAL_HCD_MODULE_ENABLED is not supported for STM32F1xx, please use HAL_PCD_MODULE_ENABLED"
|
||||
#endif
|
||||
#elif __has_include("stm32f2xx_hal.h")
|
||||
#include "stm32f2xx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = {
|
||||
#ifdef CONFIG_USB_HS
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#else
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
#endif
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (1012 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 628,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
.device_gccfg = 0,
|
||||
.host_gccfg = 0,
|
||||
#else
|
||||
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
|
||||
.host_gccfg = ((1 << 16) | (1 << 21)) // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
|
||||
#endif
|
||||
};
|
||||
#elif __has_include("stm32f4xx_hal.h")
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || \
|
||||
defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || \
|
||||
defined(STM32F423xx)
|
||||
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
|
||||
.b_session_valid_override = true,
|
||||
#else
|
||||
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS
|
||||
#endif
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = {
|
||||
#ifdef CONFIG_USB_HS
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#else
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
#endif
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (1006 - 16 - 256 - 128 - 128 - 128 - 128), // 1006/1012
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 622,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
#ifdef CONFIG_USB_HS
|
||||
.device_gccfg = 0,
|
||||
.host_gccfg = 0,
|
||||
#else
|
||||
#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || \
|
||||
defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || \
|
||||
defined(STM32F423xx)
|
||||
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
|
||||
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
|
||||
.b_session_valid_override = true,
|
||||
#else
|
||||
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
|
||||
.host_gccfg = ((1 << 16) | (1 << 21)) // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
#elif __has_include("stm32f7xx_hal.h")
|
||||
#include "stm32f7xx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
|
||||
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
|
||||
|
||||
.b_session_valid_override = true,
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = {
|
||||
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#else
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
#endif
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (1006 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 622,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
|
||||
.device_gccfg = (1 << 23), // USB_OTG_GCCFG_PHYHSEN
|
||||
.host_gccfg = (1 << 23), // USB_OTG_GCCFG_PHYHSEN
|
||||
#else
|
||||
#ifdef CONFIG_USB_HS
|
||||
.device_gccfg = 0,
|
||||
.host_gccfg = 0,
|
||||
#else
|
||||
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
|
||||
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
|
||||
#endif
|
||||
#endif
|
||||
.b_session_valid_override = true
|
||||
};
|
||||
#elif __has_include("stm32h7xx_hal.h")
|
||||
#include "stm32h7xx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS, // DWC2_PHY_TYPE_PARAM_UTMI
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 568,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
|
||||
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
|
||||
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
|
||||
|
||||
.b_session_valid_override = true
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = {
|
||||
#ifdef CONFIG_USB_HS
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#else
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
#endif
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 568,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
.device_gccfg = 0,
|
||||
.host_gccfg = 0,
|
||||
#else
|
||||
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
|
||||
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
|
||||
#endif
|
||||
.b_session_valid_override = true
|
||||
};
|
||||
#elif __has_include("stm32h7rsxx_hal.h")
|
||||
#include "stm32h7rsxx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
|
||||
.b_session_valid_override = true,
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 568,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
|
||||
.device_gccfg = ((1 << 23) | (1 << 24)), // hs: USB_OTG_GCCFG_VBVALEXTOEN | USB_OTG_GCCFG_VBVALOVAL
|
||||
.host_gccfg = (1 << 25) // hs: USB_OTG_GCCFG_PULLDOWNEN
|
||||
};
|
||||
#elif __has_include("stm32l4xx_hal.h")
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.device_gccfg = (1 << 16),
|
||||
.b_session_valid_override = true,
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
const struct dwc2_user_params param_pb14_pb15 = { 0 }; // do not support
|
||||
#if defined(HAL_HCD_MODULE_ENABLED)
|
||||
#error "HAL_HCD_MODULE_ENABLED is not supported for STM32L4xx, please use HAL_PCD_MODULE_ENABLED"
|
||||
#endif
|
||||
#elif __has_include("stm32u5xx_hal.h")
|
||||
#include "stm32u5xx_hal.h"
|
||||
|
||||
const struct dwc2_user_params param_pa11_pa12 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
|
||||
.device_dma_enable = false,
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 16, // 64 byte
|
||||
[2] = 16, // 64 byte
|
||||
[3] = 16, // 64 byte
|
||||
[4] = 0,
|
||||
[5] = 0,
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.device_gccfg = (1 << 16),
|
||||
.b_session_valid_override = true,
|
||||
.total_fifo_size = 320 // 1280 byte
|
||||
};
|
||||
|
||||
#if defined(STM32U595xx) || defined(STM32U5A5xx) || defined(STM32U599xx) || defined(STM32U5A9xx) || \
|
||||
defined(STM32U5F7xx) || defined(STM32U5G7xx) || defined(STM32U5F9xx) || defined(STM32U5G9xx)
|
||||
const struct dwc2_user_params param_pb14_pb15 = {
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
.device_dma_enable = true,
|
||||
#else
|
||||
.device_dma_enable = false,
|
||||
#endif
|
||||
.device_dma_desc_enable = false,
|
||||
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
|
||||
.device_tx_fifo_size = {
|
||||
[0] = 16, // 64 byte
|
||||
[1] = 256, // 1024 byte
|
||||
[2] = 128, // 512 byte
|
||||
[3] = 128, // 512 byte
|
||||
[4] = 128, // 512 byte
|
||||
[5] = 128, // 512 byte
|
||||
[6] = 0,
|
||||
[7] = 0,
|
||||
[8] = 0,
|
||||
[9] = 0,
|
||||
[10] = 0,
|
||||
[11] = 0,
|
||||
[12] = 0,
|
||||
[13] = 0,
|
||||
[14] = 0,
|
||||
[15] = 0 },
|
||||
|
||||
.host_dma_desc_enable = false,
|
||||
.host_rx_fifo_size = 568,
|
||||
.host_nperio_tx_fifo_size = 128, // 512 byte
|
||||
.host_perio_tx_fifo_size = 256, // 1024 byte
|
||||
|
||||
.device_gccfg = ((1 << 23) | (1 << 24)), // hs: USB_OTG_GCCFG_VBVALEXTOEN | USB_OTG_GCCFG_VBVALOVAL
|
||||
.host_gccfg = (1 << 25) // hs: USB_OTG_GCCFG_PULLDOWNEN
|
||||
};
|
||||
#else
|
||||
const struct dwc2_user_params param_pb14_pb15 = { 0 }; // do not support
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_USB_DWC2_CUSTOM_PARAM
|
||||
|
||||
#if !defined(HAL_HCD_MODULE_ENABLED) && !defined(HAL_PCD_MODULE_ENABLED)
|
||||
#error please define HAL_HCD_MODULE_ENABLED or HAL_PCD_MODULE_ENABLED in stm32xxx_hal_conf.h
|
||||
#endif
|
||||
|
||||
typedef void (*usb_dwc2_irq)(uint8_t busid);
|
||||
|
||||
struct dwc2_instance {
|
||||
USB_OTG_GlobalTypeDef *Instance;
|
||||
};
|
||||
|
||||
static usb_dwc2_irq g_usb_dwc2_irq[2];
|
||||
static uint8_t g_usb_dwc2_busid[2] = { 0, 0 };
|
||||
static struct dwc2_instance g_dwc2_instance;
|
||||
|
||||
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
|
||||
/**
|
||||
* @brief Enables control of a High Speed USB PHY
|
||||
* Init the low level hardware : GPIO, CLOCK, NVIC...
|
||||
* @param USBx Selected device
|
||||
* @retval HAL status
|
||||
*/
|
||||
static int usb_hsphy_init(uint32_t hse_value)
|
||||
{
|
||||
__IO uint32_t count = 0U;
|
||||
|
||||
/* Enable LDO */
|
||||
USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
|
||||
|
||||
/* wait for LDO Ready */
|
||||
while ((USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) == 0U) {
|
||||
count++;
|
||||
|
||||
if (count > 200000U) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Controls PHY frequency operation selection */
|
||||
if (hse_value == 12000000U) /* HSE = 12MHz */
|
||||
{
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL = (0x0U << 1);
|
||||
} else if (hse_value == 12500000U) /* HSE = 12.5MHz */
|
||||
{
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL = (0x2U << 1);
|
||||
} else if (hse_value == 16000000U) /* HSE = 16MHz */
|
||||
{
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL = (0x3U << 1);
|
||||
} else if (hse_value == 24000000U) /* HSE = 24MHz */
|
||||
{
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL = (0x4U << 1);
|
||||
} else if (hse_value == 25000000U) /* HSE = 25MHz */
|
||||
{
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL = (0x5U << 1);
|
||||
} else if (hse_value == 32000000U) /* HSE = 32MHz */
|
||||
{
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL = (0x7U << 1);
|
||||
} else {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* Control the tuning interface of the High Speed PHY */
|
||||
USB_HS_PHYC->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE;
|
||||
|
||||
/* Enable PLL internal PHY */
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
|
||||
|
||||
/* 2ms Delay required to get internal phy clock stable */
|
||||
HAL_Delay(2U);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
void usb_dc_low_level_init(uint8_t busid)
|
||||
{
|
||||
if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
|
||||
g_usb_dwc2_busid[1] = busid;
|
||||
g_usb_dwc2_irq[1] = USBD_IRQHandler;
|
||||
} else {
|
||||
g_usb_dwc2_busid[0] = busid;
|
||||
g_usb_dwc2_irq[0] = USBD_IRQHandler;
|
||||
}
|
||||
|
||||
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)g_usbdev_bus[busid].reg_base;
|
||||
HAL_PCD_MspInit((PCD_HandleTypeDef *)&g_dwc2_instance);
|
||||
|
||||
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
|
||||
usb_hsphy_init(25000000U);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usb_dc_low_level_deinit(uint8_t busid)
|
||||
{
|
||||
if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
|
||||
g_usb_dwc2_busid[1] = 0;
|
||||
g_usb_dwc2_irq[1] = NULL;
|
||||
} else {
|
||||
g_usb_dwc2_busid[0] = 0;
|
||||
g_usb_dwc2_irq[0] = NULL;
|
||||
}
|
||||
|
||||
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)g_usbdev_bus[busid].reg_base;
|
||||
HAL_PCD_MspDeInit((PCD_HandleTypeDef *)&g_dwc2_instance);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
if (bus->hcd.reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
|
||||
g_usb_dwc2_busid[1] = bus->hcd.hcd_id;
|
||||
g_usb_dwc2_irq[1] = USBH_IRQHandler;
|
||||
} else {
|
||||
g_usb_dwc2_busid[0] = bus->hcd.hcd_id;
|
||||
g_usb_dwc2_irq[0] = USBH_IRQHandler;
|
||||
}
|
||||
|
||||
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)bus->hcd.reg_base;
|
||||
HAL_HCD_MspInit((HCD_HandleTypeDef *)&g_dwc2_instance);
|
||||
|
||||
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
|
||||
usb_hsphy_init(25000000U);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
if (bus->hcd.reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
|
||||
g_usb_dwc2_busid[1] = 0;
|
||||
g_usb_dwc2_irq[1] = NULL;
|
||||
} else {
|
||||
g_usb_dwc2_busid[0] = 0;
|
||||
g_usb_dwc2_irq[0] = NULL;
|
||||
}
|
||||
|
||||
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)bus->hcd.reg_base;
|
||||
HAL_HCD_MspDeInit((HCD_HandleTypeDef *)&g_dwc2_instance);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
|
||||
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
|
||||
{
|
||||
if (reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
|
||||
memcpy(params, ¶m_pb14_pb15, sizeof(struct dwc2_user_params));
|
||||
} else {
|
||||
memcpy(params, ¶m_pa11_pa12, sizeof(struct dwc2_user_params));
|
||||
}
|
||||
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
|
||||
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
|
||||
|
||||
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
|
||||
|
||||
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
|
||||
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++)
|
||||
{
|
||||
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
void usbd_dwc2_delay_ms(uint8_t ms)
|
||||
{
|
||||
uint32_t count = SystemCoreClock / 1000 * ms;
|
||||
while (count--) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
|
||||
void OTG_FS_IRQHandler(void)
|
||||
{
|
||||
g_usb_dwc2_irq[0](g_usb_dwc2_busid[0]);
|
||||
}
|
||||
|
||||
void OTG_HS_IRQHandler(void)
|
||||
{
|
||||
g_usb_dwc2_irq[1](g_usb_dwc2_busid[1]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
void usb_dcache_clean(uintptr_t addr, size_t size)
|
||||
{
|
||||
SCB_CleanDCache_by_Addr((void *)addr, size);
|
||||
}
|
||||
|
||||
void usb_dcache_invalidate(uintptr_t addr, size_t size)
|
||||
{
|
||||
SCB_InvalidateDCache_by_Addr((void *)addr, size);
|
||||
}
|
||||
|
||||
void usb_dcache_flush(uintptr_t addr, size_t size)
|
||||
{
|
||||
SCB_CleanInvalidateDCache_by_Addr((void *)addr, size);
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user