1 /**
2 ******************************************************************************
3 * @file stm32f4xx_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 "stm32f4xx_hal.h"
43
44 /** @addtogroup STM32F4xx_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 (cfg.phy_itface == USB_OTG_ULPI_PHY)
87 {
88 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
89
90 /* Init The ULPI Interface */
91 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
92
93 /* Select vbus source */
94 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
95 if (cfg.use_external_vbus == 1U)
96 {
97 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
98 }
99
100 /* Reset after a PHY select */
101 ret = USB_CoreReset(USBx);
102 }
103 else /* FS interface (embedded Phy) */
104 {
105 /* Select FS Embedded PHY */
106 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
107
108 /* Reset after a PHY select */
109 ret = USB_CoreReset(USBx);
110
111 if (cfg.battery_charging_enable == 0U)
112 {
113 /* Activate the USB Transceiver */
114 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
115 }
116 else
117 {
118 /* Deactivate the USB Transceiver */
119 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
120 }
121 }
122
123 if (cfg.dma_enable == 1U)
124 {
125 USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
126 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
127 }
128
129 return ret;
130 }
131
132
133 /**
134 * @brief Set the USB turnaround time
135 * @param USBx USB Instance
136 * @param hclk: AHB clock frequency
137 * @retval USB turnaround time In PHY Clocks number
138 */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)139 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
140 uint32_t hclk, uint8_t speed)
141 {
142 uint32_t UsbTrd;
143
144 /* The USBTRD is configured according to the tables below, depending on AHB frequency
145 used by application. In the low AHB frequency range it is used to stretch enough the USB response
146 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
147 latency to the Data FIFO */
148 if (speed == USBD_FS_SPEED)
149 {
150 if ((hclk >= 14200000U) && (hclk < 15000000U))
151 {
152 /* hclk Clock Range between 14.2-15 MHz */
153 UsbTrd = 0xFU;
154 }
155 else if ((hclk >= 15000000U) && (hclk < 16000000U))
156 {
157 /* hclk Clock Range between 15-16 MHz */
158 UsbTrd = 0xEU;
159 }
160 else if ((hclk >= 16000000U) && (hclk < 17200000U))
161 {
162 /* hclk Clock Range between 16-17.2 MHz */
163 UsbTrd = 0xDU;
164 }
165 else if ((hclk >= 17200000U) && (hclk < 18500000U))
166 {
167 /* hclk Clock Range between 17.2-18.5 MHz */
168 UsbTrd = 0xCU;
169 }
170 else if ((hclk >= 18500000U) && (hclk < 20000000U))
171 {
172 /* hclk Clock Range between 18.5-20 MHz */
173 UsbTrd = 0xBU;
174 }
175 else if ((hclk >= 20000000U) && (hclk < 21800000U))
176 {
177 /* hclk Clock Range between 20-21.8 MHz */
178 UsbTrd = 0xAU;
179 }
180 else if ((hclk >= 21800000U) && (hclk < 24000000U))
181 {
182 /* hclk Clock Range between 21.8-24 MHz */
183 UsbTrd = 0x9U;
184 }
185 else if ((hclk >= 24000000U) && (hclk < 27700000U))
186 {
187 /* hclk Clock Range between 24-27.7 MHz */
188 UsbTrd = 0x8U;
189 }
190 else if ((hclk >= 27700000U) && (hclk < 32000000U))
191 {
192 /* hclk Clock Range between 27.7-32 MHz */
193 UsbTrd = 0x7U;
194 }
195 else /* if(hclk >= 32000000) */
196 {
197 /* hclk Clock Range between 32-200 MHz */
198 UsbTrd = 0x6U;
199 }
200 }
201 else if (speed == USBD_HS_SPEED)
202 {
203 UsbTrd = USBD_HS_TRDT_VALUE;
204 }
205 else
206 {
207 UsbTrd = USBD_DEFAULT_TRDT_VALUE;
208 }
209
210 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
211 USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
212
213 return HAL_OK;
214 }
215
216 /**
217 * @brief USB_EnableGlobalInt
218 * Enables the controller's Global Int in the AHB Config reg
219 * @param USBx Selected device
220 * @retval HAL status
221 */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)222 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
223 {
224 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
225 return HAL_OK;
226 }
227
228 /**
229 * @brief USB_DisableGlobalInt
230 * Disable the controller's Global Int in the AHB Config reg
231 * @param USBx Selected device
232 * @retval HAL status
233 */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)234 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
235 {
236 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
237 return HAL_OK;
238 }
239
240 /**
241 * @brief USB_SetCurrentMode Set functional mode
242 * @param USBx Selected device
243 * @param mode current core mode
244 * This parameter can be one of these values:
245 * @arg USB_DEVICE_MODE Peripheral mode
246 * @arg USB_HOST_MODE Host mode
247 * @retval HAL status
248 */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_OTG_ModeTypeDef mode)249 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
250 {
251 uint32_t ms = 0U;
252
253 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
254
255 if (mode == USB_HOST_MODE)
256 {
257 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
258
259 do
260 {
261 HAL_Delay(10U);
262 ms += 10U;
263 } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
264 }
265 else if (mode == USB_DEVICE_MODE)
266 {
267 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
268
269 do
270 {
271 HAL_Delay(10U);
272 ms += 10U;
273 } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
274 }
275 else
276 {
277 return HAL_ERROR;
278 }
279
280 if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
281 {
282 return HAL_ERROR;
283 }
284
285 return HAL_OK;
286 }
287
288 /**
289 * @brief USB_DevInit Initializes the USB_OTG controller registers
290 * for device mode
291 * @param USBx Selected device
292 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
293 * the configuration information for the specified USBx peripheral.
294 * @retval HAL status
295 */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)296 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
297 {
298 HAL_StatusTypeDef ret = HAL_OK;
299 uint32_t USBx_BASE = (uint32_t)USBx;
300 uint32_t i;
301
302 for (i = 0U; i < 15U; i++)
303 {
304 USBx->DIEPTXF[i] = 0U;
305 }
306
307 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
308 || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
309 || defined(STM32F423xx)
310 /* VBUS Sensing setup */
311 if (cfg.vbus_sensing_enable == 0U)
312 {
313 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
314
315 /* Deactivate VBUS Sensing B */
316 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
317
318 /* B-peripheral session valid override enable */
319 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
320 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
321 }
322 else
323 {
324 /* Enable HW VBUS sensing */
325 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
326 }
327 #else
328 /* VBUS Sensing setup */
329 if (cfg.vbus_sensing_enable == 0U)
330 {
331 /*
332 * Disable HW VBUS sensing. VBUS is internally considered to be always
333 * at VBUS-Valid level (5V).
334 */
335 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
336 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
337 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
338 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
339 }
340 else
341 {
342 /* Enable HW VBUS sensing */
343 USBx->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
344 USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
345 }
346 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
347 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
348 defined(STM32F423xx) */
349
350 /* Restart the Phy Clock */
351 USBx_PCGCCTL = 0U;
352
353 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
354 {
355 if (cfg.speed == USBD_HS_SPEED)
356 {
357 /* Set Core speed to High speed mode */
358 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
359 }
360 else
361 {
362 /* Set Core speed to Full speed mode */
363 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
364 }
365 }
366 else
367 {
368 /* Set Core speed to Full speed mode */
369 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
370 }
371
372 /* Flush the FIFOs */
373 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
374 {
375 ret = HAL_ERROR;
376 }
377
378 if (USB_FlushRxFifo(USBx) != HAL_OK)
379 {
380 ret = HAL_ERROR;
381 }
382
383 /* Clear all pending Device Interrupts */
384 USBx_DEVICE->DIEPMSK = 0U;
385 USBx_DEVICE->DOEPMSK = 0U;
386 USBx_DEVICE->DAINTMSK = 0U;
387
388 for (i = 0U; i < cfg.dev_endpoints; i++)
389 {
390 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
391 {
392 if (i == 0U)
393 {
394 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
395 }
396 else
397 {
398 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
399 }
400 }
401 else
402 {
403 USBx_INEP(i)->DIEPCTL = 0U;
404 }
405
406 USBx_INEP(i)->DIEPTSIZ = 0U;
407 USBx_INEP(i)->DIEPINT = 0xFB7FU;
408 }
409
410 for (i = 0U; i < cfg.dev_endpoints; i++)
411 {
412 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
413 {
414 if (i == 0U)
415 {
416 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
417 }
418 else
419 {
420 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
421 }
422 }
423 else
424 {
425 USBx_OUTEP(i)->DOEPCTL = 0U;
426 }
427
428 USBx_OUTEP(i)->DOEPTSIZ = 0U;
429 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
430 }
431
432 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
433
434 /* Disable all interrupts. */
435 USBx->GINTMSK = 0U;
436
437 /* Clear any pending interrupts */
438 USBx->GINTSTS = 0xBFFFFFFFU;
439
440 /* Enable the common interrupts */
441 if (cfg.dma_enable == 0U)
442 {
443 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
444 }
445
446 /* Enable interrupts matching to the Device mode ONLY */
447 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
448 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
449 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
450 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
451
452 if (cfg.Sof_enable != 0U)
453 {
454 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
455 }
456
457 if (cfg.vbus_sensing_enable == 1U)
458 {
459 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
460 }
461
462 return ret;
463 }
464
465 /**
466 * @brief USB_FlushTxFifo Flush a Tx FIFO
467 * @param USBx Selected device
468 * @param num FIFO number
469 * This parameter can be a value from 1 to 15
470 15 means Flush all Tx FIFOs
471 * @retval HAL status
472 */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)473 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
474 {
475 __IO uint32_t count = 0U;
476
477 /* Wait for AHB master IDLE state. */
478 do
479 {
480 count++;
481
482 if (count > HAL_USB_TIMEOUT)
483 {
484 return HAL_TIMEOUT;
485 }
486 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
487
488 /* Flush TX Fifo */
489 count = 0U;
490 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
491
492 do
493 {
494 count++;
495
496 if (count > HAL_USB_TIMEOUT)
497 {
498 return HAL_TIMEOUT;
499 }
500 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
501
502 return HAL_OK;
503 }
504
505 /**
506 * @brief USB_FlushRxFifo Flush Rx FIFO
507 * @param USBx Selected device
508 * @retval HAL status
509 */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)510 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
511 {
512 __IO uint32_t count = 0U;
513
514 /* Wait for AHB master IDLE state. */
515 do
516 {
517 count++;
518
519 if (count > HAL_USB_TIMEOUT)
520 {
521 return HAL_TIMEOUT;
522 }
523 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
524
525 /* Flush RX Fifo */
526 count = 0U;
527 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
528
529 do
530 {
531 count++;
532
533 if (count > HAL_USB_TIMEOUT)
534 {
535 return HAL_TIMEOUT;
536 }
537 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
538
539 return HAL_OK;
540 }
541
542 /**
543 * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
544 * depending the PHY type and the enumeration speed of the device.
545 * @param USBx Selected device
546 * @param speed device speed
547 * This parameter can be one of these values:
548 * @arg USB_OTG_SPEED_HIGH: High speed mode
549 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
550 * @arg USB_OTG_SPEED_FULL: Full speed mode
551 * @retval Hal status
552 */
USB_SetDevSpeed(const USB_OTG_GlobalTypeDef * USBx,uint8_t speed)553 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
554 {
555 uint32_t USBx_BASE = (uint32_t)USBx;
556
557 USBx_DEVICE->DCFG |= speed;
558 return HAL_OK;
559 }
560
561 /**
562 * @brief USB_GetDevSpeed Return the Dev Speed
563 * @param USBx Selected device
564 * @retval speed device speed
565 * This parameter can be one of these values:
566 * @arg USBD_HS_SPEED: High speed mode
567 * @arg USBD_FS_SPEED: Full speed mode
568 */
USB_GetDevSpeed(const USB_OTG_GlobalTypeDef * USBx)569 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
570 {
571 uint32_t USBx_BASE = (uint32_t)USBx;
572 uint8_t speed;
573 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
574
575 if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
576 {
577 speed = USBD_HS_SPEED;
578 }
579 else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
580 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
581 {
582 speed = USBD_FS_SPEED;
583 }
584 else
585 {
586 speed = 0xFU;
587 }
588
589 return speed;
590 }
591
592 /**
593 * @brief Activate and configure an endpoint
594 * @param USBx Selected device
595 * @param ep pointer to endpoint structure
596 * @retval HAL status
597 */
USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)598 HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
599 {
600 uint32_t USBx_BASE = (uint32_t)USBx;
601 uint32_t epnum = (uint32_t)ep->num;
602
603 if (ep->is_in == 1U)
604 {
605 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
606
607 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
608 {
609 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
610 ((uint32_t)ep->type << 18) | (epnum << 22) |
611 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
612 USB_OTG_DIEPCTL_USBAEP;
613 }
614 }
615 else
616 {
617 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
618
619 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
620 {
621 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
622 ((uint32_t)ep->type << 18) |
623 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
624 USB_OTG_DOEPCTL_USBAEP;
625 }
626 }
627 return HAL_OK;
628 }
629
630 /**
631 * @brief Activate and configure a dedicated endpoint
632 * @param USBx Selected device
633 * @param ep pointer to endpoint structure
634 * @retval HAL status
635 */
USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)636 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
637 {
638 uint32_t USBx_BASE = (uint32_t)USBx;
639 uint32_t epnum = (uint32_t)ep->num;
640
641 /* Read DEPCTLn register */
642 if (ep->is_in == 1U)
643 {
644 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
645 {
646 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
647 ((uint32_t)ep->type << 18) | (epnum << 22) |
648 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
649 USB_OTG_DIEPCTL_USBAEP;
650 }
651
652 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
653 }
654 else
655 {
656 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
657 {
658 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
659 ((uint32_t)ep->type << 18) | (epnum << 22) |
660 USB_OTG_DOEPCTL_USBAEP;
661 }
662
663 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
664 }
665
666 return HAL_OK;
667 }
668
669 /**
670 * @brief De-activate and de-initialize an endpoint
671 * @param USBx Selected device
672 * @param ep pointer to endpoint structure
673 * @retval HAL status
674 */
USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)675 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
676 {
677 uint32_t USBx_BASE = (uint32_t)USBx;
678 uint32_t epnum = (uint32_t)ep->num;
679
680 /* Read DEPCTLn register */
681 if (ep->is_in == 1U)
682 {
683 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
684 {
685 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
686 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
687 }
688
689 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
690 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
691 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
692 USB_OTG_DIEPCTL_MPSIZ |
693 USB_OTG_DIEPCTL_TXFNUM |
694 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
695 USB_OTG_DIEPCTL_EPTYP);
696 }
697 else
698 {
699 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
700 {
701 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
702 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
703 }
704
705 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
706 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
707 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
708 USB_OTG_DOEPCTL_MPSIZ |
709 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
710 USB_OTG_DOEPCTL_EPTYP);
711 }
712
713 return HAL_OK;
714 }
715
716 /**
717 * @brief De-activate and de-initialize a dedicated endpoint
718 * @param USBx Selected device
719 * @param ep pointer to endpoint structure
720 * @retval HAL status
721 */
USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)722 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
723 {
724 uint32_t USBx_BASE = (uint32_t)USBx;
725 uint32_t epnum = (uint32_t)ep->num;
726
727 /* Read DEPCTLn register */
728 if (ep->is_in == 1U)
729 {
730 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
731 {
732 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
733 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
734 }
735
736 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
737 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
738 }
739 else
740 {
741 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
742 {
743 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
744 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
745 }
746
747 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
748 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
749 }
750
751 return HAL_OK;
752 }
753
754 /**
755 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
756 * @param USBx Selected device
757 * @param ep pointer to endpoint structure
758 * @param dma USB dma enabled or disabled
759 * This parameter can be one of these values:
760 * 0 : DMA feature not used
761 * 1 : DMA feature used
762 * @retval HAL status
763 */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)764 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
765 {
766 uint32_t USBx_BASE = (uint32_t)USBx;
767 uint32_t epnum = (uint32_t)ep->num;
768 uint16_t pktcnt;
769
770 /* IN endpoint */
771 if (ep->is_in == 1U)
772 {
773 /* Zero Length Packet? */
774 if (ep->xfer_len == 0U)
775 {
776 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
777 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
778 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
779 }
780 else
781 {
782 /* Program the transfer size and packet count
783 * as follows: xfersize = N * maxpacket +
784 * short_packet pktcnt = N + (short_packet
785 * exist ? 1 : 0)
786 */
787 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
788 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
789
790 if (epnum == 0U)
791 {
792 if (ep->xfer_len > ep->maxpacket)
793 {
794 ep->xfer_len = ep->maxpacket;
795 }
796
797 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
798 }
799 else
800 {
801 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
802 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
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 & (pktcnt << 29));
808 }
809 }
810
811 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
812 }
813
814 if (dma == 1U)
815 {
816 if ((uint32_t)ep->dma_addr != 0U)
817 {
818 USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
819 }
820
821 if (ep->type == EP_TYPE_ISOC)
822 {
823 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
824 {
825 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
826 }
827 else
828 {
829 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
830 }
831 }
832
833 /* EP enable, IN data in FIFO */
834 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
835 }
836 else
837 {
838 /* EP enable, IN data in FIFO */
839 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
840
841 if (ep->type != EP_TYPE_ISOC)
842 {
843 /* Enable the Tx FIFO Empty Interrupt for this EP */
844 if (ep->xfer_len > 0U)
845 {
846 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
847 }
848 }
849 else
850 {
851 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
852 {
853 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
854 }
855 else
856 {
857 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
858 }
859
860 (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
861 }
862 }
863 }
864 else /* OUT endpoint */
865 {
866 /* Program the transfer size and packet count as follows:
867 * pktcnt = N
868 * xfersize = N * maxpacket
869 */
870 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
871 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
872
873 if (epnum == 0U)
874 {
875 if (ep->xfer_len > 0U)
876 {
877 ep->xfer_len = ep->maxpacket;
878 }
879
880 /* Store transfer size, for EP0 this is equal to endpoint max packet size */
881 ep->xfer_size = ep->maxpacket;
882
883 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
884 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
885 }
886 else
887 {
888 if (ep->xfer_len == 0U)
889 {
890 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
891 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
892 }
893 else
894 {
895 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
896 ep->xfer_size = ep->maxpacket * pktcnt;
897
898 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
899 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
900 }
901 }
902
903 if (dma == 1U)
904 {
905 if ((uint32_t)ep->xfer_buff != 0U)
906 {
907 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
908 }
909 }
910
911 if (ep->type == EP_TYPE_ISOC)
912 {
913 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
914 {
915 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
916 }
917 else
918 {
919 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
920 }
921 }
922 /* EP enable */
923 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
924 }
925
926 return HAL_OK;
927 }
928
929
930 /**
931 * @brief USB_EPStoptXfer Stop transfer on an EP
932 * @param USBx usb device instance
933 * @param ep pointer to endpoint structure
934 * @retval HAL status
935 */
USB_EPStopXfer(const USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)936 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
937 {
938 __IO uint32_t count = 0U;
939 HAL_StatusTypeDef ret = HAL_OK;
940 uint32_t USBx_BASE = (uint32_t)USBx;
941
942 /* IN endpoint */
943 if (ep->is_in == 1U)
944 {
945 /* EP enable, IN data in FIFO */
946 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
947 {
948 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
949 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
950
951 do
952 {
953 count++;
954
955 if (count > 10000U)
956 {
957 ret = HAL_ERROR;
958 break;
959 }
960 } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA);
961 }
962 }
963 else /* OUT endpoint */
964 {
965 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
966 {
967 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
968 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
969
970 do
971 {
972 count++;
973
974 if (count > 10000U)
975 {
976 ret = HAL_ERROR;
977 break;
978 }
979 } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA);
980 }
981 }
982
983 return ret;
984 }
985
986
987 /**
988 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
989 * with the EP/channel
990 * @param USBx Selected device
991 * @param src pointer to source buffer
992 * @param ch_ep_num endpoint or host channel number
993 * @param len Number of bytes to write
994 * @param dma USB dma enabled or disabled
995 * This parameter can be one of these values:
996 * 0 : DMA feature not used
997 * 1 : DMA feature used
998 * @retval HAL status
999 */
USB_WritePacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len,uint8_t dma)1000 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
1001 uint8_t ch_ep_num, uint16_t len, uint8_t dma)
1002 {
1003 uint32_t USBx_BASE = (uint32_t)USBx;
1004 uint8_t *pSrc = src;
1005 uint32_t count32b;
1006 uint32_t i;
1007
1008 if (dma == 0U)
1009 {
1010 count32b = ((uint32_t)len + 3U) / 4U;
1011 for (i = 0U; i < count32b; i++)
1012 {
1013 USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
1014 pSrc++;
1015 pSrc++;
1016 pSrc++;
1017 pSrc++;
1018 }
1019 }
1020
1021 return HAL_OK;
1022 }
1023
1024 /**
1025 * @brief USB_ReadPacket : read a packet from the RX FIFO
1026 * @param USBx Selected device
1027 * @param dest source pointer
1028 * @param len Number of bytes to read
1029 * @retval pointer to destination buffer
1030 */
USB_ReadPacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)1031 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1032 {
1033 uint32_t USBx_BASE = (uint32_t)USBx;
1034 uint8_t *pDest = dest;
1035 uint32_t pData;
1036 uint32_t i;
1037 uint32_t count32b = (uint32_t)len >> 2U;
1038 uint16_t remaining_bytes = len % 4U;
1039
1040 for (i = 0U; i < count32b; i++)
1041 {
1042 __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1043 pDest++;
1044 pDest++;
1045 pDest++;
1046 pDest++;
1047 }
1048
1049 /* When Number of data is not word aligned, read the remaining byte */
1050 if (remaining_bytes != 0U)
1051 {
1052 i = 0U;
1053 __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1054
1055 do
1056 {
1057 *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1058 i++;
1059 pDest++;
1060 remaining_bytes--;
1061 } while (remaining_bytes != 0U);
1062 }
1063
1064 return ((void *)pDest);
1065 }
1066
1067 /**
1068 * @brief USB_EPSetStall : set a stall condition over an EP
1069 * @param USBx Selected device
1070 * @param ep pointer to endpoint structure
1071 * @retval HAL status
1072 */
USB_EPSetStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1073 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1074 {
1075 uint32_t USBx_BASE = (uint32_t)USBx;
1076 uint32_t epnum = (uint32_t)ep->num;
1077
1078 if (ep->is_in == 1U)
1079 {
1080 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1081 {
1082 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1083 }
1084 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1085 }
1086 else
1087 {
1088 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1089 {
1090 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1091 }
1092 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1093 }
1094
1095 return HAL_OK;
1096 }
1097
1098 /**
1099 * @brief USB_EPClearStall : Clear a stall condition over an EP
1100 * @param USBx Selected device
1101 * @param ep pointer to endpoint structure
1102 * @retval HAL status
1103 */
USB_EPClearStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1104 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1105 {
1106 uint32_t USBx_BASE = (uint32_t)USBx;
1107 uint32_t epnum = (uint32_t)ep->num;
1108
1109 if (ep->is_in == 1U)
1110 {
1111 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1112 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1113 {
1114 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1115 }
1116 }
1117 else
1118 {
1119 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1120 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1121 {
1122 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1123 }
1124 }
1125 return HAL_OK;
1126 }
1127
1128 /**
1129 * @brief USB_StopDevice : Stop the usb device mode
1130 * @param USBx Selected device
1131 * @retval HAL status
1132 */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1133 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1134 {
1135 HAL_StatusTypeDef ret;
1136 uint32_t USBx_BASE = (uint32_t)USBx;
1137 uint32_t i;
1138
1139 /* Clear Pending interrupt */
1140 for (i = 0U; i < 15U; i++)
1141 {
1142 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1143 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1144 }
1145
1146 /* Clear interrupt masks */
1147 USBx_DEVICE->DIEPMSK = 0U;
1148 USBx_DEVICE->DOEPMSK = 0U;
1149 USBx_DEVICE->DAINTMSK = 0U;
1150
1151 /* Flush the FIFO */
1152 ret = USB_FlushRxFifo(USBx);
1153 if (ret != HAL_OK)
1154 {
1155 return ret;
1156 }
1157
1158 ret = USB_FlushTxFifo(USBx, 0x10U);
1159 if (ret != HAL_OK)
1160 {
1161 return ret;
1162 }
1163
1164 return ret;
1165 }
1166
1167 /**
1168 * @brief USB_SetDevAddress : Stop the usb device mode
1169 * @param USBx Selected device
1170 * @param address new device address to be assigned
1171 * This parameter can be a value from 0 to 255
1172 * @retval HAL status
1173 */
USB_SetDevAddress(const USB_OTG_GlobalTypeDef * USBx,uint8_t address)1174 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1175 {
1176 uint32_t USBx_BASE = (uint32_t)USBx;
1177
1178 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1179 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1180
1181 return HAL_OK;
1182 }
1183
1184 /**
1185 * @brief USB_DevConnect : Connect the USB device by enabling Rpu
1186 * @param USBx Selected device
1187 * @retval HAL status
1188 */
USB_DevConnect(const USB_OTG_GlobalTypeDef * USBx)1189 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1190 {
1191 uint32_t USBx_BASE = (uint32_t)USBx;
1192
1193 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1194 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1195
1196 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1197
1198 return HAL_OK;
1199 }
1200
1201 /**
1202 * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1203 * @param USBx Selected device
1204 * @retval HAL status
1205 */
USB_DevDisconnect(const USB_OTG_GlobalTypeDef * USBx)1206 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1207 {
1208 uint32_t USBx_BASE = (uint32_t)USBx;
1209
1210 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1211 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1212
1213 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1214
1215 return HAL_OK;
1216 }
1217
1218 /**
1219 * @brief USB_ReadInterrupts: return the global USB interrupt status
1220 * @param USBx Selected device
1221 * @retval USB Global Interrupt status
1222 */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef const * USBx)1223 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1224 {
1225 uint32_t tmpreg;
1226
1227 tmpreg = USBx->GINTSTS;
1228 tmpreg &= USBx->GINTMSK;
1229
1230 return tmpreg;
1231 }
1232
1233 /**
1234 * @brief USB_ReadChInterrupts: return USB channel interrupt status
1235 * @param USBx Selected device
1236 * @param chnum Channel number
1237 * @retval USB Channel Interrupt status
1238 */
USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef * USBx,uint8_t chnum)1239 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1240 {
1241 uint32_t USBx_BASE = (uint32_t)USBx;
1242 uint32_t tmpreg;
1243
1244 tmpreg = USBx_HC(chnum)->HCINT;
1245 tmpreg &= USBx_HC(chnum)->HCINTMSK;
1246
1247 return tmpreg;
1248 }
1249
1250 /**
1251 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1252 * @param USBx Selected device
1253 * @retval USB Device OUT EP interrupt status
1254 */
USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1255 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1256 {
1257 uint32_t USBx_BASE = (uint32_t)USBx;
1258 uint32_t tmpreg;
1259
1260 tmpreg = USBx_DEVICE->DAINT;
1261 tmpreg &= USBx_DEVICE->DAINTMSK;
1262
1263 return ((tmpreg & 0xffff0000U) >> 16);
1264 }
1265
1266 /**
1267 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1268 * @param USBx Selected device
1269 * @retval USB Device IN EP interrupt status
1270 */
USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1271 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1272 {
1273 uint32_t USBx_BASE = (uint32_t)USBx;
1274 uint32_t tmpreg;
1275
1276 tmpreg = USBx_DEVICE->DAINT;
1277 tmpreg &= USBx_DEVICE->DAINTMSK;
1278
1279 return ((tmpreg & 0xFFFFU));
1280 }
1281
1282 /**
1283 * @brief Returns Device OUT EP Interrupt register
1284 * @param USBx Selected device
1285 * @param epnum endpoint number
1286 * This parameter can be a value from 0 to 15
1287 * @retval Device OUT EP Interrupt register
1288 */
USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1289 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1290 {
1291 uint32_t USBx_BASE = (uint32_t)USBx;
1292 uint32_t tmpreg;
1293
1294 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1295 tmpreg &= USBx_DEVICE->DOEPMSK;
1296
1297 return tmpreg;
1298 }
1299
1300 /**
1301 * @brief Returns Device IN EP Interrupt register
1302 * @param USBx Selected device
1303 * @param epnum endpoint number
1304 * This parameter can be a value from 0 to 15
1305 * @retval Device IN EP Interrupt register
1306 */
USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1307 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1308 {
1309 uint32_t USBx_BASE = (uint32_t)USBx;
1310 uint32_t tmpreg;
1311 uint32_t msk;
1312 uint32_t emp;
1313
1314 msk = USBx_DEVICE->DIEPMSK;
1315 emp = USBx_DEVICE->DIEPEMPMSK;
1316 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1317 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1318
1319 return tmpreg;
1320 }
1321
1322 /**
1323 * @brief USB_ClearInterrupts: clear a USB interrupt
1324 * @param USBx Selected device
1325 * @param interrupt flag
1326 * @retval None
1327 */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1328 void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1329 {
1330 USBx->GINTSTS &= interrupt;
1331 }
1332
1333 /**
1334 * @brief Returns USB core mode
1335 * @param USBx Selected device
1336 * @retval return core mode : Host or Device
1337 * This parameter can be one of these values:
1338 * 0 : Host
1339 * 1 : Device
1340 */
USB_GetMode(const USB_OTG_GlobalTypeDef * USBx)1341 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1342 {
1343 return ((USBx->GINTSTS) & 0x1U);
1344 }
1345
1346 /**
1347 * @brief Activate EP0 for Setup transactions
1348 * @param USBx Selected device
1349 * @retval HAL status
1350 */
USB_ActivateSetup(const USB_OTG_GlobalTypeDef * USBx)1351 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1352 {
1353 uint32_t USBx_BASE = (uint32_t)USBx;
1354
1355 /* Set the MPS of the IN EP0 to 64 bytes */
1356 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1357
1358 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1359
1360 return HAL_OK;
1361 }
1362
1363 /**
1364 * @brief Prepare the EP0 to start the first control setup
1365 * @param USBx Selected device
1366 * @param dma USB dma enabled or disabled
1367 * This parameter can be one of these values:
1368 * 0 : DMA feature not used
1369 * 1 : DMA feature used
1370 * @param psetup pointer to setup packet
1371 * @retval HAL status
1372 */
USB_EP0_OutStart(const USB_OTG_GlobalTypeDef * USBx,uint8_t dma,const uint8_t * psetup)1373 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup)
1374 {
1375 uint32_t USBx_BASE = (uint32_t)USBx;
1376 uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1377
1378 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1379 {
1380 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1381 {
1382 return HAL_OK;
1383 }
1384 }
1385
1386 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1387 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1388 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1389 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1390
1391 if (dma == 1U)
1392 {
1393 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1394 /* EP enable */
1395 USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1396 }
1397
1398 return HAL_OK;
1399 }
1400
1401 /**
1402 * @brief Reset the USB Core (needed after USB clock settings change)
1403 * @param USBx Selected device
1404 * @retval HAL status
1405 */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1406 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1407 {
1408 __IO uint32_t count = 0U;
1409
1410 /* Wait for AHB master IDLE state. */
1411 do
1412 {
1413 count++;
1414
1415 if (count > HAL_USB_TIMEOUT)
1416 {
1417 return HAL_TIMEOUT;
1418 }
1419 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1420
1421 /* Core Soft Reset */
1422 count = 0U;
1423 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1424
1425 do
1426 {
1427 count++;
1428
1429 if (count > HAL_USB_TIMEOUT)
1430 {
1431 return HAL_TIMEOUT;
1432 }
1433 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1434
1435 return HAL_OK;
1436 }
1437
1438 /**
1439 * @brief USB_HostInit : Initializes the USB OTG controller registers
1440 * for Host mode
1441 * @param USBx Selected device
1442 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
1443 * the configuration information for the specified USBx peripheral.
1444 * @retval HAL status
1445 */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1446 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1447 {
1448 HAL_StatusTypeDef ret = HAL_OK;
1449 uint32_t USBx_BASE = (uint32_t)USBx;
1450 uint32_t i;
1451
1452 /* Restart the Phy Clock */
1453 USBx_PCGCCTL = 0U;
1454
1455 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
1456 || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
1457 || defined(STM32F423xx)
1458 /* Disable HW VBUS sensing */
1459 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1460 #else
1461 /*
1462 * Disable HW VBUS sensing. VBUS is internally considered to be always
1463 * at VBUS-Valid level (5V).
1464 */
1465 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
1466 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
1467 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
1468 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
1469 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
1470 defined(STM32F423xx) */
1471 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) \
1472 || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1473 /* Disable Battery chargin detector */
1474 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1475 #endif /* defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||
1476 defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
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