STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_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) 2017 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 "stm32h7xx_hal.h" 00058 00059 /** @addtogroup STM32H7xx_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 SOF callback. 00610 * @param hhcd HCD handle 00611 * @retval None 00612 */ 00613 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) 00614 { 00615 /* Prevent unused argument(s) compilation warning */ 00616 UNUSED(hhcd); 00617 00618 /* NOTE : This function should not be modified, when the callback is needed, 00619 the HAL_HCD_SOF_Callback could be implemented in the user file 00620 */ 00621 } 00622 00623 /** 00624 * @brief Connection Event callback. 00625 * @param hhcd HCD handle 00626 * @retval None 00627 */ 00628 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) 00629 { 00630 /* Prevent unused argument(s) compilation warning */ 00631 UNUSED(hhcd); 00632 00633 /* NOTE : This function should not be modified, when the callback is needed, 00634 the HAL_HCD_Connect_Callback could be implemented in the user file 00635 */ 00636 } 00637 00638 /** 00639 * @brief Disconnection Event callback. 00640 * @param hhcd HCD handle 00641 * @retval None 00642 */ 00643 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) 00644 { 00645 /* Prevent unused argument(s) compilation warning */ 00646 UNUSED(hhcd); 00647 00648 /* NOTE : This function should not be modified, when the callback is needed, 00649 the HAL_HCD_Disconnect_Callback could be implemented in the user file 00650 */ 00651 } 00652 00653 /** 00654 * @brief Port Enabled Event callback. 00655 * @param hhcd HCD handle 00656 * @retval None 00657 */ 00658 __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd) 00659 { 00660 /* Prevent unused argument(s) compilation warning */ 00661 UNUSED(hhcd); 00662 00663 /* NOTE : This function should not be modified, when the callback is needed, 00664 the HAL_HCD_Disconnect_Callback could be implemented in the user file 00665 */ 00666 } 00667 00668 /** 00669 * @brief Port Disabled Event callback. 00670 * @param hhcd HCD handle 00671 * @retval None 00672 */ 00673 __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd) 00674 { 00675 /* Prevent unused argument(s) compilation warning */ 00676 UNUSED(hhcd); 00677 00678 /* NOTE : This function should not be modified, when the callback is needed, 00679 the HAL_HCD_Disconnect_Callback could be implemented in the user file 00680 */ 00681 } 00682 00683 /** 00684 * @brief Notify URB state change callback. 00685 * @param hhcd HCD handle 00686 * @param chnum Channel number. 00687 * This parameter can be a value from 1 to 15 00688 * @param urb_state: 00689 * This parameter can be one of these values: 00690 * URB_IDLE/ 00691 * URB_DONE/ 00692 * URB_NOTREADY/ 00693 * URB_NYET/ 00694 * URB_ERROR/ 00695 * URB_STALL/ 00696 * @retval None 00697 */ 00698 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) 00699 { 00700 /* Prevent unused argument(s) compilation warning */ 00701 UNUSED(hhcd); 00702 UNUSED(chnum); 00703 UNUSED(urb_state); 00704 00705 /* NOTE : This function should not be modified, when the callback is needed, 00706 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file 00707 */ 00708 } 00709 00710 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 00711 /** 00712 * @brief Register a User USB HCD Callback 00713 * To be used instead of the weak predefined callback 00714 * @param hhcd USB HCD handle 00715 * @param CallbackID ID of the callback to be registered 00716 * This parameter can be one of the following values: 00717 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID 00718 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID 00719 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID 00720 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID 00721 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID 00722 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID 00723 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID 00724 * @param pCallback pointer to the Callback function 00725 * @retval HAL status 00726 */ 00727 HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, 00728 HAL_HCD_CallbackIDTypeDef CallbackID, 00729 pHCD_CallbackTypeDef pCallback) 00730 { 00731 HAL_StatusTypeDef status = HAL_OK; 00732 00733 if (pCallback == NULL) 00734 { 00735 /* Update the error code */ 00736 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00737 return HAL_ERROR; 00738 } 00739 /* Process locked */ 00740 __HAL_LOCK(hhcd); 00741 00742 if (hhcd->State == HAL_HCD_STATE_READY) 00743 { 00744 switch (CallbackID) 00745 { 00746 case HAL_HCD_SOF_CB_ID : 00747 hhcd->SOFCallback = pCallback; 00748 break; 00749 00750 case HAL_HCD_CONNECT_CB_ID : 00751 hhcd->ConnectCallback = pCallback; 00752 break; 00753 00754 case HAL_HCD_DISCONNECT_CB_ID : 00755 hhcd->DisconnectCallback = pCallback; 00756 break; 00757 00758 case HAL_HCD_PORT_ENABLED_CB_ID : 00759 hhcd->PortEnabledCallback = pCallback; 00760 break; 00761 00762 case HAL_HCD_PORT_DISABLED_CB_ID : 00763 hhcd->PortDisabledCallback = pCallback; 00764 break; 00765 00766 case HAL_HCD_MSPINIT_CB_ID : 00767 hhcd->MspInitCallback = pCallback; 00768 break; 00769 00770 case HAL_HCD_MSPDEINIT_CB_ID : 00771 hhcd->MspDeInitCallback = pCallback; 00772 break; 00773 00774 default : 00775 /* Update the error code */ 00776 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00777 /* Return error status */ 00778 status = HAL_ERROR; 00779 break; 00780 } 00781 } 00782 else if (hhcd->State == HAL_HCD_STATE_RESET) 00783 { 00784 switch (CallbackID) 00785 { 00786 case HAL_HCD_MSPINIT_CB_ID : 00787 hhcd->MspInitCallback = pCallback; 00788 break; 00789 00790 case HAL_HCD_MSPDEINIT_CB_ID : 00791 hhcd->MspDeInitCallback = pCallback; 00792 break; 00793 00794 default : 00795 /* Update the error code */ 00796 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00797 /* Return error status */ 00798 status = HAL_ERROR; 00799 break; 00800 } 00801 } 00802 else 00803 { 00804 /* Update the error code */ 00805 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00806 /* Return error status */ 00807 status = HAL_ERROR; 00808 } 00809 00810 /* Release Lock */ 00811 __HAL_UNLOCK(hhcd); 00812 return status; 00813 } 00814 00815 /** 00816 * @brief Unregister an USB HCD Callback 00817 * USB HCD callback is redirected to the weak predefined callback 00818 * @param hhcd USB HCD handle 00819 * @param CallbackID ID of the callback to be unregistered 00820 * This parameter can be one of the following values: 00821 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID 00822 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID 00823 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID 00824 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID 00825 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID 00826 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID 00827 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID 00828 * @retval HAL status 00829 */ 00830 HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID) 00831 { 00832 HAL_StatusTypeDef status = HAL_OK; 00833 00834 /* Process locked */ 00835 __HAL_LOCK(hhcd); 00836 00837 /* Setup Legacy weak Callbacks */ 00838 if (hhcd->State == HAL_HCD_STATE_READY) 00839 { 00840 switch (CallbackID) 00841 { 00842 case HAL_HCD_SOF_CB_ID : 00843 hhcd->SOFCallback = HAL_HCD_SOF_Callback; 00844 break; 00845 00846 case HAL_HCD_CONNECT_CB_ID : 00847 hhcd->ConnectCallback = HAL_HCD_Connect_Callback; 00848 break; 00849 00850 case HAL_HCD_DISCONNECT_CB_ID : 00851 hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback; 00852 break; 00853 00854 case HAL_HCD_PORT_ENABLED_CB_ID : 00855 hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback; 00856 break; 00857 00858 case HAL_HCD_PORT_DISABLED_CB_ID : 00859 hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback; 00860 break; 00861 00862 case HAL_HCD_MSPINIT_CB_ID : 00863 hhcd->MspInitCallback = HAL_HCD_MspInit; 00864 break; 00865 00866 case HAL_HCD_MSPDEINIT_CB_ID : 00867 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; 00868 break; 00869 00870 default : 00871 /* Update the error code */ 00872 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00873 00874 /* Return error status */ 00875 status = HAL_ERROR; 00876 break; 00877 } 00878 } 00879 else if (hhcd->State == HAL_HCD_STATE_RESET) 00880 { 00881 switch (CallbackID) 00882 { 00883 case HAL_HCD_MSPINIT_CB_ID : 00884 hhcd->MspInitCallback = HAL_HCD_MspInit; 00885 break; 00886 00887 case HAL_HCD_MSPDEINIT_CB_ID : 00888 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; 00889 break; 00890 00891 default : 00892 /* Update the error code */ 00893 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00894 00895 /* Return error status */ 00896 status = HAL_ERROR; 00897 break; 00898 } 00899 } 00900 else 00901 { 00902 /* Update the error code */ 00903 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00904 00905 /* Return error status */ 00906 status = HAL_ERROR; 00907 } 00908 00909 /* Release Lock */ 00910 __HAL_UNLOCK(hhcd); 00911 return status; 00912 } 00913 00914 /** 00915 * @brief Register USB HCD Host Channel Notify URB Change Callback 00916 * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback 00917 * @param hhcd HCD handle 00918 * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function 00919 * @retval HAL status 00920 */ 00921 HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, 00922 pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback) 00923 { 00924 HAL_StatusTypeDef status = HAL_OK; 00925 00926 if (pCallback == NULL) 00927 { 00928 /* Update the error code */ 00929 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00930 00931 return HAL_ERROR; 00932 } 00933 00934 /* Process locked */ 00935 __HAL_LOCK(hhcd); 00936 00937 if (hhcd->State == HAL_HCD_STATE_READY) 00938 { 00939 hhcd->HC_NotifyURBChangeCallback = pCallback; 00940 } 00941 else 00942 { 00943 /* Update the error code */ 00944 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00945 00946 /* Return error status */ 00947 status = HAL_ERROR; 00948 } 00949 00950 /* Release Lock */ 00951 __HAL_UNLOCK(hhcd); 00952 00953 return status; 00954 } 00955 00956 /** 00957 * @brief Unregister the USB HCD Host Channel Notify URB Change Callback 00958 * USB HCD Host Channel Notify URB Change Callback is redirected 00959 * to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback 00960 * @param hhcd HCD handle 00961 * @retval HAL status 00962 */ 00963 HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd) 00964 { 00965 HAL_StatusTypeDef status = HAL_OK; 00966 00967 /* Process locked */ 00968 __HAL_LOCK(hhcd); 00969 00970 if (hhcd->State == HAL_HCD_STATE_READY) 00971 { 00972 hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */ 00973 } 00974 else 00975 { 00976 /* Update the error code */ 00977 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; 00978 00979 /* Return error status */ 00980 status = HAL_ERROR; 00981 } 00982 00983 /* Release Lock */ 00984 __HAL_UNLOCK(hhcd); 00985 00986 return status; 00987 } 00988 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 00989 00990 /** 00991 * @} 00992 */ 00993 00994 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions 00995 * @brief Management functions 00996 * 00997 @verbatim 00998 =============================================================================== 00999 ##### Peripheral Control functions ##### 01000 =============================================================================== 01001 [..] 01002 This subsection provides a set of functions allowing to control the HCD data 01003 transfers. 01004 01005 @endverbatim 01006 * @{ 01007 */ 01008 01009 /** 01010 * @brief Start the host driver. 01011 * @param hhcd HCD handle 01012 * @retval HAL status 01013 */ 01014 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd) 01015 { 01016 __HAL_LOCK(hhcd); 01017 /* Enable port power */ 01018 (void)USB_DriveVbus(hhcd->Instance, 1U); 01019 01020 /* Enable global interrupt */ 01021 __HAL_HCD_ENABLE(hhcd); 01022 __HAL_UNLOCK(hhcd); 01023 01024 return HAL_OK; 01025 } 01026 01027 /** 01028 * @brief Stop the host driver. 01029 * @param hhcd HCD handle 01030 * @retval HAL status 01031 */ 01032 01033 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd) 01034 { 01035 __HAL_LOCK(hhcd); 01036 (void)USB_StopHost(hhcd->Instance); 01037 __HAL_UNLOCK(hhcd); 01038 01039 return HAL_OK; 01040 } 01041 01042 /** 01043 * @brief Reset the host port. 01044 * @param hhcd HCD handle 01045 * @retval HAL status 01046 */ 01047 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd) 01048 { 01049 return (USB_ResetPort(hhcd->Instance)); 01050 } 01051 01052 /** 01053 * @} 01054 */ 01055 01056 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions 01057 * @brief Peripheral State functions 01058 * 01059 @verbatim 01060 =============================================================================== 01061 ##### Peripheral State functions ##### 01062 =============================================================================== 01063 [..] 01064 This subsection permits to get in run-time the status of the peripheral 01065 and the data flow. 01066 01067 @endverbatim 01068 * @{ 01069 */ 01070 01071 /** 01072 * @brief Return the HCD handle state. 01073 * @param hhcd HCD handle 01074 * @retval HAL state 01075 */ 01076 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd) 01077 { 01078 return hhcd->State; 01079 } 01080 01081 /** 01082 * @brief Return URB state for a channel. 01083 * @param hhcd HCD handle 01084 * @param chnum Channel number. 01085 * This parameter can be a value from 1 to 15 01086 * @retval URB state. 01087 * This parameter can be one of these values: 01088 * URB_IDLE/ 01089 * URB_DONE/ 01090 * URB_NOTREADY/ 01091 * URB_NYET/ 01092 * URB_ERROR/ 01093 * URB_STALL 01094 */ 01095 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01096 { 01097 return hhcd->hc[chnum].urb_state; 01098 } 01099 01100 01101 /** 01102 * @brief Return the last host transfer size. 01103 * @param hhcd HCD handle 01104 * @param chnum Channel number. 01105 * This parameter can be a value from 1 to 15 01106 * @retval last transfer size in byte 01107 */ 01108 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01109 { 01110 return hhcd->hc[chnum].xfer_count; 01111 } 01112 01113 /** 01114 * @brief Return the Host Channel state. 01115 * @param hhcd HCD handle 01116 * @param chnum Channel number. 01117 * This parameter can be a value from 1 to 15 01118 * @retval Host channel state 01119 * This parameter can be one of these values: 01120 * HC_IDLE/ 01121 * HC_XFRC/ 01122 * HC_HALTED/ 01123 * HC_NYET/ 01124 * HC_NAK/ 01125 * HC_STALL/ 01126 * HC_XACTERR/ 01127 * HC_BBLERR/ 01128 * HC_DATATGLERR 01129 */ 01130 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01131 { 01132 return hhcd->hc[chnum].state; 01133 } 01134 01135 /** 01136 * @brief Return the current Host frame number. 01137 * @param hhcd HCD handle 01138 * @retval Current Host frame number 01139 */ 01140 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd) 01141 { 01142 return (USB_GetCurrentFrame(hhcd->Instance)); 01143 } 01144 01145 /** 01146 * @brief Return the Host enumeration speed. 01147 * @param hhcd HCD handle 01148 * @retval Enumeration speed 01149 */ 01150 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd) 01151 { 01152 return (USB_GetHostSpeed(hhcd->Instance)); 01153 } 01154 01155 /** 01156 * @} 01157 */ 01158 01159 /** 01160 * @} 01161 */ 01162 01163 /** @addtogroup HCD_Private_Functions 01164 * @{ 01165 */ 01166 /** 01167 * @brief Handle Host Channel IN interrupt requests. 01168 * @param hhcd HCD handle 01169 * @param chnum Channel number. 01170 * This parameter can be a value from 1 to 15 01171 * @retval none 01172 */ 01173 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01174 { 01175 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01176 uint32_t USBx_BASE = (uint32_t)USBx; 01177 uint32_t ch_num = (uint32_t)chnum; 01178 01179 uint32_t tmpreg; 01180 01181 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) 01182 { 01183 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR); 01184 hhcd->hc[ch_num].state = HC_XACTERR; 01185 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01186 } 01187 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) 01188 { 01189 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR); 01190 hhcd->hc[ch_num].state = HC_BBLERR; 01191 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01192 } 01193 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) 01194 { 01195 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK); 01196 } 01197 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) 01198 { 01199 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL); 01200 hhcd->hc[ch_num].state = HC_STALL; 01201 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01202 } 01203 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) 01204 { 01205 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR); 01206 hhcd->hc[ch_num].state = HC_DATATGLERR; 01207 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01208 } 01209 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) 01210 { 01211 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR); 01212 hhcd->hc[ch_num].state = HC_XACTERR; 01213 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01214 } 01215 else 01216 { 01217 /* ... */ 01218 } 01219 01220 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) 01221 { 01222 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01223 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR); 01224 } 01225 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) 01226 { 01227 if (hhcd->Init.dma_enable != 0U) 01228 { 01229 hhcd->hc[ch_num].xfer_count = hhcd->hc[ch_num].XferSize - \ 01230 (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); 01231 } 01232 01233 hhcd->hc[ch_num].state = HC_XFRC; 01234 hhcd->hc[ch_num].ErrCnt = 0U; 01235 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC); 01236 01237 if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) || 01238 (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK)) 01239 { 01240 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01241 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01242 } 01243 else if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR) 01244 { 01245 USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM; 01246 hhcd->hc[ch_num].urb_state = URB_DONE; 01247 01248 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01249 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01250 #else 01251 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01252 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01253 } 01254 else if (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC) 01255 { 01256 hhcd->hc[ch_num].urb_state = URB_DONE; 01257 hhcd->hc[ch_num].toggle_in ^= 1U; 01258 01259 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01260 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01261 #else 01262 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01263 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01264 } 01265 else 01266 { 01267 /* ... */ 01268 } 01269 01270 if (hhcd->Init.dma_enable == 1U) 01271 { 01272 if (((hhcd->hc[ch_num].XferSize / hhcd->hc[ch_num].max_packet) & 1U) != 0U) 01273 { 01274 hhcd->hc[ch_num].toggle_in ^= 1U; 01275 } 01276 } 01277 else 01278 { 01279 hhcd->hc[ch_num].toggle_in ^= 1U; 01280 } 01281 } 01282 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) 01283 { 01284 if (hhcd->hc[ch_num].state == HC_XFRC) 01285 { 01286 hhcd->hc[ch_num].urb_state = URB_DONE; 01287 } 01288 else if (hhcd->hc[ch_num].state == HC_STALL) 01289 { 01290 hhcd->hc[ch_num].urb_state = URB_STALL; 01291 } 01292 else if ((hhcd->hc[ch_num].state == HC_XACTERR) || 01293 (hhcd->hc[ch_num].state == HC_DATATGLERR)) 01294 { 01295 hhcd->hc[ch_num].ErrCnt++; 01296 if (hhcd->hc[ch_num].ErrCnt > 2U) 01297 { 01298 hhcd->hc[ch_num].ErrCnt = 0U; 01299 hhcd->hc[ch_num].urb_state = URB_ERROR; 01300 } 01301 else 01302 { 01303 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01304 01305 /* re-activate the channel */ 01306 tmpreg = USBx_HC(ch_num)->HCCHAR; 01307 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01308 tmpreg |= USB_OTG_HCCHAR_CHENA; 01309 USBx_HC(ch_num)->HCCHAR = tmpreg; 01310 } 01311 } 01312 else if (hhcd->hc[ch_num].state == HC_NAK) 01313 { 01314 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01315 01316 /* re-activate the channel */ 01317 tmpreg = USBx_HC(ch_num)->HCCHAR; 01318 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01319 tmpreg |= USB_OTG_HCCHAR_CHENA; 01320 USBx_HC(ch_num)->HCCHAR = tmpreg; 01321 } 01322 else if (hhcd->hc[ch_num].state == HC_BBLERR) 01323 { 01324 hhcd->hc[ch_num].ErrCnt++; 01325 hhcd->hc[ch_num].urb_state = URB_ERROR; 01326 } 01327 else 01328 { 01329 /* ... */ 01330 } 01331 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH); 01332 01333 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01334 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01335 #else 01336 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01337 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01338 } 01339 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) 01340 { 01341 if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR) 01342 { 01343 hhcd->hc[ch_num].ErrCnt = 0U; 01344 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01345 } 01346 else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) || 01347 (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK)) 01348 { 01349 hhcd->hc[ch_num].ErrCnt = 0U; 01350 01351 if (hhcd->Init.dma_enable == 0U) 01352 { 01353 hhcd->hc[ch_num].state = HC_NAK; 01354 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01355 } 01356 } 01357 else 01358 { 01359 /* ... */ 01360 } 01361 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01362 } 01363 else 01364 { 01365 /* ... */ 01366 } 01367 } 01368 01369 /** 01370 * @brief Handle Host Channel OUT interrupt requests. 01371 * @param hhcd HCD handle 01372 * @param chnum Channel number. 01373 * This parameter can be a value from 1 to 15 01374 * @retval none 01375 */ 01376 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) 01377 { 01378 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01379 uint32_t USBx_BASE = (uint32_t)USBx; 01380 uint32_t ch_num = (uint32_t)chnum; 01381 uint32_t tmpreg; 01382 uint32_t num_packets; 01383 01384 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) 01385 { 01386 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR); 01387 hhcd->hc[ch_num].state = HC_XACTERR; 01388 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01389 } 01390 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) 01391 { 01392 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK); 01393 01394 if (hhcd->hc[ch_num].do_ping == 1U) 01395 { 01396 hhcd->hc[ch_num].do_ping = 0U; 01397 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01398 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01399 } 01400 } 01401 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) 01402 { 01403 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR); 01404 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01405 } 01406 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) 01407 { 01408 hhcd->hc[ch_num].ErrCnt = 0U; 01409 01410 /* transaction completed with NYET state, update do ping state */ 01411 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) 01412 { 01413 hhcd->hc[ch_num].do_ping = 1U; 01414 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET); 01415 } 01416 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC); 01417 hhcd->hc[ch_num].state = HC_XFRC; 01418 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01419 } 01420 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) 01421 { 01422 hhcd->hc[ch_num].state = HC_NYET; 01423 hhcd->hc[ch_num].do_ping = 1U; 01424 hhcd->hc[ch_num].ErrCnt = 0U; 01425 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01426 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET); 01427 } 01428 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) 01429 { 01430 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL); 01431 hhcd->hc[ch_num].state = HC_STALL; 01432 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01433 } 01434 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) 01435 { 01436 hhcd->hc[ch_num].ErrCnt = 0U; 01437 hhcd->hc[ch_num].state = HC_NAK; 01438 01439 if (hhcd->hc[ch_num].do_ping == 0U) 01440 { 01441 if (hhcd->hc[ch_num].speed == HCD_DEVICE_SPEED_HIGH) 01442 { 01443 hhcd->hc[ch_num].do_ping = 1U; 01444 } 01445 } 01446 01447 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01448 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK); 01449 } 01450 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) 01451 { 01452 if (hhcd->Init.dma_enable == 0U) 01453 { 01454 hhcd->hc[ch_num].state = HC_XACTERR; 01455 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01456 } 01457 else 01458 { 01459 hhcd->hc[ch_num].ErrCnt++; 01460 if (hhcd->hc[ch_num].ErrCnt > 2U) 01461 { 01462 hhcd->hc[ch_num].ErrCnt = 0U; 01463 hhcd->hc[ch_num].urb_state = URB_ERROR; 01464 01465 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01466 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01467 #else 01468 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01469 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01470 } 01471 else 01472 { 01473 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01474 } 01475 } 01476 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR); 01477 } 01478 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) 01479 { 01480 hhcd->hc[ch_num].state = HC_DATATGLERR; 01481 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num); 01482 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR); 01483 } 01484 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) 01485 { 01486 if (hhcd->hc[ch_num].state == HC_XFRC) 01487 { 01488 hhcd->hc[ch_num].urb_state = URB_DONE; 01489 if ((hhcd->hc[ch_num].ep_type == EP_TYPE_BULK) || 01490 (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)) 01491 { 01492 if (hhcd->Init.dma_enable == 0U) 01493 { 01494 hhcd->hc[ch_num].toggle_out ^= 1U; 01495 } 01496 01497 if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[ch_num].xfer_len > 0U)) 01498 { 01499 num_packets = (hhcd->hc[ch_num].xfer_len + hhcd->hc[ch_num].max_packet - 1U) / hhcd->hc[ch_num].max_packet; 01500 01501 if ((num_packets & 1U) != 0U) 01502 { 01503 hhcd->hc[ch_num].toggle_out ^= 1U; 01504 } 01505 } 01506 } 01507 } 01508 else if (hhcd->hc[ch_num].state == HC_NAK) 01509 { 01510 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01511 } 01512 else if (hhcd->hc[ch_num].state == HC_NYET) 01513 { 01514 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01515 } 01516 else if (hhcd->hc[ch_num].state == HC_STALL) 01517 { 01518 hhcd->hc[ch_num].urb_state = URB_STALL; 01519 } 01520 else if ((hhcd->hc[ch_num].state == HC_XACTERR) || 01521 (hhcd->hc[ch_num].state == HC_DATATGLERR)) 01522 { 01523 hhcd->hc[ch_num].ErrCnt++; 01524 if (hhcd->hc[ch_num].ErrCnt > 2U) 01525 { 01526 hhcd->hc[ch_num].ErrCnt = 0U; 01527 hhcd->hc[ch_num].urb_state = URB_ERROR; 01528 } 01529 else 01530 { 01531 hhcd->hc[ch_num].urb_state = URB_NOTREADY; 01532 01533 /* re-activate the channel */ 01534 tmpreg = USBx_HC(ch_num)->HCCHAR; 01535 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01536 tmpreg |= USB_OTG_HCCHAR_CHENA; 01537 USBx_HC(ch_num)->HCCHAR = tmpreg; 01538 } 01539 } 01540 else 01541 { 01542 /* ... */ 01543 } 01544 01545 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH); 01546 01547 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01548 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01549 #else 01550 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state); 01551 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01552 } 01553 else 01554 { 01555 /* ... */ 01556 } 01557 } 01558 01559 /** 01560 * @brief Handle Rx Queue Level interrupt requests. 01561 * @param hhcd HCD handle 01562 * @retval none 01563 */ 01564 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd) 01565 { 01566 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01567 uint32_t USBx_BASE = (uint32_t)USBx; 01568 uint32_t pktsts; 01569 uint32_t pktcnt; 01570 uint32_t GrxstspReg; 01571 uint32_t xferSizePktCnt; 01572 uint32_t tmpreg; 01573 uint32_t ch_num; 01574 01575 GrxstspReg = hhcd->Instance->GRXSTSP; 01576 ch_num = GrxstspReg & USB_OTG_GRXSTSP_EPNUM; 01577 pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17; 01578 pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4; 01579 01580 switch (pktsts) 01581 { 01582 case GRXSTS_PKTSTS_IN: 01583 /* Read the data into the host buffer. */ 01584 if ((pktcnt > 0U) && (hhcd->hc[ch_num].xfer_buff != (void *)0)) 01585 { 01586 if ((hhcd->hc[ch_num].xfer_count + pktcnt) <= hhcd->hc[ch_num].xfer_len) 01587 { 01588 (void)USB_ReadPacket(hhcd->Instance, 01589 hhcd->hc[ch_num].xfer_buff, (uint16_t)pktcnt); 01590 01591 /* manage multiple Xfer */ 01592 hhcd->hc[ch_num].xfer_buff += pktcnt; 01593 hhcd->hc[ch_num].xfer_count += pktcnt; 01594 01595 /* get transfer size packet count */ 01596 xferSizePktCnt = (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19; 01597 01598 if ((hhcd->hc[ch_num].max_packet == pktcnt) && (xferSizePktCnt > 0U)) 01599 { 01600 /* re-activate the channel when more packets are expected */ 01601 tmpreg = USBx_HC(ch_num)->HCCHAR; 01602 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01603 tmpreg |= USB_OTG_HCCHAR_CHENA; 01604 USBx_HC(ch_num)->HCCHAR = tmpreg; 01605 hhcd->hc[ch_num].toggle_in ^= 1U; 01606 } 01607 } 01608 else 01609 { 01610 hhcd->hc[ch_num].urb_state = URB_ERROR; 01611 } 01612 } 01613 break; 01614 01615 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: 01616 break; 01617 01618 case GRXSTS_PKTSTS_IN_XFER_COMP: 01619 case GRXSTS_PKTSTS_CH_HALTED: 01620 default: 01621 break; 01622 } 01623 } 01624 01625 /** 01626 * @brief Handle Host Port interrupt requests. 01627 * @param hhcd HCD handle 01628 * @retval None 01629 */ 01630 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd) 01631 { 01632 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01633 uint32_t USBx_BASE = (uint32_t)USBx; 01634 __IO uint32_t hprt0; 01635 __IO uint32_t hprt0_dup; 01636 01637 /* Handle Host Port Interrupts */ 01638 hprt0 = USBx_HPRT0; 01639 hprt0_dup = USBx_HPRT0; 01640 01641 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \ 01642 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG); 01643 01644 /* Check whether Port Connect detected */ 01645 if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) 01646 { 01647 if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) 01648 { 01649 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01650 hhcd->ConnectCallback(hhcd); 01651 #else 01652 HAL_HCD_Connect_Callback(hhcd); 01653 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01654 } 01655 hprt0_dup |= USB_OTG_HPRT_PCDET; 01656 } 01657 01658 /* Check whether Port Enable Changed */ 01659 if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) 01660 { 01661 hprt0_dup |= USB_OTG_HPRT_PENCHNG; 01662 01663 if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) 01664 { 01665 if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY) 01666 { 01667 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) 01668 { 01669 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ); 01670 } 01671 else 01672 { 01673 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ); 01674 } 01675 } 01676 else 01677 { 01678 if (hhcd->Init.speed == HCD_SPEED_FULL) 01679 { 01680 USBx_HOST->HFIR = 60000U; 01681 } 01682 } 01683 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01684 hhcd->PortEnabledCallback(hhcd); 01685 #else 01686 HAL_HCD_PortEnabled_Callback(hhcd); 01687 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01688 01689 } 01690 else 01691 { 01692 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) 01693 hhcd->PortDisabledCallback(hhcd); 01694 #else 01695 HAL_HCD_PortDisabled_Callback(hhcd); 01696 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ 01697 } 01698 } 01699 01700 /* Check for an overcurrent */ 01701 if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) 01702 { 01703 hprt0_dup |= USB_OTG_HPRT_POCCHNG; 01704 } 01705 01706 /* Clear Port Interrupts */ 01707 USBx_HPRT0 = hprt0_dup; 01708 } 01709 01710 /** 01711 * @} 01712 */ 01713 01714 /** 01715 * @} 01716 */ 01717 01718 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 01719 #endif /* HAL_HCD_MODULE_ENABLED */ 01720 01721 /** 01722 * @} 01723 */ 01724 01725 /** 01726 * @} 01727 */