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.
Fork of TUKS-COURSE-TIMER by
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 17:38:49 by
