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