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