1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_ll_usb.c
4   * @author  MCD Application Team
5   * @brief   USB Low Layer HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the USB Peripheral Controller:
9   *           + Initialization/de-initialization functions
10   *           + I/O operation functions
11   *           + Peripheral Control functions
12   *           + Peripheral State functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2016 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                     ##### How to use this driver #####
28   ==============================================================================
29     [..]
30       (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
31 
32       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
33 
34       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
35 
36   @endverbatim
37 
38   ******************************************************************************
39   */
40 
41 /* Includes ------------------------------------------------------------------*/
42 #include "stm32f4xx_hal.h"
43 
44 /** @addtogroup STM32F4xx_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     USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
126     USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
127   }
128 
129   return ret;
130 }
131 
132 
133 /**
134   * @brief  Set the USB turnaround time
135   * @param  USBx USB Instance
136   * @param  hclk: AHB clock frequency
137   * @retval USB turnaround time In PHY Clocks number
138   */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)139 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
140                                         uint32_t hclk, uint8_t speed)
141 {
142   uint32_t UsbTrd;
143 
144   /* The USBTRD is configured according to the tables below, depending on AHB frequency
145   used by application. In the low AHB frequency range it is used to stretch enough the USB response
146   time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
147   latency to the Data FIFO */
148   if (speed == USBD_FS_SPEED)
149   {
150     if ((hclk >= 14200000U) && (hclk < 15000000U))
151     {
152       /* hclk Clock Range between 14.2-15 MHz */
153       UsbTrd = 0xFU;
154     }
155     else if ((hclk >= 15000000U) && (hclk < 16000000U))
156     {
157       /* hclk Clock Range between 15-16 MHz */
158       UsbTrd = 0xEU;
159     }
160     else if ((hclk >= 16000000U) && (hclk < 17200000U))
161     {
162       /* hclk Clock Range between 16-17.2 MHz */
163       UsbTrd = 0xDU;
164     }
165     else if ((hclk >= 17200000U) && (hclk < 18500000U))
166     {
167       /* hclk Clock Range between 17.2-18.5 MHz */
168       UsbTrd = 0xCU;
169     }
170     else if ((hclk >= 18500000U) && (hclk < 20000000U))
171     {
172       /* hclk Clock Range between 18.5-20 MHz */
173       UsbTrd = 0xBU;
174     }
175     else if ((hclk >= 20000000U) && (hclk < 21800000U))
176     {
177       /* hclk Clock Range between 20-21.8 MHz */
178       UsbTrd = 0xAU;
179     }
180     else if ((hclk >= 21800000U) && (hclk < 24000000U))
181     {
182       /* hclk Clock Range between 21.8-24 MHz */
183       UsbTrd = 0x9U;
184     }
185     else if ((hclk >= 24000000U) && (hclk < 27700000U))
186     {
187       /* hclk Clock Range between 24-27.7 MHz */
188       UsbTrd = 0x8U;
189     }
190     else if ((hclk >= 27700000U) && (hclk < 32000000U))
191     {
192       /* hclk Clock Range between 27.7-32 MHz */
193       UsbTrd = 0x7U;
194     }
195     else /* if(hclk >= 32000000) */
196     {
197       /* hclk Clock Range between 32-200 MHz */
198       UsbTrd = 0x6U;
199     }
200   }
201   else if (speed == USBD_HS_SPEED)
202   {
203     UsbTrd = USBD_HS_TRDT_VALUE;
204   }
205   else
206   {
207     UsbTrd = USBD_DEFAULT_TRDT_VALUE;
208   }
209 
210   USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
211   USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
212 
213   return HAL_OK;
214 }
215 
216 /**
217   * @brief  USB_EnableGlobalInt
218   *         Enables the controller's Global Int in the AHB Config reg
219   * @param  USBx  Selected device
220   * @retval HAL status
221   */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)222 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
223 {
224   USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
225   return HAL_OK;
226 }
227 
228 /**
229   * @brief  USB_DisableGlobalInt
230   *         Disable the controller's Global Int in the AHB Config reg
231   * @param  USBx  Selected device
232   * @retval HAL status
233   */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)234 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
235 {
236   USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
237   return HAL_OK;
238 }
239 
240 /**
241   * @brief  USB_SetCurrentMode Set functional mode
242   * @param  USBx  Selected device
243   * @param  mode  current core mode
244   *          This parameter can be one of these values:
245   *            @arg USB_DEVICE_MODE Peripheral mode
246   *            @arg USB_HOST_MODE Host mode
247   * @retval HAL status
248   */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_OTG_ModeTypeDef mode)249 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
250 {
251   uint32_t ms = 0U;
252 
253   USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
254 
255   if (mode == USB_HOST_MODE)
256   {
257     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
258 
259     do
260     {
261       HAL_Delay(10U);
262       ms += 10U;
263     } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
264   }
265   else if (mode == USB_DEVICE_MODE)
266   {
267     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
268 
269     do
270     {
271       HAL_Delay(10U);
272       ms += 10U;
273     } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
274   }
275   else
276   {
277     return HAL_ERROR;
278   }
279 
280   if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
281   {
282     return HAL_ERROR;
283   }
284 
285   return HAL_OK;
286 }
287 
288 /**
289   * @brief  USB_DevInit Initializes the USB_OTG controller registers
290   *         for device mode
291   * @param  USBx  Selected device
292   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
293   *         the configuration information for the specified USBx peripheral.
294   * @retval HAL status
295   */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)296 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
297 {
298   HAL_StatusTypeDef ret = HAL_OK;
299   uint32_t USBx_BASE = (uint32_t)USBx;
300   uint32_t i;
301 
302   for (i = 0U; i < 15U; i++)
303   {
304     USBx->DIEPTXF[i] = 0U;
305   }
306 
307 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
308  || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
309  || defined(STM32F423xx)
310   /* VBUS Sensing setup */
311   if (cfg.vbus_sensing_enable == 0U)
312   {
313     USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
314 
315     /* Deactivate VBUS Sensing B */
316     USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
317 
318     /* B-peripheral session valid override enable */
319     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
320     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
321   }
322   else
323   {
324     /* Enable HW VBUS sensing */
325     USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
326   }
327 #else
328   /* VBUS Sensing setup */
329   if (cfg.vbus_sensing_enable == 0U)
330   {
331     /*
332      * Disable HW VBUS sensing. VBUS is internally considered to be always
333      * at VBUS-Valid level (5V).
334      */
335     USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
336     USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
337     USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
338     USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
339   }
340   else
341   {
342     /* Enable HW VBUS sensing */
343     USBx->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
344     USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
345   }
346 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
347           defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
348           defined(STM32F423xx) */
349 
350   /* Restart the Phy Clock */
351   USBx_PCGCCTL = 0U;
352 
353   if (cfg.phy_itface == USB_OTG_ULPI_PHY)
354   {
355     if (cfg.speed == USBD_HS_SPEED)
356     {
357       /* Set Core speed to High speed mode */
358       (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
359     }
360     else
361     {
362       /* Set Core speed to Full speed mode */
363       (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
364     }
365   }
366   else
367   {
368     /* Set Core speed to Full speed mode */
369     (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
370   }
371 
372   /* Flush the FIFOs */
373   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
374   {
375     ret = HAL_ERROR;
376   }
377 
378   if (USB_FlushRxFifo(USBx) != HAL_OK)
379   {
380     ret = HAL_ERROR;
381   }
382 
383   /* Clear all pending Device Interrupts */
384   USBx_DEVICE->DIEPMSK = 0U;
385   USBx_DEVICE->DOEPMSK = 0U;
386   USBx_DEVICE->DAINTMSK = 0U;
387 
388   for (i = 0U; i < cfg.dev_endpoints; i++)
389   {
390     if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
391     {
392       if (i == 0U)
393       {
394         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
395       }
396       else
397       {
398         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
399       }
400     }
401     else
402     {
403       USBx_INEP(i)->DIEPCTL = 0U;
404     }
405 
406     USBx_INEP(i)->DIEPTSIZ = 0U;
407     USBx_INEP(i)->DIEPINT  = 0xFB7FU;
408   }
409 
410   for (i = 0U; i < cfg.dev_endpoints; i++)
411   {
412     if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
413     {
414       if (i == 0U)
415       {
416         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
417       }
418       else
419       {
420         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
421       }
422     }
423     else
424     {
425       USBx_OUTEP(i)->DOEPCTL = 0U;
426     }
427 
428     USBx_OUTEP(i)->DOEPTSIZ = 0U;
429     USBx_OUTEP(i)->DOEPINT  = 0xFB7FU;
430   }
431 
432   USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
433 
434   /* Disable all interrupts. */
435   USBx->GINTMSK = 0U;
436 
437   /* Clear any pending interrupts */
438   USBx->GINTSTS = 0xBFFFFFFFU;
439 
440   /* Enable the common interrupts */
441   if (cfg.dma_enable == 0U)
442   {
443     USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
444   }
445 
446   /* Enable interrupts matching to the Device mode ONLY */
447   USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
448                    USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
449                    USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM |
450                    USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
451 
452   if (cfg.Sof_enable != 0U)
453   {
454     USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
455   }
456 
457   if (cfg.vbus_sensing_enable == 1U)
458   {
459     USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
460   }
461 
462   return ret;
463 }
464 
465 /**
466   * @brief  USB_FlushTxFifo Flush a Tx FIFO
467   * @param  USBx  Selected device
468   * @param  num  FIFO number
469   *         This parameter can be a value from 1 to 15
470             15 means Flush all Tx FIFOs
471   * @retval HAL status
472   */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)473 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
474 {
475   __IO uint32_t count = 0U;
476 
477   /* Wait for AHB master IDLE state. */
478   do
479   {
480     count++;
481 
482     if (count > HAL_USB_TIMEOUT)
483     {
484       return HAL_TIMEOUT;
485     }
486   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
487 
488   /* Flush TX Fifo */
489   count = 0U;
490   USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
491 
492   do
493   {
494     count++;
495 
496     if (count > HAL_USB_TIMEOUT)
497     {
498       return HAL_TIMEOUT;
499     }
500   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
501 
502   return HAL_OK;
503 }
504 
505 /**
506   * @brief  USB_FlushRxFifo  Flush Rx FIFO
507   * @param  USBx  Selected device
508   * @retval HAL status
509   */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)510 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
511 {
512   __IO uint32_t count = 0U;
513 
514   /* Wait for AHB master IDLE state. */
515   do
516   {
517     count++;
518 
519     if (count > HAL_USB_TIMEOUT)
520     {
521       return HAL_TIMEOUT;
522     }
523   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
524 
525   /* Flush RX Fifo */
526   count = 0U;
527   USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
528 
529   do
530   {
531     count++;
532 
533     if (count > HAL_USB_TIMEOUT)
534     {
535       return HAL_TIMEOUT;
536     }
537   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
538 
539   return HAL_OK;
540 }
541 
542 /**
543   * @brief  USB_SetDevSpeed  Initializes the DevSpd field of DCFG register
544   *         depending the PHY type and the enumeration speed of the device.
545   * @param  USBx  Selected device
546   * @param  speed  device speed
547   *          This parameter can be one of these values:
548   *            @arg USB_OTG_SPEED_HIGH: High speed mode
549   *            @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
550   *            @arg USB_OTG_SPEED_FULL: Full speed mode
551   * @retval  Hal status
552   */
USB_SetDevSpeed(const USB_OTG_GlobalTypeDef * USBx,uint8_t speed)553 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
554 {
555   uint32_t USBx_BASE = (uint32_t)USBx;
556 
557   USBx_DEVICE->DCFG |= speed;
558   return HAL_OK;
559 }
560 
561 /**
562   * @brief  USB_GetDevSpeed  Return the Dev Speed
563   * @param  USBx  Selected device
564   * @retval speed  device speed
565   *          This parameter can be one of these values:
566   *            @arg USBD_HS_SPEED: High speed mode
567   *            @arg USBD_FS_SPEED: Full speed mode
568   */
USB_GetDevSpeed(const USB_OTG_GlobalTypeDef * USBx)569 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
570 {
571   uint32_t USBx_BASE = (uint32_t)USBx;
572   uint8_t speed;
573   uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
574 
575   if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
576   {
577     speed = USBD_HS_SPEED;
578   }
579   else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
580            (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
581   {
582     speed = USBD_FS_SPEED;
583   }
584   else
585   {
586     speed = 0xFU;
587   }
588 
589   return speed;
590 }
591 
592 /**
593   * @brief  Activate and configure an endpoint
594   * @param  USBx  Selected device
595   * @param  ep pointer to endpoint structure
596   * @retval HAL status
597   */
USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)598 HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
599 {
600   uint32_t USBx_BASE = (uint32_t)USBx;
601   uint32_t epnum = (uint32_t)ep->num;
602 
603   if (ep->is_in == 1U)
604   {
605     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
606 
607     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
608     {
609       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
610                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
611                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
612                                    USB_OTG_DIEPCTL_USBAEP;
613     }
614   }
615   else
616   {
617     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
618 
619     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
620     {
621       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
622                                     ((uint32_t)ep->type << 18) |
623                                     USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
624                                     USB_OTG_DOEPCTL_USBAEP;
625     }
626   }
627   return HAL_OK;
628 }
629 
630 /**
631   * @brief  Activate and configure a dedicated endpoint
632   * @param  USBx  Selected device
633   * @param  ep pointer to endpoint structure
634   * @retval HAL status
635   */
USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)636 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
637 {
638   uint32_t USBx_BASE = (uint32_t)USBx;
639   uint32_t epnum = (uint32_t)ep->num;
640 
641   /* Read DEPCTLn register */
642   if (ep->is_in == 1U)
643   {
644     if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
645     {
646       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
647                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
648                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
649                                    USB_OTG_DIEPCTL_USBAEP;
650     }
651 
652     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
653   }
654   else
655   {
656     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
657     {
658       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
659                                     ((uint32_t)ep->type << 18) | (epnum << 22) |
660                                     USB_OTG_DOEPCTL_USBAEP;
661     }
662 
663     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
664   }
665 
666   return HAL_OK;
667 }
668 
669 /**
670   * @brief  De-activate and de-initialize an endpoint
671   * @param  USBx  Selected device
672   * @param  ep pointer to endpoint structure
673   * @retval HAL status
674   */
USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)675 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
676 {
677   uint32_t USBx_BASE = (uint32_t)USBx;
678   uint32_t epnum = (uint32_t)ep->num;
679 
680   /* Read DEPCTLn register */
681   if (ep->is_in == 1U)
682   {
683     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
684     {
685       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
686       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
687     }
688 
689     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
690     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
691     USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
692                                    USB_OTG_DIEPCTL_MPSIZ |
693                                    USB_OTG_DIEPCTL_TXFNUM |
694                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
695                                    USB_OTG_DIEPCTL_EPTYP);
696   }
697   else
698   {
699     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
700     {
701       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
702       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
703     }
704 
705     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
706     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
707     USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
708                                     USB_OTG_DOEPCTL_MPSIZ |
709                                     USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
710                                     USB_OTG_DOEPCTL_EPTYP);
711   }
712 
713   return HAL_OK;
714 }
715 
716 /**
717   * @brief  De-activate and de-initialize a dedicated endpoint
718   * @param  USBx  Selected device
719   * @param  ep pointer to endpoint structure
720   * @retval HAL status
721   */
USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)722 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
723 {
724   uint32_t USBx_BASE = (uint32_t)USBx;
725   uint32_t epnum = (uint32_t)ep->num;
726 
727   /* Read DEPCTLn register */
728   if (ep->is_in == 1U)
729   {
730     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
731     {
732       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_SNAK;
733       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_EPDIS;
734     }
735 
736     USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
737     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
738   }
739   else
740   {
741     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
742     {
743       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_SNAK;
744       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_EPDIS;
745     }
746 
747     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
748     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
749   }
750 
751   return HAL_OK;
752 }
753 
754 /**
755   * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
756   * @param  USBx  Selected device
757   * @param  ep pointer to endpoint structure
758   * @param  dma USB dma enabled or disabled
759   *          This parameter can be one of these values:
760   *           0 : DMA feature not used
761   *           1 : DMA feature used
762   * @retval HAL status
763   */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)764 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
765 {
766   uint32_t USBx_BASE = (uint32_t)USBx;
767   uint32_t epnum = (uint32_t)ep->num;
768   uint16_t pktcnt;
769 
770   /* IN endpoint */
771   if (ep->is_in == 1U)
772   {
773     /* Zero Length Packet? */
774     if (ep->xfer_len == 0U)
775     {
776       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
777       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
778       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
779     }
780     else
781     {
782       /* Program the transfer size and packet count
783       * as follows: xfersize = N * maxpacket +
784       * short_packet pktcnt = N + (short_packet
785       * exist ? 1 : 0)
786       */
787       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
788       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
789 
790       if (epnum == 0U)
791       {
792         if (ep->xfer_len > ep->maxpacket)
793         {
794           ep->xfer_len = ep->maxpacket;
795         }
796 
797         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
798       }
799       else
800       {
801         pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
802         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
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 & (pktcnt << 29));
808         }
809       }
810 
811       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
812     }
813 
814     if (dma == 1U)
815     {
816       if ((uint32_t)ep->dma_addr != 0U)
817       {
818         USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
819       }
820 
821       if (ep->type == EP_TYPE_ISOC)
822       {
823         if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
824         {
825           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
826         }
827         else
828         {
829           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
830         }
831       }
832 
833       /* EP enable, IN data in FIFO */
834       USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
835     }
836     else
837     {
838       /* EP enable, IN data in FIFO */
839       USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
840 
841       if (ep->type != EP_TYPE_ISOC)
842       {
843         /* Enable the Tx FIFO Empty Interrupt for this EP */
844         if (ep->xfer_len > 0U)
845         {
846           USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
847         }
848       }
849       else
850       {
851         if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
852         {
853           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
854         }
855         else
856         {
857           USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
858         }
859 
860         (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
861       }
862     }
863   }
864   else /* OUT endpoint */
865   {
866     /* Program the transfer size and packet count as follows:
867     * pktcnt = N
868     * xfersize = N * maxpacket
869     */
870     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
871     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
872 
873     if (epnum == 0U)
874     {
875       if (ep->xfer_len > 0U)
876       {
877         ep->xfer_len = ep->maxpacket;
878       }
879 
880       /* Store transfer size, for EP0 this is equal to endpoint max packet size */
881       ep->xfer_size = ep->maxpacket;
882 
883       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
884       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
885     }
886     else
887     {
888       if (ep->xfer_len == 0U)
889       {
890         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
891         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
892       }
893       else
894       {
895         pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
896         ep->xfer_size = ep->maxpacket * pktcnt;
897 
898         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
899         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
900       }
901     }
902 
903     if (dma == 1U)
904     {
905       if ((uint32_t)ep->xfer_buff != 0U)
906       {
907         USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
908       }
909     }
910 
911     if (ep->type == EP_TYPE_ISOC)
912     {
913       if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
914       {
915         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
916       }
917       else
918       {
919         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
920       }
921     }
922     /* EP enable */
923     USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
924   }
925 
926   return HAL_OK;
927 }
928 
929 
930 /**
931    * @brief  USB_EPStoptXfer  Stop transfer on an EP
932    * @param  USBx  usb device instance
933    * @param  ep pointer to endpoint structure
934    * @retval HAL status
935    */
USB_EPStopXfer(const USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)936 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
937 {
938   __IO uint32_t count = 0U;
939   HAL_StatusTypeDef ret = HAL_OK;
940   uint32_t USBx_BASE = (uint32_t)USBx;
941 
942   /* IN endpoint */
943   if (ep->is_in == 1U)
944   {
945     /* EP enable, IN data in FIFO */
946     if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
947     {
948       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
949       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
950 
951       do
952       {
953         count++;
954 
955         if (count > 10000U)
956         {
957           ret = HAL_ERROR;
958           break;
959         }
960       } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) ==  USB_OTG_DIEPCTL_EPENA);
961     }
962   }
963   else /* OUT endpoint */
964   {
965     if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
966     {
967       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
968       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
969 
970       do
971       {
972         count++;
973 
974         if (count > 10000U)
975         {
976           ret = HAL_ERROR;
977           break;
978         }
979       } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) ==  USB_OTG_DOEPCTL_EPENA);
980     }
981   }
982 
983   return ret;
984 }
985 
986 
987 /**
988   * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
989   *         with the EP/channel
990   * @param  USBx  Selected device
991   * @param  src   pointer to source buffer
992   * @param  ch_ep_num  endpoint or host channel number
993   * @param  len  Number of bytes to write
994   * @param  dma USB dma enabled or disabled
995   *          This parameter can be one of these values:
996   *           0 : DMA feature not used
997   *           1 : DMA feature used
998   * @retval HAL status
999   */
USB_WritePacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len,uint8_t dma)1000 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
1001                                   uint8_t ch_ep_num, uint16_t len, uint8_t dma)
1002 {
1003   uint32_t USBx_BASE = (uint32_t)USBx;
1004   uint8_t *pSrc = src;
1005   uint32_t count32b;
1006   uint32_t i;
1007 
1008   if (dma == 0U)
1009   {
1010     count32b = ((uint32_t)len + 3U) / 4U;
1011     for (i = 0U; i < count32b; i++)
1012     {
1013       USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
1014       pSrc++;
1015       pSrc++;
1016       pSrc++;
1017       pSrc++;
1018     }
1019   }
1020 
1021   return HAL_OK;
1022 }
1023 
1024 /**
1025   * @brief  USB_ReadPacket : read a packet from the RX FIFO
1026   * @param  USBx  Selected device
1027   * @param  dest  source pointer
1028   * @param  len  Number of bytes to read
1029   * @retval pointer to destination buffer
1030   */
USB_ReadPacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)1031 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1032 {
1033   uint32_t USBx_BASE = (uint32_t)USBx;
1034   uint8_t *pDest = dest;
1035   uint32_t pData;
1036   uint32_t i;
1037   uint32_t count32b = (uint32_t)len >> 2U;
1038   uint16_t remaining_bytes = len % 4U;
1039 
1040   for (i = 0U; i < count32b; i++)
1041   {
1042     __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1043     pDest++;
1044     pDest++;
1045     pDest++;
1046     pDest++;
1047   }
1048 
1049   /* When Number of data is not word aligned, read the remaining byte */
1050   if (remaining_bytes != 0U)
1051   {
1052     i = 0U;
1053     __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1054 
1055     do
1056     {
1057       *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1058       i++;
1059       pDest++;
1060       remaining_bytes--;
1061     } while (remaining_bytes != 0U);
1062   }
1063 
1064   return ((void *)pDest);
1065 }
1066 
1067 /**
1068   * @brief  USB_EPSetStall : set a stall condition over an EP
1069   * @param  USBx  Selected device
1070   * @param  ep pointer to endpoint structure
1071   * @retval HAL status
1072   */
USB_EPSetStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1073 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1074 {
1075   uint32_t USBx_BASE = (uint32_t)USBx;
1076   uint32_t epnum = (uint32_t)ep->num;
1077 
1078   if (ep->is_in == 1U)
1079   {
1080     if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1081     {
1082       USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1083     }
1084     USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1085   }
1086   else
1087   {
1088     if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1089     {
1090       USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1091     }
1092     USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1093   }
1094 
1095   return HAL_OK;
1096 }
1097 
1098 /**
1099   * @brief  USB_EPClearStall : Clear a stall condition over an EP
1100   * @param  USBx  Selected device
1101   * @param  ep pointer to endpoint structure
1102   * @retval HAL status
1103   */
USB_EPClearStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1104 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1105 {
1106   uint32_t USBx_BASE = (uint32_t)USBx;
1107   uint32_t epnum = (uint32_t)ep->num;
1108 
1109   if (ep->is_in == 1U)
1110   {
1111     USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1112     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1113     {
1114       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1115     }
1116   }
1117   else
1118   {
1119     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1120     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1121     {
1122       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1123     }
1124   }
1125   return HAL_OK;
1126 }
1127 
1128 /**
1129   * @brief  USB_StopDevice : Stop the usb device mode
1130   * @param  USBx  Selected device
1131   * @retval HAL status
1132   */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1133 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1134 {
1135   HAL_StatusTypeDef ret;
1136   uint32_t USBx_BASE = (uint32_t)USBx;
1137   uint32_t i;
1138 
1139   /* Clear Pending interrupt */
1140   for (i = 0U; i < 15U; i++)
1141   {
1142     USBx_INEP(i)->DIEPINT = 0xFB7FU;
1143     USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1144   }
1145 
1146   /* Clear interrupt masks */
1147   USBx_DEVICE->DIEPMSK  = 0U;
1148   USBx_DEVICE->DOEPMSK  = 0U;
1149   USBx_DEVICE->DAINTMSK = 0U;
1150 
1151   /* Flush the FIFO */
1152   ret = USB_FlushRxFifo(USBx);
1153   if (ret != HAL_OK)
1154   {
1155     return ret;
1156   }
1157 
1158   ret = USB_FlushTxFifo(USBx,  0x10U);
1159   if (ret != HAL_OK)
1160   {
1161     return ret;
1162   }
1163 
1164   return ret;
1165 }
1166 
1167 /**
1168   * @brief  USB_SetDevAddress : Stop the usb device mode
1169   * @param  USBx  Selected device
1170   * @param  address  new device address to be assigned
1171   *          This parameter can be a value from 0 to 255
1172   * @retval HAL status
1173   */
USB_SetDevAddress(const USB_OTG_GlobalTypeDef * USBx,uint8_t address)1174 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1175 {
1176   uint32_t USBx_BASE = (uint32_t)USBx;
1177 
1178   USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1179   USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1180 
1181   return HAL_OK;
1182 }
1183 
1184 /**
1185   * @brief  USB_DevConnect : Connect the USB device by enabling Rpu
1186   * @param  USBx  Selected device
1187   * @retval HAL status
1188   */
USB_DevConnect(const USB_OTG_GlobalTypeDef * USBx)1189 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1190 {
1191   uint32_t USBx_BASE = (uint32_t)USBx;
1192 
1193   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1194   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1195 
1196   USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1197 
1198   return HAL_OK;
1199 }
1200 
1201 /**
1202   * @brief  USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1203   * @param  USBx  Selected device
1204   * @retval HAL status
1205   */
USB_DevDisconnect(const USB_OTG_GlobalTypeDef * USBx)1206 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1207 {
1208   uint32_t USBx_BASE = (uint32_t)USBx;
1209 
1210   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1211   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1212 
1213   USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1214 
1215   return HAL_OK;
1216 }
1217 
1218 /**
1219   * @brief  USB_ReadInterrupts: return the global USB interrupt status
1220   * @param  USBx  Selected device
1221   * @retval USB Global Interrupt status
1222   */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef const * USBx)1223 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1224 {
1225   uint32_t tmpreg;
1226 
1227   tmpreg = USBx->GINTSTS;
1228   tmpreg &= USBx->GINTMSK;
1229 
1230   return tmpreg;
1231 }
1232 
1233 /**
1234   * @brief  USB_ReadChInterrupts: return USB channel interrupt status
1235   * @param  USBx  Selected device
1236   * @param  chnum Channel number
1237   * @retval USB Channel Interrupt status
1238   */
USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef * USBx,uint8_t chnum)1239 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1240 {
1241   uint32_t USBx_BASE = (uint32_t)USBx;
1242   uint32_t tmpreg;
1243 
1244   tmpreg = USBx_HC(chnum)->HCINT;
1245   tmpreg &= USBx_HC(chnum)->HCINTMSK;
1246 
1247   return tmpreg;
1248 }
1249 
1250 /**
1251   * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1252   * @param  USBx  Selected device
1253   * @retval USB Device OUT EP interrupt status
1254   */
USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1255 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1256 {
1257   uint32_t USBx_BASE = (uint32_t)USBx;
1258   uint32_t tmpreg;
1259 
1260   tmpreg  = USBx_DEVICE->DAINT;
1261   tmpreg &= USBx_DEVICE->DAINTMSK;
1262 
1263   return ((tmpreg & 0xffff0000U) >> 16);
1264 }
1265 
1266 /**
1267   * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1268   * @param  USBx  Selected device
1269   * @retval USB Device IN EP interrupt status
1270   */
USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1271 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1272 {
1273   uint32_t USBx_BASE = (uint32_t)USBx;
1274   uint32_t tmpreg;
1275 
1276   tmpreg  = USBx_DEVICE->DAINT;
1277   tmpreg &= USBx_DEVICE->DAINTMSK;
1278 
1279   return ((tmpreg & 0xFFFFU));
1280 }
1281 
1282 /**
1283   * @brief  Returns Device OUT EP Interrupt register
1284   * @param  USBx  Selected device
1285   * @param  epnum  endpoint number
1286   *          This parameter can be a value from 0 to 15
1287   * @retval Device OUT EP Interrupt register
1288   */
USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1289 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1290 {
1291   uint32_t USBx_BASE = (uint32_t)USBx;
1292   uint32_t tmpreg;
1293 
1294   tmpreg  = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1295   tmpreg &= USBx_DEVICE->DOEPMSK;
1296 
1297   return tmpreg;
1298 }
1299 
1300 /**
1301   * @brief  Returns Device IN EP Interrupt register
1302   * @param  USBx  Selected device
1303   * @param  epnum  endpoint number
1304   *          This parameter can be a value from 0 to 15
1305   * @retval Device IN EP Interrupt register
1306   */
USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1307 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1308 {
1309   uint32_t USBx_BASE = (uint32_t)USBx;
1310   uint32_t tmpreg;
1311   uint32_t msk;
1312   uint32_t emp;
1313 
1314   msk = USBx_DEVICE->DIEPMSK;
1315   emp = USBx_DEVICE->DIEPEMPMSK;
1316   msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1317   tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1318 
1319   return tmpreg;
1320 }
1321 
1322 /**
1323   * @brief  USB_ClearInterrupts: clear a USB interrupt
1324   * @param  USBx  Selected device
1325   * @param  interrupt  flag
1326   * @retval None
1327   */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1328 void  USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1329 {
1330   USBx->GINTSTS &= interrupt;
1331 }
1332 
1333 /**
1334   * @brief  Returns USB core mode
1335   * @param  USBx  Selected device
1336   * @retval return core mode : Host or Device
1337   *          This parameter can be one of these values:
1338   *           0 : Host
1339   *           1 : Device
1340   */
USB_GetMode(const USB_OTG_GlobalTypeDef * USBx)1341 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1342 {
1343   return ((USBx->GINTSTS) & 0x1U);
1344 }
1345 
1346 /**
1347   * @brief  Activate EP0 for Setup transactions
1348   * @param  USBx  Selected device
1349   * @retval HAL status
1350   */
USB_ActivateSetup(const USB_OTG_GlobalTypeDef * USBx)1351 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1352 {
1353   uint32_t USBx_BASE = (uint32_t)USBx;
1354 
1355   /* Set the MPS of the IN EP0 to 64 bytes */
1356   USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1357 
1358   USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1359 
1360   return HAL_OK;
1361 }
1362 
1363 /**
1364   * @brief  Prepare the EP0 to start the first control setup
1365   * @param  USBx  Selected device
1366   * @param  dma USB dma enabled or disabled
1367   *          This parameter can be one of these values:
1368   *           0 : DMA feature not used
1369   *           1 : DMA feature used
1370   * @param  psetup  pointer to setup packet
1371   * @retval HAL status
1372   */
USB_EP0_OutStart(const USB_OTG_GlobalTypeDef * USBx,uint8_t dma,const uint8_t * psetup)1373 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup)
1374 {
1375   uint32_t USBx_BASE = (uint32_t)USBx;
1376   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1377 
1378   if (gSNPSiD > USB_OTG_CORE_ID_300A)
1379   {
1380     if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1381     {
1382       return HAL_OK;
1383     }
1384   }
1385 
1386   USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1387   USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1388   USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1389   USBx_OUTEP(0U)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;
1390 
1391   if (dma == 1U)
1392   {
1393     USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1394     /* EP enable */
1395     USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1396   }
1397 
1398   return HAL_OK;
1399 }
1400 
1401 /**
1402   * @brief  Reset the USB Core (needed after USB clock settings change)
1403   * @param  USBx  Selected device
1404   * @retval HAL status
1405   */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1406 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1407 {
1408   __IO uint32_t count = 0U;
1409 
1410   /* Wait for AHB master IDLE state. */
1411   do
1412   {
1413     count++;
1414 
1415     if (count > HAL_USB_TIMEOUT)
1416     {
1417       return HAL_TIMEOUT;
1418     }
1419   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1420 
1421   /* Core Soft Reset */
1422   count = 0U;
1423   USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1424 
1425   do
1426   {
1427     count++;
1428 
1429     if (count > HAL_USB_TIMEOUT)
1430     {
1431       return HAL_TIMEOUT;
1432     }
1433   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1434 
1435   return HAL_OK;
1436 }
1437 
1438 /**
1439   * @brief  USB_HostInit : Initializes the USB OTG controller registers
1440   *         for Host mode
1441   * @param  USBx  Selected device
1442   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
1443   *         the configuration information for the specified USBx peripheral.
1444   * @retval HAL status
1445   */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1446 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1447 {
1448   HAL_StatusTypeDef ret = HAL_OK;
1449   uint32_t USBx_BASE = (uint32_t)USBx;
1450   uint32_t i;
1451 
1452   /* Restart the Phy Clock */
1453   USBx_PCGCCTL = 0U;
1454 
1455 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
1456  || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
1457  || defined(STM32F423xx)
1458   /* Disable HW VBUS sensing */
1459   USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1460 #else
1461   /*
1462   * Disable HW VBUS sensing. VBUS is internally considered to be always
1463   * at VBUS-Valid level (5V).
1464   */
1465   USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
1466   USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
1467   USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
1468 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
1469           defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
1470           defined(STM32F423xx) */
1471 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) \
1472  || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1473   /* Disable Battery chargin detector */
1474   USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1475 #endif /* defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||
1476           defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
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