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