STM32F479xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_hcd.c 00004 * @author MCD Application Team 00005 * @brief HCD HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the USB Peripheral Controller: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral Control functions 00011 * + Peripheral State functions 00012 * 00013 ****************************************************************************** 00014 * @attention 00015 * 00016 * Copyright (c) 2016 STMicroelectronics. 00017 * All rights reserved. 00018 * 00019 * This software is licensed under terms that can be found in the LICENSE file 00020 * in the root directory of this software component. 00021 * If no LICENSE file comes with this software, it is provided AS-IS. 00022 * 00023 ****************************************************************************** 00024 @verbatim 00025 ============================================================================== 00026 ##### How to use this driver ##### 00027 ============================================================================== 00028 [..] 00029 (#)Declare a HCD_HandleTypeDef handle structure, for example: 00030 HCD_HandleTypeDef hhcd; 00031 00032 (#)Fill parameters of Init structure in HCD handle 00033 00034 (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...) 00035 00036 (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API: 00037 (##) Enable the HCD/USB Low Level interface clock using the following macros 00038 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); 00039 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode) 00040 (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode) 00041 00042 (##) Initialize the related GPIO clocks 00043 (##) Configure HCD pin-out 00044 (##) Configure HCD NVIC interrupt 00045 00046 (#)Associate the Upper USB Host stack to the HAL HCD Driver: 00047 (##) hhcd.pData = phost; 00048 00049 (#)Enable HCD transmission and reception: 00050 (##) HAL_HCD_Start(); 00051 00052 @endverbatim 00053 ****************************************************************************** 00054 */ 00055 00056 /* Includes ------------------------------------------------------------------*/ 00057 #include "stm32f4xx_hal.h" 00058 00059 /** @addtogroup STM32F4xx_HAL_Driver 00060 * @{ 00061 */ 00062 00063 #ifdef HAL_HCD_MODULE_ENABLED 00064 #if defined (USB_OTG_FS) || defined (USB_OTG_HS) 00065 00066 /** @defgroup HCD HCD 00067 * @brief HCD HAL module driver 00068 * @{ 00069 */ 00070 00071 /* Private typedef -----------------------------------------------------------*/ 00072 /* Private define ------------------------------------------------------------*/ 00073 /* Private macro -------------------------------------------------------------*/ 00074 /* Private variables ---------------------------------------------------------*/ 00075 /* Private function prototypes -----------------------------------------------*/ 00076 /** @defgroup HCD_Private_Functions HCD Private Functions 00077 * @{ 00078 */ 00079 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); 00080 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); 00081 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd); 00082 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd); 00083 /** 00084 * @} 00085 */ 00086 00087 /* Exported functions --------------------------------------------------------*/ 00088 /** @defgroup HCD_Exported_Functions HCD Exported Functions 00089 * @{ 00090 */ 00091 00092 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions 00093 * @brief Initialization and Configuration functions 00094 * 00095 @verbatim 00096 =============================================================================== 00097 ##### Initialization and de-initialization functions ##### 00098 =============================================================================== 00099 [..] This section provides functions allowing to: 00100 00101 @endverbatim 00102 * @{ 00103 */ 00104 00105 /** 00106 * @brief Initialize the host driver. 00107 * @param hhcd HCD handle 00108 * @retval HAL status 00109 */ 00110 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd) 00111 { 00112 USB_OTG_GlobalTypeDef *USBx; 00113 00114 /* Check the HCD handle allocation */ 00115 if (hhcd == NULL) 00116 { 00117 return HAL_ERROR; 00118 } 00119 00120 /* Check the parameters */ 00121 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance)); 00122 00123 USBx = hhcd->Instance; 00124 00125 if (hhcd->State == HAL_HCD_STATE_RESET) 00126 { 00127 /* Allocate lock resource and initialize it */ 00128 hhcd->Lock = HAL_UNLOCKED; 00129 00130 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 00131 hhcd->SOFCallback = HAL_HCD_SOF_Callback; 00132 hhcd->ConnectCallback = HAL_HCD_Connect_Callback; 00133 hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback; 00134 hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback; 00135 hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback; 00136 hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; 00137 00138 if (hhcd->MspInitCallback == NULL) 00139 { 00140 hhcd->MspInitCallback = HAL_HCD_MspInit; 00141 } 00142 00143 /* Init the low level hardware */ 00144 hhcd->MspInitCallback(hhcd); 00145 #else 00146 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ 00147 HAL_HCD_MspInit(hhcd); 00148 #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */ 00149 } 00150 00151 hhcd->State = HAL_HCD_STATE_BUSY; 00152 00153 /* Disable DMA mode for FS instance */ 00154 if ((USBx->CID & (0x1U << 8)) == 0U) 00155 { 00156 hhcd->Init.dma_enable = 0U; 00157 } 00158 00159 /* Disable the Interrupts */ 00160 __HAL_HCD_DISABLE(hhcd); 00161 00162 /* Init the Core (common init.) */ 00163 (void)USB_CoreInit(hhcd->Instance, hhcd->Init); 00164 00165 /* Force Host Mode*/ 00166 (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE); 00167 00168 /* Init Host */ 00169 (void)USB_HostInit(hhcd->Instance, hhcd->Init); 00170 00171 hhcd->State = HAL_HCD_STATE_READY; 00172 00173 return HAL_OK; 00174 } 00175 00176 /** 00177 * @brief Initialize a host channel. 00178 * @param hhcd HCD handle 00179 * @param ch_num Channel number. 00180 * This parameter can be a value from 1 to 15 00181 * @param epnum Endpoint number. 00182 * This parameter can be a value from 1 to 15 00183 * @param dev_address Current device address 00184 * This parameter can be a value from 0 to 255 00185 * @param speed Current device speed. 00186 * This parameter can be one of these values: 00187 * HCD_DEVICE_SPEED_HIGH: High speed mode, 00188 * HCD_DEVICE_SPEED_FULL: Full speed mode, 00189 * HCD_DEVICE_SPEED_LOW: Low speed mode 00190 * @param ep_type Endpoint Type. 00191 * This parameter can be one of these values: 00192 * EP_TYPE_CTRL: Control type, 00193 * EP_TYPE_ISOC: Isochronous type, 00194 * EP_TYPE_BULK: Bulk type, 00195 * EP_TYPE_INTR: Interrupt type 00196 * @param mps Max Packet Size. 00197 * This parameter can be a value from 0 to32K 00198 * @retval HAL status 00199 */ 00200 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, 00201 uint8_t ch_num, 00202 uint8_t epnum, 00203 uint8_t dev_address, 00204 uint8_t speed, 00205 uint8_t ep_type, 00206 uint16_t mps) 00207 { 00208 HAL_StatusTypeDef status; 00209 00210 __HAL_LOCK(hhcd); 00211 hhcd->hc[ch_num].do_ping = 0U; 00212 hhcd->hc[ch_num].dev_addr = dev_address; 00213 hhcd->hc[ch_num].max_packet = mps; 00214 hhcd->hc[ch_num].ch_num = ch_num; 00215 hhcd->hc[ch_num].ep_type = ep_type; 00216 hhcd->hc[ch_num].ep_num = epnum & 0x7FU; 00217 00218 if ((epnum & 0x80U) == 0x80U) 00219 { 00220 hhcd->hc[ch_num].ep_is_in = 1U; 00221 } 00222 else 00223 { 00224 hhcd->hc[ch_num].ep_is_in = 0U; 00225 } 00226 00227 hhcd->hc[ch_num].speed = speed; 00228 00229 status = USB_HC_Init(hhcd->Instance, 00230 ch_num, 00231 epnum, 00232 dev_address, 00233 speed, 00234 ep_type, 00235 mps); 00236 __HAL_UNLOCK(hhcd); 00237 00238 return status; 00239 } 00240 00241 /** 00242 * @brief Halt a host channel. 00243 * @param hhcd HCD handle 00244 * @param ch_num Channel number. 00245 * This parameter can be a value from 1 to 15 00246 * @retval HAL status 00247 */ 00248 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num) 00249 { 00250 HAL_StatusTypeDef status = HAL_OK; 00251 00252 __HAL_LOCK(hhcd); 00253 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 00254 __HAL_UNLOCK(hhcd); 00255 00256 return status; 00257 } 00258 00259 /** 00260 * @brief DeInitialize the host driver. 00261 * @param hhcd HCD handle 00262 * @retval HAL status 00263 */ 00264 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd) 00265 { 00266 /* Check the HCD handle allocation */ 00267 if (hhcd == NULL) 00268 { 00269 return HAL_ERROR; 00270 } 00271 00272 hhcd->State = HAL_HCD_STATE_BUSY; 00273 00274 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 00275 if (hhcd->MspDeInitCallback == NULL) 00276 { 00277 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit */ 00278 } 00279 00280 /* DeInit the low level hardware */ 00281 hhcd->MspDeInitCallback(hhcd); 00282 #else 00283 /* DeInit the low level hardware: CLOCK, NVIC.*/ 00284 HAL_HCD_MspDeInit(hhcd); 00285 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 00286 00287 __HAL_HCD_DISABLE(hhcd); 00288 00289 hhcd->State = HAL_HCD_STATE_RESET; 00290 00291 return HAL_OK; 00292 } 00293 00294 /** 00295 * @brief Initialize the HCD MSP. 00296 * @param hhcd HCD handle 00297 * @retval None 00298 */ 00299 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd) 00300 { 00301 /* Prevent unused argument(s) compilation warning */ 00302 UNUSED(hhcd); 00303 00304 /* NOTE : This function should not be modified, when the callback is needed, 00305 the HAL_HCD_MspInit could be implemented in the user file 00306 */ 00307 } 00308 00309 /** 00310 * @brief DeInitialize the HCD MSP. 00311 * @param hhcd HCD handle 00312 * @retval None 00313 */ 00314 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd) 00315 { 00316 /* Prevent unused argument(s) compilation warning */ 00317 UNUSED(hhcd); 00318 00319 /* NOTE : This function should not be modified, when the callback is needed, 00320 the HAL_HCD_MspDeInit could be implemented in the user file 00321 */ 00322 } 00323 00324 /** 00325 * @} 00326 */ 00327 00328 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions 00329 * @brief HCD IO operation functions 00330 * 00331 @verbatim 00332 =============================================================================== 00333 ##### IO operation functions ##### 00334 =============================================================================== 00335 [..] This subsection provides a set of functions allowing to manage the USB Host Data 00336 Transfer 00337 00338 @endverbatim 00339 * @{ 00340 */ 00341 00342 /** 00343 * @brief Submit a new URB for processing. 00344 * @param hhcd HCD handle 00345 * @param ch_num Channel number. 00346 * This parameter can be a value from 1 to 15 00347 * @param direction Channel number. 00348 * This parameter can be one of these values: 00349 * 0 : Output / 1 : Input 00350 * @param ep_type Endpoint Type. 00351 * This parameter can be one of these values: 00352 * EP_TYPE_CTRL: Control type/ 00353 * EP_TYPE_ISOC: Isochronous type/ 00354 * EP_TYPE_BULK: Bulk type/ 00355 * EP_TYPE_INTR: Interrupt type/ 00356 * @param token Endpoint Type. 00357 * This parameter can be one of these values: 00358 * 0: HC_PID_SETUP / 1: HC_PID_DATA1 00359 * @param pbuff pointer to URB data 00360 * @param length Length of URB data 00361 * @param do_ping activate do ping protocol (for high speed only). 00362 * This parameter can be one of these values: 00363 * 0 : do ping inactive / 1 : do ping active 00364 * @retval HAL status 00365 */ 00366 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, 00367 uint8_t ch_num, 00368 uint8_t direction, 00369 uint8_t ep_type, 00370 uint8_t token, 00371 uint8_t *pbuff, 00372 uint16_t length, 00373 uint8_t do_ping) 00374 { 00375 hhcd->hc[ch_num].ep_is_in = direction; 00376 hhcd->hc[ch_num].ep_type = ep_type; 00377 00378 if (token == 0U) 00379 { 00380 hhcd->hc[ch_num].data_pid = HC_PID_SETUP; 00381 hhcd->hc[ch_num].do_ping = do_ping; 00382 } 00383 else 00384 { 00385 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00386 } 00387 00388 /* Manage Data Toggle */ 00389 switch (ep_type) 00390 { 00391 case EP_TYPE_CTRL: 00392 if ((token == 1U) && (direction == 0U)) /*send data */ 00393 { 00394 if (length == 0U) 00395 { 00396 /* For Status OUT stage, Length==0, Status Out PID = 1 */ 00397 hhcd->hc[ch_num].toggle_out = 1U; 00398 } 00399 00400 /* Set the Data Toggle bit as per the Flag */ 00401 if (hhcd->hc[ch_num].toggle_out == 0U) 00402 { 00403 /* Put the PID 0 */ 00404 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00405 } 00406 else 00407 { 00408 /* Put the PID 1 */ 00409 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00410 } 00411 } 00412 break; 00413 00414 case EP_TYPE_BULK: 00415 if (direction == 0U) 00416 { 00417 /* Set the Data Toggle bit as per the Flag */ 00418 if (hhcd->hc[ch_num].toggle_out == 0U) 00419 { 00420 /* Put the PID 0 */ 00421 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00422 } 00423 else 00424 { 00425 /* Put the PID 1 */ 00426 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00427 } 00428 } 00429 else 00430 { 00431 if (hhcd->hc[ch_num].toggle_in == 0U) 00432 { 00433 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00434 } 00435 else 00436 { 00437 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00438 } 00439 } 00440 00441 break; 00442 case EP_TYPE_INTR: 00443 if (direction == 0U) 00444 { 00445 /* Set the Data Toggle bit as per the Flag */ 00446 if (hhcd->hc[ch_num].toggle_out == 0U) 00447 { 00448 /* Put the PID 0 */ 00449 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00450 } 00451 else 00452 { 00453 /* Put the PID 1 */ 00454 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00455 } 00456 } 00457 else 00458 { 00459 if (hhcd->hc[ch_num].toggle_in == 0U) 00460 { 00461 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00462 } 00463 else 00464 { 00465 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00466 } 00467 } 00468 break; 00469 00470 case EP_TYPE_ISOC: 00471 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00472 break; 00473 00474 default: 00475 break; 00476 } 00477 00478 hhcd->hc[ch_num].xfer_buff = pbuff; 00479 hhcd->hc[ch_num].xfer_len = length; 00480 hhcd->hc[ch_num].urb_state = URB_IDLE; 00481 hhcd->hc[ch_num].xfer_count = 0U; 00482 hhcd->hc[ch_num].ch_num = ch_num; 00483 hhcd->hc[ch_num].state = HC_IDLE; 00484 00485 return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num], (uint8_t)hhcd->Init.dma_enable); 00486 } 00487 00488 /** 00489 * @brief Handle HCD interrupt request. 00490 * @param hhcd HCD handle 00491 * @retval None 00492 */ 00493 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd) 00494 { 00495 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 00496 uint32_t USBx_BASE = (uint32_t)USBx; 00497 uint32_t i; 00498 uint32_t interrupt; 00499 00500 /* Ensure that we are in device mode */ 00501 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST) 00502 { 00503 /* Avoid spurious interrupt */ 00504 if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd)) 00505 { 00506 return; 00507 } 00508 00509 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) 00510 { 00511 /* Incorrect mode, acknowledge the interrupt */ 00512 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); 00513 } 00514 00515 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR)) 00516 { 00517 /* Incorrect mode, acknowledge the interrupt */ 00518 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR); 00519 } 00520 00521 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE)) 00522 { 00523 /* Incorrect mode, acknowledge the interrupt */ 00524 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE); 00525 } 00526 00527 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS)) 00528 { 00529 /* Incorrect mode, acknowledge the interrupt */ 00530 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS); 00531 } 00532 00533 /* Handle Host Disconnect Interrupts */ 00534 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT)) 00535 { 00536 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT); 00537 00538 if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U) 00539 { 00540 /* Flush USB Fifo */ 00541 (void)USB_FlushTxFifo(USBx, 0x10U); 00542 (void)USB_FlushRxFifo(USBx); 00543 00544 /* Restore FS Clock */ 00545 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ); 00546 00547 /* Handle Host Port Disconnect Interrupt */ 00548 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 00549 hhcd->DisconnectCallback(hhcd); 00550 #else 00551 HAL_HCD_Disconnect_Callback(hhcd); 00552 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 00553 } 00554 } 00555 00556 /* Handle Host Port Interrupts */ 00557 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT)) 00558 { 00559 HCD_Port_IRQHandler(hhcd); 00560 } 00561 00562 /* Handle Host SOF Interrupt */ 00563 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF)) 00564 { 00565 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 00566 hhcd->SOFCallback(hhcd); 00567 #else 00568 HAL_HCD_SOF_Callback(hhcd); 00569 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 00570 00571 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF); 00572 } 00573 00574 /* Handle Rx Queue Level Interrupts */ 00575 if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U) 00576 { 00577 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00578 00579 HCD_RXQLVL_IRQHandler(hhcd); 00580 00581 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00582 } 00583 00584 /* Handle Host channel Interrupt */ 00585 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT)) 00586 { 00587 interrupt = USB_HC_ReadInterrupt(hhcd->Instance); 00588 for (i = 0U; i < hhcd->Init.Host_channels; i++) 00589 { 00590 if ((interrupt & (1UL << (i & 0xFU))) != 0U) 00591 { 00592 if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR) 00593 { 00594 HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i); 00595 } 00596 else 00597 { 00598 HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i); 00599 } 00600 } 00601 } 00602 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT); 00603 } 00604 } 00605 } 00606 00607 00608 /** 00609 * @brief Handles HCD Wakeup interrupt request. 00610 * @param hhcd HCD handle 00611 * @retval HAL status 00612 */ 00613 void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd) 00614 { 00615 UNUSED(hhcd); 00616 } 00617 00618 00619 /** 00620 * @brief SOF callback. 00621 * @param hhcd HCD handle 00622 * @retval None 00623 */ 00624 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) 00625 { 00626 /* Prevent unused argument(s) compilation warning */ 00627 UNUSED(hhcd); 00628 00629 /* NOTE : This function should not be modified, when the callback is needed, 00630 the HAL_HCD_SOF_Callback could be implemented in the user file 00631 */ 00632 } 00633 00634 /** 00635 * @brief Connection Event callback. 00636 * @param hhcd HCD handle 00637 * @retval None 00638 */ 00639 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) 00640 { 00641 /* Prevent unused argument(s) compilation warning */ 00642 UNUSED(hhcd); 00643 00644 /* NOTE : This function should not be modified, when the callback is needed, 00645 the HAL_HCD_Connect_Callback could be implemented in the user file 00646 */ 00647 } 00648 00649 /** 00650 * @brief Disconnection Event callback. 00651 * @param hhcd HCD handle 00652 * @retval None 00653 */ 00654 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) 00655 { 00656 /* Prevent unused argument(s) compilation warning */ 00657 UNUSED(hhcd); 00658 00659 /* NOTE : This function should not be modified, when the callback is needed, 00660 the HAL_HCD_Disconnect_Callback could be implemented in the user file 00661 */ 00662 } 00663 00664 /** 00665 * @brief Port Enabled Event callback. 00666 * @param hhcd HCD handle 00667 * @retval None 00668 */ 00669 __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd) 00670 { 00671 /* Prevent unused argument(s) compilation warning */ 00672 UNUSED(hhcd); 00673 00674 /* NOTE : This function should not be modified, when the callback is needed, 00675 the HAL_HCD_Disconnect_Callback could be implemented in the user file 00676 */ 00677 } 00678 00679 /** 00680 * @brief Port Disabled Event callback. 00681 * @param hhcd HCD handle 00682 * @retval None 00683 */ 00684 __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd) 00685 { 00686 /* Prevent unused argument(s) compilation warning */ 00687 UNUSED(hhcd); 00688 00689 /* NOTE : This function should not be modified, when the callback is needed, 00690 the HAL_HCD_Disconnect_Callback could be implemented in the user file 00691 */ 00692 } 00693 00694 /** 00695 * @brief Notify URB state change callback. 00696 * @param hhcd HCD handle 00697 * @param chnum Channel number. 00698 * This parameter can be a value from 1 to 15 00699 * @param urb_state: 00700 * This parameter can be one of these values: 00701 * URB_IDLE/ 00702 * URB_DONE/ 00703 * URB_NOTREADY/ 00704 * URB_NYET/ 00705 * URB_ERROR/ 00706 * URB_STALL/ 00707 * @retval None 00708 */ 00709 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) 00710 { 00711 /* Prevent unused argument(s) compilation warning */ 00712 UNUSED(hhcd); 00713 UNUSED(chnum); 00714 UNUSED(urb_state); 00715 00716 /* NOTE : This function should not be modified, when the callback is needed, 00717 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file 00718 */ 00719 } 00720 00721 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 00722 /** 00723 * @brief Register a User USB HCD Callback 00724 * To be used instead of the weak predefined callback 00725 * @param hhcd USB HCD handle 00726 * @param CallbackID ID of the callback to be registered 00727 * This parameter can be one of the following values: 00728 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID 00729 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID 00730 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID 00731 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID 00732 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID 00733 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID 00734 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID 00735 * @param pCallback pointer to the Callback function 00736 * @retval HAL status 00737 */ 00738 HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, 00739 HAL_HCD_CallbackIDTypeDef CallbackID, 00740 pHCD_CallbackTypeDef pCallback) 00741 { 00742 HAL_StatusTypeDef status = HAL_OK; 00743 00744 if (pCallback == NULL) 00745 { 00746 /* Update the error code */ 00747 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00748 return HAL_ERROR; 00749 } 00750 /* Process locked */ 00751 __HAL_LOCK(hhcd); 00752 00753 if (hhcd->State == HAL_HCD_STATE_READY) 00754 { 00755 switch (CallbackID) 00756 { 00757 case HAL_HCD_SOF_CB_ID : 00758 hhcd->SOFCallback = pCallback; 00759 break; 00760 00761 case HAL_HCD_CONNECT_CB_ID : 00762 hhcd->ConnectCallback = pCallback; 00763 break; 00764 00765 case HAL_HCD_DISCONNECT_CB_ID : 00766 hhcd->DisconnectCallback = pCallback; 00767 break; 00768 00769 case HAL_HCD_PORT_ENABLED_CB_ID : 00770 hhcd->PortEnabledCallback = pCallback; 00771 break; 00772 00773 case HAL_HCD_PORT_DISABLED_CB_ID : 00774 hhcd->PortDisabledCallback = pCallback; 00775 break; 00776 00777 case HAL_HCD_MSPINIT_CB_ID : 00778 hhcd->MspInitCallback = pCallback; 00779 break; 00780 00781 case HAL_HCD_MSPDEINIT_CB_ID : 00782 hhcd->MspDeInitCallback = pCallback; 00783 break; 00784 00785 default : 00786 /* Update the error code */ 00787 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00788 /* Return error status */ 00789 status = HAL_ERROR; 00790 break; 00791 } 00792 } 00793 else if (hhcd->State == HAL_HCD_STATE_RESET) 00794 { 00795 switch (CallbackID) 00796 { 00797 case HAL_HCD_MSPINIT_CB_ID : 00798 hhcd->MspInitCallback = pCallback; 00799 break; 00800 00801 case HAL_HCD_MSPDEINIT_CB_ID : 00802 hhcd->MspDeInitCallback = pCallback; 00803 break; 00804 00805 default : 00806 /* Update the error code */ 00807 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00808 /* Return error status */ 00809 status = HAL_ERROR; 00810 break; 00811 } 00812 } 00813 else 00814 { 00815 /* Update the error code */ 00816 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00817 /* Return error status */ 00818 status = HAL_ERROR; 00819 } 00820 00821 /* Release Lock */ 00822 __HAL_UNLOCK(hhcd); 00823 return status; 00824 } 00825 00826 /** 00827 * @brief Unregister an USB HCD Callback 00828 * USB HCD callback is redirected to the weak predefined callback 00829 * @param hhcd USB HCD handle 00830 * @param CallbackID ID of the callback to be unregistered 00831 * This parameter can be one of the following values: 00832 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID 00833 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID 00834 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID 00835 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID 00836 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID 00837 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID 00838 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID 00839 * @retval HAL status 00840 */ 00841 HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID) 00842 { 00843 HAL_StatusTypeDef status = HAL_OK; 00844 00845 /* Process locked */ 00846 __HAL_LOCK(hhcd); 00847 00848 /* Setup Legacy weak Callbacks */ 00849 if (hhcd->State == HAL_HCD_STATE_READY) 00850 { 00851 switch (CallbackID) 00852 { 00853 case HAL_HCD_SOF_CB_ID : 00854 hhcd->SOFCallback = HAL_HCD_SOF_Callback; 00855 break; 00856 00857 case HAL_HCD_CONNECT_CB_ID : 00858 hhcd->ConnectCallback = HAL_HCD_Connect_Callback; 00859 break; 00860 00861 case HAL_HCD_DISCONNECT_CB_ID : 00862 hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback; 00863 break; 00864 00865 case HAL_HCD_PORT_ENABLED_CB_ID : 00866 hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback; 00867 break; 00868 00869 case HAL_HCD_PORT_DISABLED_CB_ID : 00870 hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback; 00871 break; 00872 00873 case HAL_HCD_MSPINIT_CB_ID : 00874 hhcd->MspInitCallback = HAL_HCD_MspInit; 00875 break; 00876 00877 case HAL_HCD_MSPDEINIT_CB_ID : 00878 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; 00879 break; 00880 00881 default : 00882 /* Update the error code */ 00883 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00884 00885 /* Return error status */ 00886 status = HAL_ERROR; 00887 break; 00888 } 00889 } 00890 else if (hhcd->State == HAL_HCD_STATE_RESET) 00891 { 00892 switch (CallbackID) 00893 { 00894 case HAL_HCD_MSPINIT_CB_ID : 00895 hhcd->MspInitCallback = HAL_HCD_MspInit; 00896 break; 00897 00898 case HAL_HCD_MSPDEINIT_CB_ID : 00899 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; 00900 break; 00901 00902 default : 00903 /* Update the error code */ 00904 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00905 00906 /* Return error status */ 00907 status = HAL_ERROR; 00908 break; 00909 } 00910 } 00911 else 00912 { 00913 /* Update the error code */ 00914 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00915 00916 /* Return error status */ 00917 status = HAL_ERROR; 00918 } 00919 00920 /* Release Lock */ 00921 __HAL_UNLOCK(hhcd); 00922 return status; 00923 } 00924 00925 /** 00926 * @brief Register USB HCD Host Channel Notify URB Change Callback 00927 * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback 00928 * @param hhcd HCD handle 00929 * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function 00930 * @retval HAL status 00931 */ 00932 HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, 00933 pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback) 00934 { 00935 HAL_StatusTypeDef status = HAL_OK; 00936 00937 if (pCallback == NULL) 00938 { 00939 /* Update the error code */ 00940 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00941 00942 return HAL_ERROR; 00943 } 00944 00945 /* Process locked */ 00946 __HAL_LOCK(hhcd); 00947 00948 if (hhcd->State == HAL_HCD_STATE_READY) 00949 { 00950 hhcd->HC_NotifyURBChangeCallback = pCallback; 00951 } 00952 else 00953 { 00954 /* Update the error code */ 00955 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00956 00957 /* Return error status */ 00958 status = HAL_ERROR; 00959 } 00960 00961 /* Release Lock */ 00962 __HAL_UNLOCK(hhcd); 00963 00964 return status; 00965 } 00966 00967 /** 00968 * @brief Unregister the USB HCD Host Channel Notify URB Change Callback 00969 * USB HCD Host Channel Notify URB Change Callback is redirected 00970 * to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback 00971 * @param hhcd HCD handle 00972 * @retval HAL status 00973 */ 00974 HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd) 00975 { 00976 HAL_StatusTypeDef status = HAL_OK; 00977 00978 /* Process locked */ 00979 __HAL_LOCK(hhcd); 00980 00981 if (hhcd->State == HAL_HCD_STATE_READY) 00982 { 00983 hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */ 00984 } 00985 else 00986 { 00987 /* Update the error code */ 00988 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00989 00990 /* Return error status */ 00991 status = HAL_ERROR; 00992 } 00993 00994 /* Release Lock */ 00995 __HAL_UNLOCK(hhcd); 00996 00997 return status; 00998 } 00999 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01000 01001 /** 01002 * @} 01003 */ 01004 01005 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions 01006 * @brief Management functions 01007 * 01008 @verbatim 01009 =============================================================================== 01010 ##### Peripheral Control functions ##### 01011 =============================================================================== 01012 [..] 01013 This subsection provides a set of functions allowing to control the HCD data 01014 transfers. 01015 01016 @endverbatim 01017 * @{ 01018 */ 01019 01020 /** 01021 * @brief Start the host driver. 01022 * @param hhcd HCD handle 01023 * @retval HAL status 01024 */ 01025 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd) 01026 { 01027 __HAL_LOCK(hhcd); 01028 /* Enable port power */ 01029 (void)USB_DriveVbus(hhcd->Instance, 1U); 01030 01031 /* Enable global interrupt */ 01032 __HAL_HCD_ENABLE(hhcd); 01033 __HAL_UNLOCK(hhcd); 01034 01035 return HAL_OK; 01036 } 01037 01038 /** 01039 * @brief Stop the host driver. 01040 * @param hhcd HCD handle 01041 * @retval HAL status 01042 */ 01043 01044 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd) 01045 { 01046 __HAL_LOCK(hhcd); 01047 (void)USB_StopHost(hhcd->Instance); 01048 __HAL_UNLOCK(hhcd); 01049 01050 return HAL_OK; 01051 } 01052 01053 /** 01054 * @brief Reset the host port. 01055 * @param hhcd HCD handle 01056 * @retval HAL status 01057 */ 01058 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd) 01059 { 01060 return (USB_ResetPort(hhcd->Instance)); 01061 } 01062 01063 /** 01064 * @} 01065 */ 01066 01067 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions 01068 * @brief Peripheral State functions 01069 * 01070 @verbatim 01071 =============================================================================== 01072 ##### Peripheral State functions ##### 01073 =============================================================================== 01074 [..] 01075 This subsection permits to get in run-time the status of the peripheral 01076 and the data flow. 01077 01078 @endverbatim 01079 * @{ 01080 */ 01081 01082 /** 01083 * @brief Return the HCD handle state. 01084 * @param hhcd HCD handle 01085 * @retval HAL state 01086 */ 01087 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd) 01088 { 01089 return hhcd->State; 01090 } 01091 01092 /** 01093 * @brief Return URB state for a channel. 01094 * @param hhcd HCD handle 01095 * @param chnum Channel number. 01096 * This parameter can be a value from 1 to 15 01097 * @retval URB state. 01098 * This parameter can be one of these values: 01099 * URB_IDLE/ 01100 * URB_DONE/ 01101 * URB_NOTREADY/ 01102 * URB_NYET/ 01103 * URB_ERROR/ 01104 * URB_STALL 01105 */ 01106 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01107 { 01108 return hhcd->hc[chnum].urb_state; 01109 } 01110 01111 01112 /** 01113 * @brief Return the last host transfer size. 01114 * @param hhcd HCD handle 01115 * @param chnum Channel number. 01116 * This parameter can be a value from 1 to 15 01117 * @retval last transfer size in byte 01118 */ 01119 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01120 { 01121 return hhcd->hc[chnum].xfer_count; 01122 } 01123 01124 /** 01125 * @brief Return the Host Channel state. 01126 * @param hhcd HCD handle 01127 * @param chnum Channel number. 01128 * This parameter can be a value from 1 to 15 01129 * @retval Host channel state 01130 * This parameter can be one of these values: 01131 * HC_IDLE/ 01132 * HC_XFRC/ 01133 * HC_HALTED/ 01134 * HC_NYET/ 01135 * HC_NAK/ 01136 * HC_STALL/ 01137 * HC_XACTERR/ 01138 * HC_BBLERR/ 01139 * HC_DATATGLERR 01140 */ 01141 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01142 { 01143 return hhcd->hc[chnum].state; 01144 } 01145 01146 /** 01147 * @brief Return the current Host frame number. 01148 * @param hhcd HCD handle 01149 * @retval Current Host frame number 01150 */ 01151 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd) 01152 { 01153 return (USB_GetCurrentFrame(hhcd->Instance)); 01154 } 01155 01156 /** 01157 * @brief Return the Host enumeration speed. 01158 * @param hhcd HCD handle 01159 * @retval Enumeration speed 01160 */ 01161 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd) 01162 { 01163 return (USB_GetHostSpeed(hhcd->Instance)); 01164 } 01165 01166 /** 01167 * @} 01168 */ 01169 01170 /** 01171 * @} 01172 */ 01173 01174 /** @addtogroup HCD_Private_Functions 01175 * @{ 01176 */ 01177 /** 01178 * @brief Handle Host Channel IN interrupt requests. 01179 * @param hhcd HCD handle 01180 * @param chnum Channel number. 01181 * This parameter can be a value from 1 to 15 01182 * @retval none 01183 */ 01184 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01185 { 01186 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01187 uint32_t USBx_BASE = (uint32_t)USBx; 01188 uint32_t ch_num = (uint32_t)chnum; 01189 01190 uint32_t tmpreg; 01191 01192 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) 01193 { 01194 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR); 01195 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01196 } 01197 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) 01198 { 01199 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR); 01200 hhcd->hc[ch_num].state = HC_BBLERR; 01201 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01202 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01203 } 01204 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) 01205 { 01206 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK); 01207 } 01208 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) 01209 { 01210 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01211 hhcd->hc[ch_num].state = HC_STALL; 01212 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01213 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL); 01214 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01215 } 01216 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) 01217 { 01218 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01219 hhcd->hc[ch_num].state = HC_DATATGLERR; 01220 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01221 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR); 01222 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01223 } 01224 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) 01225 { 01226 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01227 hhcd->hc[ch_num].state = HC_XACTERR; 01228 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01229 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR); 01230 } 01231 else 01232 { 01233 /* ... */ 01234 } 01235 01236 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) 01237 { 01238 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01239 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01240 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR); 01241 } 01242 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) 01243 { 01244 if (hhcd->Init.dma_enable != 0U) 01245 { 01246 hhcd->hc[ch_num].xfer_count = hhcd->hc[ch_num].XferSize - \ 01247 (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); 01248 } 01249 01250 hhcd->hc[ch_num].state = HC_XFRC; 01251 hhcd->hc[ch_num].ErrCnt = 0U; 01252 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC); 01253 01254 if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) || 01255 (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK)) 01256 { 01257 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01258 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01259 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01260 } 01261 else if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR) 01262 { 01263 USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM; 01264 hhcd->hc[ch_num].urb_state = URB_DONE; 01265 01266 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01267 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01268 #else 01269 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01270 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01271 } 01272 else if (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC) 01273 { 01274 hhcd->hc[ch_num].urb_state = URB_DONE; 01275 hhcd->hc[ch_num].toggle_in ^= 1U; 01276 01277 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01278 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01279 #else 01280 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01281 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01282 } 01283 else 01284 { 01285 /* ... */ 01286 } 01287 01288 if (hhcd->Init.dma_enable == 1U) 01289 { 01290 if (((hhcd->hc[ch_num].XferSize / hhcd->hc[ch_num].max_packet) & 1U) != 0U) 01291 { 01292 hhcd->hc[ch_num].toggle_in ^= 1U; 01293 } 01294 } 01295 else 01296 { 01297 hhcd->hc[ch_num].toggle_in ^= 1U; 01298 } 01299 } 01300 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) 01301 { 01302 __HAL_HCD_MASK_HALT_HC_INT(ch_num); 01303 01304 if (hhcd->hc[ch_num].state == HC_XFRC) 01305 { 01306 hhcd->hc[ch_num].urb_state = URB_DONE; 01307 } 01308 else if (hhcd->hc[ch_num].state == HC_STALL) 01309 { 01310 hhcd->hc[ch_num].urb_state = URB_STALL; 01311 } 01312 else if ((hhcd->hc[ch_num].state == HC_XACTERR) || 01313 (hhcd->hc[ch_num].state == HC_DATATGLERR)) 01314 { 01315 hhcd->hc[ch_num].ErrCnt++; 01316 if (hhcd->hc[ch_num].ErrCnt > 2U) 01317 { 01318 hhcd->hc[ch_num].ErrCnt = 0U; 01319 hhcd->hc[ch_num].urb_state = URB_ERROR; 01320 } 01321 else 01322 { 01323 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01324 01325 /* re-activate the channel */ 01326 tmpreg = USBx_HC(ch_num)->HCCHAR; 01327 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01328 tmpreg |= USB_OTG_HCCHAR_CHENA; 01329 USBx_HC(ch_num)->HCCHAR = tmpreg; 01330 } 01331 } 01332 else if (hhcd->hc[ch_num].state == HC_NAK) 01333 { 01334 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01335 01336 /* re-activate the channel */ 01337 tmpreg = USBx_HC(ch_num)->HCCHAR; 01338 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01339 tmpreg |= USB_OTG_HCCHAR_CHENA; 01340 USBx_HC(ch_num)->HCCHAR = tmpreg; 01341 } 01342 else if (hhcd->hc[ch_num].state == HC_BBLERR) 01343 { 01344 hhcd->hc[ch_num].ErrCnt++; 01345 hhcd->hc[ch_num].urb_state = URB_ERROR; 01346 } 01347 else 01348 { 01349 /* ... */ 01350 } 01351 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH); 01352 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01353 } 01354 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) 01355 { 01356 if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR) 01357 { 01358 hhcd->hc[ch_num].ErrCnt = 0U; 01359 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01360 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01361 } 01362 else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) || 01363 (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK)) 01364 { 01365 hhcd->hc[ch_num].ErrCnt = 0U; 01366 01367 if (hhcd->Init.dma_enable == 0U) 01368 { 01369 hhcd->hc[ch_num].state = HC_NAK; 01370 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01371 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01372 } 01373 } 01374 else 01375 { 01376 /* ... */ 01377 } 01378 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01379 } 01380 else 01381 { 01382 /* ... */ 01383 } 01384 } 01385 01386 /** 01387 * @brief Handle Host Channel OUT interrupt requests. 01388 * @param hhcd HCD handle 01389 * @param chnum Channel number. 01390 * This parameter can be a value from 1 to 15 01391 * @retval none 01392 */ 01393 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01394 { 01395 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01396 uint32_t USBx_BASE = (uint32_t)USBx; 01397 uint32_t ch_num = (uint32_t)chnum; 01398 uint32_t tmpreg; 01399 uint32_t num_packets; 01400 01401 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) 01402 { 01403 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR); 01404 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01405 } 01406 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) 01407 { 01408 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK); 01409 01410 if (hhcd->hc[ch_num].do_ping == 1U) 01411 { 01412 hhcd->hc[ch_num].do_ping = 0U; 01413 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01414 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01415 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01416 } 01417 } 01418 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) 01419 { 01420 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01421 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01422 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR); 01423 } 01424 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) 01425 { 01426 hhcd->hc[ch_num].ErrCnt = 0U; 01427 01428 /* transaction completed with NYET state, update do ping state */ 01429 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) 01430 { 01431 hhcd->hc[ch_num].do_ping = 1U; 01432 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET); 01433 } 01434 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01435 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01436 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC); 01437 hhcd->hc[ch_num].state = HC_XFRC; 01438 } 01439 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) 01440 { 01441 hhcd->hc[ch_num].state = HC_NYET; 01442 hhcd->hc[ch_num].do_ping = 1U; 01443 hhcd->hc[ch_num].ErrCnt = 0U; 01444 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01445 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01446 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET); 01447 } 01448 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) 01449 { 01450 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL); 01451 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01452 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01453 hhcd->hc[ch_num].state = HC_STALL; 01454 } 01455 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) 01456 { 01457 hhcd->hc[ch_num].ErrCnt = 0U; 01458 hhcd->hc[ch_num].state = HC_NAK; 01459 01460 if (hhcd->hc[ch_num].do_ping == 0U) 01461 { 01462 if (hhcd->hc[ch_num].speed == HCD_DEVICE_SPEED_HIGH) 01463 { 01464 hhcd->hc[ch_num].do_ping = 1U; 01465 } 01466 } 01467 01468 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01469 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01470 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01471 } 01472 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) 01473 { 01474 if (hhcd->Init.dma_enable == 0U) 01475 { 01476 hhcd->hc[ch_num].state = HC_XACTERR; 01477 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01478 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01479 } 01480 else 01481 { 01482 hhcd->hc[ch_num].ErrCnt++; 01483 if (hhcd->hc[ch_num].ErrCnt > 2U) 01484 { 01485 hhcd->hc[ch_num].ErrCnt = 0U; 01486 hhcd->hc[ch_num].urb_state = URB_ERROR; 01487 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, 01488 hhcd->hc[ch_num].urb_state); 01489 } 01490 else 01491 { 01492 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01493 } 01494 } 01495 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR); 01496 } 01497 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) 01498 { 01499 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num); 01500 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01501 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01502 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR); 01503 hhcd->hc[ch_num].state = HC_DATATGLERR; 01504 } 01505 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) 01506 { 01507 __HAL_HCD_MASK_HALT_HC_INT(ch_num); 01508 01509 if (hhcd->hc[ch_num].state == HC_XFRC) 01510 { 01511 hhcd->hc[ch_num].urb_state = URB_DONE; 01512 if ((hhcd->hc[ch_num].ep_type == EP_TYPE_BULK) || 01513 (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)) 01514 { 01515 if (hhcd->Init.dma_enable == 0U) 01516 { 01517 hhcd->hc[ch_num].toggle_out ^= 1U; 01518 } 01519 01520 if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[ch_num].xfer_len > 0U)) 01521 { 01522 num_packets = (hhcd->hc[ch_num].xfer_len + hhcd->hc[ch_num].max_packet - 1U) / hhcd->hc[ch_num].max_packet; 01523 01524 if ((num_packets & 1U) != 0U) 01525 { 01526 hhcd->hc[ch_num].toggle_out ^= 1U; 01527 } 01528 } 01529 } 01530 } 01531 else if (hhcd->hc[ch_num].state == HC_NAK) 01532 { 01533 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01534 } 01535 else if (hhcd->hc[ch_num].state == HC_NYET) 01536 { 01537 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01538 } 01539 else if (hhcd->hc[ch_num].state == HC_STALL) 01540 { 01541 hhcd->hc[ch_num].urb_state = URB_STALL; 01542 } 01543 else if ((hhcd->hc[ch_num].state == HC_XACTERR) || 01544 (hhcd->hc[ch_num].state == HC_DATATGLERR)) 01545 { 01546 hhcd->hc[ch_num].ErrCnt++; 01547 if (hhcd->hc[ch_num].ErrCnt > 2U) 01548 { 01549 hhcd->hc[ch_num].ErrCnt = 0U; 01550 hhcd->hc[ch_num].urb_state = URB_ERROR; 01551 } 01552 else 01553 { 01554 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01555 01556 /* re-activate the channel */ 01557 tmpreg = USBx_HC(ch_num)->HCCHAR; 01558 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01559 tmpreg |= USB_OTG_HCCHAR_CHENA; 01560 USBx_HC(ch_num)->HCCHAR = tmpreg; 01561 } 01562 } 01563 else 01564 { 01565 /* ... */ 01566 } 01567 01568 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH); 01569 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01570 } 01571 else 01572 { 01573 /* ... */ 01574 } 01575 } 01576 01577 /** 01578 * @brief Handle Rx Queue Level interrupt requests. 01579 * @param hhcd HCD handle 01580 * @retval none 01581 */ 01582 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd) 01583 { 01584 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01585 uint32_t USBx_BASE = (uint32_t)USBx; 01586 uint32_t pktsts; 01587 uint32_t pktcnt; 01588 uint32_t GrxstspReg; 01589 uint32_t xferSizePktCnt; 01590 uint32_t tmpreg; 01591 uint32_t ch_num; 01592 01593 GrxstspReg = hhcd->Instance->GRXSTSP; 01594 ch_num = GrxstspReg & USB_OTG_GRXSTSP_EPNUM; 01595 pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17; 01596 pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4; 01597 01598 switch (pktsts) 01599 { 01600 case GRXSTS_PKTSTS_IN: 01601 /* Read the data into the host buffer. */ 01602 if ((pktcnt > 0U) && (hhcd->hc[ch_num].xfer_buff != (void *)0)) 01603 { 01604 if ((hhcd->hc[ch_num].xfer_count + pktcnt) <= hhcd->hc[ch_num].xfer_len) 01605 { 01606 (void)USB_ReadPacket(hhcd->Instance, 01607 hhcd->hc[ch_num].xfer_buff, (uint16_t)pktcnt); 01608 01609 /* manage multiple Xfer */ 01610 hhcd->hc[ch_num].xfer_buff += pktcnt; 01611 hhcd->hc[ch_num].xfer_count += pktcnt; 01612 01613 /* get transfer size packet count */ 01614 xferSizePktCnt = (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19; 01615 01616 if ((hhcd->hc[ch_num].max_packet == pktcnt) && (xferSizePktCnt > 0U)) 01617 { 01618 /* re-activate the channel when more packets are expected */ 01619 tmpreg = USBx_HC(ch_num)->HCCHAR; 01620 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01621 tmpreg |= USB_OTG_HCCHAR_CHENA; 01622 USBx_HC(ch_num)->HCCHAR = tmpreg; 01623 hhcd->hc[ch_num].toggle_in ^= 1U; 01624 } 01625 } 01626 else 01627 { 01628 hhcd->hc[ch_num].urb_state = URB_ERROR; 01629 } 01630 } 01631 break; 01632 01633 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: 01634 break; 01635 01636 case GRXSTS_PKTSTS_IN_XFER_COMP: 01637 case GRXSTS_PKTSTS_CH_HALTED: 01638 default: 01639 break; 01640 } 01641 } 01642 01643 /** 01644 * @brief Handle Host Port interrupt requests. 01645 * @param hhcd HCD handle 01646 * @retval None 01647 */ 01648 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd) 01649 { 01650 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01651 uint32_t USBx_BASE = (uint32_t)USBx; 01652 __IO uint32_t hprt0; 01653 __IO uint32_t hprt0_dup; 01654 01655 /* Handle Host Port Interrupts */ 01656 hprt0 = USBx_HPRT0; 01657 hprt0_dup = USBx_HPRT0; 01658 01659 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \ 01660 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG); 01661 01662 /* Check whether Port Connect detected */ 01663 if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) 01664 { 01665 if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) 01666 { 01667 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01668 hhcd->ConnectCallback(hhcd); 01669 #else 01670 HAL_HCD_Connect_Callback(hhcd); 01671 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01672 } 01673 hprt0_dup |= USB_OTG_HPRT_PCDET; 01674 } 01675 01676 /* Check whether Port Enable Changed */ 01677 if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) 01678 { 01679 hprt0_dup |= USB_OTG_HPRT_PENCHNG; 01680 01681 if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) 01682 { 01683 if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY) 01684 { 01685 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) 01686 { 01687 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ); 01688 } 01689 else 01690 { 01691 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ); 01692 } 01693 } 01694 else 01695 { 01696 if (hhcd->Init.speed == HCD_SPEED_FULL) 01697 { 01698 USBx_HOST->HFIR = 60000U; 01699 } 01700 } 01701 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01702 hhcd->PortEnabledCallback(hhcd); 01703 #else 01704 HAL_HCD_PortEnabled_Callback(hhcd); 01705 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01706 01707 } 01708 else 01709 { 01710 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01711 hhcd->PortDisabledCallback(hhcd); 01712 #else 01713 HAL_HCD_PortDisabled_Callback(hhcd); 01714 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01715 } 01716 } 01717 01718 /* Check for an overcurrent */ 01719 if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) 01720 { 01721 hprt0_dup |= USB_OTG_HPRT_POCCHNG; 01722 } 01723 01724 /* Clear Port Interrupts */ 01725 USBx_HPRT0 = hprt0_dup; 01726 } 01727 01728 /** 01729 * @} 01730 */ 01731 01732 /** 01733 * @} 01734 */ 01735 01736 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 01737 #endif /* HAL_HCD_MODULE_ENABLED */ 01738 01739 /** 01740 * @} 01741 */ 01742 01743 /** 01744 * @} 01745 */