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