STM32F479xx HAL User Manual
stm32f4xx_hal_pcd_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_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) 2016 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 "stm32f4xx_hal.h"
00025 
00026 /** @addtogroup STM32F4xx_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_OTG_FS) || defined (USB_OTG_HS)
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) || defined (USB_OTG_HS)
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 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
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 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
00152 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
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 #endif /* defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
00293 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
00294 
00295 /**
00296   * @brief  Send LPM message to user layer callback.
00297   * @param  hpcd PCD handle
00298   * @param  msg LPM message
00299   * @retval HAL status
00300   */
00301 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
00302 {
00303   /* Prevent unused argument(s) compilation warning */
00304   UNUSED(hpcd);
00305   UNUSED(msg);
00306 
00307   /* NOTE : This function should not be modified, when the callback is needed,
00308             the HAL_PCDEx_LPM_Callback could be implemented in the user file
00309    */
00310 }
00311 
00312 /**
00313   * @brief  Send BatteryCharging message to user layer callback.
00314   * @param  hpcd PCD handle
00315   * @param  msg LPM message
00316   * @retval HAL status
00317   */
00318 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
00319 {
00320   /* Prevent unused argument(s) compilation warning */
00321   UNUSED(hpcd);
00322   UNUSED(msg);
00323 
00324   /* NOTE : This function should not be modified, when the callback is needed,
00325             the HAL_PCDEx_BCD_Callback could be implemented in the user file
00326    */
00327 }
00328 
00329 /**
00330   * @}
00331   */
00332 
00333 /**
00334   * @}
00335   */
00336 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
00337 #endif /* HAL_PCD_MODULE_ENABLED */
00338 
00339 /**
00340   * @}
00341   */
00342 
00343 /**
00344   * @}
00345   */