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