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