refactor(port/dwc2): support custom config for each dwc2 usb port

Signed-off-by: sakumisu <1203593632@qq.com>
This commit is contained in:
sakumisu
2025-07-03 20:55:44 +08:00
parent 8e0ff856fe
commit 22e150a8e6
9 changed files with 1381 additions and 514 deletions

View File

@@ -262,28 +262,20 @@
// #define CONFIG_USBDEV_SOF_ENABLE // #define CONFIG_USBDEV_SOF_ENABLE
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. */ /* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
* the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
*
* in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them).
*/
// #define CONFIG_USB_HS // #define CONFIG_USB_HS
/* ---------------- FSDEV Configuration ---------------- */ /* ---------------- FSDEV Configuration ---------------- */
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference //#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
/* ---------------- DWC2 Configuration ---------------- */ /* ---------------- DWC2 Configuration ---------------- */
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for /* enable dwc2 buffer dma mode for device
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK * in xxx32 chips, only pb14/pb15 can support dma mode, pa11/pa12 is not supported(only a few supports, but we ignore them)
*/ */
// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
/* IN Endpoints Max packet Size / 4 */
// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4)
// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_DMA_ENABLE // #define CONFIG_USB_DWC2_DMA_ENABLE
/* ---------------- MUSB Configuration ---------------- */ /* ---------------- MUSB Configuration ---------------- */
@@ -320,17 +312,6 @@
/* ---------------- XHCI Configuration ---------------- */ /* ---------------- XHCI Configuration ---------------- */
#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0) #define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
/* ---------------- DWC2 Configuration ---------------- */
/* largest non-periodic USB packet used / 4 */
// #define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
/* largest periodic USB packet used / 4 */
// #define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
/* ---------------- MUSB Configuration ---------------- */ /* ---------------- MUSB Configuration ---------------- */
// #define CONFIG_USB_MUSB_SUNXI // #define CONFIG_USB_MUSB_SUNXI

View File

@@ -83,8 +83,8 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
uint8_t intf_altsetting[16]; uint8_t intf_altsetting[16];
uint8_t intf_offset; uint8_t intf_offset;
struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM]; struct usbd_tx_rx_msg tx_msg[16];
struct usbd_tx_rx_msg rx_msg[CONFIG_USBDEV_EP_NUM]; struct usbd_tx_rx_msg rx_msg[16];
void (*event_handler)(uint8_t busid, uint8_t event); void (*event_handler)(uint8_t busid, uint8_t event);
} g_usbd_core[CONFIG_USBDEV_MAX_BUS]; } g_usbd_core[CONFIG_USBDEV_MAX_BUS];

View File

