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