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