STM32F439xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_pcd.c 00004 * @author MCD Application Team 00005 * @brief PCD 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 The PCD HAL driver can be used as follows: 00019 00020 (#) Declare a PCD_HandleTypeDef handle structure, for example: 00021 PCD_HandleTypeDef hpcd; 00022 00023 (#) Fill parameters of Init structure in HCD handle 00024 00025 (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) 00026 00027 (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: 00028 (##) Enable the PCD/USB Low Level interface clock using 00029 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); 00030 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode) 00031 00032 (##) Initialize the related GPIO clocks 00033 (##) Configure PCD pin-out 00034 (##) Configure PCD NVIC interrupt 00035 00036 (#)Associate the Upper USB device stack to the HAL PCD Driver: 00037 (##) hpcd.pData = pdev; 00038 00039 (#)Enable PCD transmission and reception: 00040 (##) HAL_PCD_Start(); 00041 00042 @endverbatim 00043 ****************************************************************************** 00044 * @attention 00045 * 00046 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00047 * 00048 * Redistribution and use in source and binary forms, with or without modification, 00049 * are permitted provided that the following conditions are met: 00050 * 1. Redistributions of source code must retain the above copyright notice, 00051 * this list of conditions and the following disclaimer. 00052 * 2. Redistributions in binary form must reproduce the above copyright notice, 00053 * this list of conditions and the following disclaimer in the documentation 00054 * and/or other materials provided with the distribution. 00055 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00056 * may be used to endorse or promote products derived from this software 00057 * without specific prior written permission. 00058 * 00059 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00060 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00061 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00062 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00063 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00064 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00065 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00066 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00067 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00068 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00069 * 00070 ****************************************************************************** 00071 */ 00072 00073 /* Includes ------------------------------------------------------------------*/ 00074 #include "stm32f4xx_hal.h" 00075 00076 /** @addtogroup STM32F4xx_HAL_Driver 00077 * @{ 00078 */ 00079 00080 /** @defgroup PCD PCD 00081 * @brief PCD HAL module driver 00082 * @{ 00083 */ 00084 00085 #ifdef HAL_PCD_MODULE_ENABLED 00086 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \ 00087 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ 00088 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \ 00089 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \ 00090 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 00091 /* Private types -------------------------------------------------------------*/ 00092 /* Private variables ---------------------------------------------------------*/ 00093 /* Private constants ---------------------------------------------------------*/ 00094 /* Private macros ------------------------------------------------------------*/ 00095 /** @defgroup PCD_Private_Macros PCD Private Macros 00096 * @{ 00097 */ 00098 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) 00099 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) 00100 /** 00101 * @} 00102 */ 00103 00104 /* Private functions prototypes ----------------------------------------------*/ 00105 /** @defgroup PCD_Private_Functions PCD Private Functions 00106 * @{ 00107 */ 00108 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00109 /** 00110 * @} 00111 */ 00112 00113 /* Exported functions --------------------------------------------------------*/ 00114 /** @defgroup PCD_Exported_Functions PCD Exported Functions 00115 * @{ 00116 */ 00117 00118 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions 00119 * @brief Initialization and Configuration functions 00120 * 00121 @verbatim 00122 =============================================================================== 00123 ##### Initialization and de-initialization functions ##### 00124 =============================================================================== 00125 [..] This section provides functions allowing to: 00126 00127 @endverbatim 00128 * @{ 00129 */ 00130 00131 /** 00132 * @brief Initializes the PCD according to the specified 00133 * parameters in the PCD_InitTypeDef and initialize the associated handle. 00134 * @param hpcd PCD handle 00135 * @retval HAL status 00136 */ 00137 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) 00138 { 00139 uint32_t i = 0U; 00140 00141 /* Check the PCD handle allocation */ 00142 if(hpcd == NULL) 00143 { 00144 return HAL_ERROR; 00145 } 00146 00147 /* Check the parameters */ 00148 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); 00149 00150 hpcd->State = HAL_PCD_STATE_BUSY; 00151 00152 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ 00153 HAL_PCD_MspInit(hpcd); 00154 00155 /* Disable the Interrupts */ 00156 __HAL_PCD_DISABLE(hpcd); 00157 00158 /*Init the Core (common init.) */ 00159 USB_CoreInit(hpcd->Instance, hpcd->Init); 00160 00161 /* Force Device Mode*/ 00162 USB_SetCurrentMode(hpcd->Instance , USB_OTG_DEVICE_MODE); 00163 00164 /* Init endpoints structures */ 00165 for (i = 0U; i < 15U; i++) 00166 { 00167 /* Init ep structure */ 00168 hpcd->IN_ep[i].is_in = 1U; 00169 hpcd->IN_ep[i].num = i; 00170 hpcd->IN_ep[i].tx_fifo_num = i; 00171 /* Control until ep is activated */ 00172 hpcd->IN_ep[i].type = EP_TYPE_CTRL; 00173 hpcd->IN_ep[i].maxpacket = 0U; 00174 hpcd->IN_ep[i].xfer_buff = 0U; 00175 hpcd->IN_ep[i].xfer_len = 0U; 00176 } 00177 00178 for (i = 0U; i < 15U; i++) 00179 { 00180 hpcd->OUT_ep[i].is_in = 0U; 00181 hpcd->OUT_ep[i].num = i; 00182 hpcd->IN_ep[i].tx_fifo_num = i; 00183 /* Control until ep is activated */ 00184 hpcd->OUT_ep[i].type = EP_TYPE_CTRL; 00185 hpcd->OUT_ep[i].maxpacket = 0U; 00186 hpcd->OUT_ep[i].xfer_buff = 0U; 00187 hpcd->OUT_ep[i].xfer_len = 0U; 00188 00189 hpcd->Instance->DIEPTXF[i] = 0U; 00190 } 00191 00192 /* Init Device */ 00193 USB_DevInit(hpcd->Instance, hpcd->Init); 00194 00195 hpcd->State= HAL_PCD_STATE_READY; 00196 00197 #ifdef USB_OTG_GLPMCFG_LPMEN 00198 /* Activate LPM */ 00199 if (hpcd->Init.lpm_enable == 1U) 00200 { 00201 HAL_PCDEx_ActivateLPM(hpcd); 00202 } 00203 #endif /* USB_OTG_GLPMCFG_LPMEN */ 00204 00205 #ifdef USB_OTG_GCCFG_BCDEN 00206 /* Activate Battery charging */ 00207 if (hpcd->Init.battery_charging_enable == 1U) 00208 { 00209 HAL_PCDEx_ActivateBCD(hpcd); 00210 } 00211 #endif /* USB_OTG_GCCFG_BCDEN */ 00212 00213 USB_DevDisconnect (hpcd->Instance); 00214 return HAL_OK; 00215 } 00216 00217 /** 00218 * @brief DeInitializes the PCD peripheral. 00219 * @param hpcd PCD handle 00220 * @retval HAL status 00221 */ 00222 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) 00223 { 00224 /* Check the PCD handle allocation */ 00225 if(hpcd == NULL) 00226 { 00227 return HAL_ERROR; 00228 } 00229 00230 hpcd->State = HAL_PCD_STATE_BUSY; 00231 00232 /* Stop Device */ 00233 HAL_PCD_Stop(hpcd); 00234 00235 /* DeInit the low level hardware */ 00236 HAL_PCD_MspDeInit(hpcd); 00237 00238 hpcd->State = HAL_PCD_STATE_RESET; 00239 00240 return HAL_OK; 00241 } 00242 00243 /** 00244 * @brief Initializes the PCD MSP. 00245 * @param hpcd PCD handle 00246 * @retval None 00247 */ 00248 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) 00249 { 00250 /* Prevent unused argument(s) compilation warning */ 00251 UNUSED(hpcd); 00252 /* NOTE : This function Should not be modified, when the callback is needed, 00253 the HAL_PCD_MspInit could be implemented in the user file 00254 */ 00255 } 00256 00257 /** 00258 * @brief DeInitializes PCD MSP. 00259 * @param hpcd PCD handle 00260 * @retval None 00261 */ 00262 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) 00263 { 00264 /* Prevent unused argument(s) compilation warning */ 00265 UNUSED(hpcd); 00266 /* NOTE : This function Should not be modified, when the callback is needed, 00267 the HAL_PCD_MspDeInit could be implemented in the user file 00268 */ 00269 } 00270 00271 /** 00272 * @} 00273 */ 00274 00275 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions 00276 * @brief Data transfers functions 00277 * 00278 @verbatim 00279 =============================================================================== 00280 ##### IO operation functions ##### 00281 =============================================================================== 00282 [..] 00283 This subsection provides a set of functions allowing to manage the PCD data 00284 transfers. 00285 00286 @endverbatim 00287 * @{ 00288 */ 00289 00290 /** 00291 * @brief Start The USB OTG Device. 00292 * @param hpcd PCD handle 00293 * @retval HAL status 00294 */ 00295 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) 00296 { 00297 __HAL_LOCK(hpcd); 00298 USB_DevConnect (hpcd->Instance); 00299 __HAL_PCD_ENABLE(hpcd); 00300 __HAL_UNLOCK(hpcd); 00301 return HAL_OK; 00302 } 00303 00304 /** 00305 * @brief Stop The USB OTG Device. 00306 * @param hpcd PCD handle 00307 * @retval HAL status 00308 */ 00309 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) 00310 { 00311 __HAL_LOCK(hpcd); 00312 __HAL_PCD_DISABLE(hpcd); 00313 USB_StopDevice(hpcd->Instance); 00314 USB_DevDisconnect(hpcd->Instance); 00315 __HAL_UNLOCK(hpcd); 00316 return HAL_OK; 00317 } 00318 00319 /** 00320 * @brief Handles PCD interrupt request. 00321 * @param hpcd PCD handle 00322 * @retval HAL status 00323 */ 00324 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) 00325 { 00326 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 00327 uint32_t i = 0U, ep_intr = 0U, epint = 0U, epnum = 0U; 00328 uint32_t fifoemptymsk = 0U, temp = 0U; 00329 USB_OTG_EPTypeDef *ep; 00330 uint32_t hclk = 180000000U; 00331 00332 /* ensure that we are in device mode */ 00333 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) 00334 { 00335 /* avoid spurious interrupt */ 00336 if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) 00337 { 00338 return; 00339 } 00340 00341 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) 00342 { 00343 /* incorrect mode, acknowledge the interrupt */ 00344 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); 00345 } 00346 00347 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) 00348 { 00349 epnum = 0U; 00350 00351 /* Read in the device interrupt bits */ 00352 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); 00353 00354 while ( ep_intr ) 00355 { 00356 if (ep_intr & 0x1U) 00357 { 00358 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum); 00359 00360 if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) 00361 { 00362 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); 00363 00364 if(hpcd->Init.dma_enable == 1U) 00365 { 00366 hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); 00367 hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; 00368 } 00369 00370 HAL_PCD_DataOutStageCallback(hpcd, epnum); 00371 if(hpcd->Init.dma_enable == 1U) 00372 { 00373 if((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U)) 00374 { 00375 /* this is ZLP, so prepare EP0 for next setup */ 00376 USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 00377 } 00378 } 00379 } 00380 00381 if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) 00382 { 00383 /* Inform the upper layer that a setup packet is available */ 00384 HAL_PCD_SetupStageCallback(hpcd); 00385 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); 00386 } 00387 00388 if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) 00389 { 00390 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); 00391 } 00392 00393 #ifdef USB_OTG_DOEPINT_OTEPSPR 00394 /* Clear Status Phase Received interrupt */ 00395 if(( epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) 00396 { 00397 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 00398 } 00399 #endif /* USB_OTG_DOEPINT_OTEPSPR */ 00400 } 00401 epnum++; 00402 ep_intr >>= 1U; 00403 } 00404 } 00405 00406 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) 00407 { 00408 /* Read in the device interrupt bits */ 00409 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); 00410 00411 epnum = 0U; 00412 00413 while ( ep_intr ) 00414 { 00415 if (ep_intr & 0x1U) /* In ITR */ 00416 { 00417 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum); 00418 00419 if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) 00420 { 00421 fifoemptymsk = 0x1U << epnum; 00422 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 00423 00424 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); 00425 00426 if (hpcd->Init.dma_enable == 1U) 00427 { 00428 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; 00429 } 00430 00431 HAL_PCD_DataInStageCallback(hpcd, epnum); 00432 00433 if (hpcd->Init.dma_enable == 1U) 00434 { 00435 /* this is ZLP, so prepare EP0 for next setup */ 00436 if((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U)) 00437 { 00438 /* prepare to rx more setup packets */ 00439 USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 00440 } 00441 } 00442 } 00443 if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) 00444 { 00445 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); 00446 } 00447 if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) 00448 { 00449 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); 00450 } 00451 if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) 00452 { 00453 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); 00454 } 00455 if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) 00456 { 00457 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); 00458 } 00459 if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) 00460 { 00461 PCD_WriteEmptyTxFifo(hpcd , epnum); 00462 } 00463 } 00464 epnum++; 00465 ep_intr >>= 1U; 00466 } 00467 } 00468 00469 /* Handle Resume Interrupt */ 00470 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) 00471 { 00472 /* Clear the Remote Wake-up Signaling */ 00473 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 00474 00475 #ifdef USB_OTG_GLPMCFG_LPMEN 00476 if(hpcd->LPM_State == LPM_L1) 00477 { 00478 hpcd->LPM_State = LPM_L0; 00479 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); 00480 } 00481 else 00482 #endif /* USB_OTG_GLPMCFG_LPMEN */ 00483 { 00484 HAL_PCD_ResumeCallback(hpcd); 00485 } 00486 00487 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); 00488 } 00489 00490 /* Handle Suspend Interrupt */ 00491 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) 00492 { 00493 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) 00494 { 00495 00496 HAL_PCD_SuspendCallback(hpcd); 00497 } 00498 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); 00499 } 00500 00501 #ifdef USB_OTG_GLPMCFG_LPMEN 00502 /* Handle LPM Interrupt */ 00503 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) 00504 { 00505 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); 00506 if( hpcd->LPM_State == LPM_L0) 00507 { 00508 hpcd->LPM_State = LPM_L1; 00509 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U; 00510 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); 00511 } 00512 else 00513 { 00514 HAL_PCD_SuspendCallback(hpcd); 00515 } 00516 } 00517 #endif /* USB_OTG_GLPMCFG_LPMEN */ 00518 00519 /* Handle Reset Interrupt */ 00520 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) 00521 { 00522 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 00523 USB_FlushTxFifo(hpcd->Instance , 0x10U); 00524 00525 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 00526 { 00527 USBx_INEP(i)->DIEPINT = 0xFFU; 00528 USBx_OUTEP(i)->DOEPINT = 0xFFU; 00529 } 00530 USBx_DEVICE->DAINT = 0xFFFFFFFFU; 00531 USBx_DEVICE->DAINTMSK |= 0x10001U; 00532 00533 if(hpcd->Init.use_dedicated_ep1) 00534 { 00535 USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); 00536 USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); 00537 } 00538 else 00539 { 00540 #ifdef USB_OTG_DOEPINT_OTEPSPR 00541 USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_OTEPSPRM); 00542 #else 00543 USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); 00544 #endif /* USB_OTG_DOEPINT_OTEPSPR */ 00545 USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); 00546 } 00547 00548 /* Set Default Address to 0 */ 00549 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; 00550 00551 /* setup EP0 to receive SETUP packets */ 00552 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); 00553 00554 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); 00555 } 00556 00557 /* Handle Enumeration done Interrupt */ 00558 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) 00559 { 00560 USB_ActivateSetup(hpcd->Instance); 00561 hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; 00562 00563 if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH) 00564 { 00565 hpcd->Init.speed = USB_OTG_SPEED_HIGH; 00566 hpcd->Init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE ; 00567 hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_HS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT); 00568 } 00569 else 00570 { 00571 hpcd->Init.speed = USB_OTG_SPEED_FULL; 00572 hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ; 00573 00574 /* The USBTRD is configured according to the tables below, depending on AHB frequency 00575 used by application. In the low AHB frequency range it is used to stretch enough the USB response 00576 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access 00577 latency to the Data FIFO */ 00578 00579 /* Get hclk frequency value */ 00580 hclk = HAL_RCC_GetHCLKFreq(); 00581 00582 if((hclk >= 14200000U)&&(hclk < 15000000U)) 00583 { 00584 /* hclk Clock Range between 14.2-15 MHz */ 00585 hpcd->Instance->GUSBCFG |= (uint32_t)((0xFU << 10U) & USB_OTG_GUSBCFG_TRDT); 00586 } 00587 00588 else if((hclk >= 15000000U)&&(hclk < 16000000U)) 00589 { 00590 /* hclk Clock Range between 15-16 MHz */ 00591 hpcd->Instance->GUSBCFG |= (uint32_t)((0xEU << 10U) & USB_OTG_GUSBCFG_TRDT); 00592 } 00593 00594 else if((hclk >= 16000000U)&&(hclk < 17200000U)) 00595 { 00596 /* hclk Clock Range between 16-17.2 MHz */ 00597 hpcd->Instance->GUSBCFG |= (uint32_t)((0xDU << 10U) & USB_OTG_GUSBCFG_TRDT); 00598 } 00599 00600 else if((hclk >= 17200000U)&&(hclk < 18500000U)) 00601 { 00602 /* hclk Clock Range between 17.2-18.5 MHz */ 00603 hpcd->Instance->GUSBCFG |= (uint32_t)((0xCU << 10U) & USB_OTG_GUSBCFG_TRDT); 00604 } 00605 00606 else if((hclk >= 18500000U)&&(hclk < 20000000U)) 00607 { 00608 /* hclk Clock Range between 18.5-20 MHz */ 00609 hpcd->Instance->GUSBCFG |= (uint32_t)((0xBU << 10U) & USB_OTG_GUSBCFG_TRDT); 00610 } 00611 00612 else if((hclk >= 20000000U)&&(hclk < 21800000U)) 00613 { 00614 /* hclk Clock Range between 20-21.8 MHz */ 00615 hpcd->Instance->GUSBCFG |= (uint32_t)((0xAU << 10U) & USB_OTG_GUSBCFG_TRDT); 00616 } 00617 00618 else if((hclk >= 21800000U)&&(hclk < 24000000U)) 00619 { 00620 /* hclk Clock Range between 21.8-24 MHz */ 00621 hpcd->Instance->GUSBCFG |= (uint32_t)((0x9U << 10U) & USB_OTG_GUSBCFG_TRDT); 00622 } 00623 00624 else if((hclk >= 24000000U)&&(hclk < 27700000U)) 00625 { 00626 /* hclk Clock Range between 24-27.7 MHz */ 00627 hpcd->Instance->GUSBCFG |= (uint32_t)((0x8U << 10U) & USB_OTG_GUSBCFG_TRDT); 00628 } 00629 00630 else if((hclk >= 27700000U)&&(hclk < 32000000U)) 00631 { 00632 /* hclk Clock Range between 27.7-32 MHz */ 00633 hpcd->Instance->GUSBCFG |= (uint32_t)((0x7U << 10U) & USB_OTG_GUSBCFG_TRDT); 00634 } 00635 00636 else /* if(hclk >= 32000000) */ 00637 { 00638 /* hclk Clock Range between 32-180 MHz */ 00639 hpcd->Instance->GUSBCFG |= (uint32_t)((0x6U << 10U) & USB_OTG_GUSBCFG_TRDT); 00640 } 00641 } 00642 00643 HAL_PCD_ResetCallback(hpcd); 00644 00645 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); 00646 } 00647 00648 /* Handle RxQLevel Interrupt */ 00649 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL)) 00650 { 00651 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00652 00653 temp = USBx->GRXSTSP; 00654 00655 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM]; 00656 00657 if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_DATA_UPDT) 00658 { 00659 if((temp & USB_OTG_GRXSTSP_BCNT) != 0U) 00660 { 00661 USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U); 00662 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U; 00663 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U; 00664 } 00665 } 00666 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_SETUP_UPDT) 00667 { 00668 USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U); 00669 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U; 00670 } 00671 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00672 } 00673 00674 /* Handle SOF Interrupt */ 00675 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) 00676 { 00677 HAL_PCD_SOFCallback(hpcd); 00678 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); 00679 } 00680 00681 /* Handle Incomplete ISO IN Interrupt */ 00682 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) 00683 { 00684 HAL_PCD_ISOINIncompleteCallback(hpcd, epnum); 00685 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); 00686 } 00687 00688 /* Handle Incomplete ISO OUT Interrupt */ 00689 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) 00690 { 00691 HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum); 00692 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); 00693 } 00694 00695 /* Handle Connection event Interrupt */ 00696 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) 00697 { 00698 HAL_PCD_ConnectCallback(hpcd); 00699 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); 00700 } 00701 00702 /* Handle Disconnection event Interrupt */ 00703 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) 00704 { 00705 temp = hpcd->Instance->GOTGINT; 00706 00707 if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) 00708 { 00709 HAL_PCD_DisconnectCallback(hpcd); 00710 } 00711 hpcd->Instance->GOTGINT |= temp; 00712 } 00713 } 00714 } 00715 00716 /** 00717 * @brief Data OUT stage callback. 00718 * @param hpcd PCD handle 00719 * @param epnum endpoint number 00720 * @retval None 00721 */ 00722 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00723 { 00724 /* Prevent unused argument(s) compilation warning */ 00725 UNUSED(hpcd); 00726 UNUSED(epnum); 00727 /* NOTE : This function Should not be modified, when the callback is needed, 00728 the HAL_PCD_DataOutStageCallback could be implemented in the user file 00729 */ 00730 } 00731 00732 /** 00733 * @brief Data IN stage callback. 00734 * @param hpcd PCD handle 00735 * @param epnum endpoint number 00736 * @retval None 00737 */ 00738 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00739 { 00740 /* Prevent unused argument(s) compilation warning */ 00741 UNUSED(hpcd); 00742 UNUSED(epnum); 00743 /* NOTE : This function Should not be modified, when the callback is needed, 00744 the HAL_PCD_DataInStageCallback could be implemented in the user file 00745 */ 00746 } 00747 /** 00748 * @brief Setup stage callback. 00749 * @param hpcd PCD handle 00750 * @retval None 00751 */ 00752 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) 00753 { 00754 /* Prevent unused argument(s) compilation warning */ 00755 UNUSED(hpcd); 00756 /* NOTE : This function Should not be modified, when the callback is needed, 00757 the HAL_PCD_SetupStageCallback could be implemented in the user file 00758 */ 00759 } 00760 00761 /** 00762 * @brief USB Start Of Frame callback. 00763 * @param hpcd PCD handle 00764 * @retval None 00765 */ 00766 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) 00767 { 00768 /* Prevent unused argument(s) compilation warning */ 00769 UNUSED(hpcd); 00770 /* NOTE : This function Should not be modified, when the callback is needed, 00771 the HAL_PCD_SOFCallback could be implemented in the user file 00772 */ 00773 } 00774 00775 /** 00776 * @brief USB Reset callback. 00777 * @param hpcd PCD handle 00778 * @retval None 00779 */ 00780 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) 00781 { 00782 /* Prevent unused argument(s) compilation warning */ 00783 UNUSED(hpcd); 00784 /* NOTE : This function Should not be modified, when the callback is needed, 00785 the HAL_PCD_ResetCallback could be implemented in the user file 00786 */ 00787 } 00788 00789 /** 00790 * @brief Suspend event callback. 00791 * @param hpcd PCD handle 00792 * @retval None 00793 */ 00794 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) 00795 { 00796 /* Prevent unused argument(s) compilation warning */ 00797 UNUSED(hpcd); 00798 /* NOTE : This function Should not be modified, when the callback is needed, 00799 the HAL_PCD_SuspendCallback could be implemented in the user file 00800 */ 00801 } 00802 00803 /** 00804 * @brief Resume event callback. 00805 * @param hpcd PCD handle 00806 * @retval None 00807 */ 00808 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) 00809 { 00810 /* Prevent unused argument(s) compilation warning */ 00811 UNUSED(hpcd); 00812 /* NOTE : This function Should not be modified, when the callback is needed, 00813 the HAL_PCD_ResumeCallback could be implemented in the user file 00814 */ 00815 } 00816 00817 /** 00818 * @brief Incomplete ISO OUT callback. 00819 * @param hpcd PCD handle 00820 * @param epnum endpoint number 00821 * @retval None 00822 */ 00823 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00824 { 00825 /* Prevent unused argument(s) compilation warning */ 00826 UNUSED(hpcd); 00827 UNUSED(epnum); 00828 /* NOTE : This function Should not be modified, when the callback is needed, 00829 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file 00830 */ 00831 } 00832 00833 /** 00834 * @brief Incomplete ISO IN callback. 00835 * @param hpcd PCD handle 00836 * @param epnum endpoint number 00837 * @retval None 00838 */ 00839 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00840 { 00841 /* Prevent unused argument(s) compilation warning */ 00842 UNUSED(hpcd); 00843 UNUSED(epnum); 00844 /* NOTE : This function Should not be modified, when the callback is needed, 00845 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file 00846 */ 00847 } 00848 00849 /** 00850 * @brief Connection event callback. 00851 * @param hpcd PCD handle 00852 * @retval None 00853 */ 00854 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) 00855 { 00856 /* Prevent unused argument(s) compilation warning */ 00857 UNUSED(hpcd); 00858 /* NOTE : This function Should not be modified, when the callback is needed, 00859 the HAL_PCD_ConnectCallback could be implemented in the user file 00860 */ 00861 } 00862 00863 /** 00864 * @brief Disconnection event callback. 00865 * @param hpcd PCD handle 00866 * @retval None 00867 */ 00868 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) 00869 { 00870 /* Prevent unused argument(s) compilation warning */ 00871 UNUSED(hpcd); 00872 /* NOTE : This function Should not be modified, when the callback is needed, 00873 the HAL_PCD_DisconnectCallback could be implemented in the user file 00874 */ 00875 } 00876 00877 /** 00878 * @} 00879 */ 00880 00881 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions 00882 * @brief management functions 00883 * 00884 @verbatim 00885 =============================================================================== 00886 ##### Peripheral Control functions ##### 00887 =============================================================================== 00888 [..] 00889 This subsection provides a set of functions allowing to control the PCD data 00890 transfers. 00891 00892 @endverbatim 00893 * @{ 00894 */ 00895 00896 /** 00897 * @brief Connect the USB device. 00898 * @param hpcd PCD handle 00899 * @retval HAL status 00900 */ 00901 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) 00902 { 00903 __HAL_LOCK(hpcd); 00904 USB_DevConnect(hpcd->Instance); 00905 __HAL_UNLOCK(hpcd); 00906 return HAL_OK; 00907 } 00908 00909 /** 00910 * @brief Disconnect the USB device. 00911 * @param hpcd PCD handle 00912 * @retval HAL status 00913 */ 00914 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) 00915 { 00916 __HAL_LOCK(hpcd); 00917 USB_DevDisconnect(hpcd->Instance); 00918 __HAL_UNLOCK(hpcd); 00919 return HAL_OK; 00920 } 00921 00922 /** 00923 * @brief Set the USB Device address. 00924 * @param hpcd PCD handle 00925 * @param address new device address 00926 * @retval HAL status 00927 */ 00928 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) 00929 { 00930 __HAL_LOCK(hpcd); 00931 USB_SetDevAddress(hpcd->Instance, address); 00932 __HAL_UNLOCK(hpcd); 00933 return HAL_OK; 00934 } 00935 /** 00936 * @brief Open and configure an endpoint. 00937 * @param hpcd PCD handle 00938 * @param ep_addr endpoint address 00939 * @param ep_mps endpoint max packet size 00940 * @param ep_type endpoint type 00941 * @retval HAL status 00942 */ 00943 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) 00944 { 00945 HAL_StatusTypeDef ret = HAL_OK; 00946 USB_OTG_EPTypeDef *ep; 00947 00948 if ((ep_addr & 0x80) == 0x80) 00949 { 00950 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 00951 } 00952 else 00953 { 00954 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; 00955 } 00956 ep->num = ep_addr & 0x7F; 00957 00958 ep->is_in = (0x80 & ep_addr) != 0; 00959 ep->maxpacket = ep_mps; 00960 ep->type = ep_type; 00961 if (ep->is_in) 00962 { 00963 /* Assign a Tx FIFO */ 00964 ep->tx_fifo_num = ep->num; 00965 } 00966 /* Set initial data PID. */ 00967 if (ep_type == EP_TYPE_BULK ) 00968 { 00969 ep->data_pid_start = 0U; 00970 } 00971 00972 __HAL_LOCK(hpcd); 00973 USB_ActivateEndpoint(hpcd->Instance , ep); 00974 __HAL_UNLOCK(hpcd); 00975 return ret; 00976 } 00977 00978 00979 /** 00980 * @brief Deactivate an endpoint. 00981 * @param hpcd PCD handle 00982 * @param ep_addr endpoint address 00983 * @retval HAL status 00984 */ 00985 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 00986 { 00987 USB_OTG_EPTypeDef *ep; 00988 00989 if ((ep_addr & 0x80) == 0x80) 00990 { 00991 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 00992 } 00993 else 00994 { 00995 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; 00996 } 00997 ep->num = ep_addr & 0x7F; 00998 00999 ep->is_in = (0x80 & ep_addr) != 0; 01000 01001 __HAL_LOCK(hpcd); 01002 USB_DeactivateEndpoint(hpcd->Instance , ep); 01003 __HAL_UNLOCK(hpcd); 01004 return HAL_OK; 01005 } 01006 01007 01008 /** 01009 * @brief Receive an amount of data. 01010 * @param hpcd PCD handle 01011 * @param ep_addr endpoint address 01012 * @param pBuf pointer to the reception buffer 01013 * @param len amount of data to be received 01014 * @retval HAL status 01015 */ 01016 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01017 { 01018 USB_OTG_EPTypeDef *ep; 01019 01020 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; 01021 01022 /*setup and start the Xfer */ 01023 ep->xfer_buff = pBuf; 01024 ep->xfer_len = len; 01025 ep->xfer_count = 0U; 01026 ep->is_in = 0U; 01027 ep->num = ep_addr & 0x7F; 01028 01029 if (hpcd->Init.dma_enable == 1U) 01030 { 01031 ep->dma_addr = (uint32_t)pBuf; 01032 } 01033 01034 if ((ep_addr & 0x7F) == 0) 01035 { 01036 USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); 01037 } 01038 else 01039 { 01040 USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); 01041 } 01042 01043 return HAL_OK; 01044 } 01045 01046 /** 01047 * @brief Get Received Data Size. 01048 * @param hpcd PCD handle 01049 * @param ep_addr endpoint address 01050 * @retval Data Size 01051 */ 01052 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01053 { 01054 return hpcd->OUT_ep[ep_addr & 0xF].xfer_count; 01055 } 01056 /** 01057 * @brief Send an amount of data. 01058 * @param hpcd PCD handle 01059 * @param ep_addr endpoint address 01060 * @param pBuf pointer to the transmission buffer 01061 * @param len amount of data to be sent 01062 * @retval HAL status 01063 */ 01064 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01065 { 01066 USB_OTG_EPTypeDef *ep; 01067 01068 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01069 01070 /*setup and start the Xfer */ 01071 ep->xfer_buff = pBuf; 01072 ep->xfer_len = len; 01073 ep->xfer_count = 0U; 01074 ep->is_in = 1U; 01075 ep->num = ep_addr & 0x7F; 01076 01077 if (hpcd->Init.dma_enable == 1U) 01078 { 01079 ep->dma_addr = (uint32_t)pBuf; 01080 } 01081 01082 if ((ep_addr & 0x7F) == 0) 01083 { 01084 USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); 01085 } 01086 else 01087 { 01088 USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); 01089 } 01090 01091 return HAL_OK; 01092 } 01093 01094 /** 01095 * @brief Set a STALL condition over an endpoint. 01096 * @param hpcd PCD handle 01097 * @param ep_addr endpoint address 01098 * @retval HAL status 01099 */ 01100 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01101 { 01102 USB_OTG_EPTypeDef *ep; 01103 01104 if ((0x80 & ep_addr) == 0x80) 01105 { 01106 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01107 } 01108 else 01109 { 01110 ep = &hpcd->OUT_ep[ep_addr]; 01111 } 01112 01113 ep->is_stall = 1U; 01114 ep->num = ep_addr & 0x7F; 01115 ep->is_in = ((ep_addr & 0x80) == 0x80); 01116 01117 01118 __HAL_LOCK(hpcd); 01119 USB_EPSetStall(hpcd->Instance , ep); 01120 if((ep_addr & 0x7F) == 0) 01121 { 01122 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); 01123 } 01124 __HAL_UNLOCK(hpcd); 01125 01126 return HAL_OK; 01127 } 01128 01129 /** 01130 * @brief Clear a STALL condition over in an endpoint. 01131 * @param hpcd PCD handle 01132 * @param ep_addr endpoint address 01133 * @retval HAL status 01134 */ 01135 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01136 { 01137 USB_OTG_EPTypeDef *ep; 01138 01139 if ((0x80 & ep_addr) == 0x80) 01140 { 01141 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01142 } 01143 else 01144 { 01145 ep = &hpcd->OUT_ep[ep_addr]; 01146 } 01147 01148 ep->is_stall = 0U; 01149 ep->num = ep_addr & 0x7F; 01150 ep->is_in = ((ep_addr & 0x80) == 0x80); 01151 01152 __HAL_LOCK(hpcd); 01153 USB_EPClearStall(hpcd->Instance , ep); 01154 __HAL_UNLOCK(hpcd); 01155 01156 return HAL_OK; 01157 } 01158 01159 /** 01160 * @brief Flush an endpoint. 01161 * @param hpcd PCD handle 01162 * @param ep_addr endpoint address 01163 * @retval HAL status 01164 */ 01165 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01166 { 01167 __HAL_LOCK(hpcd); 01168 01169 if ((ep_addr & 0x80) == 0x80) 01170 { 01171 USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F); 01172 } 01173 else 01174 { 01175 USB_FlushRxFifo(hpcd->Instance); 01176 } 01177 01178 __HAL_UNLOCK(hpcd); 01179 01180 return HAL_OK; 01181 } 01182 01183 /** 01184 * @brief Activate remote wakeup signalling. 01185 * @param hpcd PCD handle 01186 * @retval HAL status 01187 */ 01188 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 01189 { 01190 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01191 01192 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) 01193 { 01194 /* Activate Remote wakeup signaling */ 01195 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG; 01196 } 01197 return HAL_OK; 01198 } 01199 01200 /** 01201 * @brief De-activate remote wakeup signalling. 01202 * @param hpcd PCD handle 01203 * @retval HAL status 01204 */ 01205 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 01206 { 01207 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01208 01209 /* De-activate Remote wakeup signaling */ 01210 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG); 01211 return HAL_OK; 01212 } 01213 /** 01214 * @} 01215 */ 01216 01217 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions 01218 * @brief Peripheral State functions 01219 * 01220 @verbatim 01221 =============================================================================== 01222 ##### Peripheral State functions ##### 01223 =============================================================================== 01224 [..] 01225 This subsection permits to get in run-time the status of the peripheral 01226 and the data flow. 01227 01228 @endverbatim 01229 * @{ 01230 */ 01231 01232 /** 01233 * @brief Return the PCD handle state. 01234 * @param hpcd PCD handle 01235 * @retval HAL state 01236 */ 01237 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) 01238 { 01239 return hpcd->State; 01240 } 01241 /** 01242 * @} 01243 */ 01244 01245 /** 01246 * @} 01247 */ 01248 01249 /* Private functions ---------------------------------------------------------*/ 01250 /** @addtogroup PCD_Private_Functions 01251 * @{ 01252 */ 01253 01254 /** 01255 * @brief Check FIFO for the next packet to be loaded. 01256 * @param hpcd PCD handle 01257 * @param epnum endpoint number 01258 * @retval HAL status 01259 */ 01260 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) 01261 { 01262 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01263 USB_OTG_EPTypeDef *ep; 01264 int32_t len = 0U; 01265 uint32_t len32b; 01266 uint32_t fifoemptymsk = 0U; 01267 01268 ep = &hpcd->IN_ep[epnum]; 01269 len = ep->xfer_len - ep->xfer_count; 01270 01271 if (len > ep->maxpacket) 01272 { 01273 len = ep->maxpacket; 01274 } 01275 01276 01277 len32b = (len + 3U) / 4U; 01278 01279 while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b) && 01280 (ep->xfer_count < ep->xfer_len) && 01281 (ep->xfer_len != 0U)) 01282 { 01283 /* Write the FIFO */ 01284 len = ep->xfer_len - ep->xfer_count; 01285 01286 if (len > ep->maxpacket) 01287 { 01288 len = ep->maxpacket; 01289 } 01290 len32b = (len + 3U) / 4U; 01291 01292 USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); 01293 01294 ep->xfer_buff += len; 01295 ep->xfer_count += len; 01296 } 01297 01298 if(len <= 0U) 01299 { 01300 fifoemptymsk = 0x1U << epnum; 01301 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 01302 01303 } 01304 01305 return HAL_OK; 01306 } 01307 01308 /** 01309 * @} 01310 */ 01311 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || 01312 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx || 01313 STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */ 01314 #endif /* HAL_PCD_MODULE_ENABLED */ 01315 /** 01316 * @} 01317 */ 01318 01319 /** 01320 * @} 01321 */ 01322 01323 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/