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