@@ -246,92 +246,12 @@
#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048 #define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048
#endif #endif
/* ================ USB Device Port Configuration ================*/
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define ESP_USBD_BASE 0x60080000
#define CONFIG_USBDEV_MAX_BUS 1 #define CONFIG_USBDEV_MAX_BUS 1
// esp32s2/s3 has 7 endpoints in device mode (include ep0)
#define CONFIG_USBDEV_EP_NUM 7
/* ---------------- DWC2 Configuration ---------------- */
//esp32s2/s3 can support up to 5 IN endpoints(include ep0) at the same time
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (320 / 4)
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
#define CONFIG_USB_DWC2_DMA_ENABLE
#elif CONFIG_IDF_TARGET_ESP32P4
#define ESP_USBD_BASE 0x50000000UL
#define CONFIG_USBDEV_MAX_BUS 1
#define CONFIG_USBDEV_EP_NUM 7 // 16
/* ---------------- DWC2 Configuration ---------------- */
//esp32s2/s3 can support up to 5 IN endpoints(include ep0) at the same time
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4)
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (512 / 4)
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (512 / 4)
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (512 / 4)
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
#define CONFIG_USB_DWC2_DMA_ENABLE
#define CONFIG_USB_HS
#else
#error "Unsupported SoC"
#endif
/* ================ USB Host Port Configuration ==================*/
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define ESP_USBH_BASE 0x60080000
#define CONFIG_USBHOST_MAX_BUS 1 #define CONFIG_USBHOST_MAX_BUS 1
// esp32s2/s3 has 8 endpoints in host mode (include ep0)
#define CONFIG_USBHOST_PIPE_NUM 8
/* ---------------- DWC2 Configuration ---------------- */
/* largest non-periodic USB packet used / 4 */
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (240 / 4)
/* largest periodic USB packet used / 4 */
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (240 / 4)
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((200 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#define ESP_USBH_BASE 0x50000000UL #define CONFIG_USBDEV_MAX_BUS 2
#define CONFIG_USBHOST_MAX_BUS 2
#define CONFIG_USBHOST_MAX_BUS 1
#define CONFIG_USBHOST_PIPE_NUM 16
/* ---------------- DWC2 Configuration ---------------- */
/* largest non-periodic USB packet used / 4 */
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
/* largest periodic USB packet used / 4 */
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (512 / 4)
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((896 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
#define CONFIG_USB_HS #define CONFIG_USB_HS
#else #else
#error "Unsupported SoC" #error "Unsupported SoC"

View File

@@ -5,6 +5,7 @@
*/ */
#include "usbd_core.h" #include "usbd_core.h"
#include "usb_dwc2_reg.h" #include "usb_dwc2_reg.h"
#include "usb_dwc2_param.h"
// clang-format off // clang-format off
#if defined ( __CC_ARM ) #if defined ( __CC_ARM )
@@ -51,46 +52,6 @@
#endif #endif
// clang-format on // clang-format on
#ifndef CONFIG_USB_DWC2_RXALL_FIFO_SIZE
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX0_FIFO_SIZE
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX1_FIFO_SIZE
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX2_FIFO_SIZE
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX3_FIFO_SIZE
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX4_FIFO_SIZE
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX5_FIFO_SIZE
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX6_FIFO_SIZE
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX7_FIFO_SIZE
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX8_FIFO_SIZE
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
#endif
#define USBD_BASE (g_usbdev_bus[busid].reg_base) #define USBD_BASE (g_usbdev_bus[busid].reg_base)
#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE)) #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE))
@@ -115,9 +76,11 @@ struct dwc2_ep_state {
/* Driver state */ /* Driver state */
USB_NOCACHE_RAM_SECTION struct dwc2_udc { USB_NOCACHE_RAM_SECTION struct dwc2_udc {
USB_MEM_ALIGNX struct usb_setup_packet setup; USB_MEM_ALIGNX struct usb_setup_packet setup;
USB_MEM_ALIGNX uint32_t GSNPSID; uint8_t pad[24]; /* Pad to 32 bytes */
struct dwc2_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/ struct dwc2_hw_params hw_params;
struct dwc2_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */ struct dwc2_user_params user_params;
struct dwc2_ep_state in_ep[16]; /*!< IN endpoint parameters*/
struct dwc2_ep_state out_ep[16]; /*!< OUT endpoint parameters */
} g_dwc2_udc[CONFIG_USBDEV_MAX_BUS]; } g_dwc2_udc[CONFIG_USBDEV_MAX_BUS];
static inline int dwc2_reset(uint8_t busid) static inline int dwc2_reset(uint8_t busid)
@@ -135,7 +98,7 @@ static inline int dwc2_reset(uint8_t busid)
count = 0U; count = 0U;
USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
if (g_dwc2_udc[busid].GSNPSID < 0x4F54420AU) { if (g_dwc2_udc[busid].hw_params.snpsid < 0x4F54420AU) {
do { do {
if (++count > 200000U) { if (++count > 200000U) {
USB_LOG_ERR("DWC2 reset timeout\r\n"); USB_LOG_ERR("DWC2 reset timeout\r\n");
@@ -160,22 +123,42 @@ static inline int dwc2_reset(uint8_t busid)
static inline int dwc2_core_init(uint8_t busid) static inline int dwc2_core_init(uint8_t busid)
{ {
int ret; int ret;
#if defined(CONFIG_USB_HS) uint32_t regval;
/* Init The ULPI Interface */
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
/* Select vbus source */ if (g_dwc2_udc[busid].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); /* Select FS Embedded PHY */
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
} else {
regval = USB_OTG_GLB->GUSBCFG;
regval &= ~USB_OTG_GUSBCFG_PHYSEL;
/* disable external vbus source */
regval &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* disable ULPI FS/LS */
regval &= ~(USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_ULPICSM);
switch (g_dwc2_udc[busid].user_params.phy_type) {
case DWC2_PHY_TYPE_PARAM_ULPI:
regval |= USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
regval &= ~USB_OTG_GUSBCFG_DDR_SEL;
if (g_dwc2_udc[busid].user_params.phy_utmi_width == 16) {
regval |= USB_OTG_GUSBCFG_PHYIF16;
}
break;
case DWC2_PHY_TYPE_PARAM_UTMI:
regval &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
break;
default:
break;
}
USB_OTG_GLB->GUSBCFG = regval;
}
/* Reset after a PHY select */ /* Reset after a PHY select */
ret = dwc2_reset(busid); ret = dwc2_reset(busid);
#else
/* Select FS Embedded PHY */
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
/* Reset after a PHY select */
ret = dwc2_reset(busid);
#endif
return ret; return ret;
} }
@@ -285,8 +268,6 @@ static void dwc2_set_turnaroundtime(uint8_t busid, uint32_t hclk, uint8_t speed)
UsbTrd = USBD_DEFAULT_TRDT_VALUE; UsbTrd = USBD_DEFAULT_TRDT_VALUE;
} }
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_TOCAL;
USB_OTG_GLB->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; USB_OTG_GLB->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
USB_OTG_GLB->GUSBCFG |= (uint32_t)((UsbTrd << USB_OTG_GUSBCFG_TRDT_Pos) & USB_OTG_GUSBCFG_TRDT); USB_OTG_GLB->GUSBCFG |= (uint32_t)((UsbTrd << USB_OTG_GUSBCFG_TRDT_Pos) & USB_OTG_GUSBCFG_TRDT);
} }
@@ -347,11 +328,11 @@ static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup)
USB_OTG_OUTEP(0U)->DOEPTSIZ |= (3U * 8U); USB_OTG_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
USB_OTG_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT; USB_OTG_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
#ifdef CONFIG_USB_DWC2_DMA_ENABLE if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup; USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
/* EP enable */ /* EP enable */
USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP; USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
#endif }
} }
void dwc2_ep_write(uint8_t busid, uint8_t ep_idx, uint8_t *src, uint16_t len) void dwc2_ep_write(uint8_t busid, uint8_t ep_idx, uint8_t *src, uint16_t len)
@@ -504,41 +485,13 @@ static inline uint32_t dwc2_get_inep_intstatus(uint8_t busid, uint8_t epnum)
int usb_dc_init(uint8_t busid) int usb_dc_init(uint8_t busid)
{ {
int ret; int ret;
uint8_t fsphy_type;
uint8_t hsphy_type;
uint8_t dma_support;
uint8_t endpoints;
uint32_t fifo_num; uint32_t fifo_num;
memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc)); memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
usb_dc_low_level_init(busid); usb_dc_low_level_init(busid);
/* USB_LOG_INFO("========== dwc2 dcd params ==========\r\n");
Full-Speed PHY Interface Type (FSPhyType)
2'b00: Full-speed interface not supported
2'b01: Dedicated full-speed interface
2'b10: FS pins shared with UTMI+ pins
2'b11: FS pins shared with ULPI pins
High-Speed PHY Interface Type (HSPhyType)
2'b00: High-Speed interface not supported
2'b01: UTMI+
2'b10: ULPI
2'b11: UTMI+ and ULPI
Architecture (OtgArch)
2'b00: Slave-Only
2'b01: External DMA
2'b10: Internal DMA
Others: Reserved
*/
fsphy_type = ((USB_OTG_GLB->GHWCFG2 & (0x03 << 8)) >> 8);
hsphy_type = ((USB_OTG_GLB->GHWCFG2 & (0x03 << 6)) >> 6);
dma_support = ((USB_OTG_GLB->GHWCFG2 & (0x03 << 3)) >> 3);
endpoints = ((USB_OTG_GLB->GHWCFG2 & (0x0f << 10)) >> 10) + 1;
USB_LOG_INFO("========== dwc2 udc params ==========\r\n");
USB_LOG_INFO("CID:%08x\r\n", (unsigned int)USB_OTG_GLB->CID); USB_LOG_INFO("CID:%08x\r\n", (unsigned int)USB_OTG_GLB->CID);
USB_LOG_INFO("GSNPSID:%08x\r\n", (unsigned int)USB_OTG_GLB->GSNPSID); USB_LOG_INFO("GSNPSID:%08x\r\n", (unsigned int)USB_OTG_GLB->GSNPSID);
USB_LOG_INFO("GHWCFG1:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG1); USB_LOG_INFO("GHWCFG1:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG1);
@@ -546,26 +499,40 @@ int usb_dc_init(uint8_t busid)
USB_LOG_INFO("GHWCFG3:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG3); USB_LOG_INFO("GHWCFG3:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG3);
USB_LOG_INFO("GHWCFG4:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG4); USB_LOG_INFO("GHWCFG4:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG4);
USB_LOG_INFO("dwc2 fsphy type:%d, hsphy type:%d, dma support:%d\r\n", fsphy_type, hsphy_type, dma_support); dwc2_get_hwparams(USBD_BASE, &g_dwc2_udc[busid].hw_params);
USB_LOG_INFO("dwc2 has %d endpoints and dfifo depth(32-bit words) is %d, default config: %d endpoints\r\n", endpoints, (USB_OTG_GLB->GHWCFG3 >> 16), CONFIG_USBDEV_EP_NUM); dwc2_get_user_params(USBD_BASE, &g_dwc2_udc[busid].user_params);
USB_LOG_INFO("=================================\r\n");
USB_ASSERT_MSG(endpoints >= CONFIG_USBDEV_EP_NUM, "dwc2 has less endpoints than config, please check"); if (g_dwc2_udc[busid].user_params.phy_utmi_width == 0) {
g_dwc2_udc[busid].user_params.phy_utmi_width = 8;
}
if (g_dwc2_udc[busid].user_params.total_fifo_size == 0) {
g_dwc2_udc[busid].user_params.total_fifo_size = g_dwc2_udc[busid].hw_params.total_fifo_size;
}
g_dwc2_udc[busid].GSNPSID = USB_OTG_GLB->GSNPSID; USB_LOG_INFO("dwc2 has %d endpoints and dfifo depth(32-bit words) is %d\r\n",
g_dwc2_udc[busid].hw_params.num_dev_ep + 1,
USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS; g_dwc2_udc[busid].user_params.total_fifo_size);
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS;
/* This is vendor register */ /* This is vendor register */
USB_OTG_GLB->GCCFG = usbd_get_dwc2_gccfg_conf(USBD_BASE); USB_OTG_GLB->GCCFG = g_dwc2_udc[busid].user_params.device_gccfg;
ret = dwc2_core_init(busid); ret = dwc2_core_init(busid);
/* Force Device Mode*/ /* Force Device Mode*/
dwc2_set_mode(busid, USB_OTG_MODE_DEVICE); dwc2_set_mode(busid, USB_OTG_MODE_DEVICE);
if (g_dwc2_udc[busid].user_params.b_session_valid_override) {
/* B-peripheral session valid override enable */
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
}
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_TOCAL;
for (uint8_t i = 0U; i < 15U; i++) { for (uint8_t i = 0U; i < 15U; i++) {
USB_OTG_GLB->DIEPTXF[i] = 0U; USB_OTG_GLB->DIEPTXF[i] = 0U;
} }
@@ -575,15 +542,17 @@ int usb_dc_init(uint8_t busid)
/* Device speed configuration */ /* Device speed configuration */
USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DSPD; USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DSPD;
#if defined(CONFIG_USB_HS)
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH; if (g_dwc2_udc[busid].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
#else USB_ASSERT_MSG(g_dwc2_udc[busid].hw_params.hs_phy_type != 0, "This dwc2 version does not support hs, so stop working");
if (hsphy_type == 0) { USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH;
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_FULL;
} else { } else {
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH_IN_FULL; if (g_dwc2_udc[busid].hw_params.hs_phy_type == 0) {
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_FULL;
} else {
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH_IN_FULL;
}
} }
#endif
/* Clear all pending Device Interrupts */ /* Clear all pending Device Interrupts */
USB_OTG_DEV->DIEPMSK = 0U; USB_OTG_DEV->DIEPMSK = 0U;
@@ -600,58 +569,35 @@ int usb_dc_init(uint8_t busid)
USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT |
USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM; USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM;
#ifdef CONFIG_USB_DWC2_DMA_ENABLE if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_ASSERT_MSG(((USB_OTG_GLB->GHWCFG2 & (0x3U << 3)) >> 3) == 2, "This dwc2 version does not support dma mode, so stop working"); USB_ASSERT_MSG(g_dwc2_udc[busid].hw_params.arch == GHWCFG2_INT_DMA_ARCH, "This dwc2 version does not support dma mode, so stop working");
USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DESCDMA;
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_HBSTLEN;
USB_OTG_GLB->GAHBCFG |= (USB_OTG_GAHBCFG_DMAEN | USB_OTG_GAHBCFG_HBSTLEN_4);
} else {
USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
}
USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DESCDMA;
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_HBSTLEN;
USB_OTG_GLB->GAHBCFG |= (USB_OTG_GAHBCFG_DMAEN | USB_OTG_GAHBCFG_HBSTLEN_4);
#else
USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
#endif
#if CONFIG_DWC2_VBUS_SENSING
USB_OTG_GLB->GINTMSK |= (USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_SRQIM);
#endif
#ifdef CONFIG_USBDEV_SOF_ENABLE #ifdef CONFIG_USBDEV_SOF_ENABLE
USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_SOFM; USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_SOFM;
#endif #endif
USB_OTG_GLB->GRXFSIZ = (CONFIG_USB_DWC2_RXALL_FIFO_SIZE); USB_OTG_GLB->GRXFSIZ = g_dwc2_udc[busid].user_params.device_rx_fifo_size;
dwc2_set_txfifo(busid, 0, CONFIG_USB_DWC2_TX0_FIFO_SIZE); fifo_num = g_dwc2_udc[busid].user_params.device_rx_fifo_size;
dwc2_set_txfifo(busid, 1, CONFIG_USB_DWC2_TX1_FIFO_SIZE); for (uint8_t i = 0; i < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1); i++) {
dwc2_set_txfifo(busid, 2, CONFIG_USB_DWC2_TX2_FIFO_SIZE); dwc2_set_txfifo(busid, i, g_dwc2_udc[busid].user_params.device_tx_fifo_size[i]);
dwc2_set_txfifo(busid, 3, CONFIG_USB_DWC2_TX3_FIFO_SIZE); fifo_num += g_dwc2_udc[busid].user_params.device_tx_fifo_size[i];
fifo_num = CONFIG_USB_DWC2_RXALL_FIFO_SIZE; USB_ASSERT_MSG(fifo_num <= g_dwc2_udc[busid].user_params.total_fifo_size, "Your fifo config is overflow, please check");
fifo_num += CONFIG_USB_DWC2_TX0_FIFO_SIZE; }
fifo_num += CONFIG_USB_DWC2_TX1_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX2_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX3_FIFO_SIZE;
#if CONFIG_USBDEV_EP_NUM > 4
dwc2_set_txfifo(busid, 4, CONFIG_USB_DWC2_TX4_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX4_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 5
dwc2_set_txfifo(busid, 5, CONFIG_USB_DWC2_TX5_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX5_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 6
dwc2_set_txfifo(busid, 6, CONFIG_USB_DWC2_TX6_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX6_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 7
dwc2_set_txfifo(busid, 7, CONFIG_USB_DWC2_TX7_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX7_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 8
dwc2_set_txfifo(busid, 8, CONFIG_USB_DWC2_TX8_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX8_FIFO_SIZE;
#endif
USB_ASSERT_MSG(fifo_num <= (USB_OTG_GLB->GHWCFG3 >> 16), "Your fifo config is overflow, please check"); if (g_dwc2_udc[busid].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
/* xxx32 chips do not follow (USB_OTG_GLB->GHWCFG3 >> 16) if hsphy_type is zero, they use 1.25KB(320 DWORD) */ USB_ASSERT_MSG(g_dwc2_udc[busid].user_params.device_rx_fifo_size >= (5 + 8 + 512 / 4 + 1 + 2 * 8 + 1), "Your rx fifo size config is invalid, please check");
USB_ASSERT_MSG(!((hsphy_type == 0) && (fifo_num > 320)), "Your fifo config is larger than 320 , please check"); } else {
USB_ASSERT_MSG(g_dwc2_udc[busid].user_params.device_rx_fifo_size >= (5 + 8 + 64 / 4 + 1 + 2 * 8 + 1), "Your rx fifo size config is invalid, please check");
}
ret = dwc2_flush_txfifo(busid, 0x10U); ret = dwc2_flush_txfifo(busid, 0x10U);
ret = dwc2_flush_rxfifo(busid); ret = dwc2_flush_rxfifo(busid);
@@ -725,7 +671,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
{ {
uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress); uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
USB_ASSERT_MSG(ep_idx < CONFIG_USBDEV_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress); USB_ASSERT_MSG(ep_idx < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1), "Ep addr %02x overflow", ep->bEndpointAddress);
if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) { if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
@@ -829,11 +775,11 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
} }
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_STALL; USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
} }
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
if (ep_idx == 0) { if ((ep_idx == 0) && g_dwc2_udc[busid].user_params.device_dma_enable) {
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
} }
#endif
return 0; return 0;
} }
@@ -884,9 +830,9 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
USB_ASSERT_MSG(!((uint32_t)data % 0x04), "dwc2 data must be 4-byte aligned"); USB_ASSERT_MSG(!((uint32_t)data % 0x04), "dwc2 data must be 4-byte aligned");
#ifdef CONFIG_USB_DCACHE_ENABLE if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE); USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
#endif }
if (!data && data_len) { if (!data && data_len) {
return -1; return -1;
@@ -935,18 +881,18 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29)); USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
} }
#ifdef CONFIG_USB_DWC2_DMA_ENABLE if (g_dwc2_udc[busid].user_params.device_dma_enable) {
usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE)); usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
USB_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data; USB_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data;
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
#else } else {
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
/* Enable the Tx FIFO Empty Interrupt for this EP */ /* Enable the Tx FIFO Empty Interrupt for this EP */
if (data_len > 0U) { if (data_len > 0U) {
USB_OTG_DEV->DIEPEMPMSK |= 1UL << (ep_idx & 0x0f); USB_OTG_DEV->DIEPEMPMSK |= 1UL << (ep_idx & 0x0f);
}
} }
#endif
return 0; return 0;
} }
@@ -957,9 +903,9 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
USB_ASSERT_MSG(!((uint32_t)data % 0x04), "dwc2 data must be 4-byte aligned"); USB_ASSERT_MSG(!((uint32_t)data % 0x04), "dwc2 data must be 4-byte aligned");
#ifdef CONFIG_USB_DCACHE_ENABLE if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE); USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
#endif }
if (!data && data_len) { if (!data && data_len) {
return -1; return -1;
@@ -996,9 +942,9 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len); USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len);
} }
#ifdef CONFIG_USB_DWC2_DMA_ENABLE if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data; USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
#endif }
if (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { if (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) { if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM; USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
@@ -1025,29 +971,30 @@ void USBD_IRQHandler(uint8_t busid)
return; return;
} }
#ifndef CONFIG_USB_DWC2_DMA_ENABLE if (!g_dwc2_udc[busid].user_params.device_dma_enable) {
/* Handle RxQLevel Interrupt */ /* Handle RxQLevel Interrupt */
if (gint_status & USB_OTG_GINTSTS_RXFLVL) { if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL); USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
temp = USB_OTG_GLB->GRXSTSP; temp = USB_OTG_GLB->GRXSTSP;
ep_idx = temp & USB_OTG_GRXSTSP_EPNUM; ep_idx = temp & USB_OTG_GRXSTSP_EPNUM;
if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) { if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4; read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
if (read_count != 0) { if (read_count != 0) {
dwc2_ep_read(busid, g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, read_count); dwc2_ep_read(busid, g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, read_count);
g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf += read_count; g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf += read_count;
}
} else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) {
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
dwc2_ep_read(busid, (uint8_t *)&g_dwc2_udc[busid].setup, read_count);
} else {
/* ... */
} }
} else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) { USB_UNMASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
dwc2_ep_read(busid, (uint8_t *)&g_dwc2_udc[busid].setup, read_count);
} else {
/* ... */
} }
USB_UNMASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
} }
#endif
if (gint_status & USB_OTG_GINTSTS_OEPINT) { if (gint_status & USB_OTG_GINTSTS_OEPINT) {
ep_idx = 0; ep_idx = 0;
ep_intr = dwc2_get_outeps_intstatus(busid); ep_intr = dwc2_get_outeps_intstatus(busid);
@@ -1109,8 +1056,10 @@ void USBD_IRQHandler(uint8_t busid)
usbd_event_ep_in_complete_handler(busid, ep_idx | 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len); usbd_event_ep_in_complete_handler(busid, ep_idx | 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len);
} }
} }
if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) { if (!g_dwc2_udc[busid].user_params.device_dma_enable) {
dwc2_tx_fifo_empty_procecss(busid, ep_idx); if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) {
dwc2_tx_fifo_empty_procecss(busid, ep_idx);
}
} }
} }
ep_intr >>= 1U; ep_intr >>= 1U;
@@ -1124,7 +1073,7 @@ void USBD_IRQHandler(uint8_t busid)
dwc2_flush_txfifo(busid, 0x10U); dwc2_flush_txfifo(busid, 0x10U);
dwc2_flush_rxfifo(busid); dwc2_flush_rxfifo(busid);
for (uint8_t i = 0U; i < CONFIG_USBDEV_EP_NUM; i++) { for (uint8_t i = 0U; i < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1); i++) {
if (i == 0U) { if (i == 0U) {
USB_OTG_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK; USB_OTG_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
USB_OTG_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK; USB_OTG_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
@@ -1153,7 +1102,8 @@ void USBD_IRQHandler(uint8_t busid)
USB_OTG_DEV->DIEPMSK = USB_OTG_DIEPMSK_XFRCM; USB_OTG_DEV->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc)); memset(g_dwc2_udc[busid].in_ep, 0, sizeof(struct dwc2_ep_state) * 16);
memset(g_dwc2_udc[busid].out_ep, 0, sizeof(struct dwc2_ep_state) * 16);
usbd_event_reset_handler(busid); usbd_event_reset_handler(busid);
/* Start reading setup */ /* Start reading setup */
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);

