1 /**
2 ******************************************************************************
3 * @file stm32h7rsxx_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) 2022 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 "stm32h7rsxx_hal.h"
25
26 /** @addtogroup STM32H7RSxx_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
119 /**
120 * @brief Activate LPM feature.
121 * @param hpcd PCD handle
122 * @retval HAL status
123 */
HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef * hpcd)124 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
125 {
126 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
127
128 hpcd->lpm_active = 1U;
129 hpcd->LPM_State = LPM_L0;
130 USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM;
131 USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
132
133 return HAL_OK;
134 }
135
136 /**
137 * @brief Deactivate LPM feature.
138 * @param hpcd PCD handle
139 * @retval HAL status
140 */
HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef * hpcd)141 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
142 {
143 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
144
145 hpcd->lpm_active = 0U;
146 USBx->GINTMSK &= ~USB_OTG_GINTMSK_LPMINTM;
147 USBx->GLPMCFG &= ~(USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
148
149 return HAL_OK;
150 }
151
152
153 /**
154 * @brief Handle BatteryCharging Process.
155 * @param hpcd PCD handle
156 * @retval HAL status
157 */
HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef * hpcd)158 void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
159 {
160 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
161 uint32_t gccfg_msk;
162 uint32_t tickstart = HAL_GetTick();
163
164 /* Enable DCD : Data Contact Detect */
165 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
166 {
167 USBx->GCCFG |= USB_OTG_GCCFG_DCDEN;
168 }
169 else
170 {
171 USBx->GCCFG |= USB_OTG_GCCFG_DCDETEN;
172 }
173
174 /* Wait for Min DCD Timeout */
175 HAL_Delay(300U);
176
177 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
178 {
179 /* Check Detect flag */
180 if ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == USB_OTG_GCCFG_DCDET)
181 {
182 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
183 hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
184 #else
185 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
186 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
187 }
188 }
189
190 /* Primary detection: checks if connected to Standard Downstream Port
191 (without charging capability) */
192 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
193 {
194 USBx->GCCFG &= ~USB_OTG_GCCFG_DCDEN;
195 HAL_Delay(50U);
196 USBx->GCCFG |= USB_OTG_GCCFG_PDEN;
197 }
198 else
199 {
200 USBx->GCCFG &= ~USB_OTG_GCCFG_DCDETEN;
201 HAL_Delay(50U);
202 USBx->GCCFG |= USB_OTG_GCCFG_PDETEN;
203 }
204 HAL_Delay(50U);
205
206 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
207 {
208 gccfg_msk = USB_OTG_GCCFG_PDET;
209 }
210 else
211 {
212 gccfg_msk = USB_OTG_GCCFG_CHGDET;
213 }
214
215 if ((USBx->GCCFG & gccfg_msk) == 0U)
216 {
217 /* Case of Standard Downstream Port */
218 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
219 hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
220 #else
221 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
222 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
223 }
224 else
225 {
226 /* start secondary detection to check connection to Charging Downstream
227 Port or Dedicated Charging Port */
228 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
229 {
230 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
231 HAL_Delay(50U);
232 USBx->GCCFG |= USB_OTG_GCCFG_SDEN;
233 HAL_Delay(50U);
234
235 gccfg_msk = USB_OTG_GCCFG_SDET;
236 }
237 else
238 {
239 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDETEN);
240 HAL_Delay(50U);
241 USBx->GCCFG |= USB_OTG_GCCFG_SDETEN;
242 HAL_Delay(50U);
243
244 gccfg_msk = USB_OTG_GCCFG_FSVPLUS;
245 }
246
247 if ((USBx->GCCFG & gccfg_msk) == gccfg_msk)
248 {
249 /* case Dedicated Charging Port */
250 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
251 hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
252 #else
253 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
254 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
255 }
256 else
257 {
258 /* case Charging Downstream Port */
259 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
260 hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
261 #else
262 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
263 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
264 }
265 }
266
267 /* Battery Charging capability discovery finished */
268 (void)HAL_PCDEx_DeActivateBCD(hpcd);
269
270 /* Check for the Timeout, else start USB Device */
271 if ((HAL_GetTick() - tickstart) > 1000U)
272 {
273 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
274 hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
275 #else
276 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
277 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
278 }
279 else
280 {
281 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
282 hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
283 #else
284 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
285 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
286 }
287 }
288
289 /**
290 * @brief Activate BatteryCharging feature.
291 * @param hpcd PCD handle
292 * @retval HAL status
293 */
HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef * hpcd)294 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
295 {
296 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
297
298 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
299 {
300 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
301 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
302
303 /* Power Down USB transceiver */
304 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
305
306 /* Enable Battery charging */
307 USBx->GCCFG |= USB_OTG_GCCFG_BCDEN;
308 }
309 else
310 {
311 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDETEN);
312 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDETEN);
313 }
314
315 hpcd->battery_charging_active = 1U;
316
317 return HAL_OK;
318 }
319
320 /**
321 * @brief Deactivate BatteryCharging feature.
322 * @param hpcd PCD handle
323 * @retval HAL status
324 */
HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef * hpcd)325 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
326 {
327 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
328
329 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
330 {
331 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
332 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
333
334 /* Disable Battery charging */
335 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
336 }
337 else
338 {
339 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDETEN);
340 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDETEN);
341 }
342
343 hpcd->battery_charging_active = 0U;
344
345 return HAL_OK;
346 }
347
348 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
349
350 /**
351 * @brief Send LPM message to user layer callback.
352 * @param hpcd PCD handle
353 * @param msg LPM message
354 * @retval HAL status
355 */
HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef * hpcd,PCD_LPM_MsgTypeDef msg)356 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
357 {
358 /* Prevent unused argument(s) compilation warning */
359 UNUSED(hpcd);
360 UNUSED(msg);
361
362 /* NOTE : This function should not be modified, when the callback is needed,
363 the HAL_PCDEx_LPM_Callback could be implemented in the user file
364 */
365 }
366
367 /**
368 * @brief Send BatteryCharging message to user layer callback.
369 * @param hpcd PCD handle
370 * @param msg LPM message
371 * @retval HAL status
372 */
HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef * hpcd,PCD_BCD_MsgTypeDef msg)373 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
374 {
375 /* Prevent unused argument(s) compilation warning */
376 UNUSED(hpcd);
377 UNUSED(msg);
378
379 /* NOTE : This function should not be modified, when the callback is needed,
380 the HAL_PCDEx_BCD_Callback could be implemented in the user file
381 */
382 }
383
384 /**
385 * @}
386 */
387
388 /**
389 * @}
390 */
391 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
392 #endif /* HAL_PCD_MODULE_ENABLED */
393
394 /**
395 * @}
396 */
397
398 /**
399 * @}
400 */
401