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