357
port/dwc2/usb_dwc2_param.h Normal file
View File

@@ -0,0 +1,357 @@
/*
* 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 0xffff0000
#define GHWCFG1_OFFSET HSOTG_REG(0x0044)
#define GHWCFG2_OFFSET HSOTG_REG(0x0048)
#define GHWCFG2_OTG_ENABLE_IC_USB (1U << 31)
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1f << 26)
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT 26
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24)
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT 24
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22)
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT 22
#define GHWCFG2_MULTI_PROC_INT (1 << 20)
#define GHWCFG2_DYNAMIC_FIFO (1 << 19)
#define GHWCFG2_PERIO_EP_SUPPORTED (1 << 18)
#define GHWCFG2_NUM_HOST_CHAN_MASK (0xf << 14)
#define GHWCFG2_NUM_HOST_CHAN_SHIFT 14
#define GHWCFG2_NUM_DEV_EP_MASK (0xf << 10)
#define GHWCFG2_NUM_DEV_EP_SHIFT 10
#define GHWCFG2_FS_PHY_TYPE_MASK (0x3 << 8)
#define GHWCFG2_FS_PHY_TYPE_SHIFT 8
#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0
#define GHWCFG2_FS_PHY_TYPE_DEDICATED 1
#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI 2
#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI 3
#define GHWCFG2_HS_PHY_TYPE_MASK (0x3 << 6)
#define GHWCFG2_HS_PHY_TYPE_SHIFT 6
#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
#define GHWCFG2_HS_PHY_TYPE_UTMI 1
#define GHWCFG2_HS_PHY_TYPE_ULPI 2
#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
#define GHWCFG2_POINT2POINT (1 << 5)
#define GHWCFG2_ARCHITECTURE_MASK (0x3 << 3)
#define GHWCFG2_ARCHITECTURE_SHIFT 3
#define GHWCFG2_SLAVE_ONLY_ARCH 0
#define GHWCFG2_EXT_DMA_ARCH 1
#define GHWCFG2_INT_DMA_ARCH 2
#define GHWCFG2_OP_MODE_MASK (0x7 << 0)
#define GHWCFG2_OP_MODE_SHIFT 0
#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE 0
#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE 1
#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE 2
#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
#define GHWCFG2_OP_MODE_UNDEFINED 7
#define GHWCFG3_OFFSET HSOTG_REG(0x004c)
#define GHWCFG3_DFIFO_DEPTH_MASK (0xffff << 16)
#define GHWCFG3_DFIFO_DEPTH_SHIFT 16
#define GHWCFG3_OTG_LPM_EN (1 << 15)
#define GHWCFG3_BC_SUPPORT (1 << 14)
#define GHWCFG3_OTG_ENABLE_HSIC (1 << 13)
#define GHWCFG3_ADP_SUPP (1 << 12)
#define GHWCFG3_SYNCH_RESET_TYPE (1 << 11)
#define GHWCFG3_OPTIONAL_FEATURES (1 << 10)
#define GHWCFG3_VENDOR_CTRL_IF (1 << 9)
#define GHWCFG3_I2C (1 << 8)
#define GHWCFG3_OTG_FUNC (1 << 7)
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4)
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT 4
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xf << 0)
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT 0
#define GHWCFG4_OFFSET HSOTG_REG(0x0050)
#define GHWCFG4_DESC_DMA_DYN (1U << 31)
#define GHWCFG4_DESC_DMA (1 << 30)
#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26)
#define GHWCFG4_NUM_IN_EPS_SHIFT 26
#define GHWCFG4_DED_FIFO_EN (1 << 25)
#define GHWCFG4_DED_FIFO_SHIFT 25
#define GHWCFG4_SESSION_END_FILT_EN (1 << 24)
#define GHWCFG4_B_VALID_FILT_EN (1 << 23)
#define GHWCFG4_A_VALID_FILT_EN (1 << 22)
#define GHWCFG4_VBUS_VALID_FILT_EN (1 << 21)
#define GHWCFG4_IDDIG_FILT_EN (1 << 20)
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xf << 16)
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT 16
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14)
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2
#define GHWCFG4_ACG_SUPPORTED (1 << 12)
#define GHWCFG4_IPG_ISOC_SUPPORTED (1 << 11)
#define GHWCFG4_SERVICE_INTERVAL_SUPPORTED (1 << 10)
#define GHWCFG4_XHIBER (1 << 7)
#define GHWCFG4_HIBER (1 << 6)
#define GHWCFG4_MIN_AHB_FREQ (1 << 5)
#define GHWCFG4_POWER_OPTIMIZ (1 << 4)
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xf << 0)
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT 0
/**
* 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;
};
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);
#endif

View File

@@ -209,12 +209,15 @@ typedef struct
#define USB_OTG_HCFG_FSLSPCS_Pos (0U) #define USB_OTG_HCFG_FSLSPCS_Pos (0U)
#define USB_OTG_HCFG_FSLSPCS_Msk (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */ #define USB_OTG_HCFG_FSLSPCS_Msk (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */
#define USB_OTG_HCFG_FSLSPCS USB_OTG_HCFG_FSLSPCS_Msk /*!< FS/LS PHY clock select */ #define USB_OTG_HCFG_FSLSPCS USB_OTG_HCFG_FSLSPCS_Msk /*!< FS/LS PHY clock select */
#define USB_OTG_HCFG_FSLSPCS_0 (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */ #define USB_OTG_HCFG_FSLSPCLKSEL_30_60_MHZ (0x0UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000000 */
#define USB_OTG_HCFG_FSLSPCS_1 (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */ #define USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */
#define USB_OTG_HCFG_FSLSPCLKSEL_6_MHZ (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */
#define USB_OTG_HCFG_FSLSS_Pos (2U) #define USB_OTG_HCFG_FSLSS_Pos (2U)
#define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */ #define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */
#define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */ #define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */
#define USB_OTG_HFIR_RELOAD_CTRL_Pos (16U)
#define USB_OTG_HFIR_RELOAD_CTRL_Msk (0x1UL << USB_OTG_HFIR_RELOAD_CTRL_Pos)
#define USB_OTG_HFIR_RELOAD_CTRL USB_OTG_HFIR_RELOAD_CTRL_Msk
/******************** Bit definition for USB_OTG_DCFG register ********************/ /******************** Bit definition for USB_OTG_DCFG register ********************/
#define USB_OTG_DCFG_DSPD_Pos (0U) #define USB_OTG_DCFG_DSPD_Pos (0U)
@@ -385,12 +388,20 @@ typedef struct
#define USB_OTG_GUSBCFG_TOCAL_Pos (0U) #define USB_OTG_GUSBCFG_TOCAL_Pos (0U)
#define USB_OTG_GUSBCFG_TOCAL_Msk (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */ #define USB_OTG_GUSBCFG_TOCAL_Msk (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */
#define USB_OTG_GUSBCFG_TOCAL USB_OTG_GUSBCFG_TOCAL_Msk /*!< FS timeout calibration */ #define USB_OTG_GUSBCFG_TOCAL USB_OTG_GUSBCFG_TOCAL_Msk /*!< FS timeout calibration */
#define USB_OTG_GUSBCFG_TOCAL_0 (0x1UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000001 */ #define USB_OTG_GUSBCFG_PHYIF_Pos (3U)
#define USB_OTG_GUSBCFG_TOCAL_1 (0x2UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000002 */ #define USB_OTG_GUSBCFG_PHYIF_Msk (0x1UL << USB_OTG_GUSBCFG_PHYIF_Pos)
#define USB_OTG_GUSBCFG_TOCAL_2 (0x4UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000004 */ #define USB_OTG_GUSBCFG_PHYIF USB_OTG_GUSBCFG_PHYIF_Msk
#define USB_OTG_GUSBCFG_PHYIF8 (0x0UL << USB_OTG_GUSBCFG_PHYIF_Pos)
#define USB_OTG_GUSBCFG_PHYIF16 (0x1UL << USB_OTG_GUSBCFG_PHYIF_Pos)
#define USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Pos (4U)
#define USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Msk (0x1UL << USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Pos)
#define USB_OTG_GUSBCFG_ULPI_UTMI_SEL USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Msk
#define USB_OTG_GUSBCFG_PHYSEL_Pos (6U) #define USB_OTG_GUSBCFG_PHYSEL_Pos (6U)
#define USB_OTG_GUSBCFG_PHYSEL_Msk (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */ #define USB_OTG_GUSBCFG_PHYSEL_Msk (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */
#define USB_OTG_GUSBCFG_PHYSEL USB_OTG_GUSBCFG_PHYSEL_Msk /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ #define USB_OTG_GUSBCFG_PHYSEL USB_OTG_GUSBCFG_PHYSEL_Msk /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */
#define USB_OTG_GUSBCFG_DDR_SEL_Pos (7U)
#define USB_OTG_GUSBCFG_DDR_SEL_Msk (0x1UL << USB_OTG_GUSBCFG_DDR_SEL_Pos)
#define USB_OTG_GUSBCFG_DDR_SEL USB_OTG_GUSBCFG_DDR_SEL_Msk
#define USB_OTG_GUSBCFG_SRPCAP_Pos (8U) #define USB_OTG_GUSBCFG_SRPCAP_Pos (8U)
#define USB_OTG_GUSBCFG_SRPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */ #define USB_OTG_GUSBCFG_SRPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */
#define USB_OTG_GUSBCFG_SRPCAP USB_OTG_GUSBCFG_SRPCAP_Msk /*!< SRP-capable */ #define USB_OTG_GUSBCFG_SRPCAP USB_OTG_GUSBCFG_SRPCAP_Msk /*!< SRP-capable */
@@ -1720,7 +1731,5 @@ typedef struct
void usb_dc_low_level_init(uint8_t busid); void usb_dc_low_level_init(uint8_t busid);
void usb_dc_low_level_deinit(uint8_t busid); void usb_dc_low_level_deinit(uint8_t busid);
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base);
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base);
void usbd_dwc2_delay_ms(uint8_t ms); void usbd_dwc2_delay_ms(uint8_t ms);
#endif #endif

