1 /**
2   ******************************************************************************
3   * @file    stm32f2xx_ll_usb.c
4   * @author  MCD Application Team
5   * @brief   USB Low Layer HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the USB Peripheral Controller:
9   *           + Initialization/de-initialization functions
10   *           + I/O operation functions
11   *           + Peripheral Control functions
12   *           + Peripheral State functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2016 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                     ##### How to use this driver #####
28   ==============================================================================
29     [..]
30       (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
31 
32       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
33 
34       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
35 
36   @endverbatim
37 
38   ******************************************************************************
39   */
40 
41 /* Includes ------------------------------------------------------------------*/
42 #include "stm32f2xx_hal.h"
43 
44 /** @addtogroup STM32F2xx_LL_USB_DRIVER
45   * @{
46   */
47 
48 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
50 /* Private typedef -----------------------------------------------------------*/
51 /* Private define ------------------------------------------------------------*/
52 /* Private macro -------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 /* Private function prototypes -----------------------------------------------*/
55 /* Private functions ---------------------------------------------------------*/
56 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
57 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58 
59 /* Exported functions --------------------------------------------------------*/
60 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
61   * @{
62   */
63 
64 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
65   *  @brief    Initialization and Configuration functions
66   *
67 @verbatim
68  ===============================================================================
69                       ##### Initialization/de-initialization functions #####
70  ===============================================================================
71 
72 @endverbatim
73   * @{
74   */
75 
76 /**
77   * @brief  Initializes the USB Core
78   * @param  USBx USB Instance
79   * @param  cfg pointer to a USB_OTG_CfgTypeDef structure that contains
80   *         the configuration information for the specified USBx peripheral.
81   * @retval HAL status
82   */
USB_CoreInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)83 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
84 {
85   HAL_StatusTypeDef ret;
86   if (cfg.phy_itface == USB_OTG_ULPI_PHY)
87   {
88     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
89 
90     /* Init The ULPI Interface */
91     USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
92 
93     /* Select vbus source */
94     USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
95     if (cfg.use_external_vbus == 1U)
96     {
97       USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
98     }
99 
100     /* Reset after a PHY select */
101     ret = USB_CoreReset(USBx);
102   }
103   else /* FS interface (embedded Phy) */
104   {
105     /* Select FS Embedded PHY */
106     USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
107 
108     /* Reset after a PHY select */
109     ret = USB_CoreReset(USBx);
110 
111     /* Activate the USB Transceiver */
112     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
113   }
114 
115   if (cfg.dma_enable == 1U)
116   {
117     USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
118     USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
119   }
120 
121   return ret;
122 }
123 
124 
125 /**
126   * @brief  Set the USB turnaround time
127   * @param  USBx USB Instance
128   * @param  hclk: AHB clock frequency
129   * @retval USB turnaround time In PHY Clocks number
130   */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)131 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
132                                         uint32_t hclk, uint8_t speed)
133 {
134   uint32_t UsbTrd;
135 
136   /* The USBTRD is configured according to the tables below, depending on AHB frequency
137   used by application. In the low AHB frequency range it is used to stretch enough the USB response
138   time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
139   latency to the Data FIFO */
140   if (speed == USBD_FS_SPEED)
141   {
142     if ((hclk >= 14200000U) && (hclk < 15000000U))
143     {
144       /* hclk Clock Range between 14.2-15 MHz */
145       UsbTrd = 0xFU;
146     }
147     else if ((hclk >= 15000000U) && (hclk < 16000000U))
148     {
149       /* hclk Clock Range between 15-16 MHz */
150       UsbTrd = 0xEU;
151     }
152     else if ((hclk >= 16000000U) && (hclk < 17200000U))
153     {
154       /* hclk Clock Range between 16-17.2 MHz */
155       UsbTrd = 0xDU;
156     }
157     else if ((hclk >= 17200000U) && (hclk < 18500000U))
158     {
159       /* hclk Clock Range between 17.2-18.5 MHz */
160       UsbTrd = 0xCU;
161     }
162     else if ((hclk >= 18500000U) && (hclk < 20000000U))
163     {
164       /* hclk Clock Range between 18.5-20 MHz */
165       UsbTrd = 0xBU;
166     }
167     else if ((hclk >= 20000000U) && (hclk < 21800000U))
168     {
169       /* hclk Clock Range between 20-21.8 MHz */
170       UsbTrd = 0xAU;
171     }
172     else if ((hclk >= 21800000U) && (hclk < 24000000U))
173     {
174       /* hclk Clock Range between 21.8-24 MHz */
175       UsbTrd = 0x9U;
176     }
177     else if ((hclk >= 24000000U) && (hclk < 27700000U))
178     {
179       /* hclk Clock Range between 24-27.7 MHz */
180       UsbTrd = 0x8U;
181     }
182     else if ((hclk >= 27700000U) && (hclk < 32000000U))
183     {
184       /* hclk Clock Range between 27.7-32 MHz */
185       UsbTrd = 0x7U;
186     }
187     else /* if(hclk >= 32000000) */
188     {
189       /* hclk Clock Range between 32-200 MHz */
190       UsbTrd = 0x6U;
191     }
192   }
193   else if (speed == USBD_HS_SPEED)
194   {
195     UsbTrd = USBD_HS_TRDT_VALUE;
196   }
197   else
198   {
199     UsbTrd = USBD_DEFAULT_TRDT_VALUE;
200   }
201 
202   USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
203   USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
204 
205   return HAL_OK;
206 }
207 
208 /**
209   * @brief  USB_EnableGlobalInt
210   *         Enables the controller's Global Int in the AHB Config reg
211   * @param  USBx  Selected device
212   * @retval HAL status
213   */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)214 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
215 {
216   USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
217   return HAL_OK;
218 }
219 
220 /**
221   * @brief  USB_DisableGlobalInt
222   *         Disable the controller's Global Int in the AHB Config reg
223   * @param  USBx  Selected device
224   * @retval HAL status
225   */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)226 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
227 {
228   USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
229   return HAL_OK;
230 }
231 
232 /**
233   * @brief  USB_SetCurrentMode Set functional mode
234   * @param  USBx  Selected device
235   * @param  mode  current core mode
236   *          This parameter can be one of these values:
237   *            @arg USB_DEVICE_MODE Peripheral mode
238   *            @arg USB_HOST_MODE Host mode
239   * @retval HAL status
240   */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_OTG_ModeTypeDef mode)241 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
242 {
243   uint32_t ms = 0U;
244 
245   USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
246 
247   if (mode == USB_HOST_MODE)
248   {
249     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
250 
251     do
252     {
253       HAL_Delay(10U);
254       ms += 10U;
255     } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
256   }
257   else if (mode == USB_DEVICE_MODE)
258   {
259     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
260 
261     do
262     {
263       HAL_Delay(10U);
264       ms += 10U;
265     } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
266   }
267   else
268   {
269     return HAL_ERROR;
270   }
271 
272   if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
273   {
274     return HAL_ERROR;
275   }
276 
277   return HAL_OK;
278 }
279 
280 /**
281   * @brief  USB_DevInit Initializes the USB_OTG controller registers
282   *         for device mode
283   * @param  USBx  Selected device
284   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
285   *         the configuration information for the specified USBx peripheral.
286   * @retval HAL status
287   */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)288 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
289 {
290   HAL_StatusTypeDef ret = HAL_OK;
291   uint32_t USBx_BASE = (uint32_t)USBx;
292   uint32_t i;
293 
294   for (i = 0U; i < 15U; i++)
295   {
296     USBx->DIEPTXF[i] = 0U;
297   }
298 
299   /* VBUS Sensing setup */
300   if (cfg.vbus_sensing_enable == 0U)
301   {
302     /*
303      * disable HW VBUS sensing. VBUS is internally considered to be always
304      * at VBUS-Valid level (5V).
305      */
306     USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
307     USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
308     USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
309     USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
310   }
311   else
312   {
313     /* Enable HW VBUS sensing */
314     USBx->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
315     USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
316   }
317 
318   /* Restart the Phy Clock */
319   USBx_PCGCCTL = 0U;
320 
321   if (cfg.phy_itface == USB_OTG_ULPI_PHY)
322   {
323     if (cfg.speed == USBD_HS_SPEED)
324     {
325       /* Set Core speed to High speed mode */
326       (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
327     }
328     else
329     {
330       /* Set Core speed to Full speed mode */
331       (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
332     }
333   }
334   else
335   {
336     /* Set Core speed to Full speed mode */
337     (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
338   }
339 
340   /* Flush the FIFOs */
341   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
342   {
343     ret = HAL_ERROR;
344   }
345 
346   if (USB_FlushRxFifo(USBx) != HAL_OK)
347   {
348     ret = HAL_ERROR;
349   }
350 
351   /* Clear all pending Device Interrupts */
352   USBx_DEVICE->DIEPMSK = 0U;
353   USBx_DEVICE->DOEPMSK = 0U;
354   USBx_DEVICE->DAINTMSK = 0U;
355 
356   for (i = 0U; i < cfg.dev_endpoints; i++)
357   {
358     if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
359     {
360       if (i == 0U)
361       {
362         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
363       }
364       else
365       {
366         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
367       }
368     }
369     else
370     {
371       USBx_INEP(i)->DIEPCTL = 0U;
372     }
373 
374     USBx_INEP(i)->DIEPTSIZ = 0U;
375     USBx_INEP(i)->DIEPINT  = 0xFB7FU;
376   }
377 
378   for (i = 0U; i < cfg.dev_endpoints; i++)
379   {
380     if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
381     {
382       if (i == 0U)
383       {
384         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
385       }
386       else
387       {
388         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
389       }
390     }
391     else
392     {
393       USBx_OUTEP(i)->DOEPCTL = 0U;
394     }
395 
396     USBx_OUTEP(i)->DOEPTSIZ = 0U;
397     USBx_OUTEP(i)->DOEPINT  = 0xFB7FU;
398   }
399 
400   USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
401 
402   /* Disable all interrupts. */
403   USBx->GINTMSK = 0U;
404 
405   /* Clear any pending interrupts */
406   USBx->GINTSTS = 0xBFFFFFFFU;
407 
408   /* Enable the common interrupts */
409   if (cfg.dma_enable == 0U)
410   {
411     USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
412   }
413 
414   /* Enable interrupts matching to the Device mode ONLY */
415   USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
416                    USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
417                    USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM |
418                    USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
419 
420   if (cfg.Sof_enable != 0U)
421   {
422     USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
423   }
424 
425   if (cfg.vbus_sensing_enable == 1U)
426   {
427     USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
428   }
429 
430   return ret;
431 }
432 
433 /**
434   * @brief  USB_FlushTxFifo Flush a Tx FIFO
435   * @param  USBx  Selected device
436   * @param  num  FIFO number
437   *         This parameter can be a value from 1 to 15
438             15 means Flush all Tx FIFOs
439   * @retval HAL status
440   */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)441 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
442 {
443   __IO uint32_t count = 0U;
444 
445   /* Wait for AHB master IDLE state. */
446   do
447   {
448     count++;
449 
450     if (count > HAL_USB_TIMEOUT)
451     {
452       return HAL_TIMEOUT;
453     }
454   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
455 
456   /* Flush TX Fifo */
457   count = 0U;
458   USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
459 
460   do
461   {
462     count++;
463 
464     if (count > HAL_USB_TIMEOUT)
465     {
466       return HAL_TIMEOUT;
467     }
468   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
469 
470   return HAL_OK;
471 }
472 
473 /**
474   * @brief  USB_FlushRxFifo  Flush Rx FIFO
475   * @param  USBx  Selected device
476   * @retval HAL status
477   */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)478 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
479 {
480   __IO uint32_t count = 0U;
481 
482   /* Wait for AHB master IDLE state. */
483   do
484   {
485     count++;
486 
487     if (count > HAL_USB_TIMEOUT)
488     {
489       return HAL_TIMEOUT;
490     }
491   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
492 
493   /* Flush RX Fifo */
494   count = 0U;
495   USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
496 
497   do
498   {
499     count++;
500 
501     if (count > HAL_USB_TIMEOUT)
502     {
503       return HAL_TIMEOUT;
504     }
505   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
506 
507   return HAL_OK;
508 }
509 
510 /**
511   * @brief  USB_SetDevSpeed  Initializes the DevSpd field of DCFG register
512   *         depending the PHY type and the enumeration speed of the device.
513   * @param  USBx  Selected device
514   * @param  speed  device speed
515   *          This parameter can be one of these values:
516   *            @arg USB_OTG_SPEED_HIGH: High speed mode
517   *            @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
518   *            @arg USB_OTG_SPEED_FULL: Full speed mode
519   * @retval  Hal status
520   */
USB_SetDevSpeed(const USB_OTG_GlobalTypeDef * USBx,uint8_t speed)521 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
522 {
523   uint32_t USBx_BASE = (uint32_t)USBx;
524 
525   USBx_DEVICE->DCFG |= speed;
526   return HAL_OK;
527 }
528 
529 /**
530   * @brief  USB_GetDevSpeed  Return the Dev Speed
531   * @param  USBx  Selected device
532   * @retval speed  device speed
533   *          This parameter can be one of these values:
534   *            @arg USBD_HS_SPEED: High speed mode
535   *            @arg USBD_FS_SPEED: Full speed mode
536   */
USB_GetDevSpeed(const USB_OTG_GlobalTypeDef * USBx)537 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
538 {
539   uint32_t USBx_BASE = (uint32_t)USBx;
540   uint8_t speed;
541   uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
542 
543   if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
544   {
545     speed = USBD_HS_SPEED;
546   }
547   else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
548            (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
549   {
550     speed = USBD_FS_SPEED;
551   }
552   else
553   {
554     speed = 0xFU;
555   }
556 
557   return speed;
558 }
559 
560 /**
561   * @brief  Activate and configure an endpoint
562   * @param  USBx  Selected device
563   * @param  ep pointer to endpoint structure
564   * @retval HAL status
565   */
USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)566 HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
567 {
568   uint32_t USBx_BASE = (uint32_t)USBx;
569   uint32_t epnum = (uint32_t)ep->num;
570 
571   if (ep->is_in == 1U)
572   {
573     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
574 
575     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
576     {
577       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
578                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
579                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
580                                    USB_OTG_DIEPCTL_USBAEP;
581     }
582   }
583   else
584   {
585     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
586 
587     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
588     {
589       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
590                                     ((uint32_t)ep->type << 18) |
591                                     USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
592                                     USB_OTG_DOEPCTL_USBAEP;
593     }
594   }
595   return HAL_OK;
596 }
597 
598 /**
599   * @brief  Activate and configure a dedicated endpoint
600   * @param  USBx  Selected device
601   * @param  ep pointer to endpoint structure
602   * @retval HAL status
603   */
USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)604 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
605 {
606   uint32_t USBx_BASE = (uint32_t)USBx;
607   uint32_t epnum = (uint32_t)ep->num;
608 
609   /* Read DEPCTLn register */
610   if (ep->is_in == 1U)
611   {
612     if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
613     {
614       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
615                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
616                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
617                                    USB_OTG_DIEPCTL_USBAEP;
618     }
619 
620     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
621   }
622   else
623   {
624     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
625     {
626       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
627                                     ((uint32_t)ep->type << 18) | (epnum << 22) |
628                                     USB_OTG_DOEPCTL_USBAEP;
629     }
630 
631     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
632   }
633 
634   return HAL_OK;
635 }
636 
637 /**
638   * @brief  De-activate and de-initialize an endpoint
639   * @param  USBx  Selected device
640   * @param  ep pointer to endpoint structure
641   * @retval HAL status
642   */
USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)643 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
644 {
645   uint32_t USBx_BASE = (uint32_t)USBx;
646   uint32_t epnum = (uint32_t)ep->num;
647 
648   /* Read DEPCTLn register */
649   if (ep->is_in == 1U)
650   {
651     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
652     {
653       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
654       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
655     }
656 
657     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
658     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
659     USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
660                                    USB_OTG_DIEPCTL_MPSIZ |
661                                    USB_OTG_DIEPCTL_TXFNUM |
662                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
663                                    USB_OTG_DIEPCTL_EPTYP);
664   }
665   else
666   {
667     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
668     {
669       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
670       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
671     }
672 
673     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
674     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
675     USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
676                                     USB_OTG_DOEPCTL_MPSIZ |
677                                     USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
678                                     USB_OTG_DOEPCTL_EPTYP);
679   }
680 
681   return HAL_OK;
682 }
683 
684 /**
685   * @brief  De-activate and de-initialize a dedicated endpoint
686   * @param  USBx  Selected device
687   * @param  ep pointer to endpoint structure
688   * @retval HAL status
689   */
USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)690 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
691 {
692   uint32_t USBx_BASE = (uint32_t)USBx;
693   uint32_t epnum = (uint32_t)ep->num;
694 
695   /* Read DEPCTLn register */
696   if (ep->is_in == 1U)
697   {
698     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
699     {
700       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_SNAK;
701       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_EPDIS;
702     }
703 
704     USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
705     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
706   }
707   else
708   {
709     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
710     {
711       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_SNAK;
712       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_EPDIS;
713     }
714 
715     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
716     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
717   }
718 
719   return HAL_OK;
720 }
721 
722 /**
723   * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
724   * @param  USBx  Selected device
725   * @param  ep pointer to endpoint structure
726   * @param  dma USB dma enabled or disabled
727   *          This parameter can be one of these values:
728   *           0 : DMA feature not used
729   *           1 : DMA feature used
730   * @retval HAL status
731   */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)732 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
733 {
734   uint32_t USBx_BASE = (uint32_t)USBx;
735   uint32_t epnum = (uint32_t)ep->num;
736   uint16_t pktcnt;
737 
738   /* IN endpoint */
739   if (ep->is_in == 1U)
740   {
741     /* Zero Length Packet? */
742     if (ep->xfer_len == 0U)
743     {
744       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
745       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
746       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
747     }
748     else
749     {
750       /* Program the transfer size and packet count
751       * as follows: xfersize = N * maxpacket +
752       * short_packet pktcnt = N + (short_packet
753       * exist ? 1 : 0)
754       */
755       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
756       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
757 
758       if (epnum == 0U)
759       {
760         if (ep->xfer_len > ep->maxpacket)
761         {
762           ep->xfer_len = ep->maxpacket;
763         }
764 
765         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
766       }
767       else
768       {
769         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
770                                        (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
771       }
772 
773       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
774 
775       if (ep->type == EP_TYPE_ISOC)
776       {
777         USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
778         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
779       }
780     }
781 
782     if (dma == 1U)
783     {
784       if ((uint32_t)ep->dma_addr != 0U)
785       {
786         USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
787       }
788 
789       if (ep->type == EP_TYPE_ISOC)
790       {
791         if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
792         {
793           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
794         }
795         else
796         {
797           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
798         }
799       }
800 
801       /* EP enable, IN data in FIFO */
802       USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
803     }
804     else
805     {
806       /* EP enable, IN data in FIFO */
807       USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
808 
809       if (ep->type != EP_TYPE_ISOC)
810       {
811         /* Enable the Tx FIFO Empty Interrupt for this EP */
812         if (ep->xfer_len > 0U)
813         {
814           USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
815         }
816       }
817       else
818       {
819         if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
820         {
821           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
822         }
823         else
824         {
825           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
826         }
827 
828         (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
829       }
830     }
831   }
832   else /* OUT endpoint */
833   {
834     /* Program the transfer size and packet count as follows:
835     * pktcnt = N
836     * xfersize = N * maxpacket
837     */
838     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
839     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
840 
841     if (epnum == 0U)
842     {
843       if (ep->xfer_len > 0U)
844       {
845         ep->xfer_len = ep->maxpacket;
846       }
847 
848       /* Store transfer size, for EP0 this is equal to endpoint max packet size */
849       ep->xfer_size = ep->maxpacket;
850 
851       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
852       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
853     }
854     else
855     {
856       if (ep->xfer_len == 0U)
857       {
858         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
859         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
860       }
861       else
862       {
863         pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
864         ep->xfer_size = ep->maxpacket * pktcnt;
865 
866         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
867         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
868       }
869     }
870 
871     if (dma == 1U)
872     {
873       if ((uint32_t)ep->xfer_buff != 0U)
874       {
875         USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
876       }
877     }
878 
879     if (ep->type == EP_TYPE_ISOC)
880     {
881       if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
882       {
883         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
884       }
885       else
886       {
887         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
888       }
889     }
890     /* EP enable */
891     USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
892   }
893 
894   return HAL_OK;
895 }
896 
897 
898 /**
899    * @brief  USB_EPStoptXfer  Stop transfer on an EP
900    * @param  USBx  usb device instance
901    * @param  ep pointer to endpoint structure
902    * @retval HAL status
903    */
USB_EPStopXfer(const USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)904 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
905 {
906   __IO uint32_t count = 0U;
907   HAL_StatusTypeDef ret = HAL_OK;
908   uint32_t USBx_BASE = (uint32_t)USBx;
909 
910   /* IN endpoint */
911   if (ep->is_in == 1U)
912   {
913     /* EP enable, IN data in FIFO */
914     if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
915     {
916       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
917       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
918 
919       do
920       {
921         count++;
922 
923         if (count > 10000U)
924         {
925           ret = HAL_ERROR;
926           break;
927         }
928       } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) ==  USB_OTG_DIEPCTL_EPENA);
929     }
930   }
931   else /* OUT endpoint */
932   {
933     if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
934     {
935       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
936       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
937 
938       do
939       {
940         count++;
941 
942         if (count > 10000U)
943         {
944           ret = HAL_ERROR;
945           break;
946         }
947       } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) ==  USB_OTG_DOEPCTL_EPENA);
948     }
949   }
950 
951   return ret;
952 }
953 
954 
955 /**
956   * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
957   *         with the EP/channel
958   * @param  USBx  Selected device
959   * @param  src   pointer to source buffer
960   * @param  ch_ep_num  endpoint or host channel number
961   * @param  len  Number of bytes to write
962   * @param  dma USB dma enabled or disabled
963   *          This parameter can be one of these values:
964   *           0 : DMA feature not used
965   *           1 : DMA feature used
966   * @retval HAL status
967   */
USB_WritePacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len,uint8_t dma)968 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
969                                   uint8_t ch_ep_num, uint16_t len, uint8_t dma)
970 {
971   uint32_t USBx_BASE = (uint32_t)USBx;
972   uint8_t *pSrc = src;
973   uint32_t count32b;
974   uint32_t i;
975 
976   if (dma == 0U)
977   {
978     count32b = ((uint32_t)len + 3U) / 4U;
979     for (i = 0U; i < count32b; i++)
980     {
981       USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
982       pSrc++;
983       pSrc++;
984       pSrc++;
985       pSrc++;
986     }
987   }
988 
989   return HAL_OK;
990 }
991 
992 /**
993   * @brief  USB_ReadPacket : read a packet from the RX FIFO
994   * @param  USBx  Selected device
995   * @param  dest  source pointer
996   * @param  len  Number of bytes to read
997   * @retval pointer to destination buffer
998   */
USB_ReadPacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)999 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1000 {
1001   uint32_t USBx_BASE = (uint32_t)USBx;
1002   uint8_t *pDest = dest;
1003   uint32_t pData;
1004   uint32_t i;
1005   uint32_t count32b = (uint32_t)len >> 2U;
1006   uint16_t remaining_bytes = len % 4U;
1007 
1008   for (i = 0U; i < count32b; i++)
1009   {
1010     __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1011     pDest++;
1012     pDest++;
1013     pDest++;
1014     pDest++;
1015   }
1016 
1017   /* When Number of data is not word aligned, read the remaining byte */
1018   if (remaining_bytes != 0U)
1019   {
1020     i = 0U;
1021     __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1022 
1023     do
1024     {
1025       *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1026       i++;
1027       pDest++;
1028       remaining_bytes--;
1029     } while (remaining_bytes != 0U);
1030   }
1031 
1032   return ((void *)pDest);
1033 }
1034 
1035 /**
1036   * @brief  USB_EPSetStall : set a stall condition over an EP
1037   * @param  USBx  Selected device
1038   * @param  ep pointer to endpoint structure
1039   * @retval HAL status
1040   */
USB_EPSetStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1041 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1042 {
1043   uint32_t USBx_BASE = (uint32_t)USBx;
1044   uint32_t epnum = (uint32_t)ep->num;
1045 
1046   if (ep->is_in == 1U)
1047   {
1048     if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1049     {
1050       USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1051     }
1052     USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1053   }
1054   else
1055   {
1056     if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1057     {
1058       USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1059     }
1060     USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1061   }
1062 
1063   return HAL_OK;
1064 }
1065 
1066 /**
1067   * @brief  USB_EPClearStall : Clear a stall condition over an EP
1068   * @param  USBx  Selected device
1069   * @param  ep pointer to endpoint structure
1070   * @retval HAL status
1071   */
USB_EPClearStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1072 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1073 {
1074   uint32_t USBx_BASE = (uint32_t)USBx;
1075   uint32_t epnum = (uint32_t)ep->num;
1076 
1077   if (ep->is_in == 1U)
1078   {
1079     USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1080     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1081     {
1082       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1083     }
1084   }
1085   else
1086   {
1087     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1088     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1089     {
1090       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1091     }
1092   }
1093   return HAL_OK;
1094 }
1095 
1096 /**
1097   * @brief  USB_StopDevice : Stop the usb device mode
1098   * @param  USBx  Selected device
1099   * @retval HAL status
1100   */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1101 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1102 {
1103   HAL_StatusTypeDef ret;
1104   uint32_t USBx_BASE = (uint32_t)USBx;
1105   uint32_t i;
1106 
1107   /* Clear Pending interrupt */
1108   for (i = 0U; i < 15U; i++)
1109   {
1110     USBx_INEP(i)->DIEPINT = 0xFB7FU;
1111     USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1112   }
1113 
1114   /* Clear interrupt masks */
1115   USBx_DEVICE->DIEPMSK  = 0U;
1116   USBx_DEVICE->DOEPMSK  = 0U;
1117   USBx_DEVICE->DAINTMSK = 0U;
1118 
1119   /* Flush the FIFO */
1120   ret = USB_FlushRxFifo(USBx);
1121   if (ret != HAL_OK)
1122   {
1123     return ret;
1124   }
1125 
1126   ret = USB_FlushTxFifo(USBx,  0x10U);
1127   if (ret != HAL_OK)
1128   {
1129     return ret;
1130   }
1131 
1132   return ret;
1133 }
1134 
1135 /**
1136   * @brief  USB_SetDevAddress : Stop the usb device mode
1137   * @param  USBx  Selected device
1138   * @param  address  new device address to be assigned
1139   *          This parameter can be a value from 0 to 255
1140   * @retval HAL status
1141   */
USB_SetDevAddress(const USB_OTG_GlobalTypeDef * USBx,uint8_t address)1142 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1143 {
1144   uint32_t USBx_BASE = (uint32_t)USBx;
1145 
1146   USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1147   USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1148 
1149   return HAL_OK;
1150 }
1151 
1152 /**
1153   * @brief  USB_DevConnect : Connect the USB device by enabling Rpu
1154   * @param  USBx  Selected device
1155   * @retval HAL status
1156   */
USB_DevConnect(const USB_OTG_GlobalTypeDef * USBx)1157 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1158 {
1159   uint32_t USBx_BASE = (uint32_t)USBx;
1160 
1161   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1162   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1163 
1164   USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1165 
1166   return HAL_OK;
1167 }
1168 
1169 /**
1170   * @brief  USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1171   * @param  USBx  Selected device
1172   * @retval HAL status
1173   */
USB_DevDisconnect(const USB_OTG_GlobalTypeDef * USBx)1174 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1175 {
1176   uint32_t USBx_BASE = (uint32_t)USBx;
1177 
1178   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1179   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1180 
1181   USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1182 
1183   return HAL_OK;
1184 }
1185 
1186 /**
1187   * @brief  USB_ReadInterrupts: return the global USB interrupt status
1188   * @param  USBx  Selected device
1189   * @retval USB Global Interrupt status
1190   */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef const * USBx)1191 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1192 {
1193   uint32_t tmpreg;
1194 
1195   tmpreg = USBx->GINTSTS;
1196   tmpreg &= USBx->GINTMSK;
1197 
1198   return tmpreg;
1199 }
1200 
1201 /**
1202   * @brief  USB_ReadChInterrupts: return USB channel interrupt status
1203   * @param  USBx  Selected device
1204   * @param  chnum Channel number
1205   * @retval USB Channel Interrupt status
1206   */
USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef * USBx,uint8_t chnum)1207 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1208 {
1209   uint32_t USBx_BASE = (uint32_t)USBx;
1210   uint32_t tmpreg;
1211 
1212   tmpreg = USBx_HC(chnum)->HCINT;
1213   tmpreg &= USBx_HC(chnum)->HCINTMSK;
1214 
1215   return tmpreg;
1216 }
1217 
1218 /**
1219   * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1220   * @param  USBx  Selected device
1221   * @retval USB Device OUT EP interrupt status
1222   */
USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1223 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1224 {
1225   uint32_t USBx_BASE = (uint32_t)USBx;
1226   uint32_t tmpreg;
1227 
1228   tmpreg  = USBx_DEVICE->DAINT;
1229   tmpreg &= USBx_DEVICE->DAINTMSK;
1230 
1231   return ((tmpreg & 0xffff0000U) >> 16);
1232 }
1233 
1234 /**
1235   * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1236   * @param  USBx  Selected device
1237   * @retval USB Device IN EP interrupt status
1238   */
USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1239 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1240 {
1241   uint32_t USBx_BASE = (uint32_t)USBx;
1242   uint32_t tmpreg;
1243 
1244   tmpreg  = USBx_DEVICE->DAINT;
1245   tmpreg &= USBx_DEVICE->DAINTMSK;
1246 
1247   return ((tmpreg & 0xFFFFU));
1248 }
1249 
1250 /**
1251   * @brief  Returns Device OUT EP Interrupt register
1252   * @param  USBx  Selected device
1253   * @param  epnum  endpoint number
1254   *          This parameter can be a value from 0 to 15
1255   * @retval Device OUT EP Interrupt register
1256   */
USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1257 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1258 {
1259   uint32_t USBx_BASE = (uint32_t)USBx;
1260   uint32_t tmpreg;
1261 
1262   tmpreg  = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1263   tmpreg &= USBx_DEVICE->DOEPMSK;
1264 
1265   return tmpreg;
1266 }
1267 
1268 /**
1269   * @brief  Returns Device IN EP Interrupt register
1270   * @param  USBx  Selected device
1271   * @param  epnum  endpoint number
1272   *          This parameter can be a value from 0 to 15
1273   * @retval Device IN EP Interrupt register
1274   */
USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1275 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1276 {
1277   uint32_t USBx_BASE = (uint32_t)USBx;
1278   uint32_t tmpreg;
1279   uint32_t msk;
1280   uint32_t emp;
1281 
1282   msk = USBx_DEVICE->DIEPMSK;
1283   emp = USBx_DEVICE->DIEPEMPMSK;
1284   msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1285   tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1286 
1287   return tmpreg;
1288 }
1289 
1290 /**
1291   * @brief  USB_ClearInterrupts: clear a USB interrupt
1292   * @param  USBx  Selected device
1293   * @param  interrupt  flag
1294   * @retval None
1295   */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1296 void  USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1297 {
1298   USBx->GINTSTS &= interrupt;
1299 }
1300 
1301 /**
1302   * @brief  Returns USB core mode
1303   * @param  USBx  Selected device
1304   * @retval return core mode : Host or Device
1305   *          This parameter can be one of these values:
1306   *           0 : Host
1307   *           1 : Device
1308   */
USB_GetMode(const USB_OTG_GlobalTypeDef * USBx)1309 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1310 {
1311   return ((USBx->GINTSTS) & 0x1U);
1312 }
1313 
1314 /**
1315   * @brief  Activate EP0 for Setup transactions
1316   * @param  USBx  Selected device
1317   * @retval HAL status
1318   */
USB_ActivateSetup(const USB_OTG_GlobalTypeDef * USBx)1319 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1320 {
1321   uint32_t USBx_BASE = (uint32_t)USBx;
1322 
1323   /* Set the MPS of the IN EP0 to 64 bytes */
1324   USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1325 
1326   USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1327 
1328   return HAL_OK;
1329 }
1330 
1331 /**
1332   * @brief  Prepare the EP0 to start the first control setup
1333   * @param  USBx  Selected device
1334   * @param  dma USB dma enabled or disabled
1335   *          This parameter can be one of these values:
1336   *           0 : DMA feature not used
1337   *           1 : DMA feature used
1338   * @param  psetup  pointer to setup packet
1339   * @retval HAL status
1340   */
USB_EP0_OutStart(const USB_OTG_GlobalTypeDef * USBx,uint8_t dma,const uint8_t * psetup)1341 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup)
1342 {
1343   uint32_t USBx_BASE = (uint32_t)USBx;
1344   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1345 
1346   if (gSNPSiD > USB_OTG_CORE_ID_300A)
1347   {
1348     if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1349     {
1350       return HAL_OK;
1351     }
1352   }
1353 
1354   USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1355   USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1356   USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1357   USBx_OUTEP(0U)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;
1358 
1359   if (dma == 1U)
1360   {
1361     USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1362     /* EP enable */
1363     USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1364   }
1365 
1366   return HAL_OK;
1367 }
1368 
1369 /**
1370   * @brief  Reset the USB Core (needed after USB clock settings change)
1371   * @param  USBx  Selected device
1372   * @retval HAL status
1373   */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1374 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1375 {
1376   __IO uint32_t count = 0U;
1377 
1378   /* Wait for AHB master IDLE state. */
1379   do
1380   {
1381     count++;
1382 
1383     if (count > HAL_USB_TIMEOUT)
1384     {
1385       return HAL_TIMEOUT;
1386     }
1387   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1388 
1389   /* Core Soft Reset */
1390   count = 0U;
1391   USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1392 
1393   do
1394   {
1395     count++;
1396 
1397     if (count > HAL_USB_TIMEOUT)
1398     {
1399       return HAL_TIMEOUT;
1400     }
1401   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1402 
1403   return HAL_OK;
1404 }
1405 
1406 /**
1407   * @brief  USB_HostInit : Initializes the USB OTG controller registers
1408   *         for Host mode
1409   * @param  USBx  Selected device
1410   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
1411   *         the configuration information for the specified USBx peripheral.
1412   * @retval HAL status
1413   */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1414 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1415 {
1416   HAL_StatusTypeDef ret = HAL_OK;
1417   uint32_t USBx_BASE = (uint32_t)USBx;
1418   uint32_t i;
1419 
1420   /* Restart the Phy Clock */
1421   USBx_PCGCCTL = 0U;
1422 
1423   /* Disable VBUS sensing */
1424   USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
1425   USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSASEN);
1426   USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSBSEN);
1427 
1428   if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
1429   {
1430     if (cfg.speed == USBH_FSLS_SPEED)
1431     {
1432       /* Force Device Enumeration to FS/LS mode only */
1433       USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1434     }
1435     else
1436     {
1437       /* Set default Max speed support */
1438       USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1439     }
1440   }
1441   else
1442   {
1443     /* Set default Max speed support */
1444     USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1445   }
1446 
1447   /* Make sure the FIFOs are flushed. */
1448   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1449   {
1450     ret = HAL_ERROR;
1451   }
1452 
1453   if (USB_FlushRxFifo(USBx) != HAL_OK)
1454   {
1455     ret = HAL_ERROR;
1456   }
1457 
1458   /* Clear all pending HC Interrupts */
1459   for (i = 0U; i < cfg.Host_channels; i++)
1460   {
1461     USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1462     USBx_HC(i)->HCINTMSK = 0U;
1463   }
1464 
1465   /* Disable all interrupts. */
1466   USBx->GINTMSK = 0U;
1467 
1468   /* Clear any pending interrupts */
1469   USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1470 #if defined (USB_OTG_HS)
1471   if (USBx == USB_OTG_HS)
1472   {
1473     /* set Rx FIFO size */
1474     USBx->GRXFSIZ  = 0x200U;
1475     USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
1476     USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1477   }
1478   else
1479 #endif /* defined (USB_OTG_HS) */
1480   {
1481     /* set Rx FIFO size */
1482     USBx->GRXFSIZ  = 0x80U;
1483     USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1484     USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1485   }
1486 
1487   /* Enable the common interrupts */
1488   if (cfg.dma_enable == 0U)
1489   {
1490     USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1491   }
1492 
1493   /* Enable interrupts matching to the Host mode ONLY */
1494   USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM | \
1495                     USB_OTG_GINTMSK_SOFM             | USB_OTG_GINTSTS_DISCINT | \
1496                     USB_OTG_GINTMSK_PXFRM_IISOOXFRM  | USB_OTG_GINTMSK_WUIM);
1497 
1498   return ret;
1499 }
1500 
1501 /**
1502   * @brief  USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1503   *         HCFG register on the PHY type and set the right frame interval
1504   * @param  USBx  Selected device
1505   * @param  freq  clock frequency
1506   *          This parameter can be one of these values:
1507   *           HCFG_48_MHZ : Full Speed 48 MHz Clock
1508   *           HCFG_6_MHZ : Low Speed 6 MHz Clock
1509   * @retval HAL status
1510   */
USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1511 HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1512 {
1513   uint32_t USBx_BASE = (uint32_t)USBx;
1514 
1515   USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1516   USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1517 
1518   if (freq == HCFG_48_MHZ)
1519   {
1520     USBx_HOST->HFIR = HFIR_48_MHZ;
1521   }
1522   else if (freq == HCFG_6_MHZ)
1523   {
1524     USBx_HOST->HFIR = HFIR_6_MHZ;
1525   }
1526   else
1527   {
1528     return HAL_ERROR;
1529   }
1530 
1531   return HAL_OK;
1532 }
1533 
1534 /**
1535   * @brief  USB_OTG_ResetPort : Reset Host Port
1536   * @param  USBx  Selected device
1537   * @retval HAL status
1538   * @note (1)The application must wait at least 10 ms
1539   *   before clearing the reset bit.
1540   */
USB_ResetPort(const USB_OTG_GlobalTypeDef * USBx)1541 HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
1542 {
1543   uint32_t USBx_BASE = (uint32_t)USBx;
1544 
1545   __IO uint32_t hprt0 = 0U;
1546 
1547   hprt0 = USBx_HPRT0;
1548 
1549   hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1550              USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1551 
1552   USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1553   HAL_Delay(100U);                                 /* See Note #1 */
1554   USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1555   HAL_Delay(10U);
1556 
1557   return HAL_OK;
1558 }
1559 
1560 /**
1561   * @brief  USB_DriveVbus : activate or de-activate vbus
1562   * @param  state  VBUS state
1563   *          This parameter can be one of these values:
1564   *           0 : Deactivate VBUS
1565   *           1 : Activate VBUS
1566   * @retval HAL status
1567   */
USB_DriveVbus(const USB_OTG_GlobalTypeDef * USBx,uint8_t state)1568 HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1569 {
1570   uint32_t USBx_BASE = (uint32_t)USBx;
1571   __IO uint32_t hprt0 = 0U;
1572 
1573   hprt0 = USBx_HPRT0;
1574 
1575   hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1576              USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1577 
1578   if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1579   {
1580     USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1581   }
1582   if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1583   {
1584     USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1585   }
1586   return HAL_OK;
1587 }
1588 
1589 /**
1590   * @brief  Return Host Core speed
1591   * @param  USBx  Selected device
1592   * @retval speed : Host speed
1593   *          This parameter can be one of these values:
1594   *            @arg HCD_SPEED_HIGH: High speed mode
1595   *            @arg HCD_SPEED_FULL: Full speed mode
1596   *            @arg HCD_SPEED_LOW: Low speed mode
1597   */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef const * USBx)1598 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1599 {
1600   uint32_t USBx_BASE = (uint32_t)USBx;
1601   __IO uint32_t hprt0 = 0U;
1602 
1603   hprt0 = USBx_HPRT0;
1604   return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1605 }
1606 
1607 /**
1608   * @brief  Return Host Current Frame number
1609   * @param  USBx  Selected device
1610   * @retval current frame number
1611   */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const * USBx)1612 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1613 {
1614   uint32_t USBx_BASE = (uint32_t)USBx;
1615 
1616   return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1617 }
1618 
1619 /**
1620   * @brief  Initialize a host channel
1621   * @param  USBx  Selected device
1622   * @param  ch_num  Channel number
1623   *         This parameter can be a value from 1 to 15
1624   * @param  epnum  Endpoint number
1625   *          This parameter can be a value from 1 to 15
1626   * @param  dev_address  Current device address
1627   *          This parameter can be a value from 0 to 255
1628   * @param  speed  Current device speed
1629   *          This parameter can be one of these values:
1630   *            @arg USB_OTG_SPEED_HIGH: High speed mode
1631   *            @arg USB_OTG_SPEED_FULL: Full speed mode
1632   *            @arg USB_OTG_SPEED_LOW: Low speed mode
1633   * @param  ep_type  Endpoint Type
1634   *          This parameter can be one of these values:
1635   *            @arg EP_TYPE_CTRL: Control type
1636   *            @arg EP_TYPE_ISOC: Isochronous type
1637   *            @arg EP_TYPE_BULK: Bulk type
1638   *            @arg EP_TYPE_INTR: Interrupt type
1639   * @param  mps  Max Packet Size
1640   *          This parameter can be a value from 0 to 32K
1641   * @retval HAL state
1642   */
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)1643 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1644                               uint8_t epnum, uint8_t dev_address, uint8_t speed,
1645                               uint8_t ep_type, uint16_t mps)
1646 {
1647   HAL_StatusTypeDef ret = HAL_OK;
1648   uint32_t USBx_BASE = (uint32_t)USBx;
1649   uint32_t HCcharEpDir;
1650   uint32_t HCcharLowSpeed;
1651   uint32_t HostCoreSpeed;
1652 
1653   /* Clear old interrupt conditions for this host channel. */
1654   USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1655 
1656   /* Enable channel interrupts required for this transfer. */
1657   switch (ep_type)
1658   {
1659     case EP_TYPE_CTRL:
1660     case EP_TYPE_BULK:
1661       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1662                                             USB_OTG_HCINTMSK_STALLM |
1663                                             USB_OTG_HCINTMSK_TXERRM |
1664                                             USB_OTG_HCINTMSK_DTERRM |
1665                                             USB_OTG_HCINTMSK_AHBERR |
1666                                             USB_OTG_HCINTMSK_NAKM;
1667 
1668       if ((epnum & 0x80U) == 0x80U)
1669       {
1670         USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1671       }
1672       else
1673       {
1674 #if defined (USB_OTG_HS)
1675         if (USBx == USB_OTG_HS)
1676         {
1677           USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
1678                                                  USB_OTG_HCINTMSK_ACKM;
1679         }
1680 #endif /* defined (USB_OTG_HS) */
1681       }
1682       break;
1683 
1684     case EP_TYPE_INTR:
1685       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1686                                             USB_OTG_HCINTMSK_STALLM |
1687                                             USB_OTG_HCINTMSK_TXERRM |
1688                                             USB_OTG_HCINTMSK_DTERRM |
1689                                             USB_OTG_HCINTMSK_NAKM   |
1690                                             USB_OTG_HCINTMSK_AHBERR |
1691                                             USB_OTG_HCINTMSK_FRMORM;
1692 
1693       if ((epnum & 0x80U) == 0x80U)
1694       {
1695         USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1696       }
1697 
1698       break;
1699 
1700     case EP_TYPE_ISOC:
1701       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1702                                             USB_OTG_HCINTMSK_ACKM   |
1703                                             USB_OTG_HCINTMSK_AHBERR |
1704                                             USB_OTG_HCINTMSK_FRMORM;
1705 
1706       if ((epnum & 0x80U) == 0x80U)
1707       {
1708         USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1709       }
1710       break;
1711 
1712     default:
1713       ret = HAL_ERROR;
1714       break;
1715   }
1716 
1717   /* Clear Hub Start Split transaction */
1718   USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
1719 
1720   /* Enable host channel Halt interrupt */
1721   USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1722 
1723   /* Enable the top level host channel interrupt. */
1724   USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1725 
1726   /* Make sure host channel interrupts are enabled. */
1727   USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1728 
1729   /* Program the HCCHAR register */
1730   if ((epnum & 0x80U) == 0x80U)
1731   {
1732     HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1733   }
1734   else
1735   {
1736     HCcharEpDir = 0U;
1737   }
1738 
1739   HostCoreSpeed = USB_GetHostSpeed(USBx);
1740 
1741   /* LS device plugged to HUB */
1742   if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1743   {
1744     HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1745   }
1746   else
1747   {
1748     HCcharLowSpeed = 0U;
1749   }
1750 
1751   USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1752                                       ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1753                                       (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1754                                       ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1755                                       USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1756 
1757   if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1758   {
1759     USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1760   }
1761 
1762   return ret;
1763 }
1764 
1765 /**
1766   * @brief  Start a transfer over a host channel
1767   * @param  USBx  Selected device
1768   * @param  hc  pointer to host channel structure
1769   * @param  dma USB dma enabled or disabled
1770   *          This parameter can be one of these values:
1771   *           0 : DMA feature not used
1772   *           1 : DMA feature used
1773   * @retval HAL state
1774   */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc,uint8_t dma)1775 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1776 {
1777   uint32_t USBx_BASE = (uint32_t)USBx;
1778   uint32_t ch_num = (uint32_t)hc->ch_num;
1779   __IO uint32_t tmpreg;
1780   uint8_t  is_oddframe;
1781   uint16_t len_words;
1782   uint16_t num_packets;
1783   uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1784 
1785 #if defined (USB_OTG_HS)
1786   if (USBx == USB_OTG_HS)
1787   {
1788     /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
1789     if (dma == 1U)
1790     {
1791       if (((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)) && (hc->do_ssplit == 0U))
1792       {
1793 
1794         USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
1795                                                  USB_OTG_HCINTMSK_ACKM |
1796                                                  USB_OTG_HCINTMSK_NAKM);
1797       }
1798     }
1799     else
1800     {
1801       if ((hc->speed == USBH_HS_SPEED) && (hc->do_ping == 1U))
1802       {
1803         (void)USB_DoPing(USBx, hc->ch_num);
1804         return HAL_OK;
1805       }
1806     }
1807   }
1808 #endif /* defined (USB_OTG_HS) */
1809 
1810   if (hc->do_ssplit == 1U)
1811   {
1812     /* Set number of packet to 1 for Split transaction */
1813     num_packets = 1U;
1814 
1815     if (hc->ep_is_in != 0U)
1816     {
1817       hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1818     }
1819     else
1820     {
1821       if (hc->ep_type == EP_TYPE_ISOC)
1822       {
1823         if (hc->xfer_len > ISO_SPLT_MPS)
1824         {
1825           /* Isochrone Max Packet Size for Split mode */
1826           hc->XferSize = hc->max_packet;
1827           hc->xfer_len = hc->XferSize;
1828 
1829           if ((hc->iso_splt_xactPos == HCSPLT_BEGIN) || (hc->iso_splt_xactPos == HCSPLT_MIDDLE))
1830           {
1831             hc->iso_splt_xactPos = HCSPLT_MIDDLE;
1832           }
1833           else
1834           {
1835             hc->iso_splt_xactPos = HCSPLT_BEGIN;
1836           }
1837         }
1838         else
1839         {
1840           hc->XferSize = hc->xfer_len;
1841 
1842           if ((hc->iso_splt_xactPos != HCSPLT_BEGIN) && (hc->iso_splt_xactPos != HCSPLT_MIDDLE))
1843           {
1844             hc->iso_splt_xactPos = HCSPLT_FULL;
1845           }
1846           else
1847           {
1848             hc->iso_splt_xactPos = HCSPLT_END;
1849           }
1850         }
1851       }
1852       else
1853       {
1854         if ((dma == 1U) && (hc->xfer_len > hc->max_packet))
1855         {
1856           hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1857         }
1858         else
1859         {
1860           hc->XferSize = hc->xfer_len;
1861         }
1862       }
1863     }
1864   }
1865   else
1866   {
1867     /* Compute the expected number of packets associated to the transfer */
1868     if (hc->xfer_len > 0U)
1869     {
1870       num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1871 
1872       if (num_packets > max_hc_pkt_count)
1873       {
1874         num_packets = max_hc_pkt_count;
1875         hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1876       }
1877     }
1878     else
1879     {
1880       num_packets = 1U;
1881     }
1882 
1883     /*
1884     * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1885     * max_packet size.
1886     */
1887     if (hc->ep_is_in != 0U)
1888     {
1889       hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1890     }
1891     else
1892     {
1893       hc->XferSize = hc->xfer_len;
1894     }
1895   }
1896 
1897   /* Initialize the HCTSIZn register */
1898   USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1899                             (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1900                             (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1901 
1902   if (dma != 0U)
1903   {
1904     /* xfer_buff MUST be 32-bits aligned */
1905     USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1906   }
1907 
1908   is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1909   USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1910   USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1911 
1912   if (hc->do_ssplit == 1U)
1913   {
1914     /* Set Hub start Split transaction */
1915     USBx_HC((uint32_t)ch_num)->HCSPLT = ((uint32_t)hc->hub_addr << USB_OTG_HCSPLT_HUBADDR_Pos) |
1916                                         (uint32_t)hc->hub_port_nbr | USB_OTG_HCSPLT_SPLITEN;
1917 
1918     /* unmask ack & nyet for IN/OUT transactions */
1919     USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_ACKM |
1920                                             USB_OTG_HCINTMSK_NYET);
1921 
1922     if ((hc->do_csplit == 1U) && (hc->ep_is_in == 0U))
1923     {
1924       USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1925       USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
1926     }
1927 
1928     if (((hc->ep_type == EP_TYPE_ISOC) || (hc->ep_type == EP_TYPE_INTR)) &&
1929         (hc->do_csplit == 1U) && (hc->ep_is_in == 1U))
1930     {
1931       USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1932     }
1933 
1934     /* Position management for iso out transaction on split mode */
1935     if ((hc->ep_type == EP_TYPE_ISOC) && (hc->ep_is_in == 0U))
1936     {
1937       /* Set data payload position */
1938       switch (hc->iso_splt_xactPos)
1939       {
1940         case HCSPLT_BEGIN:
1941           /* First data payload for OUT Transaction */
1942           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_1;
1943           break;
1944 
1945         case HCSPLT_MIDDLE:
1946           /* Middle data payload for OUT Transaction */
1947           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_Pos;
1948           break;
1949 
1950         case HCSPLT_END:
1951           /* End data payload for OUT Transaction */
1952           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_0;
1953           break;
1954 
1955         case HCSPLT_FULL:
1956           /* Entire data payload for OUT Transaction */
1957           USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS;
1958           break;
1959 
1960         default:
1961           break;
1962       }
1963     }
1964   }
1965   else
1966   {
1967     /* Clear Hub Start Split transaction */
1968     USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
1969   }
1970 
1971   /* Set host channel enable */
1972   tmpreg = USBx_HC(ch_num)->HCCHAR;
1973   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1974 
1975   /* make sure to set the correct ep direction */
1976   if (hc->ep_is_in != 0U)
1977   {
1978     tmpreg |= USB_OTG_HCCHAR_EPDIR;
1979   }
1980   else
1981   {
1982     tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1983   }
1984   tmpreg |= USB_OTG_HCCHAR_CHENA;
1985   USBx_HC(ch_num)->HCCHAR = tmpreg;
1986 
1987   if (dma != 0U) /* dma mode */
1988   {
1989     return HAL_OK;
1990   }
1991 
1992   if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U) && (hc->do_csplit == 0U))
1993   {
1994     switch (hc->ep_type)
1995     {
1996       /* Non periodic transfer */
1997       case EP_TYPE_CTRL:
1998       case EP_TYPE_BULK:
1999 
2000         len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2001 
2002         /* check if there is enough space in FIFO space */
2003         if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
2004         {
2005           /* need to process data in nptxfempty interrupt */
2006           USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
2007         }
2008         break;
2009 
2010       /* Periodic transfer */
2011       case EP_TYPE_INTR:
2012       case EP_TYPE_ISOC:
2013         len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2014         /* check if there is enough space in FIFO space */
2015         if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
2016         {
2017           /* need to process data in ptxfempty interrupt */
2018           USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
2019         }
2020         break;
2021 
2022       default:
2023         break;
2024     }
2025 
2026     /* Write packet into the Tx FIFO. */
2027     (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
2028   }
2029 
2030   return HAL_OK;
2031 }
2032 
2033 /**
2034   * @brief Read all host channel interrupts status
2035   * @param  USBx  Selected device
2036   * @retval HAL state
2037   */
USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef * USBx)2038 uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
2039 {
2040   uint32_t USBx_BASE = (uint32_t)USBx;
2041 
2042   return ((USBx_HOST->HAINT) & 0xFFFFU);
2043 }
2044 
2045 /**
2046   * @brief  Halt a host channel
2047   * @param  USBx  Selected device
2048   * @param  hc_num  Host Channel number
2049   *         This parameter can be a value from 1 to 15
2050   * @retval HAL state
2051   */
USB_HC_Halt(const USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)2052 HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
2053 {
2054   uint32_t USBx_BASE = (uint32_t)USBx;
2055   uint32_t hcnum = (uint32_t)hc_num;
2056   __IO uint32_t count = 0U;
2057   uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
2058   uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
2059   uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
2060 
2061   /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
2062      At the end of the next uframe/frame (in the worst case), the core generates a channel halted
2063      and disables the channel automatically. */
2064 
2065   if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
2066       ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
2067   {
2068     return HAL_OK;
2069   }
2070 
2071   /* Check for space in the request queue to issue the halt. */
2072   if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
2073   {
2074     USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2075 
2076     if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
2077     {
2078       if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
2079       {
2080         USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2081         USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2082         do
2083         {
2084           count++;
2085 
2086           if (count > 1000U)
2087           {
2088             break;
2089           }
2090         } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2091       }
2092       else
2093       {
2094         USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2095       }
2096     }
2097     else
2098     {
2099       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2100     }
2101   }
2102   else
2103   {
2104     USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2105 
2106     if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
2107     {
2108       USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2109       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2110       do
2111       {
2112         count++;
2113 
2114         if (count > 1000U)
2115         {
2116           break;
2117         }
2118       } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2119     }
2120     else
2121     {
2122       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2123     }
2124   }
2125 
2126   return HAL_OK;
2127 }
2128 
2129 /**
2130   * @brief  Initiate Do Ping protocol
2131   * @param  USBx  Selected device
2132   * @param  hc_num  Host Channel number
2133   *         This parameter can be a value from 1 to 15
2134   * @retval HAL state
2135   */
USB_DoPing(const USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)2136 HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
2137 {
2138   uint32_t USBx_BASE = (uint32_t)USBx;
2139   uint32_t chnum = (uint32_t)ch_num;
2140   uint32_t num_packets = 1U;
2141   uint32_t tmpreg;
2142 
2143   USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
2144                            USB_OTG_HCTSIZ_DOPING;
2145 
2146   /* Set host channel enable */
2147   tmpreg = USBx_HC(chnum)->HCCHAR;
2148   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2149   tmpreg |= USB_OTG_HCCHAR_CHENA;
2150   USBx_HC(chnum)->HCCHAR = tmpreg;
2151 
2152   return HAL_OK;
2153 }
2154 
2155 /**
2156   * @brief  Stop Host Core
2157   * @param  USBx  Selected device
2158   * @retval HAL state
2159   */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)2160 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
2161 {
2162   HAL_StatusTypeDef ret = HAL_OK;
2163   uint32_t USBx_BASE = (uint32_t)USBx;
2164   __IO uint32_t count = 0U;
2165   uint32_t value;
2166   uint32_t i;
2167 
2168   (void)USB_DisableGlobalInt(USBx);
2169 
2170   /* Flush USB FIFO */
2171   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
2172   {
2173     ret = HAL_ERROR;
2174   }
2175 
2176   if (USB_FlushRxFifo(USBx) != HAL_OK)
2177   {
2178     ret = HAL_ERROR;
2179   }
2180 
2181   /* Flush out any leftover queued requests. */
2182   for (i = 0U; i <= 15U; i++)
2183   {
2184     value = USBx_HC(i)->HCCHAR;
2185     value |=  USB_OTG_HCCHAR_CHDIS;
2186     value &= ~USB_OTG_HCCHAR_CHENA;
2187     value &= ~USB_OTG_HCCHAR_EPDIR;
2188     USBx_HC(i)->HCCHAR = value;
2189   }
2190 
2191   /* Halt all channels to put them into a known state. */
2192   for (i = 0U; i <= 15U; i++)
2193   {
2194     value = USBx_HC(i)->HCCHAR;
2195     value |= USB_OTG_HCCHAR_CHDIS;
2196     value |= USB_OTG_HCCHAR_CHENA;
2197     value &= ~USB_OTG_HCCHAR_EPDIR;
2198     USBx_HC(i)->HCCHAR = value;
2199 
2200     do
2201     {
2202       count++;
2203 
2204       if (count > 1000U)
2205       {
2206         break;
2207       }
2208     } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2209   }
2210 
2211   /* Clear any pending Host interrupts */
2212   USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
2213   USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
2214 
2215   (void)USB_EnableGlobalInt(USBx);
2216 
2217   return ret;
2218 }
2219 
2220 /**
2221   * @brief  USB_ActivateRemoteWakeup active remote wakeup signalling
2222   * @param  USBx Selected device
2223   * @retval HAL status
2224   */
USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)2225 HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2226 {
2227   uint32_t USBx_BASE = (uint32_t)USBx;
2228 
2229   if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2230   {
2231     /* active Remote wakeup signalling */
2232     USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2233   }
2234 
2235   return HAL_OK;
2236 }
2237 
2238 /**
2239   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2240   * @param  USBx Selected device
2241   * @retval HAL status
2242   */
USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)2243 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2244 {
2245   uint32_t USBx_BASE = (uint32_t)USBx;
2246 
2247   /* active Remote wakeup signalling */
2248   USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2249 
2250   return HAL_OK;
2251 }
2252 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2253 
2254 /**
2255   * @}
2256   */
2257 
2258 /**
2259   * @}
2260   */
2261 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2262 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2263 
2264 /**
2265   * @}
2266   */
2267