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