source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c

Last change on this file was 1, checked in by AlexLir, 3 years ago
File size: 59.4 KB
Line 
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>&copy; 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)
56static 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 */
82HAL_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 */
138HAL_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 */
221HAL_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 */
233HAL_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 */
248HAL_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 */
277HAL_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 */
453HAL_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 */
475HAL_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 */
503HAL_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 USBD_HS_SPEED: High speed mode
517 * @arg USBD_FS_SPEED: Full speed mode
518 */
519uint8_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 */
548HAL_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 */
586HAL_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 */
625HAL_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 */
672HAL_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 */
714HAL_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 */
856HAL_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 */
956HAL_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 */
983void *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 */
1005HAL_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 */
1036HAL_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 */
1065HAL_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 */
1106HAL_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 */
1121HAL_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 */
1138HAL_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 */
1155uint32_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 */
1170uint32_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 */
1186uint32_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 */
1204uint32_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 */
1222uint32_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 */
1241void 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 */
1254uint32_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 */
1264HAL_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 */
1286HAL_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 */
1319static 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 */
1355HAL_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 */
1460HAL_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 */
1490HAL_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 */
1517HAL_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 */
1547uint32_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 */
1561uint32_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 to 32K
1590 * @retval HAL state
1591 */
1592HAL_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 uint32_t HostCoreSpeed;
1600
1601 /* Clear old interrupt conditions for this host channel. */
1602 USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
1603
1604 /* Enable channel interrupts required for this transfer. */
1605 switch (ep_type)
1606 {
1607 case EP_TYPE_CTRL:
1608 case EP_TYPE_BULK:
1609 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1610 USB_OTG_HCINTMSK_STALLM |
1611 USB_OTG_HCINTMSK_TXERRM |
1612 USB_OTG_HCINTMSK_DTERRM |
1613 USB_OTG_HCINTMSK_AHBERR |
1614 USB_OTG_HCINTMSK_NAKM;
1615
1616 if ((epnum & 0x80U) == 0x80U)
1617 {
1618 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1619 }
1620 else
1621 {
1622 if ((USBx->CID & (0x1U << 8)) != 0U)
1623 {
1624 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
1625 USB_OTG_HCINTMSK_ACKM;
1626 }
1627 }
1628 break;
1629
1630 case EP_TYPE_INTR:
1631 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1632 USB_OTG_HCINTMSK_STALLM |
1633 USB_OTG_HCINTMSK_TXERRM |
1634 USB_OTG_HCINTMSK_DTERRM |
1635 USB_OTG_HCINTMSK_NAKM |
1636 USB_OTG_HCINTMSK_AHBERR |
1637 USB_OTG_HCINTMSK_FRMORM;
1638
1639 if ((epnum & 0x80U) == 0x80U)
1640 {
1641 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1642 }
1643
1644 break;
1645
1646 case EP_TYPE_ISOC:
1647 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1648 USB_OTG_HCINTMSK_ACKM |
1649 USB_OTG_HCINTMSK_AHBERR |
1650 USB_OTG_HCINTMSK_FRMORM;
1651
1652 if ((epnum & 0x80U) == 0x80U)
1653 {
1654 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1655 }
1656 break;
1657
1658 default:
1659 ret = HAL_ERROR;
1660 break;
1661 }
1662
1663 /* Enable the top level host channel interrupt. */
1664 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1665
1666 /* Make sure host channel interrupts are enabled. */
1667 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1668
1669 /* Program the HCCHAR register */
1670 if ((epnum & 0x80U) == 0x80U)
1671 {
1672 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1673 }
1674 else
1675 {
1676 HCcharEpDir = 0U;
1677 }
1678
1679 HostCoreSpeed = USB_GetHostSpeed(USBx);
1680
1681 /* LS device plugged to HUB */
1682 if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1683 {
1684 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1685 }
1686 else
1687 {
1688 HCcharLowSpeed = 0U;
1689 }
1690
1691 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1692 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1693 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1694 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | HCcharEpDir | HCcharLowSpeed;
1695
1696 if (ep_type == EP_TYPE_INTR)
1697 {
1698 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
1699 }
1700
1701 return ret;
1702}
1703
1704/**
1705 * @brief Start a transfer over a host channel
1706 * @param USBx Selected device
1707 * @param hc pointer to host channel structure
1708 * @param dma USB dma enabled or disabled
1709 * This parameter can be one of these values:
1710 * 0 : DMA feature not used
1711 * 1 : DMA feature used
1712 * @retval HAL state
1713 */
1714HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1715{
1716 uint32_t USBx_BASE = (uint32_t)USBx;
1717 uint32_t ch_num = (uint32_t)hc->ch_num;
1718 __IO uint32_t tmpreg;
1719 uint8_t is_oddframe;
1720 uint16_t len_words;
1721 uint16_t num_packets;
1722 uint16_t max_hc_pkt_count = 256U;
1723
1724 if (((USBx->CID & (0x1U << 8)) != 0U) && (hc->speed == USBH_HS_SPEED))
1725 {
1726 /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
1727 if ((dma == 1U) && ((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)))
1728 {
1729 USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
1730 USB_OTG_HCINTMSK_ACKM |
1731 USB_OTG_HCINTMSK_NAKM);
1732 }
1733
1734 if ((dma == 0U) && (hc->do_ping == 1U))
1735 {
1736 (void)USB_DoPing(USBx, hc->ch_num);
1737 return HAL_OK;
1738 }
1739
1740 }
1741
1742 /* Compute the expected number of packets associated to the transfer */
1743 if (hc->xfer_len > 0U)
1744 {
1745 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1746
1747 if (num_packets > max_hc_pkt_count)
1748 {
1749 num_packets = max_hc_pkt_count;
1750 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1751 }
1752 }
1753 else
1754 {
1755 num_packets = 1U;
1756 }
1757
1758 /*
1759 * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1760 * max_packet size.
1761 */
1762 if (hc->ep_is_in != 0U)
1763 {
1764 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1765 }
1766 else
1767 {
1768 hc->XferSize = hc->xfer_len;
1769 }
1770
1771 /* Initialize the HCTSIZn register */
1772 USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1773 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1774 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1775
1776 if (dma != 0U)
1777 {
1778 /* xfer_buff MUST be 32-bits aligned */
1779 USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1780 }
1781
1782 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1783 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1784 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1785
1786 /* Set host channel enable */
1787 tmpreg = USBx_HC(ch_num)->HCCHAR;
1788 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1789
1790 /* make sure to set the correct ep direction */
1791 if (hc->ep_is_in != 0U)
1792 {
1793 tmpreg |= USB_OTG_HCCHAR_EPDIR;
1794 }
1795 else
1796 {
1797 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1798 }
1799 tmpreg |= USB_OTG_HCCHAR_CHENA;
1800 USBx_HC(ch_num)->HCCHAR = tmpreg;
1801
1802 if (dma != 0U) /* dma mode */
1803 {
1804 return HAL_OK;
1805 }
1806
1807 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1808 {
1809 switch (hc->ep_type)
1810 {
1811 /* Non periodic transfer */
1812 case EP_TYPE_CTRL:
1813 case EP_TYPE_BULK:
1814
1815 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1816
1817 /* check if there is enough space in FIFO space */
1818 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1819 {
1820 /* need to process data in nptxfempty interrupt */
1821 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1822 }
1823 break;
1824
1825 /* Periodic transfer */
1826 case EP_TYPE_INTR:
1827 case EP_TYPE_ISOC:
1828 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1829 /* check if there is enough space in FIFO space */
1830 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
1831 {
1832 /* need to process data in ptxfempty interrupt */
1833 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1834 }
1835 break;
1836
1837 default:
1838 break;
1839 }
1840
1841 /* Write packet into the Tx FIFO. */
1842 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
1843 }
1844
1845 return HAL_OK;
1846}
1847
1848/**
1849 * @brief Read all host channel interrupts status
1850 * @param USBx Selected device
1851 * @retval HAL state
1852 */
1853uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx)
1854{
1855 uint32_t USBx_BASE = (uint32_t)USBx;
1856
1857 return ((USBx_HOST->HAINT) & 0xFFFFU);
1858}
1859
1860/**
1861 * @brief Halt a host channel
1862 * @param USBx Selected device
1863 * @param hc_num Host Channel number
1864 * This parameter can be a value from 1 to 15
1865 * @retval HAL state
1866 */
1867HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
1868{
1869 uint32_t USBx_BASE = (uint32_t)USBx;
1870 uint32_t hcnum = (uint32_t)hc_num;
1871 uint32_t count = 0U;
1872 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
1873 uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
1874
1875 if (((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) &&
1876 (ChannelEna == 0U))
1877 {
1878 return HAL_OK;
1879 }
1880
1881 /* Check for space in the request queue to issue the halt. */
1882 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
1883 {
1884 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1885
1886 if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
1887 {
1888 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
1889 {
1890 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1891 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1892 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1893 do
1894 {
1895 if (++count > 1000U)
1896 {
1897 break;
1898 }
1899 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1900 }
1901 else
1902 {
1903 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1904 }
1905 }
1906 }
1907 else
1908 {
1909 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1910
1911 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
1912 {
1913 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1914 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1915 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1916 do
1917 {
1918 if (++count > 1000U)
1919 {
1920 break;
1921 }
1922 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1923 }
1924 else
1925 {
1926 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1927 }
1928 }
1929
1930 return HAL_OK;
1931}
1932
1933/**
1934 * @brief Initiate Do Ping protocol
1935 * @param USBx Selected device
1936 * @param hc_num Host Channel number
1937 * This parameter can be a value from 1 to 15
1938 * @retval HAL state
1939 */
1940HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
1941{
1942 uint32_t USBx_BASE = (uint32_t)USBx;
1943 uint32_t chnum = (uint32_t)ch_num;
1944 uint32_t num_packets = 1U;
1945 uint32_t tmpreg;
1946
1947 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1948 USB_OTG_HCTSIZ_DOPING;
1949
1950 /* Set host channel enable */
1951 tmpreg = USBx_HC(chnum)->HCCHAR;
1952 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1953 tmpreg |= USB_OTG_HCCHAR_CHENA;
1954 USBx_HC(chnum)->HCCHAR = tmpreg;
1955
1956 return HAL_OK;
1957}
1958
1959/**
1960 * @brief Stop Host Core
1961 * @param USBx Selected device
1962 * @retval HAL state
1963 */
1964HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1965{
1966 uint32_t USBx_BASE = (uint32_t)USBx;
1967 uint32_t count = 0U;
1968 uint32_t value;
1969 uint32_t i;
1970
1971 (void)USB_DisableGlobalInt(USBx);
1972
1973 /* Flush FIFO */
1974 (void)USB_FlushTxFifo(USBx, 0x10U);
1975 (void)USB_FlushRxFifo(USBx);
1976
1977 /* Flush out any leftover queued requests. */
1978 for (i = 0U; i <= 15U; i++)
1979 {
1980 value = USBx_HC(i)->HCCHAR;
1981 value |= USB_OTG_HCCHAR_CHDIS;
1982 value &= ~USB_OTG_HCCHAR_CHENA;
1983 value &= ~USB_OTG_HCCHAR_EPDIR;
1984 USBx_HC(i)->HCCHAR = value;
1985 }
1986
1987 /* Halt all channels to put them into a known state. */
1988 for (i = 0U; i <= 15U; i++)
1989 {
1990 value = USBx_HC(i)->HCCHAR;
1991 value |= USB_OTG_HCCHAR_CHDIS;
1992 value |= USB_OTG_HCCHAR_CHENA;
1993 value &= ~USB_OTG_HCCHAR_EPDIR;
1994 USBx_HC(i)->HCCHAR = value;
1995
1996 do
1997 {
1998 if (++count > 1000U)
1999 {
2000 break;
2001 }
2002 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2003 }
2004
2005 /* Clear any pending Host interrupts */
2006 USBx_HOST->HAINT = 0xFFFFFFFFU;
2007 USBx->GINTSTS = 0xFFFFFFFFU;
2008
2009 (void)USB_EnableGlobalInt(USBx);
2010
2011 return HAL_OK;
2012}
2013
2014/**
2015 * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
2016 * @param USBx Selected device
2017 * @retval HAL status
2018 */
2019HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
2020{
2021 uint32_t USBx_BASE = (uint32_t)USBx;
2022
2023 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2024 {
2025 /* active Remote wakeup signalling */
2026 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2027 }
2028
2029 return HAL_OK;
2030}
2031
2032/**
2033 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2034 * @param USBx Selected device
2035 * @retval HAL status
2036 */
2037HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
2038{
2039 uint32_t USBx_BASE = (uint32_t)USBx;
2040
2041 /* active Remote wakeup signalling */
2042 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2043
2044 return HAL_OK;
2045}
2046#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2047
2048
2049/**
2050 * @}
2051 */
2052
2053/**
2054 * @}
2055 */
2056#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2057#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2058
2059/**
2060 * @}
2061 */
2062
2063/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.