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