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