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