comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c @ 128:c78bcbd5deda FlipDisplay

Added current STM32 standandard libraries in version independend folder structure
author Ideenmodellierer
date Sun, 17 Feb 2019 21:12:22 +0100
parents
children
comparison
equal deleted inserted replaced
127:1369f8660eaa 128:c78bcbd5deda
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) 2017 STMicroelectronics</center></h2>
30 *
31 * Redistribution and use in source and binary forms, with or without modification,
32 * are permitted provided that the following conditions are met:
33 * 1. Redistributions of source code must retain the above copyright notice,
34 * this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright notice,
36 * this list of conditions and the following disclaimer in the documentation
37 * and/or other materials provided with the distribution.
38 * 3. Neither the name of STMicroelectronics nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 *
53 ******************************************************************************
54 */
55
56 /* Includes ------------------------------------------------------------------*/
57 #include "stm32f4xx_hal.h"
58
59 /** @addtogroup STM32F4xx_LL_USB_DRIVER
60 * @{
61 */
62
63 #if defined(HAL_PCD_MODULE_ENABLED) || defined(HAL_HCD_MODULE_ENABLED)
64 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
65 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
66 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
67 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
68 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
69 /* Private typedef -----------------------------------------------------------*/
70 /* Private define ------------------------------------------------------------*/
71 /* Private macro -------------------------------------------------------------*/
72 /* Private variables ---------------------------------------------------------*/
73 /* Private function prototypes -----------------------------------------------*/
74 /* Private functions ---------------------------------------------------------*/
75 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
76
77 /* Exported functions --------------------------------------------------------*/
78
79 /** @defgroup LL_USB_Exported_Functions USB Low Layer Exported Functions
80 * @{
81 */
82
83 /** @defgroup LL_USB_Group1 Initialization/de-initialization functions
84 * @brief Initialization and Configuration functions
85 *
86 @verbatim
87 ===============================================================================
88 ##### Initialization/de-initialization functions #####
89 ===============================================================================
90 [..] This section provides functions allowing to:
91
92 @endverbatim
93 * @{
94 */
95
96 /**
97 * @brief Initializes the USB Core
98 * @param USBx USB Instance
99 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
100 * the configuration information for the specified USBx peripheral.
101 * @retval HAL status
102 */
103 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
104 {
105 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
106 {
107
108 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
109
110 /* Init The ULPI Interface */
111 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
112
113 /* Select vbus source */
114 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
115 if(cfg.use_external_vbus == 1U)
116 {
117 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
118 }
119 /* Reset after a PHY select */
120 USB_CoreReset(USBx);
121 }
122 else /* FS interface (embedded Phy) */
123 {
124 /* Select FS Embedded PHY */
125 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
126
127 /* Reset after a PHY select and set Host mode */
128 USB_CoreReset(USBx);
129
130 /* Deactivate the power down*/
131 USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
132 }
133
134 if(cfg.dma_enable == ENABLE)
135 {
136 USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
137 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
138 }
139
140 return HAL_OK;
141 }
142
143 /**
144 * @brief USB_EnableGlobalInt
145 * Enables the controller's Global Int in the AHB Config reg
146 * @param USBx Selected device
147 * @retval HAL status
148 */
149 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
150 {
151 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
152 return HAL_OK;
153 }
154
155
156 /**
157 * @brief USB_DisableGlobalInt
158 * Disable the controller's Global Int in the AHB Config reg
159 * @param USBx Selected device
160 * @retval HAL status
161 */
162 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
163 {
164 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
165 return HAL_OK;
166 }
167
168 /**
169 * @brief USB_SetCurrentMode : Set functional mode
170 * @param USBx Selected device
171 * @param mode current core mode
172 * This parameter can be one of these values:
173 * @arg USB_OTG_DEVICE_MODE: Peripheral mode
174 * @arg USB_OTG_HOST_MODE: Host mode
175 * @arg USB_OTG_DRD_MODE: Dual Role Device mode
176 * @retval HAL status
177 */
178 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode)
179 {
180 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
181
182 if ( mode == USB_OTG_HOST_MODE)
183 {
184 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
185 }
186 else if ( mode == USB_OTG_DEVICE_MODE)
187 {
188 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
189 }
190 HAL_Delay(50U);
191
192 return HAL_OK;
193 }
194
195 /**
196 * @brief USB_DevInit : Initializes the USB_OTG controller registers
197 * for device mode
198 * @param USBx Selected device
199 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
200 * the configuration information for the specified USBx peripheral.
201 * @retval HAL status
202 */
203 HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
204 {
205 uint32_t i = 0U;
206
207 /*Activate VBUS Sensing B */
208 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
209 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
210 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
211
212 if (cfg.vbus_sensing_enable == 0U)
213 {
214 /* Deactivate VBUS Sensing B */
215 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
216
217 /* B-peripheral session valid override enable*/
218 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
219 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
220 }
221 #else
222 if (cfg.vbus_sensing_enable == 0U)
223 {
224 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
225 }
226 else
227 {
228 /* Enable VBUS */
229 USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
230 }
231 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx || STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
232
233 /* Restart the Phy Clock */
234 USBx_PCGCCTL = 0U;
235
236 /* Device mode configuration */
237 USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
238
239 if(cfg.phy_itface == USB_OTG_ULPI_PHY)
240 {
241 if(cfg.speed == USB_OTG_SPEED_HIGH)
242 {
243 /* Set High speed phy */
244 USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH);
245 }
246 else
247 {
248 /* set High speed phy in Full speed mode */
249 USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL);
250 }
251 }
252 else
253 {
254 /* Set Full speed phy */
255 USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
256 }
257
258 /* Flush the FIFOs */
259 USB_FlushTxFifo(USBx , 0x10U); /* all Tx FIFOs */
260 USB_FlushRxFifo(USBx);
261
262 /* Clear all pending Device Interrupts */
263 USBx_DEVICE->DIEPMSK = 0U;
264 USBx_DEVICE->DOEPMSK = 0U;
265 USBx_DEVICE->DAINT = 0xFFFFFFFFU;
266 USBx_DEVICE->DAINTMSK = 0U;
267
268 for (i = 0U; i < cfg.dev_endpoints; i++)
269 {
270 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
271 {
272 USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
273 }
274 else
275 {
276 USBx_INEP(i)->DIEPCTL = 0U;
277 }
278
279 USBx_INEP(i)->DIEPTSIZ = 0U;
280 USBx_INEP(i)->DIEPINT = 0xFFU;
281 }
282
283 for (i = 0U; i < cfg.dev_endpoints; i++)
284 {
285 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
286 {
287 USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
288 }
289 else
290 {
291 USBx_OUTEP(i)->DOEPCTL = 0U;
292 }
293
294 USBx_OUTEP(i)->DOEPTSIZ = 0U;
295 USBx_OUTEP(i)->DOEPINT = 0xFFU;
296 }
297
298 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
299
300 if (cfg.dma_enable == 1U)
301 {
302 /*Set threshold parameters */
303 USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6);
304 USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN);
305
306 i= USBx_DEVICE->DTHRCTL;
307 }
308
309 /* Disable all interrupts. */
310 USBx->GINTMSK = 0U;
311
312 /* Clear any pending interrupts */
313 USBx->GINTSTS = 0xBFFFFFFFU;
314
315 /* Enable the common interrupts */
316 if (cfg.dma_enable == DISABLE)
317 {
318 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
319 }
320
321 /* Enable interrupts matching to the Device mode ONLY */
322 USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
323 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
324 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\
325 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
326
327 if(cfg.Sof_enable)
328 {
329 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
330 }
331
332 if (cfg.vbus_sensing_enable == ENABLE)
333 {
334 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
335 }
336
337 return HAL_OK;
338 }
339
340
341 /**
342 * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
343 * @param USBx Selected device
344 * @param num FIFO number
345 * This parameter can be a value from 1 to 15
346 15 means Flush all Tx FIFOs
347 * @retval HAL status
348 */
349 HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
350 {
351 uint32_t count = 0;
352
353 USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 6));
354
355 do
356 {
357 if (++count > 200000)
358 {
359 return HAL_TIMEOUT;
360 }
361 }
362 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
363
364 return HAL_OK;
365 }
366
367
368 /**
369 * @brief USB_FlushRxFifo : Flush Rx FIFO
370 * @param USBx Selected device
371 * @retval HAL status
372 */
373 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
374 {
375 uint32_t count = 0;
376
377 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
378
379 do
380 {
381 if (++count > 200000)
382 {
383 return HAL_TIMEOUT;
384 }
385 }
386 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
387
388 return HAL_OK;
389 }
390
391 /**
392 * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
393 * depending the PHY type and the enumeration speed of the device.
394 * @param USBx Selected device
395 * @param speed device speed
396 * This parameter can be one of these values:
397 * @arg USB_OTG_SPEED_HIGH: High speed mode
398 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
399 * @arg USB_OTG_SPEED_FULL: Full speed mode
400 * @arg USB_OTG_SPEED_LOW: Low speed mode
401 * @retval Hal status
402 */
403 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
404 {
405 USBx_DEVICE->DCFG |= speed;
406 return HAL_OK;
407 }
408
409 /**
410 * @brief USB_GetDevSpeed :Return the Dev Speed
411 * @param USBx Selected device
412 * @retval speed : device speed
413 * This parameter can be one of these values:
414 * @arg USB_OTG_SPEED_HIGH: High speed mode
415 * @arg USB_OTG_SPEED_FULL: Full speed mode
416 * @arg USB_OTG_SPEED_LOW: Low speed mode
417 */
418 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
419 {
420 uint8_t speed = 0U;
421
422 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
423 {
424 speed = USB_OTG_SPEED_HIGH;
425 }
426 else if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
427 ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))
428 {
429 speed = USB_OTG_SPEED_FULL;
430 }
431 else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
432 {
433 speed = USB_OTG_SPEED_LOW;
434 }
435
436 return speed;
437 }
438
439 /**
440 * @brief Activate and configure an endpoint
441 * @param USBx Selected device
442 * @param ep pointer to endpoint structure
443 * @retval HAL status
444 */
445 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
446 {
447 if (ep->is_in == 1U)
448 {
449 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num)));
450
451 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
452 {
453 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
454 ((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
455 }
456 }
457 else
458 {
459 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U);
460
461 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
462 {
463 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
464 (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));
465 }
466 }
467 return HAL_OK;
468 }
469 /**
470 * @brief Activate and configure a dedicated endpoint
471 * @param USBx Selected device
472 * @param ep pointer to endpoint structure
473 * @retval HAL status
474 */
475 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
476 {
477 static __IO uint32_t debug = 0U;
478
479 /* Read DEPCTLn register */
480 if (ep->is_in == 1U)
481 {
482 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
483 {
484 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
485 ((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
486 }
487
488
489 debug |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
490 ((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
491
492 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num)));
493 }
494 else
495 {
496 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
497 {
498 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
499 ((ep->num) << 22U) | (USB_OTG_DOEPCTL_USBAEP));
500
501 debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0U)*USB_OTG_EP_REG_SIZE);
502 debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL;
503 debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
504 ((ep->num) << 22U) | (USB_OTG_DOEPCTL_USBAEP));
505 }
506
507 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U);
508 }
509
510 return HAL_OK;
511 }
512 /**
513 * @brief De-activate and de-initialize an endpoint
514 * @param USBx Selected device
515 * @param ep pointer to endpoint structure
516 * @retval HAL status
517 */
518 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
519 {
520 uint32_t count = 0U;
521
522 /* Disable the IN endpoint */
523 if (ep->is_in == 1U)
524 {
525 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_USBAEP;
526
527 /* sets the NAK bit for the IN endpoint */
528 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
529
530 /* Disable IN endpoint */
531 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS;
532
533 do
534 {
535 if (++count > 200000U)
536 {
537 return HAL_TIMEOUT;
538 }
539 }
540
541 /*Wait for EPDISD endpoint disabled interrupt*/
542 while ((USBx_INEP(ep->num)->DIEPINT & USB_OTG_DIEPCTL_EPDIS) == USB_OTG_DIEPCTL_EPDIS);
543
544
545 /* Flush any data remaining in the TxFIFO */
546 USB_FlushTxFifo(USBx , 0x10U);
547
548 /* Disable endpoint interrupts */
549 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num))));
550
551 }
552 else /* Disable the OUT endpoint */
553 {
554
555 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
556
557 /* sets the NAK bit for the OUT endpoint */
558 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
559
560 /* Disable OUT endpoint */
561 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS;
562
563 do
564 {
565 if (++count > 200000U)
566 {
567 return HAL_TIMEOUT;
568 }
569 }
570
571 /*Wait for EPDISD endpoint disabled interrupt*/
572 while ((USBx_OUTEP(ep->num)->DOEPINT & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS);
573
574 /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */
575 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
576
577 /* Disable endpoint interrupts */
578 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U));
579 }
580 return HAL_OK;
581 }
582
583 /**
584 * @brief De-activate and de-initialize a dedicated endpoint
585 * @param USBx Selected device
586 * @param ep pointer to endpoint structure
587 * @retval HAL status
588 */
589 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
590 {
591 uint32_t count = 0U;
592
593 /* Disable the IN endpoint */
594 if (ep->is_in == 1U)
595 {
596 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_USBAEP;
597
598 /* sets the NAK bit for the IN endpoint */
599 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
600
601 /* Disable IN endpoint */
602 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS;
603
604 do
605 {
606 if (++count > 200000U)
607 {
608 return HAL_TIMEOUT;
609 }
610 }
611
612 /*Wait for EPDISD endpoint disabled interrupt*/
613 while ((USBx_INEP(ep->num)->DIEPINT & USB_OTG_DIEPCTL_EPDIS) == USB_OTG_DIEPCTL_EPDIS);
614
615
616 /* Flush any data remaining in the TxFIFO */
617 USB_FlushTxFifo(USBx , 0x10U);
618
619 /* Disable endpoint interrupts */
620 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num))));
621
622 }
623 else /* Disable the OUT endpoint */
624 {
625
626 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
627
628 /* sets the NAK bit for the OUT endpoint */
629 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
630
631 /* Disable OUT endpoint */
632 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS;
633
634 do
635 {
636 if (++count > 200000U)
637 {
638 return HAL_TIMEOUT;
639 }
640 }
641
642 /*Wait for EPDISD endpoint disabled interrupt*/
643 while ((USBx_OUTEP(ep->num)->DOEPINT & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS);
644
645 /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */
646 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
647
648 /* Disable endpoint interrupts */
649 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U));
650 }
651 return HAL_OK;
652
653 }
654
655 /**
656 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
657 * @param USBx Selected device
658 * @param ep pointer to endpoint structure
659 * @param dma USB dma enabled or disabled
660 * This parameter can be one of these values:
661 * 0 : DMA feature not used
662 * 1 : DMA feature used
663 * @retval HAL status
664 */
665 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
666 {
667 uint16_t pktcnt = 0U;
668
669 /* IN endpoint */
670 if (ep->is_in == 1U)
671 {
672 /* Zero Length Packet? */
673 if (ep->xfer_len == 0U)
674 {
675 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
676 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19U)) ;
677 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
678 }
679 else
680 {
681 /* Program the transfer size and packet count
682 * as follows: xfersize = N * maxpacket +
683 * short_packet pktcnt = N + (short_packet
684 * exist ? 1 : 0)
685 */
686 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
687 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
688 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1U)/ ep->maxpacket) << 19U)) ;
689 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
690
691 if (ep->type == EP_TYPE_ISOC)
692 {
693 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
694 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29U));
695 }
696 }
697
698 if (dma == 1U)
699 {
700 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
701 }
702 else
703 {
704 if (ep->type != EP_TYPE_ISOC)
705 {
706 /* Enable the Tx FIFO Empty Interrupt for this EP */
707 if (ep->xfer_len > 0U)
708 {
709 USBx_DEVICE->DIEPEMPMSK |= 1U << ep->num;
710 }
711 }
712 }
713
714 if (ep->type == EP_TYPE_ISOC)
715 {
716 if ((USBx_DEVICE->DSTS & ( 1U << 8U )) == 0U)
717 {
718 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
719 }
720 else
721 {
722 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
723 }
724 }
725
726 /* EP enable, IN data in FIFO */
727 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
728
729 if (ep->type == EP_TYPE_ISOC)
730 {
731 USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma);
732 }
733 }
734 else /* OUT endpoint */
735 {
736 /* Program the transfer size and packet count as follows:
737 * pktcnt = N
738 * xfersize = N * maxpacket
739 */
740 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
741 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
742
743 if (ep->xfer_len == 0U)
744 {
745 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
746 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U));
747 }
748 else
749 {
750 pktcnt = (ep->xfer_len + ep->maxpacket -1U)/ ep->maxpacket;
751 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19U));
752 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
753 }
754
755 if (dma == 1U)
756 {
757 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff;
758 }
759
760 if (ep->type == EP_TYPE_ISOC)
761 {
762 if ((USBx_DEVICE->DSTS & ( 1U << 8U )) == 0U)
763 {
764 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
765 }
766 else
767 {
768 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
769 }
770 }
771 /* EP enable */
772 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
773 }
774 return HAL_OK;
775 }
776
777 /**
778 * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
779 * @param USBx Selected device
780 * @param ep pointer to endpoint structure
781 * @param dma USB dma enabled or disabled
782 * This parameter can be one of these values:
783 * 0 : DMA feature not used
784 * 1 : DMA feature used
785 * @retval HAL status
786 */
787 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
788 {
789 /* IN endpoint */
790 if (ep->is_in == 1U)
791 {
792 /* Zero Length Packet? */
793 if (ep->xfer_len == 0U)
794 {
795 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
796 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19U)) ;
797 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
798 }
799 else
800 {
801 /* Program the transfer size and packet count
802 * as follows: xfersize = N * maxpacket +
803 * short_packet pktcnt = N + (short_packet
804 * exist ? 1 : 0)
805 */
806 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
807 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
808
809 if(ep->xfer_len > ep->maxpacket)
810 {
811 ep->xfer_len = ep->maxpacket;
812 }
813 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19U)) ;
814 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
815
816 }
817
818 /* EP enable, IN data in FIFO */
819 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
820
821 if (dma == 1)
822 {
823 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
824 }
825 else
826 {
827 /* Enable the Tx FIFO Empty Interrupt for this EP */
828 if (ep->xfer_len > 0U)
829 {
830 USBx_DEVICE->DIEPEMPMSK |= 1U << (ep->num);
831 }
832 }
833 }
834
835 else /* OUT endpoint */
836 {
837 /* Program the transfer size and packet count as follows:
838 * pktcnt = N
839 * xfersize = N * maxpacket
840 */
841 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
842 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
843
844 if (ep->xfer_len > 0U)
845 {
846 ep->xfer_len = ep->maxpacket;
847 }
848
849 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U));
850 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
851
852
853 if (dma == 1U)
854 {
855 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff);
856 }
857
858 /* EP enable */
859 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
860 }
861 return HAL_OK;
862 }
863
864 /**
865 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
866 * with the EP/channel
867 * @param USBx Selected device
868 * @param src pointer to source buffer
869 * @param ch_ep_num endpoint or host channel number
870 * @param len Number of bytes to write
871 * @param dma USB dma enabled or disabled
872 * This parameter can be one of these values:
873 * 0 : DMA feature not used
874 * 1 : DMA feature used
875 * @retval HAL status
876 */
877 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
878 {
879 uint32_t count32b = 0U , i = 0U;
880
881 if (dma == 0U)
882 {
883 count32b = (len + 3U) / 4U;
884 for (i = 0U; i < count32b; i++, src += 4U)
885 {
886 USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
887 }
888 }
889 return HAL_OK;
890 }
891
892 /**
893 * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
894 * with the EP/channel
895 * @param USBx Selected device
896 * @param src source pointer
897 * @param ch_ep_num endpoint or host channel number
898 * @param len Number of bytes to read
899 * @param dma USB dma enabled or disabled
900 * This parameter can be one of these values:
901 * 0 : DMA feature not used
902 * 1 : DMA feature used
903 * @retval pointer to destination buffer
904 */
905 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
906 {
907 uint32_t i=0U;
908 uint32_t count32b = (len + 3U) / 4U;
909
910 for ( i = 0U; i < count32b; i++, dest += 4U )
911 {
912 *(__packed uint32_t *)dest = USBx_DFIFO(0U);
913
914 }
915 return ((void *)dest);
916 }
917
918 /**
919 * @brief USB_EPSetStall : set a stall condition over an EP
920 * @param USBx Selected device
921 * @param ep pointer to endpoint structure
922 * @retval HAL status
923 */
924 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
925 {
926 if (ep->is_in == 1U)
927 {
928 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0U)
929 {
930 USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
931 }
932 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
933 }
934 else
935 {
936 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0U)
937 {
938 USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
939 }
940 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
941 }
942 return HAL_OK;
943 }
944
945
946 /**
947 * @brief USB_EPClearStall : Clear a stall condition over an EP
948 * @param USBx Selected device
949 * @param ep pointer to endpoint structure
950 * @retval HAL status
951 */
952 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
953 {
954 if (ep->is_in == 1U)
955 {
956 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
957 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
958 {
959 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
960 }
961 }
962 else
963 {
964 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
965 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
966 {
967 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
968 }
969 }
970 return HAL_OK;
971 }
972
973 /**
974 * @brief USB_StopDevice : Stop the usb device mode
975 * @param USBx Selected device
976 * @retval HAL status
977 */
978 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
979 {
980 uint32_t i;
981
982 /* Clear Pending interrupt */
983 for (i = 0U; i < 15U ; i++)
984 {
985 USBx_INEP(i)->DIEPINT = 0xFFU;
986 USBx_OUTEP(i)->DOEPINT = 0xFFU;
987 }
988 USBx_DEVICE->DAINT = 0xFFFFFFFFU;
989
990 /* Clear interrupt masks */
991 USBx_DEVICE->DIEPMSK = 0U;
992 USBx_DEVICE->DOEPMSK = 0U;
993 USBx_DEVICE->DAINTMSK = 0U;
994
995 /* Flush the FIFO */
996 USB_FlushRxFifo(USBx);
997 USB_FlushTxFifo(USBx , 0x10U);
998
999 return HAL_OK;
1000 }
1001
1002 /**
1003 * @brief USB_SetDevAddress : Stop the usb device mode
1004 * @param USBx Selected device
1005 * @param address new device address to be assigned
1006 * This parameter can be a value from 0 to 255
1007 * @retval HAL status
1008 */
1009 HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1010 {
1011 USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
1012 USBx_DEVICE->DCFG |= (address << 4U) & USB_OTG_DCFG_DAD ;
1013
1014 return HAL_OK;
1015 }
1016
1017 /**
1018 * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
1019 * @param USBx Selected device
1020 * @retval HAL status
1021 */
1022 HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
1023 {
1024 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
1025 HAL_Delay(3U);
1026
1027 return HAL_OK;
1028 }
1029
1030 /**
1031 * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
1032 * @param USBx Selected device
1033 * @retval HAL status
1034 */
1035 HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
1036 {
1037 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS ;
1038 HAL_Delay(3U);
1039
1040 return HAL_OK;
1041 }
1042
1043 /**
1044 * @brief USB_ReadInterrupts: return the global USB interrupt status
1045 * @param USBx Selected device
1046 * @retval HAL status
1047 */
1048 uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
1049 {
1050 uint32_t v = 0U;
1051
1052 v = USBx->GINTSTS;
1053 v &= USBx->GINTMSK;
1054 return v;
1055 }
1056
1057 /**
1058 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1059 * @param USBx Selected device
1060 * @retval HAL status
1061 */
1062 uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
1063 {
1064 uint32_t v;
1065 v = USBx_DEVICE->DAINT;
1066 v &= USBx_DEVICE->DAINTMSK;
1067 return ((v & 0xffff0000U) >> 16U);
1068 }
1069
1070 /**
1071 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1072 * @param USBx Selected device
1073 * @retval HAL status
1074 */
1075 uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
1076 {
1077 uint32_t v;
1078 v = USBx_DEVICE->DAINT;
1079 v &= USBx_DEVICE->DAINTMSK;
1080 return ((v & 0xFFFFU));
1081 }
1082
1083 /**
1084 * @brief Returns Device OUT EP Interrupt register
1085 * @param USBx Selected device
1086 * @param epnum endpoint number
1087 * This parameter can be a value from 0 to 15
1088 * @retval Device OUT EP Interrupt register
1089 */
1090 uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
1091 {
1092 uint32_t v;
1093 v = USBx_OUTEP(epnum)->DOEPINT;
1094 v &= USBx_DEVICE->DOEPMSK;
1095 return v;
1096 }
1097
1098 /**
1099 * @brief Returns Device IN EP Interrupt register
1100 * @param USBx Selected device
1101 * @param epnum endpoint number
1102 * This parameter can be a value from 0 to 15
1103 * @retval Device IN EP Interrupt register
1104 */
1105 uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
1106 {
1107 uint32_t v, msk, emp;
1108
1109 msk = USBx_DEVICE->DIEPMSK;
1110 emp = USBx_DEVICE->DIEPEMPMSK;
1111 msk |= ((emp >> epnum) & 0x1U) << 7U;
1112 v = USBx_INEP(epnum)->DIEPINT & msk;
1113 return v;
1114 }
1115
1116 /**
1117 * @brief USB_ClearInterrupts: clear a USB interrupt
1118 * @param USBx Selected device
1119 * @param interrupt interrupt flag
1120 * @retval None
1121 */
1122 void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1123 {
1124 USBx->GINTSTS |= interrupt;
1125 }
1126
1127 /**
1128 * @brief Returns USB core mode
1129 * @param USBx Selected device
1130 * @retval return core mode : Host or Device
1131 * This parameter can be one of these values:
1132 * 0 : Host
1133 * 1 : Device
1134 */
1135 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
1136 {
1137 return ((USBx->GINTSTS ) & 0x1U);
1138 }
1139
1140
1141 /**
1142 * @brief Activate EP0 for Setup transactions
1143 * @param USBx Selected device
1144 * @retval HAL status
1145 */
1146 HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
1147 {
1148 /* Set the MPS of the IN EP based on the enumeration speed */
1149 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1150
1151 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
1152 {
1153 USBx_INEP(0U)->DIEPCTL |= 3U;
1154 }
1155 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1156
1157 return HAL_OK;
1158 }
1159
1160
1161 /**
1162 * @brief Prepare the EP0 to start the first control setup
1163 * @param USBx Selected device
1164 * @param dma USB dma enabled or disabled
1165 * This parameter can be one of these values:
1166 * 0 : DMA feature not used
1167 * 1 : DMA feature used
1168 * @param psetup pointer to setup packet
1169 * @retval HAL status
1170 */
1171 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup)
1172 {
1173 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1174 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U)) ;
1175 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1176 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1177
1178 if (dma == 1U)
1179 {
1180 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1181 /* EP enable */
1182 USBx_OUTEP(0U)->DOEPCTL = 0x80008000U;
1183 }
1184
1185 return HAL_OK;
1186 }
1187
1188
1189 /**
1190 * @brief Reset the USB Core (needed after USB clock settings change)
1191 * @param USBx Selected device
1192 * @retval HAL status
1193 */
1194 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1195 {
1196 uint32_t count = 0U;
1197
1198 /* Wait for AHB master IDLE state. */
1199 do
1200 {
1201 if (++count > 200000U)
1202 {
1203 return HAL_TIMEOUT;
1204 }
1205 }
1206 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1207
1208 /* Core Soft Reset */
1209 count = 0U;
1210 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1211
1212 do
1213 {
1214 if (++count > 200000U)
1215 {
1216 return HAL_TIMEOUT;
1217 }
1218 }
1219 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1220
1221 return HAL_OK;
1222 }
1223
1224
1225 /**
1226 * @brief USB_HostInit : Initializes the USB OTG controller registers
1227 * for Host mode
1228 * @param USBx Selected device
1229 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
1230 * the configuration information for the specified USBx peripheral.
1231 * @retval HAL status
1232 */
1233 HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1234 {
1235 uint32_t i;
1236
1237 /* Restart the Phy Clock */
1238 USBx_PCGCCTL = 0U;
1239
1240 /* Activate VBUS Sensing B */
1241 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
1242 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1243 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
1244 #else
1245 USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN);
1246 USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN);
1247 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
1248 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx || STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
1249
1250 /* Disable the FS/LS support mode only */
1251 if((cfg.speed == USB_OTG_SPEED_FULL)&&
1252 (USBx != USB_OTG_FS))
1253 {
1254 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1255 }
1256 else
1257 {
1258 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1259 }
1260
1261 /* Make sure the FIFOs are flushed. */
1262 USB_FlushTxFifo(USBx, 0x10U); /* all Tx FIFOs */
1263 USB_FlushRxFifo(USBx);
1264
1265 /* Clear all pending HC Interrupts */
1266 for (i = 0U; i < cfg.Host_channels; i++)
1267 {
1268 USBx_HC(i)->HCINT = 0xFFFFFFFFU;
1269 USBx_HC(i)->HCINTMSK = 0U;
1270 }
1271
1272 /* Enable VBUS driving */
1273 USB_DriveVbus(USBx, 1U);
1274
1275 HAL_Delay(200U);
1276
1277 /* Disable all interrupts. */
1278 USBx->GINTMSK = 0U;
1279
1280 /* Clear any pending interrupts */
1281 USBx->GINTSTS = 0xFFFFFFFFU;
1282
1283 if(USBx == USB_OTG_FS)
1284 {
1285 /* set Rx FIFO size */
1286 USBx->GRXFSIZ = 0x80U;
1287 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60U << 16U)& USB_OTG_NPTXFD) | 0x80U);
1288 USBx->HPTXFSIZ = (uint32_t )(((0x40U << 16U)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1289 }
1290 else
1291 {
1292 /* set Rx FIFO size */
1293 USBx->GRXFSIZ = 0x200U;
1294 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x100U << 16U)& USB_OTG_NPTXFD) | 0x200U);
1295 USBx->HPTXFSIZ = (uint32_t )(((0xE0U << 16U)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1296 }
1297
1298 /* Enable the common interrupts */
1299 if (cfg.dma_enable == DISABLE)
1300 {
1301 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1302 }
1303
1304 /* Enable interrupts matching to the Host mode ONLY */
1305 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
1306 USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\
1307 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1308
1309 return HAL_OK;
1310 }
1311
1312 /**
1313 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1314 * HCFG register on the PHY type and set the right frame interval
1315 * @param USBx Selected device
1316 * @param freq clock frequency
1317 * This parameter can be one of these values:
1318 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1319 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1320 * @retval HAL status
1321 */
1322 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
1323 {
1324 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1325 USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
1326
1327 if (freq == HCFG_48_MHZ)
1328 {
1329 USBx_HOST->HFIR = 48000U;
1330 }
1331 else if (freq == HCFG_6_MHZ)
1332 {
1333 USBx_HOST->HFIR = 6000U;
1334 }
1335 return HAL_OK;
1336 }
1337
1338 /**
1339 * @brief USB_OTG_ResetPort : Reset Host Port
1340 * @param USBx Selected device
1341 * @retval HAL status
1342 * @note (1)The application must wait at least 10 ms
1343 * before clearing the reset bit.
1344 */
1345 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
1346 {
1347 __IO uint32_t hprt0;
1348
1349 hprt0 = USBx_HPRT0;
1350
1351 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1352 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1353
1354 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1355 HAL_Delay (10U); /* See Note #1 */
1356 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1357 return HAL_OK;
1358 }
1359
1360 /**
1361 * @brief USB_DriveVbus : activate or de-activate vbus
1362 * @param state VBUS state
1363 * This parameter can be one of these values:
1364 * 0 : VBUS Active
1365 * 1 : VBUS Inactive
1366 * @retval HAL status
1367 */
1368 HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1369 {
1370 __IO uint32_t hprt0;
1371
1372 hprt0 = USBx_HPRT0;
1373 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1374 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1375
1376 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1377 {
1378 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1379 }
1380 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1381 {
1382 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1383 }
1384 return HAL_OK;
1385 }
1386
1387 /**
1388 * @brief Return Host Core speed
1389 * @param USBx Selected device
1390 * @retval speed : Host speed
1391 * This parameter can be one of these values:
1392 * @arg USB_OTG_SPEED_HIGH: High speed mode
1393 * @arg USB_OTG_SPEED_FULL: Full speed mode
1394 * @arg USB_OTG_SPEED_LOW: Low speed mode
1395 */
1396 uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
1397 {
1398 __IO uint32_t hprt0;
1399
1400 hprt0 = USBx_HPRT0;
1401 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17U);
1402 }
1403
1404 /**
1405 * @brief Return Host Current Frame number
1406 * @param USBx Selected device
1407 * @retval current frame number
1408 */
1409 uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
1410 {
1411 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1412 }
1413
1414 /**
1415 * @brief Initialize a host channel
1416 * @param USBx Selected device
1417 * @param ch_num Channel number
1418 * This parameter can be a value from 1 to 15
1419 * @param epnum Endpoint number
1420 * This parameter can be a value from 1 to 15
1421 * @param dev_address Current device address
1422 * This parameter can be a value from 0 to 255
1423 * @param speed Current device speed
1424 * This parameter can be one of these values:
1425 * @arg USB_OTG_SPEED_HIGH: High speed mode
1426 * @arg USB_OTG_SPEED_FULL: Full speed mode
1427 * @arg USB_OTG_SPEED_LOW: Low speed mode
1428 * @param ep_type Endpoint Type
1429 * This parameter can be one of these values:
1430 * @arg EP_TYPE_CTRL: Control type
1431 * @arg EP_TYPE_ISOC: Isochronous type
1432 * @arg EP_TYPE_BULK: Bulk type
1433 * @arg EP_TYPE_INTR: Interrupt type
1434 * @param mps Max Packet Size
1435 * This parameter can be a value from 0 to32K
1436 * @retval HAL state
1437 */
1438 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
1439 uint8_t ch_num,
1440 uint8_t epnum,
1441 uint8_t dev_address,
1442 uint8_t speed,
1443 uint8_t ep_type,
1444 uint16_t mps)
1445 {
1446
1447 /* Clear old interrupt conditions for this host channel. */
1448 USBx_HC(ch_num)->HCINT = 0xFFFFFFFFU;
1449
1450 /* Enable channel interrupts required for this transfer. */
1451 switch (ep_type)
1452 {
1453 case EP_TYPE_CTRL:
1454 case EP_TYPE_BULK:
1455
1456 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1457 USB_OTG_HCINTMSK_STALLM |\
1458 USB_OTG_HCINTMSK_TXERRM |\
1459 USB_OTG_HCINTMSK_DTERRM |\
1460 USB_OTG_HCINTMSK_AHBERR |\
1461 USB_OTG_HCINTMSK_NAKM ;
1462
1463 if (epnum & 0x80U)
1464 {
1465 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1466 }
1467 else
1468 {
1469 if(USBx != USB_OTG_FS)
1470 {
1471 USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1472 }
1473 }
1474 break;
1475
1476 case EP_TYPE_INTR:
1477
1478 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1479 USB_OTG_HCINTMSK_STALLM |\
1480 USB_OTG_HCINTMSK_TXERRM |\
1481 USB_OTG_HCINTMSK_DTERRM |\
1482 USB_OTG_HCINTMSK_NAKM |\
1483 USB_OTG_HCINTMSK_AHBERR |\
1484 USB_OTG_HCINTMSK_FRMORM ;
1485
1486 if (epnum & 0x80U)
1487 {
1488 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1489 }
1490
1491 break;
1492 case EP_TYPE_ISOC:
1493
1494 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1495 USB_OTG_HCINTMSK_ACKM |\
1496 USB_OTG_HCINTMSK_AHBERR |\
1497 USB_OTG_HCINTMSK_FRMORM ;
1498
1499 if (epnum & 0x80U)
1500 {
1501 USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1502 }
1503 break;
1504 }
1505
1506 /* Enable the top level host channel interrupt. */
1507 USBx_HOST->HAINTMSK |= (1 << ch_num);
1508
1509 /* Make sure host channel interrupts are enabled. */
1510 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1511
1512 /* Program the HCCHAR register */
1513 USBx_HC(ch_num)->HCCHAR = (((dev_address << 22U) & USB_OTG_HCCHAR_DAD) |\
1514 (((epnum & 0x7FU)<< 11U) & USB_OTG_HCCHAR_EPNUM)|\
1515 ((((epnum & 0x80U) == 0x80U)<< 15U) & USB_OTG_HCCHAR_EPDIR)|\
1516 (((speed == USB_OTG_SPEED_LOW)<< 17U) & USB_OTG_HCCHAR_LSDEV)|\
1517 ((ep_type << 18U) & USB_OTG_HCCHAR_EPTYP)|\
1518 (mps & USB_OTG_HCCHAR_MPSIZ));
1519
1520 if (ep_type == EP_TYPE_INTR)
1521 {
1522 USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
1523 }
1524
1525 return HAL_OK;
1526 }
1527
1528 /**
1529 * @brief Start a transfer over a host channel
1530 * @param USBx Selected device
1531 * @param hc pointer to host channel structure
1532 * @param dma USB dma enabled or disabled
1533 * This parameter can be one of these values:
1534 * 0 : DMA feature not used
1535 * 1 : DMA feature used
1536 * @retval HAL state
1537 */
1538 #if defined (__CC_ARM) /*!< ARM Compiler */
1539 #pragma O0
1540 #elif defined (__GNUC__) /*!< GNU Compiler */
1541 #pragma GCC optimize ("O0")
1542 #endif /* __CC_ARM */
1543 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1544 {
1545 uint8_t is_oddframe = 0;
1546 uint16_t len_words = 0;
1547 uint16_t num_packets = 0;
1548 uint16_t max_hc_pkt_count = 256;
1549 uint32_t tmpreg = 0U;
1550
1551 if((USBx != USB_OTG_FS) && (hc->speed == USB_OTG_SPEED_HIGH))
1552 {
1553 if((dma == 0) && (hc->do_ping == 1U))
1554 {
1555 USB_DoPing(USBx, hc->ch_num);
1556 return HAL_OK;
1557 }
1558 else if(dma == 1)
1559 {
1560 USBx_HC(hc->ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1561 hc->do_ping = 0U;
1562 }
1563 }
1564
1565 /* Compute the expected number of packets associated to the transfer */
1566 if (hc->xfer_len > 0U)
1567 {
1568 num_packets = (hc->xfer_len + hc->max_packet - 1U) / hc->max_packet;
1569
1570 if (num_packets > max_hc_pkt_count)
1571 {
1572 num_packets = max_hc_pkt_count;
1573 hc->xfer_len = num_packets * hc->max_packet;
1574 }
1575 }
1576 else
1577 {
1578 num_packets = 1;
1579 }
1580 if (hc->ep_is_in)
1581 {
1582 hc->xfer_len = num_packets * hc->max_packet;
1583 }
1584
1585 /* Initialize the HCTSIZn register */
1586 USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
1587 ((num_packets << 19U) & USB_OTG_HCTSIZ_PKTCNT) |\
1588 (((hc->data_pid) << 29U) & USB_OTG_HCTSIZ_DPID);
1589
1590 if (dma)
1591 {
1592 /* xfer_buff MUST be 32-bits aligned */
1593 USBx_HC(hc->ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1594 }
1595
1596 is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
1597 USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1598 USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
1599
1600 /* Set host channel enable */
1601 tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
1602 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1603 tmpreg |= USB_OTG_HCCHAR_CHENA;
1604 USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
1605
1606 if (dma == 0) /* Slave mode */
1607 {
1608 if((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1609 {
1610 switch(hc->ep_type)
1611 {
1612 /* Non periodic transfer */
1613 case EP_TYPE_CTRL:
1614 case EP_TYPE_BULK:
1615
1616 len_words = (hc->xfer_len + 3) / 4;
1617
1618 /* check if there is enough space in FIFO space */
1619 if(len_words > (USBx->HNPTXSTS & 0xFFFF))
1620 {
1621 /* need to process data in nptxfempty interrupt */
1622 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1623 }
1624 break;
1625 /* Periodic transfer */
1626 case EP_TYPE_INTR:
1627 case EP_TYPE_ISOC:
1628 len_words = (hc->xfer_len + 3) / 4;
1629 /* check if there is enough space in FIFO space */
1630 if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */
1631 {
1632 /* need to process data in ptxfempty interrupt */
1633 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1634 }
1635 break;
1636
1637 default:
1638 break;
1639 }
1640
1641 /* Write packet into the Tx FIFO. */
1642 USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0);
1643 }
1644 }
1645
1646 return HAL_OK;
1647 }
1648
1649 /**
1650 * @brief Read all host channel interrupts status
1651 * @param USBx Selected device
1652 * @retval HAL state
1653 */
1654 uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
1655 {
1656 return ((USBx_HOST->HAINT) & 0xFFFFU);
1657 }
1658
1659 /**
1660 * @brief Halt a host channel
1661 * @param USBx Selected device
1662 * @param hc_num Host Channel number
1663 * This parameter can be a value from 1 to 15
1664 * @retval HAL state
1665 */
1666 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
1667 {
1668 uint32_t count = 0U;
1669
1670 /* Check for space in the request queue to issue the halt. */
1671 if (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL) || (((((USBx_HC(hc_num)->HCCHAR) &
1672 USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK)))
1673 {
1674 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1675
1676 if ((USBx->HNPTXSTS & 0xFF0000U) == 0U)
1677 {
1678 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1679 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1680 do
1681 {
1682 if (++count > 1000U)
1683 {
1684 break;
1685 }
1686 }
1687 while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1688 }
1689 else
1690 {
1691 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1692 }
1693 }
1694 else
1695 {
1696 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1697
1698 if ((USBx_HOST->HPTXSTS & 0xFFFFU) == 0U)
1699 {
1700 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1701 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1702 do
1703 {
1704 if (++count > 1000U)
1705 {
1706 break;
1707 }
1708 }
1709 while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1710 }
1711 else
1712 {
1713 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1714 }
1715 }
1716
1717 return HAL_OK;
1718 }
1719
1720 /**
1721 * @brief Initiate Do Ping protocol
1722 * @param USBx Selected device
1723 * @param hc_num Host Channel number
1724 * This parameter can be a value from 1 to 15
1725 * @retval HAL state
1726 */
1727 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
1728 {
1729 uint8_t num_packets = 1U;
1730 uint32_t tmpreg = 0U;
1731
1732 USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19U) & USB_OTG_HCTSIZ_PKTCNT) |\
1733 USB_OTG_HCTSIZ_DOPING;
1734
1735 /* Set host channel enable */
1736 tmpreg = USBx_HC(ch_num)->HCCHAR;
1737 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1738 tmpreg |= USB_OTG_HCCHAR_CHENA;
1739 USBx_HC(ch_num)->HCCHAR = tmpreg;
1740
1741 return HAL_OK;
1742 }
1743
1744 /**
1745 * @brief Stop Host Core
1746 * @param USBx Selected device
1747 * @retval HAL state
1748 */
1749 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1750 {
1751 uint8_t i;
1752 uint32_t count = 0U;
1753 uint32_t value;
1754
1755 USB_DisableGlobalInt(USBx);
1756
1757 /* Flush FIFO */
1758 USB_FlushTxFifo(USBx, 0x10U);
1759 USB_FlushRxFifo(USBx);
1760
1761 /* Flush out any leftover queued requests. */
1762 for (i = 0; i <= 15; i++)
1763 {
1764
1765 value = USBx_HC(i)->HCCHAR ;
1766 value |= USB_OTG_HCCHAR_CHDIS;
1767 value &= ~USB_OTG_HCCHAR_CHENA;
1768 value &= ~USB_OTG_HCCHAR_EPDIR;
1769 USBx_HC(i)->HCCHAR = value;
1770 }
1771
1772 /* Halt all channels to put them into a known state. */
1773 for (i = 0; i <= 15; i++)
1774 {
1775 value = USBx_HC(i)->HCCHAR ;
1776
1777 value |= USB_OTG_HCCHAR_CHDIS;
1778 value |= USB_OTG_HCCHAR_CHENA;
1779 value &= ~USB_OTG_HCCHAR_EPDIR;
1780
1781 USBx_HC(i)->HCCHAR = value;
1782 do
1783 {
1784 if (++count > 1000U)
1785 {
1786 break;
1787 }
1788 }
1789 while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1790 }
1791
1792 /* Clear any pending Host interrupts */
1793 USBx_HOST->HAINT = 0xFFFFFFFFU;
1794 USBx->GINTSTS = 0xFFFFFFFFU;
1795 USB_EnableGlobalInt(USBx);
1796 return HAL_OK;
1797 }
1798 /**
1799 * @}
1800 */
1801 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
1802 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx ||
1803 STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
1804 #endif /* defined(HAL_PCD_MODULE_ENABLED) || defined(HAL_HCD_MODULE_ENABLED) */
1805
1806 /**
1807 * @}
1808 */
1809
1810 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/