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