summaryrefslogtreecommitdiffstats
path: root/bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c')
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c663
1 files changed, 409 insertions, 254 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c b/bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c
index 9ddb3ba450..dff3813380 100644
--- a/bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c
@@ -11,29 +11,30 @@
* + Peripheral Control functions
* + Peripheral State functions
*
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
@verbatim
==============================================================================
##### How to use this driver #####
==============================================================================
[..]
- (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
+ (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
(#) Call USB_CoreInit() API to initialize the USB Core peripheral.
(#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
@endverbatim
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
+
******************************************************************************
*/
@@ -63,8 +64,8 @@ static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
/** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
* @ingroup RTEMSBSPsARMSTM32H7
- * @brief Initialization and Configuration functions
- *
+ * @brief Initialization and Configuration functions
+ *
@verbatim
===============================================================================
##### Initialization/de-initialization functions #####
@@ -84,7 +85,6 @@ static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
{
HAL_StatusTypeDef ret;
-
if (cfg.phy_itface == USB_OTG_ULPI_PHY)
{
USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
@@ -98,7 +98,8 @@ HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
{
USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
}
- /* Reset after a PHY select */
+
+ /* Reset after a PHY select */
ret = USB_CoreReset(USBx);
}
else /* FS interface (embedded Phy) */
@@ -106,7 +107,7 @@ HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
/* Select FS Embedded PHY */
USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
- /* Reset after a PHY select and set Host mode */
+ /* Reset after a PHY select */
ret = USB_CoreReset(USBx);
if (cfg.battery_charging_enable == 0U)
@@ -123,6 +124,10 @@ HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
if (cfg.dma_enable == 1U)
{
+ /* make sure to reserve 18 fifo Locations for DMA buffers */
+ USBx->GDFIFOCFG &= ~(0xFFFFU << 16);
+ USBx->GDFIFOCFG |= 0x3EEU << 16;
+
USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
}
@@ -231,7 +236,7 @@ HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
* Disable the controller's Global Int in the AHB Config reg
* @param USBx Selected device
* @retval HAL status
-*/
+ */
HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
{
USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
@@ -239,38 +244,55 @@ HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
}
/**
- * @brief USB_SetCurrentMode : Set functional mode
+ * @brief USB_SetCurrentMode Set functional mode
* @param USBx Selected device
- * @param mode current core mode
+ * @param mode current core mode
* This parameter can be one of these values:
- * @arg USB_DEVICE_MODE: Peripheral mode
- * @arg USB_HOST_MODE: Host mode
- * @arg USB_DRD_MODE: Dual Role Device mode
+ * @arg USB_DEVICE_MODE Peripheral mode
+ * @arg USB_HOST_MODE Host mode
* @retval HAL status
*/
HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
{
+ uint32_t ms = 0U;
+
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
if (mode == USB_HOST_MODE)
{
USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
+
+ do
+ {
+ HAL_Delay(1U);
+ ms++;
+ } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < 50U));
}
else if (mode == USB_DEVICE_MODE)
{
USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
+
+ do
+ {
+ HAL_Delay(1U);
+ ms++;
+ } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < 50U));
}
else
{
return HAL_ERROR;
}
- HAL_Delay(50U);
+
+ if (ms == 50U)
+ {
+ return HAL_ERROR;
+ }
return HAL_OK;
}
/**
- * @brief USB_DevInit : Initializes the USB_OTG controller registers
+ * @brief USB_DevInit Initializes the USB_OTG controller registers
* for device mode
* @param USBx Selected device
* @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
@@ -309,9 +331,6 @@ HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cf
/* Restart the Phy Clock */
USBx_PCGCCTL = 0U;
- /* Device mode configuration */
- USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
-
if (cfg.phy_itface == USB_OTG_ULPI_PHY)
{
if (cfg.speed == USBD_HS_SPEED)
@@ -425,7 +444,7 @@ HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cf
}
/**
- * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
+ * @brief USB_FlushTxFifo Flush a Tx FIFO
* @param USBx Selected device
* @param num FIFO number
* This parameter can be a value from 1 to 15
@@ -434,41 +453,69 @@ HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cf
*/
HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
{
- uint32_t count = 0U;
+ __IO uint32_t count = 0U;
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ count++;
+
+ if (count > 200000U)
+ {
+ return HAL_TIMEOUT;
+ }
+ } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+ /* Flush TX Fifo */
+ count = 0U;
USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
do
{
- if (++count > 200000U)
+ count++;
+
+ if (count > 200000U)
{
return HAL_TIMEOUT;
}
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
+ } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
return HAL_OK;
}
/**
- * @brief USB_FlushRxFifo : Flush Rx FIFO
+ * @brief USB_FlushRxFifo Flush Rx FIFO
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
{
- uint32_t count = 0;
+ __IO uint32_t count = 0U;
+
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ count++;
+
+ if (count > 200000U)
+ {
+ return HAL_TIMEOUT;
+ }
+ } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+ /* Flush RX Fifo */
+ count = 0U;
USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
do
{
- if (++count > 200000U)
+ count++;
+
+ if (count > 200000U)
{
return HAL_TIMEOUT;
}
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
+ } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
return HAL_OK;
}
@@ -497,8 +544,8 @@ HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
* @param USBx Selected device
* @retval speed device speed
* This parameter can be one of these values:
- * @arg PCD_SPEED_HIGH: High speed mode
- * @arg PCD_SPEED_FULL: Full speed mode
+ * @arg USBD_HS_SPEED: High speed mode
+ * @arg USBD_FS_SPEED: Full speed mode
*/
uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
{
@@ -614,6 +661,12 @@ HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EP
/* Read DEPCTLn register */
if (ep->is_in == 1U)
{
+ if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
+ {
+ USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
+ USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
+ }
+
USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
@@ -624,6 +677,12 @@ HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EP
}
else
{
+ if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+ {
+ USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
+ USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
+ }
+
USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
@@ -649,11 +708,23 @@ HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, U
/* Read DEPCTLn register */
if (ep->is_in == 1U)
{
+ if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
+ {
+ USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
+ USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
+ }
+
USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
}
else
{
+ if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+ {
+ USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
+ USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
+ }
+
USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
}
@@ -696,7 +767,22 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef
*/
USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
- USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
+
+ if (epnum == 0U)
+ {
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ ep->xfer_len = ep->maxpacket;
+ }
+
+ USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
+ }
+ else
+ {
+ USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
+ (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
+ }
+
USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
if (ep->type == EP_TYPE_ISOC)
@@ -765,16 +851,34 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef
USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
- if (ep->xfer_len == 0U)
+ if (epnum == 0U)
{
- USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
+ if (ep->xfer_len > 0U)
+ {
+ ep->xfer_len = ep->maxpacket;
+ }
+
+ /* Store transfer size, for EP0 this is equal to endpoint max packet size */
+ ep->xfer_size = ep->maxpacket;
+
+ USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
}
else
{
- pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
- USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
- USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt);
+ if (ep->xfer_len == 0U)
+ {
+ USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
+ USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
+ }
+ else
+ {
+ pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
+ ep->xfer_size = ep->maxpacket * pktcnt;
+
+ USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
+ USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
+ }
}
if (dma == 1U)
@@ -803,103 +907,64 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef
return HAL_OK;
}
+
/**
- * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
- * @param USBx Selected device
- * @param ep pointer to endpoint structure
- * @param dma USB dma enabled or disabled
- * This parameter can be one of these values:
- * 0 : DMA feature not used
- * 1 : DMA feature used
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
+ * @brief USB_EPStoptXfer Stop transfer on an EP
+ * @param USBx usb device instance
+ * @param ep pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPStopXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
{
+ __IO uint32_t count = 0U;
+ HAL_StatusTypeDef ret = HAL_OK;
uint32_t USBx_BASE = (uint32_t)USBx;
- uint32_t epnum = (uint32_t)ep->num;
/* IN endpoint */
if (ep->is_in == 1U)
{
- /* Zero Length Packet? */
- if (ep->xfer_len == 0U)
+ /* EP enable, IN data in FIFO */
+ if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
{
- USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
- USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
- USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- }
- else
- {
- /* Program the transfer size and packet count
- * as follows: xfersize = N * maxpacket +
- * short_packet pktcnt = N + (short_packet
- * exist ? 1 : 0)
- */
- USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
-
- if (ep->xfer_len > ep->maxpacket)
- {
- ep->xfer_len = ep->maxpacket;
- }
- USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
- USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
- }
+ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
+ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
- if (dma == 1U)
- {
- if ((uint32_t)ep->dma_addr != 0U)
+ do
{
- USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
- }
+ count++;
- /* EP enable, IN data in FIFO */
- USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
- }
- else
- {
- /* EP enable, IN data in FIFO */
- USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
-
- /* Enable the Tx FIFO Empty Interrupt for this EP */
- if (ep->xfer_len > 0U)
- {
- USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
- }
+ if (count > 10000U)
+ {
+ ret = HAL_ERROR;
+ break;
+ }
+ } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA);
}
}
else /* OUT endpoint */
{
- /* Program the transfer size and packet count as follows:
- * pktcnt = N
- * xfersize = N * maxpacket
- */
- USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
- USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
-
- if (ep->xfer_len > 0U)
+ if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
{
- ep->xfer_len = ep->maxpacket;
- }
+ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
+ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
- USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
- USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
-
- if (dma == 1U)
- {
- if ((uint32_t)ep->xfer_buff != 0U)
+ do
{
- USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
- }
- }
+ count++;
- /* EP enable */
- USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+ if (count > 10000U)
+ {
+ ret = HAL_ERROR;
+ break;
+ }
+ } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA);
+ }
}
- return HAL_OK;
+ return ret;
}
+
/**
* @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
* with the EP/channel
@@ -913,11 +978,13 @@ HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDe
* 1 : DMA feature used
* @retval HAL status
*/
-HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
+HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
+ uint8_t ch_ep_num, uint16_t len, uint8_t dma)
{
uint32_t USBx_BASE = (uint32_t)USBx;
- uint32_t *pSrc = (uint32_t *)src;
- uint32_t count32b, i;
+ uint8_t *pSrc = src;
+ uint32_t count32b;
+ uint32_t i;
if (dma == 0U)
{
@@ -926,6 +993,9 @@ HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uin
{
USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
pSrc++;
+ pSrc++;
+ pSrc++;
+ pSrc++;
}
}
@@ -942,14 +1012,34 @@ HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uin
void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
{
uint32_t USBx_BASE = (uint32_t)USBx;
- uint32_t *pDest = (uint32_t *)dest;
+ uint8_t *pDest = dest;
+ uint32_t pData;
uint32_t i;
- uint32_t count32b = ((uint32_t)len + 3U) / 4U;
+ uint32_t count32b = (uint32_t)len >> 2U;
+ uint16_t remaining_bytes = len % 4U;
for (i = 0U; i < count32b; i++)
{
__UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
pDest++;
+ pDest++;
+ pDest++;
+ pDest++;
+ }
+
+ /* When Number of data is not word aligned, read the remaining byte */
+ if (remaining_bytes != 0U)
+ {
+ i = 0U;
+ __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
+
+ do
+ {
+ *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
+ i++;
+ pDest++;
+ remaining_bytes--;
+ } while (remaining_bytes != 0U);
}
return ((void *)pDest);
@@ -1062,7 +1152,7 @@ HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
* This parameter can be a value from 0 to 255
* @retval HAL status
*/
-HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
+HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
{
uint32_t USBx_BASE = (uint32_t)USBx;
@@ -1073,31 +1163,35 @@ HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t addres
}
/**
- * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
+ * @brief USB_DevConnect : Connect the USB device by enabling Rpu
* @param USBx Selected device
* @retval HAL status
*/
-HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
+HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t USBx_BASE = (uint32_t)USBx;
+ /* In case phy is stopped, ensure to ungate and restore the phy CLK */
+ USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
+
USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
- HAL_Delay(3U);
return HAL_OK;
}
/**
- * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
+ * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
* @param USBx Selected device
* @retval HAL status
*/
-HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
+HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t USBx_BASE = (uint32_t)USBx;
+ /* In case phy is stopped, ensure to ungate and restore the phy CLK */
+ USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
+
USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
- HAL_Delay(3U);
return HAL_OK;
}
@@ -1105,9 +1199,9 @@ HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
/**
* @brief USB_ReadInterrupts: return the global USB interrupt status
* @param USBx Selected device
- * @retval HAL status
+ * @retval USB Global Interrupt status
*/
-uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
+uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t tmpreg;
@@ -1118,9 +1212,26 @@ uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
}
/**
+ * @brief USB_ReadChInterrupts: return USB channel interrupt status
+ * @param USBx Selected device
+ * @param chnum Channel number
+ * @retval USB Channel Interrupt status
+ */
+uint32_t USB_ReadChInterrupts(USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
+{
+ uint32_t USBx_BASE = (uint32_t)USBx;
+ uint32_t tmpreg;
+
+ tmpreg = USBx_HC(chnum)->HCINT;
+ tmpreg &= USBx_HC(chnum)->HCINTMSK;
+
+ return tmpreg;
+}
+
+/**
* @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
* @param USBx Selected device
- * @retval HAL status
+ * @retval USB Device OUT EP interrupt status
*/
uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
{
@@ -1136,7 +1247,7 @@ uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
/**
* @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
* @param USBx Selected device
- * @retval HAL status
+ * @retval USB Device IN EP interrupt status
*/
uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
{
@@ -1177,7 +1288,9 @@ uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
{
uint32_t USBx_BASE = (uint32_t)USBx;
- uint32_t tmpreg, msk, emp;
+ uint32_t tmpreg;
+ uint32_t msk;
+ uint32_t emp;
msk = USBx_DEVICE->DIEPMSK;
emp = USBx_DEVICE->DIEPEMPMSK;
@@ -1190,12 +1303,12 @@ uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
/**
* @brief USB_ClearInterrupts: clear a USB interrupt
* @param USBx Selected device
- * @param interrupt interrupt flag
+ * @param interrupt flag
* @retval None
*/
void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
{
- USBx->GINTSTS |= interrupt;
+ USBx->GINTSTS &= interrupt;
}
/**
@@ -1216,7 +1329,7 @@ uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
* @param USBx Selected device
* @retval HAL status
*/
-HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
+HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t USBx_BASE = (uint32_t)USBx;
@@ -1273,17 +1386,18 @@ HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uin
*/
static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
{
- uint32_t count = 0U;
+ __IO uint32_t count = 0U;
/* Wait for AHB master IDLE state. */
do
{
- if (++count > 200000U)
+ count++;
+
+ if (count > 200000U)
{
return HAL_TIMEOUT;
}
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+ } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
/* Core Soft Reset */
count = 0U;
@@ -1291,12 +1405,13 @@ static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
do
{
- if (++count > 200000U)
+ count++;
+
+ if (count > 200000U)
{
return HAL_TIMEOUT;
}
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
+ } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
return HAL_OK;
}
@@ -1311,6 +1426,7 @@ static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
*/
HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
{
+ HAL_StatusTypeDef ret = HAL_OK;
uint32_t USBx_BASE = (uint32_t)USBx;
uint32_t i;
@@ -1326,7 +1442,7 @@ HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
if ((USBx->CID & (0x1U << 8)) != 0U)
{
- if (cfg.speed == USB_OTG_SPEED_FULL)
+ if (cfg.speed == USBH_FSLS_SPEED)
{
/* Force Device Enumeration to FS/LS mode only */
USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
@@ -1344,26 +1460,28 @@ HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
}
/* Make sure the FIFOs are flushed. */
- (void)USB_FlushTxFifo(USBx, 0x10U); /* all Tx FIFOs */
- (void)USB_FlushRxFifo(USBx);
+ if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
+ {
+ ret = HAL_ERROR;
+ }
+
+ if (USB_FlushRxFifo(USBx) != HAL_OK)
+ {
+ ret = HAL_ERROR;
+ }
/* Clear all pending HC Interrupts */
for (i = 0U; i < cfg.Host_channels; i++)
{
- USBx_HC(i)->HCINT = 0xFFFFFFFFU;
+ USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
USBx_HC(i)->HCINTMSK = 0U;
}
- /* Enable VBUS driving */
- (void)USB_DriveVbus(USBx, 1U);
-
- HAL_Delay(200U);
-
/* Disable all interrupts. */
USBx->GINTMSK = 0U;
/* Clear any pending interrupts */
- USBx->GINTSTS = 0xFFFFFFFFU;
+ USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
if ((USBx->CID & (0x1U << 8)) != 0U)
{
@@ -1391,7 +1509,7 @@ HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
- return HAL_OK;
+ return ret;
}
/**
@@ -1413,22 +1531,22 @@ HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
if (freq == HCFG_48_MHZ)
{
- USBx_HOST->HFIR = 48000U;
+ USBx_HOST->HFIR = HFIR_48_MHZ;
}
else if (freq == HCFG_6_MHZ)
{
- USBx_HOST->HFIR = 6000U;
+ USBx_HOST->HFIR = HFIR_6_MHZ;
}
else
{
- /* ... */
+ return HAL_ERROR;
}
return HAL_OK;
}
/**
-* @brief USB_OTG_ResetPort : Reset Host Port
+ * @brief USB_OTG_ResetPort : Reset Host Port
* @param USBx Selected device
* @retval HAL status
* @note (1)The application must wait at least 10 ms
@@ -1457,10 +1575,10 @@ HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
* @brief USB_DriveVbus : activate or de-activate vbus
* @param state VBUS state
* This parameter can be one of these values:
- * 0 : VBUS Active
- * 1 : VBUS Inactive
+ * 0 : Deactivate VBUS
+ * 1 : Activate VBUS
* @retval HAL status
-*/
+ */
HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state)
{
uint32_t USBx_BASE = (uint32_t)USBx;
@@ -1504,7 +1622,7 @@ uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx)
* @brief Return Host Current Frame number
* @param USBx Selected device
* @retval current frame number
-*/
+ */
uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t USBx_BASE = (uint32_t)USBx;
@@ -1533,23 +1651,21 @@ uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx)
* @arg EP_TYPE_BULK: Bulk type
* @arg EP_TYPE_INTR: Interrupt type
* @param mps Max Packet Size
- * This parameter can be a value from 0 to32K
+ * This parameter can be a value from 0 to 32K
* @retval HAL state
*/
-HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
- uint8_t ch_num,
- uint8_t epnum,
- uint8_t dev_address,
- uint8_t speed,
- uint8_t ep_type,
- uint16_t mps)
+HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
+ uint8_t epnum, uint8_t dev_address, uint8_t speed,
+ uint8_t ep_type, uint16_t mps)
{
HAL_StatusTypeDef ret = HAL_OK;
uint32_t USBx_BASE = (uint32_t)USBx;
- uint32_t HCcharEpDir, HCcharLowSpeed;
+ uint32_t HCcharEpDir;
+ uint32_t HCcharLowSpeed;
+ uint32_t HostCoreSpeed;
/* Clear old interrupt conditions for this host channel. */
- USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
+ USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
/* Enable channel interrupts required for this transfer. */
switch (ep_type)
@@ -1571,7 +1687,8 @@ HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
{
if ((USBx->CID & (0x1U << 8)) != 0U)
{
- USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
+ USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
+ USB_OTG_HCINTMSK_ACKM;
}
}
break;
@@ -1609,6 +1726,9 @@ HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
break;
}
+ /* Enable host channel Halt interrupt */
+ USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
+
/* Enable the top level host channel interrupt. */
USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
@@ -1625,7 +1745,10 @@ HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
HCcharEpDir = 0U;
}
- if (speed == HPRT0_PRTSPD_LOW_SPEED)
+ HostCoreSpeed = USB_GetHostSpeed(USBx);
+
+ /* LS device plugged to HUB */
+ if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
{
HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
}
@@ -1637,11 +1760,12 @@ HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
(((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
- ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | HCcharEpDir | HCcharLowSpeed;
+ ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
+ USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
- if (ep_type == EP_TYPE_INTR)
+ if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
{
- USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
+ USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
}
return ret;
@@ -1661,28 +1785,28 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe
{
uint32_t USBx_BASE = (uint32_t)USBx;
uint32_t ch_num = (uint32_t)hc->ch_num;
- static __IO uint32_t tmpreg = 0U;
+ __IO uint32_t tmpreg;
uint8_t is_oddframe;
uint16_t len_words;
uint16_t num_packets;
- uint16_t max_hc_pkt_count = 256U;
+ uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
if (((USBx->CID & (0x1U << 8)) != 0U) && (hc->speed == USBH_HS_SPEED))
{
+ /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
+ if ((dma == 1U) && ((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)))
+ {
+ USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
+ USB_OTG_HCINTMSK_ACKM |
+ USB_OTG_HCINTMSK_NAKM);
+ }
+
if ((dma == 0U) && (hc->do_ping == 1U))
{
(void)USB_DoPing(USBx, hc->ch_num);
return HAL_OK;
}
- else if (dma == 1U)
- {
- USBx_HC(ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
- hc->do_ping = 0U;
- }
- else
- {
- /* ... */
- }
+
}
/* Compute the expected number of packets associated to the transfer */
@@ -1693,20 +1817,29 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe
if (num_packets > max_hc_pkt_count)
{
num_packets = max_hc_pkt_count;
- hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
+ hc->XferSize = (uint32_t)num_packets * hc->max_packet;
}
}
else
{
num_packets = 1U;
}
+
+ /*
+ * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
+ * max_packet size.
+ */
if (hc->ep_is_in != 0U)
{
- hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
+ hc->XferSize = (uint32_t)num_packets * hc->max_packet;
+ }
+ else
+ {
+ hc->XferSize = hc->xfer_len;
}
/* Initialize the HCTSIZn register */
- USBx_HC(ch_num)->HCTSIZ = (hc->xfer_len & USB_OTG_HCTSIZ_XFRSIZ) |
+ USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
(((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
(((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
@@ -1736,45 +1869,47 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe
tmpreg |= USB_OTG_HCCHAR_CHENA;
USBx_HC(ch_num)->HCCHAR = tmpreg;
- if (dma == 0U) /* Slave mode */
+ if (dma != 0U) /* dma mode */
{
- if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
- {
- switch (hc->ep_type)
- {
- /* Non periodic transfer */
- case EP_TYPE_CTRL:
- case EP_TYPE_BULK:
+ return HAL_OK;
+ }
- len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
+ if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
+ {
+ switch (hc->ep_type)
+ {
+ /* Non periodic transfer */
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
- /* check if there is enough space in FIFO space */
- if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
- {
- /* need to process data in nptxfempty interrupt */
- USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
- }
- break;
+ len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
- /* Periodic transfer */
- case EP_TYPE_INTR:
- case EP_TYPE_ISOC:
- len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
- /* check if there is enough space in FIFO space */
- if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
- {
- /* need to process data in ptxfempty interrupt */
- USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
- }
- break;
+ /* check if there is enough space in FIFO space */
+ if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
+ {
+ /* need to process data in nptxfempty interrupt */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
+ }
+ break;
- default:
- break;
- }
+ /* Periodic transfer */
+ case EP_TYPE_INTR:
+ case EP_TYPE_ISOC:
+ len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
+ /* check if there is enough space in FIFO space */
+ if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
+ {
+ /* need to process data in ptxfempty interrupt */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
+ }
+ break;
- /* Write packet into the Tx FIFO. */
- (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
+ default:
+ break;
}
+
+ /* Write packet into the Tx FIFO. */
+ (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
}
return HAL_OK;
@@ -1803,27 +1938,41 @@ HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
{
uint32_t USBx_BASE = (uint32_t)USBx;
uint32_t hcnum = (uint32_t)hc_num;
- uint32_t count = 0U;
+ __IO uint32_t count = 0U;
uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
+ uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
+
+ if (((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) &&
+ (ChannelEna == 0U))
+ {
+ return HAL_OK;
+ }
/* Check for space in the request queue to issue the halt. */
if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
{
USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
- if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
+ if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
{
- USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
- USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
- do
+ if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
{
- if (++count > 1000U)
+ USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ do
{
- break;
- }
+ count++;
+
+ if (count > 1000U)
+ {
+ break;
+ }
+ } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ }
+ else
+ {
+ USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
}
- while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
}
else
{
@@ -1838,15 +1987,15 @@ HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
{
USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
do
{
- if (++count > 1000U)
+ count++;
+
+ if (count > 1000U)
{
break;
}
- }
- while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
}
else
{
@@ -1890,16 +2039,24 @@ HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
*/
HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
{
+ HAL_StatusTypeDef ret = HAL_OK;
uint32_t USBx_BASE = (uint32_t)USBx;
- uint32_t count = 0U;
+ __IO uint32_t count = 0U;
uint32_t value;
uint32_t i;
(void)USB_DisableGlobalInt(USBx);
- /* Flush FIFO */
- (void)USB_FlushTxFifo(USBx, 0x10U);
- (void)USB_FlushRxFifo(USBx);
+ /* Flush USB FIFO */
+ if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
+ {
+ ret = HAL_ERROR;
+ }
+
+ if (USB_FlushRxFifo(USBx) != HAL_OK)
+ {
+ ret = HAL_ERROR;
+ }
/* Flush out any leftover queued requests. */
for (i = 0U; i <= 15U; i++)
@@ -1922,21 +2079,22 @@ HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
do
{
- if (++count > 1000U)
+ count++;
+
+ if (count > 1000U)
{
break;
}
- }
- while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
}
/* Clear any pending Host interrupts */
- USBx_HOST->HAINT = 0xFFFFFFFFU;
- USBx->GINTSTS = 0xFFFFFFFFU;
+ USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
+ USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
(void)USB_EnableGlobalInt(USBx);
- return HAL_OK;
+ return ret;
}
/**
@@ -1973,7 +2131,6 @@ HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
}
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
-
/**
* @}
*/
@@ -1987,5 +2144,3 @@ HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
/**
* @}
*/
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/