STM32F479xx 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 ****************************************************************************** 00014 * @attention 00015 * 00016 * Copyright (c) 2016 STMicroelectronics. 00017 * All rights reserved. 00018 * 00019 * This software is licensed under terms that can be found in the LICENSE file 00020 * in the root directory of this software component. 00021 * If no LICENSE file comes with this software, it is provided AS-IS. 00022 * 00023 ****************************************************************************** 00024 @verbatim 00025 ============================================================================== 00026 ##### How to use this driver ##### 00027 ============================================================================== 00028 [..] 00029 The PCD HAL driver can be used as follows: 00030 00031 (#) Declare a PCD_HandleTypeDef handle structure, for example: 00032 PCD_HandleTypeDef hpcd; 00033 00034 (#) Fill parameters of Init structure in HCD handle 00035 00036 (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) 00037 00038 (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: 00039 (##) Enable the PCD/USB Low Level interface clock using 00040 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); 00041 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode) 00042 00043 (##) Initialize the related GPIO clocks 00044 (##) Configure PCD pin-out 00045 (##) Configure PCD NVIC interrupt 00046 00047 (#)Associate the Upper USB device stack to the HAL PCD Driver: 00048 (##) hpcd.pData = pdev; 00049 00050 (#)Enable PCD transmission and reception: 00051 (##) HAL_PCD_Start(); 00052 00053 @endverbatim 00054 ****************************************************************************** 00055 */ 00056 00057 /* Includes ------------------------------------------------------------------*/ 00058 #include "stm32f4xx_hal.h" 00059 00060 /** @addtogroup STM32F4xx_HAL_Driver 00061 * @{ 00062 */ 00063 00064 /** @defgroup PCD PCD 00065 * @brief PCD HAL module driver 00066 * @{ 00067 */ 00068 00069 #ifdef HAL_PCD_MODULE_ENABLED 00070 00071 #if defined (USB_OTG_FS) || defined (USB_OTG_HS) 00072 00073 /* Private types -------------------------------------------------------------*/ 00074 /* Private variables ---------------------------------------------------------*/ 00075 /* Private constants ---------------------------------------------------------*/ 00076 /* Private macros ------------------------------------------------------------*/ 00077 /** @defgroup PCD_Private_Macros PCD Private Macros 00078 * @{ 00079 */ 00080 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) 00081 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) 00082 /** 00083 * @} 00084 */ 00085 00086 /* Private functions prototypes ----------------------------------------------*/ 00087 /** @defgroup PCD_Private_Functions PCD Private Functions 00088 * @{ 00089 */ 00090 #if defined (USB_OTG_FS) || defined (USB_OTG_HS) 00091 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00092 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00093 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00094 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 00095 /** 00096 * @} 00097 */ 00098 00099 /* Exported functions --------------------------------------------------------*/ 00100 /** @defgroup PCD_Exported_Functions PCD Exported Functions 00101 * @{ 00102 */ 00103 00104 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions 00105 * @brief Initialization and Configuration functions 00106 * 00107 @verbatim 00108 =============================================================================== 00109 ##### Initialization and de-initialization functions ##### 00110 =============================================================================== 00111 [..] This section provides functions allowing to: 00112 00113 @endverbatim 00114 * @{ 00115 */ 00116 00117 /** 00118 * @brief Initializes the PCD according to the specified 00119 * parameters in the PCD_InitTypeDef and initialize the associated handle. 00120 * @param hpcd PCD handle 00121 * @retval HAL status 00122 */ 00123 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) 00124 { 00125 USB_OTG_GlobalTypeDef *USBx; 00126 uint8_t i; 00127 00128 /* Check the PCD handle allocation */ 00129 if (hpcd == NULL) 00130 { 00131 return HAL_ERROR; 00132 } 00133 00134 /* Check the parameters */ 00135 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); 00136 00137 USBx = hpcd->Instance; 00138 00139 if (hpcd->State == HAL_PCD_STATE_RESET) 00140 { 00141 /* Allocate lock resource and initialize it */ 00142 hpcd->Lock = HAL_UNLOCKED; 00143 00144 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00145 hpcd->SOFCallback = HAL_PCD_SOFCallback; 00146 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; 00147 hpcd->ResetCallback = HAL_PCD_ResetCallback; 00148 hpcd->SuspendCallback = HAL_PCD_SuspendCallback; 00149 hpcd->ResumeCallback = HAL_PCD_ResumeCallback; 00150 hpcd->ConnectCallback = HAL_PCD_ConnectCallback; 00151 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; 00152 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; 00153 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; 00154 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; 00155 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; 00156 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; 00157 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; 00158 00159 if (hpcd->MspInitCallback == NULL) 00160 { 00161 hpcd->MspInitCallback = HAL_PCD_MspInit; 00162 } 00163 00164 /* Init the low level hardware */ 00165 hpcd->MspInitCallback(hpcd); 00166 #else 00167 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ 00168 HAL_PCD_MspInit(hpcd); 00169 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */ 00170 } 00171 00172 hpcd->State = HAL_PCD_STATE_BUSY; 00173 00174 /* Disable DMA mode for FS instance */ 00175 if ((USBx->CID & (0x1U << 8)) == 0U) 00176 { 00177 hpcd->Init.dma_enable = 0U; 00178 } 00179 00180 /* Disable the Interrupts */ 00181 __HAL_PCD_DISABLE(hpcd); 00182 00183 /*Init the Core (common init.) */ 00184 if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK) 00185 { 00186 hpcd->State = HAL_PCD_STATE_ERROR; 00187 return HAL_ERROR; 00188 } 00189 00190 /* Force Device Mode*/ 00191 (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE); 00192 00193 /* Init endpoints structures */ 00194 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 00195 { 00196 /* Init ep structure */ 00197 hpcd->IN_ep[i].is_in = 1U; 00198 hpcd->IN_ep[i].num = i; 00199 hpcd->IN_ep[i].tx_fifo_num = i; 00200 /* Control until ep is activated */ 00201 hpcd->IN_ep[i].type = EP_TYPE_CTRL; 00202 hpcd->IN_ep[i].maxpacket = 0U; 00203 hpcd->IN_ep[i].xfer_buff = 0U; 00204 hpcd->IN_ep[i].xfer_len = 0U; 00205 } 00206 00207 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 00208 { 00209 hpcd->OUT_ep[i].is_in = 0U; 00210 hpcd->OUT_ep[i].num = i; 00211 /* Control until ep is activated */ 00212 hpcd->OUT_ep[i].type = EP_TYPE_CTRL; 00213 hpcd->OUT_ep[i].maxpacket = 0U; 00214 hpcd->OUT_ep[i].xfer_buff = 0U; 00215 hpcd->OUT_ep[i].xfer_len = 0U; 00216 } 00217 00218 /* Init Device */ 00219 if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK) 00220 { 00221 hpcd->State = HAL_PCD_STATE_ERROR; 00222 return HAL_ERROR; 00223 } 00224 00225 hpcd->USB_Address = 0U; 00226 hpcd->State = HAL_PCD_STATE_READY; 00227 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 00228 /* Activate LPM */ 00229 if (hpcd->Init.lpm_enable == 1U) 00230 { 00231 (void)HAL_PCDEx_ActivateLPM(hpcd); 00232 } 00233 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */ 00234 (void)USB_DevDisconnect(hpcd->Instance); 00235 00236 return HAL_OK; 00237 } 00238 00239 /** 00240 * @brief DeInitializes the PCD peripheral. 00241 * @param hpcd PCD handle 00242 * @retval HAL status 00243 */ 00244 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) 00245 { 00246 /* Check the PCD handle allocation */ 00247 if (hpcd == NULL) 00248 { 00249 return HAL_ERROR; 00250 } 00251 00252 hpcd->State = HAL_PCD_STATE_BUSY; 00253 00254 /* Stop Device */ 00255 if (USB_StopDevice(hpcd->Instance) != HAL_OK) 00256 { 00257 return HAL_ERROR; 00258 } 00259 00260 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00261 if (hpcd->MspDeInitCallback == NULL) 00262 { 00263 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */ 00264 } 00265 00266 /* DeInit the low level hardware */ 00267 hpcd->MspDeInitCallback(hpcd); 00268 #else 00269 /* DeInit the low level hardware: CLOCK, NVIC.*/ 00270 HAL_PCD_MspDeInit(hpcd); 00271 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00272 00273 hpcd->State = HAL_PCD_STATE_RESET; 00274 00275 return HAL_OK; 00276 } 00277 00278 /** 00279 * @brief Initializes the PCD MSP. 00280 * @param hpcd PCD handle 00281 * @retval None 00282 */ 00283 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) 00284 { 00285 /* Prevent unused argument(s) compilation warning */ 00286 UNUSED(hpcd); 00287 00288 /* NOTE : This function should not be modified, when the callback is needed, 00289 the HAL_PCD_MspInit could be implemented in the user file 00290 */ 00291 } 00292 00293 /** 00294 * @brief DeInitializes PCD MSP. 00295 * @param hpcd PCD handle 00296 * @retval None 00297 */ 00298 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) 00299 { 00300 /* Prevent unused argument(s) compilation warning */ 00301 UNUSED(hpcd); 00302 00303 /* NOTE : This function should not be modified, when the callback is needed, 00304 the HAL_PCD_MspDeInit could be implemented in the user file 00305 */ 00306 } 00307 00308 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00309 /** 00310 * @brief Register a User USB PCD Callback 00311 * To be used instead of the weak predefined callback 00312 * @param hpcd USB PCD handle 00313 * @param CallbackID ID of the callback to be registered 00314 * This parameter can be one of the following values: 00315 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID 00316 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID 00317 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID 00318 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID 00319 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID 00320 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID 00321 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID 00322 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID 00323 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID 00324 * @param pCallback pointer to the Callback function 00325 * @retval HAL status 00326 */ 00327 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, 00328 HAL_PCD_CallbackIDTypeDef CallbackID, 00329 pPCD_CallbackTypeDef pCallback) 00330 { 00331 HAL_StatusTypeDef status = HAL_OK; 00332 00333 if (pCallback == NULL) 00334 { 00335 /* Update the error code */ 00336 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00337 return HAL_ERROR; 00338 } 00339 /* Process locked */ 00340 __HAL_LOCK(hpcd); 00341 00342 if (hpcd->State == HAL_PCD_STATE_READY) 00343 { 00344 switch (CallbackID) 00345 { 00346 case HAL_PCD_SOF_CB_ID : 00347 hpcd->SOFCallback = pCallback; 00348 break; 00349 00350 case HAL_PCD_SETUPSTAGE_CB_ID : 00351 hpcd->SetupStageCallback = pCallback; 00352 break; 00353 00354 case HAL_PCD_RESET_CB_ID : 00355 hpcd->ResetCallback = pCallback; 00356 break; 00357 00358 case HAL_PCD_SUSPEND_CB_ID : 00359 hpcd->SuspendCallback = pCallback; 00360 break; 00361 00362 case HAL_PCD_RESUME_CB_ID : 00363 hpcd->ResumeCallback = pCallback; 00364 break; 00365 00366 case HAL_PCD_CONNECT_CB_ID : 00367 hpcd->ConnectCallback = pCallback; 00368 break; 00369 00370 case HAL_PCD_DISCONNECT_CB_ID : 00371 hpcd->DisconnectCallback = pCallback; 00372 break; 00373 00374 case HAL_PCD_MSPINIT_CB_ID : 00375 hpcd->MspInitCallback = pCallback; 00376 break; 00377 00378 case HAL_PCD_MSPDEINIT_CB_ID : 00379 hpcd->MspDeInitCallback = pCallback; 00380 break; 00381 00382 default : 00383 /* Update the error code */ 00384 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00385 /* Return error status */ 00386 status = HAL_ERROR; 00387 break; 00388 } 00389 } 00390 else if (hpcd->State == HAL_PCD_STATE_RESET) 00391 { 00392 switch (CallbackID) 00393 { 00394 case HAL_PCD_MSPINIT_CB_ID : 00395 hpcd->MspInitCallback = pCallback; 00396 break; 00397 00398 case HAL_PCD_MSPDEINIT_CB_ID : 00399 hpcd->MspDeInitCallback = pCallback; 00400 break; 00401 00402 default : 00403 /* Update the error code */ 00404 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00405 /* Return error status */ 00406 status = HAL_ERROR; 00407 break; 00408 } 00409 } 00410 else 00411 { 00412 /* Update the error code */ 00413 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00414 /* Return error status */ 00415 status = HAL_ERROR; 00416 } 00417 00418 /* Release Lock */ 00419 __HAL_UNLOCK(hpcd); 00420 return status; 00421 } 00422 00423 /** 00424 * @brief Unregister an USB PCD Callback 00425 * USB PCD callabck is redirected to the weak predefined callback 00426 * @param hpcd USB PCD handle 00427 * @param CallbackID ID of the callback to be unregistered 00428 * This parameter can be one of the following values: 00429 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID 00430 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID 00431 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID 00432 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID 00433 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID 00434 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID 00435 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID 00436 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID 00437 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID 00438 * @retval HAL status 00439 */ 00440 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID) 00441 { 00442 HAL_StatusTypeDef status = HAL_OK; 00443 00444 /* Process locked */ 00445 __HAL_LOCK(hpcd); 00446 00447 /* Setup Legacy weak Callbacks */ 00448 if (hpcd->State == HAL_PCD_STATE_READY) 00449 { 00450 switch (CallbackID) 00451 { 00452 case HAL_PCD_SOF_CB_ID : 00453 hpcd->SOFCallback = HAL_PCD_SOFCallback; 00454 break; 00455 00456 case HAL_PCD_SETUPSTAGE_CB_ID : 00457 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; 00458 break; 00459 00460 case HAL_PCD_RESET_CB_ID : 00461 hpcd->ResetCallback = HAL_PCD_ResetCallback; 00462 break; 00463 00464 case HAL_PCD_SUSPEND_CB_ID : 00465 hpcd->SuspendCallback = HAL_PCD_SuspendCallback; 00466 break; 00467 00468 case HAL_PCD_RESUME_CB_ID : 00469 hpcd->ResumeCallback = HAL_PCD_ResumeCallback; 00470 break; 00471 00472 case HAL_PCD_CONNECT_CB_ID : 00473 hpcd->ConnectCallback = HAL_PCD_ConnectCallback; 00474 break; 00475 00476 case HAL_PCD_DISCONNECT_CB_ID : 00477 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; 00478 break; 00479 00480 case HAL_PCD_MSPINIT_CB_ID : 00481 hpcd->MspInitCallback = HAL_PCD_MspInit; 00482 break; 00483 00484 case HAL_PCD_MSPDEINIT_CB_ID : 00485 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; 00486 break; 00487 00488 default : 00489 /* Update the error code */ 00490 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00491 00492 /* Return error status */ 00493 status = HAL_ERROR; 00494 break; 00495 } 00496 } 00497 else if (hpcd->State == HAL_PCD_STATE_RESET) 00498 { 00499 switch (CallbackID) 00500 { 00501 case HAL_PCD_MSPINIT_CB_ID : 00502 hpcd->MspInitCallback = HAL_PCD_MspInit; 00503 break; 00504 00505 case HAL_PCD_MSPDEINIT_CB_ID : 00506 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; 00507 break; 00508 00509 default : 00510 /* Update the error code */ 00511 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00512 00513 /* Return error status */ 00514 status = HAL_ERROR; 00515 break; 00516 } 00517 } 00518 else 00519 { 00520 /* Update the error code */ 00521 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00522 00523 /* Return error status */ 00524 status = HAL_ERROR; 00525 } 00526 00527 /* Release Lock */ 00528 __HAL_UNLOCK(hpcd); 00529 return status; 00530 } 00531 00532 /** 00533 * @brief Register USB PCD Data OUT Stage Callback 00534 * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback 00535 * @param hpcd PCD handle 00536 * @param pCallback pointer to the USB PCD Data OUT Stage Callback function 00537 * @retval HAL status 00538 */ 00539 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, 00540 pPCD_DataOutStageCallbackTypeDef pCallback) 00541 { 00542 HAL_StatusTypeDef status = HAL_OK; 00543 00544 if (pCallback == NULL) 00545 { 00546 /* Update the error code */ 00547 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00548 00549 return HAL_ERROR; 00550 } 00551 00552 /* Process locked */ 00553 __HAL_LOCK(hpcd); 00554 00555 if (hpcd->State == HAL_PCD_STATE_READY) 00556 { 00557 hpcd->DataOutStageCallback = pCallback; 00558 } 00559 else 00560 { 00561 /* Update the error code */ 00562 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00563 00564 /* Return error status */ 00565 status = HAL_ERROR; 00566 } 00567 00568 /* Release Lock */ 00569 __HAL_UNLOCK(hpcd); 00570 00571 return status; 00572 } 00573 00574 /** 00575 * @brief Unregister the USB PCD Data OUT Stage Callback 00576 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback 00577 * @param hpcd PCD handle 00578 * @retval HAL status 00579 */ 00580 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd) 00581 { 00582 HAL_StatusTypeDef status = HAL_OK; 00583 00584 /* Process locked */ 00585 __HAL_LOCK(hpcd); 00586 00587 if (hpcd->State == HAL_PCD_STATE_READY) 00588 { 00589 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */ 00590 } 00591 else 00592 { 00593 /* Update the error code */ 00594 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00595 00596 /* Return error status */ 00597 status = HAL_ERROR; 00598 } 00599 00600 /* Release Lock */ 00601 __HAL_UNLOCK(hpcd); 00602 00603 return status; 00604 } 00605 00606 /** 00607 * @brief Register USB PCD Data IN Stage Callback 00608 * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback 00609 * @param hpcd PCD handle 00610 * @param pCallback pointer to the USB PCD Data IN Stage Callback function 00611 * @retval HAL status 00612 */ 00613 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, 00614 pPCD_DataInStageCallbackTypeDef pCallback) 00615 { 00616 HAL_StatusTypeDef status = HAL_OK; 00617 00618 if (pCallback == NULL) 00619 { 00620 /* Update the error code */ 00621 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00622 00623 return HAL_ERROR; 00624 } 00625 00626 /* Process locked */ 00627 __HAL_LOCK(hpcd); 00628 00629 if (hpcd->State == HAL_PCD_STATE_READY) 00630 { 00631 hpcd->DataInStageCallback = pCallback; 00632 } 00633 else 00634 { 00635 /* Update the error code */ 00636 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00637 00638 /* Return error status */ 00639 status = HAL_ERROR; 00640 } 00641 00642 /* Release Lock */ 00643 __HAL_UNLOCK(hpcd); 00644 00645 return status; 00646 } 00647 00648 /** 00649 * @brief Unregister the USB PCD Data IN Stage Callback 00650 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback 00651 * @param hpcd PCD handle 00652 * @retval HAL status 00653 */ 00654 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd) 00655 { 00656 HAL_StatusTypeDef status = HAL_OK; 00657 00658 /* Process locked */ 00659 __HAL_LOCK(hpcd); 00660 00661 if (hpcd->State == HAL_PCD_STATE_READY) 00662 { 00663 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */ 00664 } 00665 else 00666 { 00667 /* Update the error code */ 00668 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00669 00670 /* Return error status */ 00671 status = HAL_ERROR; 00672 } 00673 00674 /* Release Lock */ 00675 __HAL_UNLOCK(hpcd); 00676 00677 return status; 00678 } 00679 00680 /** 00681 * @brief Register USB PCD Iso OUT incomplete Callback 00682 * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback 00683 * @param hpcd PCD handle 00684 * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function 00685 * @retval HAL status 00686 */ 00687 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, 00688 pPCD_IsoOutIncpltCallbackTypeDef pCallback) 00689 { 00690 HAL_StatusTypeDef status = HAL_OK; 00691 00692 if (pCallback == NULL) 00693 { 00694 /* Update the error code */ 00695 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00696 00697 return HAL_ERROR; 00698 } 00699 00700 /* Process locked */ 00701 __HAL_LOCK(hpcd); 00702 00703 if (hpcd->State == HAL_PCD_STATE_READY) 00704 { 00705 hpcd->ISOOUTIncompleteCallback = pCallback; 00706 } 00707 else 00708 { 00709 /* Update the error code */ 00710 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00711 00712 /* Return error status */ 00713 status = HAL_ERROR; 00714 } 00715 00716 /* Release Lock */ 00717 __HAL_UNLOCK(hpcd); 00718 00719 return status; 00720 } 00721 00722 /** 00723 * @brief Unregister the USB PCD Iso OUT incomplete Callback 00724 * USB PCD Iso OUT incomplete Callback is redirected 00725 * to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback 00726 * @param hpcd PCD handle 00727 * @retval HAL status 00728 */ 00729 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd) 00730 { 00731 HAL_StatusTypeDef status = HAL_OK; 00732 00733 /* Process locked */ 00734 __HAL_LOCK(hpcd); 00735 00736 if (hpcd->State == HAL_PCD_STATE_READY) 00737 { 00738 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */ 00739 } 00740 else 00741 { 00742 /* Update the error code */ 00743 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00744 00745 /* Return error status */ 00746 status = HAL_ERROR; 00747 } 00748 00749 /* Release Lock */ 00750 __HAL_UNLOCK(hpcd); 00751 00752 return status; 00753 } 00754 00755 /** 00756 * @brief Register USB PCD Iso IN incomplete Callback 00757 * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback 00758 * @param hpcd PCD handle 00759 * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function 00760 * @retval HAL status 00761 */ 00762 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, 00763 pPCD_IsoInIncpltCallbackTypeDef pCallback) 00764 { 00765 HAL_StatusTypeDef status = HAL_OK; 00766 00767 if (pCallback == NULL) 00768 { 00769 /* Update the error code */ 00770 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00771 00772 return HAL_ERROR; 00773 } 00774 00775 /* Process locked */ 00776 __HAL_LOCK(hpcd); 00777 00778 if (hpcd->State == HAL_PCD_STATE_READY) 00779 { 00780 hpcd->ISOINIncompleteCallback = pCallback; 00781 } 00782 else 00783 { 00784 /* Update the error code */ 00785 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00786 00787 /* Return error status */ 00788 status = HAL_ERROR; 00789 } 00790 00791 /* Release Lock */ 00792 __HAL_UNLOCK(hpcd); 00793 00794 return status; 00795 } 00796 00797 /** 00798 * @brief Unregister the USB PCD Iso IN incomplete Callback 00799 * USB PCD Iso IN incomplete Callback is redirected 00800 * to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback 00801 * @param hpcd PCD handle 00802 * @retval HAL status 00803 */ 00804 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd) 00805 { 00806 HAL_StatusTypeDef status = HAL_OK; 00807 00808 /* Process locked */ 00809 __HAL_LOCK(hpcd); 00810 00811 if (hpcd->State == HAL_PCD_STATE_READY) 00812 { 00813 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */ 00814 } 00815 else 00816 { 00817 /* Update the error code */ 00818 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00819 00820 /* Return error status */ 00821 status = HAL_ERROR; 00822 } 00823 00824 /* Release Lock */ 00825 __HAL_UNLOCK(hpcd); 00826 00827 return status; 00828 } 00829 00830 /** 00831 * @brief Register USB PCD BCD Callback 00832 * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback 00833 * @param hpcd PCD handle 00834 * @param pCallback pointer to the USB PCD BCD Callback function 00835 * @retval HAL status 00836 */ 00837 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback) 00838 { 00839 HAL_StatusTypeDef status = HAL_OK; 00840 00841 if (pCallback == NULL) 00842 { 00843 /* Update the error code */ 00844 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00845 00846 return HAL_ERROR; 00847 } 00848 00849 /* Process locked */ 00850 __HAL_LOCK(hpcd); 00851 00852 if (hpcd->State == HAL_PCD_STATE_READY) 00853 { 00854 hpcd->BCDCallback = pCallback; 00855 } 00856 else 00857 { 00858 /* Update the error code */ 00859 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00860 00861 /* Return error status */ 00862 status = HAL_ERROR; 00863 } 00864 00865 /* Release Lock */ 00866 __HAL_UNLOCK(hpcd); 00867 00868 return status; 00869 } 00870 00871 /** 00872 * @brief Unregister the USB PCD BCD Callback 00873 * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback 00874 * @param hpcd PCD handle 00875 * @retval HAL status 00876 */ 00877 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd) 00878 { 00879 HAL_StatusTypeDef status = HAL_OK; 00880 00881 /* Process locked */ 00882 __HAL_LOCK(hpcd); 00883 00884 if (hpcd->State == HAL_PCD_STATE_READY) 00885 { 00886 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */ 00887 } 00888 else 00889 { 00890 /* Update the error code */ 00891 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00892 00893 /* Return error status */ 00894 status = HAL_ERROR; 00895 } 00896 00897 /* Release Lock */ 00898 __HAL_UNLOCK(hpcd); 00899 00900 return status; 00901 } 00902 00903 /** 00904 * @brief Register USB PCD LPM Callback 00905 * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback 00906 * @param hpcd PCD handle 00907 * @param pCallback pointer to the USB PCD LPM Callback function 00908 * @retval HAL status 00909 */ 00910 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback) 00911 { 00912 HAL_StatusTypeDef status = HAL_OK; 00913 00914 if (pCallback == NULL) 00915 { 00916 /* Update the error code */ 00917 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00918 00919 return HAL_ERROR; 00920 } 00921 00922 /* Process locked */ 00923 __HAL_LOCK(hpcd); 00924 00925 if (hpcd->State == HAL_PCD_STATE_READY) 00926 { 00927 hpcd->LPMCallback = pCallback; 00928 } 00929 else 00930 { 00931 /* Update the error code */ 00932 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00933 00934 /* Return error status */ 00935 status = HAL_ERROR; 00936 } 00937 00938 /* Release Lock */ 00939 __HAL_UNLOCK(hpcd); 00940 00941 return status; 00942 } 00943 00944 /** 00945 * @brief Unregister the USB PCD LPM Callback 00946 * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback 00947 * @param hpcd PCD handle 00948 * @retval HAL status 00949 */ 00950 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd) 00951 { 00952 HAL_StatusTypeDef status = HAL_OK; 00953 00954 /* Process locked */ 00955 __HAL_LOCK(hpcd); 00956 00957 if (hpcd->State == HAL_PCD_STATE_READY) 00958 { 00959 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */ 00960 } 00961 else 00962 { 00963 /* Update the error code */ 00964 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00965 00966 /* Return error status */ 00967 status = HAL_ERROR; 00968 } 00969 00970 /* Release Lock */ 00971 __HAL_UNLOCK(hpcd); 00972 00973 return status; 00974 } 00975 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00976 00977 /** 00978 * @} 00979 */ 00980 00981 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions 00982 * @brief Data transfers functions 00983 * 00984 @verbatim 00985 =============================================================================== 00986 ##### IO operation functions ##### 00987 =============================================================================== 00988 [..] 00989 This subsection provides a set of functions allowing to manage the PCD data 00990 transfers. 00991 00992 @endverbatim 00993 * @{ 00994 */ 00995 00996 /** 00997 * @brief Start the USB device 00998 * @param hpcd PCD handle 00999 * @retval HAL status 01000 */ 01001 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) 01002 { 01003 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01004 01005 __HAL_LOCK(hpcd); 01006 01007 if ((hpcd->Init.battery_charging_enable == 1U) && 01008 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY)) 01009 { 01010 /* Enable USB Transceiver */ 01011 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; 01012 } 01013 01014 __HAL_PCD_ENABLE(hpcd); 01015 (void)USB_DevConnect(hpcd->Instance); 01016 __HAL_UNLOCK(hpcd); 01017 01018 return HAL_OK; 01019 } 01020 01021 /** 01022 * @brief Stop the USB device. 01023 * @param hpcd PCD handle 01024 * @retval HAL status 01025 */ 01026 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) 01027 { 01028 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01029 01030 __HAL_LOCK(hpcd); 01031 __HAL_PCD_DISABLE(hpcd); 01032 (void)USB_DevDisconnect(hpcd->Instance); 01033 01034 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U); 01035 01036 if ((hpcd->Init.battery_charging_enable == 1U) && 01037 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY)) 01038 { 01039 /* Disable USB Transceiver */ 01040 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); 01041 } 01042 01043 __HAL_UNLOCK(hpcd); 01044 01045 return HAL_OK; 01046 } 01047 01048 #if defined (USB_OTG_FS) || defined (USB_OTG_HS) 01049 /** 01050 * @brief Handles PCD interrupt request. 01051 * @param hpcd PCD handle 01052 * @retval HAL status 01053 */ 01054 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) 01055 { 01056 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01057 uint32_t USBx_BASE = (uint32_t)USBx; 01058 USB_OTG_EPTypeDef *ep; 01059 uint32_t i; 01060 uint32_t ep_intr; 01061 uint32_t epint; 01062 uint32_t epnum; 01063 uint32_t fifoemptymsk; 01064 uint32_t temp; 01065 01066 /* ensure that we are in device mode */ 01067 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) 01068 { 01069 /* avoid spurious interrupt */ 01070 if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) 01071 { 01072 return; 01073 } 01074 01075 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) 01076 { 01077 /* incorrect mode, acknowledge the interrupt */ 01078 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); 01079 } 01080 01081 /* Handle RxQLevel Interrupt */ 01082 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL)) 01083 { 01084 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 01085 01086 temp = USBx->GRXSTSP; 01087 01088 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM]; 01089 01090 if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) 01091 { 01092 if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U) 01093 { 01094 (void)USB_ReadPacket(USBx, ep->xfer_buff, 01095 (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4)); 01096 01097 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 01098 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 01099 } 01100 } 01101 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) 01102 { 01103 (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U); 01104 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 01105 } 01106 else 01107 { 01108 /* ... */ 01109 } 01110 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 01111 } 01112 01113 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) 01114 { 01115 epnum = 0U; 01116 01117 /* Read in the device interrupt bits */ 01118 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); 01119 01120 while (ep_intr != 0U) 01121 { 01122 if ((ep_intr & 0x1U) != 0U) 01123 { 01124 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum); 01125 01126 if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) 01127 { 01128 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); 01129 (void)PCD_EP_OutXfrComplete_int(hpcd, epnum); 01130 } 01131 01132 if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) 01133 { 01134 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); 01135 /* Class B setup phase done for previous decoded setup */ 01136 (void)PCD_EP_OutSetupPacket_int(hpcd, epnum); 01137 } 01138 01139 if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) 01140 { 01141 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); 01142 } 01143 01144 /* Clear Status Phase Received interrupt */ 01145 if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) 01146 { 01147 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 01148 } 01149 01150 /* Clear OUT NAK interrupt */ 01151 if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK) 01152 { 01153 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK); 01154 } 01155 } 01156 epnum++; 01157 ep_intr >>= 1U; 01158 } 01159 } 01160 01161 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) 01162 { 01163 /* Read in the device interrupt bits */ 01164 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); 01165 01166 epnum = 0U; 01167 01168 while (ep_intr != 0U) 01169 { 01170 if ((ep_intr & 0x1U) != 0U) /* In ITR */ 01171 { 01172 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum); 01173 01174 if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) 01175 { 01176 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); 01177 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 01178 01179 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); 01180 01181 if (hpcd->Init.dma_enable == 1U) 01182 { 01183 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; 01184 01185 /* this is ZLP, so prepare EP0 for next setup */ 01186 if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U)) 01187 { 01188 /* prepare to rx more setup packets */ 01189 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 01190 } 01191 } 01192 01193 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01194 hpcd->DataInStageCallback(hpcd, (uint8_t)epnum); 01195 #else 01196 HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum); 01197 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01198 } 01199 if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) 01200 { 01201 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); 01202 } 01203 if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) 01204 { 01205 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); 01206 } 01207 if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) 01208 { 01209 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); 01210 } 01211 if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) 01212 { 01213 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); 01214 } 01215 if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) 01216 { 01217 (void)PCD_WriteEmptyTxFifo(hpcd, epnum); 01218 } 01219 } 01220 epnum++; 01221 ep_intr >>= 1U; 01222 } 01223 } 01224 01225 /* Handle Resume Interrupt */ 01226 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) 01227 { 01228 /* Clear the Remote Wake-up Signaling */ 01229 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 01230 01231 if (hpcd->LPM_State == LPM_L1) 01232 { 01233 hpcd->LPM_State = LPM_L0; 01234 01235 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01236 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); 01237 #else 01238 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); 01239 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01240 } 01241 else 01242 { 01243 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01244 hpcd->ResumeCallback(hpcd); 01245 #else 01246 HAL_PCD_ResumeCallback(hpcd); 01247 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01248 } 01249 01250 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); 01251 } 01252 01253 /* Handle Suspend Interrupt */ 01254 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) 01255 { 01256 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) 01257 { 01258 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01259 hpcd->SuspendCallback(hpcd); 01260 #else 01261 HAL_PCD_SuspendCallback(hpcd); 01262 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01263 } 01264 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); 01265 } 01266 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 01267 /* Handle LPM Interrupt */ 01268 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) 01269 { 01270 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); 01271 01272 if (hpcd->LPM_State == LPM_L0) 01273 { 01274 hpcd->LPM_State = LPM_L1; 01275 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U; 01276 01277 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01278 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); 01279 #else 01280 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); 01281 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01282 } 01283 else 01284 { 01285 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01286 hpcd->SuspendCallback(hpcd); 01287 #else 01288 HAL_PCD_SuspendCallback(hpcd); 01289 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01290 } 01291 } 01292 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */ 01293 /* Handle Reset Interrupt */ 01294 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) 01295 { 01296 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 01297 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U); 01298 01299 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 01300 { 01301 USBx_INEP(i)->DIEPINT = 0xFB7FU; 01302 USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; 01303 USBx_INEP(i)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK; 01304 USBx_OUTEP(i)->DOEPINT = 0xFB7FU; 01305 USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; 01306 USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; 01307 } 01308 USBx_DEVICE->DAINTMSK |= 0x10001U; 01309 01310 if (hpcd->Init.use_dedicated_ep1 != 0U) 01311 { 01312 USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM | 01313 USB_OTG_DOEPMSK_XFRCM | 01314 USB_OTG_DOEPMSK_EPDM; 01315 01316 USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM | 01317 USB_OTG_DIEPMSK_XFRCM | 01318 USB_OTG_DIEPMSK_EPDM; 01319 } 01320 else 01321 { 01322 USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM | 01323 USB_OTG_DOEPMSK_XFRCM | 01324 USB_OTG_DOEPMSK_EPDM | 01325 USB_OTG_DOEPMSK_OTEPSPRM | 01326 USB_OTG_DOEPMSK_NAKM; 01327 01328 USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM | 01329 USB_OTG_DIEPMSK_XFRCM | 01330 USB_OTG_DIEPMSK_EPDM; 01331 } 01332 01333 /* Set Default Address to 0 */ 01334 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; 01335 01336 /* setup EP0 to receive SETUP packets */ 01337 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, 01338 (uint8_t *)hpcd->Setup); 01339 01340 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); 01341 } 01342 01343 /* Handle Enumeration done Interrupt */ 01344 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) 01345 { 01346 (void)USB_ActivateSetup(hpcd->Instance); 01347 hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance); 01348 01349 /* Set USB Turnaround time */ 01350 (void)USB_SetTurnaroundTime(hpcd->Instance, 01351 HAL_RCC_GetHCLKFreq(), 01352 (uint8_t)hpcd->Init.speed); 01353 01354 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01355 hpcd->ResetCallback(hpcd); 01356 #else 01357 HAL_PCD_ResetCallback(hpcd); 01358 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01359 01360 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); 01361 } 01362 01363 /* Handle SOF Interrupt */ 01364 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) 01365 { 01366 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01367 hpcd->SOFCallback(hpcd); 01368 #else 01369 HAL_PCD_SOFCallback(hpcd); 01370 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01371 01372 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); 01373 } 01374 01375 /* Handle Incomplete ISO IN Interrupt */ 01376 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) 01377 { 01378 /* Keep application checking the corresponding Iso IN endpoint 01379 causing the incomplete Interrupt */ 01380 epnum = 0U; 01381 01382 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01383 hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum); 01384 #else 01385 HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum); 01386 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01387 01388 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); 01389 } 01390 01391 /* Handle Incomplete ISO OUT Interrupt */ 01392 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) 01393 { 01394 /* Keep application checking the corresponding Iso OUT endpoint 01395 causing the incomplete Interrupt */ 01396 epnum = 0U; 01397 01398 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01399 hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); 01400 #else 01401 HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); 01402 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01403 01404 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); 01405 } 01406 01407 /* Handle Connection event Interrupt */ 01408 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) 01409 { 01410 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01411 hpcd->ConnectCallback(hpcd); 01412 #else 01413 HAL_PCD_ConnectCallback(hpcd); 01414 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01415 01416 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); 01417 } 01418 01419 /* Handle Disconnection event Interrupt */ 01420 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) 01421 { 01422 temp = hpcd->Instance->GOTGINT; 01423 01424 if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) 01425 { 01426 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01427 hpcd->DisconnectCallback(hpcd); 01428 #else 01429 HAL_PCD_DisconnectCallback(hpcd); 01430 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01431 } 01432 hpcd->Instance->GOTGINT |= temp; 01433 } 01434 } 01435 } 01436 01437 01438 /** 01439 * @brief Handles PCD Wakeup interrupt request. 01440 * @param hpcd PCD handle 01441 * @retval HAL status 01442 */ 01443 void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd) 01444 { 01445 USB_OTG_GlobalTypeDef *USBx; 01446 01447 USBx = hpcd->Instance; 01448 01449 if ((USBx->CID & (0x1U << 8)) == 0U) 01450 { 01451 /* Clear EXTI pending Bit */ 01452 __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG(); 01453 } 01454 else 01455 { 01456 /* Clear EXTI pending Bit */ 01457 __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG(); 01458 } 01459 } 01460 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 01461 01462 01463 /** 01464 * @brief Data OUT stage callback. 01465 * @param hpcd PCD handle 01466 * @param epnum endpoint number 01467 * @retval None 01468 */ 01469 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01470 { 01471 /* Prevent unused argument(s) compilation warning */ 01472 UNUSED(hpcd); 01473 UNUSED(epnum); 01474 01475 /* NOTE : This function should not be modified, when the callback is needed, 01476 the HAL_PCD_DataOutStageCallback could be implemented in the user file 01477 */ 01478 } 01479 01480 /** 01481 * @brief Data IN stage callback 01482 * @param hpcd PCD handle 01483 * @param epnum endpoint number 01484 * @retval None 01485 */ 01486 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01487 { 01488 /* Prevent unused argument(s) compilation warning */ 01489 UNUSED(hpcd); 01490 UNUSED(epnum); 01491 01492 /* NOTE : This function should not be modified, when the callback is needed, 01493 the HAL_PCD_DataInStageCallback could be implemented in the user file 01494 */ 01495 } 01496 /** 01497 * @brief Setup stage callback 01498 * @param hpcd PCD handle 01499 * @retval None 01500 */ 01501 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) 01502 { 01503 /* Prevent unused argument(s) compilation warning */ 01504 UNUSED(hpcd); 01505 01506 /* NOTE : This function should not be modified, when the callback is needed, 01507 the HAL_PCD_SetupStageCallback could be implemented in the user file 01508 */ 01509 } 01510 01511 /** 01512 * @brief USB Start Of Frame callback. 01513 * @param hpcd PCD handle 01514 * @retval None 01515 */ 01516 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) 01517 { 01518 /* Prevent unused argument(s) compilation warning */ 01519 UNUSED(hpcd); 01520 01521 /* NOTE : This function should not be modified, when the callback is needed, 01522 the HAL_PCD_SOFCallback could be implemented in the user file 01523 */ 01524 } 01525 01526 /** 01527 * @brief USB Reset callback. 01528 * @param hpcd PCD handle 01529 * @retval None 01530 */ 01531 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) 01532 { 01533 /* Prevent unused argument(s) compilation warning */ 01534 UNUSED(hpcd); 01535 01536 /* NOTE : This function should not be modified, when the callback is needed, 01537 the HAL_PCD_ResetCallback could be implemented in the user file 01538 */ 01539 } 01540 01541 /** 01542 * @brief Suspend event callback. 01543 * @param hpcd PCD handle 01544 * @retval None 01545 */ 01546 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) 01547 { 01548 /* Prevent unused argument(s) compilation warning */ 01549 UNUSED(hpcd); 01550 01551 /* NOTE : This function should not be modified, when the callback is needed, 01552 the HAL_PCD_SuspendCallback could be implemented in the user file 01553 */ 01554 } 01555 01556 /** 01557 * @brief Resume event callback. 01558 * @param hpcd PCD handle 01559 * @retval None 01560 */ 01561 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) 01562 { 01563 /* Prevent unused argument(s) compilation warning */ 01564 UNUSED(hpcd); 01565 01566 /* NOTE : This function should not be modified, when the callback is needed, 01567 the HAL_PCD_ResumeCallback could be implemented in the user file 01568 */ 01569 } 01570 01571 /** 01572 * @brief Incomplete ISO OUT callback. 01573 * @param hpcd PCD handle 01574 * @param epnum endpoint number 01575 * @retval None 01576 */ 01577 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01578 { 01579 /* Prevent unused argument(s) compilation warning */ 01580 UNUSED(hpcd); 01581 UNUSED(epnum); 01582 01583 /* NOTE : This function should not be modified, when the callback is needed, 01584 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file 01585 */ 01586 } 01587 01588 /** 01589 * @brief Incomplete ISO IN callback. 01590 * @param hpcd PCD handle 01591 * @param epnum endpoint number 01592 * @retval None 01593 */ 01594 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01595 { 01596 /* Prevent unused argument(s) compilation warning */ 01597 UNUSED(hpcd); 01598 UNUSED(epnum); 01599 01600 /* NOTE : This function should not be modified, when the callback is needed, 01601 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file 01602 */ 01603 } 01604 01605 /** 01606 * @brief Connection event callback. 01607 * @param hpcd PCD handle 01608 * @retval None 01609 */ 01610 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) 01611 { 01612 /* Prevent unused argument(s) compilation warning */ 01613 UNUSED(hpcd); 01614 01615 /* NOTE : This function should not be modified, when the callback is needed, 01616 the HAL_PCD_ConnectCallback could be implemented in the user file 01617 */ 01618 } 01619 01620 /** 01621 * @brief Disconnection event callback. 01622 * @param hpcd PCD handle 01623 * @retval None 01624 */ 01625 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) 01626 { 01627 /* Prevent unused argument(s) compilation warning */ 01628 UNUSED(hpcd); 01629 01630 /* NOTE : This function should not be modified, when the callback is needed, 01631 the HAL_PCD_DisconnectCallback could be implemented in the user file 01632 */ 01633 } 01634 01635 /** 01636 * @} 01637 */ 01638 01639 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions 01640 * @brief management functions 01641 * 01642 @verbatim 01643 =============================================================================== 01644 ##### Peripheral Control functions ##### 01645 =============================================================================== 01646 [..] 01647 This subsection provides a set of functions allowing to control the PCD data 01648 transfers. 01649 01650 @endverbatim 01651 * @{ 01652 */ 01653 01654 /** 01655 * @brief Connect the USB device 01656 * @param hpcd PCD handle 01657 * @retval HAL status 01658 */ 01659 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) 01660 { 01661 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01662 01663 __HAL_LOCK(hpcd); 01664 01665 if ((hpcd->Init.battery_charging_enable == 1U) && 01666 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY)) 01667 { 01668 /* Enable USB Transceiver */ 01669 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; 01670 } 01671 (void)USB_DevConnect(hpcd->Instance); 01672 __HAL_UNLOCK(hpcd); 01673 01674 return HAL_OK; 01675 } 01676 01677 /** 01678 * @brief Disconnect the USB device. 01679 * @param hpcd PCD handle 01680 * @retval HAL status 01681 */ 01682 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) 01683 { 01684 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01685 01686 __HAL_LOCK(hpcd); 01687 (void)USB_DevDisconnect(hpcd->Instance); 01688 01689 if ((hpcd->Init.battery_charging_enable == 1U) && 01690 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY)) 01691 { 01692 /* Disable USB Transceiver */ 01693 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); 01694 } 01695 01696 __HAL_UNLOCK(hpcd); 01697 01698 return HAL_OK; 01699 } 01700 01701 /** 01702 * @brief Set the USB Device address. 01703 * @param hpcd PCD handle 01704 * @param address new device address 01705 * @retval HAL status 01706 */ 01707 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) 01708 { 01709 __HAL_LOCK(hpcd); 01710 hpcd->USB_Address = address; 01711 (void)USB_SetDevAddress(hpcd->Instance, address); 01712 __HAL_UNLOCK(hpcd); 01713 01714 return HAL_OK; 01715 } 01716 /** 01717 * @brief Open and configure an endpoint. 01718 * @param hpcd PCD handle 01719 * @param ep_addr endpoint address 01720 * @param ep_mps endpoint max packet size 01721 * @param ep_type endpoint type 01722 * @retval HAL status 01723 */ 01724 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, 01725 uint16_t ep_mps, uint8_t ep_type) 01726 { 01727 HAL_StatusTypeDef ret = HAL_OK; 01728 PCD_EPTypeDef *ep; 01729 01730 if ((ep_addr & 0x80U) == 0x80U) 01731 { 01732 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01733 ep->is_in = 1U; 01734 } 01735 else 01736 { 01737 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01738 ep->is_in = 0U; 01739 } 01740 01741 ep->num = ep_addr & EP_ADDR_MSK; 01742 ep->maxpacket = ep_mps; 01743 ep->type = ep_type; 01744 01745 if (ep->is_in != 0U) 01746 { 01747 /* Assign a Tx FIFO */ 01748 ep->tx_fifo_num = ep->num; 01749 } 01750 /* Set initial data PID. */ 01751 if (ep_type == EP_TYPE_BULK) 01752 { 01753 ep->data_pid_start = 0U; 01754 } 01755 01756 __HAL_LOCK(hpcd); 01757 (void)USB_ActivateEndpoint(hpcd->Instance, ep); 01758 __HAL_UNLOCK(hpcd); 01759 01760 return ret; 01761 } 01762 01763 /** 01764 * @brief Deactivate an endpoint. 01765 * @param hpcd PCD handle 01766 * @param ep_addr endpoint address 01767 * @retval HAL status 01768 */ 01769 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01770 { 01771 PCD_EPTypeDef *ep; 01772 01773 if ((ep_addr & 0x80U) == 0x80U) 01774 { 01775 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01776 ep->is_in = 1U; 01777 } 01778 else 01779 { 01780 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01781 ep->is_in = 0U; 01782 } 01783 ep->num = ep_addr & EP_ADDR_MSK; 01784 01785 __HAL_LOCK(hpcd); 01786 (void)USB_DeactivateEndpoint(hpcd->Instance, ep); 01787 __HAL_UNLOCK(hpcd); 01788 return HAL_OK; 01789 } 01790 01791 01792 /** 01793 * @brief Receive an amount of data. 01794 * @param hpcd PCD handle 01795 * @param ep_addr endpoint address 01796 * @param pBuf pointer to the reception buffer 01797 * @param len amount of data to be received 01798 * @retval HAL status 01799 */ 01800 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01801 { 01802 PCD_EPTypeDef *ep; 01803 01804 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01805 01806 /*setup and start the Xfer */ 01807 ep->xfer_buff = pBuf; 01808 ep->xfer_len = len; 01809 ep->xfer_count = 0U; 01810 ep->is_in = 0U; 01811 ep->num = ep_addr & EP_ADDR_MSK; 01812 01813 if (hpcd->Init.dma_enable == 1U) 01814 { 01815 ep->dma_addr = (uint32_t)pBuf; 01816 } 01817 01818 if ((ep_addr & EP_ADDR_MSK) == 0U) 01819 { 01820 (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01821 } 01822 else 01823 { 01824 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01825 } 01826 01827 return HAL_OK; 01828 } 01829 01830 /** 01831 * @brief Get Received Data Size 01832 * @param hpcd PCD handle 01833 * @param ep_addr endpoint address 01834 * @retval Data Size 01835 */ 01836 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01837 { 01838 return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; 01839 } 01840 /** 01841 * @brief Send an amount of data 01842 * @param hpcd PCD handle 01843 * @param ep_addr endpoint address 01844 * @param pBuf pointer to the transmission buffer 01845 * @param len amount of data to be sent 01846 * @retval HAL status 01847 */ 01848 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01849 { 01850 PCD_EPTypeDef *ep; 01851 01852 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01853 01854 /*setup and start the Xfer */ 01855 ep->xfer_buff = pBuf; 01856 ep->xfer_len = len; 01857 ep->xfer_count = 0U; 01858 ep->is_in = 1U; 01859 ep->num = ep_addr & EP_ADDR_MSK; 01860 01861 if (hpcd->Init.dma_enable == 1U) 01862 { 01863 ep->dma_addr = (uint32_t)pBuf; 01864 } 01865 01866 if ((ep_addr & EP_ADDR_MSK) == 0U) 01867 { 01868 (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01869 } 01870 else 01871 { 01872 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01873 } 01874 01875 return HAL_OK; 01876 } 01877 01878 /** 01879 * @brief Set a STALL condition over an endpoint 01880 * @param hpcd PCD handle 01881 * @param ep_addr endpoint address 01882 * @retval HAL status 01883 */ 01884 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01885 { 01886 PCD_EPTypeDef *ep; 01887 01888 if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) 01889 { 01890 return HAL_ERROR; 01891 } 01892 01893 if ((0x80U & ep_addr) == 0x80U) 01894 { 01895 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01896 ep->is_in = 1U; 01897 } 01898 else 01899 { 01900 ep = &hpcd->OUT_ep[ep_addr]; 01901 ep->is_in = 0U; 01902 } 01903 01904 ep->is_stall = 1U; 01905 ep->num = ep_addr & EP_ADDR_MSK; 01906 01907 __HAL_LOCK(hpcd); 01908 01909 (void)USB_EPSetStall(hpcd->Instance, ep); 01910 01911 if ((ep_addr & EP_ADDR_MSK) == 0U) 01912 { 01913 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); 01914 } 01915 01916 __HAL_UNLOCK(hpcd); 01917 01918 return HAL_OK; 01919 } 01920 01921 /** 01922 * @brief Clear a STALL condition over in an endpoint 01923 * @param hpcd PCD handle 01924 * @param ep_addr endpoint address 01925 * @retval HAL status 01926 */ 01927 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01928 { 01929 PCD_EPTypeDef *ep; 01930 01931 if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) 01932 { 01933 return HAL_ERROR; 01934 } 01935 01936 if ((0x80U & ep_addr) == 0x80U) 01937 { 01938 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01939 ep->is_in = 1U; 01940 } 01941 else 01942 { 01943 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01944 ep->is_in = 0U; 01945 } 01946 01947 ep->is_stall = 0U; 01948 ep->num = ep_addr & EP_ADDR_MSK; 01949 01950 __HAL_LOCK(hpcd); 01951 (void)USB_EPClearStall(hpcd->Instance, ep); 01952 __HAL_UNLOCK(hpcd); 01953 01954 return HAL_OK; 01955 } 01956 01957 /** 01958 * @brief Flush an endpoint 01959 * @param hpcd PCD handle 01960 * @param ep_addr endpoint address 01961 * @retval HAL status 01962 */ 01963 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01964 { 01965 __HAL_LOCK(hpcd); 01966 01967 if ((ep_addr & 0x80U) == 0x80U) 01968 { 01969 (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK); 01970 } 01971 else 01972 { 01973 (void)USB_FlushRxFifo(hpcd->Instance); 01974 } 01975 01976 __HAL_UNLOCK(hpcd); 01977 01978 return HAL_OK; 01979 } 01980 01981 /** 01982 * @brief Activate remote wakeup signalling 01983 * @param hpcd PCD handle 01984 * @retval HAL status 01985 */ 01986 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 01987 { 01988 return (USB_ActivateRemoteWakeup(hpcd->Instance)); 01989 } 01990 01991 /** 01992 * @brief De-activate remote wakeup signalling. 01993 * @param hpcd PCD handle 01994 * @retval HAL status 01995 */ 01996 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 01997 { 01998 return (USB_DeActivateRemoteWakeup(hpcd->Instance)); 01999 } 02000 02001 /** 02002 * @} 02003 */ 02004 02005 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions 02006 * @brief Peripheral State functions 02007 * 02008 @verbatim 02009 =============================================================================== 02010 ##### Peripheral State functions ##### 02011 =============================================================================== 02012 [..] 02013 This subsection permits to get in run-time the status of the peripheral 02014 and the data flow. 02015 02016 @endverbatim 02017 * @{ 02018 */ 02019 02020 /** 02021 * @brief Return the PCD handle state. 02022 * @param hpcd PCD handle 02023 * @retval HAL state 02024 */ 02025 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) 02026 { 02027 return hpcd->State; 02028 } 02029 02030 /** 02031 * @} 02032 */ 02033 02034 /** 02035 * @} 02036 */ 02037 02038 /* Private functions ---------------------------------------------------------*/ 02039 /** @addtogroup PCD_Private_Functions 02040 * @{ 02041 */ 02042 #if defined (USB_OTG_FS) || defined (USB_OTG_HS) 02043 /** 02044 * @brief Check FIFO for the next packet to be loaded. 02045 * @param hpcd PCD handle 02046 * @param epnum endpoint number 02047 * @retval HAL status 02048 */ 02049 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02050 { 02051 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02052 uint32_t USBx_BASE = (uint32_t)USBx; 02053 USB_OTG_EPTypeDef *ep; 02054 uint32_t len; 02055 uint32_t len32b; 02056 uint32_t fifoemptymsk; 02057 02058 ep = &hpcd->IN_ep[epnum]; 02059 02060 if (ep->xfer_count > ep->xfer_len) 02061 { 02062 return HAL_ERROR; 02063 } 02064 02065 len = ep->xfer_len - ep->xfer_count; 02066 02067 if (len > ep->maxpacket) 02068 { 02069 len = ep->maxpacket; 02070 } 02071 02072 len32b = (len + 3U) / 4U; 02073 02074 while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) && 02075 (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U)) 02076 { 02077 /* Write the FIFO */ 02078 len = ep->xfer_len - ep->xfer_count; 02079 02080 if (len > ep->maxpacket) 02081 { 02082 len = ep->maxpacket; 02083 } 02084 len32b = (len + 3U) / 4U; 02085 02086 (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len, 02087 (uint8_t)hpcd->Init.dma_enable); 02088 02089 ep->xfer_buff += len; 02090 ep->xfer_count += len; 02091 } 02092 02093 if (ep->xfer_len <= ep->xfer_count) 02094 { 02095 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); 02096 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 02097 } 02098 02099 return HAL_OK; 02100 } 02101 02102 02103 /** 02104 * @brief process EP OUT transfer complete interrupt. 02105 * @param hpcd PCD handle 02106 * @param epnum endpoint number 02107 * @retval HAL status 02108 */ 02109 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02110 { 02111 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02112 uint32_t USBx_BASE = (uint32_t)USBx; 02113 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U); 02114 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; 02115 02116 if (hpcd->Init.dma_enable == 1U) 02117 { 02118 if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */ 02119 { 02120 /* StupPktRcvd = 1 this is a setup packet */ 02121 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && 02122 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) 02123 { 02124 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02125 } 02126 } 02127 else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */ 02128 { 02129 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 02130 } 02131 else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U) 02132 { 02133 /* StupPktRcvd = 1 this is a setup packet */ 02134 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && 02135 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) 02136 { 02137 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02138 } 02139 else 02140 { 02141 /* out data packet received over EP0 */ 02142 hpcd->OUT_ep[epnum].xfer_count = 02143 hpcd->OUT_ep[epnum].maxpacket - 02144 (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); 02145 02146 hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; 02147 02148 if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U)) 02149 { 02150 /* this is ZLP, so prepare EP0 for next setup */ 02151 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 02152 } 02153 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02154 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02155 #else 02156 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02157 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02158 } 02159 } 02160 else 02161 { 02162 /* ... */ 02163 } 02164 } 02165 else 02166 { 02167 if (gSNPSiD == USB_OTG_CORE_ID_310A) 02168 { 02169 /* StupPktRcvd = 1 this is a setup packet */ 02170 if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX) 02171 { 02172 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02173 } 02174 else 02175 { 02176 if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) 02177 { 02178 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 02179 } 02180 02181 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02182 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02183 #else 02184 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02185 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02186 } 02187 } 02188 else 02189 { 02190 if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U)) 02191 { 02192 /* this is ZLP, so prepare EP0 for next setup */ 02193 (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup); 02194 } 02195 02196 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02197 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02198 #else 02199 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02200 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02201 } 02202 } 02203 02204 return HAL_OK; 02205 } 02206 02207 02208 /** 02209 * @brief process EP OUT setup packet received interrupt. 02210 * @param hpcd PCD handle 02211 * @param epnum endpoint number 02212 * @retval HAL status 02213 */ 02214 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02215 { 02216 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02217 uint32_t USBx_BASE = (uint32_t)USBx; 02218 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U); 02219 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; 02220 02221 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && 02222 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) 02223 { 02224 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02225 } 02226 02227 /* Inform the upper layer that a setup packet is available */ 02228 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02229 hpcd->SetupStageCallback(hpcd); 02230 #else 02231 HAL_PCD_SetupStageCallback(hpcd); 02232 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02233 02234 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U)) 02235 { 02236 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 02237 } 02238 02239 return HAL_OK; 02240 } 02241 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 02242 02243 02244 /** 02245 * @} 02246 */ 02247 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 02248 #endif /* HAL_PCD_MODULE_ENABLED */ 02249 02250 /** 02251 * @} 02252 */ 02253 02254 /** 02255 * @} 02256 */