|
@@ -5,6 +5,7 @@
|
|
|
*/
|
|
|
#include "usbd_core.h"
|
|
|
#include "usb_dwc2_reg.h"
|
|
|
+#include "usb_dwc2_param.h"
|
|
|
|
|
|
// clang-format off
|
|
|
#if defined ( __CC_ARM )
|
|
@@ -51,46 +52,6 @@
|
|
|
#endif
|
|
|
// 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 USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE))
|
|
@@ -115,9 +76,11 @@ struct dwc2_ep_state {
|
|
|
/* Driver state */
|
|
|
USB_NOCACHE_RAM_SECTION struct dwc2_udc {
|
|
|
USB_MEM_ALIGNX struct usb_setup_packet setup;
|
|
|
- USB_MEM_ALIGNX uint32_t GSNPSID;
|
|
|
- struct dwc2_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
|
|
|
- struct dwc2_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
|
|
|
+ USB_MEM_ALIGNX uint8_t pad; /* Pad to CONFIG_USB_ALIGN_SIZE bytes */
|
|
|
+ struct dwc2_hw_params hw_params;
|
|
|
+ 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];
|
|
|
|
|
|
static inline int dwc2_reset(uint8_t busid)
|
|
@@ -135,7 +98,7 @@ static inline int dwc2_reset(uint8_t busid)
|
|
|
count = 0U;
|
|
|
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 {
|
|
|
if (++count > 200000U) {
|
|
|
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)
|
|
|
{
|
|
|
int ret;
|
|
|
-#if defined(CONFIG_USB_HS)
|
|
|
- /* Init The ULPI Interface */
|
|
|
- USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
|
|
|
-
|
|
|
- /* Select vbus source */
|
|
|
- USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
|
|
|
+ uint32_t regval;
|
|
|
|
|
|
- /* Reset after a PHY select */
|
|
|
- ret = dwc2_reset(busid);
|
|
|
-#else
|
|
|
- /* Select FS Embedded PHY */
|
|
|
- USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
|
|
|
+ if (g_dwc2_udc[busid].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
|
|
|
+ /* 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 */
|
|
|
ret = dwc2_reset(busid);
|
|
|
-#endif
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
- USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_TOCAL;
|
|
|
-
|
|
|
USB_OTG_GLB->GUSBCFG &= ~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 |= USB_OTG_DOEPTSIZ_STUPCNT;
|
|
|
|
|
|
-#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
|
|
- USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
|
|
|
- /* EP enable */
|
|
|
- USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
|
|
|
-#endif
|
|
|
+ if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
|
|
+ USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
|
|
|
+ /* EP enable */
|
|
|
+ USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
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 ret;
|
|
|
- uint8_t fsphy_type;
|
|
|
- uint8_t hsphy_type;
|
|
|
- uint8_t dma_support;
|
|
|
- uint8_t endpoints;
|
|
|
uint32_t fifo_num;
|
|
|
|
|
|
memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
|
|
|
|
|
|
usb_dc_low_level_init(busid);
|
|
|
|
|
|
- /*
|
|
|
- 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("========== dwc2 dcd params ==========\r\n");
|
|
|
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("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("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);
|
|
|
- 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);
|
|
|
- USB_LOG_INFO("=================================\r\n");
|
|
|
+ dwc2_get_hwparams(USBD_BASE, &g_dwc2_udc[busid].hw_params);
|
|
|
+ dwc2_get_user_params(USBD_BASE, &g_dwc2_udc[busid].user_params);
|
|
|
|
|
|
- USB_ASSERT_MSG(endpoints >= CONFIG_USBDEV_EP_NUM, "dwc2 has less endpoints than config, please check");
|
|
|
-
|
|
|
- g_dwc2_udc[busid].GSNPSID = USB_OTG_GLB->GSNPSID;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
|
|
|
- USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS;
|
|
|
+ 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,
|
|
|
+ g_dwc2_udc[busid].user_params.total_fifo_size);
|
|
|
|
|
|
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
|
|
|
|
|
|
+ USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS;
|
|
|
+
|
|
|
/* 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);
|
|
|
|
|
|
/* Force Device Mode*/
|
|
|
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++) {
|
|
|
USB_OTG_GLB->DIEPTXF[i] = 0U;
|
|
|
}
|
|
@@ -575,15 +542,17 @@ int usb_dc_init(uint8_t busid)
|
|
|
|
|
|
/* Device speed configuration */
|
|
|
USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DSPD;
|
|
|
-#if defined(CONFIG_USB_HS)
|
|
|
- USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH;
|
|
|
-#else
|
|
|
- if (hsphy_type == 0) {
|
|
|
- USB_OTG_DEV->DCFG |= USB_OTG_SPEED_FULL;
|
|
|
+
|
|
|
+ if (g_dwc2_udc[busid].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
|
|
|
+ USB_ASSERT_MSG(g_dwc2_udc[busid].hw_params.hs_phy_type != 0, "This dwc2 version does not support hs, so stop working");
|
|
|
+ USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH;
|
|
|
} 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 */
|
|
|
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_USBSUSPM | USB_OTG_GINTMSK_WUIM;
|
|
|
|
|
|
-#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
|
|
- 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_udc[busid].user_params.device_dma_enable) {
|
|
|
+ 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
|
|
|
USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_SOFM;
|
|
|
#endif
|
|
|
|
|
|
- USB_OTG_GLB->GRXFSIZ = (CONFIG_USB_DWC2_RXALL_FIFO_SIZE);
|
|
|
-
|
|
|
- dwc2_set_txfifo(busid, 0, CONFIG_USB_DWC2_TX0_FIFO_SIZE);
|
|
|
- dwc2_set_txfifo(busid, 1, CONFIG_USB_DWC2_TX1_FIFO_SIZE);
|
|
|
- dwc2_set_txfifo(busid, 2, CONFIG_USB_DWC2_TX2_FIFO_SIZE);
|
|
|
- dwc2_set_txfifo(busid, 3, CONFIG_USB_DWC2_TX3_FIFO_SIZE);
|
|
|
-
|
|
|
- fifo_num = CONFIG_USB_DWC2_RXALL_FIFO_SIZE;
|
|
|
- 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_OTG_GLB->GRXFSIZ = g_dwc2_udc[busid].user_params.device_rx_fifo_size;
|
|
|
|
|
|
- USB_ASSERT_MSG(fifo_num <= (USB_OTG_GLB->GHWCFG3 >> 16), "Your fifo config is overflow, please check");
|
|
|
- /* xxx32 chips do not follow (USB_OTG_GLB->GHWCFG3 >> 16) if hsphy_type is zero, they use 1.25KB(320 DWORD) */
|
|
|
- USB_ASSERT_MSG(!((hsphy_type == 0) && (fifo_num > 320)), "Your fifo config is larger than 320 , please check");
|
|
|
+ fifo_num = g_dwc2_udc[busid].user_params.device_rx_fifo_size;
|
|
|
+ for (uint8_t i = 0; i < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1); i++) {
|
|
|
+ dwc2_set_txfifo(busid, i, g_dwc2_udc[busid].user_params.device_tx_fifo_size[i]);
|
|
|
+ fifo_num += g_dwc2_udc[busid].user_params.device_tx_fifo_size[i];
|
|
|
+
|
|
|
+ USB_ASSERT_MSG(fifo_num <= g_dwc2_udc[busid].user_params.total_fifo_size, "Your fifo config is overflow, please check");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (g_dwc2_udc[busid].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
|
|
|
+ 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");
|
|
|
+ } 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_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);
|
|
|
|
|
|
- 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)) {
|
|
|
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;
|
|
|
}
|
|
|
-#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);
|
|
|
}
|
|
|
-#endif
|
|
|
+
|
|
|
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");
|
|
|
|
|
|
-#ifdef CONFIG_USB_DCACHE_ENABLE
|
|
|
- USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
|
|
|
-#endif
|
|
|
+ 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);
|
|
|
+ }
|
|
|
|
|
|
if (!data && data_len) {
|
|
|
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));
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
|
|
- usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
|
|
|
- USB_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data;
|
|
|
+ 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_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data;
|
|
|
|
|
|
- USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
|
|
-#else
|
|
|
- USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
|
|
- /* Enable the Tx FIFO Empty Interrupt for this EP */
|
|
|
- if (data_len > 0U) {
|
|
|
- USB_OTG_DEV->DIEPEMPMSK |= 1UL << (ep_idx & 0x0f);
|
|
|
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
|
|
+ } else {
|
|
|
+ USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
|
|
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
|
|
|
+ if (data_len > 0U) {
|
|
|
+ USB_OTG_DEV->DIEPEMPMSK |= 1UL << (ep_idx & 0x0f);
|
|
|
+ }
|
|
|
}
|
|
|
-#endif
|
|
|
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");
|
|
|
|
|
|
-#ifdef CONFIG_USB_DCACHE_ENABLE
|
|
|
- USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
|
|
|
-#endif
|
|
|
+ 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);
|
|
|
+ }
|
|
|
|
|
|
if (!data && data_len) {
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
|
|
- USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
|
|
|
-#endif
|
|
|
+ if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
|
|
+ USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
|
|
|
+ }
|
|
|
if (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
|
|
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
|
|
|
USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
|
|
@@ -1025,29 +971,30 @@ void USBD_IRQHandler(uint8_t busid)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-#ifndef CONFIG_USB_DWC2_DMA_ENABLE
|
|
|
- /* Handle RxQLevel Interrupt */
|
|
|
- if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
|
|
|
- USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
|
|
|
+ if (!g_dwc2_udc[busid].user_params.device_dma_enable) {
|
|
|
+ /* Handle RxQLevel Interrupt */
|
|
|
+ if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
|
|
|
+ USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
|
|
|
|
|
|
- temp = USB_OTG_GLB->GRXSTSP;
|
|
|
- ep_idx = temp & USB_OTG_GRXSTSP_EPNUM;
|
|
|
+ temp = USB_OTG_GLB->GRXSTSP;
|
|
|
+ ep_idx = temp & USB_OTG_GRXSTSP_EPNUM;
|
|
|
|
|
|
- if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
|
|
|
- read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
|
|
|
- if (read_count != 0) {
|
|
|
- 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;
|
|
|
+ if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
|
|
|
+ read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
|
|
|
+ if (read_count != 0) {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ } 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) {
|
|
|
- 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);
|
|
|
}
|
|
|
- USB_UNMASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
|
|
|
}
|
|
|
-#endif
|
|
|
+
|
|
|
if (gint_status & USB_OTG_GINTSTS_OEPINT) {
|
|
|
ep_idx = 0;
|
|
|
ep_intr = dwc2_get_outeps_intstatus(busid);
|
|
@@ -1057,25 +1004,44 @@ void USBD_IRQHandler(uint8_t busid)
|
|
|
|
|
|
if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) {
|
|
|
if (ep_idx == 0) {
|
|
|
+ if (usbd_get_ep0_next_state(busid) == USBD_EP0_STATE_SETUP) {
|
|
|
+ goto process_setup; // goto ep0 setup, xfer_len is not used
|
|
|
+ }
|
|
|
+
|
|
|
if (g_dwc2_udc[busid].out_ep[ep_idx].xfer_len == 0) {
|
|
|
- /* Out status, start reading setup */
|
|
|
- dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
|
|
+ /* If ep0 xfer_len is 0, it means that we are in outstatus phase */
|
|
|
+ g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
|
|
|
} else {
|
|
|
+ /* If ep0 xfer_len is not 0, it means that we are in outdata phase */
|
|
|
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
|
|
|
- g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
|
|
|
+ if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
|
|
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
|
|
|
- usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
|
|
|
+ }
|
|
|
+ usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
|
|
|
+
|
|
|
+ if (usbd_get_ep0_next_state(busid) == USBD_EP0_STATE_SETUP) {
|
|
|
+ /* Out status, start reading setup */
|
|
|
+ dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
|
|
}
|
|
|
} else {
|
|
|
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
|
|
|
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
|
|
|
- usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
|
|
|
+ if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
|
|
+ usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
|
|
|
+ }
|
|
|
usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ // clang-format off
|
|
|
+process_setup:
|
|
|
+ // clang-format on
|
|
|
if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) {
|
|
|
- usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE));
|
|
|
+ if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
|
|
+ usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE));
|
|
|
+ }
|
|
|
usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
|
|
}
|
|
|
}
|
|
@@ -1096,10 +1062,7 @@ void USBD_IRQHandler(uint8_t busid)
|
|
|
g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = 0;
|
|
|
usbd_event_ep_in_complete_handler(busid, 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len);
|
|
|
|
|
|
- if (g_dwc2_udc[busid].setup.wLength && ((g_dwc2_udc[busid].setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
|
|
|
- /* In status, start reading setup */
|
|
|
- dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
|
|
- } else if (g_dwc2_udc[busid].setup.wLength == 0) {
|
|
|
+ if (usbd_get_ep0_next_state(busid) == USBD_EP0_STATE_SETUP) {
|
|
|
/* In status, start reading setup */
|
|
|
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|
|
|
}
|
|
@@ -1109,8 +1072,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);
|
|
|
}
|
|
|
}
|
|
|
- if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) {
|
|
|
- dwc2_tx_fifo_empty_procecss(busid, ep_idx);
|
|
|
+ if (!g_dwc2_udc[busid].user_params.device_dma_enable) {
|
|
|
+ if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) {
|
|
|
+ dwc2_tx_fifo_empty_procecss(busid, ep_idx);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
ep_intr >>= 1U;
|
|
@@ -1124,7 +1089,7 @@ void USBD_IRQHandler(uint8_t busid)
|
|
|
dwc2_flush_txfifo(busid, 0x10U);
|
|
|
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) {
|
|
|
USB_OTG_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
|
|
|
USB_OTG_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
|
|
@@ -1153,7 +1118,8 @@ void USBD_IRQHandler(uint8_t busid)
|
|
|
|
|
|
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);
|
|
|
/* Start reading setup */
|
|
|
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
|