refactor(port/dwc2): support custom config for each dwc2 usb port
Signed-off-by: sakumisu <1203593632@qq.com>
This commit is contained in:
@@ -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 */
|
||||
uint8_t pad[24]; /* Pad to 32 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);
|
||||
uint32_t regval;
|
||||
|
||||
/* Select vbus source */
|
||||
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
|
||||
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);
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
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_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);
|
||||
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);
|
||||
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 = 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];
|
||||
|
||||
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_ASSERT_MSG(fifo_num <= g_dwc2_udc[busid].user_params.total_fifo_size, "Your fifo config is overflow, please check");
|
||||
}
|
||||
|
||||
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");
|
||||
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);
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
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 +1073,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 +1102,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);
|
||||
|
||||
Reference in New Issue
Block a user