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