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