]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil/ST_Library/stm32f7xx_ll_usb.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil / ST_Library / stm32f7xx_ll_usb.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f7xx_ll_usb.c\r
4   * @author  MCD Application Team\r
5   * @version V1.0.0RC1\r
6   * @date    24-March-2015\r
7   * @brief   USB Low Layer HAL module driver.\r
8   *    \r
9   *          This file provides firmware functions to manage the following \r
10   *          functionalities of the USB Peripheral Controller:\r
11   *           + Initialization/de-initialization functions\r
12   *           + I/O operation functions\r
13   *           + Peripheral Control functions \r
14   *           + Peripheral State functions\r
15   *         \r
16   @verbatim\r
17   ==============================================================================\r
18                     ##### How to use this driver #####\r
19   ==============================================================================\r
20     [..]\r
21       (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.\r
22   \r
23       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.\r
24 \r
25       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.\r
26 \r
27   @endverbatim\r
28   ******************************************************************************\r
29   * @attention\r
30   *\r
31   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>\r
32   *\r
33   * Redistribution and use in source and binary forms, with or without modification,\r
34   * are permitted provided that the following conditions are met:\r
35   *   1. Redistributions of source code must retain the above copyright notice,\r
36   *      this list of conditions and the following disclaimer.\r
37   *   2. Redistributions in binary form must reproduce the above copyright notice,\r
38   *      this list of conditions and the following disclaimer in the documentation\r
39   *      and/or other materials provided with the distribution.\r
40   *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
41   *      may be used to endorse or promote products derived from this software\r
42   *      without specific prior written permission.\r
43   *\r
44   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
45   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
46   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
47   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
48   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
49   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
50   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
51   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
52   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
53   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
54   *\r
55   ******************************************************************************\r
56   */ \r
57 \r
58 /* Includes ------------------------------------------------------------------*/\r
59 #include "stm32f7xx_hal.h"\r
60 \r
61 /** @addtogroup STM32F7xx_LL_USB_DRIVER\r
62   * @{\r
63   */\r
64 \r
65 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)\r
66 \r
67 /* Private typedef -----------------------------------------------------------*/\r
68 /* Private define ------------------------------------------------------------*/\r
69 /* Private macro -------------------------------------------------------------*/\r
70 /* Private variables ---------------------------------------------------------*/\r
71 /* Private function prototypes -----------------------------------------------*/\r
72 /* Private functions ---------------------------------------------------------*/\r
73 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);\r
74 \r
75 /** @defgroup PCD_Private_Functions\r
76   * @{\r
77   */\r
78 \r
79 /** @defgroup LL_USB_Group1 Initialization/de-initialization functions \r
80  *  @brief    Initialization and Configuration functions \r
81  *\r
82 @verbatim    \r
83  ===============================================================================\r
84               ##### Initialization/de-initialization functions #####\r
85  ===============================================================================\r
86     [..]  This section provides functions allowing to:\r
87  \r
88 @endverbatim\r
89   * @{\r
90   */\r
91 \r
92 /**\r
93   * @brief  Initializes the USB Core\r
94   * @param  USBx: USB Instance\r
95   * @param  cfg : pointer to a USB_OTG_CfgTypeDef structure that contains\r
96   *         the configuration information for the specified USBx peripheral.\r
97   * @retval HAL status\r
98   */\r
99 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)\r
100 {\r
101   if (cfg.phy_itface == USB_OTG_ULPI_PHY)\r
102   {\r
103     \r
104     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);\r
105 \r
106     /* Init The ULPI Interface */\r
107     USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);\r
108    \r
109     /* Select vbus source */\r
110     USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);\r
111     if(cfg.use_external_vbus == 1)\r
112     {\r
113       USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;\r
114     }\r
115     /* Reset after a PHY select  */\r
116     USB_CoreReset(USBx); \r
117   }\r
118   else /* FS interface (embedded Phy) */\r
119   {\r
120     \r
121     /* Select FS Embedded PHY */\r
122     USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;\r
123     \r
124     /* Reset after a PHY select and set Host mode */\r
125     USB_CoreReset(USBx);\r
126     \r
127     /* Deactivate the power down*/\r
128     USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;\r
129   }\r
130  \r
131   if(cfg.dma_enable == ENABLE)\r
132   {\r
133     USBx->GAHBCFG |= (USB_OTG_GAHBCFG_HBSTLEN_1 | USB_OTG_GAHBCFG_HBSTLEN_2);\r
134     USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;\r
135   }  \r
136 \r
137   return HAL_OK;\r
138 }\r
139 \r
140 /**\r
141   * @brief  USB_EnableGlobalInt\r
142   *         Enables the controller's Global Int in the AHB Config reg\r
143   * @param  USBx : Selected device\r
144   * @retval HAL status\r
145   */\r
146 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)\r
147 {\r
148   USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;\r
149   return HAL_OK;\r
150 }\r
151 \r
152 \r
153 /**\r
154   * @brief  USB_DisableGlobalInt\r
155   *         Disable the controller's Global Int in the AHB Config reg\r
156   * @param  USBx : Selected device\r
157   * @retval HAL status\r
158 */\r
159 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)\r
160 {\r
161   USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;\r
162   return HAL_OK;\r
163 }\r
164    \r
165 /**\r
166   * @brief  USB_SetCurrentMode : Set functional mode\r
167   * @param  USBx : Selected device\r
168   * @param  mode :  current core mode\r
169   *          This parameter can be one of the these values:\r
170   *            @arg USB_OTG_DEVICE_MODE: Peripheral mode\r
171   *            @arg USB_OTG_HOST_MODE: Host mode\r
172   *            @arg USB_OTG_DRD_MODE: Dual Role Device mode  \r
173   * @retval HAL status\r
174   */\r
175 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode)\r
176 {\r
177   USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD); \r
178   \r
179   if ( mode == USB_OTG_HOST_MODE)\r
180   {\r
181     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD; \r
182   }\r
183   else if ( mode == USB_OTG_DEVICE_MODE)\r
184   {\r
185     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; \r
186   }\r
187   HAL_Delay(50);\r
188   \r
189   return HAL_OK;\r
190 }\r
191 \r
192 /**\r
193   * @brief  USB_DevInit : Initializes the USB_OTG controller registers \r
194   *         for device mode\r
195   * @param  USBx : Selected device\r
196   * @param  cfg  : pointer to a USB_OTG_CfgTypeDef structure that contains\r
197   *         the configuration information for the specified USBx peripheral.\r
198   * @retval HAL status\r
199   */\r
200 HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)\r
201 {\r
202   uint32_t i = 0;\r
203 \r
204   /*Activate VBUS Sensing B */\r
205   USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;\r
206   \r
207   if (cfg.vbus_sensing_enable == 0)\r
208   {\r
209     /*Desactivate VBUS Sensing B */\r
210     USBx->GCCFG &= ~ USB_OTG_GCCFG_VBDEN;\r
211     \r
212     /* B-peripheral session valid override enable*/ \r
213     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;\r
214     USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;\r
215   }\r
216    \r
217   /* Restart the Phy Clock */\r
218   USBx_PCGCCTL = 0;\r
219 \r
220   /* Device mode configuration */\r
221   USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;\r
222   \r
223   if(cfg.phy_itface  == USB_OTG_ULPI_PHY)\r
224   {\r
225     if(cfg.speed == USB_OTG_SPEED_HIGH)\r
226     {      \r
227       /* Set High speed phy */\r
228       USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH);\r
229     }\r
230     else \r
231     {\r
232       /* set High speed phy in Full speed mode */\r
233       USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL);\r
234     }\r
235   }\r
236   else\r
237   {\r
238     /* Set Full speed phy */\r
239     USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);\r
240   }\r
241 \r
242   /* Flush the FIFOs */\r
243   USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */\r
244   USB_FlushRxFifo(USBx);\r
245 \r
246   \r
247   /* Clear all pending Device Interrupts */\r
248   USBx_DEVICE->DIEPMSK = 0;\r
249   USBx_DEVICE->DOEPMSK = 0;\r
250   USBx_DEVICE->DAINT = 0xFFFFFFFF;\r
251   USBx_DEVICE->DAINTMSK = 0;\r
252   \r
253   for (i = 0; i < cfg.dev_endpoints; i++)\r
254   {\r
255     if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)\r
256     {\r
257       USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);\r
258     }\r
259     else\r
260     {\r
261       USBx_INEP(i)->DIEPCTL = 0;\r
262     }\r
263     \r
264     USBx_INEP(i)->DIEPTSIZ = 0;\r
265     USBx_INEP(i)->DIEPINT  = 0xFF;\r
266   }\r
267   \r
268   for (i = 0; i < cfg.dev_endpoints; i++)\r
269   {\r
270     if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)\r
271     {\r
272       USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);\r
273     }\r
274     else\r
275     {\r
276       USBx_OUTEP(i)->DOEPCTL = 0;\r
277     }\r
278     \r
279     USBx_OUTEP(i)->DOEPTSIZ = 0;\r
280     USBx_OUTEP(i)->DOEPINT  = 0xFF;\r
281   }\r
282   \r
283   USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);\r
284   \r
285   if (cfg.dma_enable == 1)\r
286   {\r
287     /*Set threshold parameters */\r
288     USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6);\r
289     USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN);\r
290     \r
291     i= USBx_DEVICE->DTHRCTL;\r
292   }\r
293   \r
294   /* Disable all interrupts. */\r
295   USBx->GINTMSK = 0;\r
296   \r
297   /* Clear any pending interrupts */\r
298   USBx->GINTSTS = 0xBFFFFFFF;\r
299 \r
300   /* Enable the common interrupts */\r
301   if (cfg.dma_enable == DISABLE)\r
302   {\r
303     USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; \r
304   }\r
305   \r
306   /* Enable interrupts matching to the Device mode ONLY */\r
307   USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\\r
308                     USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\\r
309                     USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM|\\r
310                     USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);\r
311   \r
312   if(cfg.Sof_enable)\r
313   {\r
314     USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;\r
315   }\r
316 \r
317   if (cfg.vbus_sensing_enable == ENABLE)\r
318   {\r
319     USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT); \r
320   }\r
321   \r
322   return HAL_OK;\r
323 }\r
324 \r
325 \r
326 /**\r
327   * @brief  USB_OTG_FlushTxFifo : Flush a Tx FIFO\r
328   * @param  USBx : Selected device\r
329   * @param  num : FIFO number\r
330   *         This parameter can be a value from 1 to 15\r
331             15 means Flush all Tx FIFOs\r
332   * @retval HAL status\r
333   */\r
334 HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )\r
335 {\r
336   uint32_t count = 0;\r
337  \r
338   USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 5 )); \r
339  \r
340   do\r
341   {\r
342     if (++count > 200000)\r
343     {\r
344       return HAL_TIMEOUT;\r
345     }\r
346   }\r
347   while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);\r
348   \r
349   return HAL_OK;\r
350 }\r
351 \r
352 \r
353 /**\r
354   * @brief  USB_FlushRxFifo : Flush Rx FIFO\r
355   * @param  USBx : Selected device\r
356   * @retval HAL status\r
357   */\r
358 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)\r
359 {\r
360   uint32_t count = 0;\r
361   \r
362   USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;\r
363   \r
364   do\r
365   {\r
366     if (++count > 200000)\r
367     {\r
368       return HAL_TIMEOUT;\r
369     }\r
370   }\r
371   while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);\r
372   \r
373   return HAL_OK;\r
374 }\r
375 \r
376 /**\r
377   * @brief  USB_SetDevSpeed :Initializes the DevSpd field of DCFG register \r
378   *         depending the PHY type and the enumeration speed of the device.\r
379   * @param  USBx : Selected device\r
380   * @param  speed : device speed\r
381   *          This parameter can be one of the these values:\r
382   *            @arg USB_OTG_SPEED_HIGH: High speed mode\r
383   *            @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode\r
384   *            @arg USB_OTG_SPEED_FULL: Full speed mode\r
385   *            @arg USB_OTG_SPEED_LOW: Low speed mode\r
386   * @retval  Hal status\r
387   */\r
388 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)\r
389 {\r
390   USBx_DEVICE->DCFG |= speed;\r
391   return HAL_OK;\r
392 }\r
393 \r
394 /**\r
395   * @brief  USB_GetDevSpeed :Return the  Dev Speed \r
396   * @param  USBx : Selected device\r
397   * @retval speed : device speed\r
398   *          This parameter can be one of the these values:\r
399   *            @arg USB_OTG_SPEED_HIGH: High speed mode\r
400   *            @arg USB_OTG_SPEED_FULL: Full speed mode\r
401   *            @arg USB_OTG_SPEED_LOW: Low speed mode\r
402   */\r
403 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)\r
404 {\r
405   uint8_t speed = 0;\r
406   \r
407   if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)\r
408   {\r
409     speed = USB_OTG_SPEED_HIGH;\r
410   }\r
411   else if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||\r
412            ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))\r
413   {\r
414     speed = USB_OTG_SPEED_FULL;\r
415   }\r
416   else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)\r
417   {\r
418     speed = USB_OTG_SPEED_LOW;\r
419   }\r
420   \r
421   return speed;\r
422 }\r
423 \r
424 /**\r
425   * @brief  Activate and configure an endpoint\r
426   * @param  USBx : Selected device\r
427   * @param  ep: pointer to endpoint structure\r
428   * @retval HAL status\r
429   */\r
430 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)\r
431 {\r
432   if (ep->is_in == 1)\r
433   {\r
434    USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));\r
435    \r
436     if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)\r
437     {\r
438       USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\\r
439         ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); \r
440     } \r
441 \r
442   }\r
443   else\r
444   {\r
445      USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);\r
446      \r
447     if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)\r
448     {\r
449       USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\\r
450        (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));\r
451     } \r
452   }\r
453   return HAL_OK;\r
454 }\r
455 /**\r
456   * @brief  Activate and configure a dedicated endpoint\r
457   * @param  USBx : Selected device\r
458   * @param  ep: pointer to endpoint structure\r
459   * @retval HAL status\r
460   */\r
461 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)\r
462 {\r
463   static __IO uint32_t debug = 0;\r
464   \r
465   /* Read DEPCTLn register */\r
466   if (ep->is_in == 1)\r
467   {\r
468     if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)\r
469     {\r
470       USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\\r
471         ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); \r
472     } \r
473     \r
474     \r
475     debug  |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\\r
476         ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); \r
477     \r
478    USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));\r
479   }\r
480   else\r
481   {\r
482     if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)\r
483     {\r
484       USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\\r
485         ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP));\r
486       \r
487       debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0)*USB_OTG_EP_REG_SIZE);\r
488       debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL;\r
489       debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\\r
490         ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); \r
491     } \r
492     \r
493      USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);\r
494   }\r
495 \r
496   return HAL_OK;\r
497 }\r
498 /**\r
499   * @brief  De-activate and de-initialize an endpoint\r
500   * @param  USBx : Selected device\r
501   * @param  ep: pointer to endpoint structure\r
502   * @retval HAL status\r
503   */\r
504 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)\r
505 {\r
506   /* Read DEPCTLn register */\r
507   if (ep->is_in == 1)\r
508   {\r
509    USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));\r
510    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));   \r
511    USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;   \r
512   }\r
513   else\r
514   {\r
515 \r
516      USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));\r
517      USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));     \r
518      USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;      \r
519   }\r
520   return HAL_OK;\r
521 }\r
522 \r
523 /**\r
524   * @brief  De-activate and de-initialize a dedicated endpoint\r
525   * @param  USBx : Selected device\r
526   * @param  ep: pointer to endpoint structure\r
527   * @retval HAL status\r
528   */\r
529 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)\r
530 {\r
531   /* Read DEPCTLn register */\r
532   if (ep->is_in == 1)\r
533   {\r
534    USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;\r
535    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));\r
536   }\r
537   else\r
538   {\r
539      USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; \r
540      USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));\r
541   }\r
542   return HAL_OK;\r
543 }\r
544 \r
545 /**\r
546   * @brief  USB_EPStartXfer : setup and starts a transfer over an EP\r
547   * @param  USBx : Selected device\r
548   * @param  ep: pointer to endpoint structure\r
549   * @param  dma: USB dma enabled or disabled \r
550   *          This parameter can be one of the these values:\r
551   *           0 : DMA feature not used \r
552   *           1 : DMA feature used  \r
553   * @retval HAL status\r
554   */\r
555 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)\r
556 {\r
557   uint16_t pktcnt = 0;\r
558   \r
559   /* IN endpoint */\r
560   if (ep->is_in == 1)\r
561   {\r
562     /* Zero Length Packet? */\r
563     if (ep->xfer_len == 0)\r
564     {\r
565       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); \r
566       USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;\r
567       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); \r
568     }\r
569     else\r
570     {\r
571       /* Program the transfer size and packet count\r
572       * as follows: xfersize = N * maxpacket +\r
573       * short_packet pktcnt = N + (short_packet\r
574       * exist ? 1 : 0)\r
575       */\r
576       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);\r
577       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); \r
578       USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ;\r
579       USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); \r
580       \r
581       if (ep->type == EP_TYPE_ISOC)\r
582       {\r
583         USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); \r
584         USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29)); \r
585       }       \r
586     }\r
587 \r
588     if (dma == 1)\r
589     {\r
590       USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);\r
591     }\r
592     else\r
593     {\r
594       if (ep->type != EP_TYPE_ISOC)\r
595       {\r
596         /* Enable the Tx FIFO Empty Interrupt for this EP */\r
597         if (ep->xfer_len > 0)\r
598         {\r
599           USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num;\r
600         }\r
601       }\r
602     }\r
603 \r
604     if (ep->type == EP_TYPE_ISOC)\r
605     {\r
606       if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)\r
607       {\r
608         USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;\r
609       }\r
610       else\r
611       {\r
612         USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;\r
613       }\r
614     } \r
615     \r
616     /* EP enable, IN data in FIFO */\r
617     USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);\r
618     \r
619     if (ep->type == EP_TYPE_ISOC)\r
620     {\r
621       USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma);   \r
622     }    \r
623   }\r
624   else /* OUT endpoint */\r
625   {\r
626     /* Program the transfer size and packet count as follows:\r
627     * pktcnt = N\r
628     * xfersize = N * maxpacket\r
629     */  \r
630     USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); \r
631     USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); \r
632       \r
633     if (ep->xfer_len == 0)\r
634     {\r
635       USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);\r
636       USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ;      \r
637     }\r
638     else\r
639     {\r
640       pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket; \r
641       USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));\r
642       USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt)); \r
643     }\r
644 \r
645     if (dma == 1)\r
646     {\r
647       USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff;\r
648     }\r
649     \r
650     if (ep->type == EP_TYPE_ISOC)\r
651     {\r
652       if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)\r
653       {\r
654         USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;\r
655       }\r
656       else\r
657       {\r
658         USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;\r
659       }\r
660     }\r
661     /* EP enable */\r
662     USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);\r
663   }\r
664   return HAL_OK;\r
665 }\r
666 \r
667 /**\r
668   * @brief  USB_EP0StartXfer : setup and starts a transfer over the EP  0\r
669   * @param  USBx : Selected device\r
670   * @param  ep: pointer to endpoint structure\r
671   * @param  dma: USB dma enabled or disabled \r
672   *          This parameter can be one of the these values:\r
673   *           0 : DMA feature not used \r
674   *           1 : DMA feature used  \r
675   * @retval HAL status\r
676   */\r
677 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)\r
678 {\r
679   /* IN endpoint */\r
680   if (ep->is_in == 1)\r
681   {\r
682     /* Zero Length Packet? */\r
683     if (ep->xfer_len == 0)\r
684     {\r
685       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); \r
686       USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;\r
687       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); \r
688     }\r
689     else\r
690     {\r
691       /* Program the transfer size and packet count\r
692       * as follows: xfersize = N * maxpacket +\r
693       * short_packet pktcnt = N + (short_packet\r
694       * exist ? 1 : 0)\r
695       */\r
696       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);\r
697       USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); \r
698       \r
699       if(ep->xfer_len > ep->maxpacket)\r
700       {\r
701         ep->xfer_len = ep->maxpacket;\r
702       }\r
703       USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;\r
704       USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); \r
705     \r
706     }\r
707     \r
708     if (dma == 1)\r
709     {\r
710       USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);\r
711     }\r
712     else\r
713     {\r
714       /* Enable the Tx FIFO Empty Interrupt for this EP */\r
715       if (ep->xfer_len > 0)\r
716       {\r
717         USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num);\r
718       }\r
719     }\r
720     \r
721     /* EP enable, IN data in FIFO */\r
722     USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);   \r
723   }\r
724   else /* OUT endpoint */\r
725   {\r
726     /* Program the transfer size and packet count as follows:\r
727     * pktcnt = N\r
728     * xfersize = N * maxpacket\r
729     */\r
730     USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); \r
731     USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); \r
732       \r
733     if (ep->xfer_len > 0)\r
734     {\r
735       ep->xfer_len = ep->maxpacket;\r
736     }\r
737     \r
738     USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));\r
739     USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket)); \r
740     \r
741 \r
742     if (dma == 1)\r
743     {\r
744       USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff);\r
745     }\r
746     \r
747     /* EP enable */\r
748     USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);    \r
749   }\r
750   return HAL_OK;\r
751 }\r
752 \r
753 /**\r
754   * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated \r
755   *         with the EP/channel\r
756   * @param  USBx : Selected device           \r
757   * @param  src :  pointer to source buffer\r
758   * @param  ch_ep_num : endpoint or host channel number\r
759   * @param  len : Number of bytes to write\r
760   * @param  dma: USB dma enabled or disabled \r
761   *          This parameter can be one of the these values:\r
762   *           0 : DMA feature not used \r
763   *           1 : DMA feature used  \r
764   * @retval HAL status\r
765   */\r
766 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)\r
767 {\r
768   uint32_t count32b= 0 , i= 0;\r
769   \r
770   if (dma == 0)\r
771   {\r
772     count32b =  (len + 3) / 4;\r
773     for (i = 0; i < count32b; i++, src += 4)\r
774     {\r
775       USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);\r
776     }\r
777   }\r
778   return HAL_OK;\r
779 }\r
780 \r
781 /**\r
782   * @brief  USB_ReadPacket : read a packet from the Tx FIFO associated \r
783   *         with the EP/channel\r
784   * @param  USBx : Selected device  \r
785   * @param  src : source pointer\r
786   * @param  ch_ep_num : endpoint or host channel number\r
787   * @param  len : Number of bytes to read\r
788   * @param  dma: USB dma enabled or disabled \r
789   *          This parameter can be one of the these values:\r
790   *           0 : DMA feature not used \r
791   *           1 : DMA feature used  \r
792   * @retval pointer to destination buffer\r
793   */\r
794 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)\r
795 {\r
796   uint32_t i=0;\r
797   uint32_t count32b = (len + 3) / 4;\r
798   \r
799   for ( i = 0; i < count32b; i++, dest += 4 )\r
800   {\r
801     *(__packed uint32_t *)dest = USBx_DFIFO(0);\r
802     \r
803   }\r
804   return ((void *)dest);\r
805 }\r
806 \r
807 /**\r
808   * @brief  USB_EPSetStall : set a stall condition over an EP\r
809   * @param  USBx : Selected device\r
810   * @param  ep: pointer to endpoint structure   \r
811   * @retval HAL status\r
812   */\r
813 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)\r
814 {\r
815   if (ep->is_in == 1)\r
816   {\r
817     if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0)\r
818     {\r
819       USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS); \r
820     } \r
821     USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;\r
822   }\r
823   else\r
824   {\r
825     if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0)\r
826     {\r
827       USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS); \r
828     } \r
829     USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;\r
830   }\r
831   return HAL_OK;\r
832 }\r
833 \r
834 \r
835 /**\r
836   * @brief  USB_EPClearStall : Clear a stall condition over an EP\r
837   * @param  USBx : Selected device\r
838   * @param  ep: pointer to endpoint structure   \r
839   * @retval HAL status\r
840   */\r
841 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)\r
842 {\r
843   if (ep->is_in == 1)\r
844   {\r
845     USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;\r
846     if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)\r
847     {\r
848        USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */\r
849     }    \r
850   }\r
851   else\r
852   {\r
853     USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;\r
854     if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)\r
855     {\r
856       USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */\r
857     }    \r
858   }\r
859   return HAL_OK;\r
860 }\r
861 \r
862 /**\r
863   * @brief  USB_StopDevice : Stop the usb device mode\r
864   * @param  USBx : Selected device\r
865   * @retval HAL status\r
866   */\r
867 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)\r
868 {\r
869   uint32_t i;\r
870   \r
871   /* Clear Pending interrupt */\r
872   for (i = 0; i < 15 ; i++)\r
873   {\r
874     USBx_INEP(i)->DIEPINT  = 0xFF;\r
875     USBx_OUTEP(i)->DOEPINT  = 0xFF;\r
876   }\r
877   USBx_DEVICE->DAINT = 0xFFFFFFFF;\r
878   \r
879   /* Clear interrupt masks */\r
880   USBx_DEVICE->DIEPMSK  = 0;\r
881   USBx_DEVICE->DOEPMSK  = 0;\r
882   USBx_DEVICE->DAINTMSK = 0;\r
883   \r
884   /* Flush the FIFO */\r
885   USB_FlushRxFifo(USBx);\r
886   USB_FlushTxFifo(USBx ,  0x10 );  \r
887   \r
888   return HAL_OK;\r
889 }\r
890 \r
891 /**\r
892   * @brief  USB_SetDevAddress : Stop the usb device mode\r
893   * @param  USBx : Selected device\r
894   * @param  address : new device address to be assigned\r
895   *          This parameter can be a value from 0 to 255\r
896   * @retval HAL status\r
897   */\r
898 HAL_StatusTypeDef  USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)\r
899 {\r
900   USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);\r
901   USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD ;\r
902   \r
903   return HAL_OK;  \r
904 }\r
905 \r
906 /**\r
907   * @brief  USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down\r
908   * @param  USBx : Selected device\r
909   * @retval HAL status\r
910   */\r
911 HAL_StatusTypeDef  USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)\r
912 {\r
913   USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;\r
914   HAL_Delay(3);\r
915   \r
916   return HAL_OK;  \r
917 }\r
918 \r
919 /**\r
920   * @brief  USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down\r
921   * @param  USBx : Selected device\r
922   * @retval HAL status\r
923   */\r
924 HAL_StatusTypeDef  USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)\r
925 {\r
926   USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS ;\r
927   HAL_Delay(3);\r
928   \r
929   return HAL_OK;  \r
930 }\r
931 \r
932 /**\r
933   * @brief  USB_ReadInterrupts: return the global USB interrupt status\r
934   * @param  USBx : Selected device\r
935   * @retval HAL status\r
936   */\r
937 uint32_t  USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)\r
938 {\r
939   uint32_t v = 0;\r
940   \r
941   v = USBx->GINTSTS;\r
942   v &= USBx->GINTMSK;\r
943   return v;  \r
944 }\r
945 \r
946 /**\r
947   * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status\r
948   * @param  USBx : Selected device\r
949   * @retval HAL status\r
950   */\r
951 uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)\r
952 {\r
953   uint32_t v;\r
954   v  = USBx_DEVICE->DAINT;\r
955   v &= USBx_DEVICE->DAINTMSK;\r
956   return ((v & 0xffff0000) >> 16);\r
957 }\r
958 \r
959 /**\r
960   * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status\r
961   * @param  USBx : Selected device\r
962   * @retval HAL status\r
963   */\r
964 uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)\r
965 {\r
966   uint32_t v;\r
967   v  = USBx_DEVICE->DAINT;\r
968   v &= USBx_DEVICE->DAINTMSK;\r
969   return ((v & 0xFFFF));\r
970 }\r
971 \r
972 /**\r
973   * @brief  Returns Device OUT EP Interrupt register\r
974   * @param  USBx : Selected device\r
975   * @param  epnum : endpoint number\r
976   *          This parameter can be a value from 0 to 15\r
977   * @retval Device OUT EP Interrupt register\r
978   */\r
979 uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)\r
980 {\r
981   uint32_t v;\r
982   v  = USBx_OUTEP(epnum)->DOEPINT;\r
983   v &= USBx_DEVICE->DOEPMSK;\r
984   return v;\r
985 }\r
986 \r
987 /**\r
988   * @brief  Returns Device IN EP Interrupt register\r
989   * @param  USBx : Selected device\r
990   * @param  epnum : endpoint number\r
991   *          This parameter can be a value from 0 to 15\r
992   * @retval Device IN EP Interrupt register\r
993   */\r
994 uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)\r
995 {\r
996   uint32_t v, msk, emp;\r
997   \r
998   msk = USBx_DEVICE->DIEPMSK;\r
999   emp = USBx_DEVICE->DIEPEMPMSK;\r
1000   msk |= ((emp >> epnum) & 0x1) << 7;\r
1001   v = USBx_INEP(epnum)->DIEPINT & msk;\r
1002   return v;\r
1003 }\r
1004 \r
1005 /**\r
1006   * @brief  USB_ClearInterrupts: clear a USB interrupt\r
1007   * @param  USBx : Selected device\r
1008   * @param  interrupt : interrupt flag\r
1009   * @retval None\r
1010   */\r
1011 void  USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)\r
1012 {\r
1013   USBx->GINTSTS |= interrupt; \r
1014 }\r
1015 \r
1016 /**\r
1017   * @brief  Returns USB core mode\r
1018   * @param  USBx : Selected device\r
1019   * @retval return core mode : Host or Device\r
1020   *          This parameter can be one of the these values:\r
1021   *           0 : Host \r
1022   *           1 : Device\r
1023   */\r
1024 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)\r
1025 {\r
1026   return ((USBx->GINTSTS ) & 0x1);\r
1027 }\r
1028 \r
1029 \r
1030 /**\r
1031   * @brief  Activate EP0 for Setup transactions\r
1032   * @param  USBx : Selected device\r
1033   * @retval HAL status\r
1034   */\r
1035 HAL_StatusTypeDef  USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)\r
1036 {\r
1037   /* Set the MPS of the IN EP based on the enumeration speed */\r
1038   USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;\r
1039   \r
1040   if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)\r
1041   {\r
1042     USBx_INEP(0)->DIEPCTL |= 3;\r
1043   }\r
1044   USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;\r
1045 \r
1046   return HAL_OK;\r
1047 }\r
1048 \r
1049 \r
1050 /**\r
1051   * @brief  Prepare the EP0 to start the first control setup\r
1052   * @param  USBx : Selected device\r
1053   * @param  dma: USB dma enabled or disabled \r
1054   *          This parameter can be one of the these values:\r
1055   *           0 : DMA feature not used \r
1056   *           1 : DMA feature used  \r
1057   * @param  psetup : pointer to setup packet\r
1058   * @retval HAL status\r
1059   */\r
1060 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup)\r
1061 {\r
1062   USBx_OUTEP(0)->DOEPTSIZ = 0;\r
1063   USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ;\r
1064   USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8);\r
1065   USBx_OUTEP(0)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;  \r
1066   \r
1067   if (dma == 1)\r
1068   {\r
1069     USBx_OUTEP(0)->DOEPDMA = (uint32_t)psetup;\r
1070     /* EP enable */\r
1071     USBx_OUTEP(0)->DOEPCTL = 0x80008000;\r
1072   }\r
1073   \r
1074   return HAL_OK;  \r
1075 }\r
1076 \r
1077 \r
1078 /**\r
1079   * @brief  Reset the USB Core (needed after USB clock settings change)\r
1080   * @param  USBx : Selected device\r
1081   * @retval HAL status\r
1082   */\r
1083 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)\r
1084 {\r
1085   uint32_t count = 0;\r
1086 \r
1087   /* Wait for AHB master IDLE state. */\r
1088   do\r
1089   {\r
1090     if (++count > 200000)\r
1091     {\r
1092       return HAL_TIMEOUT;\r
1093     }\r
1094   }\r
1095   while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);\r
1096   \r
1097   /* Core Soft Reset */\r
1098   count = 0;\r
1099   USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;\r
1100 \r
1101   do\r
1102   {\r
1103     if (++count > 200000)\r
1104     {\r
1105       return HAL_TIMEOUT;\r
1106     }\r
1107   }\r
1108   while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);\r
1109   \r
1110   return HAL_OK;\r
1111 }\r
1112 \r
1113 \r
1114 /**\r
1115   * @brief  USB_HostInit : Initializes the USB OTG controller registers \r
1116   *         for Host mode \r
1117   * @param  USBx : Selected device\r
1118   * @param  cfg  : pointer to a USB_OTG_CfgTypeDef structure that contains\r
1119   *         the configuration information for the specified USBx peripheral.\r
1120   * @retval HAL status\r
1121   */\r
1122 HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)\r
1123 {\r
1124   uint32_t i;\r
1125   \r
1126   /* Restart the Phy Clock */\r
1127   USBx_PCGCCTL = 0;\r
1128   \r
1129   /*Activate VBUS Sensing B */\r
1130   USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;\r
1131   \r
1132   /* Disable the FS/LS support mode only */\r
1133   if((cfg.speed == USB_OTG_SPEED_FULL)&&\r
1134      (USBx != USB_OTG_FS))\r
1135   {\r
1136     USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS; \r
1137   }\r
1138   else\r
1139   {\r
1140     USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);  \r
1141   }\r
1142 \r
1143   /* Make sure the FIFOs are flushed. */\r
1144   USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */\r
1145   USB_FlushRxFifo(USBx);\r
1146 \r
1147   /* Clear all pending HC Interrupts */\r
1148   for (i = 0; i < cfg.Host_channels; i++)\r
1149   {\r
1150     USBx_HC(i)->HCINT = 0xFFFFFFFF;\r
1151     USBx_HC(i)->HCINTMSK = 0;\r
1152   }\r
1153   \r
1154   /* Enable VBUS driving */\r
1155   USB_DriveVbus(USBx, 1);\r
1156   \r
1157   HAL_Delay(200);\r
1158   \r
1159   /* Disable all interrupts. */\r
1160   USBx->GINTMSK = 0;\r
1161   \r
1162   /* Clear any pending interrupts */\r
1163   USBx->GINTSTS = 0xFFFFFFFF;\r
1164 \r
1165   \r
1166   if(USBx == USB_OTG_FS)\r
1167   {\r
1168     /* set Rx FIFO size */\r
1169     USBx->GRXFSIZ  = (uint32_t )0x80; \r
1170     USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80);\r
1171     USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);\r
1172 \r
1173   }\r
1174 \r
1175   else\r
1176   {\r
1177     /* set Rx FIFO size */\r
1178     USBx->GRXFSIZ  = (uint32_t )0x200; \r
1179     USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x100 << 16)& USB_OTG_NPTXFD) | 0x200);\r
1180     USBx->HPTXFSIZ = (uint32_t )(((0xE0 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300);\r
1181   }\r
1182   \r
1183   /* Enable the common interrupts */\r
1184   if (cfg.dma_enable == DISABLE)\r
1185   {\r
1186     USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; \r
1187   }\r
1188   \r
1189   /* Enable interrupts matching to the Host mode ONLY */\r
1190   USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM |\\r
1191                     USB_OTG_GINTMSK_SOFM             |USB_OTG_GINTSTS_DISCINT|\\r
1192                     USB_OTG_GINTMSK_PXFRM_IISOOXFRM  | USB_OTG_GINTMSK_WUIM);\r
1193 \r
1194   return HAL_OK;\r
1195 }\r
1196 \r
1197 /**\r
1198   * @brief  USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the \r
1199   *         HCFG register on the PHY type and set the right frame interval\r
1200   * @param  USBx : Selected device\r
1201   * @param  freq : clock frequency\r
1202   *          This parameter can be one of the these values:\r
1203   *           HCFG_48_MHZ : Full Speed 48 MHz Clock \r
1204   *           HCFG_6_MHZ : Low Speed 6 MHz Clock \r
1205   * @retval HAL status\r
1206   */\r
1207 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)\r
1208 {\r
1209   USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);\r
1210   USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);\r
1211   \r
1212   if (freq ==  HCFG_48_MHZ)\r
1213   {\r
1214     USBx_HOST->HFIR = (uint32_t)48000;\r
1215   }\r
1216   else if (freq ==  HCFG_6_MHZ)\r
1217   {\r
1218     USBx_HOST->HFIR = (uint32_t)6000;\r
1219   } \r
1220   return HAL_OK;  \r
1221 }\r
1222 \r
1223 /**\r
1224 * @brief  USB_OTG_ResetPort : Reset Host Port\r
1225   * @param  USBx : Selected device\r
1226   * @retval HAL status\r
1227   * @note : (1)The application must wait at least 10 ms\r
1228   *   before clearing the reset bit.\r
1229   */\r
1230 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)\r
1231 {\r
1232   __IO uint32_t hprt0;\r
1233   \r
1234   hprt0 = USBx_HPRT0;\r
1235   \r
1236   hprt0 &= ~(USB_OTG_HPRT_PENA    | USB_OTG_HPRT_PCDET |\\r
1237     USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );\r
1238   \r
1239   USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);  \r
1240   HAL_Delay (10);                                /* See Note #1 */\r
1241   USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0); \r
1242   return HAL_OK;\r
1243 }\r
1244 \r
1245 /**\r
1246   * @brief  USB_DriveVbus : activate or de-activate vbus\r
1247   * @param  state : VBUS state\r
1248   *          This parameter can be one of the these values:\r
1249   *           0 : VBUS Active \r
1250   *           1 : VBUS Inactive\r
1251   * @retval HAL status\r
1252 */\r
1253 HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)\r
1254 {\r
1255   __IO uint32_t hprt0;\r
1256 \r
1257   hprt0 = USBx_HPRT0;\r
1258   hprt0 &= ~(USB_OTG_HPRT_PENA    | USB_OTG_HPRT_PCDET |\\r
1259                          USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );\r
1260   \r
1261   if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 ))\r
1262   {\r
1263     USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0); \r
1264   }\r
1265   if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 ))\r
1266   {\r
1267     USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0); \r
1268   }\r
1269   return HAL_OK; \r
1270 }\r
1271 \r
1272 /**\r
1273   * @brief  Return Host Core speed\r
1274   * @param  USBx : Selected device\r
1275   * @retval speed : Host speed\r
1276   *          This parameter can be one of the these values:\r
1277   *            @arg USB_OTG_SPEED_HIGH: High speed mode\r
1278   *            @arg USB_OTG_SPEED_FULL: Full speed mode\r
1279   *            @arg USB_OTG_SPEED_LOW: Low speed mode\r
1280   */\r
1281 uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)\r
1282 {\r
1283   __IO uint32_t hprt0;\r
1284   \r
1285   hprt0 = USBx_HPRT0;\r
1286   return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);\r
1287 }\r
1288 \r
1289 /**\r
1290   * @brief  Return Host Current Frame number\r
1291   * @param  USBx : Selected device\r
1292   * @retval current frame number\r
1293 */\r
1294 uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)\r
1295 {\r
1296   return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);\r
1297 }\r
1298 \r
1299 /**\r
1300   * @brief  Initialize a host channel\r
1301   * @param  USBx : Selected device\r
1302   * @param  ch_num : Channel number\r
1303   *         This parameter can be a value from 1 to 15\r
1304   * @param  epnum : Endpoint number\r
1305   *          This parameter can be a value from 1 to 15\r
1306   * @param  dev_address : Current device address\r
1307   *          This parameter can be a value from 0 to 255\r
1308   * @param  speed : Current device speed\r
1309   *          This parameter can be one of the these values:\r
1310   *            @arg USB_OTG_SPEED_HIGH: High speed mode\r
1311   *            @arg USB_OTG_SPEED_FULL: Full speed mode\r
1312   *            @arg USB_OTG_SPEED_LOW: Low speed mode\r
1313   * @param  ep_type : Endpoint Type\r
1314   *          This parameter can be one of the these values:\r
1315   *            @arg EP_TYPE_CTRL: Control type\r
1316   *            @arg EP_TYPE_ISOC: Isochronous type\r
1317   *            @arg EP_TYPE_BULK: Bulk type\r
1318   *            @arg EP_TYPE_INTR: Interrupt type\r
1319   * @param  mps : Max Packet Size\r
1320   *          This parameter can be a value from 0 to32K\r
1321   * @retval HAL state\r
1322   */\r
1323 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,  \r
1324                               uint8_t ch_num,\r
1325                               uint8_t epnum,\r
1326                               uint8_t dev_address,\r
1327                               uint8_t speed,\r
1328                               uint8_t ep_type,\r
1329                               uint16_t mps)\r
1330 {\r
1331     \r
1332   /* Clear old interrupt conditions for this host channel. */\r
1333   USBx_HC(ch_num)->HCINT = 0xFFFFFFFF;\r
1334   \r
1335   /* Enable channel interrupts required for this transfer. */\r
1336   switch (ep_type) \r
1337   {\r
1338   case EP_TYPE_CTRL:\r
1339   case EP_TYPE_BULK:\r
1340     \r
1341     USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |\\r
1342                                 USB_OTG_HCINTMSK_STALLM |\\r
1343                                 USB_OTG_HCINTMSK_TXERRM |\\r
1344                                 USB_OTG_HCINTMSK_DTERRM |\\r
1345                                 USB_OTG_HCINTMSK_AHBERR |\\r
1346                                 USB_OTG_HCINTMSK_NAKM ;\r
1347  \r
1348     if (epnum & 0x80) \r
1349     {\r
1350       USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;\r
1351     } \r
1352     else \r
1353     {\r
1354       if(USBx != USB_OTG_FS)\r
1355       {\r
1356         USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);\r
1357       }\r
1358     }\r
1359     break;\r
1360   case EP_TYPE_INTR:\r
1361     \r
1362     USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |\\r
1363                                 USB_OTG_HCINTMSK_STALLM |\\r
1364                                 USB_OTG_HCINTMSK_TXERRM |\\r
1365                                 USB_OTG_HCINTMSK_DTERRM |\\r
1366                                 USB_OTG_HCINTMSK_NAKM   |\\r
1367                                 USB_OTG_HCINTMSK_AHBERR |\\r
1368                                 USB_OTG_HCINTMSK_FRMORM ;    \r
1369     \r
1370     if (epnum & 0x80) \r
1371     {\r
1372       USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;\r
1373     }\r
1374     \r
1375     break;\r
1376   case EP_TYPE_ISOC:\r
1377     \r
1378     USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |\\r
1379                                 USB_OTG_HCINTMSK_ACKM   |\\r
1380                                 USB_OTG_HCINTMSK_AHBERR |\\r
1381                                 USB_OTG_HCINTMSK_FRMORM ;   \r
1382     \r
1383     if (epnum & 0x80) \r
1384     {\r
1385       USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);      \r
1386     }\r
1387     break;\r
1388   }\r
1389   \r
1390   /* Enable the top level host channel interrupt. */\r
1391   USBx_HOST->HAINTMSK |= (1 << ch_num);\r
1392   \r
1393   /* Make sure host channel interrupts are enabled. */\r
1394   USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;\r
1395   \r
1396   /* Program the HCCHAR register */\r
1397   USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD)  |\\r
1398                              (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\\r
1399                              ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\\r
1400                              (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\\r
1401                              ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\\r
1402                              (mps & USB_OTG_HCCHAR_MPSIZ));\r
1403     \r
1404   if (ep_type == EP_TYPE_INTR)\r
1405   {\r
1406     USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;\r
1407   }\r
1408 \r
1409   return HAL_OK; \r
1410 }\r
1411 \r
1412 /**\r
1413   * @brief  Start a transfer over a host channel\r
1414   * @param  USBx : Selected device\r
1415   * @param  hc : pointer to host channel structure\r
1416   * @param  dma: USB dma enabled or disabled \r
1417   *          This parameter can be one of the these values:\r
1418   *           0 : DMA feature not used \r
1419   *           1 : DMA feature used  \r
1420   * @retval HAL state\r
1421   */\r
1422 #if defined   (__CC_ARM) /*!< ARM Compiler */\r
1423 #pragma O0\r
1424 #elif defined (__GNUC__) /*!< GNU Compiler */\r
1425 #pragma GCC optimize ("O0")\r
1426 #endif /* __CC_ARM */\r
1427 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)\r
1428 {\r
1429   uint8_t  is_oddframe = 0; \r
1430   uint16_t len_words = 0;   \r
1431   uint16_t num_packets = 0;\r
1432   uint16_t max_hc_pkt_count = 256;\r
1433   \r
1434   if((USBx != USB_OTG_FS) && (hc->speed == USB_OTG_SPEED_HIGH))\r
1435   {\r
1436     if((dma == 0) && (hc->do_ping == 1))\r
1437     {\r
1438       USB_DoPing(USBx, hc->ch_num);\r
1439       return HAL_OK;\r
1440     }\r
1441     else if(dma == 1)\r
1442     {\r
1443       USBx_HC(hc->ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);\r
1444       hc->do_ping = 0;\r
1445     }\r
1446   }\r
1447   \r
1448   /* Compute the expected number of packets associated to the transfer */\r
1449   if (hc->xfer_len > 0)\r
1450   {\r
1451     num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;\r
1452     \r
1453     if (num_packets > max_hc_pkt_count)\r
1454     {\r
1455       num_packets = max_hc_pkt_count;\r
1456       hc->xfer_len = num_packets * hc->max_packet;\r
1457     }\r
1458   }\r
1459   else\r
1460   {\r
1461     num_packets = 1;\r
1462   }\r
1463   if (hc->ep_is_in)\r
1464   {\r
1465     hc->xfer_len = num_packets * hc->max_packet;\r
1466   }\r
1467   \r
1468   \r
1469   \r
1470   /* Initialize the HCTSIZn register */\r
1471   USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\\r
1472     ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\\r
1473       (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID);\r
1474   \r
1475   if (dma)\r
1476   {\r
1477     /* xfer_buff MUST be 32-bits aligned */\r
1478     USBx_HC(hc->ch_num)->HCDMA = (uint32_t)hc->xfer_buff;\r
1479   }\r
1480   \r
1481   is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;\r
1482   USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;\r
1483   USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);\r
1484   \r
1485   /* Set host channel enable */\r
1486   USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS;\r
1487   USBx_HC(hc->ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;\r
1488   \r
1489   if (dma == 0) /* Slave mode */\r
1490   {  \r
1491     if((hc->ep_is_in == 0) && (hc->xfer_len > 0))\r
1492     {\r
1493       switch(hc->ep_type) \r
1494       {\r
1495         /* Non periodic transfer */\r
1496       case EP_TYPE_CTRL:\r
1497       case EP_TYPE_BULK:\r
1498         \r
1499         len_words = (hc->xfer_len + 3) / 4;\r
1500         \r
1501         /* check if there is enough space in FIFO space */\r
1502         if(len_words > (USBx->HNPTXSTS & 0xFFFF))\r
1503         {\r
1504           /* need to process data in nptxfempty interrupt */\r
1505           USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;\r
1506         }\r
1507         break;\r
1508         /* Periodic transfer */\r
1509       case EP_TYPE_INTR:\r
1510       case EP_TYPE_ISOC:\r
1511         len_words = (hc->xfer_len + 3) / 4;\r
1512         /* check if there is enough space in FIFO space */\r
1513         if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */\r
1514         {\r
1515           /* need to process data in ptxfempty interrupt */\r
1516           USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;          \r
1517         }\r
1518         break;\r
1519         \r
1520       default:\r
1521         break;\r
1522       }\r
1523       \r
1524       /* Write packet into the Tx FIFO. */\r
1525       USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0);\r
1526     }\r
1527   }\r
1528   \r
1529   return HAL_OK;\r
1530 }\r
1531 \r
1532 /**\r
1533   * @brief Read all host channel interrupts status\r
1534   * @param  USBx : Selected device\r
1535   * @retval HAL state\r
1536   */\r
1537 uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)\r
1538 {\r
1539   return ((USBx_HOST->HAINT) & 0xFFFF);\r
1540 }\r
1541 \r
1542 /**\r
1543   * @brief  Halt a host channel\r
1544   * @param  USBx : Selected device\r
1545   * @param  hc_num : Host Channel number\r
1546   *         This parameter can be a value from 1 to 15\r
1547   * @retval HAL state\r
1548   */\r
1549 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)\r
1550 {\r
1551   uint32_t count = 0;\r
1552   \r
1553   /* Check for space in the request queue to issue the halt. */\r
1554   if (((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_CTRL << 18)) || ((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_BULK << 18)))\r
1555   {\r
1556     USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;\r
1557     \r
1558     if ((USBx->HNPTXSTS & 0xFFFF) == 0)\r
1559     {\r
1560       USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;\r
1561       USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;  \r
1562       USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;\r
1563       do \r
1564       {\r
1565         if (++count > 1000) \r
1566         {\r
1567           break;\r
1568         }\r
1569       } \r
1570       while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);     \r
1571     }\r
1572     else\r
1573     {\r
1574       USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; \r
1575     }\r
1576   }\r
1577   else\r
1578   {\r
1579     USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;\r
1580     \r
1581     if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0)\r
1582     {\r
1583       USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;\r
1584       USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;  \r
1585       USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;\r
1586       do \r
1587       {\r
1588         if (++count > 1000) \r
1589         {\r
1590           break;\r
1591         }\r
1592       } \r
1593       while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);     \r
1594     }\r
1595     else\r
1596     {\r
1597        USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; \r
1598     }\r
1599   }\r
1600   \r
1601   return HAL_OK;\r
1602 }\r
1603 \r
1604 /**\r
1605   * @brief  Initiate Do Ping protocol\r
1606   * @param  USBx : Selected device\r
1607   * @param  hc_num : Host Channel number\r
1608   *         This parameter can be a value from 1 to 15\r
1609   * @retval HAL state\r
1610   */\r
1611 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)\r
1612 {\r
1613   uint8_t  num_packets = 1;\r
1614 \r
1615   USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\\r
1616                                 USB_OTG_HCTSIZ_DOPING;\r
1617   \r
1618   /* Set host channel enable */\r
1619   USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS;\r
1620   USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;\r
1621   \r
1622   return HAL_OK;  \r
1623 }\r
1624 \r
1625 /**\r
1626   * @brief  Stop Host Core\r
1627   * @param  USBx : Selected device\r
1628   * @retval HAL state\r
1629   */\r
1630 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)\r
1631 {\r
1632   uint8_t i;\r
1633   uint32_t count = 0;\r
1634   uint32_t value;\r
1635   \r
1636   USB_DisableGlobalInt(USBx);\r
1637   \r
1638     /* Flush FIFO */\r
1639   USB_FlushTxFifo(USBx, 0x10);\r
1640   USB_FlushRxFifo(USBx);\r
1641   \r
1642   /* Flush out any leftover queued requests. */\r
1643   for (i = 0; i <= 15; i++)\r
1644   {   \r
1645 \r
1646     value = USBx_HC(i)->HCCHAR ;\r
1647     value |=  USB_OTG_HCCHAR_CHDIS;\r
1648     value &= ~USB_OTG_HCCHAR_CHENA;  \r
1649     value &= ~USB_OTG_HCCHAR_EPDIR;\r
1650     USBx_HC(i)->HCCHAR = value;\r
1651   }\r
1652   \r
1653   /* Halt all channels to put them into a known state. */  \r
1654   for (i = 0; i <= 15; i++)\r
1655   {   \r
1656 \r
1657     value = USBx_HC(i)->HCCHAR ;\r
1658     \r
1659     value |= USB_OTG_HCCHAR_CHDIS;\r
1660     value |= USB_OTG_HCCHAR_CHENA;  \r
1661     value &= ~USB_OTG_HCCHAR_EPDIR;\r
1662     \r
1663     USBx_HC(i)->HCCHAR = value;\r
1664     do \r
1665     {\r
1666       if (++count > 1000) \r
1667       {\r
1668         break;\r
1669       }\r
1670     } \r
1671     while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);\r
1672   }\r
1673 \r
1674   /* Clear any pending Host interrupts */\r
1675   USBx_HOST->HAINT = 0xFFFFFFFF;\r
1676   USBx->GINTSTS = 0xFFFFFFFF;\r
1677   USB_EnableGlobalInt(USBx);\r
1678   return HAL_OK;  \r
1679 }\r
1680 /**\r
1681   * @}\r
1682   */\r
1683 \r
1684 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */\r
1685 \r
1686 /**\r
1687   * @}\r
1688   */\r
1689 \r
1690 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r