STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_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_CLK_ENABLE(); For USB Device only FS peripheral 00041 00042 (##) Initialize the related GPIO clocks 00043 (##) Configure PCD pin-out 00044 (##) Configure PCD NVIC interrupt 00045 00046 (#)Associate the Upper USB device stack to the HAL PCD Driver: 00047 (##) hpcd.pData = pdev; 00048 00049 (#)Enable PCD transmission and reception: 00050 (##) HAL_PCD_Start(); 00051 00052 @endverbatim 00053 ****************************************************************************** 00054 */ 00055 00056 /* Includes ------------------------------------------------------------------*/ 00057 #include "stm32l4xx_hal.h" 00058 00059 /** @addtogroup STM32L4xx_HAL_Driver 00060 * @{ 00061 */ 00062 00063 /** @defgroup PCD PCD 00064 * @brief PCD HAL module driver 00065 * @{ 00066 */ 00067 00068 #ifdef HAL_PCD_MODULE_ENABLED 00069 00070 #if defined (USB) || defined (USB_OTG_FS) 00071 00072 /* Private types -------------------------------------------------------------*/ 00073 /* Private variables ---------------------------------------------------------*/ 00074 /* Private constants ---------------------------------------------------------*/ 00075 /* Private macros ------------------------------------------------------------*/ 00076 /** @defgroup PCD_Private_Macros PCD Private Macros 00077 * @{ 00078 */ 00079 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) 00080 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) 00081 /** 00082 * @} 00083 */ 00084 00085 /* Private functions prototypes ----------------------------------------------*/ 00086 /** @defgroup PCD_Private_Functions PCD Private Functions 00087 * @{ 00088 */ 00089 #if defined (USB_OTG_FS) 00090 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00091 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00092 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00093 #endif /* defined (USB_OTG_FS) */ 00094 00095 #if defined (USB) 00096 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd); 00097 #if (USE_USB_DOUBLE_BUFFER == 1U) 00098 static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal); 00099 static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal); 00100 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ 00101 #endif /* defined (USB) */ 00102 /** 00103 * @} 00104 */ 00105 00106 /* Exported functions --------------------------------------------------------*/ 00107 /** @defgroup PCD_Exported_Functions PCD Exported Functions 00108 * @{ 00109 */ 00110 00111 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions 00112 * @brief Initialization and Configuration functions 00113 * 00114 @verbatim 00115 =============================================================================== 00116 ##### Initialization and de-initialization functions ##### 00117 =============================================================================== 00118 [..] This section provides functions allowing to: 00119 00120 @endverbatim 00121 * @{ 00122 */ 00123 00124 /** 00125 * @brief Initializes the PCD according to the specified 00126 * parameters in the PCD_InitTypeDef and initialize the associated handle. 00127 * @param hpcd PCD handle 00128 * @retval HAL status 00129 */ 00130 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) 00131 { 00132 #if defined (USB_OTG_FS) 00133 USB_OTG_GlobalTypeDef *USBx; 00134 #endif /* defined (USB_OTG_FS) */ 00135 uint8_t i; 00136 00137 /* Check the PCD handle allocation */ 00138 if (hpcd == NULL) 00139 { 00140 return HAL_ERROR; 00141 } 00142 00143 /* Check the parameters */ 00144 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); 00145 00146 #if defined (USB_OTG_FS) 00147 USBx = hpcd->Instance; 00148 #endif /* defined (USB_OTG_FS) */ 00149 00150 if (hpcd->State == HAL_PCD_STATE_RESET) 00151 { 00152 /* Allocate lock resource and initialize it */ 00153 hpcd->Lock = HAL_UNLOCKED; 00154 00155 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00156 hpcd->SOFCallback = HAL_PCD_SOFCallback; 00157 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; 00158 hpcd->ResetCallback = HAL_PCD_ResetCallback; 00159 hpcd->SuspendCallback = HAL_PCD_SuspendCallback; 00160 hpcd->ResumeCallback = HAL_PCD_ResumeCallback; 00161 hpcd->ConnectCallback = HAL_PCD_ConnectCallback; 00162 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; 00163 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; 00164 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; 00165 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; 00166 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; 00167 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; 00168 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; 00169 00170 if (hpcd->MspInitCallback == NULL) 00171 { 00172 hpcd->MspInitCallback = HAL_PCD_MspInit; 00173 } 00174 00175 /* Init the low level hardware */ 00176 hpcd->MspInitCallback(hpcd); 00177 #else 00178 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ 00179 HAL_PCD_MspInit(hpcd); 00180 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */ 00181 } 00182 00183 hpcd->State = HAL_PCD_STATE_BUSY; 00184 00185 #if defined (USB_OTG_FS) 00186 /* Disable DMA mode for FS instance */ 00187 if ((USBx->CID & (0x1U << 8)) == 0U) 00188 { 00189 hpcd->Init.dma_enable = 0U; 00190 } 00191 #endif /* defined (USB_OTG_FS) */ 00192 00193 /* Disable the Interrupts */ 00194 __HAL_PCD_DISABLE(hpcd); 00195 00196 /*Init the Core (common init.) */ 00197 if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK) 00198 { 00199 hpcd->State = HAL_PCD_STATE_ERROR; 00200 return HAL_ERROR; 00201 } 00202 00203 /* Force Device Mode*/ 00204 (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE); 00205 00206 /* Init endpoints structures */ 00207 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 00208 { 00209 /* Init ep structure */ 00210 hpcd->IN_ep[i].is_in = 1U; 00211 hpcd->IN_ep[i].num = i; 00212 hpcd->IN_ep[i].tx_fifo_num = i; 00213 /* Control until ep is activated */ 00214 hpcd->IN_ep[i].type = EP_TYPE_CTRL; 00215 hpcd->IN_ep[i].maxpacket = 0U; 00216 hpcd->IN_ep[i].xfer_buff = 0U; 00217 hpcd->IN_ep[i].xfer_len = 0U; 00218 } 00219 00220 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 00221 { 00222 hpcd->OUT_ep[i].is_in = 0U; 00223 hpcd->OUT_ep[i].num = i; 00224 /* Control until ep is activated */ 00225 hpcd->OUT_ep[i].type = EP_TYPE_CTRL; 00226 hpcd->OUT_ep[i].maxpacket = 0U; 00227 hpcd->OUT_ep[i].xfer_buff = 0U; 00228 hpcd->OUT_ep[i].xfer_len = 0U; 00229 } 00230 00231 /* Init Device */ 00232 if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK) 00233 { 00234 hpcd->State = HAL_PCD_STATE_ERROR; 00235 return HAL_ERROR; 00236 } 00237 00238 hpcd->USB_Address = 0U; 00239 hpcd->State = HAL_PCD_STATE_READY; 00240 00241 /* Activate LPM */ 00242 if (hpcd->Init.lpm_enable == 1U) 00243 { 00244 (void)HAL_PCDEx_ActivateLPM(hpcd); 00245 } 00246 00247 (void)USB_DevDisconnect(hpcd->Instance); 00248 00249 return HAL_OK; 00250 } 00251 00252 /** 00253 * @brief DeInitializes the PCD peripheral. 00254 * @param hpcd PCD handle 00255 * @retval HAL status 00256 */ 00257 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) 00258 { 00259 /* Check the PCD handle allocation */ 00260 if (hpcd == NULL) 00261 { 00262 return HAL_ERROR; 00263 } 00264 00265 hpcd->State = HAL_PCD_STATE_BUSY; 00266 00267 /* Stop Device */ 00268 if (USB_StopDevice(hpcd->Instance) != HAL_OK) 00269 { 00270 return HAL_ERROR; 00271 } 00272 00273 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00274 if (hpcd->MspDeInitCallback == NULL) 00275 { 00276 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */ 00277 } 00278 00279 /* DeInit the low level hardware */ 00280 hpcd->MspDeInitCallback(hpcd); 00281 #else 00282 /* DeInit the low level hardware: CLOCK, NVIC.*/ 00283 HAL_PCD_MspDeInit(hpcd); 00284 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00285 00286 hpcd->State = HAL_PCD_STATE_RESET; 00287 00288 return HAL_OK; 00289 } 00290 00291 /** 00292 * @brief Initializes the PCD MSP. 00293 * @param hpcd PCD handle 00294 * @retval None 00295 */ 00296 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) 00297 { 00298 /* Prevent unused argument(s) compilation warning */ 00299 UNUSED(hpcd); 00300 00301 /* NOTE : This function should not be modified, when the callback is needed, 00302 the HAL_PCD_MspInit could be implemented in the user file 00303 */ 00304 } 00305 00306 /** 00307 * @brief DeInitializes PCD MSP. 00308 * @param hpcd PCD handle 00309 * @retval None 00310 */ 00311 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) 00312 { 00313 /* Prevent unused argument(s) compilation warning */ 00314 UNUSED(hpcd); 00315 00316 /* NOTE : This function should not be modified, when the callback is needed, 00317 the HAL_PCD_MspDeInit could be implemented in the user file 00318 */ 00319 } 00320 00321 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00322 /** 00323 * @brief Register a User USB PCD Callback 00324 * To be used instead of the weak predefined callback 00325 * @param hpcd USB PCD handle 00326 * @param CallbackID ID of the callback to be registered 00327 * This parameter can be one of the following values: 00328 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID 00329 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID 00330 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID 00331 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID 00332 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID 00333 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID 00334 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID 00335 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID 00336 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID 00337 * @param pCallback pointer to the Callback function 00338 * @retval HAL status 00339 */ 00340 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, 00341 HAL_PCD_CallbackIDTypeDef CallbackID, 00342 pPCD_CallbackTypeDef pCallback) 00343 { 00344 HAL_StatusTypeDef status = HAL_OK; 00345 00346 if (pCallback == NULL) 00347 { 00348 /* Update the error code */ 00349 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00350 return HAL_ERROR; 00351 } 00352 /* Process locked */ 00353 __HAL_LOCK(hpcd); 00354 00355 if (hpcd->State == HAL_PCD_STATE_READY) 00356 { 00357 switch (CallbackID) 00358 { 00359 case HAL_PCD_SOF_CB_ID : 00360 hpcd->SOFCallback = pCallback; 00361 break; 00362 00363 case HAL_PCD_SETUPSTAGE_CB_ID : 00364 hpcd->SetupStageCallback = pCallback; 00365 break; 00366 00367 case HAL_PCD_RESET_CB_ID : 00368 hpcd->ResetCallback = pCallback; 00369 break; 00370 00371 case HAL_PCD_SUSPEND_CB_ID : 00372 hpcd->SuspendCallback = pCallback; 00373 break; 00374 00375 case HAL_PCD_RESUME_CB_ID : 00376 hpcd->ResumeCallback = pCallback; 00377 break; 00378 00379 case HAL_PCD_CONNECT_CB_ID : 00380 hpcd->ConnectCallback = pCallback; 00381 break; 00382 00383 case HAL_PCD_DISCONNECT_CB_ID : 00384 hpcd->DisconnectCallback = pCallback; 00385 break; 00386 00387 case HAL_PCD_MSPINIT_CB_ID : 00388 hpcd->MspInitCallback = pCallback; 00389 break; 00390 00391 case HAL_PCD_MSPDEINIT_CB_ID : 00392 hpcd->MspDeInitCallback = pCallback; 00393 break; 00394 00395 default : 00396 /* Update the error code */ 00397 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00398 /* Return error status */ 00399 status = HAL_ERROR; 00400 break; 00401 } 00402 } 00403 else if (hpcd->State == HAL_PCD_STATE_RESET) 00404 { 00405 switch (CallbackID) 00406 { 00407 case HAL_PCD_MSPINIT_CB_ID : 00408 hpcd->MspInitCallback = pCallback; 00409 break; 00410 00411 case HAL_PCD_MSPDEINIT_CB_ID : 00412 hpcd->MspDeInitCallback = pCallback; 00413 break; 00414 00415 default : 00416 /* Update the error code */ 00417 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00418 /* Return error status */ 00419 status = HAL_ERROR; 00420 break; 00421 } 00422 } 00423 else 00424 { 00425 /* Update the error code */ 00426 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00427 /* Return error status */ 00428 status = HAL_ERROR; 00429 } 00430 00431 /* Release Lock */ 00432 __HAL_UNLOCK(hpcd); 00433 return status; 00434 } 00435 00436 /** 00437 * @brief Unregister an USB PCD Callback 00438 * USB PCD callabck is redirected to the weak predefined callback 00439 * @param hpcd USB PCD handle 00440 * @param CallbackID ID of the callback to be unregistered 00441 * This parameter can be one of the following values: 00442 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID 00443 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID 00444 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID 00445 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID 00446 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID 00447 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID 00448 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID 00449 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID 00450 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID 00451 * @retval HAL status 00452 */ 00453 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID) 00454 { 00455 HAL_StatusTypeDef status = HAL_OK; 00456 00457 /* Process locked */ 00458 __HAL_LOCK(hpcd); 00459 00460 /* Setup Legacy weak Callbacks */ 00461 if (hpcd->State == HAL_PCD_STATE_READY) 00462 { 00463 switch (CallbackID) 00464 { 00465 case HAL_PCD_SOF_CB_ID : 00466 hpcd->SOFCallback = HAL_PCD_SOFCallback; 00467 break; 00468 00469 case HAL_PCD_SETUPSTAGE_CB_ID : 00470 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; 00471 break; 00472 00473 case HAL_PCD_RESET_CB_ID : 00474 hpcd->ResetCallback = HAL_PCD_ResetCallback; 00475 break; 00476 00477 case HAL_PCD_SUSPEND_CB_ID : 00478 hpcd->SuspendCallback = HAL_PCD_SuspendCallback; 00479 break; 00480 00481 case HAL_PCD_RESUME_CB_ID : 00482 hpcd->ResumeCallback = HAL_PCD_ResumeCallback; 00483 break; 00484 00485 case HAL_PCD_CONNECT_CB_ID : 00486 hpcd->ConnectCallback = HAL_PCD_ConnectCallback; 00487 break; 00488 00489 case HAL_PCD_DISCONNECT_CB_ID : 00490 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; 00491 break; 00492 00493 case HAL_PCD_MSPINIT_CB_ID : 00494 hpcd->MspInitCallback = HAL_PCD_MspInit; 00495 break; 00496 00497 case HAL_PCD_MSPDEINIT_CB_ID : 00498 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; 00499 break; 00500 00501 default : 00502 /* Update the error code */ 00503 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00504 00505 /* Return error status */ 00506 status = HAL_ERROR; 00507 break; 00508 } 00509 } 00510 else if (hpcd->State == HAL_PCD_STATE_RESET) 00511 { 00512 switch (CallbackID) 00513 { 00514 case HAL_PCD_MSPINIT_CB_ID : 00515 hpcd->MspInitCallback = HAL_PCD_MspInit; 00516 break; 00517 00518 case HAL_PCD_MSPDEINIT_CB_ID : 00519 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; 00520 break; 00521 00522 default : 00523 /* Update the error code */ 00524 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00525 00526 /* Return error status */ 00527 status = HAL_ERROR; 00528 break; 00529 } 00530 } 00531 else 00532 { 00533 /* Update the error code */ 00534 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00535 00536 /* Return error status */ 00537 status = HAL_ERROR; 00538 } 00539 00540 /* Release Lock */ 00541 __HAL_UNLOCK(hpcd); 00542 return status; 00543 } 00544 00545 /** 00546 * @brief Register USB PCD Data OUT Stage Callback 00547 * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback 00548 * @param hpcd PCD handle 00549 * @param pCallback pointer to the USB PCD Data OUT Stage Callback function 00550 * @retval HAL status 00551 */ 00552 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, 00553 pPCD_DataOutStageCallbackTypeDef pCallback) 00554 { 00555 HAL_StatusTypeDef status = HAL_OK; 00556 00557 if (pCallback == NULL) 00558 { 00559 /* Update the error code */ 00560 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00561 00562 return HAL_ERROR; 00563 } 00564 00565 /* Process locked */ 00566 __HAL_LOCK(hpcd); 00567 00568 if (hpcd->State == HAL_PCD_STATE_READY) 00569 { 00570 hpcd->DataOutStageCallback = pCallback; 00571 } 00572 else 00573 { 00574 /* Update the error code */ 00575 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00576 00577 /* Return error status */ 00578 status = HAL_ERROR; 00579 } 00580 00581 /* Release Lock */ 00582 __HAL_UNLOCK(hpcd); 00583 00584 return status; 00585 } 00586 00587 /** 00588 * @brief Unregister the USB PCD Data OUT Stage Callback 00589 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback 00590 * @param hpcd PCD handle 00591 * @retval HAL status 00592 */ 00593 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd) 00594 { 00595 HAL_StatusTypeDef status = HAL_OK; 00596 00597 /* Process locked */ 00598 __HAL_LOCK(hpcd); 00599 00600 if (hpcd->State == HAL_PCD_STATE_READY) 00601 { 00602 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */ 00603 } 00604 else 00605 { 00606 /* Update the error code */ 00607 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00608 00609 /* Return error status */ 00610 status = HAL_ERROR; 00611 } 00612 00613 /* Release Lock */ 00614 __HAL_UNLOCK(hpcd); 00615 00616 return status; 00617 } 00618 00619 /** 00620 * @brief Register USB PCD Data IN Stage Callback 00621 * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback 00622 * @param hpcd PCD handle 00623 * @param pCallback pointer to the USB PCD Data IN Stage Callback function 00624 * @retval HAL status 00625 */ 00626 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, 00627 pPCD_DataInStageCallbackTypeDef pCallback) 00628 { 00629 HAL_StatusTypeDef status = HAL_OK; 00630 00631 if (pCallback == NULL) 00632 { 00633 /* Update the error code */ 00634 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00635 00636 return HAL_ERROR; 00637 } 00638 00639 /* Process locked */ 00640 __HAL_LOCK(hpcd); 00641 00642 if (hpcd->State == HAL_PCD_STATE_READY) 00643 { 00644 hpcd->DataInStageCallback = pCallback; 00645 } 00646 else 00647 { 00648 /* Update the error code */ 00649 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00650 00651 /* Return error status */ 00652 status = HAL_ERROR; 00653 } 00654 00655 /* Release Lock */ 00656 __HAL_UNLOCK(hpcd); 00657 00658 return status; 00659 } 00660 00661 /** 00662 * @brief Unregister the USB PCD Data IN Stage Callback 00663 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback 00664 * @param hpcd PCD handle 00665 * @retval HAL status 00666 */ 00667 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd) 00668 { 00669 HAL_StatusTypeDef status = HAL_OK; 00670 00671 /* Process locked */ 00672 __HAL_LOCK(hpcd); 00673 00674 if (hpcd->State == HAL_PCD_STATE_READY) 00675 { 00676 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */ 00677 } 00678 else 00679 { 00680 /* Update the error code */ 00681 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00682 00683 /* Return error status */ 00684 status = HAL_ERROR; 00685 } 00686 00687 /* Release Lock */ 00688 __HAL_UNLOCK(hpcd); 00689 00690 return status; 00691 } 00692 00693 /** 00694 * @brief Register USB PCD Iso OUT incomplete Callback 00695 * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback 00696 * @param hpcd PCD handle 00697 * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function 00698 * @retval HAL status 00699 */ 00700 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, 00701 pPCD_IsoOutIncpltCallbackTypeDef pCallback) 00702 { 00703 HAL_StatusTypeDef status = HAL_OK; 00704 00705 if (pCallback == NULL) 00706 { 00707 /* Update the error code */ 00708 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00709 00710 return HAL_ERROR; 00711 } 00712 00713 /* Process locked */ 00714 __HAL_LOCK(hpcd); 00715 00716 if (hpcd->State == HAL_PCD_STATE_READY) 00717 { 00718 hpcd->ISOOUTIncompleteCallback = pCallback; 00719 } 00720 else 00721 { 00722 /* Update the error code */ 00723 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00724 00725 /* Return error status */ 00726 status = HAL_ERROR; 00727 } 00728 00729 /* Release Lock */ 00730 __HAL_UNLOCK(hpcd); 00731 00732 return status; 00733 } 00734 00735 /** 00736 * @brief Unregister the USB PCD Iso OUT incomplete Callback 00737 * USB PCD Iso OUT incomplete Callback is redirected 00738 * to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback 00739 * @param hpcd PCD handle 00740 * @retval HAL status 00741 */ 00742 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd) 00743 { 00744 HAL_StatusTypeDef status = HAL_OK; 00745 00746 /* Process locked */ 00747 __HAL_LOCK(hpcd); 00748 00749 if (hpcd->State == HAL_PCD_STATE_READY) 00750 { 00751 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */ 00752 } 00753 else 00754 { 00755 /* Update the error code */ 00756 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00757 00758 /* Return error status */ 00759 status = HAL_ERROR; 00760 } 00761 00762 /* Release Lock */ 00763 __HAL_UNLOCK(hpcd); 00764 00765 return status; 00766 } 00767 00768 /** 00769 * @brief Register USB PCD Iso IN incomplete Callback 00770 * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback 00771 * @param hpcd PCD handle 00772 * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function 00773 * @retval HAL status 00774 */ 00775 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, 00776 pPCD_IsoInIncpltCallbackTypeDef pCallback) 00777 { 00778 HAL_StatusTypeDef status = HAL_OK; 00779 00780 if (pCallback == NULL) 00781 { 00782 /* Update the error code */ 00783 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00784 00785 return HAL_ERROR; 00786 } 00787 00788 /* Process locked */ 00789 __HAL_LOCK(hpcd); 00790 00791 if (hpcd->State == HAL_PCD_STATE_READY) 00792 { 00793 hpcd->ISOINIncompleteCallback = pCallback; 00794 } 00795 else 00796 { 00797 /* Update the error code */ 00798 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00799 00800 /* Return error status */ 00801 status = HAL_ERROR; 00802 } 00803 00804 /* Release Lock */ 00805 __HAL_UNLOCK(hpcd); 00806 00807 return status; 00808 } 00809 00810 /** 00811 * @brief Unregister the USB PCD Iso IN incomplete Callback 00812 * USB PCD Iso IN incomplete Callback is redirected 00813 * to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback 00814 * @param hpcd PCD handle 00815 * @retval HAL status 00816 */ 00817 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd) 00818 { 00819 HAL_StatusTypeDef status = HAL_OK; 00820 00821 /* Process locked */ 00822 __HAL_LOCK(hpcd); 00823 00824 if (hpcd->State == HAL_PCD_STATE_READY) 00825 { 00826 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */ 00827 } 00828 else 00829 { 00830 /* Update the error code */ 00831 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00832 00833 /* Return error status */ 00834 status = HAL_ERROR; 00835 } 00836 00837 /* Release Lock */ 00838 __HAL_UNLOCK(hpcd); 00839 00840 return status; 00841 } 00842 00843 /** 00844 * @brief Register USB PCD BCD Callback 00845 * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback 00846 * @param hpcd PCD handle 00847 * @param pCallback pointer to the USB PCD BCD Callback function 00848 * @retval HAL status 00849 */ 00850 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback) 00851 { 00852 HAL_StatusTypeDef status = HAL_OK; 00853 00854 if (pCallback == NULL) 00855 { 00856 /* Update the error code */ 00857 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00858 00859 return HAL_ERROR; 00860 } 00861 00862 /* Process locked */ 00863 __HAL_LOCK(hpcd); 00864 00865 if (hpcd->State == HAL_PCD_STATE_READY) 00866 { 00867 hpcd->BCDCallback = pCallback; 00868 } 00869 else 00870 { 00871 /* Update the error code */ 00872 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00873 00874 /* Return error status */ 00875 status = HAL_ERROR; 00876 } 00877 00878 /* Release Lock */ 00879 __HAL_UNLOCK(hpcd); 00880 00881 return status; 00882 } 00883 00884 /** 00885 * @brief Unregister the USB PCD BCD Callback 00886 * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback 00887 * @param hpcd PCD handle 00888 * @retval HAL status 00889 */ 00890 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd) 00891 { 00892 HAL_StatusTypeDef status = HAL_OK; 00893 00894 /* Process locked */ 00895 __HAL_LOCK(hpcd); 00896 00897 if (hpcd->State == HAL_PCD_STATE_READY) 00898 { 00899 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */ 00900 } 00901 else 00902 { 00903 /* Update the error code */ 00904 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00905 00906 /* Return error status */ 00907 status = HAL_ERROR; 00908 } 00909 00910 /* Release Lock */ 00911 __HAL_UNLOCK(hpcd); 00912 00913 return status; 00914 } 00915 00916 /** 00917 * @brief Register USB PCD LPM Callback 00918 * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback 00919 * @param hpcd PCD handle 00920 * @param pCallback pointer to the USB PCD LPM Callback function 00921 * @retval HAL status 00922 */ 00923 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback) 00924 { 00925 HAL_StatusTypeDef status = HAL_OK; 00926 00927 if (pCallback == NULL) 00928 { 00929 /* Update the error code */ 00930 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00931 00932 return HAL_ERROR; 00933 } 00934 00935 /* Process locked */ 00936 __HAL_LOCK(hpcd); 00937 00938 if (hpcd->State == HAL_PCD_STATE_READY) 00939 { 00940 hpcd->LPMCallback = pCallback; 00941 } 00942 else 00943 { 00944 /* Update the error code */ 00945 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00946 00947 /* Return error status */ 00948 status = HAL_ERROR; 00949 } 00950 00951 /* Release Lock */ 00952 __HAL_UNLOCK(hpcd); 00953 00954 return status; 00955 } 00956 00957 /** 00958 * @brief Unregister the USB PCD LPM Callback 00959 * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback 00960 * @param hpcd PCD handle 00961 * @retval HAL status 00962 */ 00963 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd) 00964 { 00965 HAL_StatusTypeDef status = HAL_OK; 00966 00967 /* Process locked */ 00968 __HAL_LOCK(hpcd); 00969 00970 if (hpcd->State == HAL_PCD_STATE_READY) 00971 { 00972 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */ 00973 } 00974 else 00975 { 00976 /* Update the error code */ 00977 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; 00978 00979 /* Return error status */ 00980 status = HAL_ERROR; 00981 } 00982 00983 /* Release Lock */ 00984 __HAL_UNLOCK(hpcd); 00985 00986 return status; 00987 } 00988 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00989 00990 /** 00991 * @} 00992 */ 00993 00994 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions 00995 * @brief Data transfers functions 00996 * 00997 @verbatim 00998 =============================================================================== 00999 ##### IO operation functions ##### 01000 =============================================================================== 01001 [..] 01002 This subsection provides a set of functions allowing to manage the PCD data 01003 transfers. 01004 01005 @endverbatim 01006 * @{ 01007 */ 01008 01009 /** 01010 * @brief Start the USB device 01011 * @param hpcd PCD handle 01012 * @retval HAL status 01013 */ 01014 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) 01015 { 01016 #if defined (USB_OTG_FS) 01017 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01018 #endif /* defined (USB_OTG_FS) */ 01019 01020 __HAL_LOCK(hpcd); 01021 #if defined (USB_OTG_FS) 01022 if (hpcd->Init.battery_charging_enable == 1U) 01023 { 01024 /* Enable USB Transceiver */ 01025 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; 01026 } 01027 #endif /* defined (USB_OTG_FS) */ 01028 __HAL_PCD_ENABLE(hpcd); 01029 (void)USB_DevConnect(hpcd->Instance); 01030 __HAL_UNLOCK(hpcd); 01031 01032 return HAL_OK; 01033 } 01034 01035 /** 01036 * @brief Stop the USB device. 01037 * @param hpcd PCD handle 01038 * @retval HAL status 01039 */ 01040 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) 01041 { 01042 #if defined (USB_OTG_FS) 01043 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01044 #endif /* defined (USB_OTG_FS) */ 01045 01046 __HAL_LOCK(hpcd); 01047 __HAL_PCD_DISABLE(hpcd); 01048 (void)USB_DevDisconnect(hpcd->Instance); 01049 01050 #if defined (USB_OTG_FS) 01051 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U); 01052 01053 if (hpcd->Init.battery_charging_enable == 1U) 01054 { 01055 /* Disable USB Transceiver */ 01056 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); 01057 } 01058 #endif /* defined (USB_OTG_FS) */ 01059 01060 __HAL_UNLOCK(hpcd); 01061 01062 return HAL_OK; 01063 } 01064 01065 #if defined (USB_OTG_FS) 01066 /** 01067 * @brief Handles PCD interrupt request. 01068 * @param hpcd PCD handle 01069 * @retval HAL status 01070 */ 01071 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) 01072 { 01073 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01074 uint32_t USBx_BASE = (uint32_t)USBx; 01075 USB_OTG_EPTypeDef *ep; 01076 uint32_t i; 01077 uint32_t ep_intr; 01078 uint32_t epint; 01079 uint32_t epnum; 01080 uint32_t fifoemptymsk; 01081 uint32_t temp; 01082 01083 /* ensure that we are in device mode */ 01084 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) 01085 { 01086 /* avoid spurious interrupt */ 01087 if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) 01088 { 01089 return; 01090 } 01091 01092 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) 01093 { 01094 /* incorrect mode, acknowledge the interrupt */ 01095 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); 01096 } 01097 01098 /* Handle RxQLevel Interrupt */ 01099 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL)) 01100 { 01101 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 01102 01103 temp = USBx->GRXSTSP; 01104 01105 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM]; 01106 01107 if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) 01108 { 01109 if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U) 01110 { 01111 (void)USB_ReadPacket(USBx, ep->xfer_buff, 01112 (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4)); 01113 01114 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 01115 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 01116 } 01117 } 01118 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) 01119 { 01120 (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U); 01121 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 01122 } 01123 else 01124 { 01125 /* ... */ 01126 } 01127 01128 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 01129 } 01130 01131 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) 01132 { 01133 epnum = 0U; 01134 01135 /* Read in the device interrupt bits */ 01136 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); 01137 01138 while (ep_intr != 0U) 01139 { 01140 if ((ep_intr & 0x1U) != 0U) 01141 { 01142 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum); 01143 01144 if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) 01145 { 01146 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); 01147 (void)PCD_EP_OutXfrComplete_int(hpcd, epnum); 01148 } 01149 01150 if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) 01151 { 01152 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); 01153 /* Class B setup phase done for previous decoded setup */ 01154 (void)PCD_EP_OutSetupPacket_int(hpcd, epnum); 01155 } 01156 01157 if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) 01158 { 01159 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); 01160 } 01161 01162 /* Clear Status Phase Received interrupt */ 01163 if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) 01164 { 01165 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 01166 } 01167 01168 /* Clear OUT NAK interrupt */ 01169 if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK) 01170 { 01171 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK); 01172 } 01173 } 01174 epnum++; 01175 ep_intr >>= 1U; 01176 } 01177 } 01178 01179 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) 01180 { 01181 /* Read in the device interrupt bits */ 01182 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); 01183 01184 epnum = 0U; 01185 01186 while (ep_intr != 0U) 01187 { 01188 if ((ep_intr & 0x1U) != 0U) /* In ITR */ 01189 { 01190 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum); 01191 01192 if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) 01193 { 01194 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); 01195 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 01196 01197 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); 01198 01199 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01200 hpcd->DataInStageCallback(hpcd, (uint8_t)epnum); 01201 #else 01202 HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum); 01203 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01204 } 01205 if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) 01206 { 01207 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); 01208 } 01209 if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) 01210 { 01211 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); 01212 } 01213 if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) 01214 { 01215 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); 01216 } 01217 if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) 01218 { 01219 (void)USB_FlushTxFifo(USBx, epnum); 01220 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); 01221 } 01222 if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) 01223 { 01224 (void)PCD_WriteEmptyTxFifo(hpcd, epnum); 01225 } 01226 } 01227 epnum++; 01228 ep_intr >>= 1U; 01229 } 01230 } 01231 01232 /* Handle Resume Interrupt */ 01233 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) 01234 { 01235 /* Clear the Remote Wake-up Signaling */ 01236 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 01237 01238 if (hpcd->LPM_State == LPM_L1) 01239 { 01240 hpcd->LPM_State = LPM_L0; 01241 01242 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01243 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); 01244 #else 01245 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); 01246 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01247 } 01248 else 01249 { 01250 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01251 hpcd->ResumeCallback(hpcd); 01252 #else 01253 HAL_PCD_ResumeCallback(hpcd); 01254 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01255 } 01256 01257 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); 01258 } 01259 01260 /* Handle Suspend Interrupt */ 01261 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) 01262 { 01263 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) 01264 { 01265 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01266 hpcd->SuspendCallback(hpcd); 01267 #else 01268 HAL_PCD_SuspendCallback(hpcd); 01269 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01270 } 01271 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); 01272 } 01273 01274 /* Handle LPM Interrupt */ 01275 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) 01276 { 01277 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); 01278 01279 if (hpcd->LPM_State == LPM_L0) 01280 { 01281 hpcd->LPM_State = LPM_L1; 01282 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U; 01283 01284 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01285 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); 01286 #else 01287 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); 01288 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01289 } 01290 else 01291 { 01292 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01293 hpcd->SuspendCallback(hpcd); 01294 #else 01295 HAL_PCD_SuspendCallback(hpcd); 01296 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01297 } 01298 } 01299 01300 /* Handle Reset Interrupt */ 01301 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) 01302 { 01303 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 01304 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U); 01305 01306 for (i = 0U; i < hpcd->Init.dev_endpoints; i++) 01307 { 01308 USBx_INEP(i)->DIEPINT = 0xFB7FU; 01309 USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; 01310 USBx_OUTEP(i)->DOEPINT = 0xFB7FU; 01311 USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; 01312 USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; 01313 } 01314 USBx_DEVICE->DAINTMSK |= 0x10001U; 01315 01316 if (hpcd->Init.use_dedicated_ep1 != 0U) 01317 { 01318 USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM | 01319 USB_OTG_DOEPMSK_XFRCM | 01320 USB_OTG_DOEPMSK_EPDM; 01321 01322 USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM | 01323 USB_OTG_DIEPMSK_XFRCM | 01324 USB_OTG_DIEPMSK_EPDM; 01325 } 01326 else 01327 { 01328 USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM | 01329 USB_OTG_DOEPMSK_XFRCM | 01330 USB_OTG_DOEPMSK_EPDM | 01331 USB_OTG_DOEPMSK_OTEPSPRM | 01332 USB_OTG_DOEPMSK_NAKM; 01333 01334 USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM | 01335 USB_OTG_DIEPMSK_XFRCM | 01336 USB_OTG_DIEPMSK_EPDM; 01337 } 01338 01339 /* Set Default Address to 0 */ 01340 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; 01341 01342 /* setup EP0 to receive SETUP packets */ 01343 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup); 01344 01345 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); 01346 } 01347 01348 /* Handle Enumeration done Interrupt */ 01349 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) 01350 { 01351 (void)USB_ActivateSetup(hpcd->Instance); 01352 hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance); 01353 01354 /* Set USB Turnaround time */ 01355 (void)USB_SetTurnaroundTime(hpcd->Instance, 01356 HAL_RCC_GetHCLKFreq(), 01357 (uint8_t)hpcd->Init.speed); 01358 01359 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01360 hpcd->ResetCallback(hpcd); 01361 #else 01362 HAL_PCD_ResetCallback(hpcd); 01363 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01364 01365 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); 01366 } 01367 01368 /* Handle SOF Interrupt */ 01369 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) 01370 { 01371 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01372 hpcd->SOFCallback(hpcd); 01373 #else 01374 HAL_PCD_SOFCallback(hpcd); 01375 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01376 01377 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); 01378 } 01379 01380 /* Handle Incomplete ISO IN Interrupt */ 01381 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) 01382 { 01383 /* Keep application checking the corresponding Iso IN endpoint 01384 causing the incomplete Interrupt */ 01385 epnum = 0U; 01386 01387 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01388 hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum); 01389 #else 01390 HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum); 01391 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01392 01393 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); 01394 } 01395 01396 /* Handle Incomplete ISO OUT Interrupt */ 01397 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) 01398 { 01399 /* Keep application checking the corresponding Iso OUT endpoint 01400 causing the incomplete Interrupt */ 01401 epnum = 0U; 01402 01403 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01404 hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); 01405 #else 01406 HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); 01407 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01408 01409 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); 01410 } 01411 01412 /* Handle Connection event Interrupt */ 01413 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) 01414 { 01415 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01416 hpcd->ConnectCallback(hpcd); 01417 #else 01418 HAL_PCD_ConnectCallback(hpcd); 01419 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01420 01421 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); 01422 } 01423 01424 /* Handle Disconnection event Interrupt */ 01425 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) 01426 { 01427 temp = hpcd->Instance->GOTGINT; 01428 01429 if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) 01430 { 01431 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01432 hpcd->DisconnectCallback(hpcd); 01433 #else 01434 HAL_PCD_DisconnectCallback(hpcd); 01435 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01436 } 01437 hpcd->Instance->GOTGINT |= temp; 01438 } 01439 } 01440 } 01441 #endif /* defined (USB_OTG_FS) */ 01442 01443 #if defined (USB) 01444 /** 01445 * @brief This function handles PCD interrupt request. 01446 * @param hpcd PCD handle 01447 * @retval HAL status 01448 */ 01449 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) 01450 { 01451 uint32_t wIstr = USB_ReadInterrupts(hpcd->Instance); 01452 01453 if ((wIstr & USB_ISTR_CTR) == USB_ISTR_CTR) 01454 { 01455 /* servicing of the endpoint correct transfer interrupt */ 01456 /* clear of the CTR flag into the sub */ 01457 (void)PCD_EP_ISR_Handler(hpcd); 01458 01459 return; 01460 } 01461 01462 if ((wIstr & USB_ISTR_RESET) == USB_ISTR_RESET) 01463 { 01464 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); 01465 01466 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01467 hpcd->ResetCallback(hpcd); 01468 #else 01469 HAL_PCD_ResetCallback(hpcd); 01470 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01471 01472 (void)HAL_PCD_SetAddress(hpcd, 0U); 01473 01474 return; 01475 } 01476 01477 if ((wIstr & USB_ISTR_PMAOVR) == USB_ISTR_PMAOVR) 01478 { 01479 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); 01480 01481 return; 01482 } 01483 01484 if ((wIstr & USB_ISTR_ERR) == USB_ISTR_ERR) 01485 { 01486 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); 01487 01488 return; 01489 } 01490 01491 if ((wIstr & USB_ISTR_WKUP) == USB_ISTR_WKUP) 01492 { 01493 hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE); 01494 hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP); 01495 01496 if (hpcd->LPM_State == LPM_L1) 01497 { 01498 hpcd->LPM_State = LPM_L0; 01499 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01500 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); 01501 #else 01502 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); 01503 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01504 } 01505 01506 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01507 hpcd->ResumeCallback(hpcd); 01508 #else 01509 HAL_PCD_ResumeCallback(hpcd); 01510 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01511 01512 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); 01513 01514 return; 01515 } 01516 01517 if ((wIstr & USB_ISTR_SUSP) == USB_ISTR_SUSP) 01518 { 01519 /* Force low-power mode in the macrocell */ 01520 hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP; 01521 01522 /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ 01523 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); 01524 01525 hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LPMODE; 01526 01527 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01528 hpcd->SuspendCallback(hpcd); 01529 #else 01530 HAL_PCD_SuspendCallback(hpcd); 01531 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01532 01533 return; 01534 } 01535 01536 /* Handle LPM Interrupt */ 01537 if ((wIstr & USB_ISTR_L1REQ) == USB_ISTR_L1REQ) 01538 { 01539 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); 01540 if (hpcd->LPM_State == LPM_L0) 01541 { 01542 /* Force suspend and low-power mode before going to L1 state*/ 01543 hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LPMODE; 01544 hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP; 01545 01546 hpcd->LPM_State = LPM_L1; 01547 hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2; 01548 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01549 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); 01550 #else 01551 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); 01552 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01553 } 01554 else 01555 { 01556 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01557 hpcd->SuspendCallback(hpcd); 01558 #else 01559 HAL_PCD_SuspendCallback(hpcd); 01560 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01561 } 01562 01563 return; 01564 } 01565 01566 if ((wIstr & USB_ISTR_SOF) == USB_ISTR_SOF) 01567 { 01568 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); 01569 01570 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 01571 hpcd->SOFCallback(hpcd); 01572 #else 01573 HAL_PCD_SOFCallback(hpcd); 01574 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 01575 01576 return; 01577 } 01578 01579 if ((wIstr & USB_ISTR_ESOF) == USB_ISTR_ESOF) 01580 { 01581 /* clear ESOF flag in ISTR */ 01582 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); 01583 01584 return; 01585 } 01586 } 01587 #endif /* defined (USB) */ 01588 01589 /** 01590 * @brief Data OUT stage callback. 01591 * @param hpcd PCD handle 01592 * @param epnum endpoint number 01593 * @retval None 01594 */ 01595 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01596 { 01597 /* Prevent unused argument(s) compilation warning */ 01598 UNUSED(hpcd); 01599 UNUSED(epnum); 01600 01601 /* NOTE : This function should not be modified, when the callback is needed, 01602 the HAL_PCD_DataOutStageCallback could be implemented in the user file 01603 */ 01604 } 01605 01606 /** 01607 * @brief Data IN stage callback 01608 * @param hpcd PCD handle 01609 * @param epnum endpoint number 01610 * @retval None 01611 */ 01612 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01613 { 01614 /* Prevent unused argument(s) compilation warning */ 01615 UNUSED(hpcd); 01616 UNUSED(epnum); 01617 01618 /* NOTE : This function should not be modified, when the callback is needed, 01619 the HAL_PCD_DataInStageCallback could be implemented in the user file 01620 */ 01621 } 01622 /** 01623 * @brief Setup stage callback 01624 * @param hpcd PCD handle 01625 * @retval None 01626 */ 01627 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) 01628 { 01629 /* Prevent unused argument(s) compilation warning */ 01630 UNUSED(hpcd); 01631 01632 /* NOTE : This function should not be modified, when the callback is needed, 01633 the HAL_PCD_SetupStageCallback could be implemented in the user file 01634 */ 01635 } 01636 01637 /** 01638 * @brief USB Start Of Frame callback. 01639 * @param hpcd PCD handle 01640 * @retval None 01641 */ 01642 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) 01643 { 01644 /* Prevent unused argument(s) compilation warning */ 01645 UNUSED(hpcd); 01646 01647 /* NOTE : This function should not be modified, when the callback is needed, 01648 the HAL_PCD_SOFCallback could be implemented in the user file 01649 */ 01650 } 01651 01652 /** 01653 * @brief USB Reset callback. 01654 * @param hpcd PCD handle 01655 * @retval None 01656 */ 01657 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) 01658 { 01659 /* Prevent unused argument(s) compilation warning */ 01660 UNUSED(hpcd); 01661 01662 /* NOTE : This function should not be modified, when the callback is needed, 01663 the HAL_PCD_ResetCallback could be implemented in the user file 01664 */ 01665 } 01666 01667 /** 01668 * @brief Suspend event callback. 01669 * @param hpcd PCD handle 01670 * @retval None 01671 */ 01672 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) 01673 { 01674 /* Prevent unused argument(s) compilation warning */ 01675 UNUSED(hpcd); 01676 01677 /* NOTE : This function should not be modified, when the callback is needed, 01678 the HAL_PCD_SuspendCallback could be implemented in the user file 01679 */ 01680 } 01681 01682 /** 01683 * @brief Resume event callback. 01684 * @param hpcd PCD handle 01685 * @retval None 01686 */ 01687 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) 01688 { 01689 /* Prevent unused argument(s) compilation warning */ 01690 UNUSED(hpcd); 01691 01692 /* NOTE : This function should not be modified, when the callback is needed, 01693 the HAL_PCD_ResumeCallback could be implemented in the user file 01694 */ 01695 } 01696 01697 /** 01698 * @brief Incomplete ISO OUT callback. 01699 * @param hpcd PCD handle 01700 * @param epnum endpoint number 01701 * @retval None 01702 */ 01703 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01704 { 01705 /* Prevent unused argument(s) compilation warning */ 01706 UNUSED(hpcd); 01707 UNUSED(epnum); 01708 01709 /* NOTE : This function should not be modified, when the callback is needed, 01710 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file 01711 */ 01712 } 01713 01714 /** 01715 * @brief Incomplete ISO IN callback. 01716 * @param hpcd PCD handle 01717 * @param epnum endpoint number 01718 * @retval None 01719 */ 01720 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 01721 { 01722 /* Prevent unused argument(s) compilation warning */ 01723 UNUSED(hpcd); 01724 UNUSED(epnum); 01725 01726 /* NOTE : This function should not be modified, when the callback is needed, 01727 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file 01728 */ 01729 } 01730 01731 /** 01732 * @brief Connection event callback. 01733 * @param hpcd PCD handle 01734 * @retval None 01735 */ 01736 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) 01737 { 01738 /* Prevent unused argument(s) compilation warning */ 01739 UNUSED(hpcd); 01740 01741 /* NOTE : This function should not be modified, when the callback is needed, 01742 the HAL_PCD_ConnectCallback could be implemented in the user file 01743 */ 01744 } 01745 01746 /** 01747 * @brief Disconnection event callback. 01748 * @param hpcd PCD handle 01749 * @retval None 01750 */ 01751 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) 01752 { 01753 /* Prevent unused argument(s) compilation warning */ 01754 UNUSED(hpcd); 01755 01756 /* NOTE : This function should not be modified, when the callback is needed, 01757 the HAL_PCD_DisconnectCallback could be implemented in the user file 01758 */ 01759 } 01760 01761 /** 01762 * @} 01763 */ 01764 01765 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions 01766 * @brief management functions 01767 * 01768 @verbatim 01769 =============================================================================== 01770 ##### Peripheral Control functions ##### 01771 =============================================================================== 01772 [..] 01773 This subsection provides a set of functions allowing to control the PCD data 01774 transfers. 01775 01776 @endverbatim 01777 * @{ 01778 */ 01779 01780 /** 01781 * @brief Connect the USB device 01782 * @param hpcd PCD handle 01783 * @retval HAL status 01784 */ 01785 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) 01786 { 01787 #if defined (USB_OTG_FS) 01788 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01789 #endif /* defined (USB_OTG_FS) */ 01790 01791 __HAL_LOCK(hpcd); 01792 01793 #if defined (USB_OTG_FS) 01794 if (hpcd->Init.battery_charging_enable == 1U) 01795 { 01796 /* Enable USB Transceiver */ 01797 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; 01798 } 01799 #endif /* defined (USB_OTG_FS) */ 01800 01801 (void)USB_DevConnect(hpcd->Instance); 01802 __HAL_UNLOCK(hpcd); 01803 01804 return HAL_OK; 01805 } 01806 01807 /** 01808 * @brief Disconnect the USB device. 01809 * @param hpcd PCD handle 01810 * @retval HAL status 01811 */ 01812 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) 01813 { 01814 #if defined (USB_OTG_FS) 01815 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01816 #endif /* defined (USB_OTG_FS) */ 01817 01818 __HAL_LOCK(hpcd); 01819 (void)USB_DevDisconnect(hpcd->Instance); 01820 01821 #if defined (USB_OTG_FS) 01822 if (hpcd->Init.battery_charging_enable == 1U) 01823 { 01824 /* Disable USB Transceiver */ 01825 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); 01826 } 01827 #endif /* defined (USB_OTG_FS) */ 01828 01829 __HAL_UNLOCK(hpcd); 01830 01831 return HAL_OK; 01832 } 01833 01834 /** 01835 * @brief Set the USB Device address. 01836 * @param hpcd PCD handle 01837 * @param address new device address 01838 * @retval HAL status 01839 */ 01840 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) 01841 { 01842 __HAL_LOCK(hpcd); 01843 hpcd->USB_Address = address; 01844 (void)USB_SetDevAddress(hpcd->Instance, address); 01845 __HAL_UNLOCK(hpcd); 01846 01847 return HAL_OK; 01848 } 01849 /** 01850 * @brief Open and configure an endpoint. 01851 * @param hpcd PCD handle 01852 * @param ep_addr endpoint address 01853 * @param ep_mps endpoint max packet size 01854 * @param ep_type endpoint type 01855 * @retval HAL status 01856 */ 01857 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, 01858 uint16_t ep_mps, uint8_t ep_type) 01859 { 01860 HAL_StatusTypeDef ret = HAL_OK; 01861 PCD_EPTypeDef *ep; 01862 01863 if ((ep_addr & 0x80U) == 0x80U) 01864 { 01865 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01866 ep->is_in = 1U; 01867 } 01868 else 01869 { 01870 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01871 ep->is_in = 0U; 01872 } 01873 01874 ep->num = ep_addr & EP_ADDR_MSK; 01875 ep->maxpacket = ep_mps; 01876 ep->type = ep_type; 01877 01878 if (ep->is_in != 0U) 01879 { 01880 /* Assign a Tx FIFO */ 01881 ep->tx_fifo_num = ep->num; 01882 } 01883 /* Set initial data PID. */ 01884 if (ep_type == EP_TYPE_BULK) 01885 { 01886 ep->data_pid_start = 0U; 01887 } 01888 01889 __HAL_LOCK(hpcd); 01890 (void)USB_ActivateEndpoint(hpcd->Instance, ep); 01891 __HAL_UNLOCK(hpcd); 01892 01893 return ret; 01894 } 01895 01896 /** 01897 * @brief Deactivate an endpoint. 01898 * @param hpcd PCD handle 01899 * @param ep_addr endpoint address 01900 * @retval HAL status 01901 */ 01902 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01903 { 01904 PCD_EPTypeDef *ep; 01905 01906 if ((ep_addr & 0x80U) == 0x80U) 01907 { 01908 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01909 ep->is_in = 1U; 01910 } 01911 else 01912 { 01913 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01914 ep->is_in = 0U; 01915 } 01916 ep->num = ep_addr & EP_ADDR_MSK; 01917 01918 __HAL_LOCK(hpcd); 01919 (void)USB_DeactivateEndpoint(hpcd->Instance, ep); 01920 __HAL_UNLOCK(hpcd); 01921 return HAL_OK; 01922 } 01923 01924 01925 /** 01926 * @brief Receive an amount of data. 01927 * @param hpcd PCD handle 01928 * @param ep_addr endpoint address 01929 * @param pBuf pointer to the reception buffer 01930 * @param len amount of data to be received 01931 * @retval HAL status 01932 */ 01933 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01934 { 01935 PCD_EPTypeDef *ep; 01936 01937 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 01938 01939 /*setup and start the Xfer */ 01940 ep->xfer_buff = pBuf; 01941 ep->xfer_len = len; 01942 ep->xfer_count = 0U; 01943 ep->is_in = 0U; 01944 ep->num = ep_addr & EP_ADDR_MSK; 01945 01946 if ((ep_addr & EP_ADDR_MSK) == 0U) 01947 { 01948 (void)USB_EP0StartXfer(hpcd->Instance, ep); 01949 } 01950 else 01951 { 01952 (void)USB_EPStartXfer(hpcd->Instance, ep); 01953 } 01954 01955 return HAL_OK; 01956 } 01957 01958 /** 01959 * @brief Get Received Data Size 01960 * @param hpcd PCD handle 01961 * @param ep_addr endpoint address 01962 * @retval Data Size 01963 */ 01964 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01965 { 01966 return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; 01967 } 01968 /** 01969 * @brief Send an amount of data 01970 * @param hpcd PCD handle 01971 * @param ep_addr endpoint address 01972 * @param pBuf pointer to the transmission buffer 01973 * @param len amount of data to be sent 01974 * @retval HAL status 01975 */ 01976 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01977 { 01978 PCD_EPTypeDef *ep; 01979 01980 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 01981 01982 /*setup and start the Xfer */ 01983 ep->xfer_buff = pBuf; 01984 ep->xfer_len = len; 01985 #if defined (USB) 01986 ep->xfer_fill_db = 1U; 01987 ep->xfer_len_db = len; 01988 #endif /* defined (USB) */ 01989 ep->xfer_count = 0U; 01990 ep->is_in = 1U; 01991 ep->num = ep_addr & EP_ADDR_MSK; 01992 01993 if ((ep_addr & EP_ADDR_MSK) == 0U) 01994 { 01995 (void)USB_EP0StartXfer(hpcd->Instance, ep); 01996 } 01997 else 01998 { 01999 (void)USB_EPStartXfer(hpcd->Instance, ep); 02000 } 02001 02002 return HAL_OK; 02003 } 02004 02005 /** 02006 * @brief Set a STALL condition over an endpoint 02007 * @param hpcd PCD handle 02008 * @param ep_addr endpoint address 02009 * @retval HAL status 02010 */ 02011 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 02012 { 02013 PCD_EPTypeDef *ep; 02014 02015 if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) 02016 { 02017 return HAL_ERROR; 02018 } 02019 02020 if ((0x80U & ep_addr) == 0x80U) 02021 { 02022 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 02023 ep->is_in = 1U; 02024 } 02025 else 02026 { 02027 ep = &hpcd->OUT_ep[ep_addr]; 02028 ep->is_in = 0U; 02029 } 02030 02031 ep->is_stall = 1U; 02032 ep->num = ep_addr & EP_ADDR_MSK; 02033 02034 __HAL_LOCK(hpcd); 02035 02036 (void)USB_EPSetStall(hpcd->Instance, ep); 02037 02038 if ((ep_addr & EP_ADDR_MSK) == 0U) 02039 { 02040 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup); 02041 } 02042 02043 __HAL_UNLOCK(hpcd); 02044 02045 return HAL_OK; 02046 } 02047 02048 /** 02049 * @brief Clear a STALL condition over in an endpoint 02050 * @param hpcd PCD handle 02051 * @param ep_addr endpoint address 02052 * @retval HAL status 02053 */ 02054 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 02055 { 02056 PCD_EPTypeDef *ep; 02057 02058 if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) 02059 { 02060 return HAL_ERROR; 02061 } 02062 02063 if ((0x80U & ep_addr) == 0x80U) 02064 { 02065 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 02066 ep->is_in = 1U; 02067 } 02068 else 02069 { 02070 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 02071 ep->is_in = 0U; 02072 } 02073 02074 ep->is_stall = 0U; 02075 ep->num = ep_addr & EP_ADDR_MSK; 02076 02077 __HAL_LOCK(hpcd); 02078 (void)USB_EPClearStall(hpcd->Instance, ep); 02079 __HAL_UNLOCK(hpcd); 02080 02081 return HAL_OK; 02082 } 02083 02084 /** 02085 * @brief Abort an USB EP transaction. 02086 * @param hpcd PCD handle 02087 * @param ep_addr endpoint address 02088 * @retval HAL status 02089 */ 02090 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 02091 { 02092 HAL_StatusTypeDef ret; 02093 PCD_EPTypeDef *ep; 02094 02095 if ((0x80U & ep_addr) == 0x80U) 02096 { 02097 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 02098 } 02099 else 02100 { 02101 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; 02102 } 02103 02104 /* Stop Xfer */ 02105 ret = USB_EPStopXfer(hpcd->Instance, ep); 02106 02107 return ret; 02108 } 02109 02110 /** 02111 * @brief Flush an endpoint 02112 * @param hpcd PCD handle 02113 * @param ep_addr endpoint address 02114 * @retval HAL status 02115 */ 02116 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 02117 { 02118 __HAL_LOCK(hpcd); 02119 02120 if ((ep_addr & 0x80U) == 0x80U) 02121 { 02122 (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK); 02123 } 02124 else 02125 { 02126 (void)USB_FlushRxFifo(hpcd->Instance); 02127 } 02128 02129 __HAL_UNLOCK(hpcd); 02130 02131 return HAL_OK; 02132 } 02133 02134 /** 02135 * @brief Activate remote wakeup signalling 02136 * @param hpcd PCD handle 02137 * @retval HAL status 02138 */ 02139 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 02140 { 02141 return (USB_ActivateRemoteWakeup(hpcd->Instance)); 02142 } 02143 02144 /** 02145 * @brief De-activate remote wakeup signalling. 02146 * @param hpcd PCD handle 02147 * @retval HAL status 02148 */ 02149 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 02150 { 02151 return (USB_DeActivateRemoteWakeup(hpcd->Instance)); 02152 } 02153 02154 /** 02155 * @} 02156 */ 02157 02158 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions 02159 * @brief Peripheral State functions 02160 * 02161 @verbatim 02162 =============================================================================== 02163 ##### Peripheral State functions ##### 02164 =============================================================================== 02165 [..] 02166 This subsection permits to get in run-time the status of the peripheral 02167 and the data flow. 02168 02169 @endverbatim 02170 * @{ 02171 */ 02172 02173 /** 02174 * @brief Return the PCD handle state. 02175 * @param hpcd PCD handle 02176 * @retval HAL state 02177 */ 02178 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) 02179 { 02180 return hpcd->State; 02181 } 02182 02183 /** 02184 * @} 02185 */ 02186 02187 /** 02188 * @} 02189 */ 02190 02191 /* Private functions ---------------------------------------------------------*/ 02192 /** @addtogroup PCD_Private_Functions 02193 * @{ 02194 */ 02195 #if defined (USB_OTG_FS) 02196 /** 02197 * @brief Check FIFO for the next packet to be loaded. 02198 * @param hpcd PCD handle 02199 * @param epnum endpoint number 02200 * @retval HAL status 02201 */ 02202 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02203 { 02204 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02205 uint32_t USBx_BASE = (uint32_t)USBx; 02206 USB_OTG_EPTypeDef *ep; 02207 uint32_t len; 02208 uint32_t len32b; 02209 uint32_t fifoemptymsk; 02210 02211 ep = &hpcd->IN_ep[epnum]; 02212 02213 if (ep->xfer_count > ep->xfer_len) 02214 { 02215 return HAL_ERROR; 02216 } 02217 02218 len = ep->xfer_len - ep->xfer_count; 02219 02220 if (len > ep->maxpacket) 02221 { 02222 len = ep->maxpacket; 02223 } 02224 02225 len32b = (len + 3U) / 4U; 02226 02227 while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) && 02228 (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U)) 02229 { 02230 /* Write the FIFO */ 02231 len = ep->xfer_len - ep->xfer_count; 02232 02233 if (len > ep->maxpacket) 02234 { 02235 len = ep->maxpacket; 02236 } 02237 len32b = (len + 3U) / 4U; 02238 02239 (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len); 02240 02241 ep->xfer_buff += len; 02242 ep->xfer_count += len; 02243 } 02244 02245 if (ep->xfer_len <= ep->xfer_count) 02246 { 02247 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); 02248 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; 02249 } 02250 02251 return HAL_OK; 02252 } 02253 02254 02255 /** 02256 * @brief process EP OUT transfer complete interrupt. 02257 * @param hpcd PCD handle 02258 * @param epnum endpoint number 02259 * @retval HAL status 02260 */ 02261 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02262 { 02263 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02264 uint32_t USBx_BASE = (uint32_t)USBx; 02265 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U); 02266 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; 02267 02268 if (gSNPSiD == USB_OTG_CORE_ID_310A) 02269 { 02270 /* StupPktRcvd = 1 this is a setup packet */ 02271 if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX) 02272 { 02273 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02274 } 02275 else 02276 { 02277 if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) 02278 { 02279 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); 02280 } 02281 02282 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02283 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02284 #else 02285 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02286 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02287 } 02288 } 02289 else 02290 { 02291 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02292 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); 02293 #else 02294 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); 02295 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02296 } 02297 02298 return HAL_OK; 02299 } 02300 02301 02302 /** 02303 * @brief process EP OUT setup packet received interrupt. 02304 * @param hpcd PCD handle 02305 * @param epnum endpoint number 02306 * @retval HAL status 02307 */ 02308 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) 02309 { 02310 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 02311 uint32_t USBx_BASE = (uint32_t)USBx; 02312 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U); 02313 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; 02314 02315 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && 02316 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) 02317 { 02318 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); 02319 } 02320 02321 /* Inform the upper layer that a setup packet is available */ 02322 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02323 hpcd->SetupStageCallback(hpcd); 02324 #else 02325 HAL_PCD_SetupStageCallback(hpcd); 02326 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02327 02328 return HAL_OK; 02329 } 02330 #endif /* defined (USB_OTG_FS) */ 02331 02332 #if defined (USB) 02333 /** 02334 * @brief This function handles PCD Endpoint interrupt request. 02335 * @param hpcd PCD handle 02336 * @retval HAL status 02337 */ 02338 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd) 02339 { 02340 PCD_EPTypeDef *ep; 02341 uint16_t count; 02342 uint16_t wIstr; 02343 uint16_t wEPVal; 02344 uint16_t TxPctSize; 02345 uint8_t epindex; 02346 02347 /* stay in loop while pending interrupts */ 02348 while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U) 02349 { 02350 wIstr = hpcd->Instance->ISTR; 02351 02352 /* extract highest priority endpoint number */ 02353 epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID); 02354 02355 if (epindex == 0U) 02356 { 02357 /* Decode and service control endpoint interrupt */ 02358 02359 /* DIR bit = origin of the interrupt */ 02360 if ((wIstr & USB_ISTR_DIR) == 0U) 02361 { 02362 /* DIR = 0 */ 02363 02364 /* DIR = 0 => IN int */ 02365 /* DIR = 0 implies that (EP_CTR_TX = 1) always */ 02366 PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0); 02367 ep = &hpcd->IN_ep[0]; 02368 02369 ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); 02370 ep->xfer_buff += ep->xfer_count; 02371 02372 /* TX COMPLETE */ 02373 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02374 hpcd->DataInStageCallback(hpcd, 0U); 02375 #else 02376 HAL_PCD_DataInStageCallback(hpcd, 0U); 02377 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02378 02379 if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U)) 02380 { 02381 hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF); 02382 hpcd->USB_Address = 0U; 02383 } 02384 } 02385 else 02386 { 02387 /* DIR = 1 */ 02388 02389 /* DIR = 1 & CTR_RX => SETUP or OUT int */ 02390 /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ 02391 ep = &hpcd->OUT_ep[0]; 02392 wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0); 02393 02394 if ((wEPVal & USB_EP_SETUP) != 0U) 02395 { 02396 /* Get SETUP Packet */ 02397 ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); 02398 02399 USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, 02400 ep->pmaadress, (uint16_t)ep->xfer_count); 02401 02402 /* SETUP bit kept frozen while CTR_RX = 1 */ 02403 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); 02404 02405 /* Process SETUP Packet*/ 02406 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02407 hpcd->SetupStageCallback(hpcd); 02408 #else 02409 HAL_PCD_SetupStageCallback(hpcd); 02410 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02411 } 02412 else if ((wEPVal & USB_EP_CTR_RX) != 0U) 02413 { 02414 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); 02415 02416 /* Get Control Data OUT Packet */ 02417 ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); 02418 02419 if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U)) 02420 { 02421 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, 02422 ep->pmaadress, (uint16_t)ep->xfer_count); 02423 02424 ep->xfer_buff += ep->xfer_count; 02425 02426 /* Process Control Data OUT Packet */ 02427 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02428 hpcd->DataOutStageCallback(hpcd, 0U); 02429 #else 02430 HAL_PCD_DataOutStageCallback(hpcd, 0U); 02431 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02432 } 02433 02434 if ((PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0) & USB_EP_SETUP) == 0U) 02435 { 02436 PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket); 02437 PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID); 02438 } 02439 } 02440 } 02441 } 02442 else 02443 { 02444 /* Decode and service non control endpoints interrupt */ 02445 /* process related endpoint register */ 02446 wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex); 02447 02448 if ((wEPVal & USB_EP_CTR_RX) != 0U) 02449 { 02450 /* clear int flag */ 02451 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex); 02452 ep = &hpcd->OUT_ep[epindex]; 02453 02454 /* OUT Single Buffering */ 02455 if (ep->doublebuffer == 0U) 02456 { 02457 count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); 02458 02459 if (count != 0U) 02460 { 02461 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count); 02462 } 02463 } 02464 #if (USE_USB_DOUBLE_BUFFER == 1U) 02465 else 02466 { 02467 /* manage double buffer bulk out */ 02468 if (ep->type == EP_TYPE_BULK) 02469 { 02470 count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal); 02471 } 02472 else /* manage double buffer iso out */ 02473 { 02474 /* free EP OUT Buffer */ 02475 PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U); 02476 02477 if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U) 02478 { 02479 /* read from endpoint BUF0Addr buffer */ 02480 count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); 02481 02482 if (count != 0U) 02483 { 02484 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); 02485 } 02486 } 02487 else 02488 { 02489 /* read from endpoint BUF1Addr buffer */ 02490 count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); 02491 02492 if (count != 0U) 02493 { 02494 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); 02495 } 02496 } 02497 } 02498 } 02499 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ 02500 02501 /* multi-packet on the NON control OUT endpoint */ 02502 ep->xfer_count += count; 02503 ep->xfer_buff += count; 02504 02505 if ((ep->xfer_len == 0U) || (count < ep->maxpacket)) 02506 { 02507 /* RX COMPLETE */ 02508 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02509 hpcd->DataOutStageCallback(hpcd, ep->num); 02510 #else 02511 HAL_PCD_DataOutStageCallback(hpcd, ep->num); 02512 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02513 } 02514 else 02515 { 02516 (void) USB_EPStartXfer(hpcd->Instance, ep); 02517 } 02518 } 02519 02520 if ((wEPVal & USB_EP_CTR_TX) != 0U) 02521 { 02522 ep = &hpcd->IN_ep[epindex]; 02523 02524 /* clear int flag */ 02525 PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex); 02526 02527 if (ep->type != EP_TYPE_BULK) 02528 { 02529 ep->xfer_len = 0U; 02530 02531 #if (USE_USB_DOUBLE_BUFFER == 1U) 02532 if (ep->doublebuffer != 0U) 02533 { 02534 if ((wEPVal & USB_EP_DTOG_TX) != 0U) 02535 { 02536 PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); 02537 } 02538 else 02539 { 02540 PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); 02541 } 02542 } 02543 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ 02544 02545 /* TX COMPLETE */ 02546 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02547 hpcd->DataInStageCallback(hpcd, ep->num); 02548 #else 02549 HAL_PCD_DataInStageCallback(hpcd, ep->num); 02550 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02551 } 02552 else 02553 { 02554 /* Manage Bulk Single Buffer Transaction */ 02555 if ((wEPVal & USB_EP_KIND) == 0U) 02556 { 02557 /* multi-packet on the NON control IN endpoint */ 02558 TxPctSize = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); 02559 02560 if (ep->xfer_len > TxPctSize) 02561 { 02562 ep->xfer_len -= TxPctSize; 02563 } 02564 else 02565 { 02566 ep->xfer_len = 0U; 02567 } 02568 02569 /* Zero Length Packet? */ 02570 if (ep->xfer_len == 0U) 02571 { 02572 /* TX COMPLETE */ 02573 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02574 hpcd->DataInStageCallback(hpcd, ep->num); 02575 #else 02576 HAL_PCD_DataInStageCallback(hpcd, ep->num); 02577 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02578 } 02579 else 02580 { 02581 /* Transfer is not yet Done */ 02582 ep->xfer_buff += TxPctSize; 02583 ep->xfer_count += TxPctSize; 02584 (void)USB_EPStartXfer(hpcd->Instance, ep); 02585 } 02586 } 02587 #if (USE_USB_DOUBLE_BUFFER == 1U) 02588 /* Double Buffer bulk IN (bulk transfer Len > Ep_Mps) */ 02589 else 02590 { 02591 (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal); 02592 } 02593 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ 02594 } 02595 } 02596 } 02597 } 02598 02599 return HAL_OK; 02600 } 02601 02602 02603 #if (USE_USB_DOUBLE_BUFFER == 1U) 02604 /** 02605 * @brief Manage double buffer bulk out transaction from ISR 02606 * @param hpcd PCD handle 02607 * @param ep current endpoint handle 02608 * @param wEPVal Last snapshot of EPRx register value taken in ISR 02609 * @retval HAL status 02610 */ 02611 static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, 02612 PCD_EPTypeDef *ep, uint16_t wEPVal) 02613 { 02614 uint16_t count; 02615 02616 /* Manage Buffer0 OUT */ 02617 if ((wEPVal & USB_EP_DTOG_RX) != 0U) 02618 { 02619 /* Get count of received Data on buffer0 */ 02620 count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); 02621 02622 if (ep->xfer_len >= count) 02623 { 02624 ep->xfer_len -= count; 02625 } 02626 else 02627 { 02628 ep->xfer_len = 0U; 02629 } 02630 02631 if (ep->xfer_len == 0U) 02632 { 02633 /* set NAK to OUT endpoint since double buffer is enabled */ 02634 PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK); 02635 } 02636 02637 /* Check if Buffer1 is in blocked state which requires to toggle */ 02638 if ((wEPVal & USB_EP_DTOG_TX) != 0U) 02639 { 02640 PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U); 02641 } 02642 02643 if (count != 0U) 02644 { 02645 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); 02646 } 02647 } 02648 /* Manage Buffer 1 DTOG_RX=0 */ 02649 else 02650 { 02651 /* Get count of received data */ 02652 count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); 02653 02654 if (ep->xfer_len >= count) 02655 { 02656 ep->xfer_len -= count; 02657 } 02658 else 02659 { 02660 ep->xfer_len = 0U; 02661 } 02662 02663 if (ep->xfer_len == 0U) 02664 { 02665 /* set NAK on the current endpoint */ 02666 PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK); 02667 } 02668 02669 /*Need to FreeUser Buffer*/ 02670 if ((wEPVal & USB_EP_DTOG_TX) == 0U) 02671 { 02672 PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U); 02673 } 02674 02675 if (count != 0U) 02676 { 02677 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); 02678 } 02679 } 02680 02681 return count; 02682 } 02683 02684 02685 /** 02686 * @brief Manage double buffer bulk IN transaction from ISR 02687 * @param hpcd PCD handle 02688 * @param ep current endpoint handle 02689 * @param wEPVal Last snapshot of EPRx register value taken in ISR 02690 * @retval HAL status 02691 */ 02692 static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, 02693 PCD_EPTypeDef *ep, uint16_t wEPVal) 02694 { 02695 uint32_t len; 02696 uint16_t TxPctSize; 02697 02698 /* Data Buffer0 ACK received */ 02699 if ((wEPVal & USB_EP_DTOG_TX) != 0U) 02700 { 02701 /* multi-packet on the NON control IN endpoint */ 02702 TxPctSize = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); 02703 02704 if (ep->xfer_len > TxPctSize) 02705 { 02706 ep->xfer_len -= TxPctSize; 02707 } 02708 else 02709 { 02710 ep->xfer_len = 0U; 02711 } 02712 02713 /* Transfer is completed */ 02714 if (ep->xfer_len == 0U) 02715 { 02716 PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); 02717 PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); 02718 02719 /* TX COMPLETE */ 02720 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02721 hpcd->DataInStageCallback(hpcd, ep->num); 02722 #else 02723 HAL_PCD_DataInStageCallback(hpcd, ep->num); 02724 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02725 02726 if ((wEPVal & USB_EP_DTOG_RX) != 0U) 02727 { 02728 PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); 02729 } 02730 } 02731 else /* Transfer is not yet Done */ 02732 { 02733 /* need to Free USB Buff */ 02734 if ((wEPVal & USB_EP_DTOG_RX) != 0U) 02735 { 02736 PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); 02737 } 02738 02739 /* Still there is data to Fill in the next Buffer */ 02740 if (ep->xfer_fill_db == 1U) 02741 { 02742 ep->xfer_buff += TxPctSize; 02743 ep->xfer_count += TxPctSize; 02744 02745 /* Calculate the len of the new buffer to fill */ 02746 if (ep->xfer_len_db >= ep->maxpacket) 02747 { 02748 len = ep->maxpacket; 02749 ep->xfer_len_db -= len; 02750 } 02751 else if (ep->xfer_len_db == 0U) 02752 { 02753 len = TxPctSize; 02754 ep->xfer_fill_db = 0U; 02755 } 02756 else 02757 { 02758 ep->xfer_fill_db = 0U; 02759 len = ep->xfer_len_db; 02760 ep->xfer_len_db = 0U; 02761 } 02762 02763 /* Write remaining Data to Buffer */ 02764 /* Set the Double buffer counter for pma buffer1 */ 02765 PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len); 02766 02767 /* Copy user buffer to USB PMA */ 02768 USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, (uint16_t)len); 02769 } 02770 } 02771 } 02772 else /* Data Buffer1 ACK received */ 02773 { 02774 /* multi-packet on the NON control IN endpoint */ 02775 TxPctSize = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); 02776 02777 if (ep->xfer_len >= TxPctSize) 02778 { 02779 ep->xfer_len -= TxPctSize; 02780 } 02781 else 02782 { 02783 ep->xfer_len = 0U; 02784 } 02785 02786 /* Transfer is completed */ 02787 if (ep->xfer_len == 0U) 02788 { 02789 PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); 02790 PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); 02791 02792 /* TX COMPLETE */ 02793 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 02794 hpcd->DataInStageCallback(hpcd, ep->num); 02795 #else 02796 HAL_PCD_DataInStageCallback(hpcd, ep->num); 02797 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 02798 02799 /* need to Free USB Buff */ 02800 if ((wEPVal & USB_EP_DTOG_RX) == 0U) 02801 { 02802 PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); 02803 } 02804 } 02805 else /* Transfer is not yet Done */ 02806 { 02807 /* need to Free USB Buff */ 02808 if ((wEPVal & USB_EP_DTOG_RX) == 0U) 02809 { 02810 PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); 02811 } 02812 02813 /* Still there is data to Fill in the next Buffer */ 02814 if (ep->xfer_fill_db == 1U) 02815 { 02816 ep->xfer_buff += TxPctSize; 02817 ep->xfer_count += TxPctSize; 02818 02819 /* Calculate the len of the new buffer to fill */ 02820 if (ep->xfer_len_db >= ep->maxpacket) 02821 { 02822 len = ep->maxpacket; 02823 ep->xfer_len_db -= len; 02824 } 02825 else if (ep->xfer_len_db == 0U) 02826 { 02827 len = TxPctSize; 02828 ep->xfer_fill_db = 0U; 02829 } 02830 else 02831 { 02832 len = ep->xfer_len_db; 02833 ep->xfer_len_db = 0U; 02834 ep->xfer_fill_db = 0; 02835 } 02836 02837 /* Set the Double buffer counter for pmabuffer1 */ 02838 PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len); 02839 02840 /* Copy the user buffer to USB PMA */ 02841 USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, (uint16_t)len); 02842 } 02843 } 02844 } 02845 02846 /*enable endpoint IN*/ 02847 PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID); 02848 02849 return HAL_OK; 02850 } 02851 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ 02852 02853 #endif /* defined (USB) */ 02854 02855 /** 02856 * @} 02857 */ 02858 #endif /* defined (USB) || defined (USB_OTG_FS) */ 02859 #endif /* HAL_PCD_MODULE_ENABLED */ 02860 02861 /** 02862 * @} 02863 */ 02864 02865 /** 02866 * @} 02867 */