1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_pcd_ex.c
4   * @author  MCD Application Team
5   * @brief   PCD Extended HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the USB Peripheral Controller:
8   *           + Extended features functions
9   *
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2016 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   */
22 
23 /* Includes ------------------------------------------------------------------*/
24 #include "stm32f4xx_hal.h"
25 
26 /** @addtogroup STM32F4xx_HAL_Driver
27   * @{
28   */
29 
30 /** @defgroup PCDEx PCDEx
31   * @brief PCD Extended HAL module driver
32   * @{
33   */
34 
35 #ifdef HAL_PCD_MODULE_ENABLED
36 
37 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
38 /* Private types -------------------------------------------------------------*/
39 /* Private variables ---------------------------------------------------------*/
40 /* Private constants ---------------------------------------------------------*/
41 /* Private macros ------------------------------------------------------------*/
42 /* Private functions ---------------------------------------------------------*/
43 /* Exported functions --------------------------------------------------------*/
44 
45 /** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
46   * @{
47   */
48 
49 /** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
50   * @brief    PCDEx control functions
51   *
52 @verbatim
53  ===============================================================================
54                  ##### Extended features functions #####
55  ===============================================================================
56     [..]  This section provides functions allowing to:
57       (+) Update FIFO configuration
58 
59 @endverbatim
60   * @{
61   */
62 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
63 /**
64   * @brief  Set Tx FIFO
65   * @param  hpcd PCD handle
66   * @param  fifo The number of Tx fifo
67   * @param  size Fifo size
68   * @retval HAL status
69   */
HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef * hpcd,uint8_t fifo,uint16_t size)70 HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
71 {
72   uint8_t i;
73   uint32_t Tx_Offset;
74 
75   /*  TXn min size = 16 words. (n  : Transmit FIFO index)
76       When a TxFIFO is not used, the Configuration should be as follows:
77           case 1 :  n > m    and Txn is not used    (n,m  : Transmit FIFO indexes)
78          --> Txm can use the space allocated for Txn.
79          case2  :  n < m    and Txn is not used    (n,m  : Transmit FIFO indexes)
80          --> Txn should be configured with the minimum space of 16 words
81      The FIFO is used optimally when used TxFIFOs are allocated in the top
82          of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
83      When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
84 
85   Tx_Offset = hpcd->Instance->GRXFSIZ;
86 
87   if (fifo == 0U)
88   {
89     hpcd->Instance->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset;
90   }
91   else
92   {
93     Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16;
94     for (i = 0U; i < (fifo - 1U); i++)
95     {
96       Tx_Offset += (hpcd->Instance->DIEPTXF[i] >> 16);
97     }
98 
99     /* Multiply Tx_Size by 2 to get higher performance */
100     hpcd->Instance->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
101   }
102 
103   return HAL_OK;
104 }
105 
106 /**
107   * @brief  Set Rx FIFO
108   * @param  hpcd PCD handle
109   * @param  size Size of Rx fifo
110   * @retval HAL status
111   */
HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef * hpcd,uint16_t size)112 HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
113 {
114   hpcd->Instance->GRXFSIZ = size;
115 
116   return HAL_OK;
117 }
118 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
119  || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
120  || defined(STM32F423xx)
121 /**
122   * @brief  Activate LPM feature.
123   * @param  hpcd PCD handle
124   * @retval HAL status
125   */
HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef * hpcd)126 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
127 {
128   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
129 
130   hpcd->lpm_active = 1U;
131   hpcd->LPM_State = LPM_L0;
132   USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM;
133   USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
134 
135   return HAL_OK;
136 }
137 
138 /**
139   * @brief  Deactivate LPM feature.
140   * @param  hpcd PCD handle
141   * @retval HAL status
142   */
HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef * hpcd)143 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
144 {
145   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
146 
147   hpcd->lpm_active = 0U;
148   USBx->GINTMSK &= ~USB_OTG_GINTMSK_LPMINTM;
149   USBx->GLPMCFG &= ~(USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
150 
151   return HAL_OK;
152 }
153 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
154           defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
155           defined(STM32F423xx) */
156 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) \
157  || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
158 /**
159   * @brief  Handle BatteryCharging Process.
160   * @param  hpcd PCD handle
161   * @retval HAL status
162   */
HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef * hpcd)163 void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
164 {
165   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
166   uint32_t tickstart = HAL_GetTick();
167 
168   /* Enable DCD : Data Contact Detect */
169   USBx->GCCFG |= USB_OTG_GCCFG_DCDEN;
170 
171   /* Wait for Min DCD Timeout */
172   HAL_Delay(300U);
173 
174   /* Check Detect flag */
175   if ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == USB_OTG_GCCFG_DCDET)
176   {
177 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
178     hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
179 #else
180     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
181 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
182   }
183 
184   /* Primary detection: checks if connected to Standard Downstream Port
185   (without charging capability) */
186   USBx->GCCFG &= ~USB_OTG_GCCFG_DCDEN;
187   HAL_Delay(50U);
188   USBx->GCCFG |= USB_OTG_GCCFG_PDEN;
189   HAL_Delay(50U);
190 
191   if ((USBx->GCCFG & USB_OTG_GCCFG_PDET) == 0U)
192   {
193     /* Case of Standard Downstream Port */
194 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
195     hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
196 #else
197     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
198 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
199   }
200   else
201   {
202     /* start secondary detection to check connection to Charging Downstream
203     Port or Dedicated Charging Port */
204     USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
205     HAL_Delay(50U);
206     USBx->GCCFG |= USB_OTG_GCCFG_SDEN;
207     HAL_Delay(50U);
208 
209     if ((USBx->GCCFG & USB_OTG_GCCFG_SDET) == USB_OTG_GCCFG_SDET)
210     {
211       /* case Dedicated Charging Port  */
212 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
213       hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
214 #else
215       HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
216 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
217     }
218     else
219     {
220       /* case Charging Downstream Port */
221 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
222       hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
223 #else
224       HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
225 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
226     }
227   }
228 
229   /* Battery Charging capability discovery finished */
230   (void)HAL_PCDEx_DeActivateBCD(hpcd);
231 
232   /* Check for the Timeout, else start USB Device */
233   if ((HAL_GetTick() - tickstart) > 1000U)
234   {
235 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
236     hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
237 #else
238     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
239 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
240   }
241   else
242   {
243 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
244     hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
245 #else
246     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
247 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
248   }
249 }
250 
251 /**
252   * @brief  Activate BatteryCharging feature.
253   * @param  hpcd PCD handle
254   * @retval HAL status
255   */
HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef * hpcd)256 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
257 {
258   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
259 
260   USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
261   USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
262 
263   /* Power Down USB transceiver  */
264   USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
265 
266   /* Enable Battery charging */
267   USBx->GCCFG |= USB_OTG_GCCFG_BCDEN;
268 
269   hpcd->battery_charging_active = 1U;
270 
271   return HAL_OK;
272 }
273 
274 /**
275   * @brief  Deactivate BatteryCharging feature.
276   * @param  hpcd PCD handle
277   * @retval HAL status
278   */
HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef * hpcd)279 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
280 {
281   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
282 
283   USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
284   USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
285 
286   /* Disable Battery charging */
287   USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
288 
289   hpcd->battery_charging_active = 0U;
290 
291   return HAL_OK;
292 }
293 #endif /* defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||
294           defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
295 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
296 
297 /**
298   * @brief  Send LPM message to user layer callback.
299   * @param  hpcd PCD handle
300   * @param  msg LPM message
301   * @retval HAL status
302   */
HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef * hpcd,PCD_LPM_MsgTypeDef msg)303 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
304 {
305   /* Prevent unused argument(s) compilation warning */
306   UNUSED(hpcd);
307   UNUSED(msg);
308 
309   /* NOTE : This function should not be modified, when the callback is needed,
310             the HAL_PCDEx_LPM_Callback could be implemented in the user file
311    */
312 }
313 
314 /**
315   * @brief  Send BatteryCharging message to user layer callback.
316   * @param  hpcd PCD handle
317   * @param  msg LPM message
318   * @retval HAL status
319   */
HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef * hpcd,PCD_BCD_MsgTypeDef msg)320 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
321 {
322   /* Prevent unused argument(s) compilation warning */
323   UNUSED(hpcd);
324   UNUSED(msg);
325 
326   /* NOTE : This function should not be modified, when the callback is needed,
327             the HAL_PCDEx_BCD_Callback could be implemented in the user file
328    */
329 }
330 
331 /**
332   * @}
333   */
334 
335 /**
336   * @}
337   */
338 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
339 #endif /* HAL_PCD_MODULE_ENABLED */
340 
341 /**
342   * @}
343   */
344 
345 /**
346   * @}
347   */
348