1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_ll_usb.c
4   * @author  MCD Application Team
5   * @brief   USB Low Layer HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the USB Peripheral Controller:
9   *           + Initialization/de-initialization functions
10   *           + I/O operation functions
11   *           + Peripheral Control functions
12   *           + Peripheral State functions
13   *
14   @verbatim
15   ==============================================================================
16                     ##### How to use this driver #####
17   ==============================================================================
18     [..]
19       (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
20 
21       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
22 
23       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
24 
25   @endverbatim
26   ******************************************************************************
27   * @attention
28   *
29   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
30   * All rights reserved.</center></h2>
31   *
32   * This software component is licensed by ST under BSD 3-Clause license,
33   * the "License"; You may not use this file except in compliance with the
34   * License. You may obtain a copy of the License at:
35   *                        opensource.org/licenses/BSD-3-Clause
36   *
37   ******************************************************************************
38   */
39 
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32l1xx_hal.h"
42 
43 /** @addtogroup STM32L1xx_LL_USB_DRIVER
44   * @{
45   */
46 
47 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
48 #if defined (USB)
49 /* Private typedef -----------------------------------------------------------*/
50 /* Private define ------------------------------------------------------------*/
51 /* Private macro -------------------------------------------------------------*/
52 /* Private variables ---------------------------------------------------------*/
53 /* Private function prototypes -----------------------------------------------*/
54 /* Private functions ---------------------------------------------------------*/
55 
56 
57 /**
58   * @brief  Initializes the USB Core
59   * @param  USBx USB Instance
60   * @param  cfg pointer to a USB_CfgTypeDef structure that contains
61   *         the configuration information for the specified USBx peripheral.
62   * @retval HAL status
63   */
USB_CoreInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)64 HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
65 {
66   /* Prevent unused argument(s) compilation warning */
67   UNUSED(USBx);
68   UNUSED(cfg);
69 
70   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
71               only by USB OTG FS peripheral.
72             - This function is added to ensure compatibility across platforms.
73    */
74 
75   return HAL_OK;
76 }
77 
78 /**
79   * @brief  USB_EnableGlobalInt
80   *         Enables the controller's Global Int in the AHB Config reg
81   * @param  USBx Selected device
82   * @retval HAL status
83   */
USB_EnableGlobalInt(USB_TypeDef * USBx)84 HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
85 {
86   uint32_t winterruptmask;
87 
88   /* Clear pending interrupts */
89   USBx->ISTR = 0U;
90 
91   /* Set winterruptmask variable */
92   winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
93                    USB_CNTR_SUSPM | USB_CNTR_ERRM |
94                    USB_CNTR_SOFM | USB_CNTR_ESOFM |
95                    USB_CNTR_RESETM;
96 
97   /* Set interrupt mask */
98   USBx->CNTR = (uint16_t)winterruptmask;
99 
100   return HAL_OK;
101 }
102 
103 /**
104   * @brief  USB_DisableGlobalInt
105   *         Disable the controller's Global Int in the AHB Config reg
106   * @param  USBx Selected device
107   * @retval HAL status
108   */
USB_DisableGlobalInt(USB_TypeDef * USBx)109 HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
110 {
111   uint32_t winterruptmask;
112 
113   /* Set winterruptmask variable */
114   winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
115                    USB_CNTR_SUSPM | USB_CNTR_ERRM |
116                    USB_CNTR_SOFM | USB_CNTR_ESOFM |
117                    USB_CNTR_RESETM;
118 
119   /* Clear interrupt mask */
120   USBx->CNTR &= (uint16_t)(~winterruptmask);
121 
122   return HAL_OK;
123 }
124 
125 /**
126   * @brief  USB_SetCurrentMode Set functional mode
127   * @param  USBx Selected device
128   * @param  mode current core mode
129   *          This parameter can be one of the these values:
130   *            @arg USB_DEVICE_MODE Peripheral mode
131   * @retval HAL status
132   */
USB_SetCurrentMode(USB_TypeDef * USBx,USB_ModeTypeDef mode)133 HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
134 {
135   /* Prevent unused argument(s) compilation warning */
136   UNUSED(USBx);
137   UNUSED(mode);
138 
139   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
140               only by USB OTG FS peripheral.
141             - This function is added to ensure compatibility across platforms.
142    */
143   return HAL_OK;
144 }
145 
146 /**
147   * @brief  USB_DevInit Initializes the USB controller registers
148   *         for device mode
149   * @param  USBx Selected device
150   * @param  cfg  pointer to a USB_CfgTypeDef structure that contains
151   *         the configuration information for the specified USBx peripheral.
152   * @retval HAL status
153   */
USB_DevInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)154 HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
155 {
156   /* Prevent unused argument(s) compilation warning */
157   UNUSED(cfg);
158 
159   /* Init Device */
160   /* CNTR_FRES = 1 */
161   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
162 
163   /* CNTR_FRES = 0 */
164   USBx->CNTR = 0U;
165 
166   /* Clear pending interrupts */
167   USBx->ISTR = 0U;
168 
169   /*Set Btable Address*/
170   USBx->BTABLE = BTABLE_ADDRESS;
171 
172   return HAL_OK;
173 }
174 
175 #if defined (HAL_PCD_MODULE_ENABLED)
176 /**
177   * @brief  Activate and configure an endpoint
178   * @param  USBx Selected device
179   * @param  ep pointer to endpoint structure
180   * @retval HAL status
181   */
USB_ActivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)182 HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
183 {
184   HAL_StatusTypeDef ret = HAL_OK;
185   uint16_t wEpRegVal;
186 
187   wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
188 
189   /* initialize Endpoint */
190   switch (ep->type)
191   {
192     case EP_TYPE_CTRL:
193       wEpRegVal |= USB_EP_CONTROL;
194       break;
195 
196     case EP_TYPE_BULK:
197       wEpRegVal |= USB_EP_BULK;
198       break;
199 
200     case EP_TYPE_INTR:
201       wEpRegVal |= USB_EP_INTERRUPT;
202       break;
203 
204     case EP_TYPE_ISOC:
205       wEpRegVal |= USB_EP_ISOCHRONOUS;
206       break;
207 
208     default:
209       ret = HAL_ERROR;
210       break;
211   }
212 
213   PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
214 
215   PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
216 
217   if (ep->doublebuffer == 0U)
218   {
219     if (ep->is_in != 0U)
220     {
221       /*Set the endpoint Transmit buffer address */
222       PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
223       PCD_CLEAR_TX_DTOG(USBx, ep->num);
224 
225       if (ep->type != EP_TYPE_ISOC)
226       {
227         /* Configure NAK status for the Endpoint */
228         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
229       }
230       else
231       {
232         /* Configure TX Endpoint to disabled state */
233         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
234       }
235     }
236     else
237     {
238       /*Set the endpoint Receive buffer address */
239       PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
240 
241       /*Set the endpoint Receive buffer counter*/
242       PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
243       PCD_CLEAR_RX_DTOG(USBx, ep->num);
244 
245       /* Configure VALID status for the Endpoint*/
246       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
247     }
248   }
249   /*Double Buffer*/
250   else
251   {
252     /* Set the endpoint as double buffered */
253     PCD_SET_EP_DBUF(USBx, ep->num);
254 
255     /* Set buffer address for double buffered mode */
256     PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
257 
258     if (ep->is_in == 0U)
259     {
260       /* Clear the data toggle bits for the endpoint IN/OUT */
261       PCD_CLEAR_RX_DTOG(USBx, ep->num);
262       PCD_CLEAR_TX_DTOG(USBx, ep->num);
263 
264       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
265       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
266     }
267     else
268     {
269       /* Clear the data toggle bits for the endpoint IN/OUT */
270       PCD_CLEAR_RX_DTOG(USBx, ep->num);
271       PCD_CLEAR_TX_DTOG(USBx, ep->num);
272 
273       if (ep->type != EP_TYPE_ISOC)
274       {
275         /* Configure NAK status for the Endpoint */
276         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
277       }
278       else
279       {
280         /* Configure TX Endpoint to disabled state */
281         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
282       }
283 
284       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
285     }
286   }
287 
288   return ret;
289 }
290 
291 /**
292   * @brief  De-activate and de-initialize an endpoint
293   * @param  USBx Selected device
294   * @param  ep pointer to endpoint structure
295   * @retval HAL status
296   */
USB_DeactivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)297 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
298 {
299   if (ep->doublebuffer == 0U)
300   {
301     if (ep->is_in != 0U)
302     {
303       PCD_CLEAR_TX_DTOG(USBx, ep->num);
304 
305       /* Configure DISABLE status for the Endpoint*/
306       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
307     }
308     else
309     {
310       PCD_CLEAR_RX_DTOG(USBx, ep->num);
311 
312       /* Configure DISABLE status for the Endpoint*/
313       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
314     }
315   }
316   /*Double Buffer*/
317   else
318   {
319     if (ep->is_in == 0U)
320     {
321       /* Clear the data toggle bits for the endpoint IN/OUT*/
322       PCD_CLEAR_RX_DTOG(USBx, ep->num);
323       PCD_CLEAR_TX_DTOG(USBx, ep->num);
324 
325       /* Reset value of the data toggle bits for the endpoint out*/
326       PCD_TX_DTOG(USBx, ep->num);
327 
328       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
329       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
330     }
331     else
332     {
333       /* Clear the data toggle bits for the endpoint IN/OUT*/
334       PCD_CLEAR_RX_DTOG(USBx, ep->num);
335       PCD_CLEAR_TX_DTOG(USBx, ep->num);
336       PCD_RX_DTOG(USBx, ep->num);
337 
338       /* Configure DISABLE status for the Endpoint*/
339       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
340       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
341     }
342   }
343 
344   return HAL_OK;
345 }
346 
347 /**
348   * @brief  USB_EPStartXfer setup and starts a transfer over an EP
349   * @param  USBx Selected device
350   * @param  ep pointer to endpoint structure
351   * @retval HAL status
352   */
USB_EPStartXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)353 HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
354 {
355   uint32_t len;
356   uint16_t pmabuffer;
357   uint16_t wEPVal;
358 
359   /* IN endpoint */
360   if (ep->is_in == 1U)
361   {
362     /*Multi packet transfer*/
363     if (ep->xfer_len > ep->maxpacket)
364     {
365       len = ep->maxpacket;
366     }
367     else
368     {
369       len = ep->xfer_len;
370     }
371 
372     /* configure and validate Tx endpoint */
373     if (ep->doublebuffer == 0U)
374     {
375       USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
376       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
377     }
378     else
379     {
380       /* double buffer bulk management */
381       if (ep->type == EP_TYPE_BULK)
382       {
383         if (ep->xfer_len_db > ep->maxpacket)
384         {
385           /* enable double buffer */
386           PCD_SET_EP_DBUF(USBx, ep->num);
387 
388           /* each Time to write in PMA xfer_len_db will */
389           ep->xfer_len_db -= len;
390 
391           /* Fill the two first buffer in the Buffer0 & Buffer1 */
392           if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
393           {
394             /* Set the Double buffer counter for pmabuffer1 */
395             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
396             pmabuffer = ep->pmaaddr1;
397 
398             /* Write the user buffer to USB PMA */
399             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
400             ep->xfer_buff += len;
401 
402             if (ep->xfer_len_db > ep->maxpacket)
403             {
404               ep->xfer_len_db -= len;
405             }
406             else
407             {
408               len = ep->xfer_len_db;
409               ep->xfer_len_db = 0U;
410             }
411 
412             /* Set the Double buffer counter for pmabuffer0 */
413             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
414             pmabuffer = ep->pmaaddr0;
415 
416             /* Write the user buffer to USB PMA */
417             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
418           }
419           else
420           {
421             /* Set the Double buffer counter for pmabuffer0 */
422             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
423             pmabuffer = ep->pmaaddr0;
424 
425             /* Write the user buffer to USB PMA */
426             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
427             ep->xfer_buff += len;
428 
429             if (ep->xfer_len_db > ep->maxpacket)
430             {
431               ep->xfer_len_db -= len;
432             }
433             else
434             {
435               len = ep->xfer_len_db;
436               ep->xfer_len_db = 0U;
437             }
438 
439             /* Set the Double buffer counter for pmabuffer1 */
440             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
441             pmabuffer = ep->pmaaddr1;
442 
443             /* Write the user buffer to USB PMA */
444             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
445           }
446         }
447         /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
448         else
449         {
450           len = ep->xfer_len_db;
451 
452           /* disable double buffer mode */
453           PCD_CLEAR_EP_DBUF(USBx, ep->num);
454 
455           /* Set Tx count with nbre of byte to be transmitted */
456           PCD_SET_EP_TX_CNT(USBx, ep->num, len);
457           pmabuffer = ep->pmaaddr0;
458 
459           /* Write the user buffer to USB PMA */
460           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
461         }
462       }/* end if bulk double buffer */
463 
464       /* manage isochronous double buffer IN mode */
465       else
466       {
467         /* enable double buffer */
468         PCD_SET_EP_DBUF(USBx, ep->num);
469 
470         /* each Time to write in PMA xfer_len_db will */
471         ep->xfer_len_db -= len;
472 
473         /* Fill the data buffer */
474         if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
475         {
476           /* Set the Double buffer counter for pmabuffer1 */
477           PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
478           pmabuffer = ep->pmaaddr1;
479 
480           /* Write the user buffer to USB PMA */
481           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
482           ep->xfer_buff += len;
483 
484           if (ep->xfer_len_db > ep->maxpacket)
485           {
486             ep->xfer_len_db -= len;
487           }
488           else
489           {
490             len = ep->xfer_len_db;
491             ep->xfer_len_db = 0U;
492           }
493 
494           if (len > 0U)
495           {
496             /* Set the Double buffer counter for pmabuffer0 */
497             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
498             pmabuffer = ep->pmaaddr0;
499 
500             /* Write the user buffer to USB PMA */
501             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
502           }
503         }
504         else
505         {
506           /* Set the Double buffer counter for pmabuffer0 */
507           PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
508           pmabuffer = ep->pmaaddr0;
509 
510           /* Write the user buffer to USB PMA */
511           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
512           ep->xfer_buff += len;
513 
514           if (ep->xfer_len_db > ep->maxpacket)
515           {
516             ep->xfer_len_db -= len;
517           }
518           else
519           {
520             len = ep->xfer_len_db;
521             ep->xfer_len_db = 0U;
522           }
523 
524           if (len > 0U)
525           {
526             /* Set the Double buffer counter for pmabuffer1 */
527             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
528             pmabuffer = ep->pmaaddr1;
529 
530             /* Write the user buffer to USB PMA */
531             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
532           }
533         }
534       }
535     }
536 
537     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
538   }
539   else /* OUT endpoint */
540   {
541     if (ep->doublebuffer == 0U)
542     {
543       /* Multi packet transfer */
544       if (ep->xfer_len > ep->maxpacket)
545       {
546         len = ep->maxpacket;
547         ep->xfer_len -= len;
548       }
549       else
550       {
551         len = ep->xfer_len;
552         ep->xfer_len = 0U;
553       }
554       /* configure and validate Rx endpoint */
555       PCD_SET_EP_RX_CNT(USBx, ep->num, len);
556     }
557     else
558     {
559       /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
560       /* Set the Double buffer counter */
561       if (ep->type == EP_TYPE_BULK)
562       {
563         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
564 
565         /* Coming from ISR */
566         if (ep->xfer_count != 0U)
567         {
568           /* update last value to check if there is blocking state */
569           wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
570 
571           /*Blocking State */
572           if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
573               (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
574           {
575             PCD_FreeUserBuffer(USBx, ep->num, 0U);
576           }
577         }
578       }
579       /* iso out double */
580       else if (ep->type == EP_TYPE_ISOC)
581       {
582         /* Multi packet transfer */
583         if (ep->xfer_len > ep->maxpacket)
584         {
585           len = ep->maxpacket;
586           ep->xfer_len -= len;
587         }
588         else
589         {
590           len = ep->xfer_len;
591           ep->xfer_len = 0U;
592         }
593         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
594       }
595       else
596       {
597         return HAL_ERROR;
598       }
599     }
600 
601     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
602   }
603 
604   return HAL_OK;
605 }
606 
607 
608 /**
609   * @brief  USB_EPSetStall set a stall condition over an EP
610   * @param  USBx Selected device
611   * @param  ep pointer to endpoint structure
612   * @retval HAL status
613   */
USB_EPSetStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)614 HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
615 {
616   if (ep->is_in != 0U)
617   {
618     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
619   }
620   else
621   {
622     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
623   }
624 
625   return HAL_OK;
626 }
627 
628 /**
629   * @brief  USB_EPClearStall Clear a stall condition over an EP
630   * @param  USBx Selected device
631   * @param  ep pointer to endpoint structure
632   * @retval HAL status
633   */
USB_EPClearStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)634 HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
635 {
636   if (ep->doublebuffer == 0U)
637   {
638     if (ep->is_in != 0U)
639     {
640       PCD_CLEAR_TX_DTOG(USBx, ep->num);
641 
642       if (ep->type != EP_TYPE_ISOC)
643       {
644         /* Configure NAK status for the Endpoint */
645         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
646       }
647     }
648     else
649     {
650       PCD_CLEAR_RX_DTOG(USBx, ep->num);
651 
652       /* Configure VALID status for the Endpoint */
653       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
654     }
655   }
656 
657   return HAL_OK;
658 }
659 #endif
660 
661 /**
662   * @brief  USB_StopDevice Stop the usb device mode
663   * @param  USBx Selected device
664   * @retval HAL status
665   */
USB_StopDevice(USB_TypeDef * USBx)666 HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
667 {
668   /* disable all interrupts and force USB reset */
669   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
670 
671   /* clear interrupt status register */
672   USBx->ISTR = 0U;
673 
674   /* switch-off device */
675   USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
676 
677   return HAL_OK;
678 }
679 
680 /**
681   * @brief  USB_SetDevAddress Stop the usb device mode
682   * @param  USBx Selected device
683   * @param  address new device address to be assigned
684   *          This parameter can be a value from 0 to 255
685   * @retval HAL status
686   */
USB_SetDevAddress(USB_TypeDef * USBx,uint8_t address)687 HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
688 {
689   if (address == 0U)
690   {
691     /* set device address and enable function */
692     USBx->DADDR = (uint16_t)USB_DADDR_EF;
693   }
694 
695   return HAL_OK;
696 }
697 
698 /**
699   * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
700   * @param  USBx Selected device
701   * @retval HAL status
702   */
USB_DevConnect(USB_TypeDef * USBx)703 HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
704 {
705   /* Prevent unused argument(s) compilation warning */
706   UNUSED(USBx);
707 
708   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
709               only by USB OTG FS peripheral.
710             - This function is added to ensure compatibility across platforms.
711    */
712 
713   return HAL_OK;
714 }
715 
716 /**
717   * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
718   * @param  USBx Selected device
719   * @retval HAL status
720   */
USB_DevDisconnect(USB_TypeDef * USBx)721 HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
722 {
723   /* Prevent unused argument(s) compilation warning */
724   UNUSED(USBx);
725 
726   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
727               only by USB OTG FS peripheral.
728             - This function is added to ensure compatibility across platforms.
729    */
730 
731   return HAL_OK;
732 }
733 
734 /**
735   * @brief  USB_ReadInterrupts return the global USB interrupt status
736   * @param  USBx Selected device
737   * @retval HAL status
738   */
USB_ReadInterrupts(USB_TypeDef * USBx)739 uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
740 {
741   uint32_t tmpreg;
742 
743   tmpreg = USBx->ISTR;
744   return tmpreg;
745 }
746 
747 /**
748   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
749   * @param  USBx Selected device
750   * @retval HAL status
751   */
USB_ActivateRemoteWakeup(USB_TypeDef * USBx)752 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
753 {
754   USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
755 
756   return HAL_OK;
757 }
758 
759 /**
760   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
761   * @param  USBx Selected device
762   * @retval HAL status
763   */
USB_DeActivateRemoteWakeup(USB_TypeDef * USBx)764 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
765 {
766   USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
767 
768   return HAL_OK;
769 }
770 
771 /**
772   * @brief Copy a buffer from user memory area to packet memory area (PMA)
773   * @param   USBx USB peripheral instance register address.
774   * @param   pbUsrBuf pointer to user memory area.
775   * @param   wPMABufAddr address into PMA.
776   * @param   wNBytes no. of bytes to be copied.
777   * @retval None
778   */
USB_WritePMA(USB_TypeDef * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)779 void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
780 {
781   uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
782   uint32_t BaseAddr = (uint32_t)USBx;
783   uint32_t i, temp1, temp2;
784   __IO uint16_t *pdwVal;
785   uint8_t *pBuf = pbUsrBuf;
786 
787   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
788 
789   for (i = n; i != 0U; i--)
790   {
791     temp1 = *pBuf;
792     pBuf++;
793     temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
794     *pdwVal = (uint16_t)temp2;
795     pdwVal++;
796 
797 #if PMA_ACCESS > 1U
798     pdwVal++;
799 #endif
800 
801     pBuf++;
802   }
803 }
804 
805 /**
806   * @brief Copy data from packet memory area (PMA) to user memory buffer
807   * @param   USBx USB peripheral instance register address.
808   * @param   pbUsrBuf pointer to user memory area.
809   * @param   wPMABufAddr address into PMA.
810   * @param   wNBytes no. of bytes to be copied.
811   * @retval None
812   */
USB_ReadPMA(USB_TypeDef * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)813 void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
814 {
815   uint32_t n = (uint32_t)wNBytes >> 1;
816   uint32_t BaseAddr = (uint32_t)USBx;
817   uint32_t i, temp;
818   __IO uint16_t *pdwVal;
819   uint8_t *pBuf = pbUsrBuf;
820 
821   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
822 
823   for (i = n; i != 0U; i--)
824   {
825     temp = *(__IO uint16_t *)pdwVal;
826     pdwVal++;
827     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
828     pBuf++;
829     *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
830     pBuf++;
831 
832 #if PMA_ACCESS > 1U
833     pdwVal++;
834 #endif
835   }
836 
837   if ((wNBytes % 2U) != 0U)
838   {
839     temp = *pdwVal;
840     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
841   }
842 }
843 
844 
845 /**
846   * @}
847   */
848 
849 /**
850   * @}
851   */
852 #endif /* defined (USB) */
853 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
854 
855 /**
856   * @}
857   */
858 
859 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
860