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