1 /**
2 ******************************************************************************
3 * @file stm32h7rsxx_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) 2022 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 "stm32h7rsxx_hal.h"
43
44 /** @addtogroup STM32H7RSxx_LL_USB_DRIVER
45 * @{
46 */
47
48 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
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) || defined (USB_OTG_HS)
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 #if defined (USB_OTG_HS)
87 if (USBx == USB_OTG_HS)
88 {
89 if (cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
90 {
91 /* Init The UTMI Interface */
92 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS);
93 }
94
95 /* Reset after a PHY select */
96 ret = USB_CoreReset(USBx);
97
98 if (cfg.dma_enable == 1U)
99 {
100 USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
101 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
102 }
103 }
104 else
105 #endif /* defined (USB_OTG_HS) */
106 {
107 /* Select FS Embedded PHY */
108 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
109
110 /* Reset after a PHY select */
111 ret = USB_CoreReset(USBx);
112
113 if (cfg.battery_charging_enable == 0U)
114 {
115 /* Activate the USB Transceiver */
116 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
117 }
118 else
119 {
120 /* Deactivate the USB Transceiver */
121 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
122 }
123 }
124
125 return ret;
126 }
127
128
129 /**
130 * @brief Set the USB turnaround time
131 * @param USBx USB Instance
132 * @param hclk: AHB clock frequency
133 * @retval USB turnaround time In PHY Clocks number
134 */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)135 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
136 uint32_t hclk, uint8_t speed)
137 {
138 uint32_t UsbTrd;
139
140 /* The USBTRD is configured according to the tables below, depending on AHB frequency
141 used by application. In the low AHB frequency range it is used to stretch enough the USB response
142 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
143 latency to the Data FIFO */
144 if (speed == USBD_FS_SPEED)
145 {
146 if ((hclk >= 14200000U) && (hclk < 15000000U))
147 {
148 /* hclk Clock Range between 14.2-15 MHz */
149 UsbTrd = 0xFU;
150 }
151 else if ((hclk >= 15000000U) && (hclk < 16000000U))
152 {
153 /* hclk Clock Range between 15-16 MHz */
154 UsbTrd = 0xEU;
155 }
156 else if ((hclk >= 16000000U) && (hclk < 17200000U))
157 {
158 /* hclk Clock Range between 16-17.2 MHz */
159 UsbTrd = 0xDU;
160 }
161 else if ((hclk >= 17200000U) && (hclk < 18500000U))
162 {
163 /* hclk Clock Range between 17.2-18.5 MHz */
164 UsbTrd = 0xCU;
165 }
166 else if ((hclk >= 18500000U) && (hclk < 20000000U))
167 {
168 /* hclk Clock Range between 18.5-20 MHz */
169 UsbTrd = 0xBU;
170 }
171 else if ((hclk >= 20000000U) && (hclk < 21800000U))
172 {
173 /* hclk Clock Range between 20-21.8 MHz */
174 UsbTrd = 0xAU;
175 }
176 else if ((hclk >= 21800000U) && (hclk < 24000000U))
177 {
178 /* hclk Clock Range between 21.8-24 MHz */
179 UsbTrd = 0x9U;
180 }
181 else if ((hclk >= 24000000U) && (hclk < 27700000U))
182 {
183 /* hclk Clock Range between 24-27.7 MHz */
184 UsbTrd = 0x8U;
185 }
186 else if ((hclk >= 27700000U) && (hclk < 32000000U))
187 {
188 /* hclk Clock Range between 27.7-32 MHz */
189 UsbTrd = 0x7U;
190 }
191 else /* if(hclk >= 32000000) */
192 {
193 /* hclk Clock Range between 32-200 MHz */
194 UsbTrd = 0x6U;
195 }
196 }
197 else if (speed == USBD_HS_SPEED)
198 {
199 UsbTrd = USBD_HS_TRDT_VALUE;
200 }
201 else
202 {
203 UsbTrd = USBD_DEFAULT_TRDT_VALUE;
204 }
205
206 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
207 USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
208
209 return HAL_OK;
210 }
211
212 /**
213 * @brief USB_EnableGlobalInt
214 * Enables the controller's Global Int in the AHB Config reg
215 * @param USBx Selected device
216 * @retval HAL status
217 */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)218 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
219 {
220 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
221 return HAL_OK;
222 }
223
224 /**
225 * @brief USB_DisableGlobalInt
226 * Disable the controller's Global Int in the AHB Config reg
227 * @param USBx Selected device
228 * @retval HAL status
229 */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)230 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
231 {
232 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
233 return HAL_OK;
234 }
235
236 /**
237 * @brief USB_SetCurrentMode Set functional mode
238 * @param USBx Selected device
239 * @param mode current core mode
240 * This parameter can be one of these values:
241 * @arg USB_DEVICE_MODE Peripheral mode
242 * @arg USB_HOST_MODE Host mode
243 * @retval HAL status
244 */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_OTG_ModeTypeDef mode)245 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
246 {
247 uint32_t ms = 0U;
248
249 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
250
251 if (mode == USB_HOST_MODE)
252 {
253 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
254
255 do
256 {
257 HAL_Delay(10U);
258 ms += 10U;
259 } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
260 }
261 else if (mode == USB_DEVICE_MODE)
262 {
263 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
264
265 do
266 {
267 HAL_Delay(10U);
268 ms += 10U;
269 } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
270 }
271 else
272 {
273 return HAL_ERROR;
274 }
275
276 if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
277 {
278 return HAL_ERROR;
279 }
280
281 return HAL_OK;
282 }
283
284 /**
285 * @brief USB_DevInit Initializes the USB_OTG controller registers
286 * for device mode
287 * @param USBx Selected device
288 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
289 * the configuration information for the specified USBx peripheral.
290 * @retval HAL status
291 */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)292 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
293 {
294 HAL_StatusTypeDef ret = HAL_OK;
295 uint32_t USBx_BASE = (uint32_t)USBx;
296 uint32_t i;
297
298 for (i = 0U; i < 15U; i++)
299 {
300 USBx->DIEPTXF[i] = 0U;
301 }
302
303 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
304 {
305 /* Disable USB PHY pulldown resistors */
306 USBx->GCCFG &= ~USB_OTG_GCCFG_PULLDOWNEN;
307 }
308
309 /* VBUS Sensing setup */
310 if (cfg.vbus_sensing_enable == 0U)
311 {
312 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
313
314 /* Deactivate VBUS Sensing B */
315 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
316
317 /* B-peripheral session valid override enable */
318 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
319 {
320 USBx->GCCFG |= USB_OTG_GCCFG_VBVALEXTOEN;
321 USBx->GCCFG |= USB_OTG_GCCFG_VBVALOVAL;
322 }
323 else
324 {
325 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
326 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
327 }
328 }
329 else
330 {
331 /* B-peripheral session valid override disable */
332 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
333 {
334 USBx->GCCFG &= ~USB_OTG_GCCFG_VBVALEXTOEN;
335 USBx->GCCFG &= ~USB_OTG_GCCFG_VBVALOVAL;
336 }
337 else
338 {
339 USBx->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN;
340 USBx->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL;
341 }
342
343 /* Enable HW VBUS sensing */
344 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
345 }
346
347 /* Restart the Phy Clock */
348 USBx_PCGCCTL = 0U;
349
350 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
351 {
352 if (cfg.speed == USBD_HS_SPEED)
353 {
354 /* Set Core speed to High speed mode */
355 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
356 }
357 else
358 {
359 /* Set Core speed to Full speed mode */
360 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
361 }
362 }
363 else
364 {
365 /* Set Core speed to Full speed mode */
366 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
367 }
368
369 /* Flush the FIFOs */
370 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
371 {
372 ret = HAL_ERROR;
373 }
374
375 if (USB_FlushRxFifo(USBx) != HAL_OK)
376 {
377 ret = HAL_ERROR;
378 }
379
380 /* Clear all pending Device Interrupts */
381 USBx_DEVICE->DIEPMSK = 0U;
382 USBx_DEVICE->DOEPMSK = 0U;
383 USBx_DEVICE->DAINTMSK = 0U;
384
385 for (i = 0U; i < cfg.dev_endpoints; i++)
386 {
387 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
388 {
389 if (i == 0U)
390 {
391 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
392 }
393 else
394 {
395 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
396 }
397 }
398 else
399 {
400 USBx_INEP(i)->DIEPCTL = 0U;
401 }
402
403 USBx_INEP(i)->DIEPTSIZ = 0U;
404 USBx_INEP(i)->DIEPINT = 0xFB7FU;
405 }
406
407 for (i = 0U; i < cfg.dev_endpoints; i++)
408 {
409 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
410 {
411 if (i == 0U)
412 {
413 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
414 }
415 else
416 {
417 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
418 }
419 }
420 else
421 {
422 USBx_OUTEP(i)->DOEPCTL = 0U;
423 }
424
425 USBx_OUTEP(i)->DOEPTSIZ = 0U;
426 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
427 }
428
429 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
430
431 /* Disable all interrupts. */
432 USBx->GINTMSK = 0U;
433
434 /* Clear any pending interrupts */
435 USBx->GINTSTS = 0xBFFFFFFFU;
436
437 /* Enable the common interrupts */
438 if (cfg.dma_enable == 0U)
439 {
440 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
441 }
442
443 /* Enable interrupts matching to the Device mode ONLY */
444 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
445 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
446 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
447 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
448
449 if (cfg.Sof_enable != 0U)
450 {
451 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
452 }
453
454 if (cfg.vbus_sensing_enable == 1U)
455 {
456 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
457 }
458
459 return ret;
460 }
461
462 /**
463 * @brief USB_FlushTxFifo Flush a Tx FIFO
464 * @param USBx Selected device
465 * @param num FIFO number
466 * This parameter can be a value from 1 to 15
467 15 means Flush all Tx FIFOs
468 * @retval HAL status
469 */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)470 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
471 {
472 __IO uint32_t count = 0U;
473
474 /* Wait for AHB master IDLE state. */
475 do
476 {
477 count++;
478
479 if (count > HAL_USB_TIMEOUT)
480 {
481 return HAL_TIMEOUT;
482 }
483 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
484
485 /* Flush TX Fifo */
486 count = 0U;
487 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
488
489 do
490 {
491 count++;
492
493 if (count > HAL_USB_TIMEOUT)
494 {
495 return HAL_TIMEOUT;
496 }
497 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
498
499 return HAL_OK;
500 }
501
502 /**
503 * @brief USB_FlushRxFifo Flush Rx FIFO
504 * @param USBx Selected device
505 * @retval HAL status
506 */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)507 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
508 {
509 __IO uint32_t count = 0U;
510
511 /* Wait for AHB master IDLE state. */
512 do
513 {
514 count++;
515
516 if (count > HAL_USB_TIMEOUT)
517 {
518 return HAL_TIMEOUT;
519 }
520 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
521
522 /* Flush RX Fifo */
523 count = 0U;
524 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
525
526 do
527 {
528 count++;
529
530 if (count > HAL_USB_TIMEOUT)
531 {
532 return HAL_TIMEOUT;
533 }
534 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
535
536 return HAL_OK;
537 }
538
539 /**
540 * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
541 * depending the PHY type and the enumeration speed of the device.
542 * @param USBx Selected device
543 * @param speed device speed
544 * This parameter can be one of these values:
545 * @arg USB_OTG_SPEED_HIGH: High speed mode
546 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
547 * @arg USB_OTG_SPEED_FULL: Full speed mode
548 * @retval Hal status
549 */
USB_SetDevSpeed(const USB_OTG_GlobalTypeDef * USBx,uint8_t speed)550 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
551 {
552 uint32_t USBx_BASE = (uint32_t)USBx;
553
554 USBx_DEVICE->DCFG |= speed;
555 return HAL_OK;
556 }
557
558 /**
559 * @brief USB_GetDevSpeed Return the Dev Speed
560 * @param USBx Selected device
561 * @retval speed device speed
562 * This parameter can be one of these values:
563 * @arg USBD_HS_SPEED: High speed mode
564 * @arg USBD_FS_SPEED: Full speed mode
565 */
USB_GetDevSpeed(const USB_OTG_GlobalTypeDef * USBx)566 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
567 {
568 uint32_t USBx_BASE = (uint32_t)USBx;
569 uint8_t speed;
570 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
571
572 if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
573 {
574 speed = USBD_HS_SPEED;
575 }
576 else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
577 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
578 {
579 speed = USBD_FS_SPEED;
580 }
581 else
582 {
583 speed = 0xFU;
584 }
585
586 return speed;
587 }
588
589 /**
590 * @brief Activate and configure an endpoint
591 * @param USBx Selected device
592 * @param ep pointer to endpoint structure
593 * @retval HAL status
594 */
USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)595 HAL_StatusTypeDef USB_ActivateEndpoint(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 if (ep->is_in == 1U)
601 {
602 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
603
604 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
605 {
606 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
607 ((uint32_t)ep->type << 18) | (epnum << 22) |
608 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
609 USB_OTG_DIEPCTL_USBAEP;
610 }
611 }
612 else
613 {
614 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
615
616 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
617 {
618 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
619 ((uint32_t)ep->type << 18) |
620 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
621 USB_OTG_DOEPCTL_USBAEP;
622 }
623 }
624 return HAL_OK;
625 }
626
627 /**
628 * @brief Activate and configure a dedicated endpoint
629 * @param USBx Selected device
630 * @param ep pointer to endpoint structure
631 * @retval HAL status
632 */
USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)633 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
634 {
635 uint32_t USBx_BASE = (uint32_t)USBx;
636 uint32_t epnum = (uint32_t)ep->num;
637
638 /* Read DEPCTLn register */
639 if (ep->is_in == 1U)
640 {
641 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
642 {
643 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
644 ((uint32_t)ep->type << 18) | (epnum << 22) |
645 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
646 USB_OTG_DIEPCTL_USBAEP;
647 }
648
649 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
650 }
651 else
652 {
653 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
654 {
655 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
656 ((uint32_t)ep->type << 18) | (epnum << 22) |
657 USB_OTG_DOEPCTL_USBAEP;
658 }
659
660 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
661 }
662
663 return HAL_OK;
664 }
665
666 /**
667 * @brief De-activate and de-initialize an endpoint
668 * @param USBx Selected device
669 * @param ep pointer to endpoint structure
670 * @retval HAL status
671 */
USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)672 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
673 {
674 uint32_t USBx_BASE = (uint32_t)USBx;
675 uint32_t epnum = (uint32_t)ep->num;
676
677 /* Read DEPCTLn register */
678 if (ep->is_in == 1U)
679 {
680 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
681 {
682 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
683 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
684 }
685
686 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
687 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
688 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
689 USB_OTG_DIEPCTL_MPSIZ |
690 USB_OTG_DIEPCTL_TXFNUM |
691 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
692 USB_OTG_DIEPCTL_EPTYP);
693 }
694 else
695 {
696 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
697 {
698 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
699 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
700 }
701
702 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
703 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
704 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
705 USB_OTG_DOEPCTL_MPSIZ |
706 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
707 USB_OTG_DOEPCTL_EPTYP);
708 }
709
710 return HAL_OK;
711 }
712
713 /**
714 * @brief De-activate and de-initialize a dedicated endpoint
715 * @param USBx Selected device
716 * @param ep pointer to endpoint structure
717 * @retval HAL status
718 */
USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)719 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
720 {
721 uint32_t USBx_BASE = (uint32_t)USBx;
722 uint32_t epnum = (uint32_t)ep->num;
723
724 /* Read DEPCTLn register */
725 if (ep->is_in == 1U)
726 {
727 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
728 {
729 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
730 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
731 }
732
733 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
734 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
735 }
736 else
737 {
738 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
739 {
740 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
741 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
742 }
743
744 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
745 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
746 }
747
748 return HAL_OK;
749 }
750
751 /**
752 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
753 * @param USBx Selected device
754 * @param ep pointer to endpoint structure
755 * @param dma USB dma enabled or disabled
756 * This parameter can be one of these values:
757 * 0 : DMA feature not used
758 * 1 : DMA feature used
759 * @retval HAL status
760 */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)761 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
762 {
763 uint32_t USBx_BASE = (uint32_t)USBx;
764 uint32_t epnum = (uint32_t)ep->num;
765 uint16_t pktcnt;
766
767 /* IN endpoint */
768 if (ep->is_in == 1U)
769 {
770 /* Zero Length Packet? */
771 if (ep->xfer_len == 0U)
772 {
773 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
774 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
775 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
776 }
777 else
778 {
779 /* Program the transfer size and packet count
780 * as follows: xfersize = N * maxpacket +
781 * short_packet pktcnt = N + (short_packet
782 * exist ? 1 : 0)
783 */
784 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
785 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
786
787 if (epnum == 0U)
788 {
789 if (ep->xfer_len > ep->maxpacket)
790 {
791 ep->xfer_len = ep->maxpacket;
792 }
793
794 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
795 }
796 else
797 {
798 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
799 (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
800 }
801
802 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
803
804 if (ep->type == EP_TYPE_ISOC)
805 {
806 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
807 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
808 }
809 }
810
811 if (dma == 1U)
812 {
813 if ((uint32_t)ep->dma_addr != 0U)
814 {
815 USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
816 }
817
818 if (ep->type == EP_TYPE_ISOC)
819 {
820 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
821 {
822 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
823 }
824 else
825 {
826 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
827 }
828 }
829
830 /* EP enable, IN data in FIFO */
831 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
832 }
833 else
834 {
835 /* EP enable, IN data in FIFO */
836 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
837
838 if (ep->type != EP_TYPE_ISOC)
839 {
840 /* Enable the Tx FIFO Empty Interrupt for this EP */
841 if (ep->xfer_len > 0U)
842 {
843 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
844 }
845 }
846 else
847 {
848 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
849 {
850 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
851 }
852 else
853 {
854 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
855 }
856
857 (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
858 }
859 }
860 }
861 else /* OUT endpoint */
862 {
863 /* Program the transfer size and packet count as follows:
864 * pktcnt = N
865 * xfersize = N * maxpacket
866 */
867 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
868 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
869
870 if (epnum == 0U)
871 {
872 if (ep->xfer_len > 0U)
873 {
874 ep->xfer_len = ep->maxpacket;
875 }
876
877 /* Store transfer size, for EP0 this is equal to endpoint max packet size */
878 ep->xfer_size = ep->maxpacket;
879
880 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
881 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
882 }
883 else
884 {
885 if (ep->xfer_len == 0U)
886 {
887 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
888 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
889 }
890 else
891 {
892 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
893 ep->xfer_size = ep->maxpacket * pktcnt;
894
895 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
896 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
897 }
898 }
899
900 if (dma == 1U)
901 {
902 if ((uint32_t)ep->xfer_buff != 0U)
903 {
904 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
905 }
906 }
907
908 if (ep->type == EP_TYPE_ISOC)
909 {
910 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
911 {
912 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
913 }
914 else
915 {
916 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
917 }
918 }
919 /* EP enable */
920 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
921 }
922
923 return HAL_OK;
924 }
925
926
927 /**
928 * @brief USB_EPStoptXfer Stop transfer on an EP
929 * @param USBx usb device instance
930 * @param ep pointer to endpoint structure
931 * @retval HAL status
932 */
USB_EPStopXfer(const USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)933 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
934 {
935 __IO uint32_t count = 0U;
936 HAL_StatusTypeDef ret = HAL_OK;
937 uint32_t USBx_BASE = (uint32_t)USBx;
938
939 /* IN endpoint */
940 if (ep->is_in == 1U)
941 {
942 /* EP enable, IN data in FIFO */
943 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
944 {
945 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
946 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
947
948 do
949 {
950 count++;
951
952 if (count > 10000U)
953 {
954 ret = HAL_ERROR;
955 break;
956 }
957 } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA);
958 }
959 }
960 else /* OUT endpoint */
961 {
962 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
963 {
964 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
965 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
966
967 do
968 {
969 count++;
970
971 if (count > 10000U)
972 {
973 ret = HAL_ERROR;
974 break;
975 }
976 } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA);
977 }
978 }
979
980 return ret;
981 }
982
983
984 /**
985 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
986 * with the EP/channel
987 * @param USBx Selected device
988 * @param src pointer to source buffer
989 * @param ch_ep_num endpoint or host channel number
990 * @param len Number of bytes to write
991 * @param dma USB dma enabled or disabled
992 * This parameter can be one of these values:
993 * 0 : DMA feature not used
994 * 1 : DMA feature used
995 * @retval HAL status
996 */
USB_WritePacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len,uint8_t dma)997 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
998 uint8_t ch_ep_num, uint16_t len, uint8_t dma)
999 {
1000 uint32_t USBx_BASE = (uint32_t)USBx;
1001 uint8_t *pSrc = src;
1002 uint32_t count32b;
1003 uint32_t i;
1004
1005 if (dma == 0U)
1006 {
1007 count32b = ((uint32_t)len + 3U) / 4U;
1008 for (i = 0U; i < count32b; i++)
1009 {
1010 USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
1011 pSrc++;
1012 pSrc++;
1013 pSrc++;
1014 pSrc++;
1015 }
1016 }
1017
1018 return HAL_OK;
1019 }
1020
1021 /**
1022 * @brief USB_ReadPacket : read a packet from the RX FIFO
1023 * @param USBx Selected device
1024 * @param dest source pointer
1025 * @param len Number of bytes to read
1026 * @retval pointer to destination buffer
1027 */
USB_ReadPacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)1028 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1029 {
1030 uint32_t USBx_BASE = (uint32_t)USBx;
1031 uint8_t *pDest = dest;
1032 uint32_t pData;
1033 uint32_t i;
1034 uint32_t count32b = (uint32_t)len >> 2U;
1035 uint16_t remaining_bytes = len % 4U;
1036
1037 for (i = 0U; i < count32b; i++)
1038 {
1039 __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1040 pDest++;
1041 pDest++;
1042 pDest++;
1043 pDest++;
1044 }
1045
1046 /* When Number of data is not word aligned, read the remaining byte */
1047 if (remaining_bytes != 0U)
1048 {
1049 i = 0U;
1050 __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1051
1052 do
1053 {
1054 *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1055 i++;
1056 pDest++;
1057 remaining_bytes--;
1058 } while (remaining_bytes != 0U);
1059 }
1060
1061 return ((void *)pDest);
1062 }
1063
1064 /**
1065 * @brief USB_EPSetStall : set a stall condition over an EP
1066 * @param USBx Selected device
1067 * @param ep pointer to endpoint structure
1068 * @retval HAL status
1069 */
USB_EPSetStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1070 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1071 {
1072 uint32_t USBx_BASE = (uint32_t)USBx;
1073 uint32_t epnum = (uint32_t)ep->num;
1074
1075 if (ep->is_in == 1U)
1076 {
1077 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1078 {
1079 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1080 }
1081 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1082 }
1083 else
1084 {
1085 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1086 {
1087 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1088 }
1089 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1090 }
1091
1092 return HAL_OK;
1093 }
1094
1095 /**
1096 * @brief USB_EPClearStall : Clear a stall condition over an EP
1097 * @param USBx Selected device
1098 * @param ep pointer to endpoint structure
1099 * @retval HAL status
1100 */
USB_EPClearStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1101 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1102 {
1103 uint32_t USBx_BASE = (uint32_t)USBx;
1104 uint32_t epnum = (uint32_t)ep->num;
1105
1106 if (ep->is_in == 1U)
1107 {
1108 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1109 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1110 {
1111 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1112 }
1113 }
1114 else
1115 {
1116 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1117 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1118 {
1119 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1120 }
1121 }
1122 return HAL_OK;
1123 }
1124
1125 /**
1126 * @brief USB_StopDevice : Stop the usb device mode
1127 * @param USBx Selected device
1128 * @retval HAL status
1129 */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1130 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1131 {
1132 HAL_StatusTypeDef ret;
1133 uint32_t USBx_BASE = (uint32_t)USBx;
1134 uint32_t i;
1135
1136 /* Clear Pending interrupt */
1137 for (i = 0U; i < 15U; i++)
1138 {
1139 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1140 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1141 }
1142
1143 /* Clear interrupt masks */
1144 USBx_DEVICE->DIEPMSK = 0U;
1145 USBx_DEVICE->DOEPMSK = 0U;
1146 USBx_DEVICE->DAINTMSK = 0U;
1147
1148 /* Flush the FIFO */
1149 ret = USB_FlushRxFifo(USBx);
1150 if (ret != HAL_OK)
1151 {
1152 return ret;
1153 }
1154
1155 ret = USB_FlushTxFifo(USBx, 0x10U);
1156 if (ret != HAL_OK)
1157 {
1158 return ret;
1159 }
1160
1161 return ret;
1162 }
1163
1164 /**
1165 * @brief USB_SetDevAddress : Stop the usb device mode
1166 * @param USBx Selected device
1167 * @param address new device address to be assigned
1168 * This parameter can be a value from 0 to 255
1169 * @retval HAL status
1170 */
USB_SetDevAddress(const USB_OTG_GlobalTypeDef * USBx,uint8_t address)1171 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1172 {
1173 uint32_t USBx_BASE = (uint32_t)USBx;
1174
1175 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1176 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1177
1178 return HAL_OK;
1179 }
1180
1181 /**
1182 * @brief USB_DevConnect : Connect the USB device by enabling Rpu
1183 * @param USBx Selected device
1184 * @retval HAL status
1185 */
USB_DevConnect(const USB_OTG_GlobalTypeDef * USBx)1186 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1187 {
1188 uint32_t USBx_BASE = (uint32_t)USBx;
1189
1190 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1191 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1192
1193 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1194
1195 return HAL_OK;
1196 }
1197
1198 /**
1199 * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1200 * @param USBx Selected device
1201 * @retval HAL status
1202 */
USB_DevDisconnect(const USB_OTG_GlobalTypeDef * USBx)1203 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1204 {
1205 uint32_t USBx_BASE = (uint32_t)USBx;
1206
1207 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1208 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1209
1210 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1211
1212 return HAL_OK;
1213 }
1214
1215 /**
1216 * @brief USB_ReadInterrupts: return the global USB interrupt status
1217 * @param USBx Selected device
1218 * @retval USB Global Interrupt status
1219 */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef const * USBx)1220 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1221 {
1222 uint32_t tmpreg;
1223
1224 tmpreg = USBx->GINTSTS;
1225 tmpreg &= USBx->GINTMSK;
1226
1227 return tmpreg;
1228 }
1229
1230 /**
1231 * @brief USB_ReadChInterrupts: return USB channel interrupt status
1232 * @param USBx Selected device
1233 * @param chnum Channel number
1234 * @retval USB Channel Interrupt status
1235 */
USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef * USBx,uint8_t chnum)1236 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1237 {
1238 uint32_t USBx_BASE = (uint32_t)USBx;
1239 uint32_t tmpreg;
1240
1241 tmpreg = USBx_HC(chnum)->HCINT;
1242 tmpreg &= USBx_HC(chnum)->HCINTMSK;
1243
1244 return tmpreg;
1245 }
1246
1247 /**
1248 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1249 * @param USBx Selected device
1250 * @retval USB Device OUT EP interrupt status
1251 */
USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1252 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1253 {
1254 uint32_t USBx_BASE = (uint32_t)USBx;
1255 uint32_t tmpreg;
1256
1257 tmpreg = USBx_DEVICE->DAINT;
1258 tmpreg &= USBx_DEVICE->DAINTMSK;
1259
1260 return ((tmpreg & 0xffff0000U) >> 16);
1261 }
1262
1263 /**
1264 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1265 * @param USBx Selected device
1266 * @retval USB Device IN EP interrupt status
1267 */
USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1268 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1269 {
1270 uint32_t USBx_BASE = (uint32_t)USBx;
1271 uint32_t tmpreg;
1272
1273 tmpreg = USBx_DEVICE->DAINT;
1274 tmpreg &= USBx_DEVICE->DAINTMSK;
1275
1276 return ((tmpreg & 0xFFFFU));
1277 }
1278
1279 /**
1280 * @brief Returns Device OUT EP Interrupt register
1281 * @param USBx Selected device
1282 * @param epnum endpoint number
1283 * This parameter can be a value from 0 to 15
1284 * @retval Device OUT EP Interrupt register
1285 */
USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1286 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1287 {
1288 uint32_t USBx_BASE = (uint32_t)USBx;
1289 uint32_t tmpreg;
1290
1291 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1292 tmpreg &= USBx_DEVICE->DOEPMSK;
1293
1294 return tmpreg;
1295 }
1296
1297 /**
1298 * @brief Returns Device IN EP Interrupt register
1299 * @param USBx Selected device
1300 * @param epnum endpoint number
1301 * This parameter can be a value from 0 to 15
1302 * @retval Device IN EP Interrupt register
1303 */
USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1304 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1305 {
1306 uint32_t USBx_BASE = (uint32_t)USBx;
1307 uint32_t tmpreg;
1308 uint32_t msk;
1309 uint32_t emp;
1310
1311 msk = USBx_DEVICE->DIEPMSK;
1312 emp = USBx_DEVICE->DIEPEMPMSK;
1313 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1314 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1315
1316 return tmpreg;
1317 }
1318
1319 /**
1320 * @brief USB_ClearInterrupts: clear a USB interrupt
1321 * @param USBx Selected device
1322 * @param interrupt flag
1323 * @retval None
1324 */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1325 void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1326 {
1327 USBx->GINTSTS &= interrupt;
1328 }
1329
1330 /**
1331 * @brief Returns USB core mode
1332 * @param USBx Selected device
1333 * @retval return core mode : Host or Device
1334 * This parameter can be one of these values:
1335 * 0 : Host
1336 * 1 : Device
1337 */
USB_GetMode(const USB_OTG_GlobalTypeDef * USBx)1338 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1339 {
1340 return ((USBx->GINTSTS) & 0x1U);
1341 }
1342
1343 /**
1344 * @brief Activate EP0 for Setup transactions
1345 * @param USBx Selected device
1346 * @retval HAL status
1347 */
USB_ActivateSetup(const USB_OTG_GlobalTypeDef * USBx)1348 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1349 {
1350 uint32_t USBx_BASE = (uint32_t)USBx;
1351
1352 /* Set the MPS of the IN EP0 to 64 bytes */
1353 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1354
1355 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1356
1357 return HAL_OK;
1358 }
1359
1360 /**
1361 * @brief Prepare the EP0 to start the first control setup
1362 * @param USBx Selected device
1363 * @param dma USB dma enabled or disabled
1364 * This parameter can be one of these values:
1365 * 0 : DMA feature not used
1366 * 1 : DMA feature used
1367 * @param psetup pointer to setup packet
1368 * @retval HAL status
1369 */
USB_EP0_OutStart(const USB_OTG_GlobalTypeDef * USBx,uint8_t dma,const uint8_t * psetup)1370 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup)
1371 {
1372 uint32_t USBx_BASE = (uint32_t)USBx;
1373 uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1374
1375 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1376 {
1377 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1378 {
1379 return HAL_OK;
1380 }
1381 }
1382
1383 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1384 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1385 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1386 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1387
1388 if (dma == 1U)
1389 {
1390 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1391 /* EP enable */
1392 USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1393 }
1394
1395 return HAL_OK;
1396 }
1397
1398 /**
1399 * @brief Reset the USB Core (needed after USB clock settings change)
1400 * @param USBx Selected device
1401 * @retval HAL status
1402 */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1403 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1404 {
1405 __IO uint32_t count = 0U;
1406
1407 /* Wait for AHB master IDLE state. */
1408 do
1409 {
1410 count++;
1411
1412 if (count > HAL_USB_TIMEOUT)
1413 {
1414 return HAL_TIMEOUT;
1415 }
1416 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1417
1418 /* Core Soft Reset */
1419 count = 0U;
1420 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1421
1422 do
1423 {
1424 count++;
1425
1426 if (count > HAL_USB_TIMEOUT)
1427 {
1428 return HAL_TIMEOUT;
1429 }
1430 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1431
1432 return HAL_OK;
1433 }
1434
1435 /**
1436 * @brief USB_HostInit : Initializes the USB OTG controller registers
1437 * for Host mode
1438 * @param USBx Selected device
1439 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
1440 * the configuration information for the specified USBx peripheral.
1441 * @retval HAL status
1442 */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1443 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1444 {
1445 HAL_StatusTypeDef ret = HAL_OK;
1446 uint32_t USBx_BASE = (uint32_t)USBx;
1447 uint32_t i;
1448
1449 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
1450 {
1451 /* Enable USB PHY pulldown resistors */
1452 USBx->GCCFG |= USB_OTG_GCCFG_PULLDOWNEN;
1453 }
1454
1455 /* Restart the Phy Clock */
1456 USBx_PCGCCTL = 0U;
1457
1458 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
1459 {
1460 /* Disable VBUS override */
1461 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBVALOVAL | USB_OTG_GCCFG_VBVALEXTOEN);
1462 }
1463
1464 /* Disable VBUS sensing */
1465 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1466 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
1467 {
1468 /* Disable Battery chargin detector */
1469 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1470 }
1471 else
1472 {
1473 /* Disable Battery chargin detector */
1474 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
1475 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
1476 }
1477
1478 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
1479 {
1480 if (cfg.speed == USBH_FSLS_SPEED)
1481 {
1482 /* Force Device Enumeration to FS/LS mode only */
1483 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1484 }
1485 else
1486 {
1487 /* Set default Max speed support */
1488 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1489 }
1490 }
1491 else
1492 {
1493 /* Set default Max speed support */
1494 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1495 }
1496
1497 /* Make sure the FIFOs are flushed. */
1498 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1499 {
1500 ret = HAL_ERROR;
1501 }
1502
1503 if (USB_FlushRxFifo(USBx) != HAL_OK)
1504 {
1505 ret = HAL_ERROR;
1506 }
1507
1508 /* Clear all pending HC Interrupts */
1509 for (i = 0U; i < cfg.Host_channels; i++)
1510 {
1511 USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1512 USBx_HC(i)->HCINTMSK = 0U;
1513 }
1514
1515 /* Disable all interrupts. */
1516 USBx->GINTMSK = 0U;
1517
1518 /* Clear any pending interrupts */
1519 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1520 #if defined (USB_OTG_HS)
1521 if (USBx == USB_OTG_HS)
1522 {
1523 /* set Rx FIFO size */
1524 USBx->GRXFSIZ = 0x200U;
1525 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
1526 USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1527 }
1528 else
1529 #endif /* defined (USB_OTG_HS) */
1530 {
1531 /* set Rx FIFO size */
1532 USBx->GRXFSIZ = 0x80U;
1533 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1534 USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1535 }
1536
1537 /* Enable the common interrupts */
1538 if (cfg.dma_enable == 0U)
1539 {
1540 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1541 }
1542
1543 /* Enable interrupts matching to the Host mode ONLY */
1544 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
1545 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
1546 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1547
1548 return ret;
1549 }
1550
1551 /**
1552 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1553 * HCFG register on the PHY type and set the right frame interval
1554 * @param USBx Selected device
1555 * @param freq clock frequency
1556 * This parameter can be one of these values:
1557 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1558 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1559 * @retval HAL status
1560 */
USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1561 HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1562 {
1563 uint32_t USBx_BASE = (uint32_t)USBx;
1564
1565 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1566 USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1567
1568 if (freq == HCFG_48_MHZ)
1569 {
1570 USBx_HOST->HFIR = HFIR_48_MHZ;
1571 }
1572 else if (freq == HCFG_6_MHZ)
1573 {
1574 USBx_HOST->HFIR = HFIR_6_MHZ;
1575 }
1576 else
1577 {
1578 return HAL_ERROR;
1579 }
1580
1581 return HAL_OK;
1582 }
1583
1584 /**
1585 * @brief USB_OTG_ResetPort : Reset Host Port
1586 * @param USBx Selected device
1587 * @retval HAL status
1588 * @note (1)The application must wait at least 10 ms
1589 * before clearing the reset bit.
1590 */
USB_ResetPort(const USB_OTG_GlobalTypeDef * USBx)1591 HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
1592 {
1593 uint32_t USBx_BASE = (uint32_t)USBx;
1594
1595 __IO uint32_t hprt0 = 0U;
1596
1597 hprt0 = USBx_HPRT0;
1598
1599 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1600 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1601
1602 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1603 HAL_Delay(100U); /* See Note #1 */
1604 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1605 HAL_Delay(10U);
1606
1607 return HAL_OK;
1608 }
1609
1610 /**
1611 * @brief USB_DriveVbus : activate or de-activate vbus
1612 * @param state VBUS state
1613 * This parameter can be one of these values:
1614 * 0 : Deactivate VBUS
1615 * 1 : Activate VBUS
1616 * @retval HAL status
1617 */
USB_DriveVbus(const USB_OTG_GlobalTypeDef * USBx,uint8_t state)1618 HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1619 {
1620 uint32_t USBx_BASE = (uint32_t)USBx;
1621 __IO uint32_t hprt0 = 0U;
1622
1623 hprt0 = USBx_HPRT0;
1624
1625 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1626 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1627
1628 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1629 {
1630 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1631 }
1632 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1633 {
1634 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1635 }
1636 return HAL_OK;
1637 }
1638
1639 /**
1640 * @brief Return Host Core speed
1641 * @param USBx Selected device
1642 * @retval speed : Host speed
1643 * This parameter can be one of these values:
1644 * @arg HCD_SPEED_HIGH: High speed mode
1645 * @arg HCD_SPEED_FULL: Full speed mode
1646 * @arg HCD_SPEED_LOW: Low speed mode
1647 */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef const * USBx)1648 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1649 {
1650 uint32_t USBx_BASE = (uint32_t)USBx;
1651 __IO uint32_t hprt0 = 0U;
1652
1653 hprt0 = USBx_HPRT0;
1654 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1655 }
1656
1657 /**
1658 * @brief Return Host Current Frame number
1659 * @param USBx Selected device
1660 * @retval current frame number
1661 */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const * USBx)1662 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1663 {
1664 uint32_t USBx_BASE = (uint32_t)USBx;
1665
1666 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1667 }
1668
1669 /**
1670 * @brief Initialize a host channel
1671 * @param USBx Selected device
1672 * @param ch_num Channel number
1673 * This parameter can be a value from 1 to 15
1674 * @param epnum Endpoint number
1675 * This parameter can be a value from 1 to 15
1676 * @param dev_address Current device address
1677 * This parameter can be a value from 0 to 255
1678 * @param speed Current device speed
1679 * This parameter can be one of these values:
1680 * @arg USB_OTG_SPEED_HIGH: High speed mode
1681 * @arg USB_OTG_SPEED_FULL: Full speed mode
1682 * @arg USB_OTG_SPEED_LOW: Low speed mode
1683 * @param ep_type Endpoint Type
1684 * This parameter can be one of these values:
1685 * @arg EP_TYPE_CTRL: Control type
1686 * @arg EP_TYPE_ISOC: Isochronous type
1687 * @arg EP_TYPE_BULK: Bulk type
1688 * @arg EP_TYPE_INTR: Interrupt type
1689 * @param mps Max Packet Size
1690 * This parameter can be a value from 0 to 32K
1691 * @retval HAL state
1692 */
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)1693 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1694 uint8_t epnum, uint8_t dev_address, uint8_t speed,
1695 uint8_t ep_type, uint16_t mps)
1696 {
1697 HAL_StatusTypeDef ret = HAL_OK;
1698 uint32_t USBx_BASE = (uint32_t)USBx;
1699 uint32_t HCcharEpDir;
1700 uint32_t HCcharLowSpeed;
1701 uint32_t HostCoreSpeed;
1702
1703 /* Clear old interrupt conditions for this host channel. */
1704 USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1705
1706 /* Enable channel interrupts required for this transfer. */
1707 switch (ep_type)
1708 {
1709 case EP_TYPE_CTRL:
1710 case EP_TYPE_BULK:
1711 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1712 USB_OTG_HCINTMSK_STALLM |
1713 USB_OTG_HCINTMSK_TXERRM |
1714 USB_OTG_HCINTMSK_DTERRM |
1715 USB_OTG_HCINTMSK_AHBERR |
1716 USB_OTG_HCINTMSK_NAKM;
1717
1718 if ((epnum & 0x80U) == 0x80U)
1719 {
1720 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1721 }
1722 else
1723 {
1724 #if defined (USB_OTG_HS)
1725 if (USBx == USB_OTG_HS)
1726 {
1727 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
1728 USB_OTG_HCINTMSK_ACKM;
1729 }
1730 #endif /* defined (USB_OTG_HS) */
1731 }
1732 break;
1733
1734 case EP_TYPE_INTR:
1735 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1736 USB_OTG_HCINTMSK_STALLM |
1737 USB_OTG_HCINTMSK_TXERRM |
1738 USB_OTG_HCINTMSK_DTERRM |
1739 USB_OTG_HCINTMSK_NAKM |
1740 USB_OTG_HCINTMSK_AHBERR |
1741 USB_OTG_HCINTMSK_FRMORM;
1742
1743 if ((epnum & 0x80U) == 0x80U)
1744 {
1745 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1746 }
1747
1748 break;
1749
1750 case EP_TYPE_ISOC:
1751 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1752 USB_OTG_HCINTMSK_ACKM |
1753 USB_OTG_HCINTMSK_AHBERR |
1754 USB_OTG_HCINTMSK_FRMORM;
1755
1756 if ((epnum & 0x80U) == 0x80U)
1757 {
1758 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1759 }
1760 break;
1761
1762 default:
1763 ret = HAL_ERROR;
1764 break;
1765 }
1766
1767 /* Clear Hub Start Split transaction */
1768 USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
1769
1770 /* Enable host channel Halt interrupt */
1771 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1772
1773 /* Enable the top level host channel interrupt. */
1774 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1775
1776 /* Make sure host channel interrupts are enabled. */
1777 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1778
1779 /* Program the HCCHAR register */
1780 if ((epnum & 0x80U) == 0x80U)
1781 {
1782 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1783 }
1784 else
1785 {
1786 HCcharEpDir = 0U;
1787 }
1788
1789 HostCoreSpeed = USB_GetHostSpeed(USBx);
1790
1791 /* LS device plugged to HUB */
1792 if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1793 {
1794 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1795 }
1796 else
1797 {
1798 HCcharLowSpeed = 0U;
1799 }
1800
1801 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1802 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1803 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1804 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1805 USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1806
1807 if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1808 {
1809 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1810 }
1811
1812 return ret;
1813 }
1814
1815 /**
1816 * @brief Start a transfer over a host channel
1817 * @param USBx Selected device
1818 * @param hc pointer to host channel structure
1819 * @param dma USB dma enabled or disabled
1820 * This parameter can be one of these values:
1821 * 0 : DMA feature not used
1822 * 1 : DMA feature used
1823 * @retval HAL state
1824 */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc,uint8_t dma)1825 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1826 {
1827 uint32_t USBx_BASE = (uint32_t)USBx;
1828 uint32_t ch_num = (uint32_t)hc->ch_num;
1829 __IO uint32_t tmpreg;
1830 uint8_t is_oddframe;
1831 uint16_t len_words;
1832 uint16_t num_packets;
1833 uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1834
1835 #if defined (USB_OTG_HS)
1836 if (USBx == USB_OTG_HS)
1837 {
1838 /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
1839 if (dma == 1U)
1840 {
1841 if (((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)) && (hc->do_ssplit == 0U))
1842 {
1843
1844 USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
1845 USB_OTG_HCINTMSK_ACKM |
1846 USB_OTG_HCINTMSK_NAKM);
1847 }
1848 }
1849 else
1850 {
1851 if ((hc->speed == USBH_HS_SPEED) && (hc->do_ping == 1U))
1852 {
1853 (void)USB_DoPing(USBx, hc->ch_num);
1854 return HAL_OK;
1855 }
1856 }
1857 }
1858 #endif /* defined (USB_OTG_HS) */
1859
1860 if (hc->do_ssplit == 1U)
1861 {
1862 /* Set number of packet to 1 for Split transaction */
1863 num_packets = 1U;
1864
1865 if (hc->ep_is_in != 0U)
1866 {
1867 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1868 }
1869 else
1870 {
1871 if (hc->ep_type == EP_TYPE_ISOC)
1872 {
1873 if (hc->xfer_len > ISO_SPLT_MPS)
1874 {
1875 /* Isochrone Max Packet Size for Split mode */
1876 hc->XferSize = hc->max_packet;
1877 hc->xfer_len = hc->XferSize;
1878
1879 if ((hc->iso_splt_xactPos == HCSPLT_BEGIN) || (hc->iso_splt_xactPos == HCSPLT_MIDDLE))
1880 {
1881 hc->iso_splt_xactPos = HCSPLT_MIDDLE;
1882 }
1883 else
1884 {
1885 hc->iso_splt_xactPos = HCSPLT_BEGIN;
1886 }
1887 }
1888 else
1889 {
1890 hc->XferSize = hc->xfer_len;
1891
1892 if ((hc->iso_splt_xactPos != HCSPLT_BEGIN) && (hc->iso_splt_xactPos != HCSPLT_MIDDLE))
1893 {
1894 hc->iso_splt_xactPos = HCSPLT_FULL;
1895 }
1896 else
1897 {
1898 hc->iso_splt_xactPos = HCSPLT_END;
1899 }
1900 }
1901 }
1902 else
1903 {
1904 if ((dma == 1U) && (hc->xfer_len > hc->max_packet))
1905 {
1906 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1907 }
1908 else
1909 {
1910 hc->XferSize = hc->xfer_len;
1911 }
1912 }
1913 }
1914 }
1915 else
1916 {
1917 /* Compute the expected number of packets associated to the transfer */
1918 if (hc->xfer_len > 0U)
1919 {
1920 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1921
1922 if (num_packets > max_hc_pkt_count)
1923 {
1924 num_packets = max_hc_pkt_count;
1925 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1926 }
1927 }
1928 else
1929 {
1930 num_packets = 1U;
1931 }
1932
1933 /*
1934 * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1935 * max_packet size.
1936 */
1937 if (hc->ep_is_in != 0U)
1938 {
1939 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1940 }
1941 else
1942 {
1943 hc->XferSize = hc->xfer_len;
1944 }
1945 }
1946
1947 /* Initialize the HCTSIZn register */
1948 USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1949 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1950 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1951
1952 if (dma != 0U)
1953 {
1954 /* xfer_buff MUST be 32-bits aligned */
1955 USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1956 }
1957
1958 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1959 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1960 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1961
1962 if (hc->do_ssplit == 1U)
1963 {
1964 /* Set Hub start Split transaction */
1965 USBx_HC((uint32_t)ch_num)->HCSPLT = ((uint32_t)hc->hub_addr << USB_OTG_HCSPLT_HUBADDR_Pos) |
1966 (uint32_t)hc->hub_port_nbr | USB_OTG_HCSPLT_SPLITEN;
1967
1968 /* unmask ack & nyet for IN/OUT transactions */
1969 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_ACKM |
1970 USB_OTG_HCINTMSK_NYET);
1971
1972 if ((hc->do_csplit == 1U) && (hc->ep_is_in == 0U))
1973 {
1974 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1975 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
1976 }
1977
1978 if (((hc->ep_type == EP_TYPE_ISOC) || (hc->ep_type == EP_TYPE_INTR)) &&
1979 (hc->do_csplit == 1U) && (hc->ep_is_in == 1U))
1980 {
1981 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1982 }
1983
1984 /* Position management for iso out transaction on split mode */
1985 if ((hc->ep_type == EP_TYPE_ISOC) && (hc->ep_is_in == 0U))
1986 {
1987 /* Set data payload position */
1988 switch (hc->iso_splt_xactPos)
1989 {
1990 case HCSPLT_BEGIN:
1991 /* First data payload for OUT Transaction */
1992 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_1;
1993 break;
1994
1995 case HCSPLT_MIDDLE:
1996 /* Middle data payload for OUT Transaction */
1997 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_Pos;
1998 break;
1999
2000 case HCSPLT_END:
2001 /* End data payload for OUT Transaction */
2002 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_0;
2003 break;
2004
2005 case HCSPLT_FULL:
2006 /* Entire data payload for OUT Transaction */
2007 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS;
2008 break;
2009
2010 default:
2011 break;
2012 }
2013 }
2014 }
2015 else
2016 {
2017 /* Clear Hub Start Split transaction */
2018 USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
2019 }
2020
2021 /* Set host channel enable */
2022 tmpreg = USBx_HC(ch_num)->HCCHAR;
2023 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2024
2025 /* make sure to set the correct ep direction */
2026 if (hc->ep_is_in != 0U)
2027 {
2028 tmpreg |= USB_OTG_HCCHAR_EPDIR;
2029 }
2030 else
2031 {
2032 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
2033 }
2034 tmpreg |= USB_OTG_HCCHAR_CHENA;
2035 USBx_HC(ch_num)->HCCHAR = tmpreg;
2036
2037 if (dma != 0U) /* dma mode */
2038 {
2039 return HAL_OK;
2040 }
2041
2042 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U) && (hc->do_csplit == 0U))
2043 {
2044 switch (hc->ep_type)
2045 {
2046 /* Non periodic transfer */
2047 case EP_TYPE_CTRL:
2048 case EP_TYPE_BULK:
2049
2050 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2051
2052 /* check if there is enough space in FIFO space */
2053 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
2054 {
2055 /* need to process data in nptxfempty interrupt */
2056 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
2057 }
2058 break;
2059
2060 /* Periodic transfer */
2061 case EP_TYPE_INTR:
2062 case EP_TYPE_ISOC:
2063 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2064 /* check if there is enough space in FIFO space */
2065 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
2066 {
2067 /* need to process data in ptxfempty interrupt */
2068 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
2069 }
2070 break;
2071
2072 default:
2073 break;
2074 }
2075
2076 /* Write packet into the Tx FIFO. */
2077 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
2078 }
2079
2080 return HAL_OK;
2081 }
2082
2083 /**
2084 * @brief Read all host channel interrupts status
2085 * @param USBx Selected device
2086 * @retval HAL state
2087 */
USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef * USBx)2088 uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
2089 {
2090 uint32_t USBx_BASE = (uint32_t)USBx;
2091
2092 return ((USBx_HOST->HAINT) & 0xFFFFU);
2093 }
2094
2095 /**
2096 * @brief Halt a host channel
2097 * @param USBx Selected device
2098 * @param hc_num Host Channel number
2099 * This parameter can be a value from 1 to 15
2100 * @retval HAL state
2101 */
USB_HC_Halt(const USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)2102 HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
2103 {
2104 uint32_t USBx_BASE = (uint32_t)USBx;
2105 uint32_t hcnum = (uint32_t)hc_num;
2106 __IO uint32_t count = 0U;
2107 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
2108 uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
2109 uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
2110
2111 /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
2112 At the end of the next uframe/frame (in the worst case), the core generates a channel halted
2113 and disables the channel automatically. */
2114
2115 if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
2116 ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
2117 {
2118 return HAL_OK;
2119 }
2120
2121 /* Check for space in the request queue to issue the halt. */
2122 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
2123 {
2124 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2125
2126 if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
2127 {
2128 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
2129 {
2130 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2131 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2132 do
2133 {
2134 count++;
2135
2136 if (count > 1000U)
2137 {
2138 break;
2139 }
2140 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2141 }
2142 else
2143 {
2144 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2145 }
2146 }
2147 else
2148 {
2149 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2150 }
2151 }
2152 else
2153 {
2154 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2155
2156 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
2157 {
2158 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2159 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2160 do
2161 {
2162 count++;
2163
2164 if (count > 1000U)
2165 {
2166 break;
2167 }
2168 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2169 }
2170 else
2171 {
2172 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2173 }
2174 }
2175
2176 return HAL_OK;
2177 }
2178
2179 /**
2180 * @brief Initiate Do Ping protocol
2181 * @param USBx Selected device
2182 * @param hc_num Host Channel number
2183 * This parameter can be a value from 1 to 15
2184 * @retval HAL state
2185 */
USB_DoPing(const USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)2186 HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
2187 {
2188 uint32_t USBx_BASE = (uint32_t)USBx;
2189 uint32_t chnum = (uint32_t)ch_num;
2190 uint32_t num_packets = 1U;
2191 uint32_t tmpreg;
2192
2193 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
2194 USB_OTG_HCTSIZ_DOPING;
2195
2196 /* Set host channel enable */
2197 tmpreg = USBx_HC(chnum)->HCCHAR;
2198 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2199 tmpreg |= USB_OTG_HCCHAR_CHENA;
2200 USBx_HC(chnum)->HCCHAR = tmpreg;
2201
2202 return HAL_OK;
2203 }
2204
2205 /**
2206 * @brief Stop Host Core
2207 * @param USBx Selected device
2208 * @retval HAL state
2209 */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)2210 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
2211 {
2212 HAL_StatusTypeDef ret = HAL_OK;
2213 uint32_t USBx_BASE = (uint32_t)USBx;
2214 __IO uint32_t count = 0U;
2215 uint32_t value;
2216 uint32_t i;
2217
2218 (void)USB_DisableGlobalInt(USBx);
2219
2220 /* Flush USB FIFO */
2221 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
2222 {
2223 ret = HAL_ERROR;
2224 }
2225
2226 if (USB_FlushRxFifo(USBx) != HAL_OK)
2227 {
2228 ret = HAL_ERROR;
2229 }
2230
2231 /* Flush out any leftover queued requests. */
2232 for (i = 0U; i <= 15U; i++)
2233 {
2234 value = USBx_HC(i)->HCCHAR;
2235 value |= USB_OTG_HCCHAR_CHDIS;
2236 value &= ~USB_OTG_HCCHAR_CHENA;
2237 value &= ~USB_OTG_HCCHAR_EPDIR;
2238 USBx_HC(i)->HCCHAR = value;
2239 }
2240
2241 /* Halt all channels to put them into a known state. */
2242 for (i = 0U; i <= 15U; i++)
2243 {
2244 value = USBx_HC(i)->HCCHAR;
2245 value |= USB_OTG_HCCHAR_CHDIS;
2246 value |= USB_OTG_HCCHAR_CHENA;
2247 value &= ~USB_OTG_HCCHAR_EPDIR;
2248 USBx_HC(i)->HCCHAR = value;
2249
2250 do
2251 {
2252 count++;
2253
2254 if (count > 1000U)
2255 {
2256 break;
2257 }
2258 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2259 }
2260
2261 /* Clear any pending Host interrupts */
2262 USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
2263 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
2264
2265 (void)USB_EnableGlobalInt(USBx);
2266
2267 return ret;
2268 }
2269
2270 /**
2271 * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
2272 * @param USBx Selected device
2273 * @retval HAL status
2274 */
USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)2275 HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2276 {
2277 uint32_t USBx_BASE = (uint32_t)USBx;
2278
2279 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2280 {
2281 /* active Remote wakeup signalling */
2282 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2283 }
2284
2285 return HAL_OK;
2286 }
2287
2288 /**
2289 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2290 * @param USBx Selected device
2291 * @retval HAL status
2292 */
USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)2293 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2294 {
2295 uint32_t USBx_BASE = (uint32_t)USBx;
2296
2297 /* active Remote wakeup signalling */
2298 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2299
2300 return HAL_OK;
2301 }
2302 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2303
2304 /**
2305 * @}
2306 */
2307
2308 /**
2309 * @}
2310 */
2311 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2312 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2313
2314 /**
2315 * @}
2316 */
2317