Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:10

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_ll_usb.c
0004   * @author  MCD Application Team
0005   * @brief   USB Low Layer HAL module driver.
0006   *
0007   *          This file provides firmware functions to manage the following
0008   *          functionalities of the USB Peripheral Controller:
0009   *           + Initialization/de-initialization functions
0010   *           + I/O operation functions
0011   *           + Peripheral Control functions
0012   *           + Peripheral State functions
0013   *
0014   ******************************************************************************
0015   * @attention
0016   *
0017   * Copyright (c) 2017 STMicroelectronics.
0018   * All rights reserved.
0019   *
0020   * This software is licensed under terms that can be found in the LICENSE file
0021   * in the root directory of this software component.
0022   * If no LICENSE file comes with this software, it is provided AS-IS.
0023   *
0024   ******************************************************************************
0025   @verbatim
0026   ==============================================================================
0027                     ##### How to use this driver #####
0028   ==============================================================================
0029     [..]
0030       (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
0031 
0032       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
0033 
0034       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
0035 
0036   @endverbatim
0037 
0038   ******************************************************************************
0039   */
0040 
0041 /* Includes ------------------------------------------------------------------*/
0042 #include "stm32h7xx_hal.h"
0043 
0044 /** @addtogroup STM32H7xx_LL_USB_DRIVER
0045   * @{
0046   */
0047 
0048 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
0049 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
0050 /* Private typedef -----------------------------------------------------------*/
0051 /* Private define ------------------------------------------------------------*/
0052 /* Private macro -------------------------------------------------------------*/
0053 /* Private variables ---------------------------------------------------------*/
0054 /* Private function prototypes -----------------------------------------------*/
0055 /* Private functions ---------------------------------------------------------*/
0056 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
0057 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
0058 
0059 /* Exported functions --------------------------------------------------------*/
0060 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
0061   * @ingroup RTEMSBSPsARMSTM32H7
0062   * @{
0063   */
0064 
0065 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
0066   * @ingroup RTEMSBSPsARMSTM32H7
0067   *  @brief    Initialization and Configuration functions
0068   *
0069 @verbatim
0070  ===============================================================================
0071                       ##### Initialization/de-initialization functions #####
0072  ===============================================================================
0073 
0074 @endverbatim
0075   * @{
0076   */
0077 
0078 /**
0079   * @brief  Initializes the USB Core
0080   * @param  USBx USB Instance
0081   * @param  cfg pointer to a USB_OTG_CfgTypeDef structure that contains
0082   *         the configuration information for the specified USBx peripheral.
0083   * @retval HAL status
0084   */
0085 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
0086 {
0087   HAL_StatusTypeDef ret;
0088   if (cfg.phy_itface == USB_OTG_ULPI_PHY)
0089   {
0090     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
0091 
0092     /* Init The ULPI Interface */
0093     USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
0094 
0095     /* Select vbus source */
0096     USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
0097     if (cfg.use_external_vbus == 1U)
0098     {
0099       USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
0100     }
0101 
0102     /* Reset after a PHY select */
0103     ret = USB_CoreReset(USBx);
0104   }
0105   else /* FS interface (embedded Phy) */
0106   {
0107     /* Select FS Embedded PHY */
0108     USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
0109 
0110     /* Reset after a PHY select */
0111     ret = USB_CoreReset(USBx);
0112 
0113     if (cfg.battery_charging_enable == 0U)
0114     {
0115       /* Activate the USB Transceiver */
0116       USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
0117     }
0118     else
0119     {
0120       /* Deactivate the USB Transceiver */
0121       USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
0122     }
0123   }
0124 
0125   if (cfg.dma_enable == 1U)
0126   {
0127     /* make sure to reserve 18 fifo Locations for DMA buffers */
0128     USBx->GDFIFOCFG &= ~(0xFFFFU << 16);
0129     USBx->GDFIFOCFG |= 0x3EEU << 16;
0130 
0131     USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
0132     USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
0133   }
0134 
0135   return ret;
0136 }
0137 
0138 
0139 /**
0140   * @brief  Set the USB turnaround time
0141   * @param  USBx USB Instance
0142   * @param  hclk: AHB clock frequency
0143   * @retval USB turnaround time In PHY Clocks number
0144   */
0145 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
0146                                         uint32_t hclk, uint8_t speed)
0147 {
0148   uint32_t UsbTrd;
0149 
0150   /* The USBTRD is configured according to the tables below, depending on AHB frequency
0151   used by application. In the low AHB frequency range it is used to stretch enough the USB response
0152   time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
0153   latency to the Data FIFO */
0154   if (speed == USBD_FS_SPEED)
0155   {
0156     if ((hclk >= 14200000U) && (hclk < 15000000U))
0157     {
0158       /* hclk Clock Range between 14.2-15 MHz */
0159       UsbTrd = 0xFU;
0160     }
0161     else if ((hclk >= 15000000U) && (hclk < 16000000U))
0162     {
0163       /* hclk Clock Range between 15-16 MHz */
0164       UsbTrd = 0xEU;
0165     }
0166     else if ((hclk >= 16000000U) && (hclk < 17200000U))
0167     {
0168       /* hclk Clock Range between 16-17.2 MHz */
0169       UsbTrd = 0xDU;
0170     }
0171     else if ((hclk >= 17200000U) && (hclk < 18500000U))
0172     {
0173       /* hclk Clock Range between 17.2-18.5 MHz */
0174       UsbTrd = 0xCU;
0175     }
0176     else if ((hclk >= 18500000U) && (hclk < 20000000U))
0177     {
0178       /* hclk Clock Range between 18.5-20 MHz */
0179       UsbTrd = 0xBU;
0180     }
0181     else if ((hclk >= 20000000U) && (hclk < 21800000U))
0182     {
0183       /* hclk Clock Range between 20-21.8 MHz */
0184       UsbTrd = 0xAU;
0185     }
0186     else if ((hclk >= 21800000U) && (hclk < 24000000U))
0187     {
0188       /* hclk Clock Range between 21.8-24 MHz */
0189       UsbTrd = 0x9U;
0190     }
0191     else if ((hclk >= 24000000U) && (hclk < 27700000U))
0192     {
0193       /* hclk Clock Range between 24-27.7 MHz */
0194       UsbTrd = 0x8U;
0195     }
0196     else if ((hclk >= 27700000U) && (hclk < 32000000U))
0197     {
0198       /* hclk Clock Range between 27.7-32 MHz */
0199       UsbTrd = 0x7U;
0200     }
0201     else /* if(hclk >= 32000000) */
0202     {
0203       /* hclk Clock Range between 32-200 MHz */
0204       UsbTrd = 0x6U;
0205     }
0206   }
0207   else if (speed == USBD_HS_SPEED)
0208   {
0209     UsbTrd = USBD_HS_TRDT_VALUE;
0210   }
0211   else
0212   {
0213     UsbTrd = USBD_DEFAULT_TRDT_VALUE;
0214   }
0215 
0216   USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
0217   USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
0218 
0219   return HAL_OK;
0220 }
0221 
0222 /**
0223   * @brief  USB_EnableGlobalInt
0224   *         Enables the controller's Global Int in the AHB Config reg
0225   * @param  USBx  Selected device
0226   * @retval HAL status
0227   */
0228 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
0229 {
0230   USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
0231   return HAL_OK;
0232 }
0233 
0234 /**
0235   * @brief  USB_DisableGlobalInt
0236   *         Disable the controller's Global Int in the AHB Config reg
0237   * @param  USBx  Selected device
0238   * @retval HAL status
0239   */
0240 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
0241 {
0242   USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
0243   return HAL_OK;
0244 }
0245 
0246 /**
0247   * @brief  USB_SetCurrentMode Set functional mode
0248   * @param  USBx  Selected device
0249   * @param  mode  current core mode
0250   *          This parameter can be one of these values:
0251   *            @arg USB_DEVICE_MODE Peripheral mode
0252   *            @arg USB_HOST_MODE Host mode
0253   * @retval HAL status
0254   */
0255 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
0256 {
0257   uint32_t ms = 0U;
0258 
0259   USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
0260 
0261   if (mode == USB_HOST_MODE)
0262   {
0263     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
0264 
0265     do
0266     {
0267       HAL_Delay(10U);
0268       ms += 10U;
0269     } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
0270   }
0271   else if (mode == USB_DEVICE_MODE)
0272   {
0273     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
0274 
0275     do
0276     {
0277       HAL_Delay(10U);
0278       ms += 10U;
0279     } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
0280   }
0281   else
0282   {
0283     return HAL_ERROR;
0284   }
0285 
0286   if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
0287   {
0288     return HAL_ERROR;
0289   }
0290 
0291   return HAL_OK;
0292 }
0293 
0294 /**
0295   * @brief  USB_DevInit Initializes the USB_OTG controller registers
0296   *         for device mode
0297   * @param  USBx  Selected device
0298   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
0299   *         the configuration information for the specified USBx peripheral.
0300   * @retval HAL status
0301   */
0302 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
0303 {
0304   HAL_StatusTypeDef ret = HAL_OK;
0305   uint32_t USBx_BASE = (uint32_t)USBx;
0306   uint32_t i;
0307 
0308   for (i = 0U; i < 15U; i++)
0309   {
0310     USBx->DIEPTXF[i] = 0U;
0311   }
0312 
0313   /* VBUS Sensing setup */
0314   if (cfg.vbus_sensing_enable == 0U)
0315   {
0316     USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
0317 
0318     /* Deactivate VBUS Sensing B */
0319     USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
0320 
0321     /* B-peripheral session valid override enable */
0322     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
0323     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
0324   }
0325   else
0326   {
0327     /* Enable HW VBUS sensing */
0328     USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
0329   }
0330 
0331   /* Restart the Phy Clock */
0332   USBx_PCGCCTL = 0U;
0333 
0334   if (cfg.phy_itface == USB_OTG_ULPI_PHY)
0335   {
0336     if (cfg.speed == USBD_HS_SPEED)
0337     {
0338       /* Set Core speed to High speed mode */
0339       (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
0340     }
0341     else
0342     {
0343       /* Set Core speed to Full speed mode */
0344       (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
0345     }
0346   }
0347   else
0348   {
0349     /* Set Core speed to Full speed mode */
0350     (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
0351   }
0352 
0353   /* Flush the FIFOs */
0354   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
0355   {
0356     ret = HAL_ERROR;
0357   }
0358 
0359   if (USB_FlushRxFifo(USBx) != HAL_OK)
0360   {
0361     ret = HAL_ERROR;
0362   }
0363 
0364   /* Clear all pending Device Interrupts */
0365   USBx_DEVICE->DIEPMSK = 0U;
0366   USBx_DEVICE->DOEPMSK = 0U;
0367   USBx_DEVICE->DAINTMSK = 0U;
0368 
0369   for (i = 0U; i < cfg.dev_endpoints; i++)
0370   {
0371     if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
0372     {
0373       if (i == 0U)
0374       {
0375         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
0376       }
0377       else
0378       {
0379         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
0380       }
0381     }
0382     else
0383     {
0384       USBx_INEP(i)->DIEPCTL = 0U;
0385     }
0386 
0387     USBx_INEP(i)->DIEPTSIZ = 0U;
0388     USBx_INEP(i)->DIEPINT  = 0xFB7FU;
0389   }
0390 
0391   for (i = 0U; i < cfg.dev_endpoints; i++)
0392   {
0393     if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
0394     {
0395       if (i == 0U)
0396       {
0397         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
0398       }
0399       else
0400       {
0401         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
0402       }
0403     }
0404     else
0405     {
0406       USBx_OUTEP(i)->DOEPCTL = 0U;
0407     }
0408 
0409     USBx_OUTEP(i)->DOEPTSIZ = 0U;
0410     USBx_OUTEP(i)->DOEPINT  = 0xFB7FU;
0411   }
0412 
0413   USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
0414 
0415   /* Disable all interrupts. */
0416   USBx->GINTMSK = 0U;
0417 
0418   /* Clear any pending interrupts */
0419   USBx->GINTSTS = 0xBFFFFFFFU;
0420 
0421   /* Enable the common interrupts */
0422   if (cfg.dma_enable == 0U)
0423   {
0424     USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
0425   }
0426 
0427   /* Enable interrupts matching to the Device mode ONLY */
0428   USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
0429                    USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
0430                    USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM |
0431                    USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
0432 
0433   if (cfg.Sof_enable != 0U)
0434   {
0435     USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
0436   }
0437 
0438   if (cfg.vbus_sensing_enable == 1U)
0439   {
0440     USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
0441   }
0442 
0443   return ret;
0444 }
0445 
0446 /**
0447   * @brief  USB_FlushTxFifo Flush a Tx FIFO
0448   * @param  USBx  Selected device
0449   * @param  num  FIFO number
0450   *         This parameter can be a value from 1 to 15
0451             15 means Flush all Tx FIFOs
0452   * @retval HAL status
0453   */
0454 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
0455 {
0456   __IO uint32_t count = 0U;
0457 
0458   /* Wait for AHB master IDLE state. */
0459   do
0460   {
0461     count++;
0462 
0463     if (count > HAL_USB_TIMEOUT)
0464     {
0465       return HAL_TIMEOUT;
0466     }
0467   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
0468 
0469   /* Flush TX Fifo */
0470   count = 0U;
0471   USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
0472 
0473   do
0474   {
0475     count++;
0476 
0477     if (count > HAL_USB_TIMEOUT)
0478     {
0479       return HAL_TIMEOUT;
0480     }
0481   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
0482 
0483   return HAL_OK;
0484 }
0485 
0486 /**
0487   * @brief  USB_FlushRxFifo  Flush Rx FIFO
0488   * @param  USBx  Selected device
0489   * @retval HAL status
0490   */
0491 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
0492 {
0493   __IO uint32_t count = 0U;
0494 
0495   /* Wait for AHB master IDLE state. */
0496   do
0497   {
0498     count++;
0499 
0500     if (count > HAL_USB_TIMEOUT)
0501     {
0502       return HAL_TIMEOUT;
0503     }
0504   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
0505 
0506   /* Flush RX Fifo */
0507   count = 0U;
0508   USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
0509 
0510   do
0511   {
0512     count++;
0513 
0514     if (count > HAL_USB_TIMEOUT)
0515     {
0516       return HAL_TIMEOUT;
0517     }
0518   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
0519 
0520   return HAL_OK;
0521 }
0522 
0523 /**
0524   * @brief  USB_SetDevSpeed  Initializes the DevSpd field of DCFG register
0525   *         depending the PHY type and the enumeration speed of the device.
0526   * @param  USBx  Selected device
0527   * @param  speed  device speed
0528   *          This parameter can be one of these values:
0529   *            @arg USB_OTG_SPEED_HIGH: High speed mode
0530   *            @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
0531   *            @arg USB_OTG_SPEED_FULL: Full speed mode
0532   * @retval  Hal status
0533   */
0534 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
0535 {
0536   uint32_t USBx_BASE = (uint32_t)USBx;
0537 
0538   USBx_DEVICE->DCFG |= speed;
0539   return HAL_OK;
0540 }
0541 
0542 /**
0543   * @brief  USB_GetDevSpeed  Return the Dev Speed
0544   * @param  USBx  Selected device
0545   * @retval speed  device speed
0546   *          This parameter can be one of these values:
0547   *            @arg USBD_HS_SPEED: High speed mode
0548   *            @arg USBD_FS_SPEED: Full speed mode
0549   */
0550 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
0551 {
0552   uint32_t USBx_BASE = (uint32_t)USBx;
0553   uint8_t speed;
0554   uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
0555 
0556   if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
0557   {
0558     speed = USBD_HS_SPEED;
0559   }
0560   else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
0561            (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
0562   {
0563     speed = USBD_FS_SPEED;
0564   }
0565   else
0566   {
0567     speed = 0xFU;
0568   }
0569 
0570   return speed;
0571 }
0572 
0573 /**
0574   * @brief  Activate and configure an endpoint
0575   * @param  USBx  Selected device
0576   * @param  ep pointer to endpoint structure
0577   * @retval HAL status
0578   */
0579 HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
0580 {
0581   uint32_t USBx_BASE = (uint32_t)USBx;
0582   uint32_t epnum = (uint32_t)ep->num;
0583 
0584   if (ep->is_in == 1U)
0585   {
0586     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
0587 
0588     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
0589     {
0590       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
0591                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
0592                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
0593                                    USB_OTG_DIEPCTL_USBAEP;
0594     }
0595   }
0596   else
0597   {
0598     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
0599 
0600     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
0601     {
0602       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
0603                                     ((uint32_t)ep->type << 18) |
0604                                     USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
0605                                     USB_OTG_DOEPCTL_USBAEP;
0606     }
0607   }
0608   return HAL_OK;
0609 }
0610 
0611 /**
0612   * @brief  Activate and configure a dedicated endpoint
0613   * @param  USBx  Selected device
0614   * @param  ep pointer to endpoint structure
0615   * @retval HAL status
0616   */
0617 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
0618 {
0619   uint32_t USBx_BASE = (uint32_t)USBx;
0620   uint32_t epnum = (uint32_t)ep->num;
0621 
0622   /* Read DEPCTLn register */
0623   if (ep->is_in == 1U)
0624   {
0625     if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
0626     {
0627       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
0628                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
0629                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
0630                                    USB_OTG_DIEPCTL_USBAEP;
0631     }
0632 
0633     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
0634   }
0635   else
0636   {
0637     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
0638     {
0639       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
0640                                     ((uint32_t)ep->type << 18) | (epnum << 22) |
0641                                     USB_OTG_DOEPCTL_USBAEP;
0642     }
0643 
0644     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
0645   }
0646 
0647   return HAL_OK;
0648 }
0649 
0650 /**
0651   * @brief  De-activate and de-initialize an endpoint
0652   * @param  USBx  Selected device
0653   * @param  ep pointer to endpoint structure
0654   * @retval HAL status
0655   */
0656 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
0657 {
0658   uint32_t USBx_BASE = (uint32_t)USBx;
0659   uint32_t epnum = (uint32_t)ep->num;
0660 
0661   /* Read DEPCTLn register */
0662   if (ep->is_in == 1U)
0663   {
0664     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
0665     {
0666       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
0667       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
0668     }
0669 
0670     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
0671     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
0672     USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
0673                                    USB_OTG_DIEPCTL_MPSIZ |
0674                                    USB_OTG_DIEPCTL_TXFNUM |
0675                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
0676                                    USB_OTG_DIEPCTL_EPTYP);
0677   }
0678   else
0679   {
0680     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
0681     {
0682       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
0683       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
0684     }
0685 
0686     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
0687     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
0688     USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
0689                                     USB_OTG_DOEPCTL_MPSIZ |
0690                                     USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
0691                                     USB_OTG_DOEPCTL_EPTYP);
0692   }
0693 
0694   return HAL_OK;
0695 }
0696 
0697 /**
0698   * @brief  De-activate and de-initialize a dedicated endpoint
0699   * @param  USBx  Selected device
0700   * @param  ep pointer to endpoint structure
0701   * @retval HAL status
0702   */
0703 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
0704 {
0705   uint32_t USBx_BASE = (uint32_t)USBx;
0706   uint32_t epnum = (uint32_t)ep->num;
0707 
0708   /* Read DEPCTLn register */
0709   if (ep->is_in == 1U)
0710   {
0711     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
0712     {
0713       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_SNAK;
0714       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_EPDIS;
0715     }
0716 
0717     USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
0718     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
0719   }
0720   else
0721   {
0722     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
0723     {
0724       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_SNAK;
0725       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_EPDIS;
0726     }
0727 
0728     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
0729     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
0730   }
0731 
0732   return HAL_OK;
0733 }
0734 
0735 /**
0736   * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
0737   * @param  USBx  Selected device
0738   * @param  ep pointer to endpoint structure
0739   * @param  dma USB dma enabled or disabled
0740   *          This parameter can be one of these values:
0741   *           0 : DMA feature not used
0742   *           1 : DMA feature used
0743   * @retval HAL status
0744   */
0745 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
0746 {
0747   uint32_t USBx_BASE = (uint32_t)USBx;
0748   uint32_t epnum = (uint32_t)ep->num;
0749   uint16_t pktcnt;
0750 
0751   /* IN endpoint */
0752   if (ep->is_in == 1U)
0753   {
0754     /* Zero Length Packet? */
0755     if (ep->xfer_len == 0U)
0756     {
0757       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
0758       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
0759       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
0760     }
0761     else
0762     {
0763       /* Program the transfer size and packet count
0764       * as follows: xfersize = N * maxpacket +
0765       * short_packet pktcnt = N + (short_packet
0766       * exist ? 1 : 0)
0767       */
0768       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
0769       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
0770 
0771       if (epnum == 0U)
0772       {
0773         if (ep->xfer_len > ep->maxpacket)
0774         {
0775           ep->xfer_len = ep->maxpacket;
0776         }
0777 
0778         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
0779       }
0780       else
0781       {
0782         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
0783                                        (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
0784       }
0785 
0786       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
0787 
0788       if (ep->type == EP_TYPE_ISOC)
0789       {
0790         USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
0791         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
0792       }
0793     }
0794 
0795     if (dma == 1U)
0796     {
0797       if ((uint32_t)ep->dma_addr != 0U)
0798       {
0799         USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
0800       }
0801 
0802       if (ep->type == EP_TYPE_ISOC)
0803       {
0804         if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
0805         {
0806           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
0807         }
0808         else
0809         {
0810           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
0811         }
0812       }
0813 
0814       /* EP enable, IN data in FIFO */
0815       USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
0816     }
0817     else
0818     {
0819       /* EP enable, IN data in FIFO */
0820       USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
0821 
0822       if (ep->type != EP_TYPE_ISOC)
0823       {
0824         /* Enable the Tx FIFO Empty Interrupt for this EP */
0825         if (ep->xfer_len > 0U)
0826         {
0827           USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
0828         }
0829       }
0830       else
0831       {
0832         if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
0833         {
0834           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
0835         }
0836         else
0837         {
0838           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
0839         }
0840 
0841         (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
0842       }
0843     }
0844   }
0845   else /* OUT endpoint */
0846   {
0847     /* Program the transfer size and packet count as follows:
0848     * pktcnt = N
0849     * xfersize = N * maxpacket
0850     */
0851     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
0852     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
0853 
0854     if (epnum == 0U)
0855     {
0856       if (ep->xfer_len > 0U)
0857       {
0858         ep->xfer_len = ep->maxpacket;
0859       }
0860 
0861       /* Store transfer size, for EP0 this is equal to endpoint max packet size */
0862       ep->xfer_size = ep->maxpacket;
0863 
0864       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
0865       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
0866     }
0867     else
0868     {
0869       if (ep->xfer_len == 0U)
0870       {
0871         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
0872         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
0873       }
0874       else
0875       {
0876         pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
0877         ep->xfer_size = ep->maxpacket * pktcnt;
0878 
0879         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
0880         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
0881       }
0882     }
0883 
0884     if (dma == 1U)
0885     {
0886       if ((uint32_t)ep->xfer_buff != 0U)
0887       {
0888         USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
0889       }
0890     }
0891 
0892     if (ep->type == EP_TYPE_ISOC)
0893     {
0894       if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
0895       {
0896         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
0897       }
0898       else
0899       {
0900         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
0901       }
0902     }
0903     /* EP enable */
0904     USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
0905   }
0906 
0907   return HAL_OK;
0908 }
0909 
0910 
0911 /**
0912    * @brief  USB_EPStoptXfer  Stop transfer on an EP
0913    * @param  USBx  usb device instance
0914    * @param  ep pointer to endpoint structure
0915    * @retval HAL status
0916    */
0917 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
0918 {
0919   __IO uint32_t count = 0U;
0920   HAL_StatusTypeDef ret = HAL_OK;
0921   uint32_t USBx_BASE = (uint32_t)USBx;
0922 
0923   /* IN endpoint */
0924   if (ep->is_in == 1U)
0925   {
0926     /* EP enable, IN data in FIFO */
0927     if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
0928     {
0929       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
0930       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
0931 
0932       do
0933       {
0934         count++;
0935 
0936         if (count > 10000U)
0937         {
0938           ret = HAL_ERROR;
0939           break;
0940         }
0941       } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) ==  USB_OTG_DIEPCTL_EPENA);
0942     }
0943   }
0944   else /* OUT endpoint */
0945   {
0946     if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
0947     {
0948       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
0949       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
0950 
0951       do
0952       {
0953         count++;
0954 
0955         if (count > 10000U)
0956         {
0957           ret = HAL_ERROR;
0958           break;
0959         }
0960       } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) ==  USB_OTG_DOEPCTL_EPENA);
0961     }
0962   }
0963 
0964   return ret;
0965 }
0966 
0967 
0968 /**
0969   * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
0970   *         with the EP/channel
0971   * @param  USBx  Selected device
0972   * @param  src   pointer to source buffer
0973   * @param  ch_ep_num  endpoint or host channel number
0974   * @param  len  Number of bytes to write
0975   * @param  dma USB dma enabled or disabled
0976   *          This parameter can be one of these values:
0977   *           0 : DMA feature not used
0978   *           1 : DMA feature used
0979   * @retval HAL status
0980   */
0981 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
0982                                   uint8_t ch_ep_num, uint16_t len, uint8_t dma)
0983 {
0984   uint32_t USBx_BASE = (uint32_t)USBx;
0985   uint8_t *pSrc = src;
0986   uint32_t count32b;
0987   uint32_t i;
0988 
0989   if (dma == 0U)
0990   {
0991     count32b = ((uint32_t)len + 3U) / 4U;
0992     for (i = 0U; i < count32b; i++)
0993     {
0994       USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
0995       pSrc++;
0996       pSrc++;
0997       pSrc++;
0998       pSrc++;
0999     }
1000   }
1001 
1002   return HAL_OK;
1003 }
1004 
1005 /**
1006   * @brief  USB_ReadPacket : read a packet from the RX FIFO
1007   * @param  USBx  Selected device
1008   * @param  dest  source pointer
1009   * @param  len  Number of bytes to read
1010   * @retval pointer to destination buffer
1011   */
1012 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1013 {
1014   uint32_t USBx_BASE = (uint32_t)USBx;
1015   uint8_t *pDest = dest;
1016   uint32_t pData;
1017   uint32_t i;
1018   uint32_t count32b = (uint32_t)len >> 2U;
1019   uint16_t remaining_bytes = len % 4U;
1020 
1021   for (i = 0U; i < count32b; i++)
1022   {
1023     __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1024     pDest++;
1025     pDest++;
1026     pDest++;
1027     pDest++;
1028   }
1029 
1030   /* When Number of data is not word aligned, read the remaining byte */
1031   if (remaining_bytes != 0U)
1032   {
1033     i = 0U;
1034     __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1035 
1036     do
1037     {
1038       *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1039       i++;
1040       pDest++;
1041       remaining_bytes--;
1042     } while (remaining_bytes != 0U);
1043   }
1044 
1045   return ((void *)pDest);
1046 }
1047 
1048 /**
1049   * @brief  USB_EPSetStall : set a stall condition over an EP
1050   * @param  USBx  Selected device
1051   * @param  ep pointer to endpoint structure
1052   * @retval HAL status
1053   */
1054 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1055 {
1056   uint32_t USBx_BASE = (uint32_t)USBx;
1057   uint32_t epnum = (uint32_t)ep->num;
1058 
1059   if (ep->is_in == 1U)
1060   {
1061     if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1062     {
1063       USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1064     }
1065     USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1066   }
1067   else
1068   {
1069     if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1070     {
1071       USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1072     }
1073     USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1074   }
1075 
1076   return HAL_OK;
1077 }
1078 
1079 /**
1080   * @brief  USB_EPClearStall : Clear a stall condition over an EP
1081   * @param  USBx  Selected device
1082   * @param  ep pointer to endpoint structure
1083   * @retval HAL status
1084   */
1085 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1086 {
1087   uint32_t USBx_BASE = (uint32_t)USBx;
1088   uint32_t epnum = (uint32_t)ep->num;
1089 
1090   if (ep->is_in == 1U)
1091   {
1092     USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1093     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1094     {
1095       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1096     }
1097   }
1098   else
1099   {
1100     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1101     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1102     {
1103       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1104     }
1105   }
1106   return HAL_OK;
1107 }
1108 
1109 /**
1110   * @brief  USB_StopDevice : Stop the usb device mode
1111   * @param  USBx  Selected device
1112   * @retval HAL status
1113   */
1114 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1115 {
1116   HAL_StatusTypeDef ret;
1117   uint32_t USBx_BASE = (uint32_t)USBx;
1118   uint32_t i;
1119 
1120   /* Clear Pending interrupt */
1121   for (i = 0U; i < 15U; i++)
1122   {
1123     USBx_INEP(i)->DIEPINT = 0xFB7FU;
1124     USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1125   }
1126 
1127   /* Clear interrupt masks */
1128   USBx_DEVICE->DIEPMSK  = 0U;
1129   USBx_DEVICE->DOEPMSK  = 0U;
1130   USBx_DEVICE->DAINTMSK = 0U;
1131 
1132   /* Flush the FIFO */
1133   ret = USB_FlushRxFifo(USBx);
1134   if (ret != HAL_OK)
1135   {
1136     return ret;
1137   }
1138 
1139   ret = USB_FlushTxFifo(USBx,  0x10U);
1140   if (ret != HAL_OK)
1141   {
1142     return ret;
1143   }
1144 
1145   return ret;
1146 }
1147 
1148 /**
1149   * @brief  USB_SetDevAddress : Stop the usb device mode
1150   * @param  USBx  Selected device
1151   * @param  address  new device address to be assigned
1152   *          This parameter can be a value from 0 to 255
1153   * @retval HAL status
1154   */
1155 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1156 {
1157   uint32_t USBx_BASE = (uint32_t)USBx;
1158 
1159   USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1160   USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1161 
1162   return HAL_OK;
1163 }
1164 
1165 /**
1166   * @brief  USB_DevConnect : Connect the USB device by enabling Rpu
1167   * @param  USBx  Selected device
1168   * @retval HAL status
1169   */
1170 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1171 {
1172   uint32_t USBx_BASE = (uint32_t)USBx;
1173 
1174   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1175   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1176 
1177   USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1178 
1179   return HAL_OK;
1180 }
1181 
1182 /**
1183   * @brief  USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1184   * @param  USBx  Selected device
1185   * @retval HAL status
1186   */
1187 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1188 {
1189   uint32_t USBx_BASE = (uint32_t)USBx;
1190 
1191   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1192   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1193 
1194   USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1195 
1196   return HAL_OK;
1197 }
1198 
1199 /**
1200   * @brief  USB_ReadInterrupts: return the global USB interrupt status
1201   * @param  USBx  Selected device
1202   * @retval USB Global Interrupt status
1203   */
1204 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1205 {
1206   uint32_t tmpreg;
1207 
1208   tmpreg = USBx->GINTSTS;
1209   tmpreg &= USBx->GINTMSK;
1210 
1211   return tmpreg;
1212 }
1213 
1214 /**
1215   * @brief  USB_ReadChInterrupts: return USB channel interrupt status
1216   * @param  USBx  Selected device
1217   * @param  chnum Channel number
1218   * @retval USB Channel Interrupt status
1219   */
1220 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1221 {
1222   uint32_t USBx_BASE = (uint32_t)USBx;
1223   uint32_t tmpreg;
1224 
1225   tmpreg = USBx_HC(chnum)->HCINT;
1226   tmpreg &= USBx_HC(chnum)->HCINTMSK;
1227 
1228   return tmpreg;
1229 }
1230 
1231 /**
1232   * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1233   * @param  USBx  Selected device
1234   * @retval USB Device OUT EP interrupt status
1235   */
1236 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1237 {
1238   uint32_t USBx_BASE = (uint32_t)USBx;
1239   uint32_t tmpreg;
1240 
1241   tmpreg  = USBx_DEVICE->DAINT;
1242   tmpreg &= USBx_DEVICE->DAINTMSK;
1243 
1244   return ((tmpreg & 0xffff0000U) >> 16);
1245 }
1246 
1247 /**
1248   * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1249   * @param  USBx  Selected device
1250   * @retval USB Device IN EP interrupt status
1251   */
1252 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1253 {
1254   uint32_t USBx_BASE = (uint32_t)USBx;
1255   uint32_t tmpreg;
1256 
1257   tmpreg  = USBx_DEVICE->DAINT;
1258   tmpreg &= USBx_DEVICE->DAINTMSK;
1259 
1260   return ((tmpreg & 0xFFFFU));
1261 }
1262 
1263 /**
1264   * @brief  Returns Device OUT EP Interrupt register
1265   * @param  USBx  Selected device
1266   * @param  epnum  endpoint number
1267   *          This parameter can be a value from 0 to 15
1268   * @retval Device OUT EP Interrupt register
1269   */
1270 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1271 {
1272   uint32_t USBx_BASE = (uint32_t)USBx;
1273   uint32_t tmpreg;
1274 
1275   tmpreg  = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1276   tmpreg &= USBx_DEVICE->DOEPMSK;
1277 
1278   return tmpreg;
1279 }
1280 
1281 /**
1282   * @brief  Returns Device IN EP Interrupt register
1283   * @param  USBx  Selected device
1284   * @param  epnum  endpoint number
1285   *          This parameter can be a value from 0 to 15
1286   * @retval Device IN EP Interrupt register
1287   */
1288 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1289 {
1290   uint32_t USBx_BASE = (uint32_t)USBx;
1291   uint32_t tmpreg;
1292   uint32_t msk;
1293   uint32_t emp;
1294 
1295   msk = USBx_DEVICE->DIEPMSK;
1296   emp = USBx_DEVICE->DIEPEMPMSK;
1297   msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1298   tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1299 
1300   return tmpreg;
1301 }
1302 
1303 /**
1304   * @brief  USB_ClearInterrupts: clear a USB interrupt
1305   * @param  USBx  Selected device
1306   * @param  interrupt  flag
1307   * @retval None
1308   */
1309 void  USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1310 {
1311   USBx->GINTSTS &= interrupt;
1312 }
1313 
1314 /**
1315   * @brief  Returns USB core mode
1316   * @param  USBx  Selected device
1317   * @retval return core mode : Host or Device
1318   *          This parameter can be one of these values:
1319   *           0 : Host
1320   *           1 : Device
1321   */
1322 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1323 {
1324   return ((USBx->GINTSTS) & 0x1U);
1325 }
1326 
1327 /**
1328   * @brief  Activate EP0 for Setup transactions
1329   * @param  USBx  Selected device
1330   * @retval HAL status
1331   */
1332 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1333 {
1334   uint32_t USBx_BASE = (uint32_t)USBx;
1335 
1336   /* Set the MPS of the IN EP0 to 64 bytes */
1337   USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1338 
1339   USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1340 
1341   return HAL_OK;
1342 }
1343 
1344 /**
1345   * @brief  Prepare the EP0 to start the first control setup
1346   * @param  USBx  Selected device
1347   * @param  dma USB dma enabled or disabled
1348   *          This parameter can be one of these values:
1349   *           0 : DMA feature not used
1350   *           1 : DMA feature used
1351   * @param  psetup  pointer to setup packet
1352   * @retval HAL status
1353   */
1354 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup)
1355 {
1356   uint32_t USBx_BASE = (uint32_t)USBx;
1357   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1358 
1359   if (gSNPSiD > USB_OTG_CORE_ID_300A)
1360   {
1361     if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1362     {
1363       return HAL_OK;
1364     }
1365   }
1366 
1367   USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1368   USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1369   USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1370   USBx_OUTEP(0U)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;
1371 
1372   if (dma == 1U)
1373   {
1374     USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1375     /* EP enable */
1376     USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1377   }
1378 
1379   return HAL_OK;
1380 }
1381 
1382 /**
1383   * @brief  Reset the USB Core (needed after USB clock settings change)
1384   * @param  USBx  Selected device
1385   * @retval HAL status
1386   */
1387 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1388 {
1389   __IO uint32_t count = 0U;
1390 
1391   /* Wait for AHB master IDLE state. */
1392   do
1393   {
1394     count++;
1395 
1396     if (count > HAL_USB_TIMEOUT)
1397     {
1398       return HAL_TIMEOUT;
1399     }
1400   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1401 
1402   /* Core Soft Reset */
1403   count = 0U;
1404   USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1405 
1406   do
1407   {
1408     count++;
1409 
1410     if (count > HAL_USB_TIMEOUT)
1411     {
1412       return HAL_TIMEOUT;
1413     }
1414   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1415 
1416   return HAL_OK;
1417 }
1418 
1419 /**
1420   * @brief  USB_HostInit : Initializes the USB OTG controller registers
1421   *         for Host mode
1422   * @param  USBx  Selected device
1423   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
1424   *         the configuration information for the specified USBx peripheral.
1425   * @retval HAL status
1426   */
1427 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1428 {
1429   HAL_StatusTypeDef ret = HAL_OK;
1430   uint32_t USBx_BASE = (uint32_t)USBx;
1431   uint32_t i;
1432 
1433   /* Restart the Phy Clock */
1434   USBx_PCGCCTL = 0U;
1435 
1436   /* Disable VBUS sensing */
1437   USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1438 
1439   /* Disable Battery chargin detector */
1440   USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1441 
1442 
1443   if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
1444   {
1445     if (cfg.speed == USBH_FSLS_SPEED)
1446     {
1447       /* Force Device Enumeration to FS/LS mode only */
1448       USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1449     }
1450     else
1451     {
1452       /* Set default Max speed support */
1453       USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1454     }
1455   }
1456   else
1457   {
1458     /* Set default Max speed support */
1459     USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1460   }
1461 
1462   /* Make sure the FIFOs are flushed. */
1463   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1464   {
1465     ret = HAL_ERROR;
1466   }
1467 
1468   if (USB_FlushRxFifo(USBx) != HAL_OK)
1469   {
1470     ret = HAL_ERROR;
1471   }
1472 
1473   /* Clear all pending HC Interrupts */
1474   for (i = 0U; i < cfg.Host_channels; i++)
1475   {
1476     USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1477     USBx_HC(i)->HCINTMSK = 0U;
1478   }
1479 
1480   /* Disable all interrupts. */
1481   USBx->GINTMSK = 0U;
1482 
1483   /* Clear any pending interrupts */
1484   USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1485   /* set Rx FIFO size */
1486   USBx->GRXFSIZ  = 0x200U;
1487   USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
1488   USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1489 
1490   /* Enable the common interrupts */
1491   if (cfg.dma_enable == 0U)
1492   {
1493     USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1494   }
1495 
1496   /* Enable interrupts matching to the Host mode ONLY */
1497   USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM | \
1498                     USB_OTG_GINTMSK_SOFM             | USB_OTG_GINTSTS_DISCINT | \
1499                     USB_OTG_GINTMSK_PXFRM_IISOOXFRM  | USB_OTG_GINTMSK_WUIM);
1500 
1501   return ret;
1502 }
1503 
1504 /**
1505   * @brief  USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1506   *         HCFG register on the PHY type and set the right frame interval
1507   * @param  USBx  Selected device
1508   * @param  freq  clock frequency
1509   *          This parameter can be one of these values:
1510   *           HCFG_48_MHZ : Full Speed 48 MHz Clock
1511   *           HCFG_6_MHZ : Low Speed 6 MHz Clock
1512   * @retval HAL status
1513   */
1514 HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1515 {
1516   uint32_t USBx_BASE = (uint32_t)USBx;
1517 
1518   USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1519   USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1520 
1521   if (freq == HCFG_48_MHZ)
1522   {
1523     USBx_HOST->HFIR = HFIR_48_MHZ;
1524   }
1525   else if (freq == HCFG_6_MHZ)
1526   {
1527     USBx_HOST->HFIR = HFIR_6_MHZ;
1528   }
1529   else
1530   {
1531     return HAL_ERROR;
1532   }
1533 
1534   return HAL_OK;
1535 }
1536 
1537 /**
1538   * @brief  USB_OTG_ResetPort : Reset Host Port
1539   * @param  USBx  Selected device
1540   * @retval HAL status
1541   * @note (1)The application must wait at least 10 ms
1542   *   before clearing the reset bit.
1543   */
1544 HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
1545 {
1546   uint32_t USBx_BASE = (uint32_t)USBx;
1547 
1548   __IO uint32_t hprt0 = 0U;
1549 
1550   hprt0 = USBx_HPRT0;
1551 
1552   hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1553              USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1554 
1555   USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1556   HAL_Delay(100U);                                 /* See Note #1 */
1557   USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1558   HAL_Delay(10U);
1559 
1560   return HAL_OK;
1561 }
1562 
1563 /**
1564   * @brief  USB_DriveVbus : activate or de-activate vbus
1565   * @param  state  VBUS state
1566   *          This parameter can be one of these values:
1567   *           0 : Deactivate VBUS
1568   *           1 : Activate VBUS
1569   * @retval HAL status
1570   */
1571 HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1572 {
1573   uint32_t USBx_BASE = (uint32_t)USBx;
1574   __IO uint32_t hprt0 = 0U;
1575 
1576   hprt0 = USBx_HPRT0;
1577 
1578   hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1579              USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1580 
1581   if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1582   {
1583     USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1584   }
1585   if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1586   {
1587     USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1588   }
1589   return HAL_OK;
1590 }
1591 
1592 /**
1593   * @brief  Return Host Core speed
1594   * @param  USBx  Selected device
1595   * @retval speed : Host speed
1596   *          This parameter can be one of these values:
1597   *            @arg HCD_SPEED_HIGH: High speed mode
1598   *            @arg HCD_SPEED_FULL: Full speed mode
1599   *            @arg HCD_SPEED_LOW: Low speed mode
1600   */
1601 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1602 {
1603   uint32_t USBx_BASE = (uint32_t)USBx;
1604   __IO uint32_t hprt0 = 0U;
1605 
1606   hprt0 = USBx_HPRT0;
1607   return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1608 }
1609 
1610 /**
1611   * @brief  Return Host Current Frame number
1612   * @param  USBx  Selected device
1613   * @retval current frame number
1614   */
1615 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1616 {
1617   uint32_t USBx_BASE = (uint32_t)USBx;
1618 
1619   return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1620 }
1621 
1622 /**
1623   * @brief  Initialize a host channel
1624   * @param  USBx  Selected device
1625   * @param  ch_num  Channel number
1626   *         This parameter can be a value from 1 to 15
1627   * @param  epnum  Endpoint number
1628   *          This parameter can be a value from 1 to 15
1629   * @param  dev_address  Current device address
1630   *          This parameter can be a value from 0 to 255
1631   * @param  speed  Current device speed
1632   *          This parameter can be one of these values:
1633   *            @arg USB_OTG_SPEED_HIGH: High speed mode
1634   *            @arg USB_OTG_SPEED_FULL: Full speed mode
1635   *            @arg USB_OTG_SPEED_LOW: Low speed mode
1636   * @param  ep_type  Endpoint Type
1637   *          This parameter can be one of these values:
1638   *            @arg EP_TYPE_CTRL: Control type
1639   *            @arg EP_TYPE_ISOC: Isochronous type
1640   *            @arg EP_TYPE_BULK: Bulk type
1641   *            @arg EP_TYPE_INTR: Interrupt type
1642   * @param  mps  Max Packet Size
1643   *          This parameter can be a value from 0 to 32K
1644   * @retval HAL state
1645   */
1646 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1647                               uint8_t epnum, uint8_t dev_address, uint8_t speed,
1648                               uint8_t ep_type, uint16_t mps)
1649 {
1650   HAL_StatusTypeDef ret = HAL_OK;
1651   uint32_t USBx_BASE = (uint32_t)USBx;
1652   uint32_t HCcharEpDir;
1653   uint32_t HCcharLowSpeed;
1654   uint32_t HostCoreSpeed;
1655 
1656   /* Clear old interrupt conditions for this host channel. */
1657   USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1658 
1659   /* Enable channel interrupts required for this transfer. */
1660   switch (ep_type)
1661   {
1662     case EP_TYPE_CTRL:
1663     case EP_TYPE_BULK:
1664       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1665                                             USB_OTG_HCINTMSK_STALLM |
1666                                             USB_OTG_HCINTMSK_TXERRM |
1667                                             USB_OTG_HCINTMSK_DTERRM |
1668                                             USB_OTG_HCINTMSK_AHBERR |
1669                                             USB_OTG_HCINTMSK_NAKM;
1670 
1671       if ((epnum & 0x80U) == 0x80U)
1672       {
1673         USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1674       }
1675       else
1676       {
1677         USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
1678                                                USB_OTG_HCINTMSK_ACKM;
1679       }
1680       break;
1681 
1682     case EP_TYPE_INTR:
1683       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1684                                             USB_OTG_HCINTMSK_STALLM |
1685                                             USB_OTG_HCINTMSK_TXERRM |
1686                                             USB_OTG_HCINTMSK_DTERRM |
1687                                             USB_OTG_HCINTMSK_NAKM   |
1688                                             USB_OTG_HCINTMSK_AHBERR |
1689                                             USB_OTG_HCINTMSK_FRMORM;
1690 
1691       if ((epnum & 0x80U) == 0x80U)
1692       {
1693         USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1694       }
1695 
1696       break;
1697 
1698     case EP_TYPE_ISOC:
1699       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1700                                             USB_OTG_HCINTMSK_ACKM   |
1701                                             USB_OTG_HCINTMSK_AHBERR |
1702                                             USB_OTG_HCINTMSK_FRMORM;
1703 
1704       if ((epnum & 0x80U) == 0x80U)
1705       {
1706         USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1707       }
1708       break;
1709 
1710     default:
1711       ret = HAL_ERROR;
1712       break;
1713   }
1714 
1715   /* Clear Hub Start Split transaction */
1716   USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
1717 
1718   /* Enable host channel Halt interrupt */
1719   USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1720 
1721   /* Enable the top level host channel interrupt. */
1722   USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1723 
1724   /* Make sure host channel interrupts are enabled. */
1725   USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1726 
1727   /* Program the HCCHAR register */
1728   if ((epnum & 0x80U) == 0x80U)
1729   {
1730     HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1731   }
1732   else
1733   {
1734     HCcharEpDir = 0U;
1735   }
1736 
1737   HostCoreSpeed = USB_GetHostSpeed(USBx);
1738 
1739   /* LS device plugged to HUB */
1740   if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1741   {
1742     HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1743   }
1744   else
1745   {
1746     HCcharLowSpeed = 0U;
1747   }
1748 
1749   USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1750                                       ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1751                                       (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1752                                       ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1753                                       USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1754 
1755   if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1756   {
1757     USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1758   }
1759 
1760   return ret;
1761 }
1762 
1763 /**
1764   * @brief  Start a transfer over a host channel
1765   * @param  USBx  Selected device
1766   * @param  hc  pointer to host channel structure
1767   * @param  dma USB dma enabled or disabled
1768   *          This parameter can be one of these values:
1769   *           0 : DMA feature not used
1770   *           1 : DMA feature used
1771   * @retval HAL state
1772   */
1773 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1774 {
1775   uint32_t USBx_BASE = (uint32_t)USBx;
1776   uint32_t ch_num = (uint32_t)hc->ch_num;
1777   __IO uint32_t tmpreg;
1778   uint8_t  is_oddframe;
1779   uint16_t len_words;
1780   uint16_t num_packets;
1781   uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1782 
1783   /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
1784   if (dma == 1U)
1785   {
1786     if ((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK))
1787     {
1788 
1789       USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
1790                                                USB_OTG_HCINTMSK_ACKM |
1791                                                USB_OTG_HCINTMSK_NAKM);
1792     }
1793   }
1794   else
1795   {
1796     if ((hc->speed == USBH_HS_SPEED) && (hc->do_ping == 1U))
1797     {
1798       (void)USB_DoPing(USBx, hc->ch_num);
1799       return HAL_OK;
1800     }
1801   }
1802 
1803   if (hc->do_ssplit == 1U)
1804   {
1805     /* Set number of packet to 1 for Split transaction */
1806     num_packets = 1U;
1807 
1808     if (hc->ep_is_in != 0U)
1809     {
1810       hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1811     }
1812     else
1813     {
1814       if (hc->ep_type == EP_TYPE_ISOC)
1815       {
1816         if (hc->xfer_len > ISO_SPLT_MPS)
1817         {
1818           /* Isochrone Max Packet Size for Split mode */
1819           hc->XferSize = hc->max_packet;
1820           hc->xfer_len = hc->XferSize;
1821 
1822           if ((hc->iso_splt_xactPos == HCSPLT_BEGIN) || (hc->iso_splt_xactPos == HCSPLT_MIDDLE))
1823           {
1824             hc->iso_splt_xactPos = HCSPLT_MIDDLE;
1825           }
1826           else
1827           {
1828             hc->iso_splt_xactPos = HCSPLT_BEGIN;
1829           }
1830         }
1831         else
1832         {
1833           hc->XferSize = hc->xfer_len;
1834 
1835           if ((hc->iso_splt_xactPos != HCSPLT_BEGIN) && (hc->iso_splt_xactPos != HCSPLT_MIDDLE))
1836           {
1837             hc->iso_splt_xactPos = HCSPLT_FULL;
1838           }
1839           else
1840           {
1841             hc->iso_splt_xactPos = HCSPLT_END;
1842           }
1843         }
1844       }
1845       else
1846       {
1847         if ((dma == 1U) && (hc->xfer_len > hc->max_packet))
1848         {
1849           hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1850         }
1851         else
1852         {
1853           hc->XferSize = hc->xfer_len;
1854         }
1855       }
1856     }
1857   }
1858   else
1859   {
1860     /* Compute the expected number of packets associated to the transfer */
1861     if (hc->xfer_len > 0U)
1862     {
1863       num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1864 
1865       if (num_packets > max_hc_pkt_count)
1866       {
1867         num_packets = max_hc_pkt_count;
1868         hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1869       }
1870     }
1871     else
1872     {
1873       num_packets = 1U;
1874     }
1875 
1876     /*
1877     * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1878     * max_packet size.
1879     */
1880     if (hc->ep_is_in != 0U)
1881     {
1882       hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1883     }
1884     else
1885     {
1886       hc->XferSize = hc->xfer_len;
1887     }
1888   }
1889 
1890   /* Initialize the HCTSIZn register */
1891   USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1892                             (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1893                             (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1894 
1895   if (dma != 0U)
1896   {
1897     /* xfer_buff MUST be 32-bits aligned */
1898     USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1899   }
1900 
1901   is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1902   USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1903   USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1904 
1905   if (hc->do_ssplit == 1U)
1906   {
1907     /* Set Hub start Split transaction */
1908     USBx_HC((uint32_t)ch_num)->HCSPLT = ((uint32_t)hc->hub_addr << USB_OTG_HCSPLT_HUBADDR_Pos) |
1909                                         (uint32_t)hc->hub_port_nbr | USB_OTG_HCSPLT_SPLITEN;
1910 
1911     /* unmask ack & nyet for IN/OUT transactions */
1912     USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_ACKM |
1913                                             USB_OTG_HCINTMSK_NYET);
1914 
1915     if ((hc->do_csplit == 1U) && (hc->ep_is_in == 0U))
1916     {
1917       USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1918       USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
1919     }
1920 
1921     if (((hc->ep_type == EP_TYPE_ISOC) || (hc->ep_type == EP_TYPE_INTR)) &&
1922         (hc->do_csplit == 1U) && (hc->ep_is_in == 1U))
1923     {
1924       USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1925     }
1926 
1927     /* Position management for iso out transaction on split mode */
1928     if ((hc->ep_type == EP_TYPE_ISOC) && (hc->ep_is_in == 0U))
1929     {
1930       /* Set data payload position */
1931       switch (hc->iso_splt_xactPos)
1932       {
1933         case HCSPLT_BEGIN:
1934           /* First data payload for OUT Transaction */
1935           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_1;
1936           break;
1937 
1938         case HCSPLT_MIDDLE:
1939           /* Middle data payload for OUT Transaction */
1940           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_Pos;
1941           break;
1942 
1943         case HCSPLT_END:
1944           /* End data payload for OUT Transaction */
1945           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_0;
1946           break;
1947 
1948         case HCSPLT_FULL:
1949           /* Entire data payload for OUT Transaction */
1950           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS;
1951           break;
1952 
1953         default:
1954           break;
1955       }
1956     }
1957   }
1958   else
1959   {
1960     /* Clear Hub Start Split transaction */
1961     USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
1962   }
1963 
1964   /* Set host channel enable */
1965   tmpreg = USBx_HC(ch_num)->HCCHAR;
1966   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1967 
1968   /* make sure to set the correct ep direction */
1969   if (hc->ep_is_in != 0U)
1970   {
1971     tmpreg |= USB_OTG_HCCHAR_EPDIR;
1972   }
1973   else
1974   {
1975     tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1976   }
1977   tmpreg |= USB_OTG_HCCHAR_CHENA;
1978   USBx_HC(ch_num)->HCCHAR = tmpreg;
1979 
1980   if (dma != 0U) /* dma mode */
1981   {
1982     return HAL_OK;
1983   }
1984 
1985   if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U) && (hc->do_csplit == 0U))
1986   {
1987     switch (hc->ep_type)
1988     {
1989       /* Non periodic transfer */
1990       case EP_TYPE_CTRL:
1991       case EP_TYPE_BULK:
1992 
1993         len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1994 
1995         /* check if there is enough space in FIFO space */
1996         if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1997         {
1998           /* need to process data in nptxfempty interrupt */
1999           USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
2000         }
2001         break;
2002 
2003       /* Periodic transfer */
2004       case EP_TYPE_INTR:
2005       case EP_TYPE_ISOC:
2006         len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2007         /* check if there is enough space in FIFO space */
2008         if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
2009         {
2010           /* need to process data in ptxfempty interrupt */
2011           USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
2012         }
2013         break;
2014 
2015       default:
2016         break;
2017     }
2018 
2019     /* Write packet into the Tx FIFO. */
2020     (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
2021   }
2022 
2023   return HAL_OK;
2024 }
2025 
2026 /**
2027   * @brief Read all host channel interrupts status
2028   * @param  USBx  Selected device
2029   * @retval HAL state
2030   */
2031 uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
2032 {
2033   uint32_t USBx_BASE = (uint32_t)USBx;
2034 
2035   return ((USBx_HOST->HAINT) & 0xFFFFU);
2036 }
2037 
2038 /**
2039   * @brief  Halt a host channel
2040   * @param  USBx  Selected device
2041   * @param  hc_num  Host Channel number
2042   *         This parameter can be a value from 1 to 15
2043   * @retval HAL state
2044   */
2045 HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
2046 {
2047   uint32_t USBx_BASE = (uint32_t)USBx;
2048   uint32_t hcnum = (uint32_t)hc_num;
2049   __IO uint32_t count = 0U;
2050   uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
2051   uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
2052   uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
2053 
2054   /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
2055      At the end of the next uframe/frame (in the worst case), the core generates a channel halted
2056      and disables the channel automatically. */
2057 
2058   if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
2059       ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
2060   {
2061     return HAL_OK;
2062   }
2063 
2064   /* Check for space in the request queue to issue the halt. */
2065   if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
2066   {
2067     USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2068 
2069     if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
2070     {
2071       if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
2072       {
2073         USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2074         USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2075         do
2076         {
2077           count++;
2078 
2079           if (count > 1000U)
2080           {
2081             break;
2082           }
2083         } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2084       }
2085       else
2086       {
2087         USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2088       }
2089     }
2090     else
2091     {
2092       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2093     }
2094   }
2095   else
2096   {
2097     USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2098 
2099     if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
2100     {
2101       USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2102       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2103       do
2104       {
2105         count++;
2106 
2107         if (count > 1000U)
2108         {
2109           break;
2110         }
2111       } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2112     }
2113     else
2114     {
2115       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2116     }
2117   }
2118 
2119   return HAL_OK;
2120 }
2121 
2122 /**
2123   * @brief  Initiate Do Ping protocol
2124   * @param  USBx  Selected device
2125   * @param  hc_num  Host Channel number
2126   *         This parameter can be a value from 1 to 15
2127   * @retval HAL state
2128   */
2129 HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
2130 {
2131   uint32_t USBx_BASE = (uint32_t)USBx;
2132   uint32_t chnum = (uint32_t)ch_num;
2133   uint32_t num_packets = 1U;
2134   uint32_t tmpreg;
2135 
2136   USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
2137                            USB_OTG_HCTSIZ_DOPING;
2138 
2139   /* Set host channel enable */
2140   tmpreg = USBx_HC(chnum)->HCCHAR;
2141   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2142   tmpreg |= USB_OTG_HCCHAR_CHENA;
2143   USBx_HC(chnum)->HCCHAR = tmpreg;
2144 
2145   return HAL_OK;
2146 }
2147 
2148 /**
2149   * @brief  Stop Host Core
2150   * @param  USBx  Selected device
2151   * @retval HAL state
2152   */
2153 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
2154 {
2155   HAL_StatusTypeDef ret = HAL_OK;
2156   uint32_t USBx_BASE = (uint32_t)USBx;
2157   __IO uint32_t count = 0U;
2158   uint32_t value;
2159   uint32_t i;
2160 
2161   (void)USB_DisableGlobalInt(USBx);
2162 
2163   /* Flush USB FIFO */
2164   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
2165   {
2166     ret = HAL_ERROR;
2167   }
2168 
2169   if (USB_FlushRxFifo(USBx) != HAL_OK)
2170   {
2171     ret = HAL_ERROR;
2172   }
2173 
2174   /* Flush out any leftover queued requests. */
2175   for (i = 0U; i <= 15U; i++)
2176   {
2177     value = USBx_HC(i)->HCCHAR;
2178     value |=  USB_OTG_HCCHAR_CHDIS;
2179     value &= ~USB_OTG_HCCHAR_CHENA;
2180     value &= ~USB_OTG_HCCHAR_EPDIR;
2181     USBx_HC(i)->HCCHAR = value;
2182   }
2183 
2184   /* Halt all channels to put them into a known state. */
2185   for (i = 0U; i <= 15U; i++)
2186   {
2187     value = USBx_HC(i)->HCCHAR;
2188     value |= USB_OTG_HCCHAR_CHDIS;
2189     value |= USB_OTG_HCCHAR_CHENA;
2190     value &= ~USB_OTG_HCCHAR_EPDIR;
2191     USBx_HC(i)->HCCHAR = value;
2192 
2193     do
2194     {
2195       count++;
2196 
2197       if (count > 1000U)
2198       {
2199         break;
2200       }
2201     } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2202   }
2203 
2204   /* Clear any pending Host interrupts */
2205   USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
2206   USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
2207 
2208   (void)USB_EnableGlobalInt(USBx);
2209 
2210   return ret;
2211 }
2212 
2213 /**
2214   * @brief  USB_ActivateRemoteWakeup active remote wakeup signalling
2215   * @param  USBx Selected device
2216   * @retval HAL status
2217   */
2218 HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2219 {
2220   uint32_t USBx_BASE = (uint32_t)USBx;
2221 
2222   if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2223   {
2224     /* active Remote wakeup signalling */
2225     USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2226   }
2227 
2228   return HAL_OK;
2229 }
2230 
2231 /**
2232   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2233   * @param  USBx Selected device
2234   * @retval HAL status
2235   */
2236 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2237 {
2238   uint32_t USBx_BASE = (uint32_t)USBx;
2239 
2240   /* active Remote wakeup signalling */
2241   USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2242 
2243   return HAL_OK;
2244 }
2245 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2246 
2247 /**
2248   * @}
2249   */
2250 
2251 /**
2252   * @}
2253   */
2254 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2255 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2256 
2257 /**
2258   * @}
2259   */