update(port/dwc2/usb_dc_dwc2): add busid for functions to support multi ip

This commit is contained in:
sakumisu
2024-08-22 20:16:40 +08:00
parent 35da8d6747
commit e8b22163bb
5 changed files with 125 additions and 133 deletions

View File

@@ -1,5 +1,7 @@
# Note
If you are using more than one port, all ip parameters must be the same(like fifo num, endpoint num, dma support and so on), otherwise give up using multi ports.
## Support Chip List
## STM32

View File

@@ -93,7 +93,7 @@
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
#endif
#define USBD_BASE (g_usbdev_bus[0].reg_base)
#define USBD_BASE (g_usbdev_bus[busid].reg_base)
#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE))
#define USB_OTG_DEV ((DWC2_DeviceTypeDef *)(USBD_BASE + USB_OTG_DEVICE_BASE))
@@ -119,9 +119,9 @@ USB_NOCACHE_RAM_SECTION struct dwc2_udc {
__attribute__((aligned(32))) struct usb_setup_packet setup;
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 */
} g_dwc2_udc;
} g_dwc2_udc[CONFIG_USBHOST_MAX_BUS];
static inline int dwc2_reset(void)
static inline int dwc2_reset(uint8_t busid)
{
volatile uint32_t count = 0U;
@@ -145,7 +145,7 @@ static inline int dwc2_reset(void)
return 0;
}
static inline int dwc2_core_init(void)
static inline int dwc2_core_init(uint8_t busid)
{
int ret;
#if defined(CONFIG_USB_HS)
@@ -156,18 +156,18 @@ static inline int dwc2_core_init(void)
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* Reset after a PHY select */
ret = dwc2_reset();
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();
ret = dwc2_reset(busid);
#endif
return ret;
}
static inline void dwc2_set_mode(uint8_t mode)
static inline void dwc2_set_mode(uint8_t busid, uint8_t mode)
{
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
@@ -180,7 +180,7 @@ static inline void dwc2_set_mode(uint8_t mode)
usbd_dwc2_delay_ms(50);
}
static inline int dwc2_flush_rxfifo(void)
static inline int dwc2_flush_rxfifo(uint8_t busid)
{
volatile uint32_t count = 0U;
@@ -203,7 +203,7 @@ static inline int dwc2_flush_rxfifo(void)
return 0;
}
static inline int dwc2_flush_txfifo(uint32_t num)
static inline int dwc2_flush_txfifo(uint8_t busid, uint32_t num)
{
volatile uint32_t count = 0U;
@@ -226,7 +226,7 @@ static inline int dwc2_flush_txfifo(uint32_t num)
return 0;
}
static void dwc2_set_turnaroundtime(uint32_t hclk, uint8_t speed)
static void dwc2_set_turnaroundtime(uint8_t busid, uint32_t hclk, uint8_t speed)
{
uint32_t UsbTrd;
@@ -279,7 +279,7 @@ static void dwc2_set_turnaroundtime(uint32_t hclk, uint8_t speed)
USB_OTG_GLB->GUSBCFG |= (uint32_t)((UsbTrd << USB_OTG_GUSBCFG_TRDT_Pos) & USB_OTG_GUSBCFG_TRDT);
}
static void dwc2_set_txfifo(uint8_t fifo, uint16_t size)
static void dwc2_set_txfifo(uint8_t busid, uint8_t fifo, uint16_t size)
{
uint8_t i;
uint32_t tx_offset;
@@ -311,7 +311,7 @@ static void dwc2_set_txfifo(uint8_t fifo, uint16_t size)
USB_LOG_INFO("fifo%d size:%04x, offset:%04x\r\n", fifo, size, tx_offset);
}
static uint8_t dwc2_get_devspeed(void)
static uint8_t dwc2_get_devspeed(uint8_t busid)
{
uint8_t speed;
uint32_t DevEnumSpeed = USB_OTG_DEV->DSTS & USB_OTG_DSTS_ENUMSPD;
@@ -328,7 +328,7 @@ static uint8_t dwc2_get_devspeed(void)
return speed;
}
static void dwc2_ep0_start_read_setup(uint8_t *psetup)
static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup)
{
USB_OTG_OUTEP(0U)->DOEPTSIZ = 0U;
USB_OTG_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
@@ -342,7 +342,7 @@ static void dwc2_ep0_start_read_setup(uint8_t *psetup)
#endif
}
void dwc2_ep_write(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)
{
uint32_t *pSrc = (uint32_t *)src;
uint32_t count32b, i;
@@ -354,7 +354,7 @@ void dwc2_ep_write(uint8_t ep_idx, uint8_t *src, uint16_t len)
}
}
void dwc2_ep_read(uint8_t *dest, uint16_t len)
void dwc2_ep_read(uint8_t busid, uint8_t *dest, uint16_t len)
{
uint32_t *pDest = (uint32_t *)dest;
uint32_t i;
@@ -366,33 +366,33 @@ void dwc2_ep_read(uint8_t *dest, uint16_t len)
}
}
static void dwc2_tx_fifo_empty_procecss(uint8_t ep_idx)
static void dwc2_tx_fifo_empty_procecss(uint8_t busid, uint8_t ep_idx)
{
uint32_t len;
uint32_t len32b;
uint32_t fifoemptymsk;
len = g_dwc2_udc.in_ep[ep_idx].xfer_len - g_dwc2_udc.in_ep[ep_idx].actual_xfer_len;
if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps) {
len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len;
if (len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) {
len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps;
}
len32b = (len + 3U) / 4U;
while (((USB_OTG_INEP(ep_idx)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
(g_dwc2_udc.in_ep[ep_idx].actual_xfer_len < g_dwc2_udc.in_ep[ep_idx].xfer_len) && (g_dwc2_udc.in_ep[ep_idx].xfer_len != 0U)) {
(g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len < g_dwc2_udc[busid].in_ep[ep_idx].xfer_len) && (g_dwc2_udc[busid].in_ep[ep_idx].xfer_len != 0U)) {
/* Write the FIFO */
len = g_dwc2_udc.in_ep[ep_idx].xfer_len - g_dwc2_udc.in_ep[ep_idx].actual_xfer_len;
if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps) {
len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len;
if (len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) {
len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps;
}
dwc2_ep_write(ep_idx, g_dwc2_udc.in_ep[ep_idx].xfer_buf, len);
g_dwc2_udc.in_ep[ep_idx].xfer_buf += len;
g_dwc2_udc.in_ep[ep_idx].actual_xfer_len += len;
dwc2_ep_write(busid, ep_idx, g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf, len);
g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf += len;
g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len += len;
}
if (g_dwc2_udc.in_ep[ep_idx].xfer_len <= g_dwc2_udc.in_ep[ep_idx].actual_xfer_len) {
if (g_dwc2_udc[busid].in_ep[ep_idx].xfer_len <= g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len) {
fifoemptymsk = (uint32_t)(0x1UL << (ep_idx & 0x0f));
USB_OTG_DEV->DIEPEMPMSK &= ~fifoemptymsk;
}
@@ -402,7 +402,7 @@ static void dwc2_tx_fifo_empty_procecss(uint8_t ep_idx)
* @brief dwc2_get_glb_intstatus: return the global USB interrupt status
* @retval status
*/
static inline uint32_t dwc2_get_glb_intstatus(void)
static inline uint32_t dwc2_get_glb_intstatus(uint8_t busid)
{
uint32_t tmpreg;
@@ -416,7 +416,7 @@ static inline uint32_t dwc2_get_glb_intstatus(void)
* @brief dwc2_get_outeps_intstatus: return the USB device OUT endpoints interrupt status
* @retval status
*/
static inline uint32_t dwc2_get_outeps_intstatus(void)
static inline uint32_t dwc2_get_outeps_intstatus(uint8_t busid)
{
uint32_t tmpreg;
@@ -430,7 +430,7 @@ static inline uint32_t dwc2_get_outeps_intstatus(void)
* @brief dwc2_get_ineps_intstatus: return the USB device IN endpoints interrupt status
* @retval status
*/
static inline uint32_t dwc2_get_ineps_intstatus(void)
static inline uint32_t dwc2_get_ineps_intstatus(uint8_t busid)
{
uint32_t tmpreg;
@@ -446,7 +446,7 @@ static inline uint32_t dwc2_get_ineps_intstatus(void)
* This parameter can be a value from 0 to 15
* @retval Device OUT EP Interrupt register
*/
static inline uint32_t dwc2_get_outep_intstatus(uint8_t epnum)
static inline uint32_t dwc2_get_outep_intstatus(uint8_t busid, uint8_t epnum)
{
uint32_t tmpreg;
@@ -463,7 +463,7 @@ static inline uint32_t dwc2_get_outep_intstatus(uint8_t epnum)
* This parameter can be a value from 0 to 15
* @retval Device IN EP Interrupt register
*/
static inline uint32_t dwc2_get_inep_intstatus(uint8_t epnum)
static inline uint32_t dwc2_get_inep_intstatus(uint8_t busid, uint8_t epnum)
{
uint32_t tmpreg, msk, emp;
@@ -478,14 +478,6 @@ static inline uint32_t dwc2_get_inep_intstatus(uint8_t epnum)
return tmpreg;
}
__WEAK void usb_dc_low_level_init(void)
{
}
__WEAK void usb_dc_low_level_deinit(void)
{
}
int usb_dc_init(uint8_t busid)
{
int ret;
@@ -495,9 +487,9 @@ int usb_dc_init(uint8_t busid)
uint8_t endpoints;
uint32_t fifo_num;
memset(&g_dwc2_udc, 0, sizeof(struct dwc2_udc));
memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
usb_dc_low_level_init();
usb_dc_low_level_init(busid);
/*
Full-Speed PHY Interface Type (FSPhyType)
@@ -548,14 +540,10 @@ int usb_dc_init(uint8_t busid)
/* This is vendor register */
USB_OTG_GLB->GCCFG = usbd_get_dwc2_gccfg_conf(USBD_BASE);
ret = dwc2_core_init();
ret = dwc2_core_init(busid);
/* Force Device Mode*/
dwc2_set_mode(USB_OTG_MODE_DEVICE);
/* B-peripheral session valid override enable */
// USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
// USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
dwc2_set_mode(busid, USB_OTG_MODE_DEVICE);
for (uint8_t i = 0U; i < 15U; i++) {
USB_OTG_GLB->DIEPTXF[i] = 0U;
@@ -613,10 +601,10 @@ int usb_dc_init(uint8_t busid)
USB_OTG_GLB->GRXFSIZ = (CONFIG_USB_DWC2_RXALL_FIFO_SIZE);
dwc2_set_txfifo(0, CONFIG_USB_DWC2_TX0_FIFO_SIZE);
dwc2_set_txfifo(1, CONFIG_USB_DWC2_TX1_FIFO_SIZE);
dwc2_set_txfifo(2, CONFIG_USB_DWC2_TX2_FIFO_SIZE);
dwc2_set_txfifo(3, CONFIG_USB_DWC2_TX3_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;
@@ -624,23 +612,23 @@ int usb_dc_init(uint8_t busid)
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(4, CONFIG_USB_DWC2_TX4_FIFO_SIZE);
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(5, CONFIG_USB_DWC2_TX5_FIFO_SIZE);
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(6, CONFIG_USB_DWC2_TX6_FIFO_SIZE);
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(7, CONFIG_USB_DWC2_TX7_FIFO_SIZE);
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(8, CONFIG_USB_DWC2_TX8_FIFO_SIZE);
dwc2_set_txfifo(busid, 8, CONFIG_USB_DWC2_TX8_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX8_FIFO_SIZE;
#endif
@@ -657,8 +645,8 @@ int usb_dc_init(uint8_t busid)
}
}
ret = dwc2_flush_txfifo(0x10U);
ret = dwc2_flush_rxfifo();
ret = dwc2_flush_txfifo(busid, 0x10U);
ret = dwc2_flush_rxfifo(busid);
USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_SDIS;
@@ -683,10 +671,10 @@ int usb_dc_deinit(uint8_t busid)
USB_OTG_DEV->DAINTMSK = 0U;
/* Flush the FIFO */
dwc2_flush_txfifo(0x10U);
dwc2_flush_rxfifo();
dwc2_flush_txfifo(busid, 0x10U);
dwc2_flush_rxfifo(busid);
usb_dc_low_level_deinit();
usb_dc_low_level_deinit(busid);
return 0;
}
@@ -735,8 +723,8 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
}
if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
g_dwc2_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
g_dwc2_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
g_dwc2_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx));
@@ -758,8 +746,8 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
return -2;
}
g_dwc2_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
g_dwc2_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
g_dwc2_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
g_dwc2_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx);
@@ -769,7 +757,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
USB_OTG_DIEPCTL_USBAEP;
}
dwc2_flush_txfifo(ep_idx);
dwc2_flush_txfifo(busid, ep_idx);
}
return 0;
}
@@ -840,7 +828,7 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
}
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
if (ep_idx == 0) {
dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
#endif
return 0;
@@ -852,14 +840,14 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
if (USB_EP_DIR_IS_OUT(ep)) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
if ((g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
(g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
if ((g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
(g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
}
} else {
USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
if ((g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
(g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
if ((g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
(g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
}
}
@@ -906,9 +894,9 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
return -4;
}
g_dwc2_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
g_dwc2_udc.in_ep[ep_idx].xfer_len = data_len;
g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = 0;
g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data;
g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = data_len;
g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
@@ -920,20 +908,20 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
}
if (ep_idx == 0) {
if (data_len > g_dwc2_udc.in_ep[ep_idx].ep_mps) {
data_len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
if (data_len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) {
data_len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps;
}
g_dwc2_udc.in_ep[ep_idx].xfer_len = data_len;
g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = data_len;
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len);
} else {
pktcnt = (uint16_t)((data_len + g_dwc2_udc.in_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.in_ep[ep_idx].ep_mps);
pktcnt = (uint16_t)((data_len + g_dwc2_udc[busid].in_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc[busid].in_ep[ep_idx].ep_mps);
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len);
}
if (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
if (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
@@ -979,28 +967,28 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
return -4;
}
g_dwc2_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
g_dwc2_udc.out_ep[ep_idx].xfer_len = data_len;
g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = 0;
g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data;
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = data_len;
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
if (data_len == 0) {
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc.out_ep[ep_idx].ep_mps);
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc[busid].out_ep[ep_idx].ep_mps);
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
return 0;
}
if (ep_idx == 0) {
if (data_len > g_dwc2_udc.out_ep[ep_idx].ep_mps) {
data_len = g_dwc2_udc.out_ep[ep_idx].ep_mps;
if (data_len > g_dwc2_udc[busid].out_ep[ep_idx].ep_mps) {
data_len = g_dwc2_udc[busid].out_ep[ep_idx].ep_mps;
}
g_dwc2_udc.out_ep[ep_idx].xfer_len = data_len;
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = data_len;
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len);
} else {
pktcnt = (uint16_t)((data_len + g_dwc2_udc.out_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.out_ep[ep_idx].ep_mps);
pktcnt = (uint16_t)((data_len + g_dwc2_udc[busid].out_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc[busid].out_ep[ep_idx].ep_mps);
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len);
@@ -1009,7 +997,7 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
#endif
if (g_dwc2_udc.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) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
@@ -1025,7 +1013,7 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
void USBD_IRQHandler(uint8_t busid)
{
uint32_t gint_status, temp, ep_idx, ep_intr, epint, read_count, daintmask;
gint_status = dwc2_get_glb_intstatus();
gint_status = dwc2_get_glb_intstatus(busid);
if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_DEVICE) {
/* Avoid spurious interrupt */
@@ -1044,12 +1032,12 @@ void USBD_IRQHandler(uint8_t busid)
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(g_dwc2_udc.out_ep[ep_idx].xfer_buf, read_count);
g_dwc2_udc.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;
}
} 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((uint8_t *)&g_dwc2_udc.setup, read_count);
dwc2_ep_read(busid, (uint8_t *)&g_dwc2_udc[busid].setup, read_count);
} else {
/* ... */
}
@@ -1058,30 +1046,30 @@ void USBD_IRQHandler(uint8_t busid)
#endif
if (gint_status & USB_OTG_GINTSTS_OEPINT) {
ep_idx = 0;
ep_intr = dwc2_get_outeps_intstatus();
ep_intr = dwc2_get_outeps_intstatus(busid);
while (ep_intr != 0U) {
if ((ep_intr & 0x1U) != 0U) {
epint = dwc2_get_outep_intstatus(ep_idx);
epint = dwc2_get_outep_intstatus(busid, ep_idx);
if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) {
if (ep_idx == 0) {
if (g_dwc2_udc.out_ep[ep_idx].xfer_len == 0) {
if (g_dwc2_udc[busid].out_ep[ep_idx].xfer_len == 0) {
/* Out status, start reading setup */
dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
} else {
g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = g_dwc2_udc.out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
g_dwc2_udc.out_ep[ep_idx].xfer_len = 0;
usbd_event_ep_out_complete_handler(0, 0x00, g_dwc2_udc.out_ep[ep_idx].actual_xfer_len);
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;
usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
}
} else {
g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = g_dwc2_udc.out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
g_dwc2_udc.out_ep[ep_idx].xfer_len = 0;
usbd_event_ep_out_complete_handler(0, ep_idx, g_dwc2_udc.out_ep[ep_idx].actual_xfer_len);
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;
usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
}
}
if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) {
usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_dwc2_udc.setup);
usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
}
ep_intr >>= 1U;
@@ -1090,32 +1078,32 @@ void USBD_IRQHandler(uint8_t busid)
}
if (gint_status & USB_OTG_GINTSTS_IEPINT) {
ep_idx = 0U;
ep_intr = dwc2_get_ineps_intstatus();
ep_intr = dwc2_get_ineps_intstatus(busid);
while (ep_intr != 0U) {
if ((ep_intr & 0x1U) != 0U) {
epint = dwc2_get_inep_intstatus(ep_idx);
epint = dwc2_get_inep_intstatus(busid, ep_idx);
if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) {
if (ep_idx == 0) {
g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = g_dwc2_udc.in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
g_dwc2_udc.in_ep[ep_idx].xfer_len = 0;
usbd_event_ep_in_complete_handler(0, 0x80, g_dwc2_udc.in_ep[ep_idx].actual_xfer_len);
g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
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.setup.wLength && ((g_dwc2_udc.setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
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((uint8_t *)&g_dwc2_udc.setup);
} else if (g_dwc2_udc.setup.wLength == 0) {
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
} else if (g_dwc2_udc[busid].setup.wLength == 0) {
/* In status, start reading setup */
dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
} else {
g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = g_dwc2_udc.in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
g_dwc2_udc.in_ep[ep_idx].xfer_len = 0;
usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_dwc2_udc.in_ep[ep_idx].actual_xfer_len);
g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ);
g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = 0;
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(ep_idx);
dwc2_tx_fifo_empty_procecss(busid, ep_idx);
}
}
ep_intr >>= 1U;
@@ -1126,8 +1114,8 @@ void USBD_IRQHandler(uint8_t busid)
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBRST;
USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_RWUSIG;
dwc2_flush_txfifo(0x10U);
dwc2_flush_rxfifo();
dwc2_flush_txfifo(busid, 0x10U);
dwc2_flush_rxfifo(busid);
for (uint8_t i = 0U; i < CONFIG_USBDEV_EP_NUM; i++) {
if (i == 0U) {
@@ -1158,14 +1146,14 @@ void USBD_IRQHandler(uint8_t busid)
USB_OTG_DEV->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
memset(&g_dwc2_udc, 0, sizeof(struct dwc2_udc));
usbd_event_reset_handler(0);
memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
usbd_event_reset_handler(busid);
/* Start reading setup */
dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup);
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
if (gint_status & USB_OTG_GINTSTS_ENUMDNE) {
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_ENUMDNE;
dwc2_set_turnaroundtime(SystemCoreClock, dwc2_get_devspeed());
dwc2_set_turnaroundtime(busid, SystemCoreClock, dwc2_get_devspeed(busid));
USB_OTG_DEV->DCTL |= USB_OTG_DCTL_CGINAK;
}
@@ -1174,7 +1162,7 @@ void USBD_IRQHandler(uint8_t busid)
daintmask >>= 16;
for (ep_idx = 1; ep_idx < CONFIG_USBDEV_EP_NUM; ep_idx++) {
if ((BIT(ep_idx) & ~daintmask) || (g_dwc2_udc.out_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
if ((BIT(ep_idx) & ~daintmask) || (g_dwc2_udc[busid].out_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
continue;
if (!(USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_USBAEP))
continue;
@@ -1196,7 +1184,7 @@ void USBD_IRQHandler(uint8_t busid)
daintmask >>= 16;
for (ep_idx = 1; ep_idx < CONFIG_USBDEV_EP_NUM; ep_idx++) {
if (((BIT(ep_idx) & ~daintmask)) || (g_dwc2_udc.in_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
if (((BIT(ep_idx) & ~daintmask)) || (g_dwc2_udc[busid].in_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
continue;
if (!(USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP))
@@ -1218,11 +1206,11 @@ void USBD_IRQHandler(uint8_t busid)
}
if (gint_status & USB_OTG_GINTSTS_USBSUSP) {
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBSUSP;
usbd_event_suspend_handler(0);
usbd_event_suspend_handler(busid);
}
if (gint_status & USB_OTG_GINTSTS_WKUINT) {
USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_WKUINT;
usbd_event_resume_handler(0);
usbd_event_resume_handler(busid);
}
if (gint_status & USB_OTG_GINTSTS_OTGINT) {
temp = USB_OTG_GLB->GOTGINT;

View File

@@ -1716,6 +1716,8 @@ typedef struct
#define USB_UNMASK_HALT_HC_INT(chnum) (USB_OTG_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM)
#define CLEAR_HC_INT(chnum, __INTERRUPT__) (USB_OTG_HC(chnum)->HCINT = (__INTERRUPT__))
void usb_dc_low_level_init(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);

View File

@@ -35,7 +35,7 @@ static void usb_dc_interrupt_cb(void *arg_pv)
USBD_IRQHandler(0);
}
void usb_dc_low_level_init(void)
void usb_dc_low_level_init(uint8_t busid)
{
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
@@ -58,7 +58,7 @@ void usb_dc_low_level_init(void)
USB_LOG_INFO("cherryusb, version: "CHERRYUSB_VERSION_STR"\r\n");
}
void usb_dc_low_level_deinit(void)
void usb_dc_low_level_deinit(uint8_t busid)
{
if (s_interrupt_handle) {
esp_intr_free(s_interrupt_handle);

View File

@@ -113,7 +113,7 @@ static void usb_dc_interrupt_cb(int irq, void *arg_pv)
}
#ifdef CHERRYUSB_DEVICE_USING_USB0
void usb_dc_low_level_init(void)
void usb_dc_low_level_init(uint8_t busid)
{
sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28);
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000);
@@ -124,12 +124,12 @@ void usb_dc_low_level_init(void)
rt_hw_interrupt_umask(173);
}
void usb_dc_low_level_deinit(void)
void usb_dc_low_level_deinit(uint8_t busid)
{
rt_hw_interrupt_mask(173);
}
#else
void usb_dc_low_level_init(void)
void usb_dc_low_level_init(uint8_t busid)
{
sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29);
uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000);
@@ -140,7 +140,7 @@ void usb_dc_low_level_init(void)
rt_hw_interrupt_umask(174);
}
void usb_dc_low_level_deinit(void)
void usb_dc_low_level_deinit(uint8_t busid)
{
rt_hw_interrupt_mask(174);
}