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