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