Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TUKS-COURSE-TIMER by
stm32l4xx_hal_pcd.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_pcd.c 00004 * @author MCD Application Team 00005 * @version V1.5.1 00006 * @date 31-May-2016 00007 * @brief PCD HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities of the USB Peripheral Controller: 00010 * + Initialization and de-initialization functions 00011 * + IO operation functions 00012 * + Peripheral Control functions 00013 * + Peripheral State functions 00014 * 00015 @verbatim 00016 ============================================================================== 00017 ##### How to use this driver ##### 00018 ============================================================================== 00019 [..] 00020 The PCD HAL driver can be used as follows: 00021 00022 (#) Declare a PCD_HandleTypeDef handle structure, for example: 00023 PCD_HandleTypeDef hpcd; 00024 00025 (#) Fill parameters of Init structure in HCD handle 00026 00027 (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) 00028 00029 (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: 00030 (##) Enable the PCD/USB Low Level interface clock using 00031 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); 00032 (##) Initialize the related GPIO clocks 00033 (##) Configure PCD pin-out 00034 (##) Configure PCD NVIC interrupt 00035 00036 (#)Associate the Upper USB device stack to the HAL PCD Driver: 00037 (##) hpcd.pData = pdev; 00038 00039 (#)Enable PCD transmission and reception: 00040 (##) HAL_PCD_Start(); 00041 00042 @endverbatim 00043 ****************************************************************************** 00044 * @attention 00045 * 00046 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00047 * 00048 * Redistribution and use in source and binary forms, with or without modification, 00049 * are permitted provided that the following conditions are met: 00050 * 1. Redistributions of source code must retain the above copyright notice, 00051 * this list of conditions and the following disclaimer. 00052 * 2. Redistributions in binary form must reproduce the above copyright notice, 00053 * this list of conditions and the following disclaimer in the documentation 00054 * and/or other materials provided with the distribution. 00055 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00056 * may be used to endorse or promote products derived from this software 00057 * without specific prior written permission. 00058 * 00059 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00060 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00061 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00062 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00063 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00064 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00065 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00066 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00067 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00068 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00069 * 00070 ****************************************************************************** 00071 */ 00072 00073 /* Includes ------------------------------------------------------------------*/ 00074 #include "stm32l4xx_hal.h" 00075 00076 /** @addtogroup STM32L4xx_HAL_Driver 00077 * @{ 00078 */ 00079 00080 /** @defgroup PCD PCD 00081 * @brief PCD HAL module driver 00082 * @{ 00083 */ 00084 00085 #ifdef HAL_PCD_MODULE_ENABLED 00086 00087 #if defined(STM32L475xx) || defined(STM32L476xx) || \ 00088 defined(STM32L485xx) || defined(STM32L486xx) || \ 00089 defined(STM32L432xx) || defined(STM32L433xx) || \ 00090 defined(STM32L442xx) || defined(STM32L443xx) 00091 00092 /* Private types -------------------------------------------------------------*/ 00093 /* Private variables ---------------------------------------------------------*/ 00094 /* Private constants ---------------------------------------------------------*/ 00095 /* Private macros ------------------------------------------------------------*/ 00096 /** @defgroup PCD_Private_Macros PCD Private Macros 00097 * @{ 00098 */ 00099 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) 00100 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) 00101 /** 00102 * @} 00103 */ 00104 00105 /* Private functions prototypes ----------------------------------------------*/ 00106 /** @defgroup PCD_Private_Functions PCD Private Functions 00107 * @{ 00108 */ 00109 #if defined (USB_OTG_FS) 00110 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum); 00111 #endif /* USB_OTG_FS */ 00112 #if defined (USB) 00113 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd); 00114 #endif /* USB */ 00115 /** 00116 * @} 00117 */ 00118 00119 /* Exported functions --------------------------------------------------------*/ 00120 /** @defgroup PCD_Exported_Functions PCD Exported Functions 00121 * @{ 00122 */ 00123 00124 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions 00125 * @brief Initialization and Configuration functions 00126 * 00127 @verbatim 00128 =============================================================================== 00129 ##### Initialization and de-initialization functions ##### 00130 =============================================================================== 00131 [..] This section provides functions allowing to: 00132 00133 @endverbatim 00134 * @{ 00135 */ 00136 00137 /** 00138 * @brief Initializes the PCD according to the specified 00139 * parameters in the PCD_InitTypeDef and initialize the associated handle. 00140 * @param hpcd: PCD handle 00141 * @retval HAL status 00142 */ 00143 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) 00144 { 00145 uint32_t index = 0; 00146 00147 /* Check the PCD handle allocation */ 00148 if(hpcd == NULL) 00149 { 00150 return HAL_ERROR; 00151 } 00152 00153 /* Check the parameters */ 00154 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); 00155 00156 if(hpcd->State == HAL_PCD_STATE_RESET) 00157 { 00158 /* Allocate lock resource and initialize it */ 00159 hpcd->Lock = HAL_UNLOCKED; 00160 for (index = 0; index < hpcd->Init.dev_endpoints ; index++) 00161 hpcd->EPLock[index].Lock = HAL_UNLOCKED; 00162 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ 00163 HAL_PCD_MspInit(hpcd); 00164 } 00165 00166 hpcd->State = HAL_PCD_STATE_BUSY; 00167 00168 /* Disable the Interrupts */ 00169 __HAL_PCD_DISABLE(hpcd); 00170 00171 /*Init the Core (common init.) */ 00172 USB_CoreInit(hpcd->Instance, hpcd->Init); 00173 00174 /* Force Device Mode*/ 00175 USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE); 00176 00177 /* Init endpoints structures */ 00178 for (index = 0; index < hpcd->Init.dev_endpoints ; index++) 00179 { 00180 /* Init ep structure */ 00181 hpcd->IN_ep[index].is_in = 1; 00182 hpcd->IN_ep[index].num = index; 00183 hpcd->IN_ep[index].tx_fifo_num = index; 00184 /* Control until ep is activated */ 00185 hpcd->IN_ep[index].type = EP_TYPE_CTRL; 00186 hpcd->IN_ep[index].maxpacket = 0; 00187 hpcd->IN_ep[index].xfer_buff = 0; 00188 hpcd->IN_ep[index].xfer_len = 0; 00189 } 00190 00191 for (index = 0; index < 15 ; index++) 00192 { 00193 hpcd->OUT_ep[index].is_in = 0; 00194 hpcd->OUT_ep[index].num = index; 00195 hpcd->IN_ep[index].tx_fifo_num = index; 00196 /* Control until ep is activated */ 00197 hpcd->OUT_ep[index].type = EP_TYPE_CTRL; 00198 hpcd->OUT_ep[index].maxpacket = 0; 00199 hpcd->OUT_ep[index].xfer_buff = 0; 00200 hpcd->OUT_ep[index].xfer_len = 0; 00201 } 00202 /* Init Device */ 00203 USB_DevInit(hpcd->Instance, hpcd->Init); 00204 00205 hpcd->USB_Address = 0; 00206 00207 hpcd->State= HAL_PCD_STATE_READY; 00208 00209 /* Activate LPM */ 00210 if (hpcd->Init.lpm_enable ==1) 00211 { 00212 HAL_PCDEx_ActivateLPM(hpcd); 00213 } 00214 /* Activate Battery charging */ 00215 if (hpcd->Init.battery_charging_enable ==1) 00216 { 00217 HAL_PCDEx_ActivateBCD(hpcd); 00218 } 00219 USB_DevDisconnect (hpcd->Instance); 00220 return HAL_OK; 00221 } 00222 00223 /** 00224 * @brief DeInitializes the PCD peripheral. 00225 * @param hpcd: PCD handle 00226 * @retval HAL status 00227 */ 00228 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) 00229 { 00230 /* Check the PCD handle allocation */ 00231 if(hpcd == NULL) 00232 { 00233 return HAL_ERROR; 00234 } 00235 00236 hpcd->State = HAL_PCD_STATE_BUSY; 00237 00238 /* Stop Device */ 00239 HAL_PCD_Stop(hpcd); 00240 00241 /* DeInit the low level hardware */ 00242 HAL_PCD_MspDeInit(hpcd); 00243 00244 hpcd->State = HAL_PCD_STATE_RESET; 00245 00246 return HAL_OK; 00247 } 00248 00249 /** 00250 * @brief Initializes the PCD MSP. 00251 * @param hpcd: PCD handle 00252 * @retval None 00253 */ 00254 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) 00255 { 00256 /* Prevent unused argument(s) compilation warning */ 00257 UNUSED(hpcd); 00258 00259 /* NOTE : This function should not be modified, when the callback is needed, 00260 the HAL_PCD_MspInit could be implemented in the user file 00261 */ 00262 } 00263 00264 /** 00265 * @brief DeInitializes PCD MSP. 00266 * @param hpcd: PCD handle 00267 * @retval None 00268 */ 00269 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) 00270 { 00271 /* Prevent unused argument(s) compilation warning */ 00272 UNUSED(hpcd); 00273 00274 /* NOTE : This function should not be modified, when the callback is needed, 00275 the HAL_PCD_MspDeInit could be implemented in the user file 00276 */ 00277 } 00278 00279 /** 00280 * @} 00281 */ 00282 00283 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions 00284 * @brief Data transfers functions 00285 * 00286 @verbatim 00287 =============================================================================== 00288 ##### IO operation functions ##### 00289 =============================================================================== 00290 [..] 00291 This subsection provides a set of functions allowing to manage the PCD data 00292 transfers. 00293 00294 @endverbatim 00295 * @{ 00296 */ 00297 00298 /** 00299 * @brief Start The USB OTG Device. 00300 * @param hpcd: PCD handle 00301 * @retval HAL status 00302 */ 00303 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) 00304 { 00305 __HAL_LOCK(hpcd); 00306 USB_DevConnect (hpcd->Instance); 00307 __HAL_PCD_ENABLE(hpcd); 00308 __HAL_UNLOCK(hpcd); 00309 return HAL_OK; 00310 } 00311 00312 /** 00313 * @brief Stop The USB OTG Device. 00314 * @param hpcd: PCD handle 00315 * @retval HAL status 00316 */ 00317 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) 00318 { 00319 __HAL_LOCK(hpcd); 00320 __HAL_PCD_DISABLE(hpcd); 00321 USB_StopDevice(hpcd->Instance); 00322 USB_DevDisconnect (hpcd->Instance); 00323 __HAL_UNLOCK(hpcd); 00324 return HAL_OK; 00325 } 00326 #if defined (USB_OTG_FS) 00327 /** 00328 * @brief Handles PCD interrupt request. 00329 * @param hpcd: PCD handle 00330 * @retval HAL status 00331 */ 00332 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) 00333 { 00334 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 00335 uint32_t index = 0, ep_intr = 0, epint = 0, epnum = 0; 00336 uint32_t fifoemptymsk = 0, temp = 0; 00337 USB_OTG_EPTypeDef *ep = NULL; 00338 uint32_t hclk = 80000000; 00339 00340 /* ensure that we are in device mode */ 00341 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) 00342 { 00343 /* avoid spurious interrupt */ 00344 if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) 00345 { 00346 return; 00347 } 00348 00349 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) 00350 { 00351 /* incorrect mode, acknowledge the interrupt */ 00352 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); 00353 } 00354 00355 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) 00356 { 00357 epnum = 0; 00358 00359 /* Read in the device interrupt bits */ 00360 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); 00361 00362 while ( ep_intr ) 00363 { 00364 if (ep_intr & 0x1) 00365 { 00366 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum); 00367 00368 if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) 00369 { 00370 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); 00371 00372 if ((( (USBx_OUTEP(0)->DOEPINT & 0x8000) == 0)) ) 00373 { 00374 00375 if(hpcd->Init.dma_enable == 1) 00376 { 00377 hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); 00378 hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; 00379 } 00380 00381 HAL_PCD_DataOutStageCallback(hpcd, epnum); 00382 00383 if(hpcd->Init.dma_enable == 1) 00384 { 00385 if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0)) 00386 { 00387 /* this is ZLP, so prepare EP0 for next setup */ 00388 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); 00389 } 00390 } 00391 } 00392 /* Clear the SetPktRcvd flag*/ 00393 USBx_OUTEP(0)->DOEPINT |= 0x8020; 00394 } 00395 00396 if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) 00397 { 00398 /* Inform the upper layer that a setup packet is available */ 00399 HAL_PCD_SetupStageCallback(hpcd); 00400 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); 00401 } 00402 00403 if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) 00404 { 00405 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); 00406 } 00407 } 00408 epnum++; 00409 ep_intr >>= 1; 00410 } 00411 } 00412 00413 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) 00414 { 00415 /* Read in the device interrupt bits */ 00416 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); 00417 00418 epnum = 0; 00419 00420 while ( ep_intr ) 00421 { 00422 if (ep_intr & 0x1) /* In ITR */ 00423 { 00424 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum); 00425 00426 if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) 00427 { 00428 fifoemptymsk = 0x1 << epnum; 00429 atomic_clr_u32(&USBx_DEVICE->DIEPEMPMSK, fifoemptymsk); 00430 00431 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); 00432 00433 if (hpcd->Init.dma_enable == 1) 00434 { 00435 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; 00436 } 00437 00438 HAL_PCD_DataInStageCallback(hpcd, epnum); 00439 00440 if (hpcd->Init.dma_enable == 1) 00441 { 00442 /* this is ZLP, so prepare EP0 for next setup */ 00443 if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0)) 00444 { 00445 /* prepare to rx more setup packets */ 00446 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); 00447 } 00448 } 00449 } 00450 if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) 00451 { 00452 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); 00453 } 00454 if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) 00455 { 00456 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); 00457 } 00458 if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) 00459 { 00460 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); 00461 } 00462 if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) 00463 { 00464 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); 00465 } 00466 if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) 00467 { 00468 PCD_WriteEmptyTxFifo(hpcd , epnum); 00469 } 00470 } 00471 epnum++; 00472 ep_intr >>= 1; 00473 } 00474 } 00475 00476 /* Handle Resume Interrupt */ 00477 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) 00478 { 00479 /* Clear the Remote Wake-up Signaling */ 00480 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 00481 00482 if(hpcd->LPM_State == LPM_L1) 00483 { 00484 hpcd->LPM_State = LPM_L0; 00485 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); 00486 } 00487 else 00488 { 00489 HAL_PCD_ResumeCallback(hpcd); 00490 } 00491 00492 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); 00493 } 00494 00495 /* Handle Suspend Interrupt */ 00496 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) 00497 { 00498 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) 00499 { 00500 00501 HAL_PCD_SuspendCallback(hpcd); 00502 } 00503 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); 00504 } 00505 00506 /* Handle LPM Interrupt */ 00507 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) 00508 { 00509 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); 00510 if( hpcd->LPM_State == LPM_L0) 00511 { 00512 hpcd->LPM_State = LPM_L1; 00513 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ; 00514 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); 00515 } 00516 else 00517 { 00518 HAL_PCD_SuspendCallback(hpcd); 00519 } 00520 } 00521 00522 /* Handle Reset Interrupt */ 00523 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) 00524 { 00525 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 00526 USB_FlushTxFifo(hpcd->Instance , 0 ); 00527 00528 for (index = 0; index < hpcd->Init.dev_endpoints ; index++) 00529 { 00530 USBx_INEP(index)->DIEPINT = 0xFF; 00531 USBx_OUTEP(index)->DOEPINT = 0xFF; 00532 } 00533 USBx_DEVICE->DAINT = 0xFFFFFFFF; 00534 USBx_DEVICE->DAINTMSK |= 0x10001; 00535 00536 if(hpcd->Init.use_dedicated_ep1) 00537 { 00538 USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); 00539 USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); 00540 } 00541 else 00542 { 00543 USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); 00544 USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); 00545 } 00546 00547 /* Set Default Address to 0 */ 00548 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; 00549 00550 /* setup EP0 to receive SETUP packets */ 00551 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); 00552 00553 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); 00554 } 00555 00556 /* Handle Enumeration done Interrupt */ 00557 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) 00558 { 00559 USB_ActivateSetup(hpcd->Instance); 00560 hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; 00561 00562 hpcd->Init.speed = USB_OTG_SPEED_FULL; 00563 hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ; 00564 00565 /* The USBTRD is configured according to the tables below, depending on AHB frequency 00566 used by application. In the low AHB frequency range it is used to stretch enough the USB response 00567 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access 00568 latency to the Data FIFO */ 00569 00570 /* Get hclk frequency value */ 00571 hclk = HAL_RCC_GetHCLKFreq(); 00572 00573 if((hclk >= 14200000)&&(hclk < 15000000)) 00574 { 00575 /* hclk Clock Range between 14.2-15 MHz */ 00576 hpcd->Instance->GUSBCFG |= (uint32_t)((0xF << 10) & USB_OTG_GUSBCFG_TRDT); 00577 } 00578 00579 else if((hclk >= 15000000)&&(hclk < 16000000)) 00580 { 00581 /* hclk Clock Range between 15-16 MHz */ 00582 hpcd->Instance->GUSBCFG |= (uint32_t)((0xE << 10) & USB_OTG_GUSBCFG_TRDT); 00583 } 00584 00585 else if((hclk >= 16000000)&&(hclk < 17200000)) 00586 { 00587 /* hclk Clock Range between 16-17.2 MHz */ 00588 hpcd->Instance->GUSBCFG |= (uint32_t)((0xD << 10) & USB_OTG_GUSBCFG_TRDT); 00589 } 00590 00591 else if((hclk >= 17200000)&&(hclk < 18500000)) 00592 { 00593 /* hclk Clock Range between 17.2-18.5 MHz */ 00594 hpcd->Instance->GUSBCFG |= (uint32_t)((0xC << 10) & USB_OTG_GUSBCFG_TRDT); 00595 } 00596 00597 else if((hclk >= 18500000)&&(hclk < 20000000)) 00598 { 00599 /* hclk Clock Range between 18.5-20 MHz */ 00600 hpcd->Instance->GUSBCFG |= (uint32_t)((0xB << 10) & USB_OTG_GUSBCFG_TRDT); 00601 } 00602 00603 else if((hclk >= 20000000)&&(hclk < 21800000)) 00604 { 00605 /* hclk Clock Range between 20-21.8 MHz */ 00606 hpcd->Instance->GUSBCFG |= (uint32_t)((0xA << 10) & USB_OTG_GUSBCFG_TRDT); 00607 } 00608 00609 else if((hclk >= 21800000)&&(hclk < 24000000)) 00610 { 00611 /* hclk Clock Range between 21.8-24 MHz */ 00612 hpcd->Instance->GUSBCFG |= (uint32_t)((0x9 << 10) & USB_OTG_GUSBCFG_TRDT); 00613 } 00614 00615 else if((hclk >= 24000000)&&(hclk < 27700000)) 00616 { 00617 /* hclk Clock Range between 24-27.7 MHz */ 00618 hpcd->Instance->GUSBCFG |= (uint32_t)((0x8 << 10) & USB_OTG_GUSBCFG_TRDT); 00619 } 00620 00621 else if((hclk >= 27700000)&&(hclk < 32000000)) 00622 { 00623 /* hclk Clock Range between 27.7-32 MHz */ 00624 hpcd->Instance->GUSBCFG |= (uint32_t)((0x7 << 10) & USB_OTG_GUSBCFG_TRDT); 00625 } 00626 00627 else /* if(hclk >= 32000000) */ 00628 { 00629 /* hclk Clock Range between 32-80 MHz */ 00630 hpcd->Instance->GUSBCFG |= (uint32_t)((0x6 << 10) & USB_OTG_GUSBCFG_TRDT); 00631 } 00632 00633 HAL_PCD_ResetCallback(hpcd); 00634 00635 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); 00636 } 00637 00638 /* Handle RxQLevel Interrupt */ 00639 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL)) 00640 { 00641 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00642 00643 temp = USBx->GRXSTSP; 00644 00645 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM]; 00646 00647 if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) 00648 { 00649 if((temp & USB_OTG_GRXSTSP_BCNT) != 0) 00650 { 00651 USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4); 00652 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 00653 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 00654 } 00655 } 00656 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) 00657 { 00658 USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8); 00659 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; 00660 } 00661 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); 00662 } 00663 00664 /* Handle SOF Interrupt */ 00665 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) 00666 { 00667 HAL_PCD_SOFCallback(hpcd); 00668 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); 00669 } 00670 00671 /* Handle Incomplete ISO IN Interrupt */ 00672 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) 00673 { 00674 HAL_PCD_ISOINIncompleteCallback(hpcd, epnum); 00675 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); 00676 } 00677 00678 /* Handle Incomplete ISO OUT Interrupt */ 00679 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) 00680 { 00681 HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum); 00682 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); 00683 } 00684 00685 /* Handle Connection event Interrupt */ 00686 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) 00687 { 00688 HAL_PCD_ConnectCallback(hpcd); 00689 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); 00690 } 00691 00692 /* Handle Disconnection event Interrupt */ 00693 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) 00694 { 00695 temp = hpcd->Instance->GOTGINT; 00696 00697 if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) 00698 { 00699 HAL_PCD_DisconnectCallback(hpcd); 00700 } 00701 hpcd->Instance->GOTGINT |= temp; 00702 } 00703 } 00704 } 00705 00706 #endif /* USB_OTG_FS */ 00707 00708 #if defined (USB) 00709 /** 00710 * @brief This function handles PCD interrupt request. 00711 * @param hpcd: PCD handle 00712 * @retval HAL status 00713 */ 00714 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) 00715 { 00716 uint32_t wInterrupt_Mask = 0; 00717 00718 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR)) 00719 { 00720 /* servicing of the endpoint correct transfer interrupt */ 00721 /* clear of the CTR flag into the sub */ 00722 PCD_EP_ISR_Handler(hpcd); 00723 } 00724 00725 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET)) 00726 { 00727 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); 00728 HAL_PCD_ResetCallback(hpcd); 00729 HAL_PCD_SetAddress(hpcd, 0); 00730 } 00731 00732 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR)) 00733 { 00734 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); 00735 } 00736 00737 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR)) 00738 { 00739 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); 00740 } 00741 00742 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP)) 00743 { 00744 00745 hpcd->Instance->CNTR &= ~(USB_CNTR_LPMODE); 00746 00747 /*set wInterrupt_Mask global variable*/ 00748 wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \ 00749 | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM; 00750 00751 /*Set interrupt mask*/ 00752 hpcd->Instance->CNTR = wInterrupt_Mask; 00753 00754 /* enable L1REQ interrupt */ 00755 if (hpcd->Init.lpm_enable ==1) 00756 { 00757 wInterrupt_Mask |= USB_CNTR_L1REQM; 00758 00759 /* Enable LPM support and enable ACK answer to LPM request*/ 00760 USB_TypeDef *USBx = hpcd->Instance; 00761 hpcd->lpm_active = ENABLE; 00762 hpcd->LPM_State = LPM_L0; 00763 00764 USBx->LPMCSR |= (USB_LPMCSR_LMPEN); 00765 USBx->LPMCSR |= (USB_LPMCSR_LPMACK); 00766 } 00767 00768 if(hpcd->LPM_State == LPM_L1) 00769 { 00770 hpcd->LPM_State = LPM_L0; 00771 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); 00772 } 00773 00774 HAL_PCD_ResumeCallback(hpcd); 00775 00776 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); 00777 } 00778 00779 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP)) 00780 { 00781 /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ 00782 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); 00783 00784 /* Force low-power mode in the macrocell */ 00785 hpcd->Instance->CNTR |= USB_CNTR_FSUSP; 00786 hpcd->Instance->CNTR |= USB_CNTR_LPMODE; 00787 00788 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0) 00789 { 00790 HAL_PCD_SuspendCallback(hpcd); 00791 } 00792 } 00793 00794 /* Handle LPM Interrupt */ 00795 if(__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ)) 00796 { 00797 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); 00798 if( hpcd->LPM_State == LPM_L0) 00799 { 00800 /* Force suspend and low-power mode before going to L1 state*/ 00801 hpcd->Instance->CNTR |= USB_CNTR_LPMODE; 00802 hpcd->Instance->CNTR |= USB_CNTR_FSUSP; 00803 00804 hpcd->LPM_State = LPM_L1; 00805 hpcd->BESL = (hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >>2 ; 00806 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); 00807 } 00808 else 00809 { 00810 HAL_PCD_SuspendCallback(hpcd); 00811 } 00812 } 00813 00814 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF)) 00815 { 00816 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); 00817 HAL_PCD_SOFCallback(hpcd); 00818 } 00819 00820 if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF)) 00821 { 00822 /* clear ESOF flag in ISTR */ 00823 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); 00824 } 00825 } 00826 #endif /* USB */ 00827 00828 /** 00829 * @brief Data OUT stage callback. 00830 * @param hpcd: PCD handle 00831 * @param epnum: endpoint number 00832 * @retval None 00833 */ 00834 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00835 { 00836 /* Prevent unused argument(s) compilation warning */ 00837 UNUSED(hpcd); 00838 UNUSED(epnum); 00839 00840 /* NOTE : This function should not be modified, when the callback is needed, 00841 the HAL_PCD_DataOutStageCallback could be implemented in the user file 00842 */ 00843 } 00844 00845 /** 00846 * @brief Data IN stage callback. 00847 * @param hpcd: PCD handle 00848 * @param epnum: endpoint number 00849 * @retval None 00850 */ 00851 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00852 { 00853 /* Prevent unused argument(s) compilation warning */ 00854 UNUSED(hpcd); 00855 UNUSED(epnum); 00856 00857 /* NOTE : This function should not be modified, when the callback is needed, 00858 the HAL_PCD_DataInStageCallback could be implemented in the user file 00859 */ 00860 } 00861 /** 00862 * @brief Setup stage callback. 00863 * @param hpcd: PCD handle 00864 * @retval None 00865 */ 00866 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) 00867 { 00868 /* Prevent unused argument(s) compilation warning */ 00869 UNUSED(hpcd); 00870 00871 /* NOTE : This function should not be modified, when the callback is needed, 00872 the HAL_PCD_SetupStageCallback could be implemented in the user file 00873 */ 00874 } 00875 00876 /** 00877 * @brief USB Start Of Frame callback. 00878 * @param hpcd: PCD handle 00879 * @retval None 00880 */ 00881 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) 00882 { 00883 /* Prevent unused argument(s) compilation warning */ 00884 UNUSED(hpcd); 00885 00886 /* NOTE : This function should not be modified, when the callback is needed, 00887 the HAL_PCD_SOFCallback could be implemented in the user file 00888 */ 00889 } 00890 00891 /** 00892 * @brief USB Reset callback. 00893 * @param hpcd: PCD handle 00894 * @retval None 00895 */ 00896 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) 00897 { 00898 /* Prevent unused argument(s) compilation warning */ 00899 UNUSED(hpcd); 00900 00901 /* NOTE : This function should not be modified, when the callback is needed, 00902 the HAL_PCD_ResetCallback could be implemented in the user file 00903 */ 00904 } 00905 00906 /** 00907 * @brief Suspend event callback. 00908 * @param hpcd: PCD handle 00909 * @retval None 00910 */ 00911 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) 00912 { 00913 /* Prevent unused argument(s) compilation warning */ 00914 UNUSED(hpcd); 00915 00916 /* NOTE : This function should not be modified, when the callback is needed, 00917 the HAL_PCD_SuspendCallback could be implemented in the user file 00918 */ 00919 } 00920 00921 /** 00922 * @brief Resume event callback. 00923 * @param hpcd: PCD handle 00924 * @retval None 00925 */ 00926 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) 00927 { 00928 /* Prevent unused argument(s) compilation warning */ 00929 UNUSED(hpcd); 00930 00931 /* NOTE : This function should not be modified, when the callback is needed, 00932 the HAL_PCD_ResumeCallback could be implemented in the user file 00933 */ 00934 } 00935 00936 /** 00937 * @brief Incomplete ISO OUT callback. 00938 * @param hpcd: PCD handle 00939 * @param epnum: endpoint number 00940 * @retval None 00941 */ 00942 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00943 { 00944 /* Prevent unused argument(s) compilation warning */ 00945 UNUSED(hpcd); 00946 UNUSED(epnum); 00947 00948 /* NOTE : This function should not be modified, when the callback is needed, 00949 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file 00950 */ 00951 } 00952 00953 /** 00954 * @brief Incomplete ISO IN callback. 00955 * @param hpcd: PCD handle 00956 * @param epnum: endpoint number 00957 * @retval None 00958 */ 00959 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) 00960 { 00961 /* Prevent unused argument(s) compilation warning */ 00962 UNUSED(hpcd); 00963 UNUSED(epnum); 00964 00965 /* NOTE : This function should not be modified, when the callback is needed, 00966 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file 00967 */ 00968 } 00969 00970 /** 00971 * @brief Connection event callback. 00972 * @param hpcd: PCD handle 00973 * @retval None 00974 */ 00975 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) 00976 { 00977 /* Prevent unused argument(s) compilation warning */ 00978 UNUSED(hpcd); 00979 00980 /* NOTE : This function should not be modified, when the callback is needed, 00981 the HAL_PCD_ConnectCallback could be implemented in the user file 00982 */ 00983 } 00984 00985 /** 00986 * @brief Disconnection event callback. 00987 * @param hpcd: PCD handle 00988 * @retval None 00989 */ 00990 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) 00991 { 00992 /* Prevent unused argument(s) compilation warning */ 00993 UNUSED(hpcd); 00994 00995 /* NOTE : This function should not be modified, when the callback is needed, 00996 the HAL_PCD_DisconnectCallback could be implemented in the user file 00997 */ 00998 } 00999 01000 /** 01001 * @} 01002 */ 01003 01004 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions 01005 * @brief management functions 01006 * 01007 @verbatim 01008 =============================================================================== 01009 ##### Peripheral Control functions ##### 01010 =============================================================================== 01011 [..] 01012 This subsection provides a set of functions allowing to control the PCD data 01013 transfers. 01014 01015 @endverbatim 01016 * @{ 01017 */ 01018 01019 /** 01020 * @brief Connect the USB device. 01021 * @param hpcd: PCD handle 01022 * @retval HAL status 01023 */ 01024 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) 01025 { 01026 __HAL_LOCK(hpcd); 01027 USB_DevConnect(hpcd->Instance); 01028 __HAL_UNLOCK(hpcd); 01029 return HAL_OK; 01030 } 01031 01032 /** 01033 * @brief Disconnect the USB device. 01034 * @param hpcd: PCD handle 01035 * @retval HAL status 01036 */ 01037 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) 01038 { 01039 __HAL_LOCK(hpcd); 01040 USB_DevDisconnect(hpcd->Instance); 01041 __HAL_UNLOCK(hpcd); 01042 return HAL_OK; 01043 } 01044 01045 /** 01046 * @brief Set the USB Device address. 01047 * @param hpcd: PCD handle 01048 * @param address: new device address 01049 * @retval HAL status 01050 */ 01051 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) 01052 { 01053 __HAL_LOCK(hpcd); 01054 hpcd->USB_Address = address; 01055 USB_SetDevAddress(hpcd->Instance, address); 01056 __HAL_UNLOCK(hpcd); 01057 return HAL_OK; 01058 } 01059 /** 01060 * @brief Open and configure an endpoint. 01061 * @param hpcd: PCD handle 01062 * @param ep_addr: endpoint address 01063 * @param ep_mps: endpoint max packet size 01064 * @param ep_type: endpoint type 01065 * @retval HAL status 01066 */ 01067 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) 01068 { 01069 HAL_StatusTypeDef ret = HAL_OK; 01070 PCD_EPTypeDef *ep = NULL; 01071 01072 if ((ep_addr & 0x80) == 0x80) 01073 { 01074 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01075 } 01076 else 01077 { 01078 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; 01079 } 01080 ep->num = ep_addr & 0x7F; 01081 01082 ep->is_in = (0x80 & ep_addr) != 0; 01083 ep->maxpacket = ep_mps; 01084 ep->type = ep_type; 01085 01086 __HAL_LOCK(hpcd); 01087 USB_ActivateEndpoint(hpcd->Instance , ep); 01088 __HAL_UNLOCK(hpcd); 01089 return ret; 01090 01091 } 01092 01093 01094 /** 01095 * @brief Deactivate an endpoint. 01096 * @param hpcd: PCD handle 01097 * @param ep_addr: endpoint address 01098 * @retval HAL status 01099 */ 01100 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01101 { 01102 PCD_EPTypeDef *ep = NULL; 01103 01104 if ((ep_addr & 0x80) == 0x80) 01105 { 01106 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01107 } 01108 else 01109 { 01110 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; 01111 } 01112 ep->num = ep_addr & 0x7F; 01113 01114 ep->is_in = (0x80 & ep_addr) != 0; 01115 01116 __HAL_LOCK(hpcd); 01117 USB_DeactivateEndpoint(hpcd->Instance , ep); 01118 __HAL_UNLOCK(hpcd); 01119 return HAL_OK; 01120 } 01121 01122 01123 /** 01124 * @brief Receive an amount of data. 01125 * @param hpcd: PCD handle 01126 * @param ep_addr: endpoint address 01127 * @param pBuf: pointer to the reception buffer 01128 * @param len: amount of data to be received 01129 * @retval HAL status 01130 */ 01131 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01132 { 01133 PCD_EPTypeDef *ep = NULL; 01134 01135 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; 01136 01137 /*setup and start the Xfer */ 01138 ep->xfer_buff = pBuf; 01139 ep->xfer_len = len; 01140 ep->xfer_count = 0; 01141 ep->is_in = 0; 01142 ep->num = ep_addr & 0x7F; 01143 01144 __HAL_LOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01145 01146 if ((ep_addr & 0x7F) == 0 ) 01147 { 01148 USB_EP0StartXfer(hpcd->Instance, ep, hpcd->Init.dma_enable); 01149 } 01150 else 01151 { 01152 USB_EPStartXfer(hpcd->Instance, ep, hpcd->Init.dma_enable); 01153 } 01154 __HAL_UNLOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01155 01156 return HAL_OK; 01157 } 01158 01159 /** 01160 * @brief Get Received Data Size. 01161 * @param hpcd: PCD handle 01162 * @param ep_addr: endpoint address 01163 * @retval Data Size 01164 */ 01165 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01166 { 01167 return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count; 01168 } 01169 /** 01170 * @brief Send an amount of data. 01171 * @param hpcd: PCD handle 01172 * @param ep_addr: endpoint address 01173 * @param pBuf: pointer to the transmission buffer 01174 * @param len: amount of data to be sent 01175 * @retval HAL status 01176 */ 01177 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) 01178 { 01179 PCD_EPTypeDef *ep = NULL; 01180 01181 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01182 01183 /*setup and start the Xfer */ 01184 ep->xfer_buff = pBuf; 01185 ep->xfer_len = len; 01186 ep->xfer_count = 0; 01187 ep->is_in = 1; 01188 ep->num = ep_addr & 0x7F; 01189 01190 __HAL_LOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01191 01192 if ((ep_addr & 0x7F) == 0 ) 01193 { 01194 USB_EP0StartXfer(hpcd->Instance,ep, hpcd->Init.dma_enable); 01195 } 01196 else 01197 { 01198 USB_EPStartXfer(hpcd->Instance, ep, hpcd->Init.dma_enable); 01199 } 01200 01201 __HAL_UNLOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01202 01203 return HAL_OK; 01204 } 01205 01206 /** 01207 * @brief Set a STALL condition over an endpoint. 01208 * @param hpcd: PCD handle 01209 * @param ep_addr: endpoint address 01210 * @retval HAL status 01211 */ 01212 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01213 { 01214 PCD_EPTypeDef *ep = NULL; 01215 01216 if ((0x80 & ep_addr) == 0x80) 01217 { 01218 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01219 } 01220 else 01221 { 01222 ep = &hpcd->OUT_ep[ep_addr]; 01223 } 01224 01225 ep->is_stall = 1; 01226 ep->num = ep_addr & 0x7F; 01227 ep->is_in = ((ep_addr & 0x80) == 0x80); 01228 01229 __HAL_LOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01230 USB_EPSetStall(hpcd->Instance , ep); 01231 if((ep_addr & 0x7F) == 0) 01232 { 01233 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); 01234 } 01235 __HAL_UNLOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01236 01237 return HAL_OK; 01238 } 01239 01240 /** 01241 * @brief Clear a STALL condition over in an endpoint. 01242 * @param hpcd: PCD handle 01243 * @param ep_addr: endpoint address 01244 * @retval HAL status 01245 */ 01246 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01247 { 01248 PCD_EPTypeDef *ep = NULL; 01249 01250 if ((0x80 & ep_addr) == 0x80) 01251 { 01252 ep = &hpcd->IN_ep[ep_addr & 0x7F]; 01253 } 01254 else 01255 { 01256 ep = &hpcd->OUT_ep[ep_addr]; 01257 } 01258 01259 ep->is_stall = 0; 01260 ep->num = ep_addr & 0x7F; 01261 ep->is_in = ((ep_addr & 0x80) == 0x80); 01262 01263 __HAL_LOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01264 USB_EPClearStall(hpcd->Instance , ep); 01265 __HAL_UNLOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01266 01267 return HAL_OK; 01268 } 01269 01270 /** 01271 * @brief Flush an endpoint. 01272 * @param hpcd: PCD handle 01273 * @param ep_addr: endpoint address 01274 * @retval HAL status 01275 */ 01276 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) 01277 { 01278 __HAL_LOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01279 if ((ep_addr & 0x80) == 0x80) 01280 { 01281 USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F); 01282 } 01283 else 01284 { 01285 USB_FlushRxFifo(hpcd->Instance); 01286 } 01287 01288 __HAL_UNLOCK(&hpcd->EPLock[ep_addr & 0x7F]); 01289 01290 return HAL_OK; 01291 } 01292 01293 /** 01294 * @brief Activate remote wakeup signalling. 01295 * @param hpcd: PCD handle 01296 * @retval HAL status 01297 */ 01298 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 01299 { 01300 return(USB_ActivateRemoteWakeup(hpcd->Instance)); 01301 } 01302 01303 /** 01304 * @brief De-activate remote wakeup signalling. 01305 * @param hpcd: PCD handle 01306 * @retval HAL status 01307 */ 01308 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) 01309 { 01310 return(USB_DeActivateRemoteWakeup(hpcd->Instance)); 01311 } 01312 /** 01313 * @} 01314 */ 01315 01316 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions 01317 * @brief Peripheral State functions 01318 * 01319 @verbatim 01320 =============================================================================== 01321 ##### Peripheral State functions ##### 01322 =============================================================================== 01323 [..] 01324 This subsection permits to get in run-time the status of the peripheral 01325 and the data flow. 01326 01327 @endverbatim 01328 * @{ 01329 */ 01330 01331 /** 01332 * @brief Return the PCD handle state. 01333 * @param hpcd: PCD handle 01334 * @retval HAL state 01335 */ 01336 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) 01337 { 01338 return hpcd->State; 01339 } 01340 /** 01341 * @} 01342 */ 01343 01344 /** 01345 * @} 01346 */ 01347 01348 /* Private functions ---------------------------------------------------------*/ 01349 /** @addtogroup PCD_Private_Functions 01350 * @{ 01351 */ 01352 #if defined (USB_OTG_FS) 01353 /** 01354 * @brief Check FIFO for the next packet to be loaded. 01355 * @param hpcd: PCD handle 01356 * @param epnum: endpoint number 01357 * @retval HAL status 01358 */ 01359 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) 01360 { 01361 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 01362 USB_OTG_EPTypeDef *ep = NULL; 01363 int32_t len = 0; 01364 uint32_t len32b = 0; 01365 uint32_t fifoemptymsk = 0; 01366 01367 ep = &hpcd->IN_ep[epnum]; 01368 len = ep->xfer_len - ep->xfer_count; 01369 01370 if (len > ep->maxpacket) 01371 { 01372 len = ep->maxpacket; 01373 } 01374 01375 01376 len32b = (len + 3) / 4; 01377 01378 while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b && 01379 ep->xfer_count < ep->xfer_len && 01380 ep->xfer_len != 0) 01381 { 01382 /* Write the FIFO */ 01383 len = ep->xfer_len - ep->xfer_count; 01384 01385 if (len > ep->maxpacket) 01386 { 01387 len = ep->maxpacket; 01388 } 01389 len32b = (len + 3) / 4; 01390 01391 USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); 01392 01393 ep->xfer_buff += len; 01394 ep->xfer_count += len; 01395 } 01396 01397 if(len <= 0) 01398 { 01399 fifoemptymsk = 0x1 << epnum; 01400 atomic_clr_u32(&USBx_DEVICE->DIEPEMPMSK, fifoemptymsk); 01401 01402 } 01403 01404 return HAL_OK; 01405 } 01406 #endif /* USB_OTG_FS */ 01407 01408 #if defined (USB) 01409 /** 01410 * @brief This function handles PCD Endpoint interrupt request. 01411 * @param hpcd: PCD handle 01412 * @retval HAL status 01413 */ 01414 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd) 01415 { 01416 PCD_EPTypeDef *ep = NULL; 01417 uint16_t count = 0; 01418 uint8_t epindex = 0; 01419 __IO uint16_t wIstr = 0; 01420 __IO uint16_t wEPVal = 0; 01421 01422 /* stay in loop while pending interrupts */ 01423 while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0) 01424 { 01425 /* extract highest priority endpoint number */ 01426 epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID); 01427 01428 if (epindex == 0) 01429 { 01430 /* Decode and service control endpoint interrupt */ 01431 01432 /* DIR bit = origin of the interrupt */ 01433 if ((wIstr & USB_ISTR_DIR) == 0) 01434 { 01435 /* DIR = 0 */ 01436 01437 /* DIR = 0 => IN int */ 01438 /* DIR = 0 implies that (EP_CTR_TX = 1) always */ 01439 PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0); 01440 ep = &hpcd->IN_ep[0]; 01441 01442 ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); 01443 ep->xfer_buff += ep->xfer_count; 01444 01445 /* TX COMPLETE */ 01446 HAL_PCD_DataInStageCallback(hpcd, 0); 01447 01448 01449 if((hpcd->USB_Address > 0)&& ( ep->xfer_len == 0)) 01450 { 01451 hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF); 01452 hpcd->USB_Address = 0; 01453 } 01454 01455 } 01456 else 01457 { 01458 /* DIR = 1 */ 01459 01460 /* DIR = 1 & CTR_RX => SETUP or OUT int */ 01461 /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ 01462 ep = &hpcd->OUT_ep[0]; 01463 wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0); 01464 01465 if ((wEPVal & USB_EP_SETUP) != 0) 01466 { 01467 /* Get SETUP Packet*/ 01468 ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); 01469 USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count); 01470 /* SETUP bit kept frozen while CTR_RX = 1*/ 01471 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); 01472 01473 /* Process SETUP Packet*/ 01474 HAL_PCD_SetupStageCallback(hpcd); 01475 } 01476 01477 else if ((wEPVal & USB_EP_CTR_RX) != 0) 01478 { 01479 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); 01480 /* Get Control Data OUT Packet*/ 01481 ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); 01482 01483 if (ep->xfer_count != 0) 01484 { 01485 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count); 01486 ep->xfer_buff+=ep->xfer_count; 01487 } 01488 01489 /* Process Control Data OUT Packet*/ 01490 HAL_PCD_DataOutStageCallback(hpcd, 0); 01491 01492 PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket); 01493 PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID); 01494 } 01495 } 01496 } 01497 else 01498 { 01499 /* Decode and service non control endpoints interrupt */ 01500 01501 /* process related endpoint register */ 01502 wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex); 01503 if ((wEPVal & USB_EP_CTR_RX) != 0) 01504 { 01505 /* clear int flag */ 01506 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex); 01507 ep = &hpcd->OUT_ep[epindex]; 01508 01509 /* OUT double Buffering*/ 01510 if (ep->doublebuffer == 0) 01511 { 01512 count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); 01513 if (count != 0) 01514 { 01515 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count); 01516 } 01517 } 01518 else 01519 { 01520 if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) 01521 { 01522 /*read from endpoint BUF0Addr buffer*/ 01523 count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); 01524 if (count != 0) 01525 { 01526 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); 01527 } 01528 } 01529 else 01530 { 01531 /*read from endpoint BUF1Addr buffer*/ 01532 count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); 01533 if (count != 0) 01534 { 01535 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); 01536 } 01537 } 01538 PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT); 01539 } 01540 /*multi-packet on the NON control OUT endpoint*/ 01541 ep->xfer_count+=count; 01542 ep->xfer_buff+=count; 01543 01544 if ((ep->xfer_len == 0) || (count < ep->maxpacket)) 01545 { 01546 /* RX COMPLETE */ 01547 HAL_PCD_DataOutStageCallback(hpcd, ep->num); 01548 } 01549 else 01550 { 01551 HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); 01552 } 01553 01554 } /* if((wEPVal & EP_CTR_RX) */ 01555 01556 if ((wEPVal & USB_EP_CTR_TX) != 0) 01557 { 01558 ep = &hpcd->IN_ep[epindex]; 01559 01560 /* clear int flag */ 01561 PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex); 01562 01563 /* IN double Buffering*/ 01564 if (ep->doublebuffer == 0) 01565 { 01566 ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); 01567 if (ep->xfer_count != 0) 01568 { 01569 USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count); 01570 } 01571 } 01572 else 01573 { 01574 if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX) 01575 { 01576 /*read from endpoint BUF0Addr buffer*/ 01577 ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); 01578 if (ep->xfer_count != 0) 01579 { 01580 USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count); 01581 } 01582 } 01583 else 01584 { 01585 /*read from endpoint BUF1Addr buffer*/ 01586 ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); 01587 if (ep->xfer_count != 0) 01588 { 01589 USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count); 01590 } 01591 } 01592 PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN); 01593 } 01594 /*multi-packet on the NON control IN endpoint*/ 01595 ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); 01596 ep->xfer_buff+=ep->xfer_count; 01597 01598 /* Zero Length Packet? */ 01599 if (ep->xfer_len == 0) 01600 { 01601 /* TX COMPLETE */ 01602 HAL_PCD_DataInStageCallback(hpcd, ep->num); 01603 } 01604 else 01605 { 01606 HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); 01607 } 01608 } 01609 } 01610 } 01611 return HAL_OK; 01612 } 01613 #endif /* USB */ 01614 01615 /** 01616 * @} 01617 */ 01618 01619 /** 01620 * @} 01621 */ 01622 01623 #endif /* STM32L475xx || STM32L476xx || */ 01624 /* STM32L485xx || STM32L486xx || */ 01625 /* STM32L432xx || STM32L433xx || */ 01626 /* STM32L442xx || STM32L443xx */ 01627 01628 #endif /* HAL_PCD_MODULE_ENABLED */ 01629 01630 01631 /** 01632 * @} 01633 */ 01634 01635 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 17:38:49 by
