diff options
| author | sakumisu <[email protected]> | 2022-06-16 22:17:38 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2022-06-16 22:17:38 +0800 |
| commit | e2d8752f069ea9d794da5561bcd966eed7a65a58 (patch) | |
| tree | a447b804440f4eb4b3eb3147680184e894137f65 | |
| parent | 7c4809412b352af7bb35ab3b4471f5467019be83 (diff) | |
update dwc2 hcd driver
| -rw-r--r-- | SConscript | 1 | ||||
| -rw-r--r-- | demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx | 63 | ||||
| -rw-r--r-- | demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx | 2 | ||||
| -rw-r--r-- | port/dwc2/usb_hc_dwc2.c | 156 |
4 files changed, 134 insertions, 88 deletions
@@ -93,6 +93,7 @@ if GetDepend(['PKG_CHERRYUSB_HOST']): if GetDepend(['PKG_CHERRYUSB_HOST_DWC2']): src += Glob('port/synopsys/usb_hc_dwc2.c') + CPPDEFINES += ['CONFIG_USBHOST_HIGH_WORKQ'] if GetDepend(['PKG_CHERRYUSB_HOST_MUSB']): src += Glob('port/musb/usb_hc_musb.c') if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_SUNXI']): diff --git a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx index c04c248c..ef00e507 100644 --- a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx +++ b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx @@ -159,7 +159,7 @@ <Type>0</Type> <LineNumber>347</LineNumber> <EnabledFlag>1</EnabledFlag> - <Address>134246062</Address> + <Address>134246552</Address> <ByteObject>0</ByteObject> <HtxType>0</HtxType> <ManyObjects>0</ManyObjects> @@ -173,39 +173,71 @@ <Bp> <Number>1</Number> <Type>0</Type> - <LineNumber>352</LineNumber> + <LineNumber>819</LineNumber> <EnabledFlag>1</EnabledFlag> - <Address>134246088</Address> + <Address>0</Address> <ByteObject>0</ByteObject> <HtxType>0</HtxType> <ManyObjects>0</ManyObjects> <SizeOfObject>0</SizeOfObject> <BreakByAccess>0</BreakByAccess> - <BreakIfRCount>1</BreakIfRCount> - <Filename>..\..\..\..\..\class\msc\usbh_msc.c</Filename> + <BreakIfRCount>0</BreakIfRCount> + <Filename>..\..\..\..\..\core\usbh_core.c</Filename> <ExecCommand></ExecCommand> - <Expression>\\stm32f429igt6\../../../../../class/msc/usbh_msc.c\352</Expression> + <Expression></Expression> </Bp> <Bp> <Number>2</Number> <Type>0</Type> - <LineNumber>561</LineNumber> + <LineNumber>1027</LineNumber> <EnabledFlag>1</EnabledFlag> - <Address>134230510</Address> + <Address>0</Address> <ByteObject>0</ByteObject> <HtxType>0</HtxType> <ManyObjects>0</ManyObjects> <SizeOfObject>0</SizeOfObject> <BreakByAccess>0</BreakByAccess> - <BreakIfRCount>1</BreakIfRCount> + <BreakIfRCount>0</BreakIfRCount> <Filename>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</Filename> <ExecCommand></ExecCommand> - <Expression>\\stm32f429igt6\../../../../../port/dwc2/usb_hc_dwc2.c\561</Expression> + <Expression></Expression> </Bp> <Bp> <Number>3</Number> <Type>0</Type> - <LineNumber>557</LineNumber> + <LineNumber>1030</LineNumber> + <EnabledFlag>1</EnabledFlag> + <Address>0</Address> + <ByteObject>0</ByteObject> + <HtxType>0</HtxType> + <ManyObjects>0</ManyObjects> + <SizeOfObject>0</SizeOfObject> + <BreakByAccess>0</BreakByAccess> + <BreakIfRCount>0</BreakIfRCount> + <Filename>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</Filename> + <ExecCommand></ExecCommand> + <Expression></Expression> + </Bp> + <Bp> + <Number>4</Number> + <Type>0</Type> + <LineNumber>1309</LineNumber> + <EnabledFlag>1</EnabledFlag> + <Address>0</Address> + <ByteObject>0</ByteObject> + <HtxType>0</HtxType> + <ManyObjects>0</ManyObjects> + <SizeOfObject>0</SizeOfObject> + <BreakByAccess>0</BreakByAccess> + <BreakIfRCount>0</BreakIfRCount> + <Filename>..\..\..\..\..\port\dwc2\usb_hc_dwc2.c</Filename> + <ExecCommand></ExecCommand> + <Expression></Expression> + </Bp> + <Bp> + <Number>5</Number> + <Type>0</Type> + <LineNumber>1314</LineNumber> <EnabledFlag>1</EnabledFlag> <Address>0</Address> <ByteObject>0</ByteObject> @@ -235,6 +267,11 @@ <WinNumber>1</WinNumber> <ItemText>msc_class</ItemText> </Ww> + <Ww> + <count>3</count> + <WinNumber>1</WinNumber> + <ItemText>connport</ItemText> + </Ww> </WatchWindow1> <Tracepoint> <THDelay>0</THDelay> @@ -378,7 +415,7 @@ <Group> <GroupName>Drivers/STM32F4xx_HAL_Driver</GroupName> - <tvExp>0</tvExp> + <tvExp>1</tvExp> <tvExpOptDlg>0</tvExpOptDlg> <cbSel>0</cbSel> <RteFlg>0</RteFlg> @@ -726,7 +763,7 @@ <Group> <GroupName>CherryUSB</GroupName> - <tvExp>0</tvExp> + <tvExp>1</tvExp> <tvExpOptDlg>0</tvExpOptDlg> <cbSel>0</cbSel> <RteFlg>0</RteFlg> diff --git a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx index e553b38a..872fcc6f 100644 --- a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx +++ b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx @@ -338,7 +338,7 @@ <v6Rtti>0</v6Rtti> <VariousControls> <MiscControls></MiscControls> - <Define>USE_HAL_DRIVER,STM32F429xx</Define> + <Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USBHOST_HIGH_WORKQ</Define> <Undefine></Undefine> <IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\common;..\..\..\..\..\core;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hub;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\osal;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F;..\..\..\..\..\third_party\fatfs-0.14\source</IncludePath> </VariousControls> diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c index 7e255b67..a3a4c62e 100644 --- a/port/dwc2/usb_hc_dwc2.c +++ b/port/dwc2/usb_hc_dwc2.c @@ -1,6 +1,10 @@ #include "usbh_core.h" #include "usb_dwc2_reg.h" +#ifndef CONFIG_USBHOST_HIGH_WORKQ +#error "dwc2 host must use high workq" +#endif + #ifndef USBH_IRQHandler #define USBH_IRQHandler OTG_HS_IRQHandler #endif @@ -33,9 +37,10 @@ struct dwc2_pipe { uint8_t speed; uint8_t dev_addr; uint8_t data_pid; + uint8_t chidx; bool inuse; /* True: This channel is "in use" */ - uint8_t interval; /* Interrupt/isochronous EP polling interval */ - uint16_t num_packets; /* for HCTSIZx*/ + uint8_t ep_interval; /* Interrupt/isochronous EP polling interval */ + uint16_t num_packets; /* for HCTSIZx*/ uint32_t xferlen; /* for HCTSIZx*/ volatile int result; /* The result of the transfer */ volatile uint32_t xfrd; /* Bytes transferred (at end of transfer) */ @@ -82,17 +87,25 @@ static inline int dwc2_core_init(void) { int ret; #if defined(CONFIG_USB_DWC2_ULPI_PHY) + USB_OTG_GLB->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); + /* 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); + //USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD; + /* Reset after a PHY select */ + ret = dwc2_reset(); #else /* Select FS Embedded PHY */ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; -#endif /* Reset after a PHY select */ ret = dwc2_reset(); /* Activate the USB Transceiver */ USB_OTG_GLB->GCCFG |= USB_OTG_GCCFG_PWRDWN; - +#endif return ret; } @@ -175,9 +188,9 @@ static void dwc2_pipe_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uin switch (ep_type) { case USB_ENDPOINT_TYPE_CONTROL: case USB_ENDPOINT_TYPE_BULK: - if ((ep_addr & 0x80U) == 0x00U) { - regval |= USB_OTG_HCINTMSK_NYET; - } + // if ((ep_addr & 0x80U) == 0x00U) { + // regval |= USB_OTG_HCINTMSK_NYET; + // } break; case USB_ENDPOINT_TYPE_INTERRUPT: regval |= USB_OTG_HCINTMSK_FRMORM | USB_OTG_HCINTMSK_NAKM; @@ -333,6 +346,11 @@ static inline uint32_t dwc2_get_glb_intstatus(void) return tmpreg; } +static inline uint32_t dwc2_get_current_frame(void) +{ + return (USB_OTG_HOST->HFNUM & USB_OTG_HFNUM_FRNUM); +} + /**************************************************************************** * Name: dwc2_pipe_alloc * @@ -370,30 +388,11 @@ static int dwc2_pipe_alloc(void) * ****************************************************************************/ -static void dwc2_pipe_free(int chidx) +static void dwc2_pipe_free(struct dwc2_pipe *chan) { /* Mark the channel available */ - g_dwc2_hcd.chan[chidx].inuse = false; -} - -/**************************************************************************** - * Name: dwc2_pipe_freeall - * - * Description: - * Free all channels. - * - ****************************************************************************/ - -static inline void dwc2_pipe_freeall(void) -{ - uint8_t chidx; - - /* Free all host channels */ - - for (chidx = 1; chidx < CONFIG_USB_DWC2_PIPE_NUM; chidx++) { - dwc2_pipe_free(chidx); - } + chan->inuse = false; } /**************************************************************************** @@ -709,12 +708,10 @@ uint8_t usbh_get_port_speed(const uint8_t port) int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed) { struct dwc2_pipe *chan; - int chidx; int ret; - chidx = (int)ep; + chan = (struct dwc2_pipe *)ep; - chan = &g_dwc2_hcd.chan[chidx]; ret = usb_osal_mutex_take(chan->exclsem); if (ret < 0) { return ret; @@ -732,18 +729,27 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) struct usbh_hubport *hport; int chidx; uint8_t speed; + usb_osal_sem_t waitsem; + usb_osal_mutex_t exclsem; hport = ep_cfg->hport; chidx = dwc2_pipe_alloc(); chan = &g_dwc2_hcd.chan[chidx]; + + waitsem = chan->waitsem; + exclsem = chan->exclsem; + + memset(chan, 0, sizeof(struct dwc2_pipe)); + + chan->chidx = chidx; chan->ep_addr = ep_cfg->ep_addr; chan->ep_mps = ep_cfg->ep_mps; chan->ep_type = ep_cfg->ep_type; + chan->ep_interval = ep_cfg->ep_interval; chan->dev_addr = hport->dev_addr; chan->speed = hport->speed; - *ep = (usbh_epinfo_t)chidx; if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) { chan->data_pid = HC_PID_DATA1; @@ -752,15 +758,22 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) chan->data_pid = HC_PID_DATA0; } + chan->inuse = true; + chan->waitsem = waitsem; + chan->exclsem = exclsem; + + *ep = (usbh_epinfo_t)chan; + return 0; } int usbh_ep_free(usbh_epinfo_t ep) { - int chidx; + struct dwc2_pipe *chan; + + chan = (struct dwc2_pipe *)ep; - chidx = (int)ep; - dwc2_pipe_free(chidx); + dwc2_pipe_free(chan); return 0; } @@ -770,9 +783,8 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint int chidx; int ret; - chidx = (int)ep; + chan = (struct dwc2_pipe *)ep; - chan = &g_dwc2_hcd.chan[chidx]; ret = usb_osal_mutex_take(chan->exclsem); if (ret < 0) { return ret; @@ -783,6 +795,8 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint goto error_out; } + chidx = chan->chidx; + chan->waiter = true; chan->result = -EBUSY; chan->num_packets = dwc2_calculate_packet_num(8, chan->ep_addr, chan->ep_mps, &chan->xferlen); @@ -858,9 +872,8 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui int chidx; int ret; - chidx = (int)ep; + chan = (struct dwc2_pipe *)ep; - chan = &g_dwc2_hcd.chan[chidx]; ret = usb_osal_mutex_take(chan->exclsem); if (ret < 0) { return ret; @@ -871,6 +884,7 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui goto error_out; } + chidx = chan->chidx; chan->num_packets = dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen); dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid); ret = dwc2_pipe_wait(chan, timeout); @@ -892,9 +906,8 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui int chidx; int ret; - chidx = (int)ep; + chan = (struct dwc2_pipe *)ep; - chan = &g_dwc2_hcd.chan[chidx]; ret = usb_osal_mutex_take(chan->exclsem); if (ret < 0) { return ret; @@ -905,6 +918,7 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui goto error_out; } + chidx = chan->chidx; chan->num_packets = dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen); dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid); ret = dwc2_pipe_wait(chan, timeout); @@ -925,9 +939,8 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl int chidx; int ret; - chidx = (int)ep; + chan = (struct dwc2_pipe *)ep; - chan = &g_dwc2_hcd.chan[chidx]; ret = usb_osal_mutex_take(chan->exclsem); if (ret < 0) { return ret; @@ -938,6 +951,7 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl goto error_out; } + chidx = chan->chidx; chan->num_packets = dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen); dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid); @@ -953,9 +967,8 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl int chidx; int ret; - chidx = (int)ep; + chan = (struct dwc2_pipe *)ep; - chan = &g_dwc2_hcd.chan[chidx]; ret = usb_osal_mutex_take(chan->exclsem); if (ret < 0) { return ret; @@ -966,6 +979,7 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl goto error_out; } + chidx = chan->chidx; chan->num_packets = dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen); dwc2_pipe_transfer(chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid); @@ -978,7 +992,6 @@ error_out: int usb_ep_cancel(usbh_epinfo_t ep) { struct dwc2_pipe *chan; - int chidx; int ret; size_t flags; #ifdef CONFIG_USBHOST_ASYNCH @@ -986,8 +999,7 @@ int usb_ep_cancel(usbh_epinfo_t ep) void *arg; #endif - chidx = (int)ep; - chan = &g_dwc2_hcd.chan[chidx]; + chan = (struct dwc2_pipe *)ep; flags = usb_osal_enter_critical_section(); @@ -1019,11 +1031,6 @@ int usb_ep_cancel(usbh_epinfo_t ep) return 0; } -void dwc2_reset_handler(void *arg) -{ - usbh_reset_port(1); -} - //static void usb_dwc2_rxqlvl_irq_handler(void) //{ // uint32_t pktsts; @@ -1236,9 +1243,15 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num) } } +void dwc2_reset_handler(void *arg) +{ + usbh_reset_port(1); +} + static void dwc2_port_irq_handler(void) { __IO uint32_t hprt0, hprt0_dup, regval; + bool reset = false; /* Handle Host Port Interrupts */ hprt0 = USB_OTG_HPRT; @@ -1250,11 +1263,7 @@ static void dwc2_port_irq_handler(void) /* Check whether Port Connect detected */ if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) { if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) { - if (!g_dwc2_hcd.connected) { - g_dwc2_hcd.connected = true; - usbh_event_notify_handler(USBH_EVENT_CONNECTED, 1); - } - //usb_workqueue_submit(&g_hpworkq, &g_dwc2_hcd.work, dwc2_reset_handler, NULL, 0); + reset = true; } hprt0_dup |= USB_OTG_HPRT_PCDET; } @@ -1273,7 +1282,7 @@ static void dwc2_port_irq_handler(void) regval &= ~USB_OTG_HCFG_FSLSPCS; regval |= USB_OTG_HCFG_FSLSPCS_1; USB_OTG_HOST->HCFG = regval; - //usb_workqueue_submit(&g_hpworkq, &g_dwc2_hcd.work, dwc2_reset_handler, NULL, 0); + reset = true; } } else { USB_OTG_HOST->HFIR = 48000U; @@ -1282,12 +1291,21 @@ static void dwc2_port_irq_handler(void) regval &= ~USB_OTG_HCFG_FSLSPCS; regval |= USB_OTG_HCFG_FSLSPCS_0; USB_OTG_HOST->HCFG = regval; - //usb_workqueue_submit(&g_hpworkq, &g_dwc2_hcd.work, dwc2_reset_handler, NULL, 0); + reset = true; } } #endif - + usbh_event_notify_handler(USBH_EVENT_CONNECTED, 1); } else { + for (int chidx = 0; chidx < CONFIG_USB_DWC2_PIPE_NUM; chidx++) { + struct dwc2_pipe *chan; + chan = &g_dwc2_hcd.chan[chidx]; + if (chan->waiter) { + chan->waiter = false; + usb_osal_sem_give(chan->waitsem); + } + } + usbh_event_notify_handler(USBH_EVENT_DISCONNECTED, 1); } } @@ -1297,6 +1315,9 @@ static void dwc2_port_irq_handler(void) } /* Clear Port Interrupts */ USB_OTG_HPRT = hprt0_dup; + if (reset) { + usb_workqueue_submit(&g_hpworkq, &g_dwc2_hcd.work, dwc2_reset_handler, NULL, 0); + } } void USBH_IRQHandler(void) @@ -1313,19 +1334,6 @@ void USBH_IRQHandler(void) dwc2_port_irq_handler(); } if (gint_status & USB_OTG_GINTSTS_DISCINT) { - if (g_dwc2_hcd.connected) { - g_dwc2_hcd.connected = false; - - for (int chidx = 0; chidx < CONFIG_USB_DWC2_PIPE_NUM; chidx++) { - struct dwc2_pipe *chan; - chan = &g_dwc2_hcd.chan[chidx]; - if (chan->waiter) { - chan->waiter = false; - usb_osal_sem_give(chan->waitsem); - } - } - usbh_event_notify_handler(USBH_EVENT_DISCONNECTED, 1); - } USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_DISCINT; } // if (gint_status & USB_OTG_GINTSTS_RXFLVL) { |
