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