STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_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) 2017 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 "stm32h7xx_hal.h" 00059 00060 /** @addtogroup STM32H7xx_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 00228 /* Activate LPM */ 00229 if (hpcd->Init.lpm_enable == 1U) 00230 { 00231 (void)HAL_PCDEx_ActivateLPM(hpcd); 00232 } 00233 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 01111 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 01112 } 01113 01114 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) 01115 { 01116 epnum = 0U; 01117 01118 /* Read in the device interrupt bits */ 01119 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); 01120 01121 while (ep_intr != 0U) 01122 { 01123 if ((ep_intr & 0x1U) != 0U) 01124 { 01125 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum); 01126 01127 if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) 01128 { 01129 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); 01130 (void)PCD_EP_OutXfrComplete_int(hpcd, epnum); 01131 } 01132 01133 if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) 01134 { 01135 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); 01136 /* Class B setup phase done for previous decoded setup */ 01137 (void)PCD_EP_OutSetupPacket_int(hpcd, epnum); 01138 } 01139 01140 if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) 01141 { 01142 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); 01143 } 01144 01145 /* Clear Status Phase Received interrupt */ 01146 if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) 01147 { 01148 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 01149 } 01150 01151 /* Clear OUT NAK interrupt */ 01152 if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK) 01153 { 01154 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK); 01155 } 01156 } 01157 epnum++; 01158 ep_intr >>= 1U; 01159 } 01160 } 01161 01162 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) 01163 { 01164 /* Read in the device interrupt bits */ 01165 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); 01166 01167 epnum = 0U; 01168 01169 while (ep_intr != 0U) 01170 { 01171 if ((ep_intr & 0x1U) != 0U) /* In ITR */ 01172 { 01173 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum); 01174 01175 if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) 01176 { 01177 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); 01178 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 01179 01180 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); 01181 01182 if (hpcd->Init.dma_enable == 1U) 01183 { 01184 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; 01185 01186 /* this is ZLP, so prepare EP0 for next setup */ 01187 if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U)) 01188 { 01189 /* prepare to rx more setup packets */ 01190 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 01191 } 01192 } 01193 01194 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01195 hpcd->DataInStageCallback(hpcd, (uint8_t)epnum); 01196 #else 01197 HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum); 01198 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01199 } 01200 if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) 01201 { 01202 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); 01203 } 01204 if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) 01205 { 01206 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); 01207 } 01208 if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) 01209 { 01210 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); 01211 } 01212 if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) 01213 { 01214 (void)USB_FlushTxFifo(USBx, epnum); 01215 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); 01216 } 01217 if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) 01218 { 01219 (void)PCD_WriteEmptyTxFifo(hpcd, epnum); 01220 } 01221 } 01222 epnum++; 01223 ep_intr >>= 1U; 01224 } 01225 } 01226 01227 /* Handle Resume Interrupt */ 01228 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) 01229 { 01230 /* Clear the Remote Wake-up Signaling */ 01231 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 01232 01233 if (hpcd->LPM_State == LPM_L1) 01234 { 01235 hpcd->LPM_State = LPM_L0; 01236 01237 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01238 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); 01239 #else 01240 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); 01241 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01242 } 01243 else 01244 { 01245 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01246 hpcd->ResumeCallback(hpcd); 01247 #else 01248 HAL_PCD_ResumeCallback(hpcd); 01249 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01250 } 01251 01252 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); 01253 } 01254 01255 /* Handle Suspend Interrupt */ 01256 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) 01257 { 01258 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) 01259 { 01260 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01261 hpcd->SuspendCallback(hpcd); 01262 #else 01263 HAL_PCD_SuspendCallback(hpcd); 01264 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01265 } 01266 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); 01267 } 01268 01269 /* Handle LPM Interrupt */ 01270 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) 01271 { 01272 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); 01273 01274 if (hpcd->LPM_State == LPM_L0) 01275 { 01276 hpcd->LPM_State = LPM_L1; 01277 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U; 01278 01279 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01280 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); 01281 #else 01282 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); 01283 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01284 } 01285 else 01286 { 01287 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01288 hpcd->SuspendCallback(hpcd); 01289 #else 01290 HAL_PCD_SuspendCallback(hpcd); 01291 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01292 } 01293 } 01294 01295 /* Handle Reset Interrupt */ 01296 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) 01297 { 01298 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 01299 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U); 01300 01301 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 01302 { 01303 USBx_INEP(i)->DIEPINT = 0xFB7FU; 01304 USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; 01305 USBx_OUTEP(i)->DOEPINT = 0xFB7FU; 01306 USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; 01307 USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; 01308 } 01309 USBx_DEVICE->DAINTMSK |= 0x10001U; 01310 01311 if (hpcd->Init.use_dedicated_ep1 != 0U) 01312 { 01313 USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM | 01314 USB_OTG_DOEPMSK_XFRCM | 01315 USB_OTG_DOEPMSK_EPDM; 01316 01317 USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM | 01318 USB_OTG_DIEPMSK_XFRCM | 01319 USB_OTG_DIEPMSK_EPDM; 01320 } 01321 else 01322 { 01323 USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM | 01324 USB_OTG_DOEPMSK_XFRCM | 01325 USB_OTG_DOEPMSK_EPDM | 01326 USB_OTG_DOEPMSK_OTEPSPRM | 01327 USB_OTG_DOEPMSK_NAKM; 01328 01329 USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM | 01330 USB_OTG_DIEPMSK_XFRCM | 01331 USB_OTG_DIEPMSK_EPDM; 01332 } 01333 01334 /* Set Default Address to 0 */ 01335 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; 01336 01337 /* setup EP0 to receive SETUP packets */ 01338 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, 01339 (uint8_t *)hpcd->Setup); 01340 01341 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); 01342 } 01343 01344 /* Handle Enumeration done Interrupt */ 01345 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) 01346 { 01347 (void)USB_ActivateSetup(hpcd->Instance); 01348 hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance); 01349 01350 /* Set USB Turnaround time */ 01351 (void)USB_SetTurnaroundTime(hpcd->Instance, 01352 HAL_RCC_GetHCLKFreq(), 01353 (uint8_t)hpcd->Init.speed); 01354 01355 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01356 hpcd->ResetCallback(hpcd); 01357 #else 01358 HAL_PCD_ResetCallback(hpcd); 01359 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01360 01361 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); 01362 } 01363 01364 /* Handle SOF Interrupt */ 01365 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) 01366 { 01367 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01368 hpcd->SOFCallback(hpcd); 01369 #else 01370 HAL_PCD_SOFCallback(hpcd); 01371 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01372 01373 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); 01374 } 01375 01376 /* Handle Incomplete ISO IN Interrupt */ 01377 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) 01378 { 01379 /* Keep application checking the corresponding Iso IN endpoint 01380 causing the incomplete Interrupt */ 01381 epnum = 0U; 01382 01383 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01384 hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum); 01385 #else 01386 HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum); 01387 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01388 01389 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); 01390 } 01391 01392 /* Handle Incomplete ISO OUT Interrupt */ 01393 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) 01394 { 01395 /* Keep application checking the corresponding Iso OUT endpoint 01396 causing the incomplete Interrupt */ 01397 epnum = 0U; 01398 01399 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01400 hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); 01401 #else 01402 HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); 01403 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01404 01405 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); 01406 } 01407 01408 /* Handle Connection event Interrupt */ 01409 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) 01410 { 01411 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01412 hpcd->ConnectCallback(hpcd); 01413 #else 01414 HAL_PCD_ConnectCallback(hpcd); 01415 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01416 01417 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); 01418 } 01419 01420 /* Handle Disconnection event Interrupt */ 01421 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) 01422 { 01423 temp = hpcd->Instance->GOTGINT; 01424 01425 if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) 01426 { 01427 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01428 hpcd->DisconnectCallback(hpcd); 01429 #else 01430 HAL_PCD_DisconnectCallback(hpcd); 01431 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01432 } 01433 hpcd->Instance->GOTGINT |= temp; 01434 } 01435 } 01436 } 01437 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 01438 01439 01440 /** 01441 * @brief Data OUT stage callback. 01442 * @param hpcd PCD handle 01443 * @param epnum endpoint number 01444 * @retval None 01445 */ 01446 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01447 { 01448 /* Prevent unused argument(s) compilation warning */ 01449 UNUSED(hpcd); 01450 UNUSED(epnum); 01451 01452 /* NOTE : This function should not be modified, when the callback is needed, 01453 the HAL_PCD_DataOutStageCallback could be implemented in the user file 01454 */ 01455 } 01456 01457 /** 01458 * @brief Data IN stage callback 01459 * @param hpcd PCD handle 01460 * @param epnum endpoint number 01461 * @retval None 01462 */ 01463 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01464 { 01465 /* Prevent unused argument(s) compilation warning */ 01466 UNUSED(hpcd); 01467 UNUSED(epnum); 01468 01469 /* NOTE : This function should not be modified, when the callback is needed, 01470 the HAL_PCD_DataInStageCallback could be implemented in the user file 01471 */ 01472 } 01473 /** 01474 * @brief Setup stage callback 01475 * @param hpcd PCD handle 01476 * @retval None 01477 */ 01478 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) 01479 { 01480 /* Prevent unused argument(s) compilation warning */ 01481 UNUSED(hpcd); 01482 01483 /* NOTE : This function should not be modified, when the callback is needed, 01484 the HAL_PCD_SetupStageCallback could be implemented in the user file 01485 */ 01486 } 01487 01488 /** 01489 * @brief USB Start Of Frame callback. 01490 * @param hpcd PCD handle 01491 * @retval None 01492 */ 01493 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) 01494 { 01495 /* Prevent unused argument(s) compilation warning */ 01496 UNUSED(hpcd); 01497 01498 /* NOTE : This function should not be modified, when the callback is needed, 01499 the HAL_PCD_SOFCallback could be implemented in the user file 01500 */ 01501 } 01502 01503 /** 01504 * @brief USB Reset callback. 01505 * @param hpcd PCD handle 01506 * @retval None 01507 */ 01508 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) 01509 { 01510 /* Prevent unused argument(s) compilation warning */ 01511 UNUSED(hpcd); 01512 01513 /* NOTE : This function should not be modified, when the callback is needed, 01514 the HAL_PCD_ResetCallback could be implemented in the user file 01515 */ 01516 } 01517 01518 /** 01519 * @brief Suspend event callback. 01520 * @param hpcd PCD handle 01521 * @retval None 01522 */ 01523 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) 01524 { 01525 /* Prevent unused argument(s) compilation warning */ 01526 UNUSED(hpcd); 01527 01528 /* NOTE : This function should not be modified, when the callback is needed, 01529 the HAL_PCD_SuspendCallback could be implemented in the user file 01530 */ 01531 } 01532 01533 /** 01534 * @brief Resume event callback. 01535 * @param hpcd PCD handle 01536 * @retval None 01537 */ 01538 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) 01539 { 01540 /* Prevent unused argument(s) compilation warning */ 01541 UNUSED(hpcd); 01542 01543 /* NOTE : This function should not be modified, when the callback is needed, 01544 the HAL_PCD_ResumeCallback could be implemented in the user file 01545 */ 01546 } 01547 01548 /** 01549 * @brief Incomplete ISO OUT callback. 01550 * @param hpcd PCD handle 01551 * @param epnum endpoint number 01552 * @retval None 01553 */ 01554 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01555 { 01556 /* Prevent unused argument(s) compilation warning */ 01557 UNUSED(hpcd); 01558 UNUSED(epnum); 01559 01560 /* NOTE : This function should not be modified, when the callback is needed, 01561 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file 01562 */ 01563 } 01564 01565 /** 01566 * @brief Incomplete ISO IN callback. 01567 * @param hpcd PCD handle 01568 * @param epnum endpoint number 01569 * @retval None 01570 */ 01571 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01572 { 01573 /* Prevent unused argument(s) compilation warning */ 01574 UNUSED(hpcd); 01575 UNUSED(epnum); 01576 01577 /* NOTE : This function should not be modified, when the callback is needed, 01578 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file 01579 */ 01580 } 01581 01582 /** 01583 * @brief Connection event callback. 01584 * @param hpcd PCD handle 01585 * @retval None 01586 */ 01587 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) 01588 { 01589 /* Prevent unused argument(s) compilation warning */ 01590 UNUSED(hpcd); 01591 01592 /* NOTE : This function should not be modified, when the callback is needed, 01593 the HAL_PCD_ConnectCallback could be implemented in the user file 01594 */ 01595 } 01596 01597 /** 01598 * @brief Disconnection event callback. 01599 * @param hpcd PCD handle 01600 * @retval None 01601 */ 01602 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) 01603 { 01604 /* Prevent unused argument(s) compilation warning */ 01605 UNUSED(hpcd); 01606 01607 /* NOTE : This function should not be modified, when the callback is needed, 01608 the HAL_PCD_DisconnectCallback could be implemented in the user file 01609 */ 01610 } 01611 01612 /** 01613 * @} 01614 */ 01615 01616 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions 01617 * @brief management functions 01618 * 01619 @verbatim 01620 =============================================================================== 01621 ##### Peripheral Control functions ##### 01622 =============================================================================== 01623 [..] 01624 This subsection provides a set of functions allowing to control the PCD data 01625 transfers. 01626 01627 @endverbatim 01628 * @{ 01629 */ 01630 01631 /** 01632 * @brief Connect the USB device 01633 * @param hpcd PCD handle 01634 * @retval HAL status 01635 */ 01636 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) 01637 { 01638 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01639 01640 __HAL_LOCK(hpcd); 01641 01642 if ((hpcd->Init.battery_charging_enable == 1U) && 01643 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY)) 01644 { 01645 /* Enable USB Transceiver */ 01646 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; 01647 } 01648 (void)USB_DevConnect(hpcd->Instance); 01649 __HAL_UNLOCK(hpcd); 01650 01651 return HAL_OK; 01652 } 01653 01654 /** 01655 * @brief Disconnect the USB device. 01656 * @param hpcd PCD handle 01657 * @retval HAL status 01658 */ 01659 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) 01660 { 01661 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01662 01663 __HAL_LOCK(hpcd); 01664 (void)USB_DevDisconnect(hpcd->Instance); 01665 01666 if ((hpcd->Init.battery_charging_enable == 1U) && 01667 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY)) 01668 { 01669 /* Disable USB Transceiver */ 01670 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); 01671 } 01672 01673 __HAL_UNLOCK(hpcd); 01674 01675 return HAL_OK; 01676 } 01677 01678 /** 01679 * @brief Set the USB Device address. 01680 * @param hpcd PCD handle 01681 * @param address new device address 01682 * @retval HAL status 01683 */ 01684 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) 01685 { 01686 __HAL_LOCK(hpcd); 01687 hpcd->USB_Address = address; 01688 (void)USB_SetDevAddress(hpcd->Instance, address); 01689 __HAL_UNLOCK(hpcd); 01690 01691 return HAL_OK; 01692 } 01693 /** 01694 * @brief Open and configure an endpoint. 01695 * @param hpcd PCD handle 01696 * @param ep_addr endpoint address 01697 * @param ep_mps endpoint max packet size 01698 * @param ep_type endpoint type 01699 * @retval HAL status 01700 */ 01701 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, 01702 uint16_t ep_mps, uint8_t ep_type) 01703 { 01704 HAL_StatusTypeDef ret = HAL_OK; 01705 PCD_EPTypeDef *ep; 01706 01707 if ((ep_addr & 0x80U) == 0x80U) 01708 { 01709 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01710 ep->is_in = 1U; 01711 } 01712 else 01713 { 01714 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01715 ep->is_in = 0U; 01716 } 01717 01718 ep->num = ep_addr & EP_ADDR_MSK; 01719 ep->maxpacket = ep_mps; 01720 ep->type = ep_type; 01721 01722 if (ep->is_in != 0U) 01723 { 01724 /* Assign a Tx FIFO */ 01725 ep->tx_fifo_num = ep->num; 01726 } 01727 /* Set initial data PID. */ 01728 if (ep_type == EP_TYPE_BULK) 01729 { 01730 ep->data_pid_start = 0U; 01731 } 01732 01733 __HAL_LOCK(hpcd); 01734 (void)USB_ActivateEndpoint(hpcd->Instance, ep); 01735 __HAL_UNLOCK(hpcd); 01736 01737 return ret; 01738 } 01739 01740 /** 01741 * @brief Deactivate an endpoint. 01742 * @param hpcd PCD handle 01743 * @param ep_addr endpoint address 01744 * @retval HAL status 01745 */ 01746 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01747 { 01748 PCD_EPTypeDef *ep; 01749 01750 if ((ep_addr & 0x80U) == 0x80U) 01751 { 01752 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01753 ep->is_in = 1U; 01754 } 01755 else 01756 { 01757 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01758 ep->is_in = 0U; 01759 } 01760 ep->num = ep_addr & EP_ADDR_MSK; 01761 01762 __HAL_LOCK(hpcd); 01763 (void)USB_DeactivateEndpoint(hpcd->Instance, ep); 01764 __HAL_UNLOCK(hpcd); 01765 return HAL_OK; 01766 } 01767 01768 01769 /** 01770 * @brief Receive an amount of data. 01771 * @param hpcd PCD handle 01772 * @param ep_addr endpoint address 01773 * @param pBuf pointer to the reception buffer 01774 * @param len amount of data to be received 01775 * @retval HAL status 01776 */ 01777 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01778 { 01779 PCD_EPTypeDef *ep; 01780 01781 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01782 01783 /*setup and start the Xfer */ 01784 ep->xfer_buff = pBuf; 01785 ep->xfer_len = len; 01786 ep->xfer_count = 0U; 01787 ep->is_in = 0U; 01788 ep->num = ep_addr & EP_ADDR_MSK; 01789 01790 if (hpcd->Init.dma_enable == 1U) 01791 { 01792 ep->dma_addr = (uint32_t)pBuf; 01793 } 01794 01795 if ((ep_addr & EP_ADDR_MSK) == 0U) 01796 { 01797 (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01798 } 01799 else 01800 { 01801 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01802 } 01803 01804 return HAL_OK; 01805 } 01806 01807 /** 01808 * @brief Get Received Data Size 01809 * @param hpcd PCD handle 01810 * @param ep_addr endpoint address 01811 * @retval Data Size 01812 */ 01813 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01814 { 01815 return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; 01816 } 01817 /** 01818 * @brief Send an amount of data 01819 * @param hpcd PCD handle 01820 * @param ep_addr endpoint address 01821 * @param pBuf pointer to the transmission buffer 01822 * @param len amount of data to be sent 01823 * @retval HAL status 01824 */ 01825 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01826 { 01827 PCD_EPTypeDef *ep; 01828 01829 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01830 01831 /*setup and start the Xfer */ 01832 ep->xfer_buff = pBuf; 01833 ep->xfer_len = len; 01834 ep->xfer_count = 0U; 01835 ep->is_in = 1U; 01836 ep->num = ep_addr & EP_ADDR_MSK; 01837 01838 if (hpcd->Init.dma_enable == 1U) 01839 { 01840 ep->dma_addr = (uint32_t)pBuf; 01841 } 01842 01843 if ((ep_addr & EP_ADDR_MSK) == 0U) 01844 { 01845 (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01846 } 01847 else 01848 { 01849 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); 01850 } 01851 01852 return HAL_OK; 01853 } 01854 01855 /** 01856 * @brief Set a STALL condition over an endpoint 01857 * @param hpcd PCD handle 01858 * @param ep_addr endpoint address 01859 * @retval HAL status 01860 */ 01861 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01862 { 01863 PCD_EPTypeDef *ep; 01864 01865 if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) 01866 { 01867 return HAL_ERROR; 01868 } 01869 01870 if ((0x80U & ep_addr) == 0x80U) 01871 { 01872 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01873 ep->is_in = 1U; 01874 } 01875 else 01876 { 01877 ep = &hpcd->OUT_ep[ep_addr]; 01878 ep->is_in = 0U; 01879 } 01880 01881 ep->is_stall = 1U; 01882 ep->num = ep_addr & EP_ADDR_MSK; 01883 01884 __HAL_LOCK(hpcd); 01885 01886 (void)USB_EPSetStall(hpcd->Instance, ep); 01887 01888 if ((ep_addr & EP_ADDR_MSK) == 0U) 01889 { 01890 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); 01891 } 01892 01893 __HAL_UNLOCK(hpcd); 01894 01895 return HAL_OK; 01896 } 01897 01898 /** 01899 * @brief Clear a STALL condition over in an endpoint 01900 * @param hpcd PCD handle 01901 * @param ep_addr endpoint address 01902 * @retval HAL status 01903 */ 01904 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01905 { 01906 PCD_EPTypeDef *ep; 01907 01908 if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) 01909 { 01910 return HAL_ERROR; 01911 } 01912 01913 if ((0x80U & ep_addr) == 0x80U) 01914 { 01915 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01916 ep->is_in = 1U; 01917 } 01918 else 01919 { 01920 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01921 ep->is_in = 0U; 01922 } 01923 01924 ep->is_stall = 0U; 01925 ep->num = ep_addr & EP_ADDR_MSK; 01926 01927 __HAL_LOCK(hpcd); 01928 (void)USB_EPClearStall(hpcd->Instance, ep); 01929 __HAL_UNLOCK(hpcd); 01930 01931 return HAL_OK; 01932 } 01933 01934 /** 01935 * @brief Abort an USB EP transaction. 01936 * @param hpcd PCD handle 01937 * @param ep_addr endpoint address 01938 * @retval HAL status 01939 */ 01940 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01941 { 01942 HAL_StatusTypeDef ret; 01943 PCD_EPTypeDef *ep; 01944 01945 if ((0x80U & ep_addr) == 0x80U) 01946 { 01947 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01948 } 01949 else 01950 { 01951 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01952 } 01953 01954 /* Stop Xfer */ 01955 ret = USB_EPStopXfer(hpcd->Instance, ep); 01956 01957 return ret; 01958 } 01959 01960 /** 01961 * @brief Flush an endpoint 01962 * @param hpcd PCD handle 01963 * @param ep_addr endpoint address 01964 * @retval HAL status 01965 */ 01966 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01967 { 01968 __HAL_LOCK(hpcd); 01969 01970 if ((ep_addr & 0x80U) == 0x80U) 01971 { 01972 (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK); 01973 } 01974 else 01975 { 01976 (void)USB_FlushRxFifo(hpcd->Instance); 01977 } 01978 01979 __HAL_UNLOCK(hpcd); 01980 01981 return HAL_OK; 01982 } 01983 01984 /** 01985 * @brief Activate remote wakeup signalling 01986 * @param hpcd PCD handle 01987 * @retval HAL status 01988 */ 01989 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 01990 { 01991 return (USB_ActivateRemoteWakeup(hpcd->Instance)); 01992 } 01993 01994 /** 01995 * @brief De-activate remote wakeup signalling. 01996 * @param hpcd PCD handle 01997 * @retval HAL status 01998 */ 01999 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 02000 { 02001 return (USB_DeActivateRemoteWakeup(hpcd->Instance)); 02002 } 02003 02004 /** 02005 * @} 02006 */ 02007 02008 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions 02009 * @brief Peripheral State functions 02010 * 02011 @verbatim 02012 =============================================================================== 02013 ##### Peripheral State functions ##### 02014 =============================================================================== 02015 [..] 02016 This subsection permits to get in run-time the status of the peripheral 02017 and the data flow. 02018 02019 @endverbatim 02020 * @{ 02021 */ 02022 02023 /** 02024 * @brief Return the PCD handle state. 02025 * @param hpcd PCD handle 02026 * @retval HAL state 02027 */ 02028 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) 02029 { 02030 return hpcd->State; 02031 } 02032 02033 /** 02034 * @brief Set the USB Device high speed test mode. 02035 * @param hpcd PCD handle 02036 * @param address test mode 02037 * @retval HAL status 02038 */ 02039 HAL_StatusTypeDef HAL_PCD_SetTestMode(PCD_HandleTypeDef *hpcd, uint8_t testmode) 02040 { 02041 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02042 uint32_t USBx_BASE = (uint32_t)USBx; 02043 02044 switch (testmode) 02045 { 02046 case TEST_J: 02047 case TEST_K: 02048 case TEST_SE0_NAK: 02049 case TEST_PACKET: 02050 case TEST_FORCE_EN: 02051 USBx_DEVICE->DCTL |= testmode << 4; 02052 break; 02053 02054 default: 02055 break; 02056 } 02057 02058 return HAL_OK; 02059 } 02060 /** 02061 * @} 02062 */ 02063 02064 /** 02065 * @} 02066 */ 02067 02068 /* Private functions ---------------------------------------------------------*/ 02069 /** @addtogroup PCD_Private_Functions 02070 * @{ 02071 */ 02072 #if defined (USB_OTG_FS) || defined (USB_OTG_HS) 02073 /** 02074 * @brief Check FIFO for the next packet to be loaded. 02075 * @param hpcd PCD handle 02076 * @param epnum endpoint number 02077 * @retval HAL status 02078 */ 02079 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02080 { 02081 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02082 uint32_t USBx_BASE = (uint32_t)USBx; 02083 USB_OTG_EPTypeDef *ep; 02084 uint32_t len; 02085 uint32_t len32b; 02086 uint32_t fifoemptymsk; 02087 02088 ep = &hpcd->IN_ep[epnum]; 02089 02090 if (ep->xfer_count > ep->xfer_len) 02091 { 02092 return HAL_ERROR; 02093 } 02094 02095 len = ep->xfer_len - ep->xfer_count; 02096 02097 if (len > ep->maxpacket) 02098 { 02099 len = ep->maxpacket; 02100 } 02101 02102 len32b = (len + 3U) / 4U; 02103 02104 while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) && 02105 (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U)) 02106 { 02107 /* Write the FIFO */ 02108 len = ep->xfer_len - ep->xfer_count; 02109 02110 if (len > ep->maxpacket) 02111 { 02112 len = ep->maxpacket; 02113 } 02114 len32b = (len + 3U) / 4U; 02115 02116 (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len, 02117 (uint8_t)hpcd->Init.dma_enable); 02118 02119 ep->xfer_buff += len; 02120 ep->xfer_count += len; 02121 } 02122 02123 if (ep->xfer_len <= ep->xfer_count) 02124 { 02125 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); 02126 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 02127 } 02128 02129 return HAL_OK; 02130 } 02131 02132 02133 /** 02134 * @brief process EP OUT transfer complete interrupt. 02135 * @param hpcd PCD handle 02136 * @param epnum endpoint number 02137 * @retval HAL status 02138 */ 02139 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02140 { 02141 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02142 uint32_t USBx_BASE = (uint32_t)USBx; 02143 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U); 02144 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; 02145 02146 if (hpcd->Init.dma_enable == 1U) 02147 { 02148 if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */ 02149 { 02150 /* StupPktRcvd = 1 this is a setup packet */ 02151 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && 02152 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) 02153 { 02154 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02155 } 02156 } 02157 else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */ 02158 { 02159 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 02160 } 02161 else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U) 02162 { 02163 /* StupPktRcvd = 1 this is a setup packet */ 02164 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && 02165 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) 02166 { 02167 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02168 } 02169 else 02170 { 02171 /* out data packet received over EP0 */ 02172 hpcd->OUT_ep[epnum].xfer_count = 02173 hpcd->OUT_ep[epnum].maxpacket - 02174 (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); 02175 02176 hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; 02177 02178 if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U)) 02179 { 02180 /* this is ZLP, so prepare EP0 for next setup */ 02181 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 02182 } 02183 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02184 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02185 #else 02186 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02187 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02188 } 02189 } 02190 else 02191 { 02192 /* ... */ 02193 } 02194 } 02195 else 02196 { 02197 if (gSNPSiD == USB_OTG_CORE_ID_310A) 02198 { 02199 /* StupPktRcvd = 1 this is a setup packet */ 02200 if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX) 02201 { 02202 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02203 } 02204 else 02205 { 02206 if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) 02207 { 02208 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 02209 } 02210 02211 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02212 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02213 #else 02214 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02215 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02216 } 02217 } 02218 else 02219 { 02220 if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U)) 02221 { 02222 /* this is ZLP, so prepare EP0 for next setup */ 02223 (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup); 02224 } 02225 02226 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02227 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02228 #else 02229 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02230 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02231 } 02232 } 02233 02234 return HAL_OK; 02235 } 02236 02237 02238 /** 02239 * @brief process EP OUT setup packet received interrupt. 02240 * @param hpcd PCD handle 02241 * @param epnum endpoint number 02242 * @retval HAL status 02243 */ 02244 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02245 { 02246 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02247 uint32_t USBx_BASE = (uint32_t)USBx; 02248 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U); 02249 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; 02250 02251 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && 02252 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) 02253 { 02254 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02255 } 02256 02257 /* Inform the upper layer that a setup packet is available */ 02258 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02259 hpcd->SetupStageCallback(hpcd); 02260 #else 02261 HAL_PCD_SetupStageCallback(hpcd); 02262 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02263 02264 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U)) 02265 { 02266 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); 02267 } 02268 02269 return HAL_OK; 02270 } 02271 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 02272 02273 02274 /** 02275 * @} 02276 */ 02277 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ 02278 #endif /* HAL_PCD_MODULE_ENABLED */ 02279 02280 /** 02281 * @} 02282 */ 02283 02284 /** 02285 * @} 02286 */