Merge pull request #10558 from iNavFlight/MrD_Correct-comments-on-OSD-symbols
[inav.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_hcd.c
blob3d3e5b7622b684b8a907bf3444b3d3acabedd7b8
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_hcd.c
4 * @author MCD Application Team
5 * @version V1.2.2
6 * @date 14-April-2017
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
15 @verbatim
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
19 [..]
20 (#)Declare a HCD_HandleTypeDef handle structure, for example:
21 HCD_HandleTypeDef hhcd;
23 (#)Fill parameters of Init structure in HCD handle
25 (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
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)
33 (##) Initialize the related GPIO clocks
34 (##) Configure HCD pin-out
35 (##) Configure HCD NVIC interrupt
37 (#)Associate the Upper USB Host stack to the HAL HCD Driver:
38 (##) hhcd.pData = phost;
40 (#)Enable HCD transmission and reception:
41 (##) HAL_HCD_Start();
43 @endverbatim
44 ******************************************************************************
45 * @attention
47 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
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.
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.
71 ******************************************************************************
72 */
74 /* Includes ------------------------------------------------------------------*/
75 #include "stm32f7xx_hal.h"
77 /** @addtogroup STM32F7xx_HAL_Driver
78 * @{
81 /** @defgroup HCD HCD
82 * @brief HCD HAL module driver
83 * @{
86 #ifdef HAL_HCD_MODULE_ENABLED
88 /* Private typedef -----------------------------------------------------------*/
89 /* Private define ------------------------------------------------------------*/
90 /* Private macro -------------------------------------------------------------*/
91 /* Private variables ---------------------------------------------------------*/
92 /* Private function ----------------------------------------------------------*/
93 /** @defgroup HCD_Private_Functions HCD Private Functions
94 * @{
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);
101 * @}
104 /* Exported functions --------------------------------------------------------*/
105 /** @defgroup HCD_Exported_Functions HCD Exported Functions
106 * @{
109 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
110 * @brief Initialization and Configuration functions
112 @verbatim
113 ===============================================================================
114 ##### Initialization and de-initialization functions #####
115 ===============================================================================
116 [..] This section provides functions allowing to:
118 @endverbatim
119 * @{
123 * @brief Initialize the host driver.
124 * @param hhcd: HCD handle
125 * @retval HAL status
127 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
129 /* Check the HCD handle allocation */
130 if(hhcd == NULL)
132 return HAL_ERROR;
135 /* Check the parameters */
136 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
138 hhcd->State = HAL_HCD_STATE_BUSY;
140 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
141 HAL_HCD_MspInit(hhcd);
143 /* Disable the Interrupts */
144 __HAL_HCD_DISABLE(hhcd);
146 /*Init the Core (common init.) */
147 USB_CoreInit(hhcd->Instance, hhcd->Init);
149 /* Force Host Mode*/
150 USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE);
152 /* Init Host */
153 USB_HostInit(hhcd->Instance, hhcd->Init);
155 hhcd->State= HAL_HCD_STATE_READY;
157 return HAL_OK;
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
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)
192 HAL_StatusTypeDef status = HAL_OK;
194 __HAL_LOCK(hhcd);
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;
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);
213 return status;
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
223 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
225 HAL_StatusTypeDef status = HAL_OK;
227 __HAL_LOCK(hhcd);
228 USB_HC_Halt(hhcd->Instance, ch_num);
229 __HAL_UNLOCK(hhcd);
231 return status;
235 * @brief DeInitialize the host driver.
236 * @param hhcd: HCD handle
237 * @retval HAL status
239 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
241 /* Check the HCD handle allocation */
242 if(hhcd == NULL)
244 return HAL_ERROR;
247 hhcd->State = HAL_HCD_STATE_BUSY;
249 /* DeInit the low level hardware */
250 HAL_HCD_MspDeInit(hhcd);
252 __HAL_HCD_DISABLE(hhcd);
254 hhcd->State = HAL_HCD_STATE_RESET;
256 return HAL_OK;
260 * @brief Initialize the HCD MSP.
261 * @param hhcd: HCD handle
262 * @retval None
264 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
266 /* Prevent unused argument(s) compilation warning */
267 UNUSED(hhcd);
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
275 * @brief DeInitialize the HCD MSP.
276 * @param hhcd: HCD handle
277 * @retval None
279 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
281 /* Prevent unused argument(s) compilation warning */
282 UNUSED(hhcd);
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
290 * @}
293 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
294 * @brief HCD IO operation functions
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
303 @endverbatim
304 * @{
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
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)
340 hhcd->hc[ch_num].ep_is_in = direction;
341 hhcd->hc[ch_num].ep_type = ep_type;
343 if(token == 0)
345 hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
347 else
349 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
352 /* Manage Data Toggle */
353 switch(ep_type)
355 case EP_TYPE_CTRL:
356 if((token == 1) && (direction == 0)) /*send data */
358 if ( length == 0 )
359 { /* For Status OUT stage, Length==0, Status Out PID = 1 */
360 hhcd->hc[ch_num].toggle_out = 1;
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;
368 else
369 { /* Put the PID 1 */
370 hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
372 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
374 hhcd->hc[ch_num].do_ping = do_ping;
377 break;
379 case EP_TYPE_BULK:
380 if(direction == 0)
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;
387 else
388 { /* Put the PID 1 */
389 hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
391 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
393 hhcd->hc[ch_num].do_ping = do_ping;
396 else
398 if( hhcd->hc[ch_num].toggle_in == 0)
400 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
402 else
404 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
408 break;
409 case EP_TYPE_INTR:
410 if(direction == 0)
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;
417 else
418 { /* Put the PID 1 */
419 hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
422 else
424 if( hhcd->hc[ch_num].toggle_in == 0)
426 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
428 else
430 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
433 break;
435 case EP_TYPE_ISOC:
436 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
437 break;
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;
447 return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable);
451 * @brief Handle HCD interrupt request.
452 * @param hhcd: HCD handle
453 * @retval None
455 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
457 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
458 uint32_t i = 0 , interrupt = 0;
460 /* ensure that we are in device mode */
461 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
463 /* avoid spurious interrupt */
464 if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
466 return;
469 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
471 /* incorrect mode, acknowledge the interrupt */
472 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
475 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
477 /* incorrect mode, acknowledge the interrupt */
478 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
481 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
483 /* incorrect mode, acknowledge the interrupt */
484 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
487 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
489 /* incorrect mode, acknowledge the interrupt */
490 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
493 /* Handle Host Disconnect Interrupts */
494 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
497 /* Cleanup HPRT */
498 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
499 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
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);
507 /* Handle Host Port Interrupts */
508 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
510 HCD_Port_IRQHandler (hhcd);
513 /* Handle Host SOF Interrupts */
514 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
516 HAL_HCD_SOF_Callback(hhcd);
517 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
520 /* Handle Host channel Interrupts */
521 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
523 interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
524 for (i = 0; i < hhcd->Init.Host_channels ; i++)
526 if (interrupt & (1 << i))
528 if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR)
530 HCD_HC_IN_IRQHandler (hhcd, i);
532 else
534 HCD_HC_OUT_IRQHandler (hhcd, i);
538 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
541 /* Handle Rx Queue Level Interrupts */
542 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
544 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
546 HCD_RXQLVL_IRQHandler (hhcd);
548 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
554 * @brief SOF callback.
555 * @param hhcd: HCD handle
556 * @retval None
558 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
560 /* Prevent unused argument(s) compilation warning */
561 UNUSED(hhcd);
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
569 * @brief Connection Event callback.
570 * @param hhcd: HCD handle
571 * @retval None
573 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
575 /* Prevent unused argument(s) compilation warning */
576 UNUSED(hhcd);
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
584 * @brief Disconnection Event callback.
585 * @param hhcd: HCD handle
586 * @retval None
588 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
590 /* Prevent unused argument(s) compilation warning */
591 UNUSED(hhcd);
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
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
613 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
615 /* Prevent unused argument(s) compilation warning */
616 UNUSED(hhcd);
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
624 * @}
627 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
628 * @brief Management functions
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.
638 @endverbatim
639 * @{
643 * @brief Start the host driver.
644 * @param hhcd: HCD handle
645 * @retval HAL status
647 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
649 __HAL_LOCK(hhcd);
650 __HAL_HCD_ENABLE(hhcd);
651 USB_DriveVbus(hhcd->Instance, 1);
652 __HAL_UNLOCK(hhcd);
653 return HAL_OK;
657 * @brief Stop the host driver.
658 * @param hhcd: HCD handle
659 * @retval HAL status
662 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
664 __HAL_LOCK(hhcd);
665 USB_StopHost(hhcd->Instance);
666 __HAL_UNLOCK(hhcd);
667 return HAL_OK;
671 * @brief Reset the host port.
672 * @param hhcd: HCD handle
673 * @retval HAL status
675 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
677 return (USB_ResetPort(hhcd->Instance));
681 * @}
684 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
685 * @brief Peripheral State functions
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.
695 @endverbatim
696 * @{
700 * @brief Return the HCD handle state.
701 * @param hhcd: HCD handle
702 * @retval HAL state
704 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
706 return hhcd->State;
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
723 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
725 return hhcd->hc[chnum].urb_state;
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
736 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
738 return hhcd->hc[chnum].xfer_count;
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
758 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
760 return hhcd->hc[chnum].state;
764 * @brief Return the current Host frame number.
765 * @param hhcd: HCD handle
766 * @retval Current Host frame number
768 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
770 return (USB_GetCurrentFrame(hhcd->Instance));
774 * @brief Return the Host enumeration speed.
775 * @param hhcd: HCD handle
776 * @retval Enumeration speed
778 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
780 return (USB_GetHostSpeed(hhcd->Instance));
784 * @}
788 * @}
791 /** @addtogroup HCD_Private_Functions
792 * @{
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
801 static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
803 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
804 uint32_t tmpreg = 0;
806 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
808 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
809 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
811 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
813 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
816 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
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);
824 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
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);
833 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
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);
840 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
843 if (hhcd->Init.dma_enable)
845 hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \
846 (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
849 hhcd->hc[chnum].state = HC_XFRC;
850 hhcd->hc[chnum].ErrCnt = 0;
851 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
854 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
855 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
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);
862 else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
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);
868 hhcd->hc[chnum].toggle_in ^= 1;
871 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
873 __HAL_HCD_MASK_HALT_HC_INT(chnum);
875 if(hhcd->hc[chnum].state == HC_XFRC)
877 hhcd->hc[chnum].urb_state = URB_DONE;
880 else if (hhcd->hc[chnum].state == HC_STALL)
882 hhcd->hc[chnum].urb_state = URB_STALL;
885 else if((hhcd->hc[chnum].state == HC_XACTERR) ||
886 (hhcd->hc[chnum].state == HC_DATATGLERR))
888 if(hhcd->hc[chnum].ErrCnt++ > 3)
890 hhcd->hc[chnum].ErrCnt = 0;
891 hhcd->hc[chnum].urb_state = URB_ERROR;
893 else
895 hhcd->hc[chnum].urb_state = URB_NOTREADY;
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;
904 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
905 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
908 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
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);
916 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
918 if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
920 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
921 USB_HC_Halt(hhcd->Instance, chnum);
923 else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
924 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
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;
932 hhcd->hc[chnum].state = HC_NAK;
933 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
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
944 static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
946 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
947 uint32_t tmpreg = 0;
949 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
951 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
952 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
954 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
956 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
958 if( hhcd->hc[chnum].do_ping == 1)
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;
967 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET)
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);
977 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
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);
984 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
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;
994 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
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;
1002 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
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);
1011 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
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);
1019 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
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;
1029 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
1031 __HAL_HCD_MASK_HALT_HC_INT(chnum);
1033 if(hhcd->hc[chnum].state == HC_XFRC)
1035 hhcd->hc[chnum].urb_state = URB_DONE;
1036 if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
1038 hhcd->hc[chnum].toggle_out ^= 1;
1041 else if (hhcd->hc[chnum].state == HC_NAK)
1043 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1046 else if (hhcd->hc[chnum].state == HC_NYET)
1048 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1049 hhcd->hc[chnum].do_ping = 0;
1052 else if (hhcd->hc[chnum].state == HC_STALL)
1054 hhcd->hc[chnum].urb_state = URB_STALL;
1057 else if((hhcd->hc[chnum].state == HC_XACTERR) ||
1058 (hhcd->hc[chnum].state == HC_DATATGLERR))
1060 if(hhcd->hc[chnum].ErrCnt++ > 3)
1062 hhcd->hc[chnum].ErrCnt = 0;
1063 hhcd->hc[chnum].urb_state = URB_ERROR;
1065 else
1067 hhcd->hc[chnum].urb_state = URB_NOTREADY;
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;
1077 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1078 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1083 * @brief Handle Rx Queue Level interrupt requests.
1084 * @param hhcd: HCD handle
1085 * @retval none
1087 static void HCD_RXQLVL_IRQHandler (HCD_HandleTypeDef *hhcd)
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;
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;
1101 switch (pktsts)
1103 case GRXSTS_PKTSTS_IN:
1104 /* Read the data into the host buffer. */
1105 if ((pktcnt > 0) && (hhcd->hc[channelnum].xfer_buff != (void *)0))
1108 USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
1110 /*manage multiple Xfer */
1111 hhcd->hc[channelnum].xfer_buff += pktcnt;
1112 hhcd->hc[channelnum].xfer_count += pktcnt;
1114 if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0)
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;
1124 break;
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;
1136 * @brief Handle Host Port interrupt requests.
1137 * @param hhcd: HCD handle
1138 * @retval None
1140 static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
1142 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1143 __IO uint32_t hprt0, hprt0_dup;
1145 /* Handle Host Port Interrupts */
1146 hprt0 = USBx_HPRT0;
1147 hprt0_dup = USBx_HPRT0;
1149 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1150 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1152 /* Check whether Port Connect detected */
1153 if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1155 if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1157 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1158 HAL_HCD_Connect_Callback(hhcd);
1160 hprt0_dup |= USB_OTG_HPRT_PCDET;
1164 /* Check whether Port Enable Changed */
1165 if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1167 hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1169 if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1171 if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
1173 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
1175 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
1177 else
1179 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
1182 else
1184 if(hhcd->Init.speed == HCD_SPEED_FULL)
1186 USBx_HOST->HFIR = (uint32_t)60000;
1189 HAL_HCD_Connect_Callback(hhcd);
1192 else
1194 /* Cleanup HPRT */
1195 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1196 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1198 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1202 /* Check For an overcurrent */
1203 if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1205 hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1208 /* Clear Port Interrupts */
1209 USBx_HPRT0 = hprt0_dup;
1213 * @}
1217 * @}
1220 #endif /* HAL_HCD_MODULE_ENABLED */
1222 * @}
1226 * @}
1229 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/