View File

@@ -12,6 +12,7 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "usbd_core.h" #include "usbd_core.h"
#include "usbh_core.h" #include "usbh_core.h"
#include "usb_dwc2_param.h"
#ifdef CONFIG_IDF_TARGET_ESP32S2 #ifdef CONFIG_IDF_TARGET_ESP32S2
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
@@ -30,6 +31,95 @@ uint32_t SystemCoreClock = (DEFAULT_CPU_FREQ_MHZ * 1000 * 1000);
static usb_phy_handle_t s_phy_handle = NULL; static usb_phy_handle_t s_phy_handle = NULL;
static intr_handle_t s_interrupt_handle = NULL; static intr_handle_t s_interrupt_handle = 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) static void usb_dc_interrupt_cb(void *arg_pv)
{ {
extern void USBD_IRQHandler(uint8_t busid); extern void USBD_IRQHandler(uint8_t busid);
@@ -75,11 +165,6 @@ void usb_dc_low_level_deinit(uint8_t busid)
} }
} }
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
{
return 0;
}
static void usb_hc_interrupt_cb(void *arg_pv) static void usb_hc_interrupt_cb(void *arg_pv)
{ {
extern void USBH_IRQHandler(uint8_t busid); extern void USBH_IRQHandler(uint8_t busid);
@@ -129,9 +214,17 @@ void usb_hc_low_level_deinit(struct usbh_bus *bus)
} }
} }
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
{ {
return 0; #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
memcpy(params, &param_fs, sizeof(struct dwc2_user_params));
#elif CONFIG_IDF_TARGET_ESP32P4
if (reg_base == 0x50000000UL) {
memcpy(params, &param_hs, sizeof(struct dwc2_user_params));
} else {
memcpy(params, &param_fs, sizeof(struct dwc2_user_params));
}
#endif
} }
void usbd_dwc2_delay_ms(uint8_t ms) void usbd_dwc2_delay_ms(uint8_t ms)

