1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_ll_usb.c
4   * @author  MCD Application Team
5   * @brief   USB Low Layer HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the USB Peripheral Controller:
9   *           + Initialization/de-initialization functions
10   *           + I/O operation functions
11   *           + Peripheral Control functions
12   *           + Peripheral State functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2017 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                     ##### How to use this driver #####
28   ==============================================================================
29     [..]
30       (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
31 
32       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
33 
34       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
35 
36   @endverbatim
37 
38   ******************************************************************************
39   */
40 
41 /* Includes ------------------------------------------------------------------*/
42 #include "stm32l4xx_hal.h"
43 
44 /** @addtogroup STM32L4xx_LL_USB_DRIVER
45   * @{
46   */
47 
48 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49 #if defined (USB) || defined (USB_OTG_FS)
50 /* Private typedef -----------------------------------------------------------*/
51 /* Private define ------------------------------------------------------------*/
52 /* Private macro -------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 /* Private function prototypes -----------------------------------------------*/
55 /* Private functions ---------------------------------------------------------*/
56 #if defined (USB_OTG_FS)
57 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58 
59 /* Exported functions --------------------------------------------------------*/
60 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
61   * @{
62   */
63 
64 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
65   *  @brief    Initialization and Configuration functions
66   *
67 @verbatim
68  ===============================================================================
69                       ##### Initialization/de-initialization functions #####
70  ===============================================================================
71 
72 @endverbatim
73   * @{
74   */
75 
76 /**
77   * @brief  Initializes the USB Core
78   * @param  USBx USB Instance
79   * @param  cfg pointer to a USB_OTG_CfgTypeDef structure that contains
80   *         the configuration information for the specified USBx peripheral.
81   * @retval HAL status
82   */
USB_CoreInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)83 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
84 {
85   HAL_StatusTypeDef ret;
86 
87   /* Select FS Embedded PHY */
88   USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
89 
90   /* Reset after a PHY select */
91   ret = USB_CoreReset(USBx);
92 
93   if (cfg.battery_charging_enable == 0U)
94   {
95     /* Activate the USB Transceiver */
96     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
97   }
98   else
99   {
100     /* Deactivate the USB Transceiver */
101     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
102   }
103 
104   return ret;
105 }
106 
107 
108 /**
109   * @brief  Set the USB turnaround time
110   * @param  USBx USB Instance
111   * @param  hclk: AHB clock frequency
112   * @retval USB turnaround time In PHY Clocks number
113   */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)114 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
115                                         uint32_t hclk, uint8_t speed)
116 {
117   uint32_t UsbTrd;
118 
119   /* The USBTRD is configured according to the tables below, depending on AHB frequency
120   used by application. In the low AHB frequency range it is used to stretch enough the USB response
121   time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
122   latency to the Data FIFO */
123   if (speed == USBD_FS_SPEED)
124   {
125     if ((hclk >= 14200000U) && (hclk < 15000000U))
126     {
127       /* hclk Clock Range between 14.2-15 MHz */
128       UsbTrd = 0xFU;
129     }
130     else if ((hclk >= 15000000U) && (hclk < 16000000U))
131     {
132       /* hclk Clock Range between 15-16 MHz */
133       UsbTrd = 0xEU;
134     }
135     else if ((hclk >= 16000000U) && (hclk < 17200000U))
136     {
137       /* hclk Clock Range between 16-17.2 MHz */
138       UsbTrd = 0xDU;
139     }
140     else if ((hclk >= 17200000U) && (hclk < 18500000U))
141     {
142       /* hclk Clock Range between 17.2-18.5 MHz */
143       UsbTrd = 0xCU;
144     }
145     else if ((hclk >= 18500000U) && (hclk < 20000000U))
146     {
147       /* hclk Clock Range between 18.5-20 MHz */
148       UsbTrd = 0xBU;
149     }
150     else if ((hclk >= 20000000U) && (hclk < 21800000U))
151     {
152       /* hclk Clock Range between 20-21.8 MHz */
153       UsbTrd = 0xAU;
154     }
155     else if ((hclk >= 21800000U) && (hclk < 24000000U))
156     {
157       /* hclk Clock Range between 21.8-24 MHz */
158       UsbTrd = 0x9U;
159     }
160     else if ((hclk >= 24000000U) && (hclk < 27700000U))
161     {
162       /* hclk Clock Range between 24-27.7 MHz */
163       UsbTrd = 0x8U;
164     }
165     else if ((hclk >= 27700000U) && (hclk < 32000000U))
166     {
167       /* hclk Clock Range between 27.7-32 MHz */
168       UsbTrd = 0x7U;
169     }
170     else /* if(hclk >= 32000000) */
171     {
172       /* hclk Clock Range between 32-200 MHz */
173       UsbTrd = 0x6U;
174     }
175   }
176   else
177   {
178     UsbTrd = USBD_DEFAULT_TRDT_VALUE;
179   }
180 
181   USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
182   USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
183 
184   return HAL_OK;
185 }
186 
187 /**
188   * @brief  USB_EnableGlobalInt
189   *         Enables the controller's Global Int in the AHB Config reg
190   * @param  USBx  Selected device
191   * @retval HAL status
192   */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)193 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
194 {
195   USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
196   return HAL_OK;
197 }
198 
199 /**
200   * @brief  USB_DisableGlobalInt
201   *         Disable the controller's Global Int in the AHB Config reg
202   * @param  USBx  Selected device
203   * @retval HAL status
204   */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)205 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
206 {
207   USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
208   return HAL_OK;
209 }
210 
211 /**
212   * @brief  USB_SetCurrentMode Set functional mode
213   * @param  USBx  Selected device
214   * @param  mode  current core mode
215   *          This parameter can be one of these values:
216   *            @arg USB_DEVICE_MODE Peripheral mode
217   *            @arg USB_HOST_MODE Host mode
218   * @retval HAL status
219   */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_ModeTypeDef mode)220 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_ModeTypeDef mode)
221 {
222   uint32_t ms = 0U;
223 
224   USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
225 
226   if (mode == USB_HOST_MODE)
227   {
228     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
229 
230     do
231     {
232       HAL_Delay(10U);
233       ms += 10U;
234     } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
235   }
236   else if (mode == USB_DEVICE_MODE)
237   {
238     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
239 
240     do
241     {
242       HAL_Delay(10U);
243       ms += 10U;
244     } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
245   }
246   else
247   {
248     return HAL_ERROR;
249   }
250 
251   if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
252   {
253     return HAL_ERROR;
254   }
255 
256   return HAL_OK;
257 }
258 
259 /**
260   * @brief  USB_DevInit Initializes the USB_OTG controller registers
261   *         for device mode
262   * @param  USBx  Selected device
263   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
264   *         the configuration information for the specified USBx peripheral.
265   * @retval HAL status
266   */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)267 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
268 {
269   HAL_StatusTypeDef ret = HAL_OK;
270   uint32_t USBx_BASE = (uint32_t)USBx;
271   uint32_t i;
272 
273   for (i = 0U; i < 15U; i++)
274   {
275     USBx->DIEPTXF[i] = 0U;
276   }
277 
278   /* VBUS Sensing setup */
279   if (cfg.vbus_sensing_enable == 0U)
280   {
281     USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
282 
283     /* Deactivate VBUS Sensing B */
284     USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
285 
286     /* B-peripheral session valid override enable */
287     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
288     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
289   }
290   else
291   {
292     /* Enable HW VBUS sensing */
293     USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
294   }
295 
296   /* Restart the Phy Clock */
297   USBx_PCGCCTL = 0U;
298 
299   /* Set Core speed to Full speed mode */
300   (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
301 
302   /* Flush the FIFOs */
303   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
304   {
305     ret = HAL_ERROR;
306   }
307 
308   if (USB_FlushRxFifo(USBx) != HAL_OK)
309   {
310     ret = HAL_ERROR;
311   }
312 
313   /* Clear all pending Device Interrupts */
314   USBx_DEVICE->DIEPMSK = 0U;
315   USBx_DEVICE->DOEPMSK = 0U;
316   USBx_DEVICE->DAINTMSK = 0U;
317 
318   for (i = 0U; i < cfg.dev_endpoints; i++)
319   {
320     if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
321     {
322       if (i == 0U)
323       {
324         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
325       }
326       else
327       {
328         USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
329       }
330     }
331     else
332     {
333       USBx_INEP(i)->DIEPCTL = 0U;
334     }
335 
336     USBx_INEP(i)->DIEPTSIZ = 0U;
337     USBx_INEP(i)->DIEPINT  = 0xFB7FU;
338   }
339 
340   for (i = 0U; i < cfg.dev_endpoints; i++)
341   {
342     if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
343     {
344       if (i == 0U)
345       {
346         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
347       }
348       else
349       {
350         USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
351       }
352     }
353     else
354     {
355       USBx_OUTEP(i)->DOEPCTL = 0U;
356     }
357 
358     USBx_OUTEP(i)->DOEPTSIZ = 0U;
359     USBx_OUTEP(i)->DOEPINT  = 0xFB7FU;
360   }
361 
362   USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
363 
364   /* Disable all interrupts. */
365   USBx->GINTMSK = 0U;
366 
367   /* Clear any pending interrupts */
368   USBx->GINTSTS = 0xBFFFFFFFU;
369 
370   /* Enable the common interrupts */
371   USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
372 
373   /* Enable interrupts matching to the Device mode ONLY */
374   USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
375                    USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
376                    USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM |
377                    USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
378 
379   if (cfg.Sof_enable != 0U)
380   {
381     USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
382   }
383 
384   if (cfg.vbus_sensing_enable == 1U)
385   {
386     USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
387   }
388 
389   return ret;
390 }
391 
392 /**
393   * @brief  USB_FlushTxFifo Flush a Tx FIFO
394   * @param  USBx  Selected device
395   * @param  num  FIFO number
396   *         This parameter can be a value from 1 to 15
397             15 means Flush all Tx FIFOs
398   * @retval HAL status
399   */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)400 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
401 {
402   __IO uint32_t count = 0U;
403 
404   /* Wait for AHB master IDLE state. */
405   do
406   {
407     count++;
408 
409     if (count > HAL_USB_TIMEOUT)
410     {
411       return HAL_TIMEOUT;
412     }
413   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
414 
415   /* Flush TX Fifo */
416   count = 0U;
417   USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
418 
419   do
420   {
421     count++;
422 
423     if (count > HAL_USB_TIMEOUT)
424     {
425       return HAL_TIMEOUT;
426     }
427   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
428 
429   return HAL_OK;
430 }
431 
432 /**
433   * @brief  USB_FlushRxFifo  Flush Rx FIFO
434   * @param  USBx  Selected device
435   * @retval HAL status
436   */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)437 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
438 {
439   __IO uint32_t count = 0U;
440 
441   /* Wait for AHB master IDLE state. */
442   do
443   {
444     count++;
445 
446     if (count > HAL_USB_TIMEOUT)
447     {
448       return HAL_TIMEOUT;
449     }
450   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
451 
452   /* Flush RX Fifo */
453   count = 0U;
454   USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
455 
456   do
457   {
458     count++;
459 
460     if (count > HAL_USB_TIMEOUT)
461     {
462       return HAL_TIMEOUT;
463     }
464   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
465 
466   return HAL_OK;
467 }
468 
469 /**
470   * @brief  USB_SetDevSpeed  Initializes the DevSpd field of DCFG register
471   *         depending the PHY type and the enumeration speed of the device.
472   * @param  USBx  Selected device
473   * @param  speed  device speed
474   *          This parameter can be one of these values:
475   *            @arg USB_OTG_SPEED_FULL: Full speed mode
476   * @retval  Hal status
477   */
USB_SetDevSpeed(const USB_OTG_GlobalTypeDef * USBx,uint8_t speed)478 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
479 {
480   uint32_t USBx_BASE = (uint32_t)USBx;
481 
482   USBx_DEVICE->DCFG |= speed;
483   return HAL_OK;
484 }
485 
486 /**
487   * @brief  USB_GetDevSpeed  Return the Dev Speed
488   * @param  USBx  Selected device
489   * @retval speed  device speed
490   *          This parameter can be one of these values:
491   *            @arg USBD_FS_SPEED: Full speed mode
492   */
USB_GetDevSpeed(const USB_OTG_GlobalTypeDef * USBx)493 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
494 {
495   uint32_t USBx_BASE = (uint32_t)USBx;
496   uint8_t speed;
497   uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
498 
499   if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
500       (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
501   {
502     speed = USBD_FS_SPEED;
503   }
504   else
505   {
506     speed = 0xFU;
507   }
508 
509   return speed;
510 }
511 
512 /**
513   * @brief  Activate and configure an endpoint
514   * @param  USBx  Selected device
515   * @param  ep pointer to endpoint structure
516   * @retval HAL status
517   */
USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)518 HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
519 {
520   uint32_t USBx_BASE = (uint32_t)USBx;
521   uint32_t epnum = (uint32_t)ep->num;
522 
523   if (ep->is_in == 1U)
524   {
525     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
526 
527     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
528     {
529       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
530                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
531                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
532                                    USB_OTG_DIEPCTL_USBAEP;
533     }
534   }
535   else
536   {
537     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
538 
539     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
540     {
541       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
542                                     ((uint32_t)ep->type << 18) |
543                                     USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
544                                     USB_OTG_DOEPCTL_USBAEP;
545     }
546   }
547   return HAL_OK;
548 }
549 
550 /**
551   * @brief  Activate and configure a dedicated endpoint
552   * @param  USBx  Selected device
553   * @param  ep pointer to endpoint structure
554   * @retval HAL status
555   */
USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)556 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
557 {
558   uint32_t USBx_BASE = (uint32_t)USBx;
559   uint32_t epnum = (uint32_t)ep->num;
560 
561   /* Read DEPCTLn register */
562   if (ep->is_in == 1U)
563   {
564     if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
565     {
566       USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
567                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
568                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
569                                    USB_OTG_DIEPCTL_USBAEP;
570     }
571 
572     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
573   }
574   else
575   {
576     if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
577     {
578       USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
579                                     ((uint32_t)ep->type << 18) | (epnum << 22) |
580                                     USB_OTG_DOEPCTL_USBAEP;
581     }
582 
583     USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
584   }
585 
586   return HAL_OK;
587 }
588 
589 /**
590   * @brief  De-activate and de-initialize an endpoint
591   * @param  USBx  Selected device
592   * @param  ep pointer to endpoint structure
593   * @retval HAL status
594   */
USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)595 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
596 {
597   uint32_t USBx_BASE = (uint32_t)USBx;
598   uint32_t epnum = (uint32_t)ep->num;
599 
600   /* Read DEPCTLn register */
601   if (ep->is_in == 1U)
602   {
603     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
604     {
605       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
606       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
607     }
608 
609     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
610     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
611     USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
612                                    USB_OTG_DIEPCTL_MPSIZ |
613                                    USB_OTG_DIEPCTL_TXFNUM |
614                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
615                                    USB_OTG_DIEPCTL_EPTYP);
616   }
617   else
618   {
619     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
620     {
621       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
622       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
623     }
624 
625     USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
626     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
627     USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
628                                     USB_OTG_DOEPCTL_MPSIZ |
629                                     USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
630                                     USB_OTG_DOEPCTL_EPTYP);
631   }
632 
633   return HAL_OK;
634 }
635 
636 /**
637   * @brief  De-activate and de-initialize a dedicated endpoint
638   * @param  USBx  Selected device
639   * @param  ep pointer to endpoint structure
640   * @retval HAL status
641   */
USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)642 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
643 {
644   uint32_t USBx_BASE = (uint32_t)USBx;
645   uint32_t epnum = (uint32_t)ep->num;
646 
647   /* Read DEPCTLn register */
648   if (ep->is_in == 1U)
649   {
650     if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
651     {
652       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_SNAK;
653       USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_EPDIS;
654     }
655 
656     USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
657     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
658   }
659   else
660   {
661     if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
662     {
663       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_SNAK;
664       USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_EPDIS;
665     }
666 
667     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
668     USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
669   }
670 
671   return HAL_OK;
672 }
673 
674 /**
675   * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
676   * @param  USBx  Selected device
677   * @param  ep pointer to endpoint structure
678   * @retval HAL status
679   */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)680 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
681 {
682   uint32_t USBx_BASE = (uint32_t)USBx;
683   uint32_t epnum = (uint32_t)ep->num;
684   uint16_t pktcnt;
685 
686   /* IN endpoint */
687   if (ep->is_in == 1U)
688   {
689     /* Zero Length Packet? */
690     if (ep->xfer_len == 0U)
691     {
692       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
693       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
694       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
695     }
696     else
697     {
698       /* Program the transfer size and packet count
699       * as follows: xfersize = N * maxpacket +
700       * short_packet pktcnt = N + (short_packet
701       * exist ? 1 : 0)
702       */
703       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
704       USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
705 
706       if (epnum == 0U)
707       {
708         if (ep->xfer_len > ep->maxpacket)
709         {
710           ep->xfer_len = ep->maxpacket;
711         }
712 
713         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
714       }
715       else
716       {
717         pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
718         USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
719 
720         if (ep->type == EP_TYPE_ISOC)
721         {
722           USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
723           USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (pktcnt << 29));
724         }
725       }
726 
727       USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
728     }
729     /* EP enable, IN data in FIFO */
730     USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
731 
732     if (ep->type != EP_TYPE_ISOC)
733     {
734       /* Enable the Tx FIFO Empty Interrupt for this EP */
735       if (ep->xfer_len > 0U)
736       {
737         USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
738       }
739     }
740     else
741     {
742       if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
743       {
744         USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
745       }
746       else
747       {
748         USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
749       }
750 
751       (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len);
752     }
753   }
754   else /* OUT endpoint */
755   {
756     /* Program the transfer size and packet count as follows:
757     * pktcnt = N
758     * xfersize = N * maxpacket
759     */
760     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
761     USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
762 
763     if (epnum == 0U)
764     {
765       if (ep->xfer_len > 0U)
766       {
767         ep->xfer_len = ep->maxpacket;
768       }
769 
770       /* Store transfer size, for EP0 this is equal to endpoint max packet size */
771       ep->xfer_size = ep->maxpacket;
772 
773       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
774       USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
775     }
776     else
777     {
778       if (ep->xfer_len == 0U)
779       {
780         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
781         USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
782       }
783       else
784       {
785         pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
786         ep->xfer_size = ep->maxpacket * pktcnt;
787 
788         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
789         USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
790       }
791     }
792 
793     if (ep->type == EP_TYPE_ISOC)
794     {
795       if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
796       {
797         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
798       }
799       else
800       {
801         USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
802       }
803     }
804     /* EP enable */
805     USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
806   }
807 
808   return HAL_OK;
809 }
810 
811 
812 /**
813    * @brief  USB_EPStoptXfer  Stop transfer on an EP
814    * @param  USBx  usb device instance
815    * @param  ep pointer to endpoint structure
816    * @retval HAL status
817    */
USB_EPStopXfer(const USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)818 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
819 {
820   __IO uint32_t count = 0U;
821   HAL_StatusTypeDef ret = HAL_OK;
822   uint32_t USBx_BASE = (uint32_t)USBx;
823 
824   /* IN endpoint */
825   if (ep->is_in == 1U)
826   {
827     /* EP enable, IN data in FIFO */
828     if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
829     {
830       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
831       USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
832 
833       do
834       {
835         count++;
836 
837         if (count > 10000U)
838         {
839           ret = HAL_ERROR;
840           break;
841         }
842       } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) ==  USB_OTG_DIEPCTL_EPENA);
843     }
844   }
845   else /* OUT endpoint */
846   {
847     if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
848     {
849       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
850       USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
851 
852       do
853       {
854         count++;
855 
856         if (count > 10000U)
857         {
858           ret = HAL_ERROR;
859           break;
860         }
861       } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) ==  USB_OTG_DOEPCTL_EPENA);
862     }
863   }
864 
865   return ret;
866 }
867 
868 
869 /**
870   * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
871   *         with the EP/channel
872   * @param  USBx  Selected device
873   * @param  src   pointer to source buffer
874   * @param  ch_ep_num  endpoint or host channel number
875   * @param  len  Number of bytes to write
876   * @retval HAL status
877   */
USB_WritePacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len)878 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
879                                   uint8_t ch_ep_num, uint16_t len)
880 {
881   uint32_t USBx_BASE = (uint32_t)USBx;
882   uint8_t *pSrc = src;
883   uint32_t count32b;
884   uint32_t i;
885 
886   count32b = ((uint32_t)len + 3U) / 4U;
887   for (i = 0U; i < count32b; i++)
888   {
889     USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
890     pSrc++;
891     pSrc++;
892     pSrc++;
893     pSrc++;
894   }
895 
896   return HAL_OK;
897 }
898 
899 /**
900   * @brief  USB_ReadPacket : read a packet from the RX FIFO
901   * @param  USBx  Selected device
902   * @param  dest  source pointer
903   * @param  len  Number of bytes to read
904   * @retval pointer to destination buffer
905   */
USB_ReadPacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)906 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
907 {
908   uint32_t USBx_BASE = (uint32_t)USBx;
909   uint8_t *pDest = dest;
910   uint32_t pData;
911   uint32_t i;
912   uint32_t count32b = (uint32_t)len >> 2U;
913   uint16_t remaining_bytes = len % 4U;
914 
915   for (i = 0U; i < count32b; i++)
916   {
917     __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
918     pDest++;
919     pDest++;
920     pDest++;
921     pDest++;
922   }
923 
924   /* When Number of data is not word aligned, read the remaining byte */
925   if (remaining_bytes != 0U)
926   {
927     i = 0U;
928     __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
929 
930     do
931     {
932       *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
933       i++;
934       pDest++;
935       remaining_bytes--;
936     } while (remaining_bytes != 0U);
937   }
938 
939   return ((void *)pDest);
940 }
941 
942 /**
943   * @brief  USB_EPSetStall : set a stall condition over an EP
944   * @param  USBx  Selected device
945   * @param  ep pointer to endpoint structure
946   * @retval HAL status
947   */
USB_EPSetStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)948 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
949 {
950   uint32_t USBx_BASE = (uint32_t)USBx;
951   uint32_t epnum = (uint32_t)ep->num;
952 
953   if (ep->is_in == 1U)
954   {
955     if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
956     {
957       USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
958     }
959     USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
960   }
961   else
962   {
963     if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
964     {
965       USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
966     }
967     USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
968   }
969 
970   return HAL_OK;
971 }
972 
973 /**
974   * @brief  USB_EPClearStall : Clear a stall condition over an EP
975   * @param  USBx  Selected device
976   * @param  ep pointer to endpoint structure
977   * @retval HAL status
978   */
USB_EPClearStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)979 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
980 {
981   uint32_t USBx_BASE = (uint32_t)USBx;
982   uint32_t epnum = (uint32_t)ep->num;
983 
984   if (ep->is_in == 1U)
985   {
986     USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
987     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
988     {
989       USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
990     }
991   }
992   else
993   {
994     USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
995     if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
996     {
997       USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
998     }
999   }
1000   return HAL_OK;
1001 }
1002 
1003 /**
1004   * @brief  USB_StopDevice : Stop the usb device mode
1005   * @param  USBx  Selected device
1006   * @retval HAL status
1007   */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1008 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1009 {
1010   HAL_StatusTypeDef ret;
1011   uint32_t USBx_BASE = (uint32_t)USBx;
1012   uint32_t i;
1013 
1014   /* Clear Pending interrupt */
1015   for (i = 0U; i < 15U; i++)
1016   {
1017     USBx_INEP(i)->DIEPINT = 0xFB7FU;
1018     USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1019   }
1020 
1021   /* Clear interrupt masks */
1022   USBx_DEVICE->DIEPMSK  = 0U;
1023   USBx_DEVICE->DOEPMSK  = 0U;
1024   USBx_DEVICE->DAINTMSK = 0U;
1025 
1026   /* Flush the FIFO */
1027   ret = USB_FlushRxFifo(USBx);
1028   if (ret != HAL_OK)
1029   {
1030     return ret;
1031   }
1032 
1033   ret = USB_FlushTxFifo(USBx,  0x10U);
1034   if (ret != HAL_OK)
1035   {
1036     return ret;
1037   }
1038 
1039   return ret;
1040 }
1041 
1042 /**
1043   * @brief  USB_SetDevAddress : Stop the usb device mode
1044   * @param  USBx  Selected device
1045   * @param  address  new device address to be assigned
1046   *          This parameter can be a value from 0 to 255
1047   * @retval HAL status
1048   */
USB_SetDevAddress(const USB_OTG_GlobalTypeDef * USBx,uint8_t address)1049 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1050 {
1051   uint32_t USBx_BASE = (uint32_t)USBx;
1052 
1053   USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1054   USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1055 
1056   return HAL_OK;
1057 }
1058 
1059 /**
1060   * @brief  USB_DevConnect : Connect the USB device by enabling Rpu
1061   * @param  USBx  Selected device
1062   * @retval HAL status
1063   */
USB_DevConnect(const USB_OTG_GlobalTypeDef * USBx)1064 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1065 {
1066   uint32_t USBx_BASE = (uint32_t)USBx;
1067 
1068   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1069   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1070 
1071   USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1072 
1073   return HAL_OK;
1074 }
1075 
1076 /**
1077   * @brief  USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1078   * @param  USBx  Selected device
1079   * @retval HAL status
1080   */
USB_DevDisconnect(const USB_OTG_GlobalTypeDef * USBx)1081 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1082 {
1083   uint32_t USBx_BASE = (uint32_t)USBx;
1084 
1085   /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1086   USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1087 
1088   USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1089 
1090   return HAL_OK;
1091 }
1092 
1093 /**
1094   * @brief  USB_ReadInterrupts: return the global USB interrupt status
1095   * @param  USBx  Selected device
1096   * @retval USB Global Interrupt status
1097   */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef const * USBx)1098 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1099 {
1100   uint32_t tmpreg;
1101 
1102   tmpreg = USBx->GINTSTS;
1103   tmpreg &= USBx->GINTMSK;
1104 
1105   return tmpreg;
1106 }
1107 
1108 /**
1109   * @brief  USB_ReadChInterrupts: return USB channel interrupt status
1110   * @param  USBx  Selected device
1111   * @param  chnum Channel number
1112   * @retval USB Channel Interrupt status
1113   */
USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef * USBx,uint8_t chnum)1114 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1115 {
1116   uint32_t USBx_BASE = (uint32_t)USBx;
1117   uint32_t tmpreg;
1118 
1119   tmpreg = USBx_HC(chnum)->HCINT;
1120   tmpreg &= USBx_HC(chnum)->HCINTMSK;
1121 
1122   return tmpreg;
1123 }
1124 
1125 /**
1126   * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1127   * @param  USBx  Selected device
1128   * @retval USB Device OUT EP interrupt status
1129   */
USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1130 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1131 {
1132   uint32_t USBx_BASE = (uint32_t)USBx;
1133   uint32_t tmpreg;
1134 
1135   tmpreg  = USBx_DEVICE->DAINT;
1136   tmpreg &= USBx_DEVICE->DAINTMSK;
1137 
1138   return ((tmpreg & 0xffff0000U) >> 16);
1139 }
1140 
1141 /**
1142   * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1143   * @param  USBx  Selected device
1144   * @retval USB Device IN EP interrupt status
1145   */
USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1146 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1147 {
1148   uint32_t USBx_BASE = (uint32_t)USBx;
1149   uint32_t tmpreg;
1150 
1151   tmpreg  = USBx_DEVICE->DAINT;
1152   tmpreg &= USBx_DEVICE->DAINTMSK;
1153 
1154   return ((tmpreg & 0xFFFFU));
1155 }
1156 
1157 /**
1158   * @brief  Returns Device OUT EP Interrupt register
1159   * @param  USBx  Selected device
1160   * @param  epnum  endpoint number
1161   *          This parameter can be a value from 0 to 15
1162   * @retval Device OUT EP Interrupt register
1163   */
USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1164 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1165 {
1166   uint32_t USBx_BASE = (uint32_t)USBx;
1167   uint32_t tmpreg;
1168 
1169   tmpreg  = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1170   tmpreg &= USBx_DEVICE->DOEPMSK;
1171 
1172   return tmpreg;
1173 }
1174 
1175 /**
1176   * @brief  Returns Device IN EP Interrupt register
1177   * @param  USBx  Selected device
1178   * @param  epnum  endpoint number
1179   *          This parameter can be a value from 0 to 15
1180   * @retval Device IN EP Interrupt register
1181   */
USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1182 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1183 {
1184   uint32_t USBx_BASE = (uint32_t)USBx;
1185   uint32_t tmpreg;
1186   uint32_t msk;
1187   uint32_t emp;
1188 
1189   msk = USBx_DEVICE->DIEPMSK;
1190   emp = USBx_DEVICE->DIEPEMPMSK;
1191   msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1192   tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1193 
1194   return tmpreg;
1195 }
1196 
1197 /**
1198   * @brief  USB_ClearInterrupts: clear a USB interrupt
1199   * @param  USBx  Selected device
1200   * @param  interrupt  flag
1201   * @retval None
1202   */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1203 void  USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1204 {
1205   USBx->GINTSTS &= interrupt;
1206 }
1207 
1208 /**
1209   * @brief  Returns USB core mode
1210   * @param  USBx  Selected device
1211   * @retval return core mode : Host or Device
1212   *          This parameter can be one of these values:
1213   *           0 : Host
1214   *           1 : Device
1215   */
USB_GetMode(const USB_OTG_GlobalTypeDef * USBx)1216 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1217 {
1218   return ((USBx->GINTSTS) & 0x1U);
1219 }
1220 
1221 /**
1222   * @brief  Activate EP0 for Setup transactions
1223   * @param  USBx  Selected device
1224   * @retval HAL status
1225   */
USB_ActivateSetup(const USB_OTG_GlobalTypeDef * USBx)1226 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1227 {
1228   uint32_t USBx_BASE = (uint32_t)USBx;
1229 
1230   /* Set the MPS of the IN EP0 to 64 bytes */
1231   USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1232 
1233   USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1234 
1235   return HAL_OK;
1236 }
1237 
1238 /**
1239   * @brief  Prepare the EP0 to start the first control setup
1240   * @param  USBx  Selected device
1241   * @param  psetup  pointer to setup packet
1242   * @retval HAL status
1243   */
USB_EP0_OutStart(const USB_OTG_GlobalTypeDef * USBx,const uint8_t * psetup)1244 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, const uint8_t *psetup)
1245 {
1246   uint32_t USBx_BASE = (uint32_t)USBx;
1247   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1248   UNUSED(psetup);
1249 
1250   if (gSNPSiD > USB_OTG_CORE_ID_300A)
1251   {
1252     if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1253     {
1254       return HAL_OK;
1255     }
1256   }
1257 
1258   USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1259   USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1260   USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1261   USBx_OUTEP(0U)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;
1262 
1263   return HAL_OK;
1264 }
1265 
1266 /**
1267   * @brief  Reset the USB Core (needed after USB clock settings change)
1268   * @param  USBx  Selected device
1269   * @retval HAL status
1270   */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1271 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1272 {
1273   __IO uint32_t count = 0U;
1274 
1275   /* Wait for AHB master IDLE state. */
1276   do
1277   {
1278     count++;
1279 
1280     if (count > HAL_USB_TIMEOUT)
1281     {
1282       return HAL_TIMEOUT;
1283     }
1284   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1285 
1286   /* Core Soft Reset */
1287   count = 0U;
1288   USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1289 
1290   do
1291   {
1292     count++;
1293 
1294     if (count > HAL_USB_TIMEOUT)
1295     {
1296       return HAL_TIMEOUT;
1297     }
1298   } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1299 
1300   return HAL_OK;
1301 }
1302 
1303 /**
1304   * @brief  USB_HostInit : Initializes the USB OTG controller registers
1305   *         for Host mode
1306   * @param  USBx  Selected device
1307   * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
1308   *         the configuration information for the specified USBx peripheral.
1309   * @retval HAL status
1310   */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1311 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1312 {
1313   HAL_StatusTypeDef ret = HAL_OK;
1314   uint32_t USBx_BASE = (uint32_t)USBx;
1315   uint32_t i;
1316 
1317   /* Restart the Phy Clock */
1318   USBx_PCGCCTL = 0U;
1319 
1320   /* Disable VBUS sensing */
1321   USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1322 
1323   /* Disable Battery chargin detector */
1324   USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1325 
1326   /* Set default Max speed support */
1327   USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1328 
1329   /* Make sure the FIFOs are flushed. */
1330   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1331   {
1332     ret = HAL_ERROR;
1333   }
1334 
1335   if (USB_FlushRxFifo(USBx) != HAL_OK)
1336   {
1337     ret = HAL_ERROR;
1338   }
1339 
1340   /* Clear all pending HC Interrupts */
1341   for (i = 0U; i < cfg.Host_channels; i++)
1342   {
1343     USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1344     USBx_HC(i)->HCINTMSK = 0U;
1345   }
1346 
1347   /* Disable all interrupts. */
1348   USBx->GINTMSK = 0U;
1349 
1350   /* Clear any pending interrupts */
1351   USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1352 
1353   /* set Rx FIFO size */
1354   USBx->GRXFSIZ  = 0x80U;
1355   USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1356   USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1357   /* Enable the common interrupts */
1358   USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1359 
1360   /* Enable interrupts matching to the Host mode ONLY */
1361   USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM | \
1362                     USB_OTG_GINTMSK_SOFM             | USB_OTG_GINTSTS_DISCINT | \
1363                     USB_OTG_GINTMSK_PXFRM_IISOOXFRM  | USB_OTG_GINTMSK_WUIM);
1364 
1365   return ret;
1366 }
1367 
1368 /**
1369   * @brief  USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1370   *         HCFG register on the PHY type and set the right frame interval
1371   * @param  USBx  Selected device
1372   * @param  freq  clock frequency
1373   *          This parameter can be one of these values:
1374   *           HCFG_48_MHZ : Full Speed 48 MHz Clock
1375   *           HCFG_6_MHZ : Low Speed 6 MHz Clock
1376   * @retval HAL status
1377   */
USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1378 HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1379 {
1380   uint32_t USBx_BASE = (uint32_t)USBx;
1381 
1382   USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1383   USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1384 
1385   if (freq == HCFG_48_MHZ)
1386   {
1387     USBx_HOST->HFIR = HFIR_48_MHZ;
1388   }
1389   else if (freq == HCFG_6_MHZ)
1390   {
1391     USBx_HOST->HFIR = HFIR_6_MHZ;
1392   }
1393   else
1394   {
1395     return HAL_ERROR;
1396   }
1397 
1398   return HAL_OK;
1399 }
1400 
1401 /**
1402   * @brief  USB_OTG_ResetPort : Reset Host Port
1403   * @param  USBx  Selected device
1404   * @retval HAL status
1405   * @note (1)The application must wait at least 10 ms
1406   *   before clearing the reset bit.
1407   */
USB_ResetPort(const USB_OTG_GlobalTypeDef * USBx)1408 HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
1409 {
1410   uint32_t USBx_BASE = (uint32_t)USBx;
1411 
1412   __IO uint32_t hprt0 = 0U;
1413 
1414   hprt0 = USBx_HPRT0;
1415 
1416   hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1417              USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1418 
1419   USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1420   HAL_Delay(100U);                                 /* See Note #1 */
1421   USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1422   HAL_Delay(10U);
1423 
1424   return HAL_OK;
1425 }
1426 
1427 /**
1428   * @brief  USB_DriveVbus : activate or de-activate vbus
1429   * @param  state  VBUS state
1430   *          This parameter can be one of these values:
1431   *           0 : Deactivate VBUS
1432   *           1 : Activate VBUS
1433   * @retval HAL status
1434   */
USB_DriveVbus(const USB_OTG_GlobalTypeDef * USBx,uint8_t state)1435 HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1436 {
1437   uint32_t USBx_BASE = (uint32_t)USBx;
1438   __IO uint32_t hprt0 = 0U;
1439 
1440   hprt0 = USBx_HPRT0;
1441 
1442   hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1443              USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1444 
1445   if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1446   {
1447     USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1448   }
1449   if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1450   {
1451     USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1452   }
1453   return HAL_OK;
1454 }
1455 
1456 /**
1457   * @brief  Return Host Core speed
1458   * @param  USBx  Selected device
1459   * @retval speed : Host speed
1460   *          This parameter can be one of these values:
1461   *            @arg HCD_SPEED_FULL: Full speed mode
1462   *            @arg HCD_SPEED_LOW: Low speed mode
1463   */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef const * USBx)1464 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1465 {
1466   uint32_t USBx_BASE = (uint32_t)USBx;
1467   __IO uint32_t hprt0 = 0U;
1468 
1469   hprt0 = USBx_HPRT0;
1470   return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1471 }
1472 
1473 /**
1474   * @brief  Return Host Current Frame number
1475   * @param  USBx  Selected device
1476   * @retval current frame number
1477   */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const * USBx)1478 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1479 {
1480   uint32_t USBx_BASE = (uint32_t)USBx;
1481 
1482   return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1483 }
1484 
1485 /**
1486   * @brief  Initialize a host channel
1487   * @param  USBx  Selected device
1488   * @param  ch_num  Channel number
1489   *         This parameter can be a value from 1 to 15
1490   * @param  epnum  Endpoint number
1491   *          This parameter can be a value from 1 to 15
1492   * @param  dev_address  Current device address
1493   *          This parameter can be a value from 0 to 255
1494   * @param  speed  Current device speed
1495   *          This parameter can be one of these values:
1496   *            @arg USB_OTG_SPEED_FULL: Full speed mode
1497   *            @arg USB_OTG_SPEED_LOW: Low speed mode
1498   * @param  ep_type  Endpoint Type
1499   *          This parameter can be one of these values:
1500   *            @arg EP_TYPE_CTRL: Control type
1501   *            @arg EP_TYPE_ISOC: Isochronous type
1502   *            @arg EP_TYPE_BULK: Bulk type
1503   *            @arg EP_TYPE_INTR: Interrupt type
1504   * @param  mps  Max Packet Size
1505   *          This parameter can be a value from 0 to 32K
1506   * @retval HAL state
1507   */
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)1508 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1509                               uint8_t epnum, uint8_t dev_address, uint8_t speed,
1510                               uint8_t ep_type, uint16_t mps)
1511 {
1512   HAL_StatusTypeDef ret = HAL_OK;
1513   uint32_t USBx_BASE = (uint32_t)USBx;
1514   uint32_t HCcharEpDir;
1515   uint32_t HCcharLowSpeed;
1516   uint32_t HostCoreSpeed;
1517 
1518   /* Clear old interrupt conditions for this host channel. */
1519   USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1520 
1521   /* Enable channel interrupts required for this transfer. */
1522   switch (ep_type)
1523   {
1524     case EP_TYPE_CTRL:
1525     case EP_TYPE_BULK:
1526       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1527                                             USB_OTG_HCINTMSK_STALLM |
1528                                             USB_OTG_HCINTMSK_TXERRM |
1529                                             USB_OTG_HCINTMSK_DTERRM |
1530                                             USB_OTG_HCINTMSK_AHBERR |
1531                                             USB_OTG_HCINTMSK_NAKM;
1532 
1533       if ((epnum & 0x80U) == 0x80U)
1534       {
1535         USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1536       }
1537       break;
1538 
1539     case EP_TYPE_INTR:
1540       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1541                                             USB_OTG_HCINTMSK_STALLM |
1542                                             USB_OTG_HCINTMSK_TXERRM |
1543                                             USB_OTG_HCINTMSK_DTERRM |
1544                                             USB_OTG_HCINTMSK_NAKM   |
1545                                             USB_OTG_HCINTMSK_AHBERR |
1546                                             USB_OTG_HCINTMSK_FRMORM;
1547 
1548       if ((epnum & 0x80U) == 0x80U)
1549       {
1550         USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1551       }
1552 
1553       break;
1554 
1555     case EP_TYPE_ISOC:
1556       USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
1557                                             USB_OTG_HCINTMSK_ACKM   |
1558                                             USB_OTG_HCINTMSK_AHBERR |
1559                                             USB_OTG_HCINTMSK_FRMORM;
1560 
1561       if ((epnum & 0x80U) == 0x80U)
1562       {
1563         USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1564       }
1565       break;
1566 
1567     default:
1568       ret = HAL_ERROR;
1569       break;
1570   }
1571 
1572   /* Enable host channel Halt interrupt */
1573   USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1574 
1575   /* Enable the top level host channel interrupt. */
1576   USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1577 
1578   /* Make sure host channel interrupts are enabled. */
1579   USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1580 
1581   /* Program the HCCHAR register */
1582   if ((epnum & 0x80U) == 0x80U)
1583   {
1584     HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1585   }
1586   else
1587   {
1588     HCcharEpDir = 0U;
1589   }
1590 
1591   HostCoreSpeed = USB_GetHostSpeed(USBx);
1592 
1593   /* LS device plugged to HUB */
1594   if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1595   {
1596     HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1597   }
1598   else
1599   {
1600     HCcharLowSpeed = 0U;
1601   }
1602 
1603   USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1604                                       ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1605                                       (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1606                                       ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1607                                       USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1608 
1609   if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1610   {
1611     USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1612   }
1613 
1614   return ret;
1615 }
1616 
1617 /**
1618   * @brief  Start a transfer over a host channel
1619   * @param  USBx  Selected device
1620   * @param  hc  pointer to host channel structure
1621   * @retval HAL state
1622   */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc)1623 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
1624 {
1625   uint32_t USBx_BASE = (uint32_t)USBx;
1626   uint32_t ch_num = (uint32_t)hc->ch_num;
1627   __IO uint32_t tmpreg;
1628   uint8_t  is_oddframe;
1629   uint16_t len_words;
1630   uint16_t num_packets;
1631   uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1632 
1633   /* Compute the expected number of packets associated to the transfer */
1634   if (hc->xfer_len > 0U)
1635   {
1636     num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1637 
1638     if (num_packets > max_hc_pkt_count)
1639     {
1640       num_packets = max_hc_pkt_count;
1641       hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1642     }
1643   }
1644   else
1645   {
1646     num_packets = 1U;
1647   }
1648 
1649   /*
1650    * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1651    * max_packet size.
1652    */
1653   if (hc->ep_is_in != 0U)
1654   {
1655     hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1656   }
1657   else
1658   {
1659     hc->XferSize = hc->xfer_len;
1660   }
1661 
1662   /* Initialize the HCTSIZn register */
1663   USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1664                             (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1665                             (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1666 
1667   is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1668   USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1669   USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1670 
1671   /* Set host channel enable */
1672   tmpreg = USBx_HC(ch_num)->HCCHAR;
1673   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1674 
1675   /* make sure to set the correct ep direction */
1676   if (hc->ep_is_in != 0U)
1677   {
1678     tmpreg |= USB_OTG_HCCHAR_EPDIR;
1679   }
1680   else
1681   {
1682     tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1683   }
1684   tmpreg |= USB_OTG_HCCHAR_CHENA;
1685   USBx_HC(ch_num)->HCCHAR = tmpreg;
1686 
1687   if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1688   {
1689     switch (hc->ep_type)
1690     {
1691       /* Non periodic transfer */
1692       case EP_TYPE_CTRL:
1693       case EP_TYPE_BULK:
1694 
1695         len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1696 
1697         /* check if there is enough space in FIFO space */
1698         if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1699         {
1700           /* need to process data in nptxfempty interrupt */
1701           USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1702         }
1703         break;
1704 
1705       /* Periodic transfer */
1706       case EP_TYPE_INTR:
1707       case EP_TYPE_ISOC:
1708         len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1709         /* check if there is enough space in FIFO space */
1710         if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
1711         {
1712           /* need to process data in ptxfempty interrupt */
1713           USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1714         }
1715         break;
1716 
1717       default:
1718         break;
1719     }
1720 
1721     /* Write packet into the Tx FIFO. */
1722     (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len);
1723   }
1724 
1725   return HAL_OK;
1726 }
1727 
1728 /**
1729   * @brief Read all host channel interrupts status
1730   * @param  USBx  Selected device
1731   * @retval HAL state
1732   */
USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef * USBx)1733 uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1734 {
1735   uint32_t USBx_BASE = (uint32_t)USBx;
1736 
1737   return ((USBx_HOST->HAINT) & 0xFFFFU);
1738 }
1739 
1740 /**
1741   * @brief  Halt a host channel
1742   * @param  USBx  Selected device
1743   * @param  hc_num  Host Channel number
1744   *         This parameter can be a value from 1 to 15
1745   * @retval HAL state
1746   */
USB_HC_Halt(const USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)1747 HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
1748 {
1749   uint32_t USBx_BASE = (uint32_t)USBx;
1750   uint32_t hcnum = (uint32_t)hc_num;
1751   __IO uint32_t count = 0U;
1752   uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
1753   uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
1754   uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
1755 
1756   /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
1757      At the end of the next uframe/frame (in the worst case), the core generates a channel halted
1758      and disables the channel automatically. */
1759 
1760   if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
1761       ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
1762   {
1763     return HAL_OK;
1764   }
1765 
1766   /* Check for space in the request queue to issue the halt. */
1767   if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
1768   {
1769     USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1770 
1771     if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
1772     {
1773       if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
1774       {
1775         USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1776         USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1777         do
1778         {
1779           count++;
1780 
1781           if (count > 1000U)
1782           {
1783             break;
1784           }
1785         } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1786       }
1787       else
1788       {
1789         USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1790       }
1791     }
1792     else
1793     {
1794       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1795     }
1796   }
1797   else
1798   {
1799     USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1800 
1801     if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
1802     {
1803       USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1804       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1805       do
1806       {
1807         count++;
1808 
1809         if (count > 1000U)
1810         {
1811           break;
1812         }
1813       } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1814     }
1815     else
1816     {
1817       USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1818     }
1819   }
1820 
1821   return HAL_OK;
1822 }
1823 
1824 /**
1825   * @brief  Initiate Do Ping protocol
1826   * @param  USBx  Selected device
1827   * @param  hc_num  Host Channel number
1828   *         This parameter can be a value from 1 to 15
1829   * @retval HAL state
1830   */
USB_DoPing(const USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)1831 HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
1832 {
1833   uint32_t USBx_BASE = (uint32_t)USBx;
1834   uint32_t chnum = (uint32_t)ch_num;
1835   uint32_t num_packets = 1U;
1836   uint32_t tmpreg;
1837 
1838   USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1839                            USB_OTG_HCTSIZ_DOPING;
1840 
1841   /* Set host channel enable */
1842   tmpreg = USBx_HC(chnum)->HCCHAR;
1843   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1844   tmpreg |= USB_OTG_HCCHAR_CHENA;
1845   USBx_HC(chnum)->HCCHAR = tmpreg;
1846 
1847   return HAL_OK;
1848 }
1849 
1850 /**
1851   * @brief  Stop Host Core
1852   * @param  USBx  Selected device
1853   * @retval HAL state
1854   */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)1855 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1856 {
1857   HAL_StatusTypeDef ret = HAL_OK;
1858   uint32_t USBx_BASE = (uint32_t)USBx;
1859   __IO uint32_t count = 0U;
1860   uint32_t value;
1861   uint32_t i;
1862 
1863   (void)USB_DisableGlobalInt(USBx);
1864 
1865   /* Flush USB FIFO */
1866   if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1867   {
1868     ret = HAL_ERROR;
1869   }
1870 
1871   if (USB_FlushRxFifo(USBx) != HAL_OK)
1872   {
1873     ret = HAL_ERROR;
1874   }
1875 
1876   /* Flush out any leftover queued requests. */
1877   for (i = 0U; i <= 15U; i++)
1878   {
1879     value = USBx_HC(i)->HCCHAR;
1880     value |=  USB_OTG_HCCHAR_CHDIS;
1881     value &= ~USB_OTG_HCCHAR_CHENA;
1882     value &= ~USB_OTG_HCCHAR_EPDIR;
1883     USBx_HC(i)->HCCHAR = value;
1884   }
1885 
1886   /* Halt all channels to put them into a known state. */
1887   for (i = 0U; i <= 15U; i++)
1888   {
1889     value = USBx_HC(i)->HCCHAR;
1890     value |= USB_OTG_HCCHAR_CHDIS;
1891     value |= USB_OTG_HCCHAR_CHENA;
1892     value &= ~USB_OTG_HCCHAR_EPDIR;
1893     USBx_HC(i)->HCCHAR = value;
1894 
1895     do
1896     {
1897       count++;
1898 
1899       if (count > 1000U)
1900       {
1901         break;
1902       }
1903     } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1904   }
1905 
1906   /* Clear any pending Host interrupts */
1907   USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
1908   USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1909 
1910   (void)USB_EnableGlobalInt(USBx);
1911 
1912   return ret;
1913 }
1914 
1915 /**
1916   * @brief  USB_ActivateRemoteWakeup active remote wakeup signalling
1917   * @param  USBx Selected device
1918   * @retval HAL status
1919   */
USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)1920 HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
1921 {
1922   uint32_t USBx_BASE = (uint32_t)USBx;
1923 
1924   if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1925   {
1926     /* active Remote wakeup signalling */
1927     USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
1928   }
1929 
1930   return HAL_OK;
1931 }
1932 
1933 /**
1934   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
1935   * @param  USBx Selected device
1936   * @retval HAL status
1937   */
USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)1938 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
1939 {
1940   uint32_t USBx_BASE = (uint32_t)USBx;
1941 
1942   /* active Remote wakeup signalling */
1943   USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
1944 
1945   return HAL_OK;
1946 }
1947 #endif /* defined (USB_OTG_FS) */
1948 
1949 #if defined (USB)
1950 /**
1951   * @brief  Initializes the USB Core
1952   * @param  USBx USB Instance
1953   * @param  cfg pointer to a USB_CfgTypeDef structure that contains
1954   *         the configuration information for the specified USBx peripheral.
1955   * @retval HAL status
1956   */
USB_CoreInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)1957 HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
1958 {
1959   /* Prevent unused argument(s) compilation warning */
1960   UNUSED(USBx);
1961   UNUSED(cfg);
1962 
1963   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
1964               only by USB OTG FS peripheral.
1965             - This function is added to ensure compatibility across platforms.
1966    */
1967 
1968   return HAL_OK;
1969 }
1970 
1971 /**
1972   * @brief  USB_EnableGlobalInt
1973   *         Enables the controller's Global Int in the AHB Config reg
1974   * @param  USBx Selected device
1975   * @retval HAL status
1976   */
USB_EnableGlobalInt(USB_TypeDef * USBx)1977 HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
1978 {
1979   uint32_t winterruptmask;
1980 
1981   /* Clear pending interrupts */
1982   USBx->ISTR = 0U;
1983 
1984   /* Set winterruptmask variable */
1985   winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
1986                    USB_CNTR_SUSPM | USB_CNTR_ERRM |
1987                    USB_CNTR_SOFM | USB_CNTR_ESOFM |
1988                    USB_CNTR_RESETM | USB_CNTR_L1REQM;
1989 
1990   /* Set interrupt mask */
1991   USBx->CNTR = (uint16_t)winterruptmask;
1992 
1993   return HAL_OK;
1994 }
1995 
1996 /**
1997   * @brief  USB_DisableGlobalInt
1998   *         Disable the controller's Global Int in the AHB Config reg
1999   * @param  USBx Selected device
2000   * @retval HAL status
2001   */
USB_DisableGlobalInt(USB_TypeDef * USBx)2002 HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
2003 {
2004   uint32_t winterruptmask;
2005 
2006   /* Set winterruptmask variable */
2007   winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
2008                    USB_CNTR_SUSPM | USB_CNTR_ERRM |
2009                    USB_CNTR_SOFM | USB_CNTR_ESOFM |
2010                    USB_CNTR_RESETM | USB_CNTR_L1REQM;
2011 
2012   /* Clear interrupt mask */
2013   USBx->CNTR &= (uint16_t)(~winterruptmask);
2014 
2015   return HAL_OK;
2016 }
2017 
2018 /**
2019   * @brief  USB_SetCurrentMode Set functional mode
2020   * @param  USBx Selected device
2021   * @param  mode current core mode
2022   *          This parameter can be one of the these values:
2023   *            @arg USB_DEVICE_MODE Peripheral mode
2024   * @retval HAL status
2025   */
USB_SetCurrentMode(USB_TypeDef * USBx,USB_ModeTypeDef mode)2026 HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
2027 {
2028   /* Prevent unused argument(s) compilation warning */
2029   UNUSED(USBx);
2030   UNUSED(mode);
2031 
2032   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2033               only by USB OTG FS peripheral.
2034             - This function is added to ensure compatibility across platforms.
2035    */
2036   return HAL_OK;
2037 }
2038 
2039 /**
2040   * @brief  USB_DevInit Initializes the USB controller registers
2041   *         for device mode
2042   * @param  USBx Selected device
2043   * @param  cfg  pointer to a USB_CfgTypeDef structure that contains
2044   *         the configuration information for the specified USBx peripheral.
2045   * @retval HAL status
2046   */
USB_DevInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)2047 HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
2048 {
2049   /* Prevent unused argument(s) compilation warning */
2050   UNUSED(cfg);
2051 
2052   /* Init Device */
2053   /* CNTR_FRES = 1 */
2054   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2055 
2056   /* CNTR_FRES = 0 */
2057   USBx->CNTR = 0U;
2058 
2059   /* Clear pending interrupts */
2060   USBx->ISTR = 0U;
2061 
2062   /*Set Btable Address*/
2063   USBx->BTABLE = BTABLE_ADDRESS;
2064 
2065   return HAL_OK;
2066 }
2067 
2068 /**
2069   * @brief  USB_FlushTxFifo : Flush a Tx FIFO
2070   * @param  USBx : Selected device
2071   * @param  num : FIFO number
2072   *         This parameter can be a value from 1 to 15
2073             15 means Flush all Tx FIFOs
2074   * @retval HAL status
2075   */
USB_FlushTxFifo(USB_TypeDef const * USBx,uint32_t num)2076 HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef const *USBx, uint32_t num)
2077 {
2078   /* Prevent unused argument(s) compilation warning */
2079   UNUSED(USBx);
2080   UNUSED(num);
2081 
2082   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2083               only by USB OTG FS peripheral.
2084             - This function is added to ensure compatibility across platforms.
2085    */
2086 
2087   return HAL_OK;
2088 }
2089 
2090 /**
2091   * @brief  USB_FlushRxFifo : Flush Rx FIFO
2092   * @param  USBx : Selected device
2093   * @retval HAL status
2094   */
USB_FlushRxFifo(USB_TypeDef const * USBx)2095 HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef const *USBx)
2096 {
2097   /* Prevent unused argument(s) compilation warning */
2098   UNUSED(USBx);
2099 
2100   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2101               only by USB OTG FS peripheral.
2102             - This function is added to ensure compatibility across platforms.
2103    */
2104 
2105   return HAL_OK;
2106 }
2107 
2108 
2109 #if defined (HAL_PCD_MODULE_ENABLED)
2110 /**
2111   * @brief  Activate and configure an endpoint
2112   * @param  USBx Selected device
2113   * @param  ep pointer to endpoint structure
2114   * @retval HAL status
2115   */
USB_ActivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)2116 HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2117 {
2118   HAL_StatusTypeDef ret = HAL_OK;
2119   uint16_t wEpRegVal;
2120 
2121   wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
2122 
2123   /* initialize Endpoint */
2124   switch (ep->type)
2125   {
2126     case EP_TYPE_CTRL:
2127       wEpRegVal |= USB_EP_CONTROL;
2128       break;
2129 
2130     case EP_TYPE_BULK:
2131       wEpRegVal |= USB_EP_BULK;
2132       break;
2133 
2134     case EP_TYPE_INTR:
2135       wEpRegVal |= USB_EP_INTERRUPT;
2136       break;
2137 
2138     case EP_TYPE_ISOC:
2139       wEpRegVal |= USB_EP_ISOCHRONOUS;
2140       break;
2141 
2142     default:
2143       ret = HAL_ERROR;
2144       break;
2145   }
2146 
2147   PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
2148 
2149   PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
2150 
2151   if (ep->doublebuffer == 0U)
2152   {
2153     if (ep->is_in != 0U)
2154     {
2155       /*Set the endpoint Transmit buffer address */
2156       PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
2157       PCD_CLEAR_TX_DTOG(USBx, ep->num);
2158 
2159       if (ep->type != EP_TYPE_ISOC)
2160       {
2161         /* Configure NAK status for the Endpoint */
2162         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2163       }
2164       else
2165       {
2166         /* Configure TX Endpoint to disabled state */
2167         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2168       }
2169     }
2170     else
2171     {
2172       /* Set the endpoint Receive buffer address */
2173       PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
2174 
2175       /* Set the endpoint Receive buffer counter */
2176       PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
2177       PCD_CLEAR_RX_DTOG(USBx, ep->num);
2178 
2179       if (ep->num == 0U)
2180       {
2181         /* Configure VALID status for EP0 */
2182         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2183       }
2184       else
2185       {
2186         /* Configure NAK status for OUT Endpoint */
2187         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2188       }
2189     }
2190   }
2191 #if (USE_USB_DOUBLE_BUFFER == 1U)
2192   /* Double Buffer */
2193   else
2194   {
2195     if (ep->type == EP_TYPE_BULK)
2196     {
2197       /* Set bulk endpoint as double buffered */
2198       PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2199     }
2200     else
2201     {
2202       /* Set the ISOC endpoint in double buffer mode */
2203       PCD_CLEAR_EP_KIND(USBx, ep->num);
2204     }
2205 
2206     /* Set buffer address for double buffered mode */
2207     PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
2208 
2209     if (ep->is_in == 0U)
2210     {
2211       /* Clear the data toggle bits for the endpoint IN/OUT */
2212       PCD_CLEAR_RX_DTOG(USBx, ep->num);
2213       PCD_CLEAR_TX_DTOG(USBx, ep->num);
2214 
2215       /* Set endpoint RX count */
2216       PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
2217 
2218       /* Set endpoint RX to valid state */
2219       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2220       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2221     }
2222     else
2223     {
2224       /* Clear the data toggle bits for the endpoint IN/OUT */
2225       PCD_CLEAR_RX_DTOG(USBx, ep->num);
2226       PCD_CLEAR_TX_DTOG(USBx, ep->num);
2227 
2228       if (ep->type != EP_TYPE_ISOC)
2229       {
2230         /* Configure NAK status for the Endpoint */
2231         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2232       }
2233       else
2234       {
2235         /* Configure TX Endpoint to disabled state */
2236         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2237       }
2238 
2239       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2240     }
2241   }
2242 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2243 
2244   return ret;
2245 }
2246 
2247 /**
2248   * @brief  De-activate and de-initialize an endpoint
2249   * @param  USBx Selected device
2250   * @param  ep pointer to endpoint structure
2251   * @retval HAL status
2252   */
USB_DeactivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)2253 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2254 {
2255   if (ep->doublebuffer == 0U)
2256   {
2257     if (ep->is_in != 0U)
2258     {
2259       PCD_CLEAR_TX_DTOG(USBx, ep->num);
2260 
2261       /* Configure DISABLE status for the Endpoint */
2262       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2263     }
2264 
2265     else
2266     {
2267       PCD_CLEAR_RX_DTOG(USBx, ep->num);
2268 
2269       /* Configure DISABLE status for the Endpoint */
2270       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2271     }
2272   }
2273 #if (USE_USB_DOUBLE_BUFFER == 1U)
2274   /* Double Buffer */
2275   else
2276   {
2277     if (ep->is_in == 0U)
2278     {
2279       /* Clear the data toggle bits for the endpoint IN/OUT*/
2280       PCD_CLEAR_RX_DTOG(USBx, ep->num);
2281       PCD_CLEAR_TX_DTOG(USBx, ep->num);
2282 
2283       /* Reset value of the data toggle bits for the endpoint out*/
2284       PCD_TX_DTOG(USBx, ep->num);
2285 
2286       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2287       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2288     }
2289     else
2290     {
2291       /* Clear the data toggle bits for the endpoint IN/OUT*/
2292       PCD_CLEAR_RX_DTOG(USBx, ep->num);
2293       PCD_CLEAR_TX_DTOG(USBx, ep->num);
2294       PCD_RX_DTOG(USBx, ep->num);
2295 
2296       /* Configure DISABLE status for the Endpoint*/
2297       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2298       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2299     }
2300   }
2301 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2302 
2303   return HAL_OK;
2304 }
2305 
2306 /**
2307   * @brief  USB_EPStartXfer setup and starts a transfer over an EP
2308   * @param  USBx Selected device
2309   * @param  ep pointer to endpoint structure
2310   * @retval HAL status
2311   */
USB_EPStartXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)2312 HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2313 {
2314   uint32_t len;
2315 #if (USE_USB_DOUBLE_BUFFER == 1U)
2316   uint16_t pmabuffer;
2317   uint16_t wEPVal;
2318 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2319 
2320   /* IN endpoint */
2321   if (ep->is_in == 1U)
2322   {
2323     /* Multi packet transfer */
2324     if (ep->xfer_len > ep->maxpacket)
2325     {
2326       len = ep->maxpacket;
2327     }
2328     else
2329     {
2330       len = ep->xfer_len;
2331     }
2332 
2333     /* configure and validate Tx endpoint */
2334     if (ep->doublebuffer == 0U)
2335     {
2336       USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
2337       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2338     }
2339 #if (USE_USB_DOUBLE_BUFFER == 1U)
2340     else
2341     {
2342       /* double buffer bulk management */
2343       if (ep->type == EP_TYPE_BULK)
2344       {
2345         if (ep->xfer_len_db > ep->maxpacket)
2346         {
2347           /* enable double buffer */
2348           PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2349 
2350           /* each Time to write in PMA xfer_len_db will */
2351           ep->xfer_len_db -= len;
2352 
2353           /* Fill the two first buffer in the Buffer0 & Buffer1 */
2354           if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2355           {
2356             /* Set the Double buffer counter for pmabuffer1 */
2357             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2358             pmabuffer = ep->pmaaddr1;
2359 
2360             /* Write the user buffer to USB PMA */
2361             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2362             ep->xfer_buff += len;
2363 
2364             if (ep->xfer_len_db > ep->maxpacket)
2365             {
2366               ep->xfer_len_db -= len;
2367             }
2368             else
2369             {
2370               len = ep->xfer_len_db;
2371               ep->xfer_len_db = 0U;
2372             }
2373 
2374             /* Set the Double buffer counter for pmabuffer0 */
2375             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2376             pmabuffer = ep->pmaaddr0;
2377 
2378             /* Write the user buffer to USB PMA */
2379             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2380           }
2381           else
2382           {
2383             /* Set the Double buffer counter for pmabuffer0 */
2384             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2385             pmabuffer = ep->pmaaddr0;
2386 
2387             /* Write the user buffer to USB PMA */
2388             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2389             ep->xfer_buff += len;
2390 
2391             if (ep->xfer_len_db > ep->maxpacket)
2392             {
2393               ep->xfer_len_db -= len;
2394             }
2395             else
2396             {
2397               len = ep->xfer_len_db;
2398               ep->xfer_len_db = 0U;
2399             }
2400 
2401             /* Set the Double buffer counter for pmabuffer1 */
2402             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2403             pmabuffer = ep->pmaaddr1;
2404 
2405             /* Write the user buffer to USB PMA */
2406             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2407           }
2408         }
2409         /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
2410         else
2411         {
2412           len = ep->xfer_len_db;
2413 
2414           /* disable double buffer mode for Bulk endpoint */
2415           PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
2416 
2417           /* Set Tx count with nbre of byte to be transmitted */
2418           PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2419           pmabuffer = ep->pmaaddr0;
2420 
2421           /* Write the user buffer to USB PMA */
2422           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2423         }
2424       }
2425       else /* Manage isochronous double buffer IN mode */
2426       {
2427         /* Each Time to write in PMA xfer_len_db will */
2428         ep->xfer_len_db -= len;
2429 
2430         /* Fill the data buffer */
2431         if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2432         {
2433           /* Set the Double buffer counter for pmabuffer1 */
2434           PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2435           pmabuffer = ep->pmaaddr1;
2436 
2437           /* Write the user buffer to USB PMA */
2438           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2439         }
2440         else
2441         {
2442           /* Set the Double buffer counter for pmabuffer0 */
2443           PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2444           pmabuffer = ep->pmaaddr0;
2445 
2446           /* Write the user buffer to USB PMA */
2447           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2448         }
2449       }
2450     }
2451 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2452 
2453     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
2454   }
2455   else /* OUT endpoint */
2456   {
2457     if (ep->doublebuffer == 0U)
2458     {
2459       if ((ep->xfer_len == 0U) && (ep->type == EP_TYPE_CTRL))
2460       {
2461         /* This is a status out stage set the OUT_STATUS */
2462         PCD_SET_OUT_STATUS(USBx, ep->num);
2463       }
2464       else
2465       {
2466         PCD_CLEAR_OUT_STATUS(USBx, ep->num);
2467       }
2468 
2469       /* Multi packet transfer */
2470       if (ep->xfer_len > ep->maxpacket)
2471       {
2472         ep->xfer_len -= ep->maxpacket;
2473       }
2474       else
2475       {
2476         ep->xfer_len = 0U;
2477       }
2478     }
2479 #if (USE_USB_DOUBLE_BUFFER == 1U)
2480     else
2481     {
2482       /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
2483       /* Set the Double buffer counter */
2484       if (ep->type == EP_TYPE_BULK)
2485       {
2486         /* Coming from ISR */
2487         if (ep->xfer_count != 0U)
2488         {
2489           /* Update last value to check if there is blocking state */
2490           wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
2491 
2492           /* Blocking State */
2493           if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
2494               (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
2495           {
2496             PCD_FREE_USER_BUFFER(USBx, ep->num, 0U);
2497           }
2498         }
2499       }
2500       /* iso out double */
2501       else if (ep->type == EP_TYPE_ISOC)
2502       {
2503         /* Only single packet transfer supported in FS */
2504         ep->xfer_len = 0U;
2505       }
2506       else
2507       {
2508         return HAL_ERROR;
2509       }
2510     }
2511 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2512 
2513     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2514   }
2515 
2516   return HAL_OK;
2517 }
2518 
2519 
2520 /**
2521   * @brief  USB_EPSetStall set a stall condition over an EP
2522   * @param  USBx Selected device
2523   * @param  ep pointer to endpoint structure
2524   * @retval HAL status
2525   */
USB_EPSetStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)2526 HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2527 {
2528   if (ep->is_in != 0U)
2529   {
2530     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
2531   }
2532   else
2533   {
2534     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
2535   }
2536 
2537   return HAL_OK;
2538 }
2539 
2540 /**
2541   * @brief  USB_EPClearStall Clear a stall condition over an EP
2542   * @param  USBx Selected device
2543   * @param  ep pointer to endpoint structure
2544   * @retval HAL status
2545   */
USB_EPClearStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)2546 HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2547 {
2548   if (ep->is_in != 0U)
2549   {
2550     PCD_CLEAR_TX_DTOG(USBx, ep->num);
2551 
2552     if (ep->type != EP_TYPE_ISOC)
2553     {
2554       /* Configure NAK status for the Endpoint */
2555       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2556     }
2557   }
2558   else
2559   {
2560     PCD_CLEAR_RX_DTOG(USBx, ep->num);
2561 
2562     /* Configure VALID status for the Endpoint */
2563     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2564   }
2565 
2566   return HAL_OK;
2567 }
2568 
2569 /**
2570    * @brief  USB_EPStoptXfer  Stop transfer on an EP
2571    * @param  USBx  usb device instance
2572    * @param  ep pointer to endpoint structure
2573    * @retval HAL status
2574    */
USB_EPStopXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)2575 HAL_StatusTypeDef USB_EPStopXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2576 {
2577   /* IN endpoint */
2578   if (ep->is_in == 1U)
2579   {
2580     if (ep->doublebuffer == 0U)
2581     {
2582       if (ep->type != EP_TYPE_ISOC)
2583       {
2584         /* Configure NAK status for the Endpoint */
2585         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2586       }
2587       else
2588       {
2589         /* Configure TX Endpoint to disabled state */
2590         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2591       }
2592     }
2593   }
2594   else /* OUT endpoint */
2595   {
2596     if (ep->doublebuffer == 0U)
2597     {
2598       if (ep->type != EP_TYPE_ISOC)
2599       {
2600         /* Configure NAK status for the Endpoint */
2601         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2602       }
2603       else
2604       {
2605         /* Configure RX Endpoint to disabled state */
2606         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2607       }
2608     }
2609   }
2610 
2611   return HAL_OK;
2612 }
2613 #endif /* defined (HAL_PCD_MODULE_ENABLED) */
2614 
2615 /**
2616   * @brief  USB_StopDevice Stop the usb device mode
2617   * @param  USBx Selected device
2618   * @retval HAL status
2619   */
USB_StopDevice(USB_TypeDef * USBx)2620 HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
2621 {
2622   /* disable all interrupts and force USB reset */
2623   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2624 
2625   /* clear interrupt status register */
2626   USBx->ISTR = 0U;
2627 
2628   /* switch-off device */
2629   USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
2630 
2631   return HAL_OK;
2632 }
2633 
2634 /**
2635   * @brief  USB_SetDevAddress Stop the usb device mode
2636   * @param  USBx Selected device
2637   * @param  address new device address to be assigned
2638   *          This parameter can be a value from 0 to 255
2639   * @retval HAL status
2640   */
USB_SetDevAddress(USB_TypeDef * USBx,uint8_t address)2641 HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
2642 {
2643   if (address == 0U)
2644   {
2645     /* set device address and enable function */
2646     USBx->DADDR = (uint16_t)USB_DADDR_EF;
2647   }
2648 
2649   return HAL_OK;
2650 }
2651 
2652 /**
2653   * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
2654   * @param  USBx Selected device
2655   * @retval HAL status
2656   */
USB_DevConnect(USB_TypeDef * USBx)2657 HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
2658 {
2659   /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */
2660   USBx->BCDR |= (uint16_t)USB_BCDR_DPPU;
2661 
2662   return HAL_OK;
2663 }
2664 
2665 /**
2666   * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
2667   * @param  USBx Selected device
2668   * @retval HAL status
2669   */
USB_DevDisconnect(USB_TypeDef * USBx)2670 HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
2671 {
2672   /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */
2673   USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU));
2674 
2675   return HAL_OK;
2676 }
2677 
2678 /**
2679   * @brief  USB_ReadInterrupts return the global USB interrupt status
2680   * @param  USBx Selected device
2681   * @retval USB Global Interrupt status
2682   */
USB_ReadInterrupts(USB_TypeDef const * USBx)2683 uint32_t USB_ReadInterrupts(USB_TypeDef const *USBx)
2684 {
2685   uint32_t tmpreg;
2686 
2687   tmpreg = USBx->ISTR;
2688   return tmpreg;
2689 }
2690 
2691 /**
2692   * @brief  USB_ReadDevAllOutEpInterrupt return the USB device OUT endpoints interrupt status
2693   * @param  USBx Selected device
2694   * @retval HAL status
2695   */
USB_ReadDevAllOutEpInterrupt(USB_TypeDef * USBx)2696 uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx)
2697 {
2698   /* Prevent unused argument(s) compilation warning */
2699   UNUSED(USBx);
2700   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2701               only by USB OTG FS peripheral.
2702             - This function is added to ensure compatibility across platforms.
2703    */
2704   return (0);
2705 }
2706 
2707 /**
2708   * @brief  USB_ReadDevAllInEpInterrupt return the USB device IN endpoints interrupt status
2709   * @param  USBx Selected device
2710   * @retval HAL status
2711   */
USB_ReadDevAllInEpInterrupt(USB_TypeDef * USBx)2712 uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx)
2713 {
2714   /* Prevent unused argument(s) compilation warning */
2715   UNUSED(USBx);
2716   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2717               only by USB OTG FS peripheral.
2718             - This function is added to ensure compatibility across platforms.
2719    */
2720   return (0);
2721 }
2722 
2723 /**
2724   * @brief  Returns Device OUT EP Interrupt register
2725   * @param  USBx Selected device
2726   * @param  epnum endpoint number
2727   *          This parameter can be a value from 0 to 15
2728   * @retval Device OUT EP Interrupt register
2729   */
USB_ReadDevOutEPInterrupt(USB_TypeDef * USBx,uint8_t epnum)2730 uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2731 {
2732   /* Prevent unused argument(s) compilation warning */
2733   UNUSED(USBx);
2734   UNUSED(epnum);
2735   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2736               only by USB OTG FS peripheral.
2737             - This function is added to ensure compatibility across platforms.
2738    */
2739   return (0);
2740 }
2741 
2742 /**
2743   * @brief  Returns Device IN EP Interrupt register
2744   * @param  USBx Selected device
2745   * @param  epnum endpoint number
2746   *          This parameter can be a value from 0 to 15
2747   * @retval Device IN EP Interrupt register
2748   */
USB_ReadDevInEPInterrupt(USB_TypeDef * USBx,uint8_t epnum)2749 uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2750 {
2751   /* Prevent unused argument(s) compilation warning */
2752   UNUSED(USBx);
2753   UNUSED(epnum);
2754   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2755               only by USB OTG FS peripheral.
2756             - This function is added to ensure compatibility across platforms.
2757    */
2758   return (0);
2759 }
2760 
2761 /**
2762   * @brief  USB_ClearInterrupts: clear a USB interrupt
2763   * @param  USBx Selected device
2764   * @param  interrupt  flag
2765   * @retval None
2766   */
USB_ClearInterrupts(USB_TypeDef * USBx,uint32_t interrupt)2767 void  USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt)
2768 {
2769   /* Prevent unused argument(s) compilation warning */
2770   UNUSED(USBx);
2771   UNUSED(interrupt);
2772   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2773               only by USB OTG FS peripheral.
2774             - This function is added to ensure compatibility across platforms.
2775    */
2776 }
2777 
2778 /**
2779   * @brief  Prepare the EP0 to start the first control setup
2780   * @param  USBx Selected device
2781   * @param  psetup pointer to setup packet
2782   * @retval HAL status
2783   */
USB_EP0_OutStart(USB_TypeDef * USBx,uint8_t * psetup)2784 HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
2785 {
2786   /* Prevent unused argument(s) compilation warning */
2787   UNUSED(USBx);
2788   UNUSED(psetup);
2789   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2790               only by USB OTG FS peripheral.
2791             - This function is added to ensure compatibility across platforms.
2792    */
2793   return HAL_OK;
2794 }
2795 
2796 /**
2797   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
2798   * @param  USBx Selected device
2799   * @retval HAL status
2800   */
USB_ActivateRemoteWakeup(USB_TypeDef * USBx)2801 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
2802 {
2803   USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
2804 
2805   return HAL_OK;
2806 }
2807 
2808 /**
2809   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2810   * @param  USBx Selected device
2811   * @retval HAL status
2812   */
USB_DeActivateRemoteWakeup(USB_TypeDef * USBx)2813 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
2814 {
2815   USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
2816 
2817   return HAL_OK;
2818 }
2819 
2820 /**
2821   * @brief Copy a buffer from user memory area to packet memory area (PMA)
2822   * @param   USBx USB peripheral instance register address.
2823   * @param   pbUsrBuf pointer to user memory area.
2824   * @param   wPMABufAddr address into PMA.
2825   * @param   wNBytes no. of bytes to be copied.
2826   * @retval None
2827   */
USB_WritePMA(USB_TypeDef const * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)2828 void USB_WritePMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2829 {
2830   uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
2831   uint32_t BaseAddr = (uint32_t)USBx;
2832   uint32_t count;
2833   uint16_t WrVal;
2834   __IO uint16_t *pdwVal;
2835   uint8_t *pBuf = pbUsrBuf;
2836 
2837   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2838 
2839   for (count = n; count != 0U; count--)
2840   {
2841     WrVal = pBuf[0];
2842     WrVal |= (uint16_t)pBuf[1] << 8;
2843     *pdwVal = (WrVal & 0xFFFFU);
2844     pdwVal++;
2845 
2846 #if PMA_ACCESS > 1U
2847     pdwVal++;
2848 #endif /* PMA_ACCESS */
2849 
2850     pBuf++;
2851     pBuf++;
2852   }
2853 }
2854 
2855 /**
2856   * @brief Copy data from packet memory area (PMA) to user memory buffer
2857   * @param   USBx USB peripheral instance register address.
2858   * @param   pbUsrBuf pointer to user memory area.
2859   * @param   wPMABufAddr address into PMA.
2860   * @param   wNBytes no. of bytes to be copied.
2861   * @retval None
2862   */
USB_ReadPMA(USB_TypeDef const * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)2863 void USB_ReadPMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2864 {
2865   uint32_t n = (uint32_t)wNBytes >> 1;
2866   uint32_t BaseAddr = (uint32_t)USBx;
2867   uint32_t count;
2868   uint32_t RdVal;
2869   __IO uint16_t *pdwVal;
2870   uint8_t *pBuf = pbUsrBuf;
2871 
2872   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2873 
2874   for (count = n; count != 0U; count--)
2875   {
2876     RdVal = *(__IO uint16_t *)pdwVal;
2877     pdwVal++;
2878     *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2879     pBuf++;
2880     *pBuf = (uint8_t)((RdVal >> 8) & 0xFFU);
2881     pBuf++;
2882 
2883 #if PMA_ACCESS > 1U
2884     pdwVal++;
2885 #endif /* PMA_ACCESS */
2886   }
2887 
2888   if ((wNBytes % 2U) != 0U)
2889   {
2890     RdVal = *pdwVal;
2891     *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2892   }
2893 }
2894 
2895 #endif /* defined (USB) */
2896 /**
2897   * @}
2898   */
2899 
2900 /**
2901   * @}
2902   */
2903 #endif /* defined (USB) || defined (USB_OTG_FS) */
2904 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2905 
2906 /**
2907   * @}
2908   */
2909