]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil/ST_Library/stm32f7xx_hal_pcd.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil / ST_Library / stm32f7xx_hal_pcd.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f7xx_hal_pcd.c\r
4   * @author  MCD Application Team\r
5   * @version V1.0.0RC1\r
6   * @date    24-March-2015\r
7   * @brief   PCD HAL module driver.\r
8   *          This file provides firmware functions to manage the following \r
9   *          functionalities of the USB Peripheral Controller:\r
10   *           + Initialization and de-initialization functions\r
11   *           + IO operation functions\r
12   *           + Peripheral Control functions \r
13   *           + Peripheral State functions\r
14   *         \r
15   @verbatim\r
16   ==============================================================================\r
17                     ##### How to use this driver #####\r
18   ==============================================================================\r
19     [..]\r
20       The PCD HAL driver can be used as follows:\r
21 \r
22      (#) Declare a PCD_HandleTypeDef handle structure, for example:\r
23          PCD_HandleTypeDef  hpcd;\r
24         \r
25      (#) Fill parameters of Init structure in HCD handle\r
26   \r
27      (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...) \r
28 \r
29      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:\r
30          (##) Enable the PCD/USB Low Level interface clock using \r
31               (+++) __OTGFS-OTG_CLK_ENABLE()/__OTGHS-OTG_CLK_ENABLE();\r
32               (+++) __OTGHSULPI_CLK_ENABLE(); (For High Speed Mode)\r
33            \r
34          (##) Initialize the related GPIO clocks\r
35          (##) Configure PCD pin-out\r
36          (##) Configure PCD NVIC interrupt\r
37     \r
38      (#)Associate the Upper USB device stack to the HAL PCD Driver:\r
39          (##) hpcd.pData = pdev;\r
40 \r
41      (#)Enable HCD transmission and reception:\r
42          (##) HAL_PCD_Start();\r
43 \r
44   @endverbatim\r
45   ******************************************************************************\r
46   * @attention\r
47   *\r
48   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>\r
49   *\r
50   * Redistribution and use in source and binary forms, with or without modification,\r
51   * are permitted provided that the following conditions are met:\r
52   *   1. Redistributions of source code must retain the above copyright notice,\r
53   *      this list of conditions and the following disclaimer.\r
54   *   2. Redistributions in binary form must reproduce the above copyright notice,\r
55   *      this list of conditions and the following disclaimer in the documentation\r
56   *      and/or other materials provided with the distribution.\r
57   *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
58   *      may be used to endorse or promote products derived from this software\r
59   *      without specific prior written permission.\r
60   *\r
61   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
62   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
63   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
64   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
65   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
66   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
67   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
68   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
69   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
70   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
71   *\r
72   ******************************************************************************\r
73   */ \r
74 \r
75 /* Includes ------------------------------------------------------------------*/\r
76 #include "stm32f7xx_hal.h"\r
77 \r
78 /** @addtogroup STM32F7xx_HAL_Driver\r
79   * @{\r
80   */\r
81 \r
82 /** @defgroup PCD PCD\r
83   * @brief PCD HAL module driver\r
84   * @{\r
85   */\r
86 \r
87 #ifdef HAL_PCD_MODULE_ENABLED\r
88 \r
89 /* Private types -------------------------------------------------------------*/\r
90 /* Private variables ---------------------------------------------------------*/\r
91 /* Private constants ---------------------------------------------------------*/\r
92 /* Private macros ------------------------------------------------------------*/\r
93 /** @defgroup PCD_Private_Macros PCD Private Macros\r
94   * @{\r
95   */ \r
96 #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))\r
97 #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))\r
98 /**\r
99   * @}\r
100   */\r
101 \r
102 /* Private functions prototypes ----------------------------------------------*/\r
103 /** @defgroup PCD_Private_Functions PCD Private Functions\r
104   * @{\r
105   */\r
106 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);\r
107 /**\r
108   * @}\r
109   */\r
110 \r
111 /* Exported functions --------------------------------------------------------*/\r
112 /** @defgroup PCD_Exported_Functions PCD Exported Functions\r
113   * @{\r
114   */\r
115 \r
116 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions \r
117  *  @brief    Initialization and Configuration functions \r
118  *\r
119 @verbatim    \r
120  ===============================================================================\r
121             ##### Initialization and de-initialization functions #####\r
122  ===============================================================================\r
123     [..]  This section provides functions allowing to:\r
124  \r
125 @endverbatim\r
126   * @{\r
127   */\r
128 \r
129 /**\r
130   * @brief  Initializes the PCD according to the specified\r
131   *         parameters in the PCD_InitTypeDef and create the associated handle.\r
132   * @param  hpcd: PCD handle\r
133   * @retval HAL status\r
134   */\r
135 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)\r
136\r
137   uint32_t i = 0;\r
138   \r
139   /* Check the PCD handle allocation */\r
140   if(hpcd == NULL)\r
141   {\r
142     return HAL_ERROR;\r
143   }\r
144   \r
145   /* Check the parameters */\r
146   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));\r
147 \r
148   hpcd->State = HAL_PCD_STATE_BUSY;\r
149   \r
150   /* Init the low level hardware : GPIO, CLOCK, NVIC... */\r
151   HAL_PCD_MspInit(hpcd);\r
152 \r
153   /* Disable the Interrupts */\r
154  __HAL_PCD_DISABLE(hpcd);\r
155  \r
156  /*Init the Core (common init.) */\r
157  USB_CoreInit(hpcd->Instance, hpcd->Init);\r
158  \r
159  /* Force Device Mode*/\r
160  USB_SetCurrentMode(hpcd->Instance , USB_OTG_DEVICE_MODE);\r
161  \r
162  /* Init endpoints structures */\r
163  for (i = 0; i < 15 ; i++)\r
164  {\r
165    /* Init ep structure */\r
166    hpcd->IN_ep[i].is_in = 1;\r
167    hpcd->IN_ep[i].num = i;\r
168    hpcd->IN_ep[i].tx_fifo_num = i;\r
169    /* Control until ep is activated */\r
170    hpcd->IN_ep[i].type = EP_TYPE_CTRL;\r
171    hpcd->IN_ep[i].maxpacket =  0;\r
172    hpcd->IN_ep[i].xfer_buff = 0;\r
173    hpcd->IN_ep[i].xfer_len = 0;\r
174  }\r
175  \r
176  for (i = 0; i < 15 ; i++)\r
177  {\r
178    hpcd->OUT_ep[i].is_in = 0;\r
179    hpcd->OUT_ep[i].num = i;\r
180    hpcd->IN_ep[i].tx_fifo_num = i;\r
181    /* Control until ep is activated */\r
182    hpcd->OUT_ep[i].type = EP_TYPE_CTRL;\r
183    hpcd->OUT_ep[i].maxpacket = 0;\r
184    hpcd->OUT_ep[i].xfer_buff = 0;\r
185    hpcd->OUT_ep[i].xfer_len = 0;\r
186    \r
187    hpcd->Instance->DIEPTXF[i] = 0;\r
188  }\r
189  \r
190  /* Init Device */\r
191  USB_DevInit(hpcd->Instance, hpcd->Init);\r
192  \r
193  hpcd->State= HAL_PCD_STATE_READY;\r
194  \r
195  /* Activate LPM */\r
196  if (hpcd->Init.lpm_enable == 1)\r
197  {\r
198    HAL_PCDEx_ActivateLPM(hpcd);\r
199  }\r
200  \r
201  USB_DevDisconnect (hpcd->Instance);  \r
202  return HAL_OK;\r
203 }\r
204 \r
205 /**\r
206   * @brief  DeInitializes the PCD peripheral \r
207   * @param  hpcd: PCD handle\r
208   * @retval HAL status\r
209   */\r
210 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)\r
211 {\r
212   /* Check the PCD handle allocation */\r
213   if(hpcd == NULL)\r
214   {\r
215     return HAL_ERROR;\r
216   }\r
217 \r
218   hpcd->State = HAL_PCD_STATE_BUSY;\r
219   \r
220   /* Stop Device */\r
221   HAL_PCD_Stop(hpcd);\r
222     \r
223   /* DeInit the low level hardware */\r
224   HAL_PCD_MspDeInit(hpcd);\r
225   \r
226   hpcd->State = HAL_PCD_STATE_RESET; \r
227   \r
228   return HAL_OK;\r
229 }\r
230 \r
231 /**\r
232   * @brief  Initializes the PCD MSP.\r
233   * @param  hpcd: PCD handle\r
234   * @retval None\r
235   */\r
236 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)\r
237 {\r
238   /* NOTE : This function Should not be modified, when the callback is needed,\r
239             the HAL_PCD_MspInit could be implemented in the user file\r
240    */\r
241 }\r
242 \r
243 /**\r
244   * @brief  DeInitializes PCD MSP.\r
245   * @param  hpcd: PCD handle\r
246   * @retval None\r
247   */\r
248 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)\r
249 {\r
250   /* NOTE : This function Should not be modified, when the callback is needed,\r
251             the HAL_PCD_MspDeInit could be implemented in the user file\r
252    */\r
253 }\r
254 \r
255 /**\r
256   * @}\r
257   */\r
258 \r
259 /** @defgroup PCD_Exported_Functions_Group2 IO operation functions \r
260  *  @brief   Data transfers functions \r
261  *\r
262 @verbatim   \r
263  ===============================================================================\r
264                       ##### IO operation functions #####\r
265  ===============================================================================  \r
266     [..]\r
267     This subsection provides a set of functions allowing to manage the PCD data \r
268     transfers.\r
269 \r
270 @endverbatim\r
271   * @{\r
272   */\r
273   \r
274 /**\r
275   * @brief  Start The USB OTG Device.\r
276   * @param  hpcd: PCD handle\r
277   * @retval HAL status\r
278   */\r
279 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)\r
280\r
281   __HAL_LOCK(hpcd); \r
282   USB_DevConnect (hpcd->Instance);  \r
283   __HAL_PCD_ENABLE(hpcd);\r
284   __HAL_UNLOCK(hpcd); \r
285   return HAL_OK;\r
286 }\r
287 \r
288 /**\r
289   * @brief  Stop The USB OTG Device.\r
290   * @param  hpcd: PCD handle\r
291   * @retval HAL status\r
292   */\r
293 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)\r
294\r
295   __HAL_LOCK(hpcd); \r
296   __HAL_PCD_DISABLE(hpcd);\r
297   USB_StopDevice(hpcd->Instance);\r
298   USB_DevDisconnect (hpcd->Instance);\r
299   __HAL_UNLOCK(hpcd); \r
300   return HAL_OK;\r
301 }\r
302 \r
303 /**\r
304   * @brief  This function handles PCD interrupt request.\r
305   * @param  hpcd: PCD handle\r
306   * @retval HAL status\r
307   */\r
308 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)\r
309 {\r
310   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;\r
311   uint32_t i = 0, ep_intr = 0, epint = 0, epnum = 0;\r
312   uint32_t fifoemptymsk = 0, temp = 0;\r
313   USB_OTG_EPTypeDef *ep;\r
314     \r
315   /* ensure that we are in device mode */\r
316   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)\r
317   {\r
318     /* avoid spurious interrupt */\r
319     if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) \r
320     {\r
321       return;\r
322     }\r
323     \r
324     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))\r
325     {\r
326      /* incorrect mode, acknowledge the interrupt */\r
327       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);\r
328     }\r
329     \r
330     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))\r
331     {\r
332       epnum = 0;\r
333       \r
334       /* Read in the device interrupt bits */\r
335       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);\r
336       \r
337       while ( ep_intr )\r
338       {\r
339         if (ep_intr & 0x1)\r
340         {\r
341           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);\r
342           \r
343           if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)\r
344           {\r
345             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);\r
346             \r
347             if(hpcd->Init.dma_enable == 1)\r
348             {\r
349               hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); \r
350               hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;            \r
351             }\r
352             \r
353             HAL_PCD_DataOutStageCallback(hpcd, epnum);\r
354             if(hpcd->Init.dma_enable == 1)\r
355             {\r
356               if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0))\r
357               {\r
358                  /* this is ZLP, so prepare EP0 for next setup */\r
359                 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);\r
360               }              \r
361             }\r
362           }\r
363           \r
364           if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)\r
365           {\r
366             /* Inform the upper layer that a setup packet is available */\r
367             HAL_PCD_SetupStageCallback(hpcd);\r
368             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);\r
369           }\r
370           \r
371           if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)\r
372           {\r
373             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);\r
374           }\r
375         }\r
376         epnum++;\r
377         ep_intr >>= 1;\r
378       }\r
379     }\r
380     \r
381     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))\r
382     {\r
383       /* Read in the device interrupt bits */\r
384       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);\r
385       \r
386       epnum = 0;\r
387       \r
388       while ( ep_intr )\r
389       {\r
390         if (ep_intr & 0x1) /* In ITR */\r
391         {\r
392           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);\r
393 \r
394            if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)\r
395           {\r
396             fifoemptymsk = 0x1 << epnum;\r
397             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;\r
398             \r
399             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);\r
400             \r
401             if (hpcd->Init.dma_enable == 1)\r
402             {\r
403               hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; \r
404             }\r
405                                       \r
406             HAL_PCD_DataInStageCallback(hpcd, epnum);\r
407 \r
408             if (hpcd->Init.dma_enable == 1)\r
409             {\r
410               /* this is ZLP, so prepare EP0 for next setup */\r
411               if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0))\r
412               {\r
413                 /* prepare to rx more setup packets */\r
414                 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);\r
415               }\r
416             }           \r
417           }\r
418            if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)\r
419           {\r
420             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);\r
421           }\r
422           if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)\r
423           {\r
424             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);\r
425           }\r
426           if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)\r
427           {\r
428             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);\r
429           }\r
430           if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)\r
431           {\r
432             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);\r
433           }       \r
434           if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)\r
435           {\r
436             PCD_WriteEmptyTxFifo(hpcd , epnum);\r
437           }\r
438         }\r
439         epnum++;\r
440         ep_intr >>= 1;\r
441       }\r
442     }\r
443     \r
444     /* Handle Resume Interrupt */\r
445     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))\r
446     {\r
447       /* Clear the Remote Wake-up Signaling */\r
448       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;\r
449       \r
450       if(hpcd->LPM_State == LPM_L1)\r
451       {\r
452         hpcd->LPM_State = LPM_L0;\r
453         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);\r
454       }\r
455       else\r
456       {\r
457         HAL_PCD_ResumeCallback(hpcd);\r
458       }\r
459       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);\r
460     }\r
461     \r
462     /* Handle Suspend Interrupt */\r
463     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))\r
464     {\r
465 \r
466       if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)\r
467       {\r
468         \r
469         HAL_PCD_SuspendCallback(hpcd);\r
470       }\r
471       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);\r
472     }\r
473     \r
474     /* Handle LPM Interrupt */ \r
475     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))\r
476     {\r
477       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);      \r
478       if( hpcd->LPM_State == LPM_L0)\r
479       {\r
480         hpcd->LPM_State = LPM_L1;\r
481         hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ;\r
482         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);\r
483       }\r
484       else\r
485       {\r
486         HAL_PCD_SuspendCallback(hpcd);\r
487       }\r
488     }\r
489     \r
490     /* Handle Reset Interrupt */\r
491     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))\r
492     {\r
493       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; \r
494       USB_FlushTxFifo(hpcd->Instance ,  0 );\r
495       \r
496       for (i = 0; i < hpcd->Init.dev_endpoints ; i++)\r
497       {\r
498         USBx_INEP(i)->DIEPINT = 0xFF;\r
499         USBx_OUTEP(i)->DOEPINT = 0xFF;\r
500       }\r
501       USBx_DEVICE->DAINT = 0xFFFFFFFF;\r
502       USBx_DEVICE->DAINTMSK |= 0x10001;\r
503       \r
504       if(hpcd->Init.use_dedicated_ep1)\r
505       {\r
506         USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); \r
507         USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);  \r
508       }\r
509       else\r
510       {\r
511         USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);\r
512         USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);\r
513       }\r
514       \r
515       /* Set Default Address to 0 */\r
516       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;\r
517       \r
518       /* setup EP0 to receive SETUP packets */\r
519       USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);\r
520         \r
521       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);\r
522     }\r
523     \r
524     /* Handle Enumeration done Interrupt */\r
525     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))\r
526     {\r
527       USB_ActivateSetup(hpcd->Instance);\r
528       hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;\r
529       \r
530       if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH)\r
531       {\r
532         hpcd->Init.speed            = USB_OTG_SPEED_HIGH;\r
533         hpcd->Init.ep0_mps          = USB_OTG_HS_MAX_PACKET_SIZE ;    \r
534         hpcd->Instance->GUSBCFG |= (USB_OTG_GUSBCFG_TRDT_0 | USB_OTG_GUSBCFG_TRDT_3);\r
535       }\r
536       else\r
537       {\r
538         hpcd->Init.speed            = USB_OTG_SPEED_FULL;\r
539         hpcd->Init.ep0_mps          = USB_OTG_FS_MAX_PACKET_SIZE ;  \r
540         hpcd->Instance->GUSBCFG |= (USB_OTG_GUSBCFG_TRDT_0 | USB_OTG_GUSBCFG_TRDT_2);\r
541       }\r
542       \r
543       HAL_PCD_ResetCallback(hpcd);\r
544       \r
545       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);\r
546     }\r
547     \r
548     /* Handle RxQLevel Interrupt */\r
549     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))\r
550     {\r
551       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);\r
552       temp = USBx->GRXSTSP;\r
553       ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];\r
554       \r
555       if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)\r
556       {\r
557         if((temp & USB_OTG_GRXSTSP_BCNT) != 0)\r
558         {\r
559           USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4);\r
560           ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;\r
561           ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;\r
562         }\r
563       }\r
564       else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_SETUP_UPDT)\r
565       {\r
566         USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8);\r
567         ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;\r
568       }\r
569       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);\r
570     }\r
571     \r
572     /* Handle SOF Interrupt */\r
573     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))\r
574     {\r
575       HAL_PCD_SOFCallback(hpcd);\r
576       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);\r
577     }\r
578     \r
579     /* Handle Incomplete ISO IN Interrupt */\r
580     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))\r
581     {\r
582       HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);\r
583       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);\r
584     } \r
585     \r
586     /* Handle Incomplete ISO OUT Interrupt */\r
587     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))\r
588     {\r
589       HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);\r
590       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);\r
591     } \r
592     \r
593     /* Handle Connection event Interrupt */\r
594     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))\r
595     {\r
596       HAL_PCD_ConnectCallback(hpcd);\r
597       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);\r
598     } \r
599     \r
600     /* Handle Disconnection event Interrupt */\r
601     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))\r
602     {\r
603       temp = hpcd->Instance->GOTGINT;\r
604       \r
605       if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)\r
606       {\r
607         HAL_PCD_DisconnectCallback(hpcd);\r
608       }\r
609       hpcd->Instance->GOTGINT |= temp;\r
610     }\r
611   }\r
612 }\r
613 \r
614 /**\r
615   * @brief  Data out stage callbacks\r
616   * @param  hpcd: PCD handle\r
617   * @param  epnum: endpoint number  \r
618   * @retval None\r
619   */\r
620  __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)\r
621 {\r
622   /* NOTE : This function Should not be modified, when the callback is needed,\r
623             the HAL_PCD_DataOutStageCallback could be implemented in the user file\r
624    */ \r
625 }\r
626 \r
627 /**\r
628   * @brief  Data IN stage callbacks\r
629   * @param  hpcd: PCD handle\r
630   * @param  epnum: endpoint number  \r
631   * @retval None\r
632   */\r
633  __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)\r
634 {\r
635   /* NOTE : This function Should not be modified, when the callback is needed,\r
636             the HAL_PCD_DataInStageCallback could be implemented in the user file\r
637    */ \r
638 }\r
639 /**\r
640   * @brief  Setup stage callback\r
641   * @param  hpcd: PCD handle\r
642   * @retval None\r
643   */\r
644  __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)\r
645 {\r
646   /* NOTE : This function Should not be modified, when the callback is needed,\r
647             the HAL_PCD_SetupStageCallback could be implemented in the user file\r
648    */ \r
649 }\r
650 \r
651 /**\r
652   * @brief  USB Start Of Frame callbacks\r
653   * @param  hpcd: PCD handle\r
654   * @retval None\r
655   */\r
656  __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)\r
657 {\r
658   /* NOTE : This function Should not be modified, when the callback is needed,\r
659             the HAL_PCD_SOFCallback could be implemented in the user file\r
660    */ \r
661 }\r
662 \r
663 /**\r
664   * @brief  USB Reset callbacks\r
665   * @param  hpcd: PCD handle\r
666   * @retval None\r
667   */\r
668  __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)\r
669 {\r
670   /* NOTE : This function Should not be modified, when the callback is needed,\r
671             the HAL_PCD_ResetCallback could be implemented in the user file\r
672    */ \r
673 }\r
674 \r
675 \r
676 /**\r
677   * @brief  Suspend event callbacks\r
678   * @param  hpcd: PCD handle\r
679   * @retval None\r
680   */\r
681  __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)\r
682 {\r
683   /* NOTE : This function Should not be modified, when the callback is needed,\r
684             the HAL_PCD_SuspendCallback could be implemented in the user file\r
685    */ \r
686 }\r
687 \r
688 /**\r
689   * @brief  Resume event callbacks\r
690   * @param  hpcd: PCD handle\r
691   * @retval None\r
692   */\r
693  __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)\r
694 {\r
695   /* NOTE : This function Should not be modified, when the callback is needed,\r
696             the HAL_PCD_ResumeCallback could be implemented in the user file\r
697    */ \r
698 }\r
699 \r
700 /**\r
701   * @brief  Incomplete ISO OUT callbacks\r
702   * @param  hpcd: PCD handle\r
703   * @param  epnum: endpoint number\r
704   * @retval None\r
705   */\r
706  __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)\r
707 {\r
708   /* NOTE : This function Should not be modified, when the callback is needed,\r
709             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file\r
710    */ \r
711 }\r
712 \r
713 /**\r
714   * @brief  Incomplete ISO IN  callbacks\r
715   * @param  hpcd: PCD handle\r
716   * @param  epnum: endpoint number  \r
717   * @retval None\r
718   */\r
719  __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)\r
720 {\r
721   /* NOTE : This function Should not be modified, when the callback is needed,\r
722             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file\r
723    */ \r
724 }\r
725 \r
726 /**\r
727   * @brief  Connection event callbacks\r
728   * @param  hpcd: PCD handle\r
729   * @retval None\r
730   */\r
731  __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)\r
732 {\r
733   /* NOTE : This function Should not be modified, when the callback is needed,\r
734             the HAL_PCD_ConnectCallback could be implemented in the user file\r
735    */ \r
736 }\r
737 \r
738 /**\r
739   * @brief  Disconnection event callbacks\r
740   * @param  hpcd: PCD handle\r
741   * @retval None\r
742   */\r
743  __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)\r
744 {\r
745   /* NOTE : This function Should not be modified, when the callback is needed,\r
746             the HAL_PCD_DisconnectCallback could be implemented in the user file\r
747    */ \r
748 }\r
749 \r
750 /**\r
751   * @}\r
752   */\r
753   \r
754 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions\r
755  *  @brief   management functions \r
756  *\r
757 @verbatim   \r
758  ===============================================================================\r
759                       ##### Peripheral Control functions #####\r
760  ===============================================================================  \r
761     [..]\r
762     This subsection provides a set of functions allowing to control the PCD data \r
763     transfers.\r
764 \r
765 @endverbatim\r
766   * @{\r
767   */\r
768 \r
769 /**\r
770   * @brief  Connect the USB device\r
771   * @param  hpcd: PCD handle\r
772   * @retval HAL status\r
773   */\r
774 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)\r
775 {\r
776   __HAL_LOCK(hpcd); \r
777   USB_DevConnect(hpcd->Instance);\r
778   __HAL_UNLOCK(hpcd); \r
779   return HAL_OK;\r
780 }\r
781 \r
782 /**\r
783   * @brief  Disconnect the USB device\r
784   * @param  hpcd: PCD handle\r
785   * @retval HAL status\r
786   */\r
787 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)\r
788 {\r
789   __HAL_LOCK(hpcd); \r
790   USB_DevDisconnect(hpcd->Instance);\r
791   __HAL_UNLOCK(hpcd); \r
792   return HAL_OK;\r
793 }\r
794 \r
795 /**\r
796   * @brief  Set the USB Device address \r
797   * @param  hpcd: PCD handle\r
798   * @param  address: new device address\r
799   * @retval HAL status\r
800   */\r
801 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)\r
802 {\r
803   __HAL_LOCK(hpcd); \r
804   USB_SetDevAddress(hpcd->Instance, address);\r
805   __HAL_UNLOCK(hpcd);   \r
806   return HAL_OK;\r
807 }\r
808 /**\r
809   * @brief  Open and configure an endpoint\r
810   * @param  hpcd: PCD handle\r
811   * @param  ep_addr: endpoint address\r
812   * @param  ep_mps: endpoint max packet size\r
813   * @param  ep_type: endpoint type   \r
814   * @retval HAL status\r
815   */\r
816 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)\r
817 {\r
818   HAL_StatusTypeDef  ret = HAL_OK;\r
819   USB_OTG_EPTypeDef *ep;\r
820   \r
821   if ((ep_addr & 0x80) == 0x80)\r
822   {\r
823     ep = &hpcd->IN_ep[ep_addr & 0x7F];\r
824   }\r
825   else\r
826   {\r
827     ep = &hpcd->OUT_ep[ep_addr & 0x7F];\r
828   }\r
829   ep->num   = ep_addr & 0x7F;\r
830   \r
831   ep->is_in = (0x80 & ep_addr) != 0;\r
832   ep->maxpacket = ep_mps;\r
833   ep->type = ep_type;\r
834   if (ep->is_in)\r
835   {\r
836     /* Assign a Tx FIFO */\r
837     ep->tx_fifo_num = ep->num;\r
838   }\r
839   /* Set initial data PID. */\r
840   if (ep_type == EP_TYPE_BULK )\r
841   {\r
842     ep->data_pid_start = 0;\r
843   }\r
844   \r
845   __HAL_LOCK(hpcd); \r
846   USB_ActivateEndpoint(hpcd->Instance , ep);\r
847   __HAL_UNLOCK(hpcd);   \r
848   return ret;\r
849 }\r
850 \r
851 \r
852 /**\r
853   * @brief  Deactivate an endpoint\r
854   * @param  hpcd: PCD handle\r
855   * @param  ep_addr: endpoint address\r
856   * @retval HAL status\r
857   */\r
858 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)\r
859 {  \r
860   USB_OTG_EPTypeDef *ep;\r
861   \r
862   if ((ep_addr & 0x80) == 0x80)\r
863   {\r
864     ep = &hpcd->IN_ep[ep_addr & 0x7F];\r
865   }\r
866   else\r
867   {\r
868     ep = &hpcd->OUT_ep[ep_addr & 0x7F];\r
869   }\r
870   ep->num   = ep_addr & 0x7F;\r
871   \r
872   ep->is_in = (0x80 & ep_addr) != 0;\r
873   \r
874   __HAL_LOCK(hpcd); \r
875   USB_DeactivateEndpoint(hpcd->Instance , ep);\r
876   __HAL_UNLOCK(hpcd);   \r
877   return HAL_OK;\r
878 }\r
879 \r
880 \r
881 /**\r
882   * @brief  Receive an amount of data  \r
883   * @param  hpcd: PCD handle\r
884   * @param  ep_addr: endpoint address\r
885   * @param  pBuf: pointer to the reception buffer   \r
886   * @param  len: amount of data to be received\r
887   * @retval HAL status\r
888   */\r
889 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)\r
890 {\r
891   USB_OTG_EPTypeDef *ep;\r
892   \r
893   ep = &hpcd->OUT_ep[ep_addr & 0x7F];\r
894   \r
895   /*setup and start the Xfer */\r
896   ep->xfer_buff = pBuf;  \r
897   ep->xfer_len = len;\r
898   ep->xfer_count = 0;\r
899   ep->is_in = 0;\r
900   ep->num = ep_addr & 0x7F;\r
901   \r
902   if (hpcd->Init.dma_enable == 1)\r
903   {\r
904     ep->dma_addr = (uint32_t)pBuf;  \r
905   }\r
906   \r
907   __HAL_LOCK(hpcd); \r
908   \r
909   if ((ep_addr & 0x7F) == 0 )\r
910   {\r
911     USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);\r
912   }\r
913   else\r
914   {\r
915     USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);\r
916   }\r
917   __HAL_UNLOCK(hpcd); \r
918   \r
919   return HAL_OK;\r
920 }\r
921 \r
922 /**\r
923   * @brief  Get Received Data Size\r
924   * @param  hpcd: PCD handle\r
925   * @param  ep_addr: endpoint address\r
926   * @retval Data Size\r
927   */\r
928 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)\r
929 {\r
930   return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count;\r
931 }\r
932 /**\r
933   * @brief  Send an amount of data  \r
934   * @param  hpcd: PCD handle\r
935   * @param  ep_addr: endpoint address\r
936   * @param  pBuf: pointer to the transmission buffer   \r
937   * @param  len: amount of data to be sent\r
938   * @retval HAL status\r
939   */\r
940 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)\r
941 {\r
942   USB_OTG_EPTypeDef *ep;\r
943   \r
944   ep = &hpcd->IN_ep[ep_addr & 0x7F];\r
945   \r
946   /*setup and start the Xfer */\r
947   ep->xfer_buff = pBuf;  \r
948   ep->xfer_len = len;\r
949   ep->xfer_count = 0;\r
950   ep->is_in = 1;\r
951   ep->num = ep_addr & 0x7F;\r
952   \r
953   if (hpcd->Init.dma_enable == 1)\r
954   {\r
955     ep->dma_addr = (uint32_t)pBuf;  \r
956   }\r
957   \r
958   __HAL_LOCK(hpcd); \r
959   \r
960   if ((ep_addr & 0x7F) == 0 )\r
961   {\r
962     USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);\r
963   }\r
964   else\r
965   {\r
966     USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);\r
967   }\r
968   \r
969   __HAL_UNLOCK(hpcd);\r
970      \r
971   return HAL_OK;\r
972 }\r
973 \r
974 /**\r
975   * @brief  Set a STALL condition over an endpoint\r
976   * @param  hpcd: PCD handle\r
977   * @param  ep_addr: endpoint address\r
978   * @retval HAL status\r
979   */\r
980 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)\r
981 {\r
982   USB_OTG_EPTypeDef *ep;\r
983   \r
984   if ((0x80 & ep_addr) == 0x80)\r
985   {\r
986     ep = &hpcd->IN_ep[ep_addr & 0x7F];\r
987   }\r
988   else\r
989   {\r
990     ep = &hpcd->OUT_ep[ep_addr];\r
991   }\r
992   \r
993   ep->is_stall = 1;\r
994   ep->num   = ep_addr & 0x7F;\r
995   ep->is_in = ((ep_addr & 0x80) == 0x80);\r
996   \r
997   \r
998   __HAL_LOCK(hpcd); \r
999   USB_EPSetStall(hpcd->Instance , ep);\r
1000   if((ep_addr & 0x7F) == 0)\r
1001   {\r
1002     USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);\r
1003   }\r
1004   __HAL_UNLOCK(hpcd); \r
1005   \r
1006   return HAL_OK;\r
1007 }\r
1008 \r
1009 /**\r
1010   * @brief  Clear a STALL condition over in an endpoint\r
1011   * @param  hpcd: PCD handle\r
1012   * @param  ep_addr: endpoint address\r
1013   * @retval HAL status\r
1014   */\r
1015 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)\r
1016 {\r
1017   USB_OTG_EPTypeDef *ep;\r
1018   \r
1019   if ((0x80 & ep_addr) == 0x80)\r
1020   {\r
1021     ep = &hpcd->IN_ep[ep_addr & 0x7F];\r
1022   }\r
1023   else\r
1024   {\r
1025     ep = &hpcd->OUT_ep[ep_addr];\r
1026   }\r
1027   \r
1028   ep->is_stall = 0;\r
1029   ep->num   = ep_addr & 0x7F;\r
1030   ep->is_in = ((ep_addr & 0x80) == 0x80);\r
1031   \r
1032   __HAL_LOCK(hpcd); \r
1033   USB_EPClearStall(hpcd->Instance , ep);\r
1034   __HAL_UNLOCK(hpcd); \r
1035     \r
1036   return HAL_OK;\r
1037 }\r
1038 \r
1039 /**\r
1040   * @brief  Flush an endpoint\r
1041   * @param  hpcd: PCD handle\r
1042   * @param  ep_addr: endpoint address\r
1043   * @retval HAL status\r
1044   */\r
1045 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)\r
1046 {\r
1047   __HAL_LOCK(hpcd); \r
1048   \r
1049   if ((ep_addr & 0x80) == 0x80)\r
1050   {\r
1051     USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F);\r
1052   }\r
1053   else\r
1054   {\r
1055     USB_FlushRxFifo(hpcd->Instance);\r
1056   }\r
1057   \r
1058   __HAL_UNLOCK(hpcd); \r
1059     \r
1060   return HAL_OK;\r
1061 }\r
1062 \r
1063 /**\r
1064   * @brief  HAL_PCD_ActivateRemoteWakeup : Active remote wake-up signalling\r
1065   * @param  hpcd: PCD handle\r
1066   * @retval HAL status\r
1067   */\r
1068 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)\r
1069 {\r
1070   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  \r
1071     \r
1072   if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)\r
1073   {\r
1074     /* Activate Remote wake-up signaling */\r
1075     USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;\r
1076   }\r
1077   return HAL_OK;  \r
1078 }\r
1079 \r
1080 /**\r
1081   * @brief  HAL_PCD_DeActivateRemoteWakeup : de-active remote wake-up signalling\r
1082   * @param  hpcd: PCD handle\r
1083   * @retval HAL status\r
1084   */\r
1085 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)\r
1086 {\r
1087   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  \r
1088   \r
1089   /* De-activate Remote wake-up signaling */\r
1090    USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);\r
1091   return HAL_OK;  \r
1092 }\r
1093 /**\r
1094   * @}\r
1095   */\r
1096   \r
1097 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions \r
1098  *  @brief   Peripheral State functions \r
1099  *\r
1100 @verbatim   \r
1101  ===============================================================================\r
1102                       ##### Peripheral State functions #####\r
1103  ===============================================================================  \r
1104     [..]\r
1105     This subsection permits to get in run-time the status of the peripheral \r
1106     and the data flow.\r
1107 \r
1108 @endverbatim\r
1109   * @{\r
1110   */\r
1111 \r
1112 /**\r
1113   * @brief  Return the PCD state\r
1114   * @param  hpcd: PCD handle\r
1115   * @retval HAL state\r
1116   */\r
1117 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)\r
1118 {\r
1119   return hpcd->State;\r
1120 }\r
1121 /**\r
1122   * @}\r
1123   */\r
1124 \r
1125 /**\r
1126   * @}\r
1127   */\r
1128 \r
1129 /* Private functions ---------------------------------------------------------*/\r
1130 /** @addtogroup PCD_Private_Functions\r
1131   * @{\r
1132   */\r
1133 \r
1134 /**\r
1135   * @brief  DCD_WriteEmptyTxFifo\r
1136   *         check FIFO for the next packet to be loaded\r
1137   * @param  hpcd: PCD handle\r
1138   * @param  epnum : endpoint number   \r
1139   * @retval HAL status\r
1140   */\r
1141 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)\r
1142 {\r
1143   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  \r
1144   USB_OTG_EPTypeDef *ep;\r
1145   int32_t len = 0;\r
1146   uint32_t len32b;\r
1147   uint32_t fifoemptymsk = 0;\r
1148 \r
1149   ep = &hpcd->IN_ep[epnum];\r
1150   len = ep->xfer_len - ep->xfer_count;\r
1151   \r
1152   if (len > ep->maxpacket)\r
1153   {\r
1154     len = ep->maxpacket;\r
1155   }\r
1156   \r
1157   \r
1158   len32b = (len + 3) / 4;\r
1159  \r
1160   while  ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&\r
1161           ep->xfer_count < ep->xfer_len &&\r
1162             ep->xfer_len != 0)\r
1163   {\r
1164     /* Write the FIFO */\r
1165     len = ep->xfer_len - ep->xfer_count;\r
1166     \r
1167     if (len > ep->maxpacket)\r
1168     {\r
1169       len = ep->maxpacket;\r
1170     }\r
1171     len32b = (len + 3) / 4;\r
1172     \r
1173     USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); \r
1174     \r
1175     ep->xfer_buff  += len;\r
1176     ep->xfer_count += len;\r
1177   }\r
1178   \r
1179   if(len <= 0)\r
1180   {\r
1181     fifoemptymsk = 0x1 << epnum;\r
1182     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;\r
1183     \r
1184   }\r
1185   \r
1186   return HAL_OK;  \r
1187 }\r
1188 \r
1189 /**\r
1190   * @}\r
1191   */\r
1192 \r
1193 #endif /* HAL_PCD_MODULE_ENABLED */\r
1194 /**\r
1195   * @}\r
1196   */\r
1197 \r
1198 /**\r
1199   * @}\r
1200   */\r
1201 \r
1202 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r