1 /**
2 ******************************************************************************
3 * @file stm32g4xx_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) 2019 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 "stm32g4xx_hal.h"
25
26 /** @addtogroup STM32G4xx_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)
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_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_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_TypeDef *USBx = hpcd->Instance;
162 uint32_t tickstart = HAL_GetTick();
163
164 /* Wait Detect flag or a timeout is happen */
165 while ((USBx->BCDR & USB_BCDR_DCDET) == 0U)
166 {
167 /* Check for the Timeout */
168 if ((HAL_GetTick() - tickstart) > 1000U)
169 {
170 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
171 hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
172 #else
173 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
174 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
175
176 return;
177 }
178 }
179
180 HAL_Delay(200U);
181
182 /* Data Pin Contact ? Check Detect flag */
183 if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET)
184 {
185 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
186 hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
187 #else
188 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
189 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
190 }
191 /* Primary detection: checks if connected to Standard Downstream Port
192 (without charging capability) */
193 USBx->BCDR &= ~(USB_BCDR_DCDEN);
194 HAL_Delay(50U);
195 USBx->BCDR |= (USB_BCDR_PDEN);
196 HAL_Delay(50U);
197
198 /* If Charger detect ? */
199 if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET)
200 {
201 /* Start secondary detection to check connection to Charging Downstream
202 Port or Dedicated Charging Port */
203 USBx->BCDR &= ~(USB_BCDR_PDEN);
204 HAL_Delay(50U);
205 USBx->BCDR |= (USB_BCDR_SDEN);
206 HAL_Delay(50U);
207
208 /* If CDP ? */
209 if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET)
210 {
211 /* Dedicated Downstream Port DCP */
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 /* Charging Downstream Port CDP */
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 else /* NO */
229 {
230 /* Standard Downstream Port */
231 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
232 hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
233 #else
234 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
235 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
236 }
237
238 /* Battery Charging capability discovery finished Start Enumeration */
239 (void)HAL_PCDEx_DeActivateBCD(hpcd);
240 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
241 hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
242 #else
243 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
244 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
245 }
246
247
248 /**
249 * @brief Activate LPM feature.
250 * @param hpcd PCD handle
251 * @retval HAL status
252 */
HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef * hpcd)253 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
254 {
255
256 USB_TypeDef *USBx = hpcd->Instance;
257 hpcd->lpm_active = 1U;
258 hpcd->LPM_State = LPM_L0;
259
260 USBx->LPMCSR |= USB_LPMCSR_LMPEN;
261 USBx->LPMCSR |= USB_LPMCSR_LPMACK;
262
263 return HAL_OK;
264 }
265
266 /**
267 * @brief Deactivate LPM feature.
268 * @param hpcd PCD handle
269 * @retval HAL status
270 */
HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef * hpcd)271 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
272 {
273 USB_TypeDef *USBx = hpcd->Instance;
274
275 hpcd->lpm_active = 0U;
276
277 USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN);
278 USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK);
279
280 return HAL_OK;
281 }
282
283
284
285 /**
286 * @brief Send LPM message to user layer callback.
287 * @param hpcd PCD handle
288 * @param msg LPM message
289 * @retval HAL status
290 */
HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef * hpcd,PCD_LPM_MsgTypeDef msg)291 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
292 {
293 /* Prevent unused argument(s) compilation warning */
294 UNUSED(hpcd);
295 UNUSED(msg);
296
297 /* NOTE : This function should not be modified, when the callback is needed,
298 the HAL_PCDEx_LPM_Callback could be implemented in the user file
299 */
300 }
301
302 /**
303 * @brief Send BatteryCharging message to user layer callback.
304 * @param hpcd PCD handle
305 * @param msg LPM message
306 * @retval HAL status
307 */
HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef * hpcd,PCD_BCD_MsgTypeDef msg)308 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
309 {
310 /* Prevent unused argument(s) compilation warning */
311 UNUSED(hpcd);
312 UNUSED(msg);
313
314 /* NOTE : This function should not be modified, when the callback is needed,
315 the HAL_PCDEx_BCD_Callback could be implemented in the user file
316 */
317 }
318
319 /**
320 * @}
321 */
322
323 /**
324 * @}
325 */
326 #endif /* defined (USB) */
327 #endif /* HAL_PCD_MODULE_ENABLED */
328
329 /**
330 * @}
331 */
332
333 /**
334 * @}
335 */
336