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