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) 2023 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_OTG_FS) || defined (USB_OTG_HS) || 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 #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 #if defined (USB_OTG_HS)
170   else
171   {
172     USBx->GCCFG |= USB_OTG_GCCFG_DCDETEN;
173   }
174 #endif /* defined (USB_OTG_HS) */
175 
176   /* Wait for Min DCD Timeout */
177   HAL_Delay(300U);
178 
179   if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
180   {
181     /* Check Detect flag */
182     if ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == USB_OTG_GCCFG_DCDET)
183     {
184 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
185       hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
186 #else
187       HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
188 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
189     }
190   }
191 
192   /* Primary detection: checks if connected to Standard Downstream Port
193   (without charging capability) */
194   if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
195   {
196     USBx->GCCFG &= ~USB_OTG_GCCFG_DCDEN;
197     HAL_Delay(50U);
198     USBx->GCCFG |= USB_OTG_GCCFG_PDEN;
199   }
200 #if defined (USB_OTG_HS)
201   else
202   {
203     USBx->GCCFG &= ~USB_OTG_GCCFG_DCDETEN;
204     HAL_Delay(50U);
205     USBx->GCCFG |= USB_OTG_GCCFG_PDETEN;
206   }
207 #endif /* defined (USB_OTG_HS) */
208   HAL_Delay(50U);
209 
210   if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
211   {
212     gccfg_msk = USB_OTG_GCCFG_PDET;
213   }
214 #if defined (USB_OTG_HS)
215   else
216   {
217     gccfg_msk = USB_OTG_GCCFG_CHGDET;
218   }
219 #endif /* defined (USB_OTG_HS) */
220 
221   if ((USBx->GCCFG & gccfg_msk) == 0U)
222   {
223     /* Case of Standard Downstream Port */
224 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
225     hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
226 #else
227     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
228 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
229   }
230   else
231   {
232     /* start secondary detection to check connection to Charging Downstream
233     Port or Dedicated Charging Port */
234     if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
235     {
236       USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
237       HAL_Delay(50U);
238       USBx->GCCFG |= USB_OTG_GCCFG_SDEN;
239       HAL_Delay(50U);
240 
241       gccfg_msk = USB_OTG_GCCFG_SDET;
242     }
243 #if defined (USB_OTG_HS)
244     else
245     {
246       USBx->GCCFG &= ~(USB_OTG_GCCFG_PDETEN);
247       HAL_Delay(50U);
248       USBx->GCCFG |= USB_OTG_GCCFG_SDETEN;
249       HAL_Delay(50U);
250 
251       gccfg_msk = USB_OTG_GCCFG_FSVPLUS;
252     }
253 #endif /* defined (USB_OTG_HS) */
254 
255     if ((USBx->GCCFG & gccfg_msk) == gccfg_msk)
256     {
257       /* case Dedicated Charging Port  */
258 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
259       hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
260 #else
261       HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
262 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
263     }
264     else
265     {
266       /* case Charging Downstream Port */
267 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
268       hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
269 #else
270       HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
271 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
272     }
273   }
274 
275   /* Battery Charging capability discovery finished */
276   (void)HAL_PCDEx_DeActivateBCD(hpcd);
277 
278   /* Check for the Timeout, else start USB Device */
279   if ((HAL_GetTick() - tickstart) > 1000U)
280   {
281 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
282     hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
283 #else
284     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
285 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
286   }
287   else
288   {
289 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
290     hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
291 #else
292     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
293 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
294   }
295 }
296 
297 /**
298   * @brief  Activate BatteryCharging feature.
299   * @param  hpcd PCD handle
300   * @retval HAL status
301   */
HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef * hpcd)302 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
303 {
304   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
305 
306   if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
307   {
308     USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
309     USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
310 
311     /* Power Down USB transceiver  */
312     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
313 
314     /* Enable Battery charging */
315     USBx->GCCFG |= USB_OTG_GCCFG_BCDEN;
316   }
317 #if defined (USB_OTG_HS)
318   else
319   {
320     USBx->GCCFG &= ~(USB_OTG_GCCFG_PDETEN);
321     USBx->GCCFG &= ~(USB_OTG_GCCFG_SDETEN);
322   }
323 #endif /* defined (USB_OTG_HS) */
324 
325   hpcd->battery_charging_active = 1U;
326 
327   return HAL_OK;
328 }
329 
330 /**
331   * @brief  Deactivate BatteryCharging feature.
332   * @param  hpcd PCD handle
333   * @retval HAL status
334   */
HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef * hpcd)335 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
336 {
337   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
338 
339   if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U)
340   {
341     USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
342     USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
343 
344     /* Disable Battery charging */
345     USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
346   }
347 #if defined (USB_OTG_HS)
348   else
349   {
350     USBx->GCCFG &= ~(USB_OTG_GCCFG_PDETEN);
351     USBx->GCCFG &= ~(USB_OTG_GCCFG_SDETEN);
352   }
353 #endif /* defined (USB_OTG_HS) */
354 
355   hpcd->battery_charging_active = 0U;
356 
357   return HAL_OK;
358 }
359 
360 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
361 #if defined (USB_DRD_FS)
362 /**
363   * @brief  Configure PMA for EP
364   * @param  hpcd  Device instance
365   * @param  ep_addr endpoint address
366   * @param  ep_kind endpoint Kind
367   *                  USB_SNG_BUF: Single Buffer used
368   *                  USB_DBL_BUF: Double Buffer used
369   * @param  pmaadress: EP address in The PMA: In case of single buffer endpoint
370   *                   this parameter is 16-bit value providing the address
371   *                   in PMA allocated to endpoint.
372   *                   In case of double buffer endpoint this parameter
373   *                   is a 32-bit value providing the endpoint buffer 0 address
374   *                   in the LSB part of 32-bit value and endpoint buffer 1 address
375   *                   in the MSB part of 32-bit value.
376   * @retval HAL status
377   */
378 
HAL_PCDEx_PMAConfig(PCD_HandleTypeDef * hpcd,uint16_t ep_addr,uint16_t ep_kind,uint32_t pmaadress)379 HAL_StatusTypeDef  HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr,
380                                        uint16_t ep_kind, uint32_t pmaadress)
381 {
382   PCD_EPTypeDef *ep;
383 
384   /* initialize ep structure*/
385   if ((0x80U & ep_addr) == 0x80U)
386   {
387     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
388   }
389   else
390   {
391     ep = &hpcd->OUT_ep[ep_addr];
392   }
393 
394   /* Here we check if the endpoint is single or double Buffer*/
395   if (ep_kind == PCD_SNG_BUF)
396   {
397     /* Single Buffer */
398     ep->doublebuffer = 0U;
399     /* Configure the PMA */
400     ep->pmaadress = (uint16_t)pmaadress;
401   }
402 #if (USE_USB_DOUBLE_BUFFER == 1U)
403   else /* USB_DBL_BUF */
404   {
405     /* Double Buffer Endpoint */
406     ep->doublebuffer = 1U;
407     /* Configure the PMA */
408     ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU);
409     ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16);
410   }
411 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
412 
413   return HAL_OK;
414 }
415 
416 /**
417   * @brief  Activate BatteryCharging feature.
418   * @param  hpcd PCD handle
419   * @retval HAL status
420   */
HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef * hpcd)421 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
422 {
423   USB_DRD_TypeDef *USBx = hpcd->Instance;
424   hpcd->battery_charging_active = 1U;
425 
426   /* Enable BCD feature */
427   USBx->BCDR |= USB_BCDR_BCDEN;
428 
429   /* Enable DCD : Data Contact Detect */
430   USBx->BCDR &= ~(USB_BCDR_PDEN);
431   USBx->BCDR &= ~(USB_BCDR_SDEN);
432   USBx->BCDR |= USB_BCDR_DCDEN;
433 
434   return HAL_OK;
435 }
436 
437 /**
438   * @brief  Deactivate BatteryCharging feature.
439   * @param  hpcd PCD handle
440   * @retval HAL status
441   */
HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef * hpcd)442 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
443 {
444   USB_DRD_TypeDef *USBx = hpcd->Instance;
445   hpcd->battery_charging_active = 0U;
446 
447   /* Disable BCD feature */
448   USBx->BCDR &= ~(USB_BCDR_BCDEN);
449 
450   return HAL_OK;
451 }
452 
453 /**
454   * @brief  Handle BatteryCharging Process.
455   * @param  hpcd PCD handle
456   * @retval HAL status
457   */
HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef * hpcd)458 void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
459 {
460   USB_DRD_TypeDef *USBx = hpcd->Instance;
461   uint32_t tickstart = HAL_GetTick();
462 
463   /* Wait for Min DCD Timeout */
464   HAL_Delay(300U);
465 
466   /* Data Pin Contact ? Check Detect flag */
467   if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET)
468   {
469 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
470     hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
471 #else
472     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
473 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
474   }
475   /* Primary detection: checks if connected to Standard Downstream Port
476   (without charging capability) */
477   USBx->BCDR &= ~(USB_BCDR_DCDEN);
478   HAL_Delay(50U);
479   USBx->BCDR |= (USB_BCDR_PDEN);
480   HAL_Delay(50U);
481 
482   /* If Charger detect ? */
483   if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET)
484   {
485     /* Start secondary detection to check connection to Charging Downstream
486     Port or Dedicated Charging Port */
487     USBx->BCDR &= ~(USB_BCDR_PDEN);
488     HAL_Delay(50U);
489     USBx->BCDR |= (USB_BCDR_SDEN);
490     HAL_Delay(50U);
491 
492     /* If CDP ? */
493     if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET)
494     {
495       /* Dedicated Downstream Port DCP */
496 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
497       hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
498 #else
499       HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
500 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
501     }
502     else
503     {
504       /* Charging Downstream Port CDP */
505 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
506       hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
507 #else
508       HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
509 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
510     }
511   }
512   else /* NO */
513   {
514     /* Standard Downstream Port */
515 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
516     hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
517 #else
518     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
519 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
520   }
521 
522   /* Battery Charging capability discovery finished Start Enumeration */
523   (void)HAL_PCDEx_DeActivateBCD(hpcd);
524 
525   /* Check for the Timeout, else start USB Device */
526   if ((HAL_GetTick() - tickstart) > 1000U)
527   {
528 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
529     hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
530 #else
531     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
532 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
533   }
534   else
535   {
536 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
537     hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
538 #else
539     HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
540 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
541   }
542 }
543 
544 /**
545   * @brief  Activate LPM feature.
546   * @param  hpcd PCD handle
547   * @retval HAL status
548   */
HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef * hpcd)549 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
550 {
551 
552   USB_DRD_TypeDef *USBx = hpcd->Instance;
553   hpcd->lpm_active = 1U;
554   hpcd->LPM_State = LPM_L0;
555 
556   USBx->LPMCSR |= USB_LPMCSR_LMPEN;
557   USBx->LPMCSR |= USB_LPMCSR_LPMACK;
558 
559   return HAL_OK;
560 }
561 
562 /**
563   * @brief  Deactivate LPM feature.
564   * @param  hpcd PCD handle
565   * @retval HAL status
566   */
HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef * hpcd)567 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
568 {
569   USB_DRD_TypeDef *USBx = hpcd->Instance;
570 
571   hpcd->lpm_active = 0U;
572 
573   USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN);
574   USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK);
575 
576   return HAL_OK;
577 }
578 #endif /* defined (USB_DRD_FS) */
579 
580 /**
581   * @brief  Send LPM message to user layer callback.
582   * @param  hpcd PCD handle
583   * @param  msg LPM message
584   * @retval HAL status
585   */
HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef * hpcd,PCD_LPM_MsgTypeDef msg)586 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
587 {
588   /* Prevent unused argument(s) compilation warning */
589   UNUSED(hpcd);
590   UNUSED(msg);
591 
592   /* NOTE : This function should not be modified, when the callback is needed,
593             the HAL_PCDEx_LPM_Callback could be implemented in the user file
594    */
595 }
596 
597 /**
598   * @brief  Send BatteryCharging message to user layer callback.
599   * @param  hpcd PCD handle
600   * @param  msg LPM message
601   * @retval HAL status
602   */
HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef * hpcd,PCD_BCD_MsgTypeDef msg)603 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
604 {
605   /* Prevent unused argument(s) compilation warning */
606   UNUSED(hpcd);
607   UNUSED(msg);
608 
609   /* NOTE : This function should not be modified, when the callback is needed,
610             the HAL_PCDEx_BCD_Callback could be implemented in the user file
611    */
612 }
613 
614 /**
615   * @}
616   */
617 
618 /**
619   * @}
620   */
621 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) || defined (USB_DRD_FS) */
622 #endif /* HAL_PCD_MODULE_ENABLED */
623 
624 /**
625   * @}
626   */
627 
628 /**
629   * @}
630   */
631