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 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
20
21 (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
22
23 (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
24
25 @endverbatim
26 ******************************************************************************
27 * @attention
28 *
29 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
30 * All rights reserved.</center></h2>
31 *
32 * This software component is licensed by ST under BSD 3-Clause license,
33 * the "License"; You may not use this file except in compliance with the
34 * License. You may obtain a copy of the License at:
35 * opensource.org/licenses/BSD-3-Clause
36 *
37 ******************************************************************************
38 */
39
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32f4xx_hal.h"
42
43 /** @addtogroup STM32F4xx_LL_USB_DRIVER
44 * @{
45 */
46
47 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
48 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
49 /* Private typedef -----------------------------------------------------------*/
50 /* Private define ------------------------------------------------------------*/
51 /* Private macro -------------------------------------------------------------*/
52 /* Private variables ---------------------------------------------------------*/
53 /* Private function prototypes -----------------------------------------------*/
54 /* Private functions ---------------------------------------------------------*/
55 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
56 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
57
58 /* Exported functions --------------------------------------------------------*/
59 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
60 * @{
61 */
62
63 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
64 * @brief Initialization and Configuration functions
65 *
66 @verbatim
67 ===============================================================================
68 ##### Initialization/de-initialization functions #####
69 ===============================================================================
70
71 @endverbatim
72 * @{
73 */
74
75 /**
76 * @brief Initializes the USB Core
77 * @param USBx USB Instance
78 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
79 * the configuration information for the specified USBx peripheral.
80 * @retval HAL status
81 */
USB_CoreInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)82 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
83 {
84 HAL_StatusTypeDef ret;
85
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(1U);
262 ms++;
263 } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < 50U));
264 }
265 else if (mode == USB_DEVICE_MODE)
266 {
267 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
268
269 do
270 {
271 HAL_Delay(1U);
272 ms++;
273 } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < 50U));
274 }
275 else
276 {
277 return HAL_ERROR;
278 }
279
280 if (ms == 50U)
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) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
308 /* VBUS Sensing setup */
309 if (cfg.vbus_sensing_enable == 0U)
310 {
311 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
312
313 /* Deactivate VBUS Sensing B */
314 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
315
316 /* B-peripheral session valid override enable */
317 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
318 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
319 }
320 else
321 {
322 /* Enable HW VBUS sensing */
323 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
324 }
325 #else
326 /* VBUS Sensing setup */
327 if (cfg.vbus_sensing_enable == 0U)
328 {
329 /*
330 * Disable HW VBUS sensing. VBUS is internally considered to be always
331 * at VBUS-Valid level (5V).
332 */
333 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
334 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
335 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
336 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
337 }
338 else
339 {
340 /* Enable HW VBUS sensing */
341 USBx->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
342 USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
343 }
344 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
345
346 /* Restart the Phy Clock */
347 USBx_PCGCCTL = 0U;
348
349 /* Device mode configuration */
350 USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
351
352 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
353 {
354 if (cfg.speed == USBD_HS_SPEED)
355 {
356 /* Set Core speed to High speed mode */
357 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
358 }
359 else
360 {
361 /* Set Core speed to Full speed mode */
362 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
363 }
364 }
365 else
366 {
367 /* Set Core speed to Full speed mode */
368 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
369 }
370
371 /* Flush the FIFOs */
372 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
373 {
374 ret = HAL_ERROR;
375 }
376
377 if (USB_FlushRxFifo(USBx) != HAL_OK)
378 {
379 ret = HAL_ERROR;
380 }
381
382 /* Clear all pending Device Interrupts */
383 USBx_DEVICE->DIEPMSK = 0U;
384 USBx_DEVICE->DOEPMSK = 0U;
385 USBx_DEVICE->DAINTMSK = 0U;
386
387 for (i = 0U; i < cfg.dev_endpoints; i++)
388 {
389 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
390 {
391 if (i == 0U)
392 {
393 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
394 }
395 else
396 {
397 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
398 }
399 }
400 else
401 {
402 USBx_INEP(i)->DIEPCTL = 0U;
403 }
404
405 USBx_INEP(i)->DIEPTSIZ = 0U;
406 USBx_INEP(i)->DIEPINT = 0xFB7FU;
407 }
408
409 for (i = 0U; i < cfg.dev_endpoints; i++)
410 {
411 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
412 {
413 if (i == 0U)
414 {
415 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
416 }
417 else
418 {
419 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
420 }
421 }
422 else
423 {
424 USBx_OUTEP(i)->DOEPCTL = 0U;
425 }
426
427 USBx_OUTEP(i)->DOEPTSIZ = 0U;
428 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
429 }
430
431 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
432
433 /* Disable all interrupts. */
434 USBx->GINTMSK = 0U;
435
436 /* Clear any pending interrupts */
437 USBx->GINTSTS = 0xBFFFFFFFU;
438
439 /* Enable the common interrupts */
440 if (cfg.dma_enable == 0U)
441 {
442 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
443 }
444
445 /* Enable interrupts matching to the Device mode ONLY */
446 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
447 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
448 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
449 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
450
451 if (cfg.Sof_enable != 0U)
452 {
453 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
454 }
455
456 if (cfg.vbus_sensing_enable == 1U)
457 {
458 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
459 }
460
461 return ret;
462 }
463
464 /**
465 * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
466 * @param USBx Selected device
467 * @param num FIFO number
468 * This parameter can be a value from 1 to 15
469 15 means Flush all Tx FIFOs
470 * @retval HAL status
471 */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)472 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
473 {
474 __IO uint32_t count = 0U;
475
476 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
477
478 do
479 {
480 if (++count > 200000U)
481 {
482 return HAL_TIMEOUT;
483 }
484 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
485
486 return HAL_OK;
487 }
488
489 /**
490 * @brief USB_FlushRxFifo : Flush Rx FIFO
491 * @param USBx Selected device
492 * @retval HAL status
493 */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)494 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
495 {
496 __IO uint32_t count = 0U;
497
498 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
499
500 do
501 {
502 if (++count > 200000U)
503 {
504 return HAL_TIMEOUT;
505 }
506 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
507
508 return HAL_OK;
509 }
510
511 /**
512 * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
513 * depending the PHY type and the enumeration speed of the device.
514 * @param USBx Selected device
515 * @param speed device speed
516 * This parameter can be one of these values:
517 * @arg USB_OTG_SPEED_HIGH: High speed mode
518 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
519 * @arg USB_OTG_SPEED_FULL: Full speed mode
520 * @retval Hal status
521 */
USB_SetDevSpeed(USB_OTG_GlobalTypeDef * USBx,uint8_t speed)522 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
523 {
524 uint32_t USBx_BASE = (uint32_t)USBx;
525
526 USBx_DEVICE->DCFG |= speed;
527 return HAL_OK;
528 }
529
530 /**
531 * @brief USB_GetDevSpeed Return the Dev Speed
532 * @param USBx Selected device
533 * @retval speed device speed
534 * This parameter can be one of these values:
535 * @arg USBD_HS_SPEED: High speed mode
536 * @arg USBD_FS_SPEED: Full speed mode
537 */
USB_GetDevSpeed(USB_OTG_GlobalTypeDef * USBx)538 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
539 {
540 uint32_t USBx_BASE = (uint32_t)USBx;
541 uint8_t speed;
542 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
543
544 if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
545 {
546 speed = USBD_HS_SPEED;
547 }
548 else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
549 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
550 {
551 speed = USBD_FS_SPEED;
552 }
553 else
554 {
555 speed = 0xFU;
556 }
557
558 return speed;
559 }
560
561 /**
562 * @brief Activate and configure an endpoint
563 * @param USBx Selected device
564 * @param ep pointer to endpoint structure
565 * @retval HAL status
566 */
USB_ActivateEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)567 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
568 {
569 uint32_t USBx_BASE = (uint32_t)USBx;
570 uint32_t epnum = (uint32_t)ep->num;
571
572 if (ep->is_in == 1U)
573 {
574 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
575
576 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
577 {
578 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
579 ((uint32_t)ep->type << 18) | (epnum << 22) |
580 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
581 USB_OTG_DIEPCTL_USBAEP;
582 }
583 }
584 else
585 {
586 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
587
588 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
589 {
590 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
591 ((uint32_t)ep->type << 18) |
592 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
593 USB_OTG_DOEPCTL_USBAEP;
594 }
595 }
596 return HAL_OK;
597 }
598
599 /**
600 * @brief Activate and configure a dedicated endpoint
601 * @param USBx Selected device
602 * @param ep pointer to endpoint structure
603 * @retval HAL status
604 */
USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)605 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
606 {
607 uint32_t USBx_BASE = (uint32_t)USBx;
608 uint32_t epnum = (uint32_t)ep->num;
609
610 /* Read DEPCTLn register */
611 if (ep->is_in == 1U)
612 {
613 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
614 {
615 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
616 ((uint32_t)ep->type << 18) | (epnum << 22) |
617 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
618 USB_OTG_DIEPCTL_USBAEP;
619 }
620
621 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
622 }
623 else
624 {
625 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
626 {
627 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
628 ((uint32_t)ep->type << 18) | (epnum << 22) |
629 USB_OTG_DOEPCTL_USBAEP;
630 }
631
632 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
633 }
634
635 return HAL_OK;
636 }
637
638 /**
639 * @brief De-activate and de-initialize an endpoint
640 * @param USBx Selected device
641 * @param ep pointer to endpoint structure
642 * @retval HAL status
643 */
USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)644 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
645 {
646 uint32_t USBx_BASE = (uint32_t)USBx;
647 uint32_t epnum = (uint32_t)ep->num;
648
649 /* Read DEPCTLn register */
650 if (ep->is_in == 1U)
651 {
652 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
653 {
654 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
655 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
656 }
657
658 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
659 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
660 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
661 USB_OTG_DIEPCTL_MPSIZ |
662 USB_OTG_DIEPCTL_TXFNUM |
663 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
664 USB_OTG_DIEPCTL_EPTYP);
665 }
666 else
667 {
668 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
669 {
670 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
671 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
672 }
673
674 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
675 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
676 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
677 USB_OTG_DOEPCTL_MPSIZ |
678 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
679 USB_OTG_DOEPCTL_EPTYP);
680 }
681
682 return HAL_OK;
683 }
684
685 /**
686 * @brief De-activate and de-initialize a dedicated endpoint
687 * @param USBx Selected device
688 * @param ep pointer to endpoint structure
689 * @retval HAL status
690 */
USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)691 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
692 {
693 uint32_t USBx_BASE = (uint32_t)USBx;
694 uint32_t epnum = (uint32_t)ep->num;
695
696 /* Read DEPCTLn register */
697 if (ep->is_in == 1U)
698 {
699 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
700 {
701 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
702 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
703 }
704
705 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
706 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
707 }
708 else
709 {
710 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
711 {
712 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
713 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
714 }
715
716 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
717 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
718 }
719
720 return HAL_OK;
721 }
722
723 /**
724 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
725 * @param USBx Selected device
726 * @param ep pointer to endpoint structure
727 * @param dma USB dma enabled or disabled
728 * This parameter can be one of these values:
729 * 0 : DMA feature not used
730 * 1 : DMA feature used
731 * @retval HAL status
732 */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)733 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
734 {
735 uint32_t USBx_BASE = (uint32_t)USBx;
736 uint32_t epnum = (uint32_t)ep->num;
737 uint16_t pktcnt;
738
739 /* IN endpoint */
740 if (ep->is_in == 1U)
741 {
742 /* Zero Length Packet? */
743 if (ep->xfer_len == 0U)
744 {
745 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
746 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
747 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
748 }
749 else
750 {
751 /* Program the transfer size and packet count
752 * as follows: xfersize = N * maxpacket +
753 * short_packet pktcnt = N + (short_packet
754 * exist ? 1 : 0)
755 */
756 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
757 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
758 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
759 (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
760
761 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
762
763 if (ep->type == EP_TYPE_ISOC)
764 {
765 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
766 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
767 }
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 (ep->xfer_len == 0U)
830 {
831 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
832 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
833 }
834 else
835 {
836 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
837 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
838 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt);
839 }
840
841 if (dma == 1U)
842 {
843 if ((uint32_t)ep->xfer_buff != 0U)
844 {
845 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
846 }
847 }
848
849 if (ep->type == EP_TYPE_ISOC)
850 {
851 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
852 {
853 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
854 }
855 else
856 {
857 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
858 }
859 }
860 /* EP enable */
861 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
862 }
863
864 return HAL_OK;
865 }
866
867 /**
868 * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
869 * @param USBx Selected device
870 * @param ep pointer to endpoint structure
871 * @param dma USB dma enabled or disabled
872 * This parameter can be one of these values:
873 * 0 : DMA feature not used
874 * 1 : DMA feature used
875 * @retval HAL status
876 */
USB_EP0StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)877 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
878 {
879 uint32_t USBx_BASE = (uint32_t)USBx;
880 uint32_t epnum = (uint32_t)ep->num;
881
882 /* IN endpoint */
883 if (ep->is_in == 1U)
884 {
885 /* Zero Length Packet? */
886 if (ep->xfer_len == 0U)
887 {
888 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
889 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
890 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
891 }
892 else
893 {
894 /* Program the transfer size and packet count
895 * as follows: xfersize = N * maxpacket +
896 * short_packet pktcnt = N + (short_packet
897 * exist ? 1 : 0)
898 */
899 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
900 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
901
902 if (ep->xfer_len > ep->maxpacket)
903 {
904 ep->xfer_len = ep->maxpacket;
905 }
906 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
907 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
908 }
909
910 if (dma == 1U)
911 {
912 if ((uint32_t)ep->dma_addr != 0U)
913 {
914 USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
915 }
916
917 /* EP enable, IN data in FIFO */
918 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
919 }
920 else
921 {
922 /* EP enable, IN data in FIFO */
923 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
924
925 /* Enable the Tx FIFO Empty Interrupt for this EP */
926 if (ep->xfer_len > 0U)
927 {
928 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
929 }
930 }
931 }
932 else /* OUT endpoint */
933 {
934 /* Program the transfer size and packet count as follows:
935 * pktcnt = N
936 * xfersize = N * maxpacket
937 */
938 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
939 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
940
941 if (ep->xfer_len > 0U)
942 {
943 ep->xfer_len = ep->maxpacket;
944 }
945
946 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
947 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
948
949 if (dma == 1U)
950 {
951 if ((uint32_t)ep->xfer_buff != 0U)
952 {
953 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
954 }
955 }
956
957 /* EP enable */
958 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
959 }
960
961 return HAL_OK;
962 }
963
964 /**
965 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
966 * with the EP/channel
967 * @param USBx Selected device
968 * @param src pointer to source buffer
969 * @param ch_ep_num endpoint or host channel number
970 * @param len Number of bytes to write
971 * @param dma USB dma enabled or disabled
972 * This parameter can be one of these values:
973 * 0 : DMA feature not used
974 * 1 : DMA feature used
975 * @retval HAL status
976 */
USB_WritePacket(USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len,uint8_t dma)977 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
978 uint8_t ch_ep_num, uint16_t len, uint8_t dma)
979 {
980 uint32_t USBx_BASE = (uint32_t)USBx;
981 uint8_t *pSrc = src;
982 uint32_t count32b;
983 uint32_t i;
984
985 if (dma == 0U)
986 {
987 count32b = ((uint32_t)len + 3U) / 4U;
988 for (i = 0U; i < count32b; i++)
989 {
990 USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
991 pSrc++;
992 pSrc++;
993 pSrc++;
994 pSrc++;
995 }
996 }
997
998 return HAL_OK;
999 }
1000
1001 /**
1002 * @brief USB_ReadPacket : read a packet from the RX FIFO
1003 * @param USBx Selected device
1004 * @param dest source pointer
1005 * @param len Number of bytes to read
1006 * @retval pointer to destination buffer
1007 */
USB_ReadPacket(USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)1008 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1009 {
1010 uint32_t USBx_BASE = (uint32_t)USBx;
1011 uint8_t *pDest = dest;
1012 uint32_t pData;
1013 uint32_t i;
1014 uint32_t count32b = (uint32_t)len >> 2U;
1015 uint16_t remaining_bytes = len % 4U;
1016
1017 for (i = 0U; i < count32b; i++)
1018 {
1019 __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1020 pDest++;
1021 pDest++;
1022 pDest++;
1023 pDest++;
1024 }
1025
1026 /* When Number of data is not word aligned, read the remaining byte */
1027 if (remaining_bytes != 0U)
1028 {
1029 i = 0U;
1030 __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1031
1032 do
1033 {
1034 *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1035 i++;
1036 pDest++;
1037 remaining_bytes--;
1038 } while (remaining_bytes != 0U);
1039 }
1040
1041 return ((void *)pDest);
1042 }
1043
1044 /**
1045 * @brief USB_EPSetStall : set a stall condition over an EP
1046 * @param USBx Selected device
1047 * @param ep pointer to endpoint structure
1048 * @retval HAL status
1049 */
USB_EPSetStall(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)1050 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
1051 {
1052 uint32_t USBx_BASE = (uint32_t)USBx;
1053 uint32_t epnum = (uint32_t)ep->num;
1054
1055 if (ep->is_in == 1U)
1056 {
1057 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1058 {
1059 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1060 }
1061 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1062 }
1063 else
1064 {
1065 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1066 {
1067 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1068 }
1069 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1070 }
1071
1072 return HAL_OK;
1073 }
1074
1075 /**
1076 * @brief USB_EPClearStall : Clear a stall condition over an EP
1077 * @param USBx Selected device
1078 * @param ep pointer to endpoint structure
1079 * @retval HAL status
1080 */
USB_EPClearStall(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)1081 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
1082 {
1083 uint32_t USBx_BASE = (uint32_t)USBx;
1084 uint32_t epnum = (uint32_t)ep->num;
1085
1086 if (ep->is_in == 1U)
1087 {
1088 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1089 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1090 {
1091 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1092 }
1093 }
1094 else
1095 {
1096 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1097 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1098 {
1099 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1100 }
1101 }
1102 return HAL_OK;
1103 }
1104
1105 /**
1106 * @brief USB_StopDevice : Stop the usb device mode
1107 * @param USBx Selected device
1108 * @retval HAL status
1109 */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1110 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1111 {
1112 HAL_StatusTypeDef ret;
1113 uint32_t USBx_BASE = (uint32_t)USBx;
1114 uint32_t i;
1115
1116 /* Clear Pending interrupt */
1117 for (i = 0U; i < 15U; i++)
1118 {
1119 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1120 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1121 }
1122
1123 /* Clear interrupt masks */
1124 USBx_DEVICE->DIEPMSK = 0U;
1125 USBx_DEVICE->DOEPMSK = 0U;
1126 USBx_DEVICE->DAINTMSK = 0U;
1127
1128 /* Flush the FIFO */
1129 ret = USB_FlushRxFifo(USBx);
1130 if (ret != HAL_OK)
1131 {
1132 return ret;
1133 }
1134
1135 ret = USB_FlushTxFifo(USBx, 0x10U);
1136 if (ret != HAL_OK)
1137 {
1138 return ret;
1139 }
1140
1141 return ret;
1142 }
1143
1144 /**
1145 * @brief USB_SetDevAddress : Stop the usb device mode
1146 * @param USBx Selected device
1147 * @param address new device address to be assigned
1148 * This parameter can be a value from 0 to 255
1149 * @retval HAL status
1150 */
USB_SetDevAddress(USB_OTG_GlobalTypeDef * USBx,uint8_t address)1151 HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1152 {
1153 uint32_t USBx_BASE = (uint32_t)USBx;
1154
1155 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1156 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1157
1158 return HAL_OK;
1159 }
1160
1161 /**
1162 * @brief USB_DevConnect : Connect the USB device by enabling Rpu
1163 * @param USBx Selected device
1164 * @retval HAL status
1165 */
USB_DevConnect(USB_OTG_GlobalTypeDef * USBx)1166 HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
1167 {
1168 uint32_t USBx_BASE = (uint32_t)USBx;
1169
1170 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1171 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1172
1173 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1174
1175 return HAL_OK;
1176 }
1177
1178 /**
1179 * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1180 * @param USBx Selected device
1181 * @retval HAL status
1182 */
USB_DevDisconnect(USB_OTG_GlobalTypeDef * USBx)1183 HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
1184 {
1185 uint32_t USBx_BASE = (uint32_t)USBx;
1186
1187 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1188 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1189
1190 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1191
1192 return HAL_OK;
1193 }
1194
1195 /**
1196 * @brief USB_ReadInterrupts: return the global USB interrupt status
1197 * @param USBx Selected device
1198 * @retval HAL status
1199 */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef * USBx)1200 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
1201 {
1202 uint32_t tmpreg;
1203
1204 tmpreg = USBx->GINTSTS;
1205 tmpreg &= USBx->GINTMSK;
1206
1207 return tmpreg;
1208 }
1209
1210 /**
1211 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1212 * @param USBx Selected device
1213 * @retval HAL status
1214 */
USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef * USBx)1215 uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1216 {
1217 uint32_t USBx_BASE = (uint32_t)USBx;
1218 uint32_t tmpreg;
1219
1220 tmpreg = USBx_DEVICE->DAINT;
1221 tmpreg &= USBx_DEVICE->DAINTMSK;
1222
1223 return ((tmpreg & 0xffff0000U) >> 16);
1224 }
1225
1226 /**
1227 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1228 * @param USBx Selected device
1229 * @retval HAL status
1230 */
USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef * USBx)1231 uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1232 {
1233 uint32_t USBx_BASE = (uint32_t)USBx;
1234 uint32_t tmpreg;
1235
1236 tmpreg = USBx_DEVICE->DAINT;
1237 tmpreg &= USBx_DEVICE->DAINTMSK;
1238
1239 return ((tmpreg & 0xFFFFU));
1240 }
1241
1242 /**
1243 * @brief Returns Device OUT EP Interrupt register
1244 * @param USBx Selected device
1245 * @param epnum endpoint number
1246 * This parameter can be a value from 0 to 15
1247 * @retval Device OUT EP Interrupt register
1248 */
USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1249 uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1250 {
1251 uint32_t USBx_BASE = (uint32_t)USBx;
1252 uint32_t tmpreg;
1253
1254 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1255 tmpreg &= USBx_DEVICE->DOEPMSK;
1256
1257 return tmpreg;
1258 }
1259
1260 /**
1261 * @brief Returns Device IN EP Interrupt register
1262 * @param USBx Selected device
1263 * @param epnum endpoint number
1264 * This parameter can be a value from 0 to 15
1265 * @retval Device IN EP Interrupt register
1266 */
USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1267 uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1268 {
1269 uint32_t USBx_BASE = (uint32_t)USBx;
1270 uint32_t tmpreg;
1271 uint32_t msk;
1272 uint32_t emp;
1273
1274 msk = USBx_DEVICE->DIEPMSK;
1275 emp = USBx_DEVICE->DIEPEMPMSK;
1276 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1277 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1278
1279 return tmpreg;
1280 }
1281
1282 /**
1283 * @brief USB_ClearInterrupts: clear a USB interrupt
1284 * @param USBx Selected device
1285 * @param interrupt flag
1286 * @retval None
1287 */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1288 void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1289 {
1290 USBx->GINTSTS |= interrupt;
1291 }
1292
1293 /**
1294 * @brief Returns USB core mode
1295 * @param USBx Selected device
1296 * @retval return core mode : Host or Device
1297 * This parameter can be one of these values:
1298 * 0 : Host
1299 * 1 : Device
1300 */
USB_GetMode(USB_OTG_GlobalTypeDef * USBx)1301 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
1302 {
1303 return ((USBx->GINTSTS) & 0x1U);
1304 }
1305
1306 /**
1307 * @brief Activate EP0 for Setup transactions
1308 * @param USBx Selected device
1309 * @retval HAL status
1310 */
USB_ActivateSetup(USB_OTG_GlobalTypeDef * USBx)1311 HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
1312 {
1313 uint32_t USBx_BASE = (uint32_t)USBx;
1314
1315 /* Set the MPS of the IN EP0 to 64 bytes */
1316 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1317
1318 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1319
1320 return HAL_OK;
1321 }
1322
1323 /**
1324 * @brief Prepare the EP0 to start the first control setup
1325 * @param USBx Selected device
1326 * @param dma USB dma enabled or disabled
1327 * This parameter can be one of these values:
1328 * 0 : DMA feature not used
1329 * 1 : DMA feature used
1330 * @param psetup pointer to setup packet
1331 * @retval HAL status
1332 */
USB_EP0_OutStart(USB_OTG_GlobalTypeDef * USBx,uint8_t dma,uint8_t * psetup)1333 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup)
1334 {
1335 uint32_t USBx_BASE = (uint32_t)USBx;
1336 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
1337
1338 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1339 {
1340 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1341 {
1342 return HAL_OK;
1343 }
1344 }
1345
1346 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1347 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1348 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1349 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1350
1351 if (dma == 1U)
1352 {
1353 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1354 /* EP enable */
1355 USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1356 }
1357
1358 return HAL_OK;
1359 }
1360
1361 /**
1362 * @brief Reset the USB Core (needed after USB clock settings change)
1363 * @param USBx Selected device
1364 * @retval HAL status
1365 */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1366 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1367 {
1368 __IO uint32_t count = 0U;
1369
1370 /* Wait for AHB master IDLE state. */
1371 do
1372 {
1373 if (++count > 200000U)
1374 {
1375 return HAL_TIMEOUT;
1376 }
1377 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1378
1379 /* Core Soft Reset */
1380 count = 0U;
1381 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1382
1383 do
1384 {
1385 if (++count > 200000U)
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 uint32_t USBx_BASE = (uint32_t)USBx;
1405 uint32_t i;
1406
1407 /* Restart the Phy Clock */
1408 USBx_PCGCCTL = 0U;
1409
1410 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1411 /* Disable HW VBUS sensing */
1412 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1413 #else
1414 /*
1415 * Disable HW VBUS sensing. VBUS is internally considered to be always
1416 * at VBUS-Valid level (5V).
1417 */
1418 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
1419 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
1420 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
1421 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
1422 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1423 /* Disable Battery chargin detector */
1424 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1425 #endif /* defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
1426
1427 if ((USBx->CID & (0x1U << 8)) != 0U)
1428 {
1429 if (cfg.speed == USBH_FSLS_SPEED)
1430 {
1431 /* Force Device Enumeration to FS/LS mode only */
1432 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1433 }
1434 else
1435 {
1436 /* Set default Max speed support */
1437 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1438 }
1439 }
1440 else
1441 {
1442 /* Set default Max speed support */
1443 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1444 }
1445
1446 /* Make sure the FIFOs are flushed. */
1447 (void)USB_FlushTxFifo(USBx, 0x10U); /* all Tx FIFOs */
1448 (void)USB_FlushRxFifo(USBx);
1449
1450 /* Clear all pending HC Interrupts */
1451 for (i = 0U; i < cfg.Host_channels; i++)
1452 {
1453 USBx_HC(i)->HCINT = 0xFFFFFFFFU;
1454 USBx_HC(i)->HCINTMSK = 0U;
1455 }
1456
1457 /* Disable all interrupts. */
1458 USBx->GINTMSK = 0U;
1459
1460 /* Clear any pending interrupts */
1461 USBx->GINTSTS = 0xFFFFFFFFU;
1462
1463 if ((USBx->CID & (0x1U << 8)) != 0U)
1464 {
1465 /* set Rx FIFO size */
1466 USBx->GRXFSIZ = 0x200U;
1467 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
1468 USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1469 }
1470 else
1471 {
1472 /* set Rx FIFO size */
1473 USBx->GRXFSIZ = 0x80U;
1474 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1475 USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1476 }
1477
1478 /* Enable the common interrupts */
1479 if (cfg.dma_enable == 0U)
1480 {
1481 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1482 }
1483
1484 /* Enable interrupts matching to the Host mode ONLY */
1485 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
1486 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
1487 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1488
1489 return HAL_OK;
1490 }
1491
1492 /**
1493 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1494 * HCFG register on the PHY type and set the right frame interval
1495 * @param USBx Selected device
1496 * @param freq clock frequency
1497 * This parameter can be one of these values:
1498 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1499 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1500 * @retval HAL status
1501 */
USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1502 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1503 {
1504 uint32_t USBx_BASE = (uint32_t)USBx;
1505
1506 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1507 USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1508
1509 if (freq == HCFG_48_MHZ)
1510 {
1511 USBx_HOST->HFIR = 48000U;
1512 }
1513 else if (freq == HCFG_6_MHZ)
1514 {
1515 USBx_HOST->HFIR = 6000U;
1516 }
1517 else
1518 {
1519 /* ... */
1520 }
1521
1522 return HAL_OK;
1523 }
1524
1525 /**
1526 * @brief USB_OTG_ResetPort : Reset Host Port
1527 * @param USBx Selected device
1528 * @retval HAL status
1529 * @note (1)The application must wait at least 10 ms
1530 * before clearing the reset bit.
1531 */
USB_ResetPort(USB_OTG_GlobalTypeDef * USBx)1532 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
1533 {
1534 uint32_t USBx_BASE = (uint32_t)USBx;
1535
1536 __IO uint32_t hprt0 = 0U;
1537
1538 hprt0 = USBx_HPRT0;
1539
1540 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1541 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1542
1543 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1544 HAL_Delay(100U); /* See Note #1 */
1545 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1546 HAL_Delay(10U);
1547
1548 return HAL_OK;
1549 }
1550
1551 /**
1552 * @brief USB_DriveVbus : activate or de-activate vbus
1553 * @param state VBUS state
1554 * This parameter can be one of these values:
1555 * 0 : Deactivate VBUS
1556 * 1 : Activate VBUS
1557 * @retval HAL status
1558 */
USB_DriveVbus(USB_OTG_GlobalTypeDef * USBx,uint8_t state)1559 HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1560 {
1561 uint32_t USBx_BASE = (uint32_t)USBx;
1562 __IO uint32_t hprt0 = 0U;
1563
1564 hprt0 = USBx_HPRT0;
1565
1566 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1567 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1568
1569 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1570 {
1571 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1572 }
1573 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1574 {
1575 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1576 }
1577 return HAL_OK;
1578 }
1579
1580 /**
1581 * @brief Return Host Core speed
1582 * @param USBx Selected device
1583 * @retval speed : Host speed
1584 * This parameter can be one of these values:
1585 * @arg HCD_SPEED_HIGH: High speed mode
1586 * @arg HCD_SPEED_FULL: Full speed mode
1587 * @arg HCD_SPEED_LOW: Low speed mode
1588 */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef * USBx)1589 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx)
1590 {
1591 uint32_t USBx_BASE = (uint32_t)USBx;
1592 __IO uint32_t hprt0 = 0U;
1593
1594 hprt0 = USBx_HPRT0;
1595 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1596 }
1597
1598 /**
1599 * @brief Return Host Current Frame number
1600 * @param USBx Selected device
1601 * @retval current frame number
1602 */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef * USBx)1603 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx)
1604 {
1605 uint32_t USBx_BASE = (uint32_t)USBx;
1606
1607 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1608 }
1609
1610 /**
1611 * @brief Initialize a host channel
1612 * @param USBx Selected device
1613 * @param ch_num Channel number
1614 * This parameter can be a value from 1 to 15
1615 * @param epnum Endpoint number
1616 * This parameter can be a value from 1 to 15
1617 * @param dev_address Current device address
1618 * This parameter can be a value from 0 to 255
1619 * @param speed Current device speed
1620 * This parameter can be one of these values:
1621 * @arg USB_OTG_SPEED_HIGH: High speed mode
1622 * @arg USB_OTG_SPEED_FULL: Full speed mode
1623 * @arg USB_OTG_SPEED_LOW: Low speed mode
1624 * @param ep_type Endpoint Type
1625 * This parameter can be one of these values:
1626 * @arg EP_TYPE_CTRL: Control type
1627 * @arg EP_TYPE_ISOC: Isochronous type
1628 * @arg EP_TYPE_BULK: Bulk type
1629 * @arg EP_TYPE_INTR: Interrupt type
1630 * @param mps Max Packet Size
1631 * This parameter can be a value from 0 to 32K
1632 * @retval HAL state
1633 */
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)1634 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1635 uint8_t epnum, uint8_t dev_address, uint8_t speed,
1636 uint8_t ep_type, uint16_t mps)
1637 {
1638 HAL_StatusTypeDef ret = HAL_OK;
1639 uint32_t USBx_BASE = (uint32_t)USBx;
1640 uint32_t HCcharEpDir;
1641 uint32_t HCcharLowSpeed;
1642 uint32_t HostCoreSpeed;
1643
1644 /* Clear old interrupt conditions for this host channel. */
1645 USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
1646
1647 /* Enable channel interrupts required for this transfer. */
1648 switch (ep_type)
1649 {
1650 case EP_TYPE_CTRL:
1651 case EP_TYPE_BULK:
1652 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1653 USB_OTG_HCINTMSK_STALLM |
1654 USB_OTG_HCINTMSK_TXERRM |
1655 USB_OTG_HCINTMSK_DTERRM |
1656 USB_OTG_HCINTMSK_AHBERR |
1657 USB_OTG_HCINTMSK_NAKM;
1658
1659 if ((epnum & 0x80U) == 0x80U)
1660 {
1661 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1662 }
1663 else
1664 {
1665 if ((USBx->CID & (0x1U << 8)) != 0U)
1666 {
1667 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
1668 USB_OTG_HCINTMSK_ACKM;
1669 }
1670 }
1671 break;
1672
1673 case EP_TYPE_INTR:
1674 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1675 USB_OTG_HCINTMSK_STALLM |
1676 USB_OTG_HCINTMSK_TXERRM |
1677 USB_OTG_HCINTMSK_DTERRM |
1678 USB_OTG_HCINTMSK_NAKM |
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_BBERRM;
1685 }
1686
1687 break;
1688
1689 case EP_TYPE_ISOC:
1690 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1691 USB_OTG_HCINTMSK_ACKM |
1692 USB_OTG_HCINTMSK_AHBERR |
1693 USB_OTG_HCINTMSK_FRMORM;
1694
1695 if ((epnum & 0x80U) == 0x80U)
1696 {
1697 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1698 }
1699 break;
1700
1701 default:
1702 ret = HAL_ERROR;
1703 break;
1704 }
1705
1706 /* Enable the top level host channel interrupt. */
1707 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1708
1709 /* Make sure host channel interrupts are enabled. */
1710 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1711
1712 /* Program the HCCHAR register */
1713 if ((epnum & 0x80U) == 0x80U)
1714 {
1715 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1716 }
1717 else
1718 {
1719 HCcharEpDir = 0U;
1720 }
1721
1722 HostCoreSpeed = USB_GetHostSpeed(USBx);
1723
1724 /* LS device plugged to HUB */
1725 if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1726 {
1727 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1728 }
1729 else
1730 {
1731 HCcharLowSpeed = 0U;
1732 }
1733
1734 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1735 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1736 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1737 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | HCcharEpDir | HCcharLowSpeed;
1738
1739 if (ep_type == EP_TYPE_INTR)
1740 {
1741 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
1742 }
1743
1744 return ret;
1745 }
1746
1747 /**
1748 * @brief Start a transfer over a host channel
1749 * @param USBx Selected device
1750 * @param hc pointer to host channel structure
1751 * @param dma USB dma enabled or disabled
1752 * This parameter can be one of these values:
1753 * 0 : DMA feature not used
1754 * 1 : DMA feature used
1755 * @retval HAL state
1756 */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc,uint8_t dma)1757 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1758 {
1759 uint32_t USBx_BASE = (uint32_t)USBx;
1760 uint32_t ch_num = (uint32_t)hc->ch_num;
1761 __IO uint32_t tmpreg;
1762 uint8_t is_oddframe;
1763 uint16_t len_words;
1764 uint16_t num_packets;
1765 uint16_t max_hc_pkt_count = 256U;
1766
1767 if (((USBx->CID & (0x1U << 8)) != 0U) && (hc->speed == USBH_HS_SPEED))
1768 {
1769 /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
1770 if ((dma == 1U) && ((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)))
1771 {
1772 USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
1773 USB_OTG_HCINTMSK_ACKM |
1774 USB_OTG_HCINTMSK_NAKM);
1775 }
1776
1777 if ((dma == 0U) && (hc->do_ping == 1U))
1778 {
1779 (void)USB_DoPing(USBx, hc->ch_num);
1780 return HAL_OK;
1781 }
1782
1783 }
1784
1785 /* Compute the expected number of packets associated to the transfer */
1786 if (hc->xfer_len > 0U)
1787 {
1788 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1789
1790 if (num_packets > max_hc_pkt_count)
1791 {
1792 num_packets = max_hc_pkt_count;
1793 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1794 }
1795 }
1796 else
1797 {
1798 num_packets = 1U;
1799 }
1800
1801 /*
1802 * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1803 * max_packet size.
1804 */
1805 if (hc->ep_is_in != 0U)
1806 {
1807 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1808 }
1809 else
1810 {
1811 hc->XferSize = hc->xfer_len;
1812 }
1813
1814 /* Initialize the HCTSIZn register */
1815 USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1816 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1817 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1818
1819 if (dma != 0U)
1820 {
1821 /* xfer_buff MUST be 32-bits aligned */
1822 USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1823 }
1824
1825 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1826 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1827 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1828
1829 /* Set host channel enable */
1830 tmpreg = USBx_HC(ch_num)->HCCHAR;
1831 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1832
1833 /* make sure to set the correct ep direction */
1834 if (hc->ep_is_in != 0U)
1835 {
1836 tmpreg |= USB_OTG_HCCHAR_EPDIR;
1837 }
1838 else
1839 {
1840 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1841 }
1842 tmpreg |= USB_OTG_HCCHAR_CHENA;
1843 USBx_HC(ch_num)->HCCHAR = tmpreg;
1844
1845 if (dma != 0U) /* dma mode */
1846 {
1847 return HAL_OK;
1848 }
1849
1850 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1851 {
1852 switch (hc->ep_type)
1853 {
1854 /* Non periodic transfer */
1855 case EP_TYPE_CTRL:
1856 case EP_TYPE_BULK:
1857
1858 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1859
1860 /* check if there is enough space in FIFO space */
1861 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1862 {
1863 /* need to process data in nptxfempty interrupt */
1864 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1865 }
1866 break;
1867
1868 /* Periodic transfer */
1869 case EP_TYPE_INTR:
1870 case EP_TYPE_ISOC:
1871 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1872 /* check if there is enough space in FIFO space */
1873 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
1874 {
1875 /* need to process data in ptxfempty interrupt */
1876 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1877 }
1878 break;
1879
1880 default:
1881 break;
1882 }
1883
1884 /* Write packet into the Tx FIFO. */
1885 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
1886 }
1887
1888 return HAL_OK;
1889 }
1890
1891 /**
1892 * @brief Read all host channel interrupts status
1893 * @param USBx Selected device
1894 * @retval HAL state
1895 */
USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef * USBx)1896 uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx)
1897 {
1898 uint32_t USBx_BASE = (uint32_t)USBx;
1899
1900 return ((USBx_HOST->HAINT) & 0xFFFFU);
1901 }
1902
1903 /**
1904 * @brief Halt a host channel
1905 * @param USBx Selected device
1906 * @param hc_num Host Channel number
1907 * This parameter can be a value from 1 to 15
1908 * @retval HAL state
1909 */
USB_HC_Halt(USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)1910 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
1911 {
1912 uint32_t USBx_BASE = (uint32_t)USBx;
1913 uint32_t hcnum = (uint32_t)hc_num;
1914 uint32_t count = 0U;
1915 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
1916 uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
1917
1918 if (((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) &&
1919 (ChannelEna == 0U))
1920 {
1921 return HAL_OK;
1922 }
1923
1924 /* Check for space in the request queue to issue the halt. */
1925 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
1926 {
1927 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1928
1929 if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
1930 {
1931 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
1932 {
1933 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1934 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1935 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1936 do
1937 {
1938 if (++count > 1000U)
1939 {
1940 break;
1941 }
1942 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1943 }
1944 else
1945 {
1946 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1947 }
1948 }
1949 }
1950 else
1951 {
1952 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1953
1954 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
1955 {
1956 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1957 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1958 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1959 do
1960 {
1961 if (++count > 1000U)
1962 {
1963 break;
1964 }
1965 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1966 }
1967 else
1968 {
1969 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1970 }
1971 }
1972
1973 return HAL_OK;
1974 }
1975
1976 /**
1977 * @brief Initiate Do Ping protocol
1978 * @param USBx Selected device
1979 * @param hc_num Host Channel number
1980 * This parameter can be a value from 1 to 15
1981 * @retval HAL state
1982 */
USB_DoPing(USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)1983 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
1984 {
1985 uint32_t USBx_BASE = (uint32_t)USBx;
1986 uint32_t chnum = (uint32_t)ch_num;
1987 uint32_t num_packets = 1U;
1988 uint32_t tmpreg;
1989
1990 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1991 USB_OTG_HCTSIZ_DOPING;
1992
1993 /* Set host channel enable */
1994 tmpreg = USBx_HC(chnum)->HCCHAR;
1995 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1996 tmpreg |= USB_OTG_HCCHAR_CHENA;
1997 USBx_HC(chnum)->HCCHAR = tmpreg;
1998
1999 return HAL_OK;
2000 }
2001
2002 /**
2003 * @brief Stop Host Core
2004 * @param USBx Selected device
2005 * @retval HAL state
2006 */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)2007 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
2008 {
2009 uint32_t USBx_BASE = (uint32_t)USBx;
2010 uint32_t count = 0U;
2011 uint32_t value;
2012 uint32_t i;
2013
2014 (void)USB_DisableGlobalInt(USBx);
2015
2016 /* Flush FIFO */
2017 (void)USB_FlushTxFifo(USBx, 0x10U);
2018 (void)USB_FlushRxFifo(USBx);
2019
2020 /* Flush out any leftover queued requests. */
2021 for (i = 0U; i <= 15U; i++)
2022 {
2023 value = USBx_HC(i)->HCCHAR;
2024 value |= USB_OTG_HCCHAR_CHDIS;
2025 value &= ~USB_OTG_HCCHAR_CHENA;
2026 value &= ~USB_OTG_HCCHAR_EPDIR;
2027 USBx_HC(i)->HCCHAR = value;
2028 }
2029
2030 /* Halt all channels to put them into a known state. */
2031 for (i = 0U; i <= 15U; i++)
2032 {
2033 value = USBx_HC(i)->HCCHAR;
2034 value |= USB_OTG_HCCHAR_CHDIS;
2035 value |= USB_OTG_HCCHAR_CHENA;
2036 value &= ~USB_OTG_HCCHAR_EPDIR;
2037 USBx_HC(i)->HCCHAR = value;
2038
2039 do
2040 {
2041 if (++count > 1000U)
2042 {
2043 break;
2044 }
2045 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2046 }
2047
2048 /* Clear any pending Host interrupts */
2049 USBx_HOST->HAINT = 0xFFFFFFFFU;
2050 USBx->GINTSTS = 0xFFFFFFFFU;
2051
2052 (void)USB_EnableGlobalInt(USBx);
2053
2054 return HAL_OK;
2055 }
2056
2057 /**
2058 * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
2059 * @param USBx Selected device
2060 * @retval HAL status
2061 */
USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef * USBx)2062 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
2063 {
2064 uint32_t USBx_BASE = (uint32_t)USBx;
2065
2066 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2067 {
2068 /* active Remote wakeup signalling */
2069 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2070 }
2071
2072 return HAL_OK;
2073 }
2074
2075 /**
2076 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2077 * @param USBx Selected device
2078 * @retval HAL status
2079 */
USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef * USBx)2080 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
2081 {
2082 uint32_t USBx_BASE = (uint32_t)USBx;
2083
2084 /* active Remote wakeup signalling */
2085 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2086
2087 return HAL_OK;
2088 }
2089 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2090
2091
2092 /**
2093 * @}
2094 */
2095
2096 /**
2097 * @}
2098 */
2099 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2100 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2101
2102 /**
2103 * @}
2104 */
2105
2106 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2107