1 /**
2 ******************************************************************************
3 * @file stm32h5xx_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 "stm32h5xx_hal.h"
25
26 /** @addtogroup STM32H5xx_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_DRD_FS)
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
63 /**
64 * @brief Configure PMA for EP
65 * @param hpcd Device instance
66 * @param ep_addr endpoint address
67 * @param ep_kind endpoint Kind
68 * USB_SNG_BUF: Single Buffer used
69 * USB_DBL_BUF: Double Buffer used
70 * @param pmaadress: EP address in The PMA: In case of single buffer endpoint
71 * this parameter is 16-bit value providing the address
72 * in PMA allocated to endpoint.
73 * In case of double buffer endpoint this parameter
74 * is a 32-bit value providing the endpoint buffer 0 address
75 * in the LSB part of 32-bit value and endpoint buffer 1 address
76 * in the MSB part of 32-bit value.
77 * @retval HAL status
78 */
79
HAL_PCDEx_PMAConfig(PCD_HandleTypeDef * hpcd,uint16_t ep_addr,uint16_t ep_kind,uint32_t pmaadress)80 HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr,
81 uint16_t ep_kind, uint32_t pmaadress)
82 {
83 PCD_EPTypeDef *ep;
84
85 /* initialize ep structure*/
86 if ((0x80U & ep_addr) == 0x80U)
87 {
88 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
89 }
90 else
91 {
92 ep = &hpcd->OUT_ep[ep_addr];
93 }
94
95 /* Here we check if the endpoint is single or double Buffer*/
96 if (ep_kind == PCD_SNG_BUF)
97 {
98 /* Single Buffer */
99 ep->doublebuffer = 0U;
100 /* Configure the PMA */
101 ep->pmaadress = (uint16_t)pmaadress;
102 }
103 #if (USE_USB_DOUBLE_BUFFER == 1U)
104 else /* USB_DBL_BUF */
105 {
106 /* Double Buffer Endpoint */
107 ep->doublebuffer = 1U;
108 /* Configure the PMA */
109 ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU);
110 ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16);
111 }
112 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
113
114 return HAL_OK;
115 }
116
117 /**
118 * @brief Activate BatteryCharging feature.
119 * @param hpcd PCD handle
120 * @retval HAL status
121 */
HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef * hpcd)122 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
123 {
124 USB_DRD_TypeDef *USBx = hpcd->Instance;
125 hpcd->battery_charging_active = 1U;
126
127 /* Enable BCD feature */
128 USBx->BCDR |= USB_BCDR_BCDEN;
129
130 /* Enable DCD : Data Contact Detect */
131 USBx->BCDR &= ~(USB_BCDR_PDEN);
132 USBx->BCDR &= ~(USB_BCDR_SDEN);
133 USBx->BCDR |= USB_BCDR_DCDEN;
134
135 return HAL_OK;
136 }
137
138 /**
139 * @brief Deactivate BatteryCharging feature.
140 * @param hpcd PCD handle
141 * @retval HAL status
142 */
HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef * hpcd)143 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
144 {
145 USB_DRD_TypeDef *USBx = hpcd->Instance;
146 hpcd->battery_charging_active = 0U;
147
148 /* Disable BCD feature */
149 USBx->BCDR &= ~(USB_BCDR_BCDEN);
150
151 return HAL_OK;
152 }
153
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_DRD_TypeDef *USBx = hpcd->Instance;
162 uint32_t tickstart = HAL_GetTick();
163
164 /* Wait for Min DCD Timeout */
165 HAL_Delay(300U);
166
167 /* Data Pin Contact ? Check Detect flag */
168 if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET)
169 {
170 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
171 hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
172 #else
173 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
174 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
175 }
176 /* Primary detection: checks if connected to Standard Downstream Port
177 (without charging capability) */
178 USBx->BCDR &= ~(USB_BCDR_DCDEN);
179 HAL_Delay(50U);
180 USBx->BCDR |= (USB_BCDR_PDEN);
181 HAL_Delay(50U);
182
183 /* If Charger detect ? */
184 if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET)
185 {
186 /* Start secondary detection to check connection to Charging Downstream
187 Port or Dedicated Charging Port */
188 USBx->BCDR &= ~(USB_BCDR_PDEN);
189 HAL_Delay(50U);
190 USBx->BCDR |= (USB_BCDR_SDEN);
191 HAL_Delay(50U);
192
193 /* If CDP ? */
194 if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET)
195 {
196 /* Dedicated Downstream Port DCP */
197 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
198 hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
199 #else
200 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
201 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
202 }
203 else
204 {
205 /* Charging Downstream Port CDP */
206 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
207 hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
208 #else
209 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
210 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
211 }
212 }
213 else /* NO */
214 {
215 /* Standard Downstream Port */
216 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
217 hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
218 #else
219 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
220 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
221 }
222
223 /* Battery Charging capability discovery finished Start Enumeration */
224 (void)HAL_PCDEx_DeActivateBCD(hpcd);
225
226 /* Check for the Timeout, else start USB Device */
227 if ((HAL_GetTick() - tickstart) > 1000U)
228 {
229 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
230 hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
231 #else
232 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
233 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
234 }
235 else
236 {
237 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
238 hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
239 #else
240 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
241 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
242 }
243 }
244
245
246 /**
247 * @brief Activate LPM feature.
248 * @param hpcd PCD handle
249 * @retval HAL status
250 */
HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef * hpcd)251 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
252 {
253
254 USB_DRD_TypeDef *USBx = hpcd->Instance;
255 hpcd->lpm_active = 1U;
256 hpcd->LPM_State = LPM_L0;
257
258 USBx->LPMCSR |= USB_LPMCSR_LMPEN;
259 USBx->LPMCSR |= USB_LPMCSR_LPMACK;
260
261 return HAL_OK;
262 }
263
264 /**
265 * @brief Deactivate LPM feature.
266 * @param hpcd PCD handle
267 * @retval HAL status
268 */
HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef * hpcd)269 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
270 {
271 USB_DRD_TypeDef *USBx = hpcd->Instance;
272
273 hpcd->lpm_active = 0U;
274
275 USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN);
276 USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK);
277
278 return HAL_OK;
279 }
280
281
282
283 /**
284 * @brief Send LPM message to user layer callback.
285 * @param hpcd PCD handle
286 * @param msg LPM message
287 * @retval HAL status
288 */
HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef * hpcd,PCD_LPM_MsgTypeDef msg)289 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
290 {
291 /* Prevent unused argument(s) compilation warning */
292 UNUSED(hpcd);
293 UNUSED(msg);
294
295 /* NOTE : This function should not be modified, when the callback is needed,
296 the HAL_PCDEx_LPM_Callback could be implemented in the user file
297 */
298 }
299
300 /**
301 * @brief Send BatteryCharging message to user layer callback.
302 * @param hpcd PCD handle
303 * @param msg LPM message
304 * @retval HAL status
305 */
HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef * hpcd,PCD_BCD_MsgTypeDef msg)306 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
307 {
308 /* Prevent unused argument(s) compilation warning */
309 UNUSED(hpcd);
310 UNUSED(msg);
311
312 /* NOTE : This function should not be modified, when the callback is needed,
313 the HAL_PCDEx_BCD_Callback could be implemented in the user file
314 */
315 }
316
317 /**
318 * @}
319 */
320
321 /**
322 * @}
323 */
324 #endif /* defined (USB_DRD_FS) */
325 #endif /* HAL_PCD_MODULE_ENABLED */
326
327 /**
328 * @}
329 */
330
331 /**
332 * @}
333 */
334