25f700438e509270d2f0fa54e1854bd7f9afd1f5
[mTask.git] / int / com / lib / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_hcd.c
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_hcd.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 22-April-2016
7 * @brief HCD HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the USB Peripheral Controller:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral Control functions
13 * + Peripheral State functions
14 *
15 @verbatim
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
19 [..]
20 (#)Declare a HCD_HandleTypeDef handle structure, for example:
21 HCD_HandleTypeDef hhcd;
22
23 (#)Fill parameters of Init structure in HCD handle
24
25 (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
26
27 (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
28 (##) Enable the HCD/USB Low Level interface clock using the following macros
29 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
30 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
31 (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode)
32
33 (##) Initialize the related GPIO clocks
34 (##) Configure HCD pin-out
35 (##) Configure HCD NVIC interrupt
36
37 (#)Associate the Upper USB Host stack to the HAL HCD Driver:
38 (##) hhcd.pData = phost;
39
40 (#)Enable HCD transmission and reception:
41 (##) HAL_HCD_Start();
42
43 @endverbatim
44 ******************************************************************************
45 * @attention
46 *
47 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
48 *
49 * Redistribution and use in source and binary forms, with or without modification,
50 * are permitted provided that the following conditions are met:
51 * 1. Redistributions of source code must retain the above copyright notice,
52 * this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright notice,
54 * this list of conditions and the following disclaimer in the documentation
55 * and/or other materials provided with the distribution.
56 * 3. Neither the name of STMicroelectronics nor the names of its contributors
57 * may be used to endorse or promote products derived from this software
58 * without specific prior written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
61 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
66 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
67 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
68 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
69 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70 *
71 ******************************************************************************
72 */
73
74 /* Includes ------------------------------------------------------------------*/
75 #include "stm32f7xx_hal.h"
76
77 /** @addtogroup STM32F7xx_HAL_Driver
78 * @{
79 */
80
81 /** @defgroup HCD HCD
82 * @brief HCD HAL module driver
83 * @{
84 */
85
86 #ifdef HAL_HCD_MODULE_ENABLED
87
88 /* Private typedef -----------------------------------------------------------*/
89 /* Private define ------------------------------------------------------------*/
90 /* Private macro -------------------------------------------------------------*/
91 /* Private variables ---------------------------------------------------------*/
92 /* Private function ----------------------------------------------------------*/
93 /** @defgroup HCD_Private_Functions HCD Private Functions
94 * @{
95 */
96 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
97 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
98 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
99 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
100 /**
101 * @}
102 */
103
104 /* Exported functions --------------------------------------------------------*/
105 /** @defgroup HCD_Exported_Functions HCD Exported Functions
106 * @{
107 */
108
109 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
110 * @brief Initialization and Configuration functions
111 *
112 @verbatim
113 ===============================================================================
114 ##### Initialization and de-initialization functions #####
115 ===============================================================================
116 [..] This section provides functions allowing to:
117
118 @endverbatim
119 * @{
120 */
121
122 /**
123 * @brief Initialize the host driver.
124 * @param hhcd: HCD handle
125 * @retval HAL status
126 */
127 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
128 {
129 /* Check the HCD handle allocation */
130 if(hhcd == NULL)
131 {
132 return HAL_ERROR;
133 }
134
135 /* Check the parameters */
136 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
137
138 hhcd->State = HAL_HCD_STATE_BUSY;
139
140 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
141 HAL_HCD_MspInit(hhcd);
142
143 /* Disable the Interrupts */
144 __HAL_HCD_DISABLE(hhcd);
145
146 /*Init the Core (common init.) */
147 USB_CoreInit(hhcd->Instance, hhcd->Init);
148
149 /* Force Host Mode*/
150 USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE);
151
152 /* Init Host */
153 USB_HostInit(hhcd->Instance, hhcd->Init);
154
155 hhcd->State= HAL_HCD_STATE_READY;
156
157 return HAL_OK;
158 }
159
160 /**
161 * @brief Initialize a host channel.
162 * @param hhcd: HCD handle
163 * @param ch_num: Channel number.
164 * This parameter can be a value from 1 to 15
165 * @param epnum: Endpoint number.
166 * This parameter can be a value from 1 to 15
167 * @param dev_address : Current device address
168 * This parameter can be a value from 0 to 255
169 * @param speed: Current device speed.
170 * This parameter can be one of these values:
171 * HCD_SPEED_HIGH: High speed mode,
172 * HCD_SPEED_FULL: Full speed mode,
173 * HCD_SPEED_LOW: Low speed mode
174 * @param ep_type: Endpoint Type.
175 * This parameter can be one of these values:
176 * EP_TYPE_CTRL: Control type,
177 * EP_TYPE_ISOC: Isochronous type,
178 * EP_TYPE_BULK: Bulk type,
179 * EP_TYPE_INTR: Interrupt type
180 * @param mps: Max Packet Size.
181 * This parameter can be a value from 0 to32K
182 * @retval HAL status
183 */
184 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
185 uint8_t ch_num,
186 uint8_t epnum,
187 uint8_t dev_address,
188 uint8_t speed,
189 uint8_t ep_type,
190 uint16_t mps)
191 {
192 HAL_StatusTypeDef status = HAL_OK;
193
194 __HAL_LOCK(hhcd);
195
196 hhcd->hc[ch_num].dev_addr = dev_address;
197 hhcd->hc[ch_num].max_packet = mps;
198 hhcd->hc[ch_num].ch_num = ch_num;
199 hhcd->hc[ch_num].ep_type = ep_type;
200 hhcd->hc[ch_num].ep_num = epnum & 0x7F;
201 hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80);
202 hhcd->hc[ch_num].speed = speed;
203
204 status = USB_HC_Init(hhcd->Instance,
205 ch_num,
206 epnum,
207 dev_address,
208 speed,
209 ep_type,
210 mps);
211 __HAL_UNLOCK(hhcd);
212
213 return status;
214 }
215
216 /**
217 * @brief Halt a host channel.
218 * @param hhcd: HCD handle
219 * @param ch_num: Channel number.
220 * This parameter can be a value from 1 to 15
221 * @retval HAL status
222 */
223 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
224 {
225 HAL_StatusTypeDef status = HAL_OK;
226
227 __HAL_LOCK(hhcd);
228 USB_HC_Halt(hhcd->Instance, ch_num);
229 __HAL_UNLOCK(hhcd);
230
231 return status;
232 }
233
234 /**
235 * @brief DeInitialize the host driver.
236 * @param hhcd: HCD handle
237 * @retval HAL status
238 */
239 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
240 {
241 /* Check the HCD handle allocation */
242 if(hhcd == NULL)
243 {
244 return HAL_ERROR;
245 }
246
247 hhcd->State = HAL_HCD_STATE_BUSY;
248
249 /* DeInit the low level hardware */
250 HAL_HCD_MspDeInit(hhcd);
251
252 __HAL_HCD_DISABLE(hhcd);
253
254 hhcd->State = HAL_HCD_STATE_RESET;
255
256 return HAL_OK;
257 }
258
259 /**
260 * @brief Initialize the HCD MSP.
261 * @param hhcd: HCD handle
262 * @retval None
263 */
264 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
265 {
266 /* Prevent unused argument(s) compilation warning */
267 UNUSED(hhcd);
268
269 /* NOTE : This function Should not be modified, when the callback is needed,
270 the HAL_HCD_MspInit could be implemented in the user file
271 */
272 }
273
274 /**
275 * @brief DeInitialize the HCD MSP.
276 * @param hhcd: HCD handle
277 * @retval None
278 */
279 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
280 {
281 /* Prevent unused argument(s) compilation warning */
282 UNUSED(hhcd);
283
284 /* NOTE : This function Should not be modified, when the callback is needed,
285 the HAL_HCD_MspDeInit could be implemented in the user file
286 */
287 }
288
289 /**
290 * @}
291 */
292
293 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
294 * @brief HCD IO operation functions
295 *
296 @verbatim
297 ===============================================================================
298 ##### IO operation functions #####
299 ===============================================================================
300 [..] This subsection provides a set of functions allowing to manage the USB Host Data
301 Transfer
302
303 @endverbatim
304 * @{
305 */
306
307 /**
308 * @brief Submit a new URB for processing.
309 * @param hhcd: HCD handle
310 * @param ch_num: Channel number.
311 * This parameter can be a value from 1 to 15
312 * @param direction: Channel number.
313 * This parameter can be one of these values:
314 * 0 : Output / 1 : Input
315 * @param ep_type: Endpoint Type.
316 * This parameter can be one of these values:
317 * EP_TYPE_CTRL: Control type/
318 * EP_TYPE_ISOC: Isochronous type/
319 * EP_TYPE_BULK: Bulk type/
320 * EP_TYPE_INTR: Interrupt type/
321 * @param token: Endpoint Type.
322 * This parameter can be one of these values:
323 * 0: HC_PID_SETUP / 1: HC_PID_DATA1
324 * @param pbuff: pointer to URB data
325 * @param length: Length of URB data
326 * @param do_ping: activate do ping protocol (for high speed only).
327 * This parameter can be one of these values:
328 * 0 : do ping inactive / 1 : do ping active
329 * @retval HAL status
330 */
331 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
332 uint8_t ch_num,
333 uint8_t direction ,
334 uint8_t ep_type,
335 uint8_t token,
336 uint8_t* pbuff,
337 uint16_t length,
338 uint8_t do_ping)
339 {
340 hhcd->hc[ch_num].ep_is_in = direction;
341 hhcd->hc[ch_num].ep_type = ep_type;
342
343 if(token == 0)
344 {
345 hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
346 }
347 else
348 {
349 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
350 }
351
352 /* Manage Data Toggle */
353 switch(ep_type)
354 {
355 case EP_TYPE_CTRL:
356 if((token == 1) && (direction == 0)) /*send data */
357 {
358 if ( length == 0 )
359 { /* For Status OUT stage, Length==0, Status Out PID = 1 */
360 hhcd->hc[ch_num].toggle_out = 1;
361 }
362
363 /* Set the Data Toggle bit as per the Flag */
364 if ( hhcd->hc[ch_num].toggle_out == 0)
365 { /* Put the PID 0 */
366 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
367 }
368 else
369 { /* Put the PID 1 */
370 hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
371 }
372 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
373 {
374 hhcd->hc[ch_num].do_ping = do_ping;
375 }
376 }
377 break;
378
379 case EP_TYPE_BULK:
380 if(direction == 0)
381 {
382 /* Set the Data Toggle bit as per the Flag */
383 if ( hhcd->hc[ch_num].toggle_out == 0)
384 { /* Put the PID 0 */
385 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
386 }
387 else
388 { /* Put the PID 1 */
389 hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
390 }
391 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
392 {
393 hhcd->hc[ch_num].do_ping = do_ping;
394 }
395 }
396 else
397 {
398 if( hhcd->hc[ch_num].toggle_in == 0)
399 {
400 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
401 }
402 else
403 {
404 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
405 }
406 }
407
408 break;
409 case EP_TYPE_INTR:
410 if(direction == 0)
411 {
412 /* Set the Data Toggle bit as per the Flag */
413 if ( hhcd->hc[ch_num].toggle_out == 0)
414 { /* Put the PID 0 */
415 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
416 }
417 else
418 { /* Put the PID 1 */
419 hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
420 }
421 }
422 else
423 {
424 if( hhcd->hc[ch_num].toggle_in == 0)
425 {
426 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
427 }
428 else
429 {
430 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
431 }
432 }
433 break;
434
435 case EP_TYPE_ISOC:
436 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
437 break;
438 }
439
440 hhcd->hc[ch_num].xfer_buff = pbuff;
441 hhcd->hc[ch_num].xfer_len = length;
442 hhcd->hc[ch_num].urb_state = URB_IDLE;
443 hhcd->hc[ch_num].xfer_count = 0 ;
444 hhcd->hc[ch_num].ch_num = ch_num;
445 hhcd->hc[ch_num].state = HC_IDLE;
446
447 return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable);
448 }
449
450 /**
451 * @brief Handle HCD interrupt request.
452 * @param hhcd: HCD handle
453 * @retval None
454 */
455 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
456 {
457 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
458 uint32_t i = 0 , interrupt = 0;
459
460 /* ensure that we are in device mode */
461 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
462 {
463 /* avoid spurious interrupt */
464 if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
465 {
466 return;
467 }
468
469 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
470 {
471 /* incorrect mode, acknowledge the interrupt */
472 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
473 }
474
475 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
476 {
477 /* incorrect mode, acknowledge the interrupt */
478 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
479 }
480
481 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
482 {
483 /* incorrect mode, acknowledge the interrupt */
484 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
485 }
486
487 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
488 {
489 /* incorrect mode, acknowledge the interrupt */
490 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
491 }
492
493 /* Handle Host Disconnect Interrupts */
494 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
495 {
496
497 /* Cleanup HPRT */
498 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
499 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
500
501 /* Handle Host Port Interrupts */
502 HAL_HCD_Disconnect_Callback(hhcd);
503 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
504 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
505 }
506
507 /* Handle Host Port Interrupts */
508 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
509 {
510 HCD_Port_IRQHandler (hhcd);
511 }
512
513 /* Handle Host SOF Interrupts */
514 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
515 {
516 HAL_HCD_SOF_Callback(hhcd);
517 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
518 }
519
520 /* Handle Host channel Interrupts */
521 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
522 {
523 interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
524 for (i = 0; i < hhcd->Init.Host_channels ; i++)
525 {
526 if (interrupt & (1 << i))
527 {
528 if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR)
529 {
530 HCD_HC_IN_IRQHandler (hhcd, i);
531 }
532 else
533 {
534 HCD_HC_OUT_IRQHandler (hhcd, i);
535 }
536 }
537 }
538 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
539 }
540
541 /* Handle Rx Queue Level Interrupts */
542 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
543 {
544 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
545
546 HCD_RXQLVL_IRQHandler (hhcd);
547
548 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
549 }
550 }
551 }
552
553 /**
554 * @brief SOF callback.
555 * @param hhcd: HCD handle
556 * @retval None
557 */
558 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
559 {
560 /* Prevent unused argument(s) compilation warning */
561 UNUSED(hhcd);
562
563 /* NOTE : This function Should not be modified, when the callback is needed,
564 the HAL_HCD_SOF_Callback could be implemented in the user file
565 */
566 }
567
568 /**
569 * @brief Connection Event callback.
570 * @param hhcd: HCD handle
571 * @retval None
572 */
573 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
574 {
575 /* Prevent unused argument(s) compilation warning */
576 UNUSED(hhcd);
577
578 /* NOTE : This function Should not be modified, when the callback is needed,
579 the HAL_HCD_Connect_Callback could be implemented in the user file
580 */
581 }
582
583 /**
584 * @brief Disconnection Event callback.
585 * @param hhcd: HCD handle
586 * @retval None
587 */
588 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
589 {
590 /* Prevent unused argument(s) compilation warning */
591 UNUSED(hhcd);
592
593 /* NOTE : This function Should not be modified, when the callback is needed,
594 the HAL_HCD_Disconnect_Callback could be implemented in the user file
595 */
596 }
597
598 /**
599 * @brief Notify URB state change callback.
600 * @param hhcd: HCD handle
601 * @param chnum: Channel number.
602 * This parameter can be a value from 1 to 15
603 * @param urb_state:
604 * This parameter can be one of these values:
605 * URB_IDLE/
606 * URB_DONE/
607 * URB_NOTREADY/
608 * URB_NYET/
609 * URB_ERROR/
610 * URB_STALL/
611 * @retval None
612 */
613 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
614 {
615 /* Prevent unused argument(s) compilation warning */
616 UNUSED(hhcd);
617
618 /* NOTE : This function Should not be modified, when the callback is needed,
619 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
620 */
621 }
622
623 /**
624 * @}
625 */
626
627 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
628 * @brief Management functions
629 *
630 @verbatim
631 ===============================================================================
632 ##### Peripheral Control functions #####
633 ===============================================================================
634 [..]
635 This subsection provides a set of functions allowing to control the HCD data
636 transfers.
637
638 @endverbatim
639 * @{
640 */
641
642 /**
643 * @brief Start the host driver.
644 * @param hhcd: HCD handle
645 * @retval HAL status
646 */
647 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
648 {
649 __HAL_LOCK(hhcd);
650 __HAL_HCD_ENABLE(hhcd);
651 USB_DriveVbus(hhcd->Instance, 1);
652 __HAL_UNLOCK(hhcd);
653 return HAL_OK;
654 }
655
656 /**
657 * @brief Stop the host driver.
658 * @param hhcd: HCD handle
659 * @retval HAL status
660 */
661
662 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
663 {
664 __HAL_LOCK(hhcd);
665 USB_StopHost(hhcd->Instance);
666 __HAL_UNLOCK(hhcd);
667 return HAL_OK;
668 }
669
670 /**
671 * @brief Reset the host port.
672 * @param hhcd: HCD handle
673 * @retval HAL status
674 */
675 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
676 {
677 return (USB_ResetPort(hhcd->Instance));
678 }
679
680 /**
681 * @}
682 */
683
684 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
685 * @brief Peripheral State functions
686 *
687 @verbatim
688 ===============================================================================
689 ##### Peripheral State functions #####
690 ===============================================================================
691 [..]
692 This subsection permits to get in run-time the status of the peripheral
693 and the data flow.
694
695 @endverbatim
696 * @{
697 */
698
699 /**
700 * @brief Return the HCD handle state.
701 * @param hhcd: HCD handle
702 * @retval HAL state
703 */
704 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
705 {
706 return hhcd->State;
707 }
708
709 /**
710 * @brief Return URB state for a channel.
711 * @param hhcd: HCD handle
712 * @param chnum: Channel number.
713 * This parameter can be a value from 1 to 15
714 * @retval URB state.
715 * This parameter can be one of these values:
716 * URB_IDLE/
717 * URB_DONE/
718 * URB_NOTREADY/
719 * URB_NYET/
720 * URB_ERROR/
721 * URB_STALL
722 */
723 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
724 {
725 return hhcd->hc[chnum].urb_state;
726 }
727
728
729 /**
730 * @brief Return the last host transfer size.
731 * @param hhcd: HCD handle
732 * @param chnum: Channel number.
733 * This parameter can be a value from 1 to 15
734 * @retval last transfer size in byte
735 */
736 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
737 {
738 return hhcd->hc[chnum].xfer_count;
739 }
740
741 /**
742 * @brief Return the Host Channel state.
743 * @param hhcd: HCD handle
744 * @param chnum: Channel number.
745 * This parameter can be a value from 1 to 15
746 * @retval Host channel state
747 * This parameter can be one of these values:
748 * HC_IDLE/
749 * HC_XFRC/
750 * HC_HALTED/
751 * HC_NYET/
752 * HC_NAK/
753 * HC_STALL/
754 * HC_XACTERR/
755 * HC_BBLERR/
756 * HC_DATATGLERR
757 */
758 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
759 {
760 return hhcd->hc[chnum].state;
761 }
762
763 /**
764 * @brief Return the current Host frame number.
765 * @param hhcd: HCD handle
766 * @retval Current Host frame number
767 */
768 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
769 {
770 return (USB_GetCurrentFrame(hhcd->Instance));
771 }
772
773 /**
774 * @brief Return the Host enumeration speed.
775 * @param hhcd: HCD handle
776 * @retval Enumeration speed
777 */
778 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
779 {
780 return (USB_GetHostSpeed(hhcd->Instance));
781 }
782
783 /**
784 * @}
785 */
786
787 /**
788 * @}
789 */
790
791 /** @addtogroup HCD_Private_Functions
792 * @{
793 */
794 /**
795 * @brief Handle Host Channel IN interrupt requests.
796 * @param hhcd: HCD handle
797 * @param chnum: Channel number.
798 * This parameter can be a value from 1 to 15
799 * @retval none
800 */
801 static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
802 {
803 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
804 uint32_t tmpreg = 0;
805
806 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
807 {
808 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
809 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
810 }
811 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
812 {
813 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
814 }
815
816 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
817 {
818 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
819 hhcd->hc[chnum].state = HC_STALL;
820 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
821 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
822 USB_HC_Halt(hhcd->Instance, chnum);
823 }
824 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
825 {
826 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
827 USB_HC_Halt(hhcd->Instance, chnum);
828 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
829 hhcd->hc[chnum].state = HC_DATATGLERR;
830 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
831 }
832
833 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
834 {
835 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
836 USB_HC_Halt(hhcd->Instance, chnum);
837 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
838 }
839
840 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
841 {
842
843 if (hhcd->Init.dma_enable)
844 {
845 hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \
846 (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
847 }
848
849 hhcd->hc[chnum].state = HC_XFRC;
850 hhcd->hc[chnum].ErrCnt = 0;
851 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
852
853
854 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
855 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
856 {
857 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
858 USB_HC_Halt(hhcd->Instance, chnum);
859 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
860
861 }
862 else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
863 {
864 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
865 hhcd->hc[chnum].urb_state = URB_DONE;
866 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
867 }
868 hhcd->hc[chnum].toggle_in ^= 1;
869
870 }
871 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
872 {
873 __HAL_HCD_MASK_HALT_HC_INT(chnum);
874
875 if(hhcd->hc[chnum].state == HC_XFRC)
876 {
877 hhcd->hc[chnum].urb_state = URB_DONE;
878 }
879
880 else if (hhcd->hc[chnum].state == HC_STALL)
881 {
882 hhcd->hc[chnum].urb_state = URB_STALL;
883 }
884
885 else if((hhcd->hc[chnum].state == HC_XACTERR) ||
886 (hhcd->hc[chnum].state == HC_DATATGLERR))
887 {
888 if(hhcd->hc[chnum].ErrCnt++ > 3)
889 {
890 hhcd->hc[chnum].ErrCnt = 0;
891 hhcd->hc[chnum].urb_state = URB_ERROR;
892 }
893 else
894 {
895 hhcd->hc[chnum].urb_state = URB_NOTREADY;
896 }
897
898 /* re-activate the channel */
899 tmpreg = USBx_HC(chnum)->HCCHAR;
900 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
901 tmpreg |= USB_OTG_HCCHAR_CHENA;
902 USBx_HC(chnum)->HCCHAR = tmpreg;
903 }
904 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
905 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
906 }
907
908 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
909 {
910 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
911 hhcd->hc[chnum].ErrCnt++;
912 hhcd->hc[chnum].state = HC_XACTERR;
913 USB_HC_Halt(hhcd->Instance, chnum);
914 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
915 }
916 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
917 {
918 if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
919 {
920 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
921 USB_HC_Halt(hhcd->Instance, chnum);
922 }
923 else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
924 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
925 {
926 /* re-activate the channel */
927 tmpreg = USBx_HC(chnum)->HCCHAR;
928 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
929 tmpreg |= USB_OTG_HCCHAR_CHENA;
930 USBx_HC(chnum)->HCCHAR = tmpreg;
931 }
932 hhcd->hc[chnum].state = HC_NAK;
933 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
934 }
935 }
936
937 /**
938 * @brief Handle Host Channel OUT interrupt requests.
939 * @param hhcd: HCD handle
940 * @param chnum: Channel number.
941 * This parameter can be a value from 1 to 15
942 * @retval none
943 */
944 static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
945 {
946 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
947 uint32_t tmpreg = 0;
948
949 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
950 {
951 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
952 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
953 }
954 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
955 {
956 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
957
958 if( hhcd->hc[chnum].do_ping == 1)
959 {
960 hhcd->hc[chnum].state = HC_NYET;
961 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
962 USB_HC_Halt(hhcd->Instance, chnum);
963 hhcd->hc[chnum].urb_state = URB_NOTREADY;
964 }
965 }
966
967 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET)
968 {
969 hhcd->hc[chnum].state = HC_NYET;
970 hhcd->hc[chnum].ErrCnt= 0;
971 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
972 USB_HC_Halt(hhcd->Instance, chnum);
973 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
974
975 }
976
977 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
978 {
979 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
980 USB_HC_Halt(hhcd->Instance, chnum);
981 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
982 }
983
984 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
985 {
986 hhcd->hc[chnum].ErrCnt = 0;
987 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
988 USB_HC_Halt(hhcd->Instance, chnum);
989 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
990 hhcd->hc[chnum].state = HC_XFRC;
991
992 }
993
994 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
995 {
996 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
997 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
998 USB_HC_Halt(hhcd->Instance, chnum);
999 hhcd->hc[chnum].state = HC_STALL;
1000 }
1001
1002 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
1003 {
1004 hhcd->hc[chnum].ErrCnt = 0;
1005 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
1006 USB_HC_Halt(hhcd->Instance, chnum);
1007 hhcd->hc[chnum].state = HC_NAK;
1008 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1009 }
1010
1011 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
1012 {
1013 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
1014 USB_HC_Halt(hhcd->Instance, chnum);
1015 hhcd->hc[chnum].state = HC_XACTERR;
1016 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1017 }
1018
1019 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
1020 {
1021 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
1022 USB_HC_Halt(hhcd->Instance, chnum);
1023 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1024 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1025 hhcd->hc[chnum].state = HC_DATATGLERR;
1026 }
1027
1028
1029 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
1030 {
1031 __HAL_HCD_MASK_HALT_HC_INT(chnum);
1032
1033 if(hhcd->hc[chnum].state == HC_XFRC)
1034 {
1035 hhcd->hc[chnum].urb_state = URB_DONE;
1036 if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
1037 {
1038 hhcd->hc[chnum].toggle_out ^= 1;
1039 }
1040 }
1041 else if (hhcd->hc[chnum].state == HC_NAK)
1042 {
1043 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1044 }
1045
1046 else if (hhcd->hc[chnum].state == HC_NYET)
1047 {
1048 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1049 hhcd->hc[chnum].do_ping = 0;
1050 }
1051
1052 else if (hhcd->hc[chnum].state == HC_STALL)
1053 {
1054 hhcd->hc[chnum].urb_state = URB_STALL;
1055 }
1056
1057 else if((hhcd->hc[chnum].state == HC_XACTERR) ||
1058 (hhcd->hc[chnum].state == HC_DATATGLERR))
1059 {
1060 if(hhcd->hc[chnum].ErrCnt++ > 3)
1061 {
1062 hhcd->hc[chnum].ErrCnt = 0;
1063 hhcd->hc[chnum].urb_state = URB_ERROR;
1064 }
1065 else
1066 {
1067 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1068 }
1069
1070 /* re-activate the channel */
1071 tmpreg = USBx_HC(chnum)->HCCHAR;
1072 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1073 tmpreg |= USB_OTG_HCCHAR_CHENA;
1074 USBx_HC(chnum)->HCCHAR = tmpreg;
1075 }
1076
1077 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1078 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1079 }
1080 }
1081
1082 /**
1083 * @brief Handle Rx Queue Level interrupt requests.
1084 * @param hhcd: HCD handle
1085 * @retval none
1086 */
1087 static void HCD_RXQLVL_IRQHandler (HCD_HandleTypeDef *hhcd)
1088 {
1089 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1090 uint8_t channelnum =0;
1091 uint32_t pktsts;
1092 uint32_t pktcnt;
1093 uint32_t temp = 0;
1094 uint32_t tmpreg = 0;
1095
1096 temp = hhcd->Instance->GRXSTSP ;
1097 channelnum = temp & USB_OTG_GRXSTSP_EPNUM;
1098 pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17;
1099 pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1100
1101 switch (pktsts)
1102 {
1103 case GRXSTS_PKTSTS_IN:
1104 /* Read the data into the host buffer. */
1105 if ((pktcnt > 0) && (hhcd->hc[channelnum].xfer_buff != (void *)0))
1106 {
1107
1108 USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
1109
1110 /*manage multiple Xfer */
1111 hhcd->hc[channelnum].xfer_buff += pktcnt;
1112 hhcd->hc[channelnum].xfer_count += pktcnt;
1113
1114 if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0)
1115 {
1116 /* re-activate the channel when more packets are expected */
1117 tmpreg = USBx_HC(channelnum)->HCCHAR;
1118 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1119 tmpreg |= USB_OTG_HCCHAR_CHENA;
1120 USBx_HC(channelnum)->HCCHAR = tmpreg;
1121 hhcd->hc[channelnum].toggle_in ^= 1;
1122 }
1123 }
1124 break;
1125
1126 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1127 break;
1128 case GRXSTS_PKTSTS_IN_XFER_COMP:
1129 case GRXSTS_PKTSTS_CH_HALTED:
1130 default:
1131 break;
1132 }
1133 }
1134
1135 /**
1136 * @brief Handle Host Port interrupt requests.
1137 * @param hhcd: HCD handle
1138 * @retval None
1139 */
1140 static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
1141 {
1142 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1143 __IO uint32_t hprt0, hprt0_dup;
1144
1145 /* Handle Host Port Interrupts */
1146 hprt0 = USBx_HPRT0;
1147 hprt0_dup = USBx_HPRT0;
1148
1149 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1150 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1151
1152 /* Check whether Port Connect detected */
1153 if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1154 {
1155 if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1156 {
1157 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1158 HAL_HCD_Connect_Callback(hhcd);
1159 }
1160 hprt0_dup |= USB_OTG_HPRT_PCDET;
1161
1162 }
1163
1164 /* Check whether Port Enable Changed */
1165 if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1166 {
1167 hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1168
1169 if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1170 {
1171 if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
1172 {
1173 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
1174 {
1175 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
1176 }
1177 else
1178 {
1179 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
1180 }
1181 }
1182 else
1183 {
1184 if(hhcd->Init.speed == HCD_SPEED_FULL)
1185 {
1186 USBx_HOST->HFIR = (uint32_t)60000;
1187 }
1188 }
1189 HAL_HCD_Connect_Callback(hhcd);
1190
1191 }
1192 else
1193 {
1194 /* Cleanup HPRT */
1195 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1196 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1197
1198 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1199 }
1200 }
1201
1202 /* Check For an overcurrent */
1203 if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1204 {
1205 hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1206 }
1207
1208 /* Clear Port Interrupts */
1209 USBx_HPRT0 = hprt0_dup;
1210 }
1211
1212 /**
1213 * @}
1214 */
1215
1216 /**
1217 * @}
1218 */
1219
1220 #endif /* HAL_HCD_MODULE_ENABLED */
1221 /**
1222 * @}
1223 */
1224
1225 /**
1226 * @}
1227 */
1228
1229 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/