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