View File

@@ -5,21 +5,544 @@
*/ */
#include "usbd_core.h" #include "usbd_core.h"
#include "usbh_core.h" #include "usbh_core.h"
#include "usb_dwc2_param.h"
#if __has_include("stm32f1xx_hal.h") #if __has_include("stm32f1xx_hal.h")
#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") #elif __has_include("stm32f2xx_hal.h")
#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") #elif __has_include("stm32f4xx_hal.h")
#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 = (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
#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") #elif __has_include("stm32f7xx_hal.h")
#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") #elif __has_include("stm32h7xx_hal.h")
#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") #elif __has_include("stm32h7rsxx_hal.h")
#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") #elif __has_include("stm32l4xx_hal.h")
#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
#if !defined(HAL_HCD_MODULE_ENABLED) && !defined(HAL_PCD_MODULE_ENABLED) #if !defined(HAL_HCD_MODULE_ENABLED) && !defined(HAL_PCD_MODULE_ENABLED)
@@ -36,74 +559,6 @@ static usb_dwc2_irq g_usb_dwc2_irq[2];
static uint8_t g_usb_dwc2_busid[2] = { 0, 0 }; static uint8_t g_usb_dwc2_busid[2] = { 0, 0 };
static struct dwc2_instance g_dwc2_instance; static struct dwc2_instance g_dwc2_instance;
#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);
}
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);
}
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
/* you can find this config in function: USB_DevInit, file:stm32xxx_ll_usb.c, for example:
*
* USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
* USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
* USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
* USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
*
*/
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx) #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
/** /**
* @brief Enables control of a High Speed USB PHY * @brief Enables control of a High Speed USB PHY
@@ -163,60 +618,81 @@ static int usb_hsphy_init(uint32_t hse_value)
} }
#endif #endif
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) #ifdef HAL_PCD_MODULE_ENABLED
void usb_dc_low_level_init(uint8_t busid)
{ {
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h") if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
#define USB_OTG_GLB ((USB_OTG_GlobalTypeDef *)(reg_base)) g_usb_dwc2_busid[1] = busid;
/* B-peripheral session valid override enable */ g_usb_dwc2_irq[1] = USBD_IRQHandler;
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; } else {
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; g_usb_dwc2_busid[0] = busid;
#endif 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);
#ifdef CONFIG_USB_HS
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx) #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
USB_OTG_GLB->GCCFG = (1 << 23);
usb_hsphy_init(25000000U); usb_hsphy_init(25000000U);
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
#elif __has_include("stm32h7rsxx.h")
return ((1 << 23) | (1 << 24));
#else
return 0;
#endif
#else
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
return (1 << 16);
#else
return ((1 << 16) | (1 << 21));
#endif
#endif #endif
} }
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) void usb_dc_low_level_deinit(uint8_t busid)
{ {
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h") if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
#define USB_OTG_GLB ((USB_OTG_GlobalTypeDef *)(reg_base)) g_usb_dwc2_busid[1] = 0;
/* B-peripheral session valid override enable */ g_usb_dwc2_irq[1] = NULL;
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN; } else {
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL; 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 #endif
#ifdef CONFIG_USB_HS #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) #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
USB_OTG_GLB->GCCFG = (1 << 23);
usb_hsphy_init(25000000U); usb_hsphy_init(25000000U);
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
#elif __has_include("stm32h7rsxx.h")
return (1 << 25);
#else
return 0;
#endif
#else
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
return (1 << 16);
#else
return ((1 << 16) | (1 << 21));
#endif #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 #endif
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, &param_pb14_pb15, sizeof(struct dwc2_user_params));
} else {
memcpy(params, &param_pa11_pa12, sizeof(struct dwc2_user_params));
}
} }
extern uint32_t SystemCoreClock; extern uint32_t SystemCoreClock;

