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>© 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