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