1 /**
2 ******************************************************************************
3 * @file stm32l4xx_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) 2017 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_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 "stm32l4xx_hal.h"
43
44 /** @addtogroup STM32L4xx_LL_USB_DRIVER
45 * @{
46 */
47
48 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49 #if defined (USB) || defined (USB_OTG_FS)
50 /* Private typedef -----------------------------------------------------------*/
51 /* Private define ------------------------------------------------------------*/
52 /* Private macro -------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 /* Private function prototypes -----------------------------------------------*/
55 /* Private functions ---------------------------------------------------------*/
56 #if defined (USB_OTG_FS)
57 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58
59 /* Exported functions --------------------------------------------------------*/
60 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
61 * @{
62 */
63
64 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
65 * @brief Initialization and Configuration functions
66 *
67 @verbatim
68 ===============================================================================
69 ##### Initialization/de-initialization functions #####
70 ===============================================================================
71
72 @endverbatim
73 * @{
74 */
75
76 /**
77 * @brief Initializes the USB Core
78 * @param USBx USB Instance
79 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
80 * the configuration information for the specified USBx peripheral.
81 * @retval HAL status
82 */
USB_CoreInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)83 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
84 {
85 HAL_StatusTypeDef ret;
86
87 /* Select FS Embedded PHY */
88 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
89
90 /* Reset after a PHY select */
91 ret = USB_CoreReset(USBx);
92
93 if (cfg.battery_charging_enable == 0U)
94 {
95 /* Activate the USB Transceiver */
96 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
97 }
98 else
99 {
100 /* Deactivate the USB Transceiver */
101 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
102 }
103
104 return ret;
105 }
106
107
108 /**
109 * @brief Set the USB turnaround time
110 * @param USBx USB Instance
111 * @param hclk: AHB clock frequency
112 * @retval USB turnaround time In PHY Clocks number
113 */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)114 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
115 uint32_t hclk, uint8_t speed)
116 {
117 uint32_t UsbTrd;
118
119 /* The USBTRD is configured according to the tables below, depending on AHB frequency
120 used by application. In the low AHB frequency range it is used to stretch enough the USB response
121 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
122 latency to the Data FIFO */
123 if (speed == USBD_FS_SPEED)
124 {
125 if ((hclk >= 14200000U) && (hclk < 15000000U))
126 {
127 /* hclk Clock Range between 14.2-15 MHz */
128 UsbTrd = 0xFU;
129 }
130 else if ((hclk >= 15000000U) && (hclk < 16000000U))
131 {
132 /* hclk Clock Range between 15-16 MHz */
133 UsbTrd = 0xEU;
134 }
135 else if ((hclk >= 16000000U) && (hclk < 17200000U))
136 {
137 /* hclk Clock Range between 16-17.2 MHz */
138 UsbTrd = 0xDU;
139 }
140 else if ((hclk >= 17200000U) && (hclk < 18500000U))
141 {
142 /* hclk Clock Range between 17.2-18.5 MHz */
143 UsbTrd = 0xCU;
144 }
145 else if ((hclk >= 18500000U) && (hclk < 20000000U))
146 {
147 /* hclk Clock Range between 18.5-20 MHz */
148 UsbTrd = 0xBU;
149 }
150 else if ((hclk >= 20000000U) && (hclk < 21800000U))
151 {
152 /* hclk Clock Range between 20-21.8 MHz */
153 UsbTrd = 0xAU;
154 }
155 else if ((hclk >= 21800000U) && (hclk < 24000000U))
156 {
157 /* hclk Clock Range between 21.8-24 MHz */
158 UsbTrd = 0x9U;
159 }
160 else if ((hclk >= 24000000U) && (hclk < 27700000U))
161 {
162 /* hclk Clock Range between 24-27.7 MHz */
163 UsbTrd = 0x8U;
164 }
165 else if ((hclk >= 27700000U) && (hclk < 32000000U))
166 {
167 /* hclk Clock Range between 27.7-32 MHz */
168 UsbTrd = 0x7U;
169 }
170 else /* if(hclk >= 32000000) */
171 {
172 /* hclk Clock Range between 32-200 MHz */
173 UsbTrd = 0x6U;
174 }
175 }
176 else
177 {
178 UsbTrd = USBD_DEFAULT_TRDT_VALUE;
179 }
180
181 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
182 USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
183
184 return HAL_OK;
185 }
186
187 /**
188 * @brief USB_EnableGlobalInt
189 * Enables the controller's Global Int in the AHB Config reg
190 * @param USBx Selected device
191 * @retval HAL status
192 */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)193 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
194 {
195 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
196 return HAL_OK;
197 }
198
199 /**
200 * @brief USB_DisableGlobalInt
201 * Disable the controller's Global Int in the AHB Config reg
202 * @param USBx Selected device
203 * @retval HAL status
204 */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)205 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
206 {
207 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
208 return HAL_OK;
209 }
210
211 /**
212 * @brief USB_SetCurrentMode Set functional mode
213 * @param USBx Selected device
214 * @param mode current core mode
215 * This parameter can be one of these values:
216 * @arg USB_DEVICE_MODE Peripheral mode
217 * @arg USB_HOST_MODE Host mode
218 * @retval HAL status
219 */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_ModeTypeDef mode)220 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_ModeTypeDef mode)
221 {
222 uint32_t ms = 0U;
223
224 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
225
226 if (mode == USB_HOST_MODE)
227 {
228 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
229
230 do
231 {
232 HAL_Delay(10U);
233 ms += 10U;
234 } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
235 }
236 else if (mode == USB_DEVICE_MODE)
237 {
238 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
239
240 do
241 {
242 HAL_Delay(10U);
243 ms += 10U;
244 } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
245 }
246 else
247 {
248 return HAL_ERROR;
249 }
250
251 if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
252 {
253 return HAL_ERROR;
254 }
255
256 return HAL_OK;
257 }
258
259 /**
260 * @brief USB_DevInit Initializes the USB_OTG controller registers
261 * for device mode
262 * @param USBx Selected device
263 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
264 * the configuration information for the specified USBx peripheral.
265 * @retval HAL status
266 */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)267 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
268 {
269 HAL_StatusTypeDef ret = HAL_OK;
270 uint32_t USBx_BASE = (uint32_t)USBx;
271 uint32_t i;
272
273 for (i = 0U; i < 15U; i++)
274 {
275 USBx->DIEPTXF[i] = 0U;
276 }
277
278 /* VBUS Sensing setup */
279 if (cfg.vbus_sensing_enable == 0U)
280 {
281 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
282
283 /* Deactivate VBUS Sensing B */
284 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
285
286 /* B-peripheral session valid override enable */
287 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
288 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
289 }
290 else
291 {
292 /* Enable HW VBUS sensing */
293 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
294 }
295
296 /* Restart the Phy Clock */
297 USBx_PCGCCTL = 0U;
298
299 /* Set Core speed to Full speed mode */
300 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
301
302 /* Flush the FIFOs */
303 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
304 {
305 ret = HAL_ERROR;
306 }
307
308 if (USB_FlushRxFifo(USBx) != HAL_OK)
309 {
310 ret = HAL_ERROR;
311 }
312
313 /* Clear all pending Device Interrupts */
314 USBx_DEVICE->DIEPMSK = 0U;
315 USBx_DEVICE->DOEPMSK = 0U;
316 USBx_DEVICE->DAINTMSK = 0U;
317
318 for (i = 0U; i < cfg.dev_endpoints; i++)
319 {
320 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
321 {
322 if (i == 0U)
323 {
324 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
325 }
326 else
327 {
328 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
329 }
330 }
331 else
332 {
333 USBx_INEP(i)->DIEPCTL = 0U;
334 }
335
336 USBx_INEP(i)->DIEPTSIZ = 0U;
337 USBx_INEP(i)->DIEPINT = 0xFB7FU;
338 }
339
340 for (i = 0U; i < cfg.dev_endpoints; i++)
341 {
342 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
343 {
344 if (i == 0U)
345 {
346 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
347 }
348 else
349 {
350 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
351 }
352 }
353 else
354 {
355 USBx_OUTEP(i)->DOEPCTL = 0U;
356 }
357
358 USBx_OUTEP(i)->DOEPTSIZ = 0U;
359 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
360 }
361
362 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
363
364 /* Disable all interrupts. */
365 USBx->GINTMSK = 0U;
366
367 /* Clear any pending interrupts */
368 USBx->GINTSTS = 0xBFFFFFFFU;
369
370 /* Enable the common interrupts */
371 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
372
373 /* Enable interrupts matching to the Device mode ONLY */
374 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
375 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
376 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
377 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
378
379 if (cfg.Sof_enable != 0U)
380 {
381 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
382 }
383
384 if (cfg.vbus_sensing_enable == 1U)
385 {
386 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
387 }
388
389 return ret;
390 }
391
392 /**
393 * @brief USB_FlushTxFifo Flush a Tx FIFO
394 * @param USBx Selected device
395 * @param num FIFO number
396 * This parameter can be a value from 1 to 15
397 15 means Flush all Tx FIFOs
398 * @retval HAL status
399 */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)400 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
401 {
402 __IO uint32_t count = 0U;
403
404 /* Wait for AHB master IDLE state. */
405 do
406 {
407 count++;
408
409 if (count > HAL_USB_TIMEOUT)
410 {
411 return HAL_TIMEOUT;
412 }
413 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
414
415 /* Flush TX Fifo */
416 count = 0U;
417 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
418
419 do
420 {
421 count++;
422
423 if (count > HAL_USB_TIMEOUT)
424 {
425 return HAL_TIMEOUT;
426 }
427 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
428
429 return HAL_OK;
430 }
431
432 /**
433 * @brief USB_FlushRxFifo Flush Rx FIFO
434 * @param USBx Selected device
435 * @retval HAL status
436 */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)437 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
438 {
439 __IO uint32_t count = 0U;
440
441 /* Wait for AHB master IDLE state. */
442 do
443 {
444 count++;
445
446 if (count > HAL_USB_TIMEOUT)
447 {
448 return HAL_TIMEOUT;
449 }
450 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
451
452 /* Flush RX Fifo */
453 count = 0U;
454 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
455
456 do
457 {
458 count++;
459
460 if (count > HAL_USB_TIMEOUT)
461 {
462 return HAL_TIMEOUT;
463 }
464 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
465
466 return HAL_OK;
467 }
468
469 /**
470 * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
471 * depending the PHY type and the enumeration speed of the device.
472 * @param USBx Selected device
473 * @param speed device speed
474 * This parameter can be one of these values:
475 * @arg USB_OTG_SPEED_FULL: Full speed mode
476 * @retval Hal status
477 */
USB_SetDevSpeed(const USB_OTG_GlobalTypeDef * USBx,uint8_t speed)478 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
479 {
480 uint32_t USBx_BASE = (uint32_t)USBx;
481
482 USBx_DEVICE->DCFG |= speed;
483 return HAL_OK;
484 }
485
486 /**
487 * @brief USB_GetDevSpeed Return the Dev Speed
488 * @param USBx Selected device
489 * @retval speed device speed
490 * This parameter can be one of these values:
491 * @arg USBD_FS_SPEED: Full speed mode
492 */
USB_GetDevSpeed(const USB_OTG_GlobalTypeDef * USBx)493 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
494 {
495 uint32_t USBx_BASE = (uint32_t)USBx;
496 uint8_t speed;
497 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
498
499 if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
500 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
501 {
502 speed = USBD_FS_SPEED;
503 }
504 else
505 {
506 speed = 0xFU;
507 }
508
509 return speed;
510 }
511
512 /**
513 * @brief Activate and configure an endpoint
514 * @param USBx Selected device
515 * @param ep pointer to endpoint structure
516 * @retval HAL status
517 */
USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)518 HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
519 {
520 uint32_t USBx_BASE = (uint32_t)USBx;
521 uint32_t epnum = (uint32_t)ep->num;
522
523 if (ep->is_in == 1U)
524 {
525 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
526
527 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
528 {
529 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
530 ((uint32_t)ep->type << 18) | (epnum << 22) |
531 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
532 USB_OTG_DIEPCTL_USBAEP;
533 }
534 }
535 else
536 {
537 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
538
539 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
540 {
541 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
542 ((uint32_t)ep->type << 18) |
543 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
544 USB_OTG_DOEPCTL_USBAEP;
545 }
546 }
547 return HAL_OK;
548 }
549
550 /**
551 * @brief Activate and configure a dedicated endpoint
552 * @param USBx Selected device
553 * @param ep pointer to endpoint structure
554 * @retval HAL status
555 */
USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)556 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
557 {
558 uint32_t USBx_BASE = (uint32_t)USBx;
559 uint32_t epnum = (uint32_t)ep->num;
560
561 /* Read DEPCTLn register */
562 if (ep->is_in == 1U)
563 {
564 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
565 {
566 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
567 ((uint32_t)ep->type << 18) | (epnum << 22) |
568 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
569 USB_OTG_DIEPCTL_USBAEP;
570 }
571
572 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
573 }
574 else
575 {
576 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
577 {
578 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
579 ((uint32_t)ep->type << 18) | (epnum << 22) |
580 USB_OTG_DOEPCTL_USBAEP;
581 }
582
583 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
584 }
585
586 return HAL_OK;
587 }
588
589 /**
590 * @brief De-activate and de-initialize an endpoint
591 * @param USBx Selected device
592 * @param ep pointer to endpoint structure
593 * @retval HAL status
594 */
USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)595 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
596 {
597 uint32_t USBx_BASE = (uint32_t)USBx;
598 uint32_t epnum = (uint32_t)ep->num;
599
600 /* Read DEPCTLn register */
601 if (ep->is_in == 1U)
602 {
603 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
604 {
605 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
606 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
607 }
608
609 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
610 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
611 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
612 USB_OTG_DIEPCTL_MPSIZ |
613 USB_OTG_DIEPCTL_TXFNUM |
614 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
615 USB_OTG_DIEPCTL_EPTYP);
616 }
617 else
618 {
619 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
620 {
621 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
622 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
623 }
624
625 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
626 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
627 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
628 USB_OTG_DOEPCTL_MPSIZ |
629 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
630 USB_OTG_DOEPCTL_EPTYP);
631 }
632
633 return HAL_OK;
634 }
635
636 /**
637 * @brief De-activate and de-initialize a dedicated endpoint
638 * @param USBx Selected device
639 * @param ep pointer to endpoint structure
640 * @retval HAL status
641 */
USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)642 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
643 {
644 uint32_t USBx_BASE = (uint32_t)USBx;
645 uint32_t epnum = (uint32_t)ep->num;
646
647 /* Read DEPCTLn register */
648 if (ep->is_in == 1U)
649 {
650 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
651 {
652 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
653 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
654 }
655
656 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
657 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
658 }
659 else
660 {
661 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
662 {
663 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
664 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
665 }
666
667 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
668 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
669 }
670
671 return HAL_OK;
672 }
673
674 /**
675 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
676 * @param USBx Selected device
677 * @param ep pointer to endpoint structure
678 * @retval HAL status
679 */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)680 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
681 {
682 uint32_t USBx_BASE = (uint32_t)USBx;
683 uint32_t epnum = (uint32_t)ep->num;
684 uint16_t pktcnt;
685
686 /* IN endpoint */
687 if (ep->is_in == 1U)
688 {
689 /* Zero Length Packet? */
690 if (ep->xfer_len == 0U)
691 {
692 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
693 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
694 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
695 }
696 else
697 {
698 /* Program the transfer size and packet count
699 * as follows: xfersize = N * maxpacket +
700 * short_packet pktcnt = N + (short_packet
701 * exist ? 1 : 0)
702 */
703 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
704 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
705
706 if (epnum == 0U)
707 {
708 if (ep->xfer_len > ep->maxpacket)
709 {
710 ep->xfer_len = ep->maxpacket;
711 }
712
713 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
714 }
715 else
716 {
717 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
718 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
719
720 if (ep->type == EP_TYPE_ISOC)
721 {
722 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
723 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (pktcnt << 29));
724 }
725 }
726
727 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
728 }
729 /* EP enable, IN data in FIFO */
730 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
731
732 if (ep->type != EP_TYPE_ISOC)
733 {
734 /* Enable the Tx FIFO Empty Interrupt for this EP */
735 if (ep->xfer_len > 0U)
736 {
737 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
738 }
739 }
740 else
741 {
742 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
743 {
744 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
745 }
746 else
747 {
748 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
749 }
750
751 (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len);
752 }
753 }
754 else /* OUT endpoint */
755 {
756 /* Program the transfer size and packet count as follows:
757 * pktcnt = N
758 * xfersize = N * maxpacket
759 */
760 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
761 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
762
763 if (epnum == 0U)
764 {
765 if (ep->xfer_len > 0U)
766 {
767 ep->xfer_len = ep->maxpacket;
768 }
769
770 /* Store transfer size, for EP0 this is equal to endpoint max packet size */
771 ep->xfer_size = ep->maxpacket;
772
773 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
774 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
775 }
776 else
777 {
778 if (ep->xfer_len == 0U)
779 {
780 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
781 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
782 }
783 else
784 {
785 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
786 ep->xfer_size = ep->maxpacket * pktcnt;
787
788 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
789 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
790 }
791 }
792
793 if (ep->type == EP_TYPE_ISOC)
794 {
795 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
796 {
797 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
798 }
799 else
800 {
801 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
802 }
803 }
804 /* EP enable */
805 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
806 }
807
808 return HAL_OK;
809 }
810
811
812 /**
813 * @brief USB_EPStoptXfer Stop transfer on an EP
814 * @param USBx usb device instance
815 * @param ep pointer to endpoint structure
816 * @retval HAL status
817 */
USB_EPStopXfer(const USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)818 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
819 {
820 __IO uint32_t count = 0U;
821 HAL_StatusTypeDef ret = HAL_OK;
822 uint32_t USBx_BASE = (uint32_t)USBx;
823
824 /* IN endpoint */
825 if (ep->is_in == 1U)
826 {
827 /* EP enable, IN data in FIFO */
828 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
829 {
830 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
831 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
832
833 do
834 {
835 count++;
836
837 if (count > 10000U)
838 {
839 ret = HAL_ERROR;
840 break;
841 }
842 } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA);
843 }
844 }
845 else /* OUT endpoint */
846 {
847 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
848 {
849 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
850 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
851
852 do
853 {
854 count++;
855
856 if (count > 10000U)
857 {
858 ret = HAL_ERROR;
859 break;
860 }
861 } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA);
862 }
863 }
864
865 return ret;
866 }
867
868
869 /**
870 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
871 * with the EP/channel
872 * @param USBx Selected device
873 * @param src pointer to source buffer
874 * @param ch_ep_num endpoint or host channel number
875 * @param len Number of bytes to write
876 * @retval HAL status
877 */
USB_WritePacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len)878 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
879 uint8_t ch_ep_num, uint16_t len)
880 {
881 uint32_t USBx_BASE = (uint32_t)USBx;
882 uint8_t *pSrc = src;
883 uint32_t count32b;
884 uint32_t i;
885
886 count32b = ((uint32_t)len + 3U) / 4U;
887 for (i = 0U; i < count32b; i++)
888 {
889 USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
890 pSrc++;
891 pSrc++;
892 pSrc++;
893 pSrc++;
894 }
895
896 return HAL_OK;
897 }
898
899 /**
900 * @brief USB_ReadPacket : read a packet from the RX FIFO
901 * @param USBx Selected device
902 * @param dest source pointer
903 * @param len Number of bytes to read
904 * @retval pointer to destination buffer
905 */
USB_ReadPacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)906 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
907 {
908 uint32_t USBx_BASE = (uint32_t)USBx;
909 uint8_t *pDest = dest;
910 uint32_t pData;
911 uint32_t i;
912 uint32_t count32b = (uint32_t)len >> 2U;
913 uint16_t remaining_bytes = len % 4U;
914
915 for (i = 0U; i < count32b; i++)
916 {
917 __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
918 pDest++;
919 pDest++;
920 pDest++;
921 pDest++;
922 }
923
924 /* When Number of data is not word aligned, read the remaining byte */
925 if (remaining_bytes != 0U)
926 {
927 i = 0U;
928 __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
929
930 do
931 {
932 *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
933 i++;
934 pDest++;
935 remaining_bytes--;
936 } while (remaining_bytes != 0U);
937 }
938
939 return ((void *)pDest);
940 }
941
942 /**
943 * @brief USB_EPSetStall : set a stall condition over an EP
944 * @param USBx Selected device
945 * @param ep pointer to endpoint structure
946 * @retval HAL status
947 */
USB_EPSetStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)948 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
949 {
950 uint32_t USBx_BASE = (uint32_t)USBx;
951 uint32_t epnum = (uint32_t)ep->num;
952
953 if (ep->is_in == 1U)
954 {
955 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
956 {
957 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
958 }
959 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
960 }
961 else
962 {
963 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
964 {
965 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
966 }
967 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
968 }
969
970 return HAL_OK;
971 }
972
973 /**
974 * @brief USB_EPClearStall : Clear a stall condition over an EP
975 * @param USBx Selected device
976 * @param ep pointer to endpoint structure
977 * @retval HAL status
978 */
USB_EPClearStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)979 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
980 {
981 uint32_t USBx_BASE = (uint32_t)USBx;
982 uint32_t epnum = (uint32_t)ep->num;
983
984 if (ep->is_in == 1U)
985 {
986 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
987 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
988 {
989 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
990 }
991 }
992 else
993 {
994 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
995 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
996 {
997 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
998 }
999 }
1000 return HAL_OK;
1001 }
1002
1003 /**
1004 * @brief USB_StopDevice : Stop the usb device mode
1005 * @param USBx Selected device
1006 * @retval HAL status
1007 */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1008 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1009 {
1010 HAL_StatusTypeDef ret;
1011 uint32_t USBx_BASE = (uint32_t)USBx;
1012 uint32_t i;
1013
1014 /* Clear Pending interrupt */
1015 for (i = 0U; i < 15U; i++)
1016 {
1017 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1018 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1019 }
1020
1021 /* Clear interrupt masks */
1022 USBx_DEVICE->DIEPMSK = 0U;
1023 USBx_DEVICE->DOEPMSK = 0U;
1024 USBx_DEVICE->DAINTMSK = 0U;
1025
1026 /* Flush the FIFO */
1027 ret = USB_FlushRxFifo(USBx);
1028 if (ret != HAL_OK)
1029 {
1030 return ret;
1031 }
1032
1033 ret = USB_FlushTxFifo(USBx, 0x10U);
1034 if (ret != HAL_OK)
1035 {
1036 return ret;
1037 }
1038
1039 return ret;
1040 }
1041
1042 /**
1043 * @brief USB_SetDevAddress : Stop the usb device mode
1044 * @param USBx Selected device
1045 * @param address new device address to be assigned
1046 * This parameter can be a value from 0 to 255
1047 * @retval HAL status
1048 */
USB_SetDevAddress(const USB_OTG_GlobalTypeDef * USBx,uint8_t address)1049 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1050 {
1051 uint32_t USBx_BASE = (uint32_t)USBx;
1052
1053 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1054 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1055
1056 return HAL_OK;
1057 }
1058
1059 /**
1060 * @brief USB_DevConnect : Connect the USB device by enabling Rpu
1061 * @param USBx Selected device
1062 * @retval HAL status
1063 */
USB_DevConnect(const USB_OTG_GlobalTypeDef * USBx)1064 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1065 {
1066 uint32_t USBx_BASE = (uint32_t)USBx;
1067
1068 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1069 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1070
1071 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1072
1073 return HAL_OK;
1074 }
1075
1076 /**
1077 * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1078 * @param USBx Selected device
1079 * @retval HAL status
1080 */
USB_DevDisconnect(const USB_OTG_GlobalTypeDef * USBx)1081 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1082 {
1083 uint32_t USBx_BASE = (uint32_t)USBx;
1084
1085 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1086 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1087
1088 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1089
1090 return HAL_OK;
1091 }
1092
1093 /**
1094 * @brief USB_ReadInterrupts: return the global USB interrupt status
1095 * @param USBx Selected device
1096 * @retval USB Global Interrupt status
1097 */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef const * USBx)1098 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1099 {
1100 uint32_t tmpreg;
1101
1102 tmpreg = USBx->GINTSTS;
1103 tmpreg &= USBx->GINTMSK;
1104
1105 return tmpreg;
1106 }
1107
1108 /**
1109 * @brief USB_ReadChInterrupts: return USB channel interrupt status
1110 * @param USBx Selected device
1111 * @param chnum Channel number
1112 * @retval USB Channel Interrupt status
1113 */
USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef * USBx,uint8_t chnum)1114 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1115 {
1116 uint32_t USBx_BASE = (uint32_t)USBx;
1117 uint32_t tmpreg;
1118
1119 tmpreg = USBx_HC(chnum)->HCINT;
1120 tmpreg &= USBx_HC(chnum)->HCINTMSK;
1121
1122 return tmpreg;
1123 }
1124
1125 /**
1126 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1127 * @param USBx Selected device
1128 * @retval USB Device OUT EP interrupt status
1129 */
USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1130 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1131 {
1132 uint32_t USBx_BASE = (uint32_t)USBx;
1133 uint32_t tmpreg;
1134
1135 tmpreg = USBx_DEVICE->DAINT;
1136 tmpreg &= USBx_DEVICE->DAINTMSK;
1137
1138 return ((tmpreg & 0xffff0000U) >> 16);
1139 }
1140
1141 /**
1142 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1143 * @param USBx Selected device
1144 * @retval USB Device IN EP interrupt status
1145 */
USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1146 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1147 {
1148 uint32_t USBx_BASE = (uint32_t)USBx;
1149 uint32_t tmpreg;
1150
1151 tmpreg = USBx_DEVICE->DAINT;
1152 tmpreg &= USBx_DEVICE->DAINTMSK;
1153
1154 return ((tmpreg & 0xFFFFU));
1155 }
1156
1157 /**
1158 * @brief Returns Device OUT EP Interrupt register
1159 * @param USBx Selected device
1160 * @param epnum endpoint number
1161 * This parameter can be a value from 0 to 15
1162 * @retval Device OUT EP Interrupt register
1163 */
USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1164 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1165 {
1166 uint32_t USBx_BASE = (uint32_t)USBx;
1167 uint32_t tmpreg;
1168
1169 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1170 tmpreg &= USBx_DEVICE->DOEPMSK;
1171
1172 return tmpreg;
1173 }
1174
1175 /**
1176 * @brief Returns Device IN EP Interrupt register
1177 * @param USBx Selected device
1178 * @param epnum endpoint number
1179 * This parameter can be a value from 0 to 15
1180 * @retval Device IN EP Interrupt register
1181 */
USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1182 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1183 {
1184 uint32_t USBx_BASE = (uint32_t)USBx;
1185 uint32_t tmpreg;
1186 uint32_t msk;
1187 uint32_t emp;
1188
1189 msk = USBx_DEVICE->DIEPMSK;
1190 emp = USBx_DEVICE->DIEPEMPMSK;
1191 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1192 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1193
1194 return tmpreg;
1195 }
1196
1197 /**
1198 * @brief USB_ClearInterrupts: clear a USB interrupt
1199 * @param USBx Selected device
1200 * @param interrupt flag
1201 * @retval None
1202 */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1203 void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1204 {
1205 USBx->GINTSTS &= interrupt;
1206 }
1207
1208 /**
1209 * @brief Returns USB core mode
1210 * @param USBx Selected device
1211 * @retval return core mode : Host or Device
1212 * This parameter can be one of these values:
1213 * 0 : Host
1214 * 1 : Device
1215 */
USB_GetMode(const USB_OTG_GlobalTypeDef * USBx)1216 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1217 {
1218 return ((USBx->GINTSTS) & 0x1U);
1219 }
1220
1221 /**
1222 * @brief Activate EP0 for Setup transactions
1223 * @param USBx Selected device
1224 * @retval HAL status
1225 */
USB_ActivateSetup(const USB_OTG_GlobalTypeDef * USBx)1226 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1227 {
1228 uint32_t USBx_BASE = (uint32_t)USBx;
1229
1230 /* Set the MPS of the IN EP0 to 64 bytes */
1231 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1232
1233 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1234
1235 return HAL_OK;
1236 }
1237
1238 /**
1239 * @brief Prepare the EP0 to start the first control setup
1240 * @param USBx Selected device
1241 * @param psetup pointer to setup packet
1242 * @retval HAL status
1243 */
USB_EP0_OutStart(const USB_OTG_GlobalTypeDef * USBx,const uint8_t * psetup)1244 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, const uint8_t *psetup)
1245 {
1246 uint32_t USBx_BASE = (uint32_t)USBx;
1247 uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1248 UNUSED(psetup);
1249
1250 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1251 {
1252 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1253 {
1254 return HAL_OK;
1255 }
1256 }
1257
1258 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1259 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1260 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1261 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1262
1263 return HAL_OK;
1264 }
1265
1266 /**
1267 * @brief Reset the USB Core (needed after USB clock settings change)
1268 * @param USBx Selected device
1269 * @retval HAL status
1270 */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1271 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1272 {
1273 __IO uint32_t count = 0U;
1274
1275 /* Wait for AHB master IDLE state. */
1276 do
1277 {
1278 count++;
1279
1280 if (count > HAL_USB_TIMEOUT)
1281 {
1282 return HAL_TIMEOUT;
1283 }
1284 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1285
1286 /* Core Soft Reset */
1287 count = 0U;
1288 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1289
1290 do
1291 {
1292 count++;
1293
1294 if (count > HAL_USB_TIMEOUT)
1295 {
1296 return HAL_TIMEOUT;
1297 }
1298 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1299
1300 return HAL_OK;
1301 }
1302
1303 /**
1304 * @brief USB_HostInit : Initializes the USB OTG controller registers
1305 * for Host mode
1306 * @param USBx Selected device
1307 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
1308 * the configuration information for the specified USBx peripheral.
1309 * @retval HAL status
1310 */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1311 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1312 {
1313 HAL_StatusTypeDef ret = HAL_OK;
1314 uint32_t USBx_BASE = (uint32_t)USBx;
1315 uint32_t i;
1316
1317 /* Restart the Phy Clock */
1318 USBx_PCGCCTL = 0U;
1319
1320 /* Disable VBUS sensing */
1321 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1322
1323 /* Disable Battery chargin detector */
1324 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1325
1326 /* Set default Max speed support */
1327 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1328
1329 /* Make sure the FIFOs are flushed. */
1330 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1331 {
1332 ret = HAL_ERROR;
1333 }
1334
1335 if (USB_FlushRxFifo(USBx) != HAL_OK)
1336 {
1337 ret = HAL_ERROR;
1338 }
1339
1340 /* Clear all pending HC Interrupts */
1341 for (i = 0U; i < cfg.Host_channels; i++)
1342 {
1343 USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1344 USBx_HC(i)->HCINTMSK = 0U;
1345 }
1346
1347 /* Disable all interrupts. */
1348 USBx->GINTMSK = 0U;
1349
1350 /* Clear any pending interrupts */
1351 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1352
1353 /* set Rx FIFO size */
1354 USBx->GRXFSIZ = 0x80U;
1355 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1356 USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1357 /* Enable the common interrupts */
1358 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1359
1360 /* Enable interrupts matching to the Host mode ONLY */
1361 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
1362 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
1363 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1364
1365 return ret;
1366 }
1367
1368 /**
1369 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1370 * HCFG register on the PHY type and set the right frame interval
1371 * @param USBx Selected device
1372 * @param freq clock frequency
1373 * This parameter can be one of these values:
1374 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1375 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1376 * @retval HAL status
1377 */
USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1378 HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1379 {
1380 uint32_t USBx_BASE = (uint32_t)USBx;
1381
1382 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1383 USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1384
1385 if (freq == HCFG_48_MHZ)
1386 {
1387 USBx_HOST->HFIR = HFIR_48_MHZ;
1388 }
1389 else if (freq == HCFG_6_MHZ)
1390 {
1391 USBx_HOST->HFIR = HFIR_6_MHZ;
1392 }
1393 else
1394 {
1395 return HAL_ERROR;
1396 }
1397
1398 return HAL_OK;
1399 }
1400
1401 /**
1402 * @brief USB_OTG_ResetPort : Reset Host Port
1403 * @param USBx Selected device
1404 * @retval HAL status
1405 * @note (1)The application must wait at least 10 ms
1406 * before clearing the reset bit.
1407 */
USB_ResetPort(const USB_OTG_GlobalTypeDef * USBx)1408 HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
1409 {
1410 uint32_t USBx_BASE = (uint32_t)USBx;
1411
1412 __IO uint32_t hprt0 = 0U;
1413
1414 hprt0 = USBx_HPRT0;
1415
1416 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1417 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1418
1419 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1420 HAL_Delay(100U); /* See Note #1 */
1421 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1422 HAL_Delay(10U);
1423
1424 return HAL_OK;
1425 }
1426
1427 /**
1428 * @brief USB_DriveVbus : activate or de-activate vbus
1429 * @param state VBUS state
1430 * This parameter can be one of these values:
1431 * 0 : Deactivate VBUS
1432 * 1 : Activate VBUS
1433 * @retval HAL status
1434 */
USB_DriveVbus(const USB_OTG_GlobalTypeDef * USBx,uint8_t state)1435 HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1436 {
1437 uint32_t USBx_BASE = (uint32_t)USBx;
1438 __IO uint32_t hprt0 = 0U;
1439
1440 hprt0 = USBx_HPRT0;
1441
1442 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1443 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1444
1445 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1446 {
1447 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1448 }
1449 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1450 {
1451 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1452 }
1453 return HAL_OK;
1454 }
1455
1456 /**
1457 * @brief Return Host Core speed
1458 * @param USBx Selected device
1459 * @retval speed : Host speed
1460 * This parameter can be one of these values:
1461 * @arg HCD_SPEED_FULL: Full speed mode
1462 * @arg HCD_SPEED_LOW: Low speed mode
1463 */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef const * USBx)1464 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1465 {
1466 uint32_t USBx_BASE = (uint32_t)USBx;
1467 __IO uint32_t hprt0 = 0U;
1468
1469 hprt0 = USBx_HPRT0;
1470 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1471 }
1472
1473 /**
1474 * @brief Return Host Current Frame number
1475 * @param USBx Selected device
1476 * @retval current frame number
1477 */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const * USBx)1478 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1479 {
1480 uint32_t USBx_BASE = (uint32_t)USBx;
1481
1482 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1483 }
1484
1485 /**
1486 * @brief Initialize a host channel
1487 * @param USBx Selected device
1488 * @param ch_num Channel number
1489 * This parameter can be a value from 1 to 15
1490 * @param epnum Endpoint number
1491 * This parameter can be a value from 1 to 15
1492 * @param dev_address Current device address
1493 * This parameter can be a value from 0 to 255
1494 * @param speed Current device speed
1495 * This parameter can be one of these values:
1496 * @arg USB_OTG_SPEED_FULL: Full speed mode
1497 * @arg USB_OTG_SPEED_LOW: Low speed mode
1498 * @param ep_type Endpoint Type
1499 * This parameter can be one of these values:
1500 * @arg EP_TYPE_CTRL: Control type
1501 * @arg EP_TYPE_ISOC: Isochronous type
1502 * @arg EP_TYPE_BULK: Bulk type
1503 * @arg EP_TYPE_INTR: Interrupt type
1504 * @param mps Max Packet Size
1505 * This parameter can be a value from 0 to 32K
1506 * @retval HAL state
1507 */
USB_HC_Init(USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num,uint8_t epnum,uint8_t dev_address,uint8_t speed,uint8_t ep_type,uint16_t mps)1508 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1509 uint8_t epnum, uint8_t dev_address, uint8_t speed,
1510 uint8_t ep_type, uint16_t mps)
1511 {
1512 HAL_StatusTypeDef ret = HAL_OK;
1513 uint32_t USBx_BASE = (uint32_t)USBx;
1514 uint32_t HCcharEpDir;
1515 uint32_t HCcharLowSpeed;
1516 uint32_t HostCoreSpeed;
1517
1518 /* Clear old interrupt conditions for this host channel. */
1519 USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1520
1521 /* Enable channel interrupts required for this transfer. */
1522 switch (ep_type)
1523 {
1524 case EP_TYPE_CTRL:
1525 case EP_TYPE_BULK:
1526 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1527 USB_OTG_HCINTMSK_STALLM |
1528 USB_OTG_HCINTMSK_TXERRM |
1529 USB_OTG_HCINTMSK_DTERRM |
1530 USB_OTG_HCINTMSK_AHBERR |
1531 USB_OTG_HCINTMSK_NAKM;
1532
1533 if ((epnum & 0x80U) == 0x80U)
1534 {
1535 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1536 }
1537 break;
1538
1539 case EP_TYPE_INTR:
1540 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1541 USB_OTG_HCINTMSK_STALLM |
1542 USB_OTG_HCINTMSK_TXERRM |
1543 USB_OTG_HCINTMSK_DTERRM |
1544 USB_OTG_HCINTMSK_NAKM |
1545 USB_OTG_HCINTMSK_AHBERR |
1546 USB_OTG_HCINTMSK_FRMORM;
1547
1548 if ((epnum & 0x80U) == 0x80U)
1549 {
1550 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1551 }
1552
1553 break;
1554
1555 case EP_TYPE_ISOC:
1556 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1557 USB_OTG_HCINTMSK_ACKM |
1558 USB_OTG_HCINTMSK_AHBERR |
1559 USB_OTG_HCINTMSK_FRMORM;
1560
1561 if ((epnum & 0x80U) == 0x80U)
1562 {
1563 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1564 }
1565 break;
1566
1567 default:
1568 ret = HAL_ERROR;
1569 break;
1570 }
1571
1572 /* Enable host channel Halt interrupt */
1573 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1574
1575 /* Enable the top level host channel interrupt. */
1576 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1577
1578 /* Make sure host channel interrupts are enabled. */
1579 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1580
1581 /* Program the HCCHAR register */
1582 if ((epnum & 0x80U) == 0x80U)
1583 {
1584 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1585 }
1586 else
1587 {
1588 HCcharEpDir = 0U;
1589 }
1590
1591 HostCoreSpeed = USB_GetHostSpeed(USBx);
1592
1593 /* LS device plugged to HUB */
1594 if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1595 {
1596 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1597 }
1598 else
1599 {
1600 HCcharLowSpeed = 0U;
1601 }
1602
1603 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1604 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1605 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1606 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1607 USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1608
1609 if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1610 {
1611 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1612 }
1613
1614 return ret;
1615 }
1616
1617 /**
1618 * @brief Start a transfer over a host channel
1619 * @param USBx Selected device
1620 * @param hc pointer to host channel structure
1621 * @retval HAL state
1622 */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc)1623 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
1624 {
1625 uint32_t USBx_BASE = (uint32_t)USBx;
1626 uint32_t ch_num = (uint32_t)hc->ch_num;
1627 __IO uint32_t tmpreg;
1628 uint8_t is_oddframe;
1629 uint16_t len_words;
1630 uint16_t num_packets;
1631 uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1632
1633 /* Compute the expected number of packets associated to the transfer */
1634 if (hc->xfer_len > 0U)
1635 {
1636 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1637
1638 if (num_packets > max_hc_pkt_count)
1639 {
1640 num_packets = max_hc_pkt_count;
1641 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1642 }
1643 }
1644 else
1645 {
1646 num_packets = 1U;
1647 }
1648
1649 /*
1650 * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1651 * max_packet size.
1652 */
1653 if (hc->ep_is_in != 0U)
1654 {
1655 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1656 }
1657 else
1658 {
1659 hc->XferSize = hc->xfer_len;
1660 }
1661
1662 /* Initialize the HCTSIZn register */
1663 USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1664 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1665 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1666
1667 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1668 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1669 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1670
1671 /* Set host channel enable */
1672 tmpreg = USBx_HC(ch_num)->HCCHAR;
1673 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1674
1675 /* make sure to set the correct ep direction */
1676 if (hc->ep_is_in != 0U)
1677 {
1678 tmpreg |= USB_OTG_HCCHAR_EPDIR;
1679 }
1680 else
1681 {
1682 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1683 }
1684 tmpreg |= USB_OTG_HCCHAR_CHENA;
1685 USBx_HC(ch_num)->HCCHAR = tmpreg;
1686
1687 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1688 {
1689 switch (hc->ep_type)
1690 {
1691 /* Non periodic transfer */
1692 case EP_TYPE_CTRL:
1693 case EP_TYPE_BULK:
1694
1695 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1696
1697 /* check if there is enough space in FIFO space */
1698 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1699 {
1700 /* need to process data in nptxfempty interrupt */
1701 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1702 }
1703 break;
1704
1705 /* Periodic transfer */
1706 case EP_TYPE_INTR:
1707 case EP_TYPE_ISOC:
1708 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1709 /* check if there is enough space in FIFO space */
1710 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
1711 {
1712 /* need to process data in ptxfempty interrupt */
1713 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1714 }
1715 break;
1716
1717 default:
1718 break;
1719 }
1720
1721 /* Write packet into the Tx FIFO. */
1722 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len);
1723 }
1724
1725 return HAL_OK;
1726 }
1727
1728 /**
1729 * @brief Read all host channel interrupts status
1730 * @param USBx Selected device
1731 * @retval HAL state
1732 */
USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef * USBx)1733 uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1734 {
1735 uint32_t USBx_BASE = (uint32_t)USBx;
1736
1737 return ((USBx_HOST->HAINT) & 0xFFFFU);
1738 }
1739
1740 /**
1741 * @brief Halt a host channel
1742 * @param USBx Selected device
1743 * @param hc_num Host Channel number
1744 * This parameter can be a value from 1 to 15
1745 * @retval HAL state
1746 */
USB_HC_Halt(const USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)1747 HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
1748 {
1749 uint32_t USBx_BASE = (uint32_t)USBx;
1750 uint32_t hcnum = (uint32_t)hc_num;
1751 __IO uint32_t count = 0U;
1752 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
1753 uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
1754 uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
1755
1756 /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
1757 At the end of the next uframe/frame (in the worst case), the core generates a channel halted
1758 and disables the channel automatically. */
1759
1760 if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
1761 ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
1762 {
1763 return HAL_OK;
1764 }
1765
1766 /* Check for space in the request queue to issue the halt. */
1767 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
1768 {
1769 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1770
1771 if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
1772 {
1773 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
1774 {
1775 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1776 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1777 do
1778 {
1779 count++;
1780
1781 if (count > 1000U)
1782 {
1783 break;
1784 }
1785 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1786 }
1787 else
1788 {
1789 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1790 }
1791 }
1792 else
1793 {
1794 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1795 }
1796 }
1797 else
1798 {
1799 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1800
1801 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
1802 {
1803 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1804 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1805 do
1806 {
1807 count++;
1808
1809 if (count > 1000U)
1810 {
1811 break;
1812 }
1813 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1814 }
1815 else
1816 {
1817 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1818 }
1819 }
1820
1821 return HAL_OK;
1822 }
1823
1824 /**
1825 * @brief Initiate Do Ping protocol
1826 * @param USBx Selected device
1827 * @param hc_num Host Channel number
1828 * This parameter can be a value from 1 to 15
1829 * @retval HAL state
1830 */
USB_DoPing(const USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)1831 HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
1832 {
1833 uint32_t USBx_BASE = (uint32_t)USBx;
1834 uint32_t chnum = (uint32_t)ch_num;
1835 uint32_t num_packets = 1U;
1836 uint32_t tmpreg;
1837
1838 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1839 USB_OTG_HCTSIZ_DOPING;
1840
1841 /* Set host channel enable */
1842 tmpreg = USBx_HC(chnum)->HCCHAR;
1843 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1844 tmpreg |= USB_OTG_HCCHAR_CHENA;
1845 USBx_HC(chnum)->HCCHAR = tmpreg;
1846
1847 return HAL_OK;
1848 }
1849
1850 /**
1851 * @brief Stop Host Core
1852 * @param USBx Selected device
1853 * @retval HAL state
1854 */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)1855 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1856 {
1857 HAL_StatusTypeDef ret = HAL_OK;
1858 uint32_t USBx_BASE = (uint32_t)USBx;
1859 __IO uint32_t count = 0U;
1860 uint32_t value;
1861 uint32_t i;
1862
1863 (void)USB_DisableGlobalInt(USBx);
1864
1865 /* Flush USB FIFO */
1866 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1867 {
1868 ret = HAL_ERROR;
1869 }
1870
1871 if (USB_FlushRxFifo(USBx) != HAL_OK)
1872 {
1873 ret = HAL_ERROR;
1874 }
1875
1876 /* Flush out any leftover queued requests. */
1877 for (i = 0U; i <= 15U; i++)
1878 {
1879 value = USBx_HC(i)->HCCHAR;
1880 value |= USB_OTG_HCCHAR_CHDIS;
1881 value &= ~USB_OTG_HCCHAR_CHENA;
1882 value &= ~USB_OTG_HCCHAR_EPDIR;
1883 USBx_HC(i)->HCCHAR = value;
1884 }
1885
1886 /* Halt all channels to put them into a known state. */
1887 for (i = 0U; i <= 15U; i++)
1888 {
1889 value = USBx_HC(i)->HCCHAR;
1890 value |= USB_OTG_HCCHAR_CHDIS;
1891 value |= USB_OTG_HCCHAR_CHENA;
1892 value &= ~USB_OTG_HCCHAR_EPDIR;
1893 USBx_HC(i)->HCCHAR = value;
1894
1895 do
1896 {
1897 count++;
1898
1899 if (count > 1000U)
1900 {
1901 break;
1902 }
1903 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1904 }
1905
1906 /* Clear any pending Host interrupts */
1907 USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
1908 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1909
1910 (void)USB_EnableGlobalInt(USBx);
1911
1912 return ret;
1913 }
1914
1915 /**
1916 * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
1917 * @param USBx Selected device
1918 * @retval HAL status
1919 */
USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)1920 HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
1921 {
1922 uint32_t USBx_BASE = (uint32_t)USBx;
1923
1924 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1925 {
1926 /* active Remote wakeup signalling */
1927 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
1928 }
1929
1930 return HAL_OK;
1931 }
1932
1933 /**
1934 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
1935 * @param USBx Selected device
1936 * @retval HAL status
1937 */
USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)1938 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
1939 {
1940 uint32_t USBx_BASE = (uint32_t)USBx;
1941
1942 /* active Remote wakeup signalling */
1943 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
1944
1945 return HAL_OK;
1946 }
1947 #endif /* defined (USB_OTG_FS) */
1948
1949 #if defined (USB)
1950 /**
1951 * @brief Initializes the USB Core
1952 * @param USBx USB Instance
1953 * @param cfg pointer to a USB_CfgTypeDef structure that contains
1954 * the configuration information for the specified USBx peripheral.
1955 * @retval HAL status
1956 */
USB_CoreInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)1957 HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
1958 {
1959 /* Prevent unused argument(s) compilation warning */
1960 UNUSED(USBx);
1961 UNUSED(cfg);
1962
1963 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
1964 only by USB OTG FS peripheral.
1965 - This function is added to ensure compatibility across platforms.
1966 */
1967
1968 return HAL_OK;
1969 }
1970
1971 /**
1972 * @brief USB_EnableGlobalInt
1973 * Enables the controller's Global Int in the AHB Config reg
1974 * @param USBx Selected device
1975 * @retval HAL status
1976 */
USB_EnableGlobalInt(USB_TypeDef * USBx)1977 HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
1978 {
1979 uint32_t winterruptmask;
1980
1981 /* Clear pending interrupts */
1982 USBx->ISTR = 0U;
1983
1984 /* Set winterruptmask variable */
1985 winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
1986 USB_CNTR_SUSPM | USB_CNTR_ERRM |
1987 USB_CNTR_SOFM | USB_CNTR_ESOFM |
1988 USB_CNTR_RESETM | USB_CNTR_L1REQM;
1989
1990 /* Set interrupt mask */
1991 USBx->CNTR = (uint16_t)winterruptmask;
1992
1993 return HAL_OK;
1994 }
1995
1996 /**
1997 * @brief USB_DisableGlobalInt
1998 * Disable the controller's Global Int in the AHB Config reg
1999 * @param USBx Selected device
2000 * @retval HAL status
2001 */
USB_DisableGlobalInt(USB_TypeDef * USBx)2002 HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
2003 {
2004 uint32_t winterruptmask;
2005
2006 /* Set winterruptmask variable */
2007 winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
2008 USB_CNTR_SUSPM | USB_CNTR_ERRM |
2009 USB_CNTR_SOFM | USB_CNTR_ESOFM |
2010 USB_CNTR_RESETM | USB_CNTR_L1REQM;
2011
2012 /* Clear interrupt mask */
2013 USBx->CNTR &= (uint16_t)(~winterruptmask);
2014
2015 return HAL_OK;
2016 }
2017
2018 /**
2019 * @brief USB_SetCurrentMode Set functional mode
2020 * @param USBx Selected device
2021 * @param mode current core mode
2022 * This parameter can be one of the these values:
2023 * @arg USB_DEVICE_MODE Peripheral mode
2024 * @retval HAL status
2025 */
USB_SetCurrentMode(USB_TypeDef * USBx,USB_ModeTypeDef mode)2026 HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
2027 {
2028 /* Prevent unused argument(s) compilation warning */
2029 UNUSED(USBx);
2030 UNUSED(mode);
2031
2032 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2033 only by USB OTG FS peripheral.
2034 - This function is added to ensure compatibility across platforms.
2035 */
2036 return HAL_OK;
2037 }
2038
2039 /**
2040 * @brief USB_DevInit Initializes the USB controller registers
2041 * for device mode
2042 * @param USBx Selected device
2043 * @param cfg pointer to a USB_CfgTypeDef structure that contains
2044 * the configuration information for the specified USBx peripheral.
2045 * @retval HAL status
2046 */
USB_DevInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)2047 HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
2048 {
2049 /* Prevent unused argument(s) compilation warning */
2050 UNUSED(cfg);
2051
2052 /* Init Device */
2053 /* CNTR_FRES = 1 */
2054 USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2055
2056 /* CNTR_FRES = 0 */
2057 USBx->CNTR = 0U;
2058
2059 /* Clear pending interrupts */
2060 USBx->ISTR = 0U;
2061
2062 /*Set Btable Address*/
2063 USBx->BTABLE = BTABLE_ADDRESS;
2064
2065 return HAL_OK;
2066 }
2067
2068 /**
2069 * @brief USB_FlushTxFifo : Flush a Tx FIFO
2070 * @param USBx : Selected device
2071 * @param num : FIFO number
2072 * This parameter can be a value from 1 to 15
2073 15 means Flush all Tx FIFOs
2074 * @retval HAL status
2075 */
USB_FlushTxFifo(USB_TypeDef const * USBx,uint32_t num)2076 HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef const *USBx, uint32_t num)
2077 {
2078 /* Prevent unused argument(s) compilation warning */
2079 UNUSED(USBx);
2080 UNUSED(num);
2081
2082 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2083 only by USB OTG FS peripheral.
2084 - This function is added to ensure compatibility across platforms.
2085 */
2086
2087 return HAL_OK;
2088 }
2089
2090 /**
2091 * @brief USB_FlushRxFifo : Flush Rx FIFO
2092 * @param USBx : Selected device
2093 * @retval HAL status
2094 */
USB_FlushRxFifo(USB_TypeDef const * USBx)2095 HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef const *USBx)
2096 {
2097 /* Prevent unused argument(s) compilation warning */
2098 UNUSED(USBx);
2099
2100 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2101 only by USB OTG FS peripheral.
2102 - This function is added to ensure compatibility across platforms.
2103 */
2104
2105 return HAL_OK;
2106 }
2107
2108
2109 #if defined (HAL_PCD_MODULE_ENABLED)
2110 /**
2111 * @brief Activate and configure an endpoint
2112 * @param USBx Selected device
2113 * @param ep pointer to endpoint structure
2114 * @retval HAL status
2115 */
USB_ActivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)2116 HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2117 {
2118 HAL_StatusTypeDef ret = HAL_OK;
2119 uint16_t wEpRegVal;
2120
2121 wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
2122
2123 /* initialize Endpoint */
2124 switch (ep->type)
2125 {
2126 case EP_TYPE_CTRL:
2127 wEpRegVal |= USB_EP_CONTROL;
2128 break;
2129
2130 case EP_TYPE_BULK:
2131 wEpRegVal |= USB_EP_BULK;
2132 break;
2133
2134 case EP_TYPE_INTR:
2135 wEpRegVal |= USB_EP_INTERRUPT;
2136 break;
2137
2138 case EP_TYPE_ISOC:
2139 wEpRegVal |= USB_EP_ISOCHRONOUS;
2140 break;
2141
2142 default:
2143 ret = HAL_ERROR;
2144 break;
2145 }
2146
2147 PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
2148
2149 PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
2150
2151 if (ep->doublebuffer == 0U)
2152 {
2153 if (ep->is_in != 0U)
2154 {
2155 /*Set the endpoint Transmit buffer address */
2156 PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
2157 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2158
2159 if (ep->type != EP_TYPE_ISOC)
2160 {
2161 /* Configure NAK status for the Endpoint */
2162 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2163 }
2164 else
2165 {
2166 /* Configure TX Endpoint to disabled state */
2167 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2168 }
2169 }
2170 else
2171 {
2172 /* Set the endpoint Receive buffer address */
2173 PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
2174
2175 /* Set the endpoint Receive buffer counter */
2176 PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
2177 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2178
2179 if (ep->num == 0U)
2180 {
2181 /* Configure VALID status for EP0 */
2182 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2183 }
2184 else
2185 {
2186 /* Configure NAK status for OUT Endpoint */
2187 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2188 }
2189 }
2190 }
2191 #if (USE_USB_DOUBLE_BUFFER == 1U)
2192 /* Double Buffer */
2193 else
2194 {
2195 if (ep->type == EP_TYPE_BULK)
2196 {
2197 /* Set bulk endpoint as double buffered */
2198 PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2199 }
2200 else
2201 {
2202 /* Set the ISOC endpoint in double buffer mode */
2203 PCD_CLEAR_EP_KIND(USBx, ep->num);
2204 }
2205
2206 /* Set buffer address for double buffered mode */
2207 PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
2208
2209 if (ep->is_in == 0U)
2210 {
2211 /* Clear the data toggle bits for the endpoint IN/OUT */
2212 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2213 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2214
2215 /* Set endpoint RX count */
2216 PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
2217
2218 /* Set endpoint RX to valid state */
2219 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2220 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2221 }
2222 else
2223 {
2224 /* Clear the data toggle bits for the endpoint IN/OUT */
2225 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2226 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2227
2228 if (ep->type != EP_TYPE_ISOC)
2229 {
2230 /* Configure NAK status for the Endpoint */
2231 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2232 }
2233 else
2234 {
2235 /* Configure TX Endpoint to disabled state */
2236 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2237 }
2238
2239 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2240 }
2241 }
2242 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2243
2244 return ret;
2245 }
2246
2247 /**
2248 * @brief De-activate and de-initialize an endpoint
2249 * @param USBx Selected device
2250 * @param ep pointer to endpoint structure
2251 * @retval HAL status
2252 */
USB_DeactivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)2253 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2254 {
2255 if (ep->doublebuffer == 0U)
2256 {
2257 if (ep->is_in != 0U)
2258 {
2259 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2260
2261 /* Configure DISABLE status for the Endpoint */
2262 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2263 }
2264
2265 else
2266 {
2267 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2268
2269 /* Configure DISABLE status for the Endpoint */
2270 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2271 }
2272 }
2273 #if (USE_USB_DOUBLE_BUFFER == 1U)
2274 /* Double Buffer */
2275 else
2276 {
2277 if (ep->is_in == 0U)
2278 {
2279 /* Clear the data toggle bits for the endpoint IN/OUT*/
2280 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2281 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2282
2283 /* Reset value of the data toggle bits for the endpoint out*/
2284 PCD_TX_DTOG(USBx, ep->num);
2285
2286 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2287 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2288 }
2289 else
2290 {
2291 /* Clear the data toggle bits for the endpoint IN/OUT*/
2292 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2293 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2294 PCD_RX_DTOG(USBx, ep->num);
2295
2296 /* Configure DISABLE status for the Endpoint*/
2297 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2298 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2299 }
2300 }
2301 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2302
2303 return HAL_OK;
2304 }
2305
2306 /**
2307 * @brief USB_EPStartXfer setup and starts a transfer over an EP
2308 * @param USBx Selected device
2309 * @param ep pointer to endpoint structure
2310 * @retval HAL status
2311 */
USB_EPStartXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)2312 HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2313 {
2314 uint32_t len;
2315 #if (USE_USB_DOUBLE_BUFFER == 1U)
2316 uint16_t pmabuffer;
2317 uint16_t wEPVal;
2318 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2319
2320 /* IN endpoint */
2321 if (ep->is_in == 1U)
2322 {
2323 /* Multi packet transfer */
2324 if (ep->xfer_len > ep->maxpacket)
2325 {
2326 len = ep->maxpacket;
2327 }
2328 else
2329 {
2330 len = ep->xfer_len;
2331 }
2332
2333 /* configure and validate Tx endpoint */
2334 if (ep->doublebuffer == 0U)
2335 {
2336 USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
2337 PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2338 }
2339 #if (USE_USB_DOUBLE_BUFFER == 1U)
2340 else
2341 {
2342 /* double buffer bulk management */
2343 if (ep->type == EP_TYPE_BULK)
2344 {
2345 if (ep->xfer_len_db > ep->maxpacket)
2346 {
2347 /* enable double buffer */
2348 PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2349
2350 /* each Time to write in PMA xfer_len_db will */
2351 ep->xfer_len_db -= len;
2352
2353 /* Fill the two first buffer in the Buffer0 & Buffer1 */
2354 if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2355 {
2356 /* Set the Double buffer counter for pmabuffer1 */
2357 PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2358 pmabuffer = ep->pmaaddr1;
2359
2360 /* Write the user buffer to USB PMA */
2361 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2362 ep->xfer_buff += len;
2363
2364 if (ep->xfer_len_db > ep->maxpacket)
2365 {
2366 ep->xfer_len_db -= len;
2367 }
2368 else
2369 {
2370 len = ep->xfer_len_db;
2371 ep->xfer_len_db = 0U;
2372 }
2373
2374 /* Set the Double buffer counter for pmabuffer0 */
2375 PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2376 pmabuffer = ep->pmaaddr0;
2377
2378 /* Write the user buffer to USB PMA */
2379 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2380 }
2381 else
2382 {
2383 /* Set the Double buffer counter for pmabuffer0 */
2384 PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2385 pmabuffer = ep->pmaaddr0;
2386
2387 /* Write the user buffer to USB PMA */
2388 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2389 ep->xfer_buff += len;
2390
2391 if (ep->xfer_len_db > ep->maxpacket)
2392 {
2393 ep->xfer_len_db -= len;
2394 }
2395 else
2396 {
2397 len = ep->xfer_len_db;
2398 ep->xfer_len_db = 0U;
2399 }
2400
2401 /* Set the Double buffer counter for pmabuffer1 */
2402 PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2403 pmabuffer = ep->pmaaddr1;
2404
2405 /* Write the user buffer to USB PMA */
2406 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2407 }
2408 }
2409 /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
2410 else
2411 {
2412 len = ep->xfer_len_db;
2413
2414 /* disable double buffer mode for Bulk endpoint */
2415 PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
2416
2417 /* Set Tx count with nbre of byte to be transmitted */
2418 PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2419 pmabuffer = ep->pmaaddr0;
2420
2421 /* Write the user buffer to USB PMA */
2422 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2423 }
2424 }
2425 else /* Manage isochronous double buffer IN mode */
2426 {
2427 /* Each Time to write in PMA xfer_len_db will */
2428 ep->xfer_len_db -= len;
2429
2430 /* Fill the data buffer */
2431 if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2432 {
2433 /* Set the Double buffer counter for pmabuffer1 */
2434 PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2435 pmabuffer = ep->pmaaddr1;
2436
2437 /* Write the user buffer to USB PMA */
2438 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2439 }
2440 else
2441 {
2442 /* Set the Double buffer counter for pmabuffer0 */
2443 PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2444 pmabuffer = ep->pmaaddr0;
2445
2446 /* Write the user buffer to USB PMA */
2447 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2448 }
2449 }
2450 }
2451 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2452
2453 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
2454 }
2455 else /* OUT endpoint */
2456 {
2457 if (ep->doublebuffer == 0U)
2458 {
2459 if ((ep->xfer_len == 0U) && (ep->type == EP_TYPE_CTRL))
2460 {
2461 /* This is a status out stage set the OUT_STATUS */
2462 PCD_SET_OUT_STATUS(USBx, ep->num);
2463 }
2464 else
2465 {
2466 PCD_CLEAR_OUT_STATUS(USBx, ep->num);
2467 }
2468
2469 /* Multi packet transfer */
2470 if (ep->xfer_len > ep->maxpacket)
2471 {
2472 ep->xfer_len -= ep->maxpacket;
2473 }
2474 else
2475 {
2476 ep->xfer_len = 0U;
2477 }
2478 }
2479 #if (USE_USB_DOUBLE_BUFFER == 1U)
2480 else
2481 {
2482 /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
2483 /* Set the Double buffer counter */
2484 if (ep->type == EP_TYPE_BULK)
2485 {
2486 /* Coming from ISR */
2487 if (ep->xfer_count != 0U)
2488 {
2489 /* Update last value to check if there is blocking state */
2490 wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
2491
2492 /* Blocking State */
2493 if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
2494 (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
2495 {
2496 PCD_FREE_USER_BUFFER(USBx, ep->num, 0U);
2497 }
2498 }
2499 }
2500 /* iso out double */
2501 else if (ep->type == EP_TYPE_ISOC)
2502 {
2503 /* Only single packet transfer supported in FS */
2504 ep->xfer_len = 0U;
2505 }
2506 else
2507 {
2508 return HAL_ERROR;
2509 }
2510 }
2511 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2512
2513 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2514 }
2515
2516 return HAL_OK;
2517 }
2518
2519
2520 /**
2521 * @brief USB_EPSetStall set a stall condition over an EP
2522 * @param USBx Selected device
2523 * @param ep pointer to endpoint structure
2524 * @retval HAL status
2525 */
USB_EPSetStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)2526 HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2527 {
2528 if (ep->is_in != 0U)
2529 {
2530 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
2531 }
2532 else
2533 {
2534 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
2535 }
2536
2537 return HAL_OK;
2538 }
2539
2540 /**
2541 * @brief USB_EPClearStall Clear a stall condition over an EP
2542 * @param USBx Selected device
2543 * @param ep pointer to endpoint structure
2544 * @retval HAL status
2545 */
USB_EPClearStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)2546 HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2547 {
2548 if (ep->is_in != 0U)
2549 {
2550 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2551
2552 if (ep->type != EP_TYPE_ISOC)
2553 {
2554 /* Configure NAK status for the Endpoint */
2555 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2556 }
2557 }
2558 else
2559 {
2560 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2561
2562 /* Configure VALID status for the Endpoint */
2563 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2564 }
2565
2566 return HAL_OK;
2567 }
2568
2569 /**
2570 * @brief USB_EPStoptXfer Stop transfer on an EP
2571 * @param USBx usb device instance
2572 * @param ep pointer to endpoint structure
2573 * @retval HAL status
2574 */
USB_EPStopXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)2575 HAL_StatusTypeDef USB_EPStopXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2576 {
2577 /* IN endpoint */
2578 if (ep->is_in == 1U)
2579 {
2580 if (ep->doublebuffer == 0U)
2581 {
2582 if (ep->type != EP_TYPE_ISOC)
2583 {
2584 /* Configure NAK status for the Endpoint */
2585 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2586 }
2587 else
2588 {
2589 /* Configure TX Endpoint to disabled state */
2590 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2591 }
2592 }
2593 }
2594 else /* OUT endpoint */
2595 {
2596 if (ep->doublebuffer == 0U)
2597 {
2598 if (ep->type != EP_TYPE_ISOC)
2599 {
2600 /* Configure NAK status for the Endpoint */
2601 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2602 }
2603 else
2604 {
2605 /* Configure RX Endpoint to disabled state */
2606 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2607 }
2608 }
2609 }
2610
2611 return HAL_OK;
2612 }
2613 #endif /* defined (HAL_PCD_MODULE_ENABLED) */
2614
2615 /**
2616 * @brief USB_StopDevice Stop the usb device mode
2617 * @param USBx Selected device
2618 * @retval HAL status
2619 */
USB_StopDevice(USB_TypeDef * USBx)2620 HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
2621 {
2622 /* disable all interrupts and force USB reset */
2623 USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2624
2625 /* clear interrupt status register */
2626 USBx->ISTR = 0U;
2627
2628 /* switch-off device */
2629 USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
2630
2631 return HAL_OK;
2632 }
2633
2634 /**
2635 * @brief USB_SetDevAddress Stop the usb device mode
2636 * @param USBx Selected device
2637 * @param address new device address to be assigned
2638 * This parameter can be a value from 0 to 255
2639 * @retval HAL status
2640 */
USB_SetDevAddress(USB_TypeDef * USBx,uint8_t address)2641 HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
2642 {
2643 if (address == 0U)
2644 {
2645 /* set device address and enable function */
2646 USBx->DADDR = (uint16_t)USB_DADDR_EF;
2647 }
2648
2649 return HAL_OK;
2650 }
2651
2652 /**
2653 * @brief USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
2654 * @param USBx Selected device
2655 * @retval HAL status
2656 */
USB_DevConnect(USB_TypeDef * USBx)2657 HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx)
2658 {
2659 /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */
2660 USBx->BCDR |= (uint16_t)USB_BCDR_DPPU;
2661
2662 return HAL_OK;
2663 }
2664
2665 /**
2666 * @brief USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
2667 * @param USBx Selected device
2668 * @retval HAL status
2669 */
USB_DevDisconnect(USB_TypeDef * USBx)2670 HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx)
2671 {
2672 /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */
2673 USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU));
2674
2675 return HAL_OK;
2676 }
2677
2678 /**
2679 * @brief USB_ReadInterrupts return the global USB interrupt status
2680 * @param USBx Selected device
2681 * @retval USB Global Interrupt status
2682 */
USB_ReadInterrupts(USB_TypeDef const * USBx)2683 uint32_t USB_ReadInterrupts(USB_TypeDef const *USBx)
2684 {
2685 uint32_t tmpreg;
2686
2687 tmpreg = USBx->ISTR;
2688 return tmpreg;
2689 }
2690
2691 /**
2692 * @brief USB_ReadDevAllOutEpInterrupt return the USB device OUT endpoints interrupt status
2693 * @param USBx Selected device
2694 * @retval HAL status
2695 */
USB_ReadDevAllOutEpInterrupt(USB_TypeDef * USBx)2696 uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx)
2697 {
2698 /* Prevent unused argument(s) compilation warning */
2699 UNUSED(USBx);
2700 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2701 only by USB OTG FS peripheral.
2702 - This function is added to ensure compatibility across platforms.
2703 */
2704 return (0);
2705 }
2706
2707 /**
2708 * @brief USB_ReadDevAllInEpInterrupt return the USB device IN endpoints interrupt status
2709 * @param USBx Selected device
2710 * @retval HAL status
2711 */
USB_ReadDevAllInEpInterrupt(USB_TypeDef * USBx)2712 uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx)
2713 {
2714 /* Prevent unused argument(s) compilation warning */
2715 UNUSED(USBx);
2716 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2717 only by USB OTG FS peripheral.
2718 - This function is added to ensure compatibility across platforms.
2719 */
2720 return (0);
2721 }
2722
2723 /**
2724 * @brief Returns Device OUT EP Interrupt register
2725 * @param USBx Selected device
2726 * @param epnum endpoint number
2727 * This parameter can be a value from 0 to 15
2728 * @retval Device OUT EP Interrupt register
2729 */
USB_ReadDevOutEPInterrupt(USB_TypeDef * USBx,uint8_t epnum)2730 uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2731 {
2732 /* Prevent unused argument(s) compilation warning */
2733 UNUSED(USBx);
2734 UNUSED(epnum);
2735 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2736 only by USB OTG FS peripheral.
2737 - This function is added to ensure compatibility across platforms.
2738 */
2739 return (0);
2740 }
2741
2742 /**
2743 * @brief Returns Device IN EP Interrupt register
2744 * @param USBx Selected device
2745 * @param epnum endpoint number
2746 * This parameter can be a value from 0 to 15
2747 * @retval Device IN EP Interrupt register
2748 */
USB_ReadDevInEPInterrupt(USB_TypeDef * USBx,uint8_t epnum)2749 uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2750 {
2751 /* Prevent unused argument(s) compilation warning */
2752 UNUSED(USBx);
2753 UNUSED(epnum);
2754 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2755 only by USB OTG FS peripheral.
2756 - This function is added to ensure compatibility across platforms.
2757 */
2758 return (0);
2759 }
2760
2761 /**
2762 * @brief USB_ClearInterrupts: clear a USB interrupt
2763 * @param USBx Selected device
2764 * @param interrupt flag
2765 * @retval None
2766 */
USB_ClearInterrupts(USB_TypeDef * USBx,uint32_t interrupt)2767 void USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt)
2768 {
2769 /* Prevent unused argument(s) compilation warning */
2770 UNUSED(USBx);
2771 UNUSED(interrupt);
2772 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2773 only by USB OTG FS peripheral.
2774 - This function is added to ensure compatibility across platforms.
2775 */
2776 }
2777
2778 /**
2779 * @brief Prepare the EP0 to start the first control setup
2780 * @param USBx Selected device
2781 * @param psetup pointer to setup packet
2782 * @retval HAL status
2783 */
USB_EP0_OutStart(USB_TypeDef * USBx,uint8_t * psetup)2784 HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
2785 {
2786 /* Prevent unused argument(s) compilation warning */
2787 UNUSED(USBx);
2788 UNUSED(psetup);
2789 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2790 only by USB OTG FS peripheral.
2791 - This function is added to ensure compatibility across platforms.
2792 */
2793 return HAL_OK;
2794 }
2795
2796 /**
2797 * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
2798 * @param USBx Selected device
2799 * @retval HAL status
2800 */
USB_ActivateRemoteWakeup(USB_TypeDef * USBx)2801 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
2802 {
2803 USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
2804
2805 return HAL_OK;
2806 }
2807
2808 /**
2809 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2810 * @param USBx Selected device
2811 * @retval HAL status
2812 */
USB_DeActivateRemoteWakeup(USB_TypeDef * USBx)2813 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
2814 {
2815 USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
2816
2817 return HAL_OK;
2818 }
2819
2820 /**
2821 * @brief Copy a buffer from user memory area to packet memory area (PMA)
2822 * @param USBx USB peripheral instance register address.
2823 * @param pbUsrBuf pointer to user memory area.
2824 * @param wPMABufAddr address into PMA.
2825 * @param wNBytes no. of bytes to be copied.
2826 * @retval None
2827 */
USB_WritePMA(USB_TypeDef const * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)2828 void USB_WritePMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2829 {
2830 uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
2831 uint32_t BaseAddr = (uint32_t)USBx;
2832 uint32_t count;
2833 uint16_t WrVal;
2834 __IO uint16_t *pdwVal;
2835 uint8_t *pBuf = pbUsrBuf;
2836
2837 pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2838
2839 for (count = n; count != 0U; count--)
2840 {
2841 WrVal = pBuf[0];
2842 WrVal |= (uint16_t)pBuf[1] << 8;
2843 *pdwVal = (WrVal & 0xFFFFU);
2844 pdwVal++;
2845
2846 #if PMA_ACCESS > 1U
2847 pdwVal++;
2848 #endif /* PMA_ACCESS */
2849
2850 pBuf++;
2851 pBuf++;
2852 }
2853 }
2854
2855 /**
2856 * @brief Copy data from packet memory area (PMA) to user memory buffer
2857 * @param USBx USB peripheral instance register address.
2858 * @param pbUsrBuf pointer to user memory area.
2859 * @param wPMABufAddr address into PMA.
2860 * @param wNBytes no. of bytes to be copied.
2861 * @retval None
2862 */
USB_ReadPMA(USB_TypeDef const * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)2863 void USB_ReadPMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2864 {
2865 uint32_t n = (uint32_t)wNBytes >> 1;
2866 uint32_t BaseAddr = (uint32_t)USBx;
2867 uint32_t count;
2868 uint32_t RdVal;
2869 __IO uint16_t *pdwVal;
2870 uint8_t *pBuf = pbUsrBuf;
2871
2872 pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2873
2874 for (count = n; count != 0U; count--)
2875 {
2876 RdVal = *(__IO uint16_t *)pdwVal;
2877 pdwVal++;
2878 *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2879 pBuf++;
2880 *pBuf = (uint8_t)((RdVal >> 8) & 0xFFU);
2881 pBuf++;
2882
2883 #if PMA_ACCESS > 1U
2884 pdwVal++;
2885 #endif /* PMA_ACCESS */
2886 }
2887
2888 if ((wNBytes % 2U) != 0U)
2889 {
2890 RdVal = *pdwVal;
2891 *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2892 }
2893 }
2894
2895 #endif /* defined (USB) */
2896 /**
2897 * @}
2898 */
2899
2900 /**
2901 * @}
2902 */
2903 #endif /* defined (USB) || defined (USB_OTG_FS) */
2904 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2905
2906 /**
2907 * @}
2908 */
2909