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