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