View File

@@ -6,28 +6,7 @@
#include "usbh_core.h" #include "usbh_core.h"
#include "usbh_hub.h" #include "usbh_hub.h"
#include "usb_dwc2_reg.h" #include "usb_dwc2_reg.h"
#include "usb_dwc2_param.h"
#ifndef CONFIG_USBHOST_PIPE_NUM
#define CONFIG_USBHOST_PIPE_NUM 12
#endif
/* largest non-periodic USB packet used / 4 */
#ifndef CONFIG_USB_DWC2_NPTX_FIFO_SIZE
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
#endif
/* largest periodic USB packet used / 4 */
#ifndef CONFIG_USB_DWC2_PTX_FIFO_SIZE
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
#endif
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
#ifndef CONFIG_USB_DWC2_RX_FIFO_SIZE
#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
#endif
#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(bus->hcd.reg_base)) #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(bus->hcd.reg_base))
#define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)bus->hcd.reg_base + USB_OTG_PCGCCTL_BASE) #define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)bus->hcd.reg_base + USB_OTG_PCGCCTL_BASE)
@@ -56,8 +35,9 @@ struct dwc2_hcd {
volatile bool port_csc; volatile bool port_csc;
volatile bool port_pec; volatile bool port_pec;
volatile bool port_occ; volatile bool port_occ;
uint32_t GSNPSID; struct dwc2_hw_params hw_params;
struct dwc2_chan chan_pool[CONFIG_USBHOST_PIPE_NUM]; struct dwc2_user_params user_params;
struct dwc2_chan chan_pool[16];
} g_dwc2_hcd[CONFIG_USBHOST_MAX_BUS]; } g_dwc2_hcd[CONFIG_USBHOST_MAX_BUS];
#define DWC2_EP0_STATE_SETUP 0 #define DWC2_EP0_STATE_SETUP 0
@@ -81,7 +61,7 @@ static inline int dwc2_reset(struct usbh_bus *bus)
count = 0U; count = 0U;
USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
if (g_dwc2_hcd[bus->hcd.hcd_id].GSNPSID < 0x4F54420AU) { if (g_dwc2_hcd[bus->hcd.hcd_id].hw_params.snpsid < 0x4F54420AU) {
do { do {
if (++count > 200000U) { if (++count > 200000U) {
USB_LOG_ERR("DWC2 reset timeout\r\n"); USB_LOG_ERR("DWC2 reset timeout\r\n");
@@ -106,22 +86,43 @@ static inline int dwc2_reset(struct usbh_bus *bus)
static inline int dwc2_core_init(struct usbh_bus *bus) static inline int dwc2_core_init(struct usbh_bus *bus)
{ {
int ret; int ret;
#if defined(CONFIG_USB_HS) uint32_t regval;
/* Init The ULPI Interface */
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
/* Select vbus source */ if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); /* Select FS Embedded PHY */
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
} else {
regval = USB_OTG_GLB->GUSBCFG;
regval &= ~USB_OTG_GUSBCFG_PHYSEL;
/* disable external vbus source */
regval &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* disable ULPI FS/LS */
regval &= ~(USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_ULPICSM);
switch (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type) {
case DWC2_PHY_TYPE_PARAM_ULPI:
regval |= USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
regval &= ~USB_OTG_GUSBCFG_DDR_SEL;
break;
case DWC2_PHY_TYPE_PARAM_UTMI:
regval &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_utmi_width == 16) {
regval |= USB_OTG_GUSBCFG_PHYIF16;
}
break;
default:
break;
}
USB_OTG_GLB->GUSBCFG = regval;
}
//USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
/* Reset after a PHY select */ /* Reset after a PHY select */
ret = dwc2_reset(bus); ret = dwc2_reset(bus);
#else
/* Select FS Embedded PHY */
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
/* Reset after a PHY select */
ret = dwc2_reset(bus);
#endif
return ret; return ret;
} }
@@ -390,13 +391,60 @@ static inline uint16_t dwc2_get_full_frame_num(struct usbh_bus *bus)
return ((frame & 0x3FFF) >> 3); return ((frame & 0x3FFF) >> 3);
} }
/**
* dwc2_calc_frame_interval() - Calculates the correct frame Interval value for
* the HFIR register according to PHY type and speed
*
* NOTE: The caller can modify the value of the HFIR register only after the
* Port Enable bit of the Host Port Control and Status register (HPRT.EnaPort)
* has been set
*/
uint32_t dwc2_calc_frame_interval(struct usbh_bus *bus)
{
uint32_t usbcfg;
uint32_t hprt0;
int clock = 60; /* default value */
usbcfg = USB_OTG_GLB->GUSBCFG;
hprt0 = USB_OTG_HPRT;
if (!(usbcfg & USB_OTG_GUSBCFG_PHYSEL) && (usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) &&
!(usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 60;
if ((usbcfg & USB_OTG_GUSBCFG_PHYSEL) && g_dwc2_hcd[bus->hcd.hcd_id].hw_params.fs_phy_type ==
GHWCFG2_FS_PHY_TYPE_SHARED_ULPI)
clock = 48;
if (!(usbcfg & USB_OTG_GUSBCFG_PHYLPCS) && !(usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
!(usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 30;
if (!(usbcfg & USB_OTG_GUSBCFG_PHYLPCS) && !(usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
!(usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) && !(usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 60;
if ((usbcfg & USB_OTG_GUSBCFG_PHYLPCS) && !(usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
!(usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 48;
if ((usbcfg & USB_OTG_GUSBCFG_PHYSEL) && !(usbcfg & USB_OTG_GUSBCFG_PHYIF16) &&
g_dwc2_hcd[bus->hcd.hcd_id].hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_SHARED_UTMI)
clock = 48;
if ((usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
g_dwc2_hcd[bus->hcd.hcd_id].hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED)
clock = 48;
if ((hprt0 & USB_OTG_HPRT_PSPD) >> USB_OTG_HPRT_PSPD_Pos == HPRT0_PRTSPD_HIGH_SPEED)
/* High speed case */
return 125 * clock - 1;
/* FS/LS case */
return 1000 * clock - 1;
}
static int dwc2_chan_alloc(struct usbh_bus *bus) static int dwc2_chan_alloc(struct usbh_bus *bus)
{ {
size_t flags; size_t flags;
int chidx; int chidx;
flags = usb_osal_enter_critical_section(); flags = usb_osal_enter_critical_section();
for (chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) { for (chidx = 0; chidx < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; chidx++) {
if (!g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse) { if (!g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse) {
g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse = true; g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse = true;
usb_osal_leave_critical_section(flags); usb_osal_leave_critical_section(flags);
@@ -544,18 +592,11 @@ __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus)
int usb_hc_init(struct usbh_bus *bus) int usb_hc_init(struct usbh_bus *bus)
{ {
int ret; int ret;
uint8_t channels;
memset(&g_dwc2_hcd[bus->hcd.hcd_id], 0, sizeof(struct dwc2_hcd)); memset(&g_dwc2_hcd[bus->hcd.hcd_id], 0, sizeof(struct dwc2_hcd));
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem = usb_osal_sem_create(0);
}
usb_hc_low_level_init(bus); usb_hc_low_level_init(bus);
channels = ((USB_OTG_GLB->GHWCFG2 & (0x0f << 14)) >> 14) + 1;
USB_LOG_INFO("========== dwc2 hcd params ==========\r\n"); USB_LOG_INFO("========== dwc2 hcd params ==========\r\n");
USB_LOG_INFO("CID:%08x\r\n", (unsigned int)USB_OTG_GLB->CID); USB_LOG_INFO("CID:%08x\r\n", (unsigned int)USB_OTG_GLB->CID);
USB_LOG_INFO("GSNPSID:%08x\r\n", (unsigned int)USB_OTG_GLB->GSNPSID); USB_LOG_INFO("GSNPSID:%08x\r\n", (unsigned int)USB_OTG_GLB->GSNPSID);
@@ -564,34 +605,70 @@ int usb_hc_init(struct usbh_bus *bus)
USB_LOG_INFO("GHWCFG3:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG3); USB_LOG_INFO("GHWCFG3:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG3);
USB_LOG_INFO("GHWCFG4:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG4); USB_LOG_INFO("GHWCFG4:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG4);
USB_LOG_INFO("dwc2 has %d channels and dfifo depth(32-bit words) is %d\r\n", channels, (USB_OTG_GLB->GHWCFG3 >> 16)); dwc2_get_hwparams(bus->hcd.reg_base, &g_dwc2_hcd[bus->hcd.hcd_id].hw_params);
dwc2_get_user_params(bus->hcd.reg_base, &g_dwc2_hcd[bus->hcd.hcd_id].user_params);
USB_ASSERT_MSG(((USB_OTG_GLB->GHWCFG2 & (0x3U << 3)) >> 3) == 2, "This dwc2 version does not support dma mode, so stop working"); if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_utmi_width == 0) {
USB_ASSERT_MSG(channels >= CONFIG_USBHOST_PIPE_NUM, "dwc2 has less channels than config, please check"); g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_utmi_width = 8;
USB_ASSERT_MSG((CONFIG_USB_DWC2_RX_FIFO_SIZE + CONFIG_USB_DWC2_NPTX_FIFO_SIZE + CONFIG_USB_DWC2_PTX_FIFO_SIZE) <= (USB_OTG_GLB->GHWCFG3 >> 16), }
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size == 0) {
g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size = g_dwc2_hcd[bus->hcd.hcd_id].hw_params.total_fifo_size;
}
for (uint8_t chidx = 0; chidx < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; chidx++) {
g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem = usb_osal_sem_create(0);
}
USB_LOG_INFO("dwc2 has %d channels and dfifo depth(32-bit words) is %d\r\n",
g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels,
g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size);
USB_ASSERT_MSG(g_dwc2_hcd[bus->hcd.hcd_id].hw_params.arch == GHWCFG2_INT_DMA_ARCH, "This dwc2 version does not support dma mode, so stop working");
USB_ASSERT_MSG((g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size +
g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size +
g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_perio_tx_fifo_size) <=
g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size,
"Your fifo config is overflow, please check"); "Your fifo config is overflow, please check");
g_dwc2_hcd[bus->hcd.hcd_id].GSNPSID = USB_OTG_GLB->GSNPSID;
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
/* This is vendor register */ /* This is vendor register */
USB_OTG_GLB->GCCFG = usbh_get_dwc2_gccfg_conf(bus->hcd.reg_base); USB_OTG_GLB->GCCFG = g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_gccfg;
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
USB_ASSERT_MSG(g_dwc2_hcd[bus->hcd.hcd_id].hw_params.hs_phy_type != 0, "This dwc2 version does not support hs, so stop working");
}
ret = dwc2_core_init(bus); ret = dwc2_core_init(bus);
/* Force Host Mode*/ /* Force Host Mode*/
dwc2_set_mode(bus, USB_OTG_MODE_HOST); dwc2_set_mode(bus, USB_OTG_MODE_HOST);
usb_osal_msleep(50);
/* B-peripheral session valid override enable */
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN;
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL;
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_TOCAL;
/* Restart the Phy Clock */ /* Restart the Phy Clock */
USB_OTG_PCGCCTL = 0U; USB_OTG_PCGCCTL = 0U;
/* Set default Max speed support */ /* Set default Max speed support */
USB_OTG_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS); USB_OTG_HOST->HCFG &= ~USB_OTG_HCFG_FSLSS;
USB_OTG_HOST->HCFG &= ~USB_OTG_HCFG_FSLSPCS;
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
USB_OTG_HOST->HCFG |= USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ;
} else {
USB_OTG_HOST->HCFG |= USB_OTG_HCFG_FSLSPCLKSEL_30_60_MHZ;
}
if (g_dwc2_hcd[bus->hcd.hcd_id].hw_params.snpsid > 0x4F54292AU) {
USB_OTG_HOST->HCFG |= USB_OTG_HFIR_RELOAD_CTRL;
}
/* Clear all pending HC Interrupts */ /* Clear all pending HC Interrupts */
for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) { for (uint8_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
USB_OTG_HC(i)->HCINT = 0xFFFFFFFFU; USB_OTG_HC(i)->HCINT = 0xFFFFFFFFU;
USB_OTG_HC(i)->HCINTMSK = 0U; USB_OTG_HC(i)->HCINTMSK = 0U;
} }
@@ -603,9 +680,11 @@ int usb_hc_init(struct usbh_bus *bus)
USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU; USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
/* set Rx FIFO size */ /* set Rx FIFO size */
USB_OTG_GLB->GRXFSIZ = CONFIG_USB_DWC2_RX_FIFO_SIZE; USB_OTG_GLB->GRXFSIZ = g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size;
USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((CONFIG_USB_DWC2_NPTX_FIFO_SIZE << 16) & USB_OTG_NPTXFD) | CONFIG_USB_DWC2_RX_FIFO_SIZE); USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size << 16) & USB_OTG_NPTXFD) |
USB_OTG_GLB->HPTXFSIZ = (uint32_t)(((CONFIG_USB_DWC2_PTX_FIFO_SIZE << 16) & USB_OTG_HPTXFSIZ_PTXFD) | (CONFIG_USB_DWC2_RX_FIFO_SIZE + CONFIG_USB_DWC2_NPTX_FIFO_SIZE)); g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size);
USB_OTG_GLB->HPTXFSIZ = (uint32_t)(((g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_perio_tx_fifo_size << 16) & USB_OTG_HPTXFSIZ_PTXFD) |
(g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size + g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size));
ret = dwc2_flush_txfifo(bus, 0x10U); ret = dwc2_flush_txfifo(bus, 0x10U);
ret = dwc2_flush_rxfifo(bus); ret = dwc2_flush_rxfifo(bus);
@@ -637,7 +716,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
dwc2_flush_rxfifo(bus); dwc2_flush_rxfifo(bus);
/* Flush out any leftover queued requests. */ /* Flush out any leftover queued requests. */
for (uint32_t i = 0U; i <= 15U; i++) { for (uint32_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
value = USB_OTG_HC(i)->HCCHAR; value = USB_OTG_HC(i)->HCCHAR;
value |= USB_OTG_HCCHAR_CHDIS; value |= USB_OTG_HCCHAR_CHDIS;
value &= ~USB_OTG_HCCHAR_CHENA; value &= ~USB_OTG_HCCHAR_CHENA;
@@ -646,7 +725,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
} }
/* Halt all channels to put them into a known state. */ /* Halt all channels to put them into a known state. */
for (uint32_t i = 0U; i <= 15U; i++) { for (uint32_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
value = USB_OTG_HC(i)->HCCHAR; value = USB_OTG_HC(i)->HCCHAR;
value |= USB_OTG_HCCHAR_CHDIS; value |= USB_OTG_HCCHAR_CHDIS;
value |= USB_OTG_HCCHAR_CHENA; value |= USB_OTG_HCCHAR_CHENA;
@@ -670,7 +749,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
dwc2_drivebus(bus, 0); dwc2_drivebus(bus, 0);
usb_osal_msleep(200); usb_osal_msleep(200);
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) { for (uint8_t chidx = 0; chidx < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; chidx++) {
usb_osal_sem_delete(g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem); usb_osal_sem_delete(g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem);
} }
@@ -858,18 +937,18 @@ int usbh_submit_urb(struct usbh_urb *urb)
if (urb->ep->bEndpointAddress & 0x80) { if (urb->ep->bEndpointAddress & 0x80) {
/* Check if pipe rx fifo is overflow */ /* Check if pipe rx fifo is overflow */
if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_RX_FIFO_SIZE * 4)) { if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size * 4)) {
return -USB_ERR_RANGE; return -USB_ERR_RANGE;
} }
} else { } else {
/* Check if intr and iso pipe tx fifo is overflow */ /* Check if intr and iso pipe tx fifo is overflow */
if (((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) || if (((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) ||
(USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT)) && (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT)) &&
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_PTX_FIFO_SIZE * 4)) { USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_perio_tx_fifo_size * 4)) {
return -USB_ERR_RANGE; return -USB_ERR_RANGE;
} else { } else {
/* Check if control and bulk pipe tx fifo is overflow */ /* Check if control and bulk pipe tx fifo is overflow */
if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_NPTX_FIFO_SIZE * 4)) { if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size * 4)) {
return -USB_ERR_RANGE; return -USB_ERR_RANGE;
} }
} }
@@ -1297,7 +1376,7 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
static void dwc2_port_irq_handler(struct usbh_bus *bus) static void dwc2_port_irq_handler(struct usbh_bus *bus)
{ {
__IO uint32_t hprt0, hprt0_dup; __IO uint32_t hprt0, hprt0_dup, regval;
/* Handle Host Port Interrupts */ /* Handle Host Port Interrupts */
hprt0 = USB_OTG_HPRT; hprt0 = USB_OTG_HPRT;
@@ -1322,26 +1401,28 @@ static void dwc2_port_irq_handler(struct usbh_bus *bus)
g_dwc2_hcd[bus->hcd.hcd_id].port_pec = 1; g_dwc2_hcd[bus->hcd.hcd_id].port_pec = 1;
if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) { if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) {
#if defined(CONFIG_USB_HS) regval = USB_OTG_HOST->HFIR;
#else regval &= ~USB_OTG_HFIR_FRIVL;
if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) { regval |= dwc2_calc_frame_interval(bus) & USB_OTG_HFIR_FRIVL;
USB_OTG_HOST->HFIR = 6000U; USB_OTG_HOST->HFIR = regval;
if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_1) {
uint32_t regval = USB_OTG_HOST->HCFG; if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
regval &= ~USB_OTG_HCFG_FSLSPCS; if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) {
regval |= USB_OTG_HCFG_FSLSPCS_1; if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCLKSEL_6_MHZ) {
USB_OTG_HOST->HCFG = regval; regval = USB_OTG_HOST->HCFG;
} regval &= ~USB_OTG_HCFG_FSLSPCS;
} else { regval |= USB_OTG_HCFG_FSLSPCLKSEL_6_MHZ;
USB_OTG_HOST->HFIR = 48000U; USB_OTG_HOST->HCFG = regval;
if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_0) { }
uint32_t regval = USB_OTG_HOST->HCFG; } else {
regval &= ~USB_OTG_HCFG_FSLSPCS; if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ) {
regval |= USB_OTG_HCFG_FSLSPCS_0; regval = USB_OTG_HOST->HCFG;
USB_OTG_HOST->HCFG = regval; regval &= ~USB_OTG_HCFG_FSLSPCS;
regval |= USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ;
USB_OTG_HOST->HCFG = regval;
}
} }
} }
#endif
} else { } else {
} }
} }
@@ -1380,7 +1461,7 @@ void USBH_IRQHandler(uint8_t busid)
} }
if (gint_status & USB_OTG_GINTSTS_HCINT) { if (gint_status & USB_OTG_GINTSTS_HCINT) {
chan_int = (USB_OTG_HOST->HAINT & USB_OTG_HOST->HAINTMSK) & 0xFFFFU; chan_int = (USB_OTG_HOST->HAINT & USB_OTG_HOST->HAINTMSK) & 0xFFFFU;
for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) { for (uint8_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
if ((chan_int & (1UL << (i & 0xFU))) != 0U) { if ((chan_int & (1UL << (i & 0xFU))) != 0U) {
if ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR) { if ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR) {
dwc2_inchan_irq_handler(bus, i); dwc2_inchan_irq_handler(bus, i);