1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_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 "stm32l0xx_hal.h"
42 
43 /** @addtogroup STM32L0xx_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 | USB_CNTR_L1REQM;
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 | USB_CNTR_L1REQM;
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     if (ep->type == EP_TYPE_BULK)
253     {
254       /* Set bulk endpoint as double buffered */
255       PCD_SET_BULK_EP_DBUF(USBx, ep->num);
256     }
257     else
258     {
259       /* Set the ISOC endpoint in double buffer mode */
260       PCD_CLEAR_EP_KIND(USBx, ep->num);
261     }
262 
263     /* Set buffer address for double buffered mode */
264     PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
265 
266     if (ep->is_in == 0U)
267     {
268       /* Clear the data toggle bits for the endpoint IN/OUT */
269       PCD_CLEAR_RX_DTOG(USBx, ep->num);
270       PCD_CLEAR_TX_DTOG(USBx, ep->num);
271 
272       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
273       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
274     }
275     else
276     {
277       /* Clear the data toggle bits for the endpoint IN/OUT */
278       PCD_CLEAR_RX_DTOG(USBx, ep->num);
279       PCD_CLEAR_TX_DTOG(USBx, ep->num);
280 
281       if (ep->type != EP_TYPE_ISOC)
282       {
283         /* Configure NAK status for the Endpoint */
284         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
285       }
286       else
287       {
288         /* Configure TX Endpoint to disabled state */
289         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
290       }
291 
292       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
293     }
294   }
295 
296   return ret;
297 }
298 
299 /**
300   * @brief  De-activate and de-initialize an endpoint
301   * @param  USBx Selected device
302   * @param  ep pointer to endpoint structure
303   * @retval HAL status
304   */
USB_DeactivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)305 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
306 {
307   if (ep->doublebuffer == 0U)
308   {
309     if (ep->is_in != 0U)
310     {
311       PCD_CLEAR_TX_DTOG(USBx, ep->num);
312 
313       /* Configure DISABLE status for the Endpoint*/
314       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
315     }
316     else
317     {
318       PCD_CLEAR_RX_DTOG(USBx, ep->num);
319 
320       /* Configure DISABLE status for the Endpoint*/
321       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
322     }
323   }
324   /*Double Buffer*/
325   else
326   {
327     if (ep->is_in == 0U)
328     {
329       /* Clear the data toggle bits for the endpoint IN/OUT*/
330       PCD_CLEAR_RX_DTOG(USBx, ep->num);
331       PCD_CLEAR_TX_DTOG(USBx, ep->num);
332 
333       /* Reset value of the data toggle bits for the endpoint out*/
334       PCD_TX_DTOG(USBx, ep->num);
335 
336       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
337       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
338     }
339     else
340     {
341       /* Clear the data toggle bits for the endpoint IN/OUT*/
342       PCD_CLEAR_RX_DTOG(USBx, ep->num);
343       PCD_CLEAR_TX_DTOG(USBx, ep->num);
344       PCD_RX_DTOG(USBx, ep->num);
345 
346       /* Configure DISABLE status for the Endpoint*/
347       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
348       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
349     }
350   }
351 
352   return HAL_OK;
353 }
354 
355 /**
356   * @brief  USB_EPStartXfer setup and starts a transfer over an EP
357   * @param  USBx Selected device
358   * @param  ep pointer to endpoint structure
359   * @retval HAL status
360   */
USB_EPStartXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)361 HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
362 {
363   uint32_t len;
364   uint16_t pmabuffer;
365   uint16_t wEPVal;
366 
367   /* IN endpoint */
368   if (ep->is_in == 1U)
369   {
370     /*Multi packet transfer*/
371     if (ep->xfer_len > ep->maxpacket)
372     {
373       len = ep->maxpacket;
374     }
375     else
376     {
377       len = ep->xfer_len;
378     }
379 
380     /* configure and validate Tx endpoint */
381     if (ep->doublebuffer == 0U)
382     {
383       USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
384       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
385     }
386     else
387     {
388       /* double buffer bulk management */
389       if (ep->type == EP_TYPE_BULK)
390       {
391         if (ep->xfer_len_db > ep->maxpacket)
392         {
393           /* enable double buffer */
394           PCD_SET_BULK_EP_DBUF(USBx, ep->num);
395 
396           /* each Time to write in PMA xfer_len_db will */
397           ep->xfer_len_db -= len;
398 
399           /* Fill the two first buffer in the Buffer0 & Buffer1 */
400           if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
401           {
402             /* Set the Double buffer counter for pmabuffer1 */
403             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
404             pmabuffer = ep->pmaaddr1;
405 
406             /* Write the user buffer to USB PMA */
407             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
408             ep->xfer_buff += len;
409 
410             if (ep->xfer_len_db > ep->maxpacket)
411             {
412               ep->xfer_len_db -= len;
413             }
414             else
415             {
416               len = ep->xfer_len_db;
417               ep->xfer_len_db = 0U;
418             }
419 
420             /* Set the Double buffer counter for pmabuffer0 */
421             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
422             pmabuffer = ep->pmaaddr0;
423 
424             /* Write the user buffer to USB PMA */
425             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
426           }
427           else
428           {
429             /* Set the Double buffer counter for pmabuffer0 */
430             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
431             pmabuffer = ep->pmaaddr0;
432 
433             /* Write the user buffer to USB PMA */
434             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
435             ep->xfer_buff += len;
436 
437             if (ep->xfer_len_db > ep->maxpacket)
438             {
439               ep->xfer_len_db -= len;
440             }
441             else
442             {
443               len = ep->xfer_len_db;
444               ep->xfer_len_db = 0U;
445             }
446 
447             /* Set the Double buffer counter for pmabuffer1 */
448             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
449             pmabuffer = ep->pmaaddr1;
450 
451             /* Write the user buffer to USB PMA */
452             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
453           }
454         }
455         /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
456         else
457         {
458           len = ep->xfer_len_db;
459 
460           /* disable double buffer mode for Bulk endpoint */
461           PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
462 
463           /* Set Tx count with nbre of byte to be transmitted */
464           PCD_SET_EP_TX_CNT(USBx, ep->num, len);
465           pmabuffer = ep->pmaaddr0;
466 
467           /* Write the user buffer to USB PMA */
468           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
469         }
470       }
471       else /* manage isochronous double buffer IN mode */
472       {
473         /* each Time to write in PMA xfer_len_db will */
474         ep->xfer_len_db -= len;
475 
476         /* Fill the data buffer */
477         if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
478         {
479           /* Set the Double buffer counter for pmabuffer1 */
480           PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
481           pmabuffer = ep->pmaaddr1;
482 
483           /* Write the user buffer to USB PMA */
484           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
485         }
486         else
487         {
488           /* Set the Double buffer counter for pmabuffer0 */
489           PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
490           pmabuffer = ep->pmaaddr0;
491 
492           /* Write the user buffer to USB PMA */
493           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
494         }
495       }
496     }
497 
498     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
499   }
500   else /* OUT endpoint */
501   {
502     if (ep->doublebuffer == 0U)
503     {
504       /* Multi packet transfer */
505       if (ep->xfer_len > ep->maxpacket)
506       {
507         len = ep->maxpacket;
508         ep->xfer_len -= len;
509       }
510       else
511       {
512         len = ep->xfer_len;
513         ep->xfer_len = 0U;
514       }
515       /* configure and validate Rx endpoint */
516       PCD_SET_EP_RX_CNT(USBx, ep->num, len);
517     }
518     else
519     {
520       /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
521       /* Set the Double buffer counter */
522       if (ep->type == EP_TYPE_BULK)
523       {
524         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
525 
526         /* Coming from ISR */
527         if (ep->xfer_count != 0U)
528         {
529           /* update last value to check if there is blocking state */
530           wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
531 
532           /*Blocking State */
533           if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
534               (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
535           {
536             PCD_FreeUserBuffer(USBx, ep->num, 0U);
537           }
538         }
539       }
540       /* iso out double */
541       else if (ep->type == EP_TYPE_ISOC)
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         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
555       }
556       else
557       {
558         return HAL_ERROR;
559       }
560     }
561 
562     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
563   }
564 
565   return HAL_OK;
566 }
567 
568 
569 /**
570   * @brief  USB_EPSetStall set a stall condition over an EP
571   * @param  USBx Selected device
572   * @param  ep pointer to endpoint structure
573   * @retval HAL status
574   */
USB_EPSetStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)575 HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
576 {
577   if (ep->is_in != 0U)
578   {
579     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
580   }
581   else
582   {
583     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
584   }
585 
586   return HAL_OK;
587 }
588 
589 /**
590   * @brief  USB_EPClearStall Clear a stall condition over an EP
591   * @param  USBx Selected device
592   * @param  ep pointer to endpoint structure
593   * @retval HAL status
594   */
USB_EPClearStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)595 HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
596 {
597   if (ep->doublebuffer == 0U)
598   {
599     if (ep->is_in != 0U)
600     {
601       PCD_CLEAR_TX_DTOG(USBx, ep->num);
602 
603       if (ep->type != EP_TYPE_ISOC)
604       {
605         /* Configure NAK status for the Endpoint */
606         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
607       }
608     }
609     else
610     {
611       PCD_CLEAR_RX_DTOG(USBx, ep->num);
612 
613       /* Configure VALID status for the Endpoint */
614       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
615     }
616   }
617 
618   return HAL_OK;
619 }
620 #endif /* defined (HAL_PCD_MODULE_ENABLED) */
621 
622 /**
623   * @brief  USB_StopDevice Stop the usb device mode
624   * @param  USBx Selected device
625   * @retval HAL status
626   */
USB_StopDevice(USB_TypeDef * USBx)627 HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
628 {
629   /* disable all interrupts and force USB reset */
630   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
631 
632   /* clear interrupt status register */
633   USBx->ISTR = 0U;
634 
635   /* switch-off device */
636   USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
637 
638   return HAL_OK;
639 }
640 
641 /**
642   * @brief  USB_SetDevAddress Stop the usb device mode
643   * @param  USBx Selected device
644   * @param  address new device address to be assigned
645   *          This parameter can be a value from 0 to 255
646   * @retval HAL status
647   */
USB_SetDevAddress(USB_TypeDef * USBx,uint8_t address)648 HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
649 {
650   if (address == 0U)
651   {
652     /* set device address and enable function */
653     USBx->DADDR = (uint16_t)USB_DADDR_EF;
654   }
655 
656   return HAL_OK;
657 }
658 
659 /**
660   * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
661   * @param  USBx Selected device
662   * @retval HAL status
663   */
USB_DevConnect(USB_TypeDef * USBx)664 HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
665 {
666   /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */
667   USBx->BCDR |= (uint16_t)USB_BCDR_DPPU;
668 
669   return HAL_OK;
670 }
671 
672 /**
673   * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
674   * @param  USBx Selected device
675   * @retval HAL status
676   */
USB_DevDisconnect(USB_TypeDef * USBx)677 HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
678 {
679   /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */
680   USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU));
681 
682   return HAL_OK;
683 }
684 
685 /**
686   * @brief  USB_ReadInterrupts return the global USB interrupt status
687   * @param  USBx Selected device
688   * @retval HAL status
689   */
USB_ReadInterrupts(USB_TypeDef * USBx)690 uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
691 {
692   uint32_t tmpreg;
693 
694   tmpreg = USBx->ISTR;
695   return tmpreg;
696 }
697 
698 /**
699   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
700   * @param  USBx Selected device
701   * @retval HAL status
702   */
USB_ActivateRemoteWakeup(USB_TypeDef * USBx)703 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
704 {
705   USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
706 
707   return HAL_OK;
708 }
709 
710 /**
711   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
712   * @param  USBx Selected device
713   * @retval HAL status
714   */
USB_DeActivateRemoteWakeup(USB_TypeDef * USBx)715 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
716 {
717   USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
718 
719   return HAL_OK;
720 }
721 
722 /**
723   * @brief Copy a buffer from user memory area to packet memory area (PMA)
724   * @param   USBx USB peripheral instance register address.
725   * @param   pbUsrBuf pointer to user memory area.
726   * @param   wPMABufAddr address into PMA.
727   * @param   wNBytes no. of bytes to be copied.
728   * @retval None
729   */
USB_WritePMA(USB_TypeDef * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)730 void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
731 {
732   uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
733   uint32_t BaseAddr = (uint32_t)USBx;
734   uint32_t i, temp1, temp2;
735   __IO uint16_t *pdwVal;
736   uint8_t *pBuf = pbUsrBuf;
737 
738   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
739 
740   for (i = n; i != 0U; i--)
741   {
742     temp1 = *pBuf;
743     pBuf++;
744     temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
745     *pdwVal = (uint16_t)temp2;
746     pdwVal++;
747 
748 #if PMA_ACCESS > 1U
749     pdwVal++;
750 #endif
751 
752     pBuf++;
753   }
754 }
755 
756 /**
757   * @brief Copy data from packet memory area (PMA) to user memory buffer
758   * @param   USBx USB peripheral instance register address.
759   * @param   pbUsrBuf pointer to user memory area.
760   * @param   wPMABufAddr address into PMA.
761   * @param   wNBytes no. of bytes to be copied.
762   * @retval None
763   */
USB_ReadPMA(USB_TypeDef * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)764 void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
765 {
766   uint32_t n = (uint32_t)wNBytes >> 1;
767   uint32_t BaseAddr = (uint32_t)USBx;
768   uint32_t i, temp;
769   __IO uint16_t *pdwVal;
770   uint8_t *pBuf = pbUsrBuf;
771 
772   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
773 
774   for (i = n; i != 0U; i--)
775   {
776     temp = *(__IO uint16_t *)pdwVal;
777     pdwVal++;
778     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
779     pBuf++;
780     *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
781     pBuf++;
782 
783 #if PMA_ACCESS > 1U
784     pdwVal++;
785 #endif
786   }
787 
788   if ((wNBytes % 2U) != 0U)
789   {
790     temp = *pdwVal;
791     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
792   }
793 }
794 
795 
796 /**
797   * @}
798   */
799 
800 /**
801   * @}
802   */
803 #endif /* defined (USB) */
804 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
805 
806 /**
807   * @}
808   */
809