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