STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_pcd_ex.c 00004 * @author MCD Application Team 00005 * @brief PCD Extended HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the USB Peripheral Controller: 00008 * + Extended features functions 00009 * 00010 ****************************************************************************** 00011 * @attention 00012 * 00013 * Copyright (c) 2017 STMicroelectronics. 00014 * All rights reserved. 00015 * 00016 * This software is licensed under terms that can be found in the LICENSE file 00017 * in the root directory of this software component. 00018 * If no LICENSE file comes with this software, it is provided AS-IS. 00019 * 00020 ****************************************************************************** 00021 */ 00022 00023 /* Includes ------------------------------------------------------------------*/ 00024 #include "stm32l4xx_hal.h" 00025 00026 /** @addtogroup STM32L4xx_HAL_Driver 00027 * @{ 00028 */ 00029 00030 /** @defgroup PCDEx PCDEx 00031 * @brief PCD Extended HAL module driver 00032 * @{ 00033 */ 00034 00035 #ifdef HAL_PCD_MODULE_ENABLED 00036 00037 #if defined (USB) || defined (USB_OTG_FS) 00038 /* Private types -------------------------------------------------------------*/ 00039 /* Private variables ---------------------------------------------------------*/ 00040 /* Private constants ---------------------------------------------------------*/ 00041 /* Private macros ------------------------------------------------------------*/ 00042 /* Private functions ---------------------------------------------------------*/ 00043 /* Exported functions --------------------------------------------------------*/ 00044 00045 /** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions 00046 * @{ 00047 */ 00048 00049 /** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions 00050 * @brief PCDEx control functions 00051 * 00052 @verbatim 00053 =============================================================================== 00054 ##### Extended features functions ##### 00055 =============================================================================== 00056 [..] This section provides functions allowing to: 00057 (+) Update FIFO configuration 00058 00059 @endverbatim 00060 * @{ 00061 */ 00062 #if defined (USB_OTG_FS) 00063 /** 00064 * @brief Set Tx FIFO 00065 * @param hpcd PCD handle 00066 * @param fifo The number of Tx fifo 00067 * @param size Fifo size 00068 * @retval HAL status 00069 */ 00070 HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size) 00071 { 00072 uint8_t i; 00073 uint32_t Tx_Offset; 00074 00075 /* TXn min size = 16 words. (n : Transmit FIFO index) 00076 When a TxFIFO is not used, the Configuration should be as follows: 00077 case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) 00078 --> Txm can use the space allocated for Txn. 00079 case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) 00080 --> Txn should be configured with the minimum space of 16 words 00081 The FIFO is used optimally when used TxFIFOs are allocated in the top 00082 of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. 00083 When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */ 00084 00085 Tx_Offset = hpcd->Instance->GRXFSIZ; 00086 00087 if (fifo == 0U) 00088 { 00089 hpcd->Instance->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset; 00090 } 00091 else 00092 { 00093 Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16; 00094 for (i = 0U; i < (fifo - 1U); i++) 00095 { 00096 Tx_Offset += (hpcd->Instance->DIEPTXF[i] >> 16); 00097 } 00098 00099 /* Multiply Tx_Size by 2 to get higher performance */ 00100 hpcd->Instance->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset; 00101 } 00102 00103 return HAL_OK; 00104 } 00105 00106 /** 00107 * @brief Set Rx FIFO 00108 * @param hpcd PCD handle 00109 * @param size Size of Rx fifo 00110 * @retval HAL status 00111 */ 00112 HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size) 00113 { 00114 hpcd->Instance->GRXFSIZ = size; 00115 00116 return HAL_OK; 00117 } 00118 00119 /** 00120 * @brief Activate LPM feature. 00121 * @param hpcd PCD handle 00122 * @retval HAL status 00123 */ 00124 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) 00125 { 00126 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 00127 00128 hpcd->lpm_active = 1U; 00129 hpcd->LPM_State = LPM_L0; 00130 USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM; 00131 USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL); 00132 00133 return HAL_OK; 00134 } 00135 00136 /** 00137 * @brief Deactivate LPM feature. 00138 * @param hpcd PCD handle 00139 * @retval HAL status 00140 */ 00141 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) 00142 { 00143 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 00144 00145 hpcd->lpm_active = 0U; 00146 USBx->GINTMSK &= ~USB_OTG_GINTMSK_LPMINTM; 00147 USBx->GLPMCFG &= ~(USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL); 00148 00149 return HAL_OK; 00150 } 00151 00152 00153 /** 00154 * @brief Handle BatteryCharging Process. 00155 * @param hpcd PCD handle 00156 * @retval HAL status 00157 */ 00158 void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd) 00159 { 00160 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 00161 uint32_t tickstart = HAL_GetTick(); 00162 00163 /* Enable DCD : Data Contact Detect */ 00164 USBx->GCCFG |= USB_OTG_GCCFG_DCDEN; 00165 00166 /* Wait Detect flag or a timeout is happen */ 00167 while ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == 0U) 00168 { 00169 /* Check for the Timeout */ 00170 if ((HAL_GetTick() - tickstart) > 1000U) 00171 { 00172 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00173 hpcd->BCDCallback(hpcd, PCD_BCD_ERROR); 00174 #else 00175 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR); 00176 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00177 00178 return; 00179 } 00180 } 00181 00182 /* Right response got */ 00183 HAL_Delay(200U); 00184 00185 /* Check Detect flag*/ 00186 if ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == USB_OTG_GCCFG_DCDET) 00187 { 00188 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00189 hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION); 00190 #else 00191 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION); 00192 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00193 } 00194 00195 /*Primary detection: checks if connected to Standard Downstream Port 00196 (without charging capability) */ 00197 USBx->GCCFG &= ~ USB_OTG_GCCFG_DCDEN; 00198 HAL_Delay(50U); 00199 USBx->GCCFG |= USB_OTG_GCCFG_PDEN; 00200 HAL_Delay(50U); 00201 00202 if ((USBx->GCCFG & USB_OTG_GCCFG_PDET) == 0U) 00203 { 00204 /* Case of Standard Downstream Port */ 00205 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00206 hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); 00207 #else 00208 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); 00209 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00210 } 00211 else 00212 { 00213 /* start secondary detection to check connection to Charging Downstream 00214 Port or Dedicated Charging Port */ 00215 USBx->GCCFG &= ~ USB_OTG_GCCFG_PDEN; 00216 HAL_Delay(50U); 00217 USBx->GCCFG |= USB_OTG_GCCFG_SDEN; 00218 HAL_Delay(50U); 00219 00220 if ((USBx->GCCFG & USB_OTG_GCCFG_SDET) == USB_OTG_GCCFG_SDET) 00221 { 00222 /* case Dedicated Charging Port */ 00223 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00224 hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); 00225 #else 00226 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); 00227 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00228 } 00229 else 00230 { 00231 /* case Charging Downstream Port */ 00232 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00233 hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); 00234 #else 00235 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); 00236 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00237 } 00238 } 00239 00240 /* Battery Charging capability discovery finished */ 00241 (void)HAL_PCDEx_DeActivateBCD(hpcd); 00242 00243 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00244 hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); 00245 #else 00246 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); 00247 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00248 } 00249 00250 /** 00251 * @brief Activate BatteryCharging feature. 00252 * @param hpcd PCD handle 00253 * @retval HAL status 00254 */ 00255 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd) 00256 { 00257 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 00258 00259 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN); 00260 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN); 00261 00262 /* Power Down USB transceiver */ 00263 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); 00264 00265 /* Enable Battery charging */ 00266 USBx->GCCFG |= USB_OTG_GCCFG_BCDEN; 00267 00268 hpcd->battery_charging_active = 1U; 00269 00270 return HAL_OK; 00271 } 00272 00273 /** 00274 * @brief Deactivate BatteryCharging feature. 00275 * @param hpcd PCD handle 00276 * @retval HAL status 00277 */ 00278 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd) 00279 { 00280 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; 00281 00282 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN); 00283 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN); 00284 00285 /* Disable Battery charging */ 00286 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN); 00287 00288 hpcd->battery_charging_active = 0U; 00289 00290 return HAL_OK; 00291 } 00292 00293 #endif /* defined (USB_OTG_FS) */ 00294 #if defined (USB) 00295 /** 00296 * @brief Configure PMA for EP 00297 * @param hpcd Device instance 00298 * @param ep_addr endpoint address 00299 * @param ep_kind endpoint Kind 00300 * USB_SNG_BUF: Single Buffer used 00301 * USB_DBL_BUF: Double Buffer used 00302 * @param pmaadress: EP address in The PMA: In case of single buffer endpoint 00303 * this parameter is 16-bit value providing the address 00304 * in PMA allocated to endpoint. 00305 * In case of double buffer endpoint this parameter 00306 * is a 32-bit value providing the endpoint buffer 0 address 00307 * in the LSB part of 32-bit value and endpoint buffer 1 address 00308 * in the MSB part of 32-bit value. 00309 * @retval HAL status 00310 */ 00311 00312 HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, 00313 uint16_t ep_kind, uint32_t pmaadress) 00314 { 00315 PCD_EPTypeDef *ep; 00316 00317 /* initialize ep structure*/ 00318 if ((0x80U & ep_addr) == 0x80U) 00319 { 00320 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; 00321 } 00322 else 00323 { 00324 ep = &hpcd->OUT_ep[ep_addr]; 00325 } 00326 00327 /* Here we check if the endpoint is single or double Buffer*/ 00328 if (ep_kind == PCD_SNG_BUF) 00329 { 00330 /* Single Buffer */ 00331 ep->doublebuffer = 0U; 00332 /* Configure the PMA */ 00333 ep->pmaadress = (uint16_t)pmaadress; 00334 } 00335 #if (USE_USB_DOUBLE_BUFFER == 1U) 00336 else /* USB_DBL_BUF */ 00337 { 00338 /* Double Buffer Endpoint */ 00339 ep->doublebuffer = 1U; 00340 /* Configure the PMA */ 00341 ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU); 00342 ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16); 00343 } 00344 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ 00345 00346 return HAL_OK; 00347 } 00348 00349 /** 00350 * @brief Activate BatteryCharging feature. 00351 * @param hpcd PCD handle 00352 * @retval HAL status 00353 */ 00354 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd) 00355 { 00356 USB_TypeDef *USBx = hpcd->Instance; 00357 hpcd->battery_charging_active = 1U; 00358 00359 /* Enable BCD feature */ 00360 USBx->BCDR |= USB_BCDR_BCDEN; 00361 00362 /* Enable DCD : Data Contact Detect */ 00363 USBx->BCDR &= ~(USB_BCDR_PDEN); 00364 USBx->BCDR &= ~(USB_BCDR_SDEN); 00365 USBx->BCDR |= USB_BCDR_DCDEN; 00366 00367 return HAL_OK; 00368 } 00369 00370 /** 00371 * @brief Deactivate BatteryCharging feature. 00372 * @param hpcd PCD handle 00373 * @retval HAL status 00374 */ 00375 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd) 00376 { 00377 USB_TypeDef *USBx = hpcd->Instance; 00378 hpcd->battery_charging_active = 0U; 00379 00380 /* Disable BCD feature */ 00381 USBx->BCDR &= ~(USB_BCDR_BCDEN); 00382 00383 return HAL_OK; 00384 } 00385 00386 /** 00387 * @brief Handle BatteryCharging Process. 00388 * @param hpcd PCD handle 00389 * @retval HAL status 00390 */ 00391 void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd) 00392 { 00393 USB_TypeDef *USBx = hpcd->Instance; 00394 uint32_t tickstart = HAL_GetTick(); 00395 00396 /* Wait Detect flag or a timeout is happen */ 00397 while ((USBx->BCDR & USB_BCDR_DCDET) == 0U) 00398 { 00399 /* Check for the Timeout */ 00400 if ((HAL_GetTick() - tickstart) > 1000U) 00401 { 00402 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00403 hpcd->BCDCallback(hpcd, PCD_BCD_ERROR); 00404 #else 00405 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR); 00406 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00407 00408 return; 00409 } 00410 } 00411 00412 HAL_Delay(200U); 00413 00414 /* Data Pin Contact ? Check Detect flag */ 00415 if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET) 00416 { 00417 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00418 hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION); 00419 #else 00420 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION); 00421 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00422 } 00423 /* Primary detection: checks if connected to Standard Downstream Port 00424 (without charging capability) */ 00425 USBx->BCDR &= ~(USB_BCDR_DCDEN); 00426 HAL_Delay(50U); 00427 USBx->BCDR |= (USB_BCDR_PDEN); 00428 HAL_Delay(50U); 00429 00430 /* If Charger detect ? */ 00431 if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET) 00432 { 00433 /* Start secondary detection to check connection to Charging Downstream 00434 Port or Dedicated Charging Port */ 00435 USBx->BCDR &= ~(USB_BCDR_PDEN); 00436 HAL_Delay(50U); 00437 USBx->BCDR |= (USB_BCDR_SDEN); 00438 HAL_Delay(50U); 00439 00440 /* If CDP ? */ 00441 if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET) 00442 { 00443 /* Dedicated Downstream Port DCP */ 00444 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00445 hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); 00446 #else 00447 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); 00448 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00449 } 00450 else 00451 { 00452 /* Charging Downstream Port CDP */ 00453 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00454 hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); 00455 #else 00456 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); 00457 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00458 } 00459 } 00460 else /* NO */ 00461 { 00462 /* Standard Downstream Port */ 00463 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00464 hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); 00465 #else 00466 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); 00467 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00468 } 00469 00470 /* Battery Charging capability discovery finished Start Enumeration */ 00471 (void)HAL_PCDEx_DeActivateBCD(hpcd); 00472 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 00473 hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); 00474 #else 00475 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); 00476 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 00477 } 00478 00479 00480 /** 00481 * @brief Activate LPM feature. 00482 * @param hpcd PCD handle 00483 * @retval HAL status 00484 */ 00485 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) 00486 { 00487 00488 USB_TypeDef *USBx = hpcd->Instance; 00489 hpcd->lpm_active = 1U; 00490 hpcd->LPM_State = LPM_L0; 00491 00492 USBx->LPMCSR |= USB_LPMCSR_LMPEN; 00493 USBx->LPMCSR |= USB_LPMCSR_LPMACK; 00494 00495 return HAL_OK; 00496 } 00497 00498 /** 00499 * @brief Deactivate LPM feature. 00500 * @param hpcd PCD handle 00501 * @retval HAL status 00502 */ 00503 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) 00504 { 00505 USB_TypeDef *USBx = hpcd->Instance; 00506 00507 hpcd->lpm_active = 0U; 00508 00509 USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN); 00510 USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK); 00511 00512 return HAL_OK; 00513 } 00514 00515 #endif /* defined (USB) */ 00516 00517 /** 00518 * @brief Send LPM message to user layer callback. 00519 * @param hpcd PCD handle 00520 * @param msg LPM message 00521 * @retval HAL status 00522 */ 00523 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) 00524 { 00525 /* Prevent unused argument(s) compilation warning */ 00526 UNUSED(hpcd); 00527 UNUSED(msg); 00528 00529 /* NOTE : This function should not be modified, when the callback is needed, 00530 the HAL_PCDEx_LPM_Callback could be implemented in the user file 00531 */ 00532 } 00533 00534 /** 00535 * @brief Send BatteryCharging message to user layer callback. 00536 * @param hpcd PCD handle 00537 * @param msg LPM message 00538 * @retval HAL status 00539 */ 00540 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg) 00541 { 00542 /* Prevent unused argument(s) compilation warning */ 00543 UNUSED(hpcd); 00544 UNUSED(msg); 00545 00546 /* NOTE : This function should not be modified, when the callback is needed, 00547 the HAL_PCDEx_BCD_Callback could be implemented in the user file 00548 */ 00549 } 00550 00551 /** 00552 * @} 00553 */ 00554 00555 /** 00556 * @} 00557 */ 00558 #endif /* defined (USB) || defined (USB_OTG_FS) */ 00559 #endif /* HAL_PCD_MODULE_ENABLED */ 00560 00561 /** 00562 * @} 00563 */ 00564 00565 /** 00566 * @} 00567 */