STM32F439xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_hcd.c 00004 * @author MCD Application Team 00005 * @brief HCD HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the USB Peripheral Controller: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral Control functions 00011 * + Peripheral State functions 00012 * 00013 @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 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode) 00029 (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode) 00030 00031 (##) Initialize the related GPIO clocks 00032 (##) Configure HCD pin-out 00033 (##) Configure HCD NVIC interrupt 00034 00035 (#)Associate the Upper USB Host stack to the HAL HCD Driver: 00036 (##) hhcd.pData = phost; 00037 00038 (#)Enable HCD transmission and reception: 00039 (##) HAL_HCD_Start(); 00040 00041 @endverbatim 00042 ****************************************************************************** 00043 * @attention 00044 * 00045 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00046 * 00047 * Redistribution and use in source and binary forms, with or without modification, 00048 * are permitted provided that the following conditions are met: 00049 * 1. Redistributions of source code must retain the above copyright notice, 00050 * this list of conditions and the following disclaimer. 00051 * 2. Redistributions in binary form must reproduce the above copyright notice, 00052 * this list of conditions and the following disclaimer in the documentation 00053 * and/or other materials provided with the distribution. 00054 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00055 * may be used to endorse or promote products derived from this software 00056 * without specific prior written permission. 00057 * 00058 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00059 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00060 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00061 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00062 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00063 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00064 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00065 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00066 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00067 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00068 * 00069 ****************************************************************************** 00070 */ 00071 00072 /* Includes ------------------------------------------------------------------*/ 00073 #include "stm32f4xx_hal.h" 00074 00075 /** @addtogroup STM32F4xx_HAL_Driver 00076 * @{ 00077 */ 00078 00079 /** @defgroup HCD HCD 00080 * @brief HCD HAL module driver 00081 * @{ 00082 */ 00083 00084 #ifdef HAL_HCD_MODULE_ENABLED 00085 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \ 00086 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ 00087 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \ 00088 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \ 00089 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 00090 /* Private typedef -----------------------------------------------------------*/ 00091 /* Private define ------------------------------------------------------------*/ 00092 /* Private macro -------------------------------------------------------------*/ 00093 /* Private variables ---------------------------------------------------------*/ 00094 /* Private function prototypes -----------------------------------------------*/ 00095 /** @defgroup HCD_Private_Functions HCD Private Functions 00096 * @{ 00097 */ 00098 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); 00099 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); 00100 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd); 00101 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd); 00102 /** 00103 * @} 00104 */ 00105 00106 /* Exported functions --------------------------------------------------------*/ 00107 /** @defgroup HCD_Exported_Functions HCD Exported Functions 00108 * @{ 00109 */ 00110 00111 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions 00112 * @brief Initialization and Configuration functions 00113 * 00114 @verbatim 00115 =============================================================================== 00116 ##### Initialization and de-initialization functions ##### 00117 =============================================================================== 00118 [..] This section provides functions allowing to: 00119 00120 @endverbatim 00121 * @{ 00122 */ 00123 00124 /** 00125 * @brief Initialize the host driver. 00126 * @param hhcd HCD handle 00127 * @retval HAL status 00128 */ 00129 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd) 00130 { 00131 /* Check the HCD handle allocation */ 00132 if(hhcd == NULL) 00133 { 00134 return HAL_ERROR; 00135 } 00136 00137 /* Check the parameters */ 00138 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance)); 00139 00140 hhcd->State = HAL_HCD_STATE_BUSY; 00141 00142 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ 00143 HAL_HCD_MspInit(hhcd); 00144 00145 /* Disable the Interrupts */ 00146 __HAL_HCD_DISABLE(hhcd); 00147 00148 /* Init the Core (common init.) */ 00149 USB_CoreInit(hhcd->Instance, hhcd->Init); 00150 00151 /* Force Host Mode*/ 00152 USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE); 00153 00154 /* Init Host */ 00155 USB_HostInit(hhcd->Instance, hhcd->Init); 00156 00157 hhcd->State= HAL_HCD_STATE_READY; 00158 00159 return HAL_OK; 00160 } 00161 00162 /** 00163 * @brief Initialize a host channel. 00164 * @param hhcd HCD handle 00165 * @param ch_num Channel number. 00166 * This parameter can be a value from 1 to 15 00167 * @param epnum Endpoint number. 00168 * This parameter can be a value from 1 to 15 00169 * @param dev_address Current device address 00170 * This parameter can be a value from 0 to 255 00171 * @param speed Current device speed. 00172 * This parameter can be one of these values: 00173 * HCD_SPEED_HIGH: High speed mode, 00174 * HCD_SPEED_FULL: Full speed mode, 00175 * HCD_SPEED_LOW: Low speed mode 00176 * @param ep_type Endpoint Type. 00177 * This parameter can be one of these values: 00178 * EP_TYPE_CTRL: Control type, 00179 * EP_TYPE_ISOC: Isochronous type, 00180 * EP_TYPE_BULK: Bulk type, 00181 * EP_TYPE_INTR: Interrupt type 00182 * @param mps Max Packet Size. 00183 * This parameter can be a value from 0 to32K 00184 * @retval HAL status 00185 */ 00186 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, 00187 uint8_t ch_num, 00188 uint8_t epnum, 00189 uint8_t dev_address, 00190 uint8_t speed, 00191 uint8_t ep_type, 00192 uint16_t mps) 00193 { 00194 HAL_StatusTypeDef status = HAL_OK; 00195 00196 __HAL_LOCK(hhcd); 00197 00198 hhcd->hc[ch_num].dev_addr = dev_address; 00199 hhcd->hc[ch_num].max_packet = mps; 00200 hhcd->hc[ch_num].ch_num = ch_num; 00201 hhcd->hc[ch_num].ep_type = ep_type; 00202 hhcd->hc[ch_num].ep_num = epnum & 0x7F; 00203 hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80); 00204 hhcd->hc[ch_num].speed = speed; 00205 00206 status = USB_HC_Init(hhcd->Instance, 00207 ch_num, 00208 epnum, 00209 dev_address, 00210 speed, 00211 ep_type, 00212 mps); 00213 __HAL_UNLOCK(hhcd); 00214 00215 return status; 00216 } 00217 00218 /** 00219 * @brief Halt a host channel. 00220 * @param hhcd HCD handle 00221 * @param ch_num Channel number. 00222 * This parameter can be a value from 1 to 15 00223 * @retval HAL status 00224 */ 00225 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num) 00226 { 00227 HAL_StatusTypeDef status = HAL_OK; 00228 00229 __HAL_LOCK(hhcd); 00230 USB_HC_Halt(hhcd->Instance, ch_num); 00231 __HAL_UNLOCK(hhcd); 00232 00233 return status; 00234 } 00235 00236 /** 00237 * @brief DeInitialize the host driver. 00238 * @param hhcd HCD handle 00239 * @retval HAL status 00240 */ 00241 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd) 00242 { 00243 /* Check the HCD handle allocation */ 00244 if(hhcd == NULL) 00245 { 00246 return HAL_ERROR; 00247 } 00248 00249 hhcd->State = HAL_HCD_STATE_BUSY; 00250 00251 /* DeInit the low level hardware */ 00252 HAL_HCD_MspDeInit(hhcd); 00253 00254 __HAL_HCD_DISABLE(hhcd); 00255 00256 hhcd->State = HAL_HCD_STATE_RESET; 00257 00258 return HAL_OK; 00259 } 00260 00261 /** 00262 * @brief Initialize the HCD MSP. 00263 * @param hhcd HCD handle 00264 * @retval None 00265 */ 00266 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd) 00267 { 00268 /* Prevent unused argument(s) compilation warning */ 00269 UNUSED(hhcd); 00270 /* NOTE : This function Should not be modified, when the callback is needed, 00271 the HAL_PCD_MspInit could be implemented in the user file 00272 */ 00273 } 00274 00275 /** 00276 * @brief DeInitialize the HCD MSP. 00277 * @param hhcd HCD handle 00278 * @retval None 00279 */ 00280 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd) 00281 { 00282 /* Prevent unused argument(s) compilation warning */ 00283 UNUSED(hhcd); 00284 /* NOTE : This function Should not be modified, when the callback is needed, 00285 the HAL_PCD_MspDeInit could be implemented in the user file 00286 */ 00287 } 00288 00289 /** 00290 * @} 00291 */ 00292 00293 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions 00294 * @brief HCD IO operation functions 00295 * 00296 @verbatim 00297 =============================================================================== 00298 ##### IO operation functions ##### 00299 =============================================================================== 00300 [..] This subsection provides a set of functions allowing to manage the USB Host Data 00301 Transfer 00302 00303 @endverbatim 00304 * @{ 00305 */ 00306 00307 /** 00308 * @brief Submit a new URB for processing. 00309 * @param hhcd HCD handle 00310 * @param ch_num Channel number. 00311 * This parameter can be a value from 1 to 15 00312 * @param direction Channel number. 00313 * This parameter can be one of these values: 00314 * 0 : Output / 1 : Input 00315 * @param ep_type Endpoint Type. 00316 * This parameter can be one of these values: 00317 * EP_TYPE_CTRL: Control type/ 00318 * EP_TYPE_ISOC: Isochronous type/ 00319 * EP_TYPE_BULK: Bulk type/ 00320 * EP_TYPE_INTR: Interrupt type/ 00321 * @param token Endpoint Type. 00322 * This parameter can be one of these values: 00323 * 0: HC_PID_SETUP / 1: HC_PID_DATA1 00324 * @param pbuff pointer to URB data 00325 * @param length Length of URB data 00326 * @param do_ping activate do ping protocol (for high speed only). 00327 * This parameter can be one of these values: 00328 * 0 : do ping inactive / 1 : do ping active 00329 * @retval HAL status 00330 */ 00331 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, 00332 uint8_t ch_num, 00333 uint8_t direction, 00334 uint8_t ep_type, 00335 uint8_t token, 00336 uint8_t* pbuff, 00337 uint16_t length, 00338 uint8_t do_ping) 00339 { 00340 hhcd->hc[ch_num].ep_is_in = direction; 00341 hhcd->hc[ch_num].ep_type = ep_type; 00342 00343 if(token == 0) 00344 { 00345 hhcd->hc[ch_num].data_pid = HC_PID_SETUP; 00346 } 00347 else 00348 { 00349 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00350 } 00351 00352 /* Manage Data Toggle */ 00353 switch(ep_type) 00354 { 00355 case EP_TYPE_CTRL: 00356 if((token == 1) && (direction == 0)) /*send data */ 00357 { 00358 if (length == 0) 00359 { /* For Status OUT stage, Length==0, Status Out PID = 1 */ 00360 hhcd->hc[ch_num].toggle_out = 1; 00361 } 00362 00363 /* Set the Data Toggle bit as per the Flag */ 00364 if (hhcd->hc[ch_num].toggle_out == 0) 00365 { /* Put the PID 0 */ 00366 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00367 } 00368 else 00369 { /* Put the PID 1 */ 00370 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00371 } 00372 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) 00373 { 00374 hhcd->hc[ch_num].do_ping = do_ping; 00375 } 00376 } 00377 break; 00378 00379 case EP_TYPE_BULK: 00380 if(direction == 0) 00381 { 00382 /* Set the Data Toggle bit as per the Flag */ 00383 if ( hhcd->hc[ch_num].toggle_out == 0) 00384 { /* Put the PID 0 */ 00385 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00386 } 00387 else 00388 { /* Put the PID 1 */ 00389 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00390 } 00391 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) 00392 { 00393 hhcd->hc[ch_num].do_ping = do_ping; 00394 } 00395 } 00396 else 00397 { 00398 if( hhcd->hc[ch_num].toggle_in == 0) 00399 { 00400 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00401 } 00402 else 00403 { 00404 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00405 } 00406 } 00407 00408 break; 00409 case EP_TYPE_INTR: 00410 if(direction == 0) 00411 { 00412 /* Set the Data Toggle bit as per the Flag */ 00413 if ( hhcd->hc[ch_num].toggle_out == 0) 00414 { /* Put the PID 0 */ 00415 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00416 } 00417 else 00418 { /* Put the PID 1 */ 00419 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00420 } 00421 } 00422 else 00423 { 00424 if( hhcd->hc[ch_num].toggle_in == 0) 00425 { 00426 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00427 } 00428 else 00429 { 00430 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; 00431 } 00432 } 00433 break; 00434 00435 case EP_TYPE_ISOC: 00436 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; 00437 break; 00438 } 00439 00440 hhcd->hc[ch_num].xfer_buff = pbuff; 00441 hhcd->hc[ch_num].xfer_len = length; 00442 hhcd->hc[ch_num].urb_state = URB_IDLE; 00443 hhcd->hc[ch_num].xfer_count = 0; 00444 hhcd->hc[ch_num].ch_num = ch_num; 00445 hhcd->hc[ch_num].state = HC_IDLE; 00446 00447 return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable); 00448 } 00449 00450 /** 00451 * @brief Handle HCD interrupt request. 00452 * @param hhcd HCD handle 00453 * @retval None 00454 */ 00455 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd) 00456 { 00457 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 00458 uint32_t i = 0U , interrupt = 0U; 00459 00460 /* Ensure that we are in device mode */ 00461 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST) 00462 { 00463 /* Avoid spurious interrupt */ 00464 if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd)) 00465 { 00466 return; 00467 } 00468 00469 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) 00470 { 00471 /* Incorrect mode, acknowledge the interrupt */ 00472 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); 00473 } 00474 00475 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR)) 00476 { 00477 /* Incorrect mode, acknowledge the interrupt */ 00478 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR); 00479 } 00480 00481 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE)) 00482 { 00483 /* Incorrect mode, acknowledge the interrupt */ 00484 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE); 00485 } 00486 00487 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS)) 00488 { 00489 /* Incorrect mode, acknowledge the interrupt */ 00490 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS); 00491 } 00492 00493 /* Handle Host Disconnect Interrupts */ 00494 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT)) 00495 { 00496 00497 /* Cleanup HPRT */ 00498 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ 00499 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); 00500 00501 /* Handle Host Port Interrupts */ 00502 HAL_HCD_Disconnect_Callback(hhcd); 00503 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); 00504 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT); 00505 } 00506 00507 /* Handle Host Port Interrupts */ 00508 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT)) 00509 { 00510 HCD_Port_IRQHandler (hhcd); 00511 } 00512 00513 /* Handle Host SOF Interrupts */ 00514 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF)) 00515 { 00516 HAL_HCD_SOF_Callback(hhcd); 00517 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF); 00518 } 00519 00520 /* Handle Host channel Interrupts */ 00521 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT)) 00522 { 00523 interrupt = USB_HC_ReadInterrupt(hhcd->Instance); 00524 for (i = 0U; i < hhcd->Init.Host_channels; i++) 00525 { 00526 if (interrupt & (1U << i)) 00527 { 00528 if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR) 00529 { 00530 HCD_HC_IN_IRQHandler(hhcd, i); 00531 } 00532 else 00533 { 00534 HCD_HC_OUT_IRQHandler (hhcd, i); 00535 } 00536 } 00537 } 00538 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT); 00539 } 00540 00541 /* Handle Rx Queue Level Interrupts */ 00542 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) 00543 { 00544 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00545 00546 HCD_RXQLVL_IRQHandler (hhcd); 00547 00548 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00549 } 00550 } 00551 } 00552 00553 /** 00554 * @brief SOF callback. 00555 * @param hhcd HCD handle 00556 * @retval None 00557 */ 00558 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) 00559 { 00560 /* Prevent unused argument(s) compilation warning */ 00561 UNUSED(hhcd); 00562 /* NOTE : This function Should not be modified, when the callback is needed, 00563 the HAL_HCD_SOF_Callback could be implemented in the user file 00564 */ 00565 } 00566 00567 /** 00568 * @brief Connection Event callback. 00569 * @param hhcd HCD handle 00570 * @retval None 00571 */ 00572 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) 00573 { 00574 /* Prevent unused argument(s) compilation warning */ 00575 UNUSED(hhcd); 00576 /* NOTE : This function Should not be modified, when the callback is needed, 00577 the HAL_HCD_Connect_Callback could be implemented in the user file 00578 */ 00579 } 00580 00581 /** 00582 * @brief Disconnection Event callback. 00583 * @param hhcd HCD handle 00584 * @retval None 00585 */ 00586 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) 00587 { 00588 /* Prevent unused argument(s) compilation warning */ 00589 UNUSED(hhcd); 00590 /* NOTE : This function Should not be modified, when the callback is needed, 00591 the HAL_HCD_Disconnect_Callback could be implemented in the user file 00592 */ 00593 } 00594 00595 /** 00596 * @brief Notify URB state change callback. 00597 * @param hhcd HCD handle 00598 * @param chnum Channel number. 00599 * This parameter can be a value from 1 to 15 00600 * @param urb_state: 00601 * This parameter can be one of these values: 00602 * URB_IDLE/ 00603 * URB_DONE/ 00604 * URB_NOTREADY/ 00605 * URB_NYET/ 00606 * URB_ERROR/ 00607 * URB_STALL/ 00608 * @retval None 00609 */ 00610 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) 00611 { 00612 /* Prevent unused argument(s) compilation warning */ 00613 UNUSED(hhcd); 00614 UNUSED(chnum); 00615 UNUSED(urb_state); 00616 /* NOTE : This function Should not be modified, when the callback is needed, 00617 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file 00618 */ 00619 } 00620 00621 /** 00622 * @} 00623 */ 00624 00625 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions 00626 * @brief Management functions 00627 * 00628 @verbatim 00629 =============================================================================== 00630 ##### Peripheral Control functions ##### 00631 =============================================================================== 00632 [..] 00633 This subsection provides a set of functions allowing to control the HCD data 00634 transfers. 00635 00636 @endverbatim 00637 * @{ 00638 */ 00639 00640 /** 00641 * @brief Start the host driver. 00642 * @param hhcd HCD handle 00643 * @retval HAL status 00644 */ 00645 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd) 00646 { 00647 __HAL_LOCK(hhcd); 00648 __HAL_HCD_ENABLE(hhcd); 00649 USB_DriveVbus(hhcd->Instance, 1U); 00650 __HAL_UNLOCK(hhcd); 00651 return HAL_OK; 00652 } 00653 00654 /** 00655 * @brief Stop the host driver. 00656 * @param hhcd HCD handle 00657 * @retval HAL status 00658 */ 00659 00660 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd) 00661 { 00662 __HAL_LOCK(hhcd); 00663 USB_StopHost(hhcd->Instance); 00664 __HAL_UNLOCK(hhcd); 00665 return HAL_OK; 00666 } 00667 00668 /** 00669 * @brief Reset the host port. 00670 * @param hhcd HCD handle 00671 * @retval HAL status 00672 */ 00673 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd) 00674 { 00675 return (USB_ResetPort(hhcd->Instance)); 00676 } 00677 00678 /** 00679 * @} 00680 */ 00681 00682 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions 00683 * @brief Peripheral State functions 00684 * 00685 @verbatim 00686 =============================================================================== 00687 ##### Peripheral State functions ##### 00688 =============================================================================== 00689 [..] 00690 This subsection permits to get in run-time the status of the peripheral 00691 and the data flow. 00692 00693 @endverbatim 00694 * @{ 00695 */ 00696 00697 /** 00698 * @brief Return the HCD handle state. 00699 * @param hhcd HCD handle 00700 * @retval HAL state 00701 */ 00702 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd) 00703 { 00704 return hhcd->State; 00705 } 00706 00707 /** 00708 * @brief Return URB state for a channel. 00709 * @param hhcd HCD handle 00710 * @param chnum Channel number. 00711 * This parameter can be a value from 1 to 15 00712 * @retval URB state. 00713 * This parameter can be one of these values: 00714 * URB_IDLE/ 00715 * URB_DONE/ 00716 * URB_NOTREADY/ 00717 * URB_NYET/ 00718 * URB_ERROR/ 00719 * URB_STALL 00720 */ 00721 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum) 00722 { 00723 return hhcd->hc[chnum].urb_state; 00724 } 00725 00726 00727 /** 00728 * @brief Return the last host transfer size. 00729 * @param hhcd HCD handle 00730 * @param chnum Channel number. 00731 * This parameter can be a value from 1 to 15 00732 * @retval last transfer size in byte 00733 */ 00734 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum) 00735 { 00736 return hhcd->hc[chnum].xfer_count; 00737 } 00738 00739 /** 00740 * @brief Return the Host Channel state. 00741 * @param hhcd HCD handle 00742 * @param chnum Channel number. 00743 * This parameter can be a value from 1 to 15 00744 * @retval Host channel state 00745 * This parameter can be one of these values: 00746 * HC_IDLE/ 00747 * HC_XFRC/ 00748 * HC_HALTED/ 00749 * HC_NYET/ 00750 * HC_NAK/ 00751 * HC_STALL/ 00752 * HC_XACTERR/ 00753 * HC_BBLERR/ 00754 * HC_DATATGLERR 00755 */ 00756 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum) 00757 { 00758 return hhcd->hc[chnum].state; 00759 } 00760 00761 /** 00762 * @brief Return the current Host frame number. 00763 * @param hhcd HCD handle 00764 * @retval Current Host frame number 00765 */ 00766 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd) 00767 { 00768 return (USB_GetCurrentFrame(hhcd->Instance)); 00769 } 00770 00771 /** 00772 * @brief Return the Host enumeration speed. 00773 * @param hhcd HCD handle 00774 * @retval Enumeration speed 00775 */ 00776 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd) 00777 { 00778 return (USB_GetHostSpeed(hhcd->Instance)); 00779 } 00780 00781 /** 00782 * @} 00783 */ 00784 00785 /** 00786 * @} 00787 */ 00788 00789 /** @addtogroup HCD_Private_Functions 00790 * @{ 00791 */ 00792 /** 00793 * @brief Handle Host Channel IN interrupt requests. 00794 * @param hhcd HCD handle 00795 * @param chnum Channel number. 00796 * This parameter can be a value from 1 to 15 00797 * @retval None 00798 */ 00799 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) 00800 { 00801 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 00802 uint32_t tmpreg = 0U; 00803 00804 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR) 00805 { 00806 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR); 00807 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00808 } 00809 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK) 00810 { 00811 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK); 00812 } 00813 00814 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL) 00815 { 00816 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00817 hhcd->hc[chnum].state = HC_STALL; 00818 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); 00819 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL); 00820 USB_HC_Halt(hhcd->Instance, chnum); 00821 } 00822 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR) 00823 { 00824 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00825 USB_HC_Halt(hhcd->Instance, chnum); 00826 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); 00827 hhcd->hc[chnum].state = HC_DATATGLERR; 00828 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR); 00829 } 00830 00831 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR) 00832 { 00833 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00834 USB_HC_Halt(hhcd->Instance, chnum); 00835 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR); 00836 } 00837 00838 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC) 00839 { 00840 00841 if (hhcd->Init.dma_enable) 00842 { 00843 hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \ 00844 (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); 00845 } 00846 00847 hhcd->hc[chnum].state = HC_XFRC; 00848 hhcd->hc[chnum].ErrCnt = 0U; 00849 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC); 00850 00851 00852 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)|| 00853 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) 00854 { 00855 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00856 USB_HC_Halt(hhcd->Instance, chnum); 00857 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); 00858 00859 } 00860 else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR) 00861 { 00862 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM; 00863 hhcd->hc[chnum].urb_state = URB_DONE; 00864 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); 00865 } 00866 hhcd->hc[chnum].toggle_in ^= 1U; 00867 00868 } 00869 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) 00870 { 00871 __HAL_HCD_MASK_HALT_HC_INT(chnum); 00872 00873 if(hhcd->hc[chnum].state == HC_XFRC) 00874 { 00875 hhcd->hc[chnum].urb_state = URB_DONE; 00876 } 00877 00878 else if (hhcd->hc[chnum].state == HC_STALL) 00879 { 00880 hhcd->hc[chnum].urb_state = URB_STALL; 00881 } 00882 00883 else if((hhcd->hc[chnum].state == HC_XACTERR) || 00884 (hhcd->hc[chnum].state == HC_DATATGLERR)) 00885 { 00886 if(hhcd->hc[chnum].ErrCnt++ > 3U) 00887 { 00888 hhcd->hc[chnum].ErrCnt = 0U; 00889 hhcd->hc[chnum].urb_state = URB_ERROR; 00890 } 00891 else 00892 { 00893 hhcd->hc[chnum].urb_state = URB_NOTREADY; 00894 } 00895 00896 /* re-activate the channel */ 00897 tmpreg = USBx_HC(chnum)->HCCHAR; 00898 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 00899 tmpreg |= USB_OTG_HCCHAR_CHENA; 00900 USBx_HC(chnum)->HCCHAR = tmpreg; 00901 } 00902 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); 00903 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); 00904 } 00905 00906 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) 00907 { 00908 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00909 hhcd->hc[chnum].ErrCnt++; 00910 hhcd->hc[chnum].state = HC_XACTERR; 00911 USB_HC_Halt(hhcd->Instance, chnum); 00912 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR); 00913 } 00914 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK) 00915 { 00916 if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR) 00917 { 00918 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00919 USB_HC_Halt(hhcd->Instance, chnum); 00920 } 00921 00922 /* Clear the NAK flag before re-enabling the channel for new IN request */ 00923 hhcd->hc[chnum].state = HC_NAK; 00924 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); 00925 00926 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)|| 00927 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) 00928 { 00929 /* re-activate the channel */ 00930 tmpreg = USBx_HC(chnum)->HCCHAR; 00931 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 00932 tmpreg |= USB_OTG_HCCHAR_CHENA; 00933 USBx_HC(chnum)->HCCHAR = tmpreg; 00934 } 00935 } 00936 } 00937 00938 /** 00939 * @brief Handle Host Channel OUT interrupt requests. 00940 * @param hhcd HCD handle 00941 * @param chnum Channel number. 00942 * This parameter can be a value from 1 to 15 00943 * @retval None 00944 */ 00945 static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum) 00946 { 00947 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 00948 00949 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR) 00950 { 00951 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR); 00952 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00953 } 00954 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK) 00955 { 00956 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK); 00957 00958 if( hhcd->hc[chnum].do_ping == 1U) 00959 { 00960 hhcd->hc[chnum].state = HC_NYET; 00961 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00962 USB_HC_Halt(hhcd->Instance, chnum); 00963 hhcd->hc[chnum].urb_state = URB_NOTREADY; 00964 } 00965 } 00966 00967 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET) 00968 { 00969 hhcd->hc[chnum].state = HC_NYET; 00970 hhcd->hc[chnum].ErrCnt= 0U; 00971 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00972 USB_HC_Halt(hhcd->Instance, chnum); 00973 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET); 00974 00975 } 00976 00977 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR) 00978 { 00979 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00980 USB_HC_Halt(hhcd->Instance, chnum); 00981 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR); 00982 } 00983 00984 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC) 00985 { 00986 hhcd->hc[chnum].ErrCnt = 0U; 00987 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00988 USB_HC_Halt(hhcd->Instance, chnum); 00989 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC); 00990 hhcd->hc[chnum].state = HC_XFRC; 00991 00992 } 00993 00994 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL) 00995 { 00996 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL); 00997 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 00998 USB_HC_Halt(hhcd->Instance, chnum); 00999 hhcd->hc[chnum].state = HC_STALL; 01000 } 01001 01002 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK) 01003 { 01004 hhcd->hc[chnum].ErrCnt = 0U; 01005 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 01006 USB_HC_Halt(hhcd->Instance, chnum); 01007 hhcd->hc[chnum].state = HC_NAK; 01008 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); 01009 } 01010 01011 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) 01012 { 01013 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 01014 USB_HC_Halt(hhcd->Instance, chnum); 01015 hhcd->hc[chnum].state = HC_XACTERR; 01016 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR); 01017 } 01018 01019 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR) 01020 { 01021 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 01022 USB_HC_Halt(hhcd->Instance, chnum); 01023 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); 01024 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR); 01025 hhcd->hc[chnum].state = HC_DATATGLERR; 01026 } 01027 01028 01029 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) 01030 { 01031 __HAL_HCD_MASK_HALT_HC_INT(chnum); 01032 01033 if(hhcd->hc[chnum].state == HC_XFRC) 01034 { 01035 hhcd->hc[chnum].urb_state = URB_DONE; 01036 if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK) 01037 { 01038 hhcd->hc[chnum].toggle_out ^= 1U; 01039 } 01040 } 01041 else if (hhcd->hc[chnum].state == HC_NAK) 01042 { 01043 hhcd->hc[chnum].urb_state = URB_NOTREADY; 01044 } 01045 01046 else if (hhcd->hc[chnum].state == HC_NYET) 01047 { 01048 hhcd->hc[chnum].urb_state = URB_NOTREADY; 01049 hhcd->hc[chnum].do_ping = 0U; 01050 } 01051 01052 else if (hhcd->hc[chnum].state == HC_STALL) 01053 { 01054 hhcd->hc[chnum].urb_state = URB_STALL; 01055 } 01056 01057 else if((hhcd->hc[chnum].state == HC_XACTERR) || 01058 (hhcd->hc[chnum].state == HC_DATATGLERR)) 01059 { 01060 if(hhcd->hc[chnum].ErrCnt++ > 3U) 01061 { 01062 hhcd->hc[chnum].ErrCnt = 0U; 01063 hhcd->hc[chnum].urb_state = URB_ERROR; 01064 } 01065 else 01066 { 01067 hhcd->hc[chnum].urb_state = URB_NOTREADY; 01068 } 01069 } 01070 01071 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); 01072 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); 01073 } 01074 } 01075 01076 /** 01077 * @brief Handle Rx Queue Level interrupt requests. 01078 * @param hhcd HCD handle 01079 * @retval None 01080 */ 01081 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd) 01082 { 01083 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01084 uint8_t channelnum = 0; 01085 uint32_t pktsts; 01086 uint32_t pktcnt; 01087 uint32_t temp = 0U; 01088 uint32_t tmpreg = 0U; 01089 01090 temp = hhcd->Instance->GRXSTSP; 01091 channelnum = temp & USB_OTG_GRXSTSP_EPNUM; 01092 pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U; 01093 pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4U; 01094 01095 switch (pktsts) 01096 { 01097 case GRXSTS_PKTSTS_IN: 01098 /* Read the data into the host buffer. */ 01099 if ((pktcnt > 0U) && (hhcd->hc[channelnum].xfer_buff != (void *)0)) 01100 { 01101 01102 USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt); 01103 01104 /*manage multiple Xfer */ 01105 hhcd->hc[channelnum].xfer_buff += pktcnt; 01106 hhcd->hc[channelnum].xfer_count += pktcnt; 01107 01108 if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0) 01109 { 01110 /* re-activate the channel when more packets are expected */ 01111 tmpreg = USBx_HC(channelnum)->HCCHAR; 01112 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01113 tmpreg |= USB_OTG_HCCHAR_CHENA; 01114 USBx_HC(channelnum)->HCCHAR = tmpreg; 01115 hhcd->hc[channelnum].toggle_in ^= 1; 01116 } 01117 } 01118 break; 01119 01120 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: 01121 break; 01122 case GRXSTS_PKTSTS_IN_XFER_COMP: 01123 case GRXSTS_PKTSTS_CH_HALTED: 01124 default: 01125 break; 01126 } 01127 } 01128 01129 /** 01130 * @brief Handle Host Port interrupt requests. 01131 * @param hhcd HCD handle 01132 * @retval None 01133 */ 01134 static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd) 01135 { 01136 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; 01137 __IO uint32_t hprt0, hprt0_dup; 01138 01139 /* Handle Host Port Interrupts */ 01140 hprt0 = USBx_HPRT0; 01141 hprt0_dup = USBx_HPRT0; 01142 01143 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ 01144 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); 01145 01146 /* Check whether Port Connect Detected */ 01147 if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) 01148 { 01149 if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) 01150 { 01151 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); 01152 HAL_HCD_Connect_Callback(hhcd); 01153 } 01154 hprt0_dup |= USB_OTG_HPRT_PCDET; 01155 01156 } 01157 01158 /* Check whether Port Enable Changed */ 01159 if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) 01160 { 01161 hprt0_dup |= USB_OTG_HPRT_PENCHNG; 01162 01163 if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) 01164 { 01165 if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY) 01166 { 01167 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17U)) 01168 { 01169 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ ); 01170 } 01171 else 01172 { 01173 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); 01174 } 01175 } 01176 else 01177 { 01178 if(hhcd->Init.speed == HCD_SPEED_FULL) 01179 { 01180 USBx_HOST->HFIR = 60000U; 01181 } 01182 } 01183 01184 HAL_HCD_Connect_Callback(hhcd); 01185 } 01186 else 01187 { 01188 /* Clean up HPRT */ 01189 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ 01190 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); 01191 01192 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); 01193 } 01194 } 01195 01196 /* Check for an over current */ 01197 if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) 01198 { 01199 hprt0_dup |= USB_OTG_HPRT_POCCHNG; 01200 } 01201 01202 /* Clear Port Interrupts */ 01203 USBx_HPRT0 = hprt0_dup; 01204 } 01205 01206 /** 01207 * @} 01208 */ 01209 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || 01210 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx || 01211 STM32F412Vx || STM32F412Cx || defined(STM32F413xx) || defined(STM32F423xx) */ 01212 #endif /* HAL_HCD_MODULE_ENABLED */ 01213 /** 01214 * @} 01215 */ 01216 01217 /** 01218 * @} 01219 */ 01220 01221 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/