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