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