From eb08bcc5a0b0cb3ad1c8af6422ec5c2631e8c157 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Sun, 6 Feb 2022 19:02:28 +0800 Subject: [PATCH] update hcd synopsys port, fix speed value when run HAL_HCD_HC_Init --- .../usb_host/stm32f429igt6/Core/Src/main.c | 38 +- .../stm32f429igt6/Core/Src/stm32f4xx_it.c | 18 +- .../MDK-ARM/stm32f429igt6.uvoptx | 40 +- .../MDK-ARM/stm32f429igt6.uvprojx | 14 +- .../usb_host/stm32f429igt6/stm32f429igt6.ioc | 6 +- port/synopsys/usb_hc_synopsys.c | 772 ++++++++++-------- 6 files changed, 501 insertions(+), 387 deletions(-) diff --git a/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c b/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c index e7f2a9cd..e9fe153f 100644 --- a/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c +++ b/demo/stm32/usb_host/stm32f429igt6/Core/Src/main.c @@ -45,7 +45,7 @@ /* Private variables ---------------------------------------------------------*/ UART_HandleTypeDef huart1; -HCD_HandleTypeDef hhcd_USB_OTG_HS; +//HCD_HandleTypeDef hhcd_USB_OTG_HS; /* USER CODE BEGIN PV */ @@ -68,11 +68,6 @@ int fputc(int ch, FILE *f) return ch; } -void usb_hc_low_level_init(void) -{ - MX_USB_OTG_HS_HCD_Init(); -} - /* USER CODE END 0 */ /** @@ -107,8 +102,9 @@ int main(void) //MX_USB_OTG_HS_HCD_Init(); /* USER CODE BEGIN 2 */ - usbh_initialize(); - vTaskStartScheduler(); + usbh_initialize(); + printf("Start usb host task...\r\n"); + vTaskStartScheduler(); /* USER CODE END 2 */ /* Infinite loop */ @@ -213,19 +209,19 @@ static void MX_USB_OTG_HS_HCD_Init(void) /* USER CODE BEGIN USB_OTG_HS_Init 1 */ /* USER CODE END USB_OTG_HS_Init 1 */ - hhcd_USB_OTG_HS.Instance = USB_OTG_HS; - hhcd_USB_OTG_HS.Init.Host_channels = 12; - hhcd_USB_OTG_HS.Init.speed = HCD_SPEED_FULL; - hhcd_USB_OTG_HS.Init.dma_enable = DISABLE; - hhcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY; - hhcd_USB_OTG_HS.Init.Sof_enable = DISABLE; - hhcd_USB_OTG_HS.Init.low_power_enable = DISABLE; - hhcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE; - hhcd_USB_OTG_HS.Init.use_external_vbus = DISABLE; - if (HAL_HCD_Init(&hhcd_USB_OTG_HS) != HAL_OK) - { - Error_Handler(); - } +// hhcd_USB_OTG_HS.Instance = USB_OTG_HS; +// hhcd_USB_OTG_HS.Init.Host_channels = 12; +// hhcd_USB_OTG_HS.Init.speed = HCD_SPEED_FULL; +// hhcd_USB_OTG_HS.Init.dma_enable = DISABLE; +// hhcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY; +// hhcd_USB_OTG_HS.Init.Sof_enable = DISABLE; +// hhcd_USB_OTG_HS.Init.low_power_enable = DISABLE; +// hhcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE; +// hhcd_USB_OTG_HS.Init.use_external_vbus = DISABLE; +// if (HAL_HCD_Init(&hhcd_USB_OTG_HS) != HAL_OK) +// { +// Error_Handler(); +// } /* USER CODE BEGIN USB_OTG_HS_Init 2 */ /* USER CODE END USB_OTG_HS_Init 2 */ diff --git a/demo/stm32/usb_host/stm32f429igt6/Core/Src/stm32f4xx_it.c b/demo/stm32/usb_host/stm32f429igt6/Core/Src/stm32f4xx_it.c index 763a21e1..0d99ed40 100644 --- a/demo/stm32/usb_host/stm32f429igt6/Core/Src/stm32f4xx_it.c +++ b/demo/stm32/usb_host/stm32f429igt6/Core/Src/stm32f4xx_it.c @@ -196,7 +196,7 @@ extern void xPortSysTickHandler(void); } #endif /* INCLUDE_xTaskGetSchedulerState */ /* USER CODE END SysTick_IRQn 0 */ - //HAL_IncTick(); + HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ @@ -212,16 +212,16 @@ extern void xPortSysTickHandler(void); /** * @brief This function handles USB On The Go HS global interrupt. */ -void OTG_HS_IRQHandler(void) -{ - /* USER CODE BEGIN OTG_HS_IRQn 0 */ +//void OTG_HS_IRQHandler(void) +//{ +// /* USER CODE BEGIN OTG_HS_IRQn 0 */ - /* USER CODE END OTG_HS_IRQn 0 */ - HAL_HCD_IRQHandler(&hhcd_USB_OTG_HS); - /* USER CODE BEGIN OTG_HS_IRQn 1 */ +// /* USER CODE END OTG_HS_IRQn 0 */ +// HAL_HCD_IRQHandler(&hhcd_USB_OTG_HS); +// /* USER CODE BEGIN OTG_HS_IRQn 1 */ - /* USER CODE END OTG_HS_IRQn 1 */ -} +// /* USER CODE END OTG_HS_IRQn 1 */ +//} /* USER CODE BEGIN 1 */ diff --git a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx index e3fc25dc..11a668e7 100644 --- a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx +++ b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvoptx @@ -157,18 +157,18 @@ 0 0 - 89 + 360 1 -
0
+
134233946
0 0 0 0 0 - 0 - ..\..\..\..\..\class\cdc\usbh_cdc_acm.c + 1 + ..\..\..\..\..\class\msc\usbh_msc.c - + \\stm32f429igt6\../../../../../class/msc/usbh_msc.c\360
@@ -269,6 +269,18 @@ 2 2 + 5 + 0 + 0 + 0 + ..\Core\Inc\FreeRTOSConfig.h + FreeRTOSConfig.h + 0 + 0 + + + 2 + 3 1 0 0 @@ -280,7 +292,7 @@ 2 - 3 + 4 1 0 0 @@ -292,7 +304,7 @@ 2 - 4 + 5 1 0 0 @@ -302,18 +314,6 @@ 0 0 - - 2 - 5 - 5 - 0 - 0 - 0 - ..\Core\Inc\FreeRTOSConfig.h - FreeRTOSConfig.h - 0 - 0 - @@ -562,7 +562,7 @@ FreeRTOS - 0 + 1 0 0 0 diff --git a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx index 56e428c0..b72a0449 100644 --- a/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx +++ b/demo/stm32/usb_host/stm32f429igt6/MDK-ARM/stm32f429igt6.uvprojx @@ -338,9 +338,9 @@ 0 - USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_HS + USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_HS_IN_FULL - ../Core/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy; ../Drivers/CMSIS/Device/ST/STM32F4xx/Include; ../Drivers/CMSIS/Include; ..\FreeRTOS\include; ..\FreeRTOS\portable\GCC\ARM_CM4F; ..\..\..\..\..\common; ..\..\..\..\..\core; ..\..\..\..\..\class\cdc; ..\..\..\..\..\class\hub; ..\..\..\..\..\class\hid; ..\..\..\..\..\class\msc; ..\..\..\..\..\osal + ../Core/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc; ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy; ../Drivers/CMSIS/Device/ST/STM32F4xx/Include; ../Drivers/CMSIS/Include; ..\FreeRTOS\include; ..\FreeRTOS\portable\GCC\ARM_CM4F; ..\..\..\..\..\common; ..\..\..\..\..\core; ..\..\..\..\..\class\cdc; ..\..\..\..\..\class\hub; ..\..\..\..\..\class\hid; ..\..\..\..\..\class\msc; ..\..\..\..\..\osal @@ -394,6 +394,11 @@ Application/User/Core + + FreeRTOSConfig.h + 5 + ..\Core\Inc\FreeRTOSConfig.h + main.c 1 @@ -409,11 +414,6 @@ 1 ../Core/Src/stm32f4xx_hal_msp.c - - FreeRTOSConfig.h - 5 - ..\Core\Inc\FreeRTOSConfig.h - diff --git a/demo/stm32/usb_host/stm32f429igt6/stm32f429igt6.ioc b/demo/stm32/usb_host/stm32f429igt6/stm32f429igt6.ioc index 52fe5b65..6ccd8df5 100644 --- a/demo/stm32/usb_host/stm32f429igt6/stm32f429igt6.ioc +++ b/demo/stm32/usb_host/stm32f429igt6/stm32f429igt6.ioc @@ -60,8 +60,8 @@ ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=false -ProjectManager.CustomerFirmwarePackage=E\:\\Library\\STM32\\STM32Cube_FW_F4_V1.25.2 -ProjectManager.DefaultFWLocation=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32F429IGTx ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.26.0 @@ -69,7 +69,7 @@ ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true -ProjectManager.LastFirmware=true +ProjectManager.LastFirmware=false ProjectManager.LibraryCopy=0 ProjectManager.MainLocation=Core/Src ProjectManager.NoMain=false diff --git a/port/synopsys/usb_hc_synopsys.c b/port/synopsys/usb_hc_synopsys.c index ed9e5043..09517f45 100644 --- a/port/synopsys/usb_hc_synopsys.c +++ b/port/synopsys/usb_hc_synopsys.c @@ -1,11 +1,21 @@ #include "usbh_core.h" #include "stm32f4xx_hal.h" +#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL) +HCD_HandleTypeDef hhcd_USB_OTG_HS; +#ifndef USBH_IRQHandler +#define USBH_IRQHandler OTG_HS_IRQHandler +#endif +#else +HCD_HandleTypeDef hhcd_USB_OTG_FS; +#ifndef USBH_IRQHandler +#define USBH_IRQHandler OTG_FS_IRQHandler +#endif +#endif + #define USBH_PID_SETUP 0U #define USBH_PID_DATA 1U -#define USB_SNOPSYS_RETRY_COUNT 5 - #ifndef CONFIG_USBHOST_CHANNELS #define CONFIG_USBHOST_CHANNELS 12 /* Number of host channels */ #endif @@ -18,8 +28,11 @@ struct usb_synopsys_chan { usb_osal_sem_t waitsem; /* Channel wait semaphore */ - uint8_t chidx; /* Channel index */ + volatile int result; /* The result of the transfer */ bool inuse; /* True: This channel is "in use" */ + bool in; /* True: IN endpoint */ + volatile bool waiter; /* True: Thread is waiting for a channel event */ + volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */ #ifdef CONFIG_USBHOST_ASYNCH usbh_asynch_callback_t callback; /* Transfer complete callback */ void *arg; /* Argument that accompanies the callback */ @@ -90,6 +103,185 @@ static void usb_synopsys_chan_free(struct usb_synopsys_priv *priv, int chidx) priv->chan[chidx].inuse = false; } +/**************************************************************************** + * Name: usb_synopsys_chan_waitsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling + * the transfer (as soon as we are absolutely committed to the transfer). + * We do this to minimize race conditions. This logic would have to be + * expanded if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Called from a normal thread context BEFORE the transfer has been + * started. + * + ****************************************************************************/ + +static int usb_synopsys_chan_waitsetup(struct usb_synopsys_priv *priv, + struct usb_synopsys_chan *chan) +{ + uint32_t flags; + int ret = -ENODEV; + + flags = usb_osal_enter_critical_section(); + + /* Is the device still connected? */ + + if (priv->connected) { + /* Yes.. then set waiter to indicate that we expect to be informed + * when either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + chan->waiter = true; +#ifdef CONFIG_USBHOST_ASYNCH + chan->callback = NULL; + chan->arg = NULL; +#endif + ret = 0; + } + usb_osal_leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: usb_synopsys_chan_asynchsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling + * the transfer (as soon as we are absolutely committed to the to avoid + * transfer). We do this to minimize race conditions. This logic would + * have to be expanded if we want to have more than one packet in flight + * at a time! + * + * Assumptions: + * Might be called from the level of an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int usb_synopsys_chan_asynchsetup(struct usb_synopsys_priv *priv, + struct usb_synopsys_chan *chan, + usbh_asynch_callback_t callback, void *arg) +{ + uint32_t flags; + int ret = -ENODEV; + + flags = usb_osal_enter_critical_section(); + /* Is the device still connected? */ + + if (priv->connected) { + /* Yes.. then set waiter to indicate that we expect to be informed + * when either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + chan->waiter = false; + chan->callback = callback; + chan->arg = arg; + ret = 0; + } + + usb_osal_leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_chan_wait + * + * Description: + * Wait for a transfer on a channel to complete. + * + * Assumptions: + * Called from a normal thread context + * + ****************************************************************************/ + +static int usb_synopsys_chan_wait(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan) +{ + int ret; + + /* Loop, testing for an end of transfer condition. The channel 'result' + * was set to EBUSY and 'waiter' was set to true before the transfer; + * 'waiter' will be set to false and 'result' will be set appropriately + * when the transfer is completed. + */ + + while (chan->waiter) { + usb_osal_sem_take(chan->waitsem); + } + + /* The transfer is complete re-enable interrupts and return the result */ + ret = chan->result; + return ret; +} + +/**************************************************************************** + * Name: stm32_chan_wakeup + * + * Description: + * A channel transfer has completed... wakeup any threads waiting for the + * transfer to complete. + * + * Assumptions: + * This function is called from the transfer complete interrupt handler for + * the channel. Interrupts are disabled. + * + ****************************************************************************/ + +static void usb_synopsys_chan_wakeup(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan) +{ + usbh_asynch_callback_t callback; + void *arg; + int nbytes; + + /* Is the transfer complete? */ + + if (chan->result != -EBUSY) { + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) { + /* Wake'em up! */ + chan->waiter = false; + usb_osal_sem_give(chan->waitsem); + } +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + else if (chan->callback) { + /* Handle continuation of IN/OUT pipes */ + if (chan->in) { + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + chan->callback = NULL; + chan->arg = NULL; + if (chan->result < 0) { + nbytes = chan->result; + } + + callback(arg, nbytes); + + } else { + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + chan->callback = NULL; + chan->arg = NULL; + if (chan->result < 0) { + nbytes = chan->result; + } + + callback(arg, nbytes); + } + } +#endif + } +} + __WEAK void usb_hc_low_level_init(void) { } @@ -97,12 +289,12 @@ __WEAK void usb_hc_low_level_init(void) int usb_hc_init(void) { memset(&g_usbhost, 0, sizeof(struct usb_synopsys_priv)); -#ifdef CONFIG_USB_HS - extern HCD_HandleTypeDef hhcd_USB_OTG_HS; +#if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL) g_usbhost.handle = &hhcd_USB_OTG_HS; + g_usbhost.handle->Instance = USB_OTG_HS; #else - extern HCD_HandleTypeDef hhcd_USB_OTG_FS; g_usbhost.handle = &hhcd_USB_OTG_FS; + g_usbhost.handle->Instance = USB_OTG_FS; #endif g_usbhost.exclsem = usb_osal_mutex_create(); @@ -110,14 +302,23 @@ int usb_hc_init(void) for (uint8_t i = 0; i < CONFIG_USBHOST_CHANNELS; i++) { struct usb_synopsys_chan *chan = &g_usbhost.chan[i]; - chan->chidx = i; - /* The waitsem semaphore is used for signaling and, hence, should not * have priority inheritance enabled. */ chan->waitsem = usb_osal_sem_create(0); } - usb_hc_low_level_init(); + + g_usbhost.handle->Init.Host_channels = CONFIG_USBHOST_CHANNELS; + g_usbhost.handle->Init.speed = HCD_SPEED_FULL; + g_usbhost.handle->Init.dma_enable = DISABLE; + g_usbhost.handle->Init.phy_itface = USB_OTG_EMBEDDED_PHY; + g_usbhost.handle->Init.Sof_enable = DISABLE; + g_usbhost.handle->Init.low_power_enable = DISABLE; + g_usbhost.handle->Init.vbus_sensing_enable = DISABLE; + g_usbhost.handle->Init.use_external_vbus = DISABLE; + if (HAL_HCD_Init(g_usbhost.handle) != HAL_OK) { + return -1; + } HAL_HCD_Start(g_usbhost.handle); return 0; } @@ -168,6 +369,7 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) struct usbh_hubport *hport; int chidx; int ret; + uint8_t speed; ret = usb_osal_mutex_take(g_usbhost.exclsem); if (ret < 0) { @@ -176,27 +378,30 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) hport = ep_cfg->hport; - if ((ep_cfg->ep_type & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_CONTROL) { + if (hport->speed == USB_SPEED_FULL) { + speed = HCD_SPEED_FULL; + } else if (hport->speed == USB_SPEED_LOW) { + speed = HCD_SPEED_LOW; + } + + if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) { ep0 = usb_malloc(sizeof(struct usb_synopsys_ctrlinfo)); ep0->outndx = usb_synopsys_chan_alloc(&g_usbhost); ep0->inndx = usb_synopsys_chan_alloc(&g_usbhost); - HAL_HCD_HC_Init(g_usbhost.handle, ep0->outndx, 0x00, hport->dev_addr, hport->speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps); - HAL_HCD_HC_Init(g_usbhost.handle, ep0->inndx, 0x80, hport->dev_addr, hport->speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps); + HAL_HCD_HC_Init(g_usbhost.handle, ep0->outndx, 0x00, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps); + HAL_HCD_HC_Init(g_usbhost.handle, ep0->inndx, 0x80, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps); *ep = (usbh_epinfo_t)ep0; } else { chidx = usb_synopsys_chan_alloc(&g_usbhost); - HAL_HCD_HC_Init(g_usbhost.handle, chidx, ep_cfg->ep_addr, hport->dev_addr, hport->speed, ep_cfg->ep_type, ep_cfg->ep_mps); - if ((ep_cfg->ep_type & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) { - if (g_usbhost.handle->hc[chidx].ep_is_in) { - g_usbhost.handle->hc[chidx].toggle_in = 0; - } else { - g_usbhost.handle->hc[chidx].toggle_out = 0; - } - } + HAL_HCD_HC_Init(g_usbhost.handle, chidx, ep_cfg->ep_addr, hport->dev_addr, speed, ep_cfg->ep_type, ep_cfg->ep_mps); + + g_usbhost.handle->hc[chidx].toggle_in = 0; + g_usbhost.handle->hc[chidx].toggle_out = 0; + *ep = (usbh_epinfo_t)chidx; } usb_osal_mutex_give(g_usbhost.exclsem); @@ -204,185 +409,97 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) } int usbh_ep_free(usbh_epinfo_t ep) { + uint8_t chidx = (uint8_t)ep; + usb_synopsys_chan_free(&g_usbhost, chidx); return 0; } int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint8_t *buffer) { - uint8_t retries; int ret; + uint32_t flags; + struct usb_synopsys_chan *chan; + struct usb_synopsys_priv *priv = &g_usbhost; struct usb_synopsys_ctrlinfo *ep0info = (struct usb_synopsys_ctrlinfo *)ep; ret = usb_osal_mutex_take(g_usbhost.exclsem); if (ret < 0) { return ret; } - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - ep0info->outndx, /* Pipe index */ - 0, /* Direction : OUT */ - 0, /* EP type */ - USBH_PID_SETUP, /* Type Data */ - (uint8_t *)setup, /* data buffer */ - 8, /* data length */ - 0); /* do ping (HS Only)*/ - ret = usb_osal_sem_take(g_usbhost.chan[ep0info->outndx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(5); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[ep0info->outndx]; + usb_synopsys_chan_waitsetup(priv, chan); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + ep0info->outndx, /* Pipe index */ + 0, /* Direction : OUT */ + 0, /* EP type */ + USBH_PID_SETUP, /* Type Data */ + (uint8_t *)setup, /* data buffer */ + 8, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + + ret = usb_synopsys_chan_wait(priv, chan); + if (ret < 0) { goto errout_with_mutex; } - if (setup->wLength && buffer) { if (setup->bmRequestType & 0x80) { - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - ep0info->inndx, /* Pipe index */ - 1, /* Direction : IN */ - 0, /* EP type */ - USBH_PID_DATA, /* Type Data */ - buffer, /* data buffer */ - setup->wLength, /* data length */ - 0); /* do ping (HS Only)*/ - usb_osal_sem_take(g_usbhost.chan[ep0info->inndx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(5); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[ep0info->inndx]; + usb_synopsys_chan_waitsetup(priv, chan); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + ep0info->inndx, /* Pipe index */ + 1, /* Direction : IN */ + 0, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buffer, /* data buffer */ + setup->wLength, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + ret = usb_synopsys_chan_wait(priv, chan); + if (ret < 0) { goto errout_with_mutex; } - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - ep0info->outndx, /* Pipe index */ - 0, /* Direction : OUT */ - 0, /* EP type */ - USBH_PID_DATA, /* Type Data */ - NULL, /* data buffer */ - 0, /* data length */ - 0); /* do ping (HS Only)*/ - usb_osal_sem_take(g_usbhost.chan[ep0info->outndx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(5); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; + + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[ep0info->outndx]; + usb_synopsys_chan_waitsetup(priv, chan); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + ep0info->outndx, /* Pipe index */ + 0, /* Direction : OUT */ + 0, /* EP type */ + USBH_PID_DATA, /* Type Data */ + NULL, /* data buffer */ + 0, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + ret = usb_synopsys_chan_wait(priv, chan); + if (ret < 0) { goto errout_with_mutex; } } else { - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - ep0info->outndx, /* Pipe index */ - 0, /* Direction : OUT */ - 0, /* EP type */ - USBH_PID_DATA, /* Type Data */ - buffer, /* data buffer */ - setup->wLength, /* data length */ - 0); /* do ping (HS Only)*/ - - usb_osal_sem_take(g_usbhost.chan[ep0info->outndx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(5); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->outndx) == URB_DONE) { - break; - } - } - - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[ep0info->outndx]; + usb_synopsys_chan_waitsetup(priv, chan); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + ep0info->outndx, /* Pipe index */ + 0, /* Direction : OUT */ + 0, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buffer, /* data buffer */ + setup->wLength, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + ret = usb_synopsys_chan_wait(priv, chan); + if (ret < 0) { goto errout_with_mutex; } - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - ep0info->inndx, /* Pipe index */ - 1, /* Direction : IN */ - 0, /* EP type */ - USBH_PID_DATA, /* Type Data */ - NULL, /* data buffer */ - 0, /* data length */ - 0); /* do ping (HS Only)*/ - usb_osal_sem_take(g_usbhost.chan[ep0info->inndx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(5); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; - goto errout_with_mutex; - } - } - } else { - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[ep0info->inndx]; + usb_synopsys_chan_waitsetup(priv, chan); ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, ep0info->inndx, /* Pipe index */ 1, /* Direction : IN */ @@ -391,26 +508,27 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint NULL, /* data buffer */ 0, /* data length */ 0); /* do ping (HS Only)*/ - usb_osal_sem_take(g_usbhost.chan[ep0info->inndx].waitsem); + usb_osal_leave_critical_section(flags); + ret = usb_synopsys_chan_wait(priv, chan); if (ret < 0) { goto errout_with_mutex; } - usb_osal_msleep(10); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, ep0info->inndx) == URB_DONE) { - break; - } } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; + } else { + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[ep0info->inndx]; + usb_synopsys_chan_waitsetup(priv, chan); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + ep0info->inndx, /* Pipe index */ + 1, /* Direction : IN */ + 0, /* EP type */ + USBH_PID_DATA, /* Type Data */ + NULL, /* data buffer */ + 0, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + ret = usb_synopsys_chan_wait(priv, chan); + if (ret < 0) { goto errout_with_mutex; } } @@ -420,84 +538,39 @@ errout_with_mutex: usb_osal_mutex_give(g_usbhost.exclsem); return ret; } + int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen) { - uint8_t retries; int ret; + uint32_t flags; + struct usb_synopsys_chan *chan; + struct usb_synopsys_priv *priv = &g_usbhost; uint8_t chidx = (uint8_t)ep; ret = usb_osal_mutex_take(g_usbhost.exclsem); if (ret < 0) { return ret; } - if (g_usbhost.handle->hc[chidx].ep_is_in) { - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - chidx, /* Pipe index */ - 1, /* Direction : IN */ - 2, /* EP type */ - USBH_PID_DATA, /* Type Data */ - buffer, /* data buffer */ - buflen, /* data length */ - 0); /* do ping (HS Only)*/ - usb_osal_sem_take(g_usbhost.chan[chidx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(10); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; - goto errout_with_mutex; - } - } else { - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - chidx, /* Pipe index */ - 0, /* Direction : OUT */ - 2, /* EP type */ - USBH_PID_DATA, /* Type Data */ - buffer, /* data buffer */ - buflen, /* data length */ - 1); /* do ping (HS Only)*/ - usb_osal_sem_take(g_usbhost.chan[chidx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(10); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; - goto errout_with_mutex; - } + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[chidx]; + usb_synopsys_chan_waitsetup(priv, chan); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + chidx, /* Pipe index */ + g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */ + 2, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buffer, /* data buffer */ + buflen, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + ret = usb_synopsys_chan_wait(priv, chan); + if (ret < 0) { + goto errout_with_mutex; } + usb_osal_mutex_give(g_usbhost.exclsem); - return HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx); + return g_usbhost.handle->hc[chidx].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx) : buflen; errout_with_mutex: usb_osal_mutex_give(g_usbhost.exclsem); return ret; @@ -505,82 +578,35 @@ errout_with_mutex: int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen) { - uint8_t retries; + uint32_t flags; int ret; + struct usb_synopsys_chan *chan; + struct usb_synopsys_priv *priv = &g_usbhost; uint8_t chidx = (uint8_t)ep; ret = usb_osal_mutex_take(g_usbhost.exclsem); if (ret < 0) { return ret; } - if (g_usbhost.handle->hc[chidx].ep_is_in) { - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - chidx, /* Pipe index */ - 1, /* Direction : IN */ - 3, /* EP type */ - USBH_PID_DATA, /* Type Data */ - buffer, /* data buffer */ - buflen, /* data length */ - 0); /* do ping (HS Only)*/ - - usb_osal_sem_take(g_usbhost.chan[chidx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(10); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; - goto errout_with_mutex; - } - } else { - for (retries = 0; retries < USB_SNOPSYS_RETRY_COUNT; retries++) { - ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, - chidx, /* Pipe index */ - 0, /* Direction : OUT */ - 3, /* EP type */ - USBH_PID_DATA, /* Type Data */ - buffer, /* data buffer */ - buflen, /* data length */ - 1); /* do ping (HS Only)*/ - usb_osal_sem_take(g_usbhost.chan[chidx].waitsem); - if (ret < 0) { - goto errout_with_mutex; - } - usb_osal_msleep(10); - if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_NOTREADY) { - ret = -EAGAIN; - continue; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_STALL) { - ret = -EPERM; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_ERROR) { - ret = -EIO; - goto errout_with_mutex; - } else if (HAL_HCD_HC_GetURBState(g_usbhost.handle, chidx) == URB_DONE) { - break; - } - } - if (retries >= USB_SNOPSYS_RETRY_COUNT) { - ret = -ETIMEDOUT; - goto errout_with_mutex; - } + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[chidx]; + usb_synopsys_chan_waitsetup(priv, chan); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + chidx, /* Pipe index */ + g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */ + 3, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buffer, /* data buffer */ + buflen, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + ret = usb_synopsys_chan_wait(priv, chan); + if (ret < 0) { + goto errout_with_mutex; } + usb_osal_mutex_give(g_usbhost.exclsem); - return HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx); + return g_usbhost.handle->hc[chidx].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chidx) : buflen; errout_with_mutex: usb_osal_mutex_give(g_usbhost.exclsem); return ret; @@ -588,12 +614,64 @@ errout_with_mutex: int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg) { - return 0; + int ret; + uint32_t flags; + struct usb_synopsys_chan *chan; + struct usb_synopsys_priv *priv = &g_usbhost; + uint8_t chidx = (uint8_t)ep; + + ret = usb_osal_mutex_take(g_usbhost.exclsem); + if (ret < 0) { + return ret; + } + + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[chidx]; + usb_synopsys_chan_asynchsetup(priv, chan, callback, arg); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + chidx, /* Pipe index */ + g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */ + 2, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buffer, /* data buffer */ + buflen, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + + usb_osal_mutex_give(g_usbhost.exclsem); + + return ret; } int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg) { - return 0; + int ret; + uint32_t flags; + struct usb_synopsys_chan *chan; + struct usb_synopsys_priv *priv = &g_usbhost; + uint8_t chidx = (uint8_t)ep; + + ret = usb_osal_mutex_take(g_usbhost.exclsem); + if (ret < 0) { + return ret; + } + + flags = usb_osal_enter_critical_section(); + chan = &priv->chan[chidx]; + usb_synopsys_chan_asynchsetup(priv, chan, callback, arg); + ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + chidx, /* Pipe index */ + g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */ + 3, /* EP type */ + USBH_PID_DATA, /* Type Data */ + buffer, /* data buffer */ + buflen, /* data length */ + 0); /* do ping (HS Only)*/ + usb_osal_leave_critical_section(flags); + + usb_osal_mutex_give(g_usbhost.exclsem); + + return ret; } int usb_ep_cancel(usbh_epinfo_t ep) @@ -627,5 +705,45 @@ void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) { - usb_osal_sem_give(g_usbhost.chan[chnum].waitsem); -} \ No newline at end of file + struct usb_synopsys_chan *chan; + struct usb_synopsys_priv *priv = &g_usbhost; + + chan = &priv->chan[chnum]; + if (urb_state == URB_DONE || urb_state == URB_STALL || urb_state == URB_ERROR || urb_state == URB_NOTREADY) { + if (urb_state != URB_NOTREADY) { + if (urb_state == URB_ERROR) { + chan->result = -EIO; + HAL_HCD_HC_Halt(hhcd, chnum); + } else if (urb_state == URB_STALL) { + chan->result = -EPERM; + } else if (urb_state == URB_DONE) { + chan->result = 0; + } + chan->in = g_usbhost.handle->hc[chnum].ep_is_in; + chan->xfrd = g_usbhost.handle->hc[chnum].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chnum) : g_usbhost.handle->hc[chnum].xfer_len; + usb_synopsys_chan_wakeup(priv, chan); + } else { + if (g_usbhost.handle->hc[chnum].ep_is_in == 0 && (g_usbhost.handle->hc[chnum].ep_type == USB_ENDPOINT_TYPE_CONTROL || g_usbhost.handle->hc[chnum].ep_type == USB_ENDPOINT_TYPE_BULK)) { + HAL_HCD_HC_SubmitRequest(g_usbhost.handle, + chnum, /* Pipe index */ + 0, /* Direction : OUT */ + g_usbhost.handle->hc[chnum].ep_type, /* EP type */ + USBH_PID_DATA, /* Type Data */ + g_usbhost.handle->hc[chnum].xfer_buff, /* data buffer */ + g_usbhost.handle->hc[chnum].xfer_len, /* data length */ + 0); /* do ping (HS Only)*/ + } + } + } +} + +void USBH_IRQHandler(void) +{ + /* USER CODE BEGIN OTG_HS_IRQn 0 */ + + /* USER CODE END OTG_HS_IRQn 0 */ + HAL_HCD_IRQHandler(g_usbhost.handle); + /* USER CODE BEGIN OTG_HS_IRQn 1 */ + + /* USER CODE END OTG_HS_IRQn 1 */ +}