2 ******************************************************************************
\r
3 * @file stm32l4xx_hal_pcd_ex.c
\r
4 * @author MCD Application Team
\r
5 * @brief PCD Extended HAL module driver.
\r
6 * This file provides firmware functions to manage the following
\r
7 * functionalities of the USB Peripheral Controller:
\r
8 * + Extended features functions
\r
10 ******************************************************************************
\r
13 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
\r
14 * All rights reserved.</center></h2>
\r
16 * This software component is licensed by ST under BSD 3-Clause license,
\r
17 * the "License"; You may not use this file except in compliance with the
\r
18 * License. You may obtain a copy of the License at:
\r
19 * opensource.org/licenses/BSD-3-Clause
\r
21 ******************************************************************************
\r
24 /* Includes ------------------------------------------------------------------*/
\r
25 #include "stm32l4xx_hal.h"
\r
27 /** @addtogroup STM32L4xx_HAL_Driver
\r
31 /** @defgroup PCDEx PCDEx
\r
32 * @brief PCD Extended HAL module driver
\r
36 #ifdef HAL_PCD_MODULE_ENABLED
\r
38 #if defined (USB) || defined (USB_OTG_FS)
\r
39 /* Private types -------------------------------------------------------------*/
\r
40 /* Private variables ---------------------------------------------------------*/
\r
41 /* Private constants ---------------------------------------------------------*/
\r
42 /* Private macros ------------------------------------------------------------*/
\r
43 /* Private functions ---------------------------------------------------------*/
\r
44 /* Exported functions --------------------------------------------------------*/
\r
46 /** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
\r
50 /** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
\r
51 * @brief PCDEx control functions
\r
54 ===============================================================================
\r
55 ##### Extended features functions #####
\r
56 ===============================================================================
\r
57 [..] This section provides functions allowing to:
\r
58 (+) Update FIFO configuration
\r
63 #if defined (USB_OTG_FS)
\r
65 * @brief Set Tx FIFO
\r
66 * @param hpcd PCD handle
\r
67 * @param fifo The number of Tx fifo
\r
68 * @param size Fifo size
\r
69 * @retval HAL status
\r
71 HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
\r
76 /* TXn min size = 16 words. (n : Transmit FIFO index)
\r
77 When a TxFIFO is not used, the Configuration should be as follows:
\r
78 case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
\r
79 --> Txm can use the space allocated for Txn.
\r
80 case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
\r
81 --> Txn should be configured with the minimum space of 16 words
\r
82 The FIFO is used optimally when used TxFIFOs are allocated in the top
\r
83 of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
\r
84 When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
\r
86 Tx_Offset = hpcd->Instance->GRXFSIZ;
\r
90 hpcd->Instance->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset;
\r
94 Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16;
\r
95 for (i = 0U; i < (fifo - 1U); i++)
\r
97 Tx_Offset += (hpcd->Instance->DIEPTXF[i] >> 16);
\r
100 /* Multiply Tx_Size by 2 to get higher performance */
\r
101 hpcd->Instance->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
\r
108 * @brief Set Rx FIFO
\r
109 * @param hpcd PCD handle
\r
110 * @param size Size of Rx fifo
\r
111 * @retval HAL status
\r
113 HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
\r
115 hpcd->Instance->GRXFSIZ = size;
\r
121 * @brief Activate LPM feature.
\r
122 * @param hpcd PCD handle
\r
123 * @retval HAL status
\r
125 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
\r
127 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
129 hpcd->lpm_active = 1U;
\r
130 hpcd->LPM_State = LPM_L0;
\r
131 USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM;
\r
132 USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
\r
138 * @brief Deactivate LPM feature.
\r
139 * @param hpcd PCD handle
\r
140 * @retval HAL status
\r
142 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
\r
144 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
146 hpcd->lpm_active = 0U;
\r
147 USBx->GINTMSK &= ~USB_OTG_GINTMSK_LPMINTM;
\r
148 USBx->GLPMCFG &= ~(USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
\r
155 * @brief Handle BatteryCharging Process.
\r
156 * @param hpcd PCD handle
\r
157 * @retval HAL status
\r
159 void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
\r
161 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
162 uint32_t tickstart = HAL_GetTick();
\r
164 /* Enable DCD : Data Contact Detect */
\r
165 USBx->GCCFG |= USB_OTG_GCCFG_DCDEN;
\r
167 /* Wait Detect flag or a timeout is happen*/
\r
168 while ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == 0U)
\r
170 /* Check for the Timeout */
\r
171 if ((HAL_GetTick() - tickstart) > 1000U)
\r
173 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
174 hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
\r
176 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
\r
177 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
183 /* Right response got */
\r
186 /* Check Detect flag*/
\r
187 if ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == USB_OTG_GCCFG_DCDET)
\r
189 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
190 hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
\r
192 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
\r
193 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
196 /*Primary detection: checks if connected to Standard Downstream Port
\r
197 (without charging capability) */
\r
198 USBx->GCCFG &= ~ USB_OTG_GCCFG_DCDEN;
\r
200 USBx->GCCFG |= USB_OTG_GCCFG_PDEN;
\r
203 if ((USBx->GCCFG & USB_OTG_GCCFG_PDET) == 0U)
\r
205 /* Case of Standard Downstream Port */
\r
206 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
207 hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
\r
209 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
\r
210 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
214 /* start secondary detection to check connection to Charging Downstream
\r
215 Port or Dedicated Charging Port */
\r
216 USBx->GCCFG &= ~ USB_OTG_GCCFG_PDEN;
\r
218 USBx->GCCFG |= USB_OTG_GCCFG_SDEN;
\r
221 if ((USBx->GCCFG & USB_OTG_GCCFG_SDET) == USB_OTG_GCCFG_SDET)
\r
223 /* case Dedicated Charging Port */
\r
224 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
225 hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
\r
227 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
\r
228 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
232 /* case Charging Downstream Port */
\r
233 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
234 hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
\r
236 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
\r
237 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
241 /* Battery Charging capability discovery finished */
\r
242 (void)HAL_PCDEx_DeActivateBCD(hpcd);
\r
244 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
245 hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
\r
247 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
\r
248 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
252 * @brief Activate BatteryCharging feature.
\r
253 * @param hpcd PCD handle
\r
254 * @retval HAL status
\r
256 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
\r
258 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
260 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
\r
261 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
\r
263 /* Power Down USB tranceiver */
\r
264 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
\r
266 /* Enable Battery charging */
\r
267 USBx->GCCFG |= USB_OTG_GCCFG_BCDEN;
\r
269 hpcd->battery_charging_active = 1U;
\r
275 * @brief Deactivate BatteryCharging feature.
\r
276 * @param hpcd PCD handle
\r
277 * @retval HAL status
\r
279 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
\r
281 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
283 USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
\r
284 USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
\r
286 /* Disable Battery charging */
\r
287 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
\r
289 hpcd->battery_charging_active = 0U;
\r
294 #endif /* defined (USB_OTG_FS) */
\r
297 * @brief Configure PMA for EP
\r
298 * @param hpcd Device instance
\r
299 * @param ep_addr endpoint address
\r
300 * @param ep_kind endpoint Kind
\r
301 * USB_SNG_BUF: Single Buffer used
\r
302 * USB_DBL_BUF: Double Buffer used
\r
303 * @param pmaadress: EP address in The PMA: In case of single buffer endpoint
\r
304 * this parameter is 16-bit value providing the address
\r
305 * in PMA allocated to endpoint.
\r
306 * In case of double buffer endpoint this parameter
\r
307 * is a 32-bit value providing the endpoint buffer 0 address
\r
308 * in the LSB part of 32-bit value and endpoint buffer 1 address
\r
309 * in the MSB part of 32-bit value.
\r
310 * @retval HAL status
\r
313 HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
\r
316 uint32_t pmaadress)
\r
320 /* initialize ep structure*/
\r
321 if ((0x80U & ep_addr) == 0x80U)
\r
323 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
\r
327 ep = &hpcd->OUT_ep[ep_addr];
\r
330 /* Here we check if the endpoint is single or double Buffer*/
\r
331 if (ep_kind == PCD_SNG_BUF)
\r
333 /* Single Buffer */
\r
334 ep->doublebuffer = 0U;
\r
335 /* Configure the PMA */
\r
336 ep->pmaadress = (uint16_t)pmaadress;
\r
338 else /* USB_DBL_BUF */
\r
340 /* Double Buffer Endpoint */
\r
341 ep->doublebuffer = 1U;
\r
342 /* Configure the PMA */
\r
343 ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU);
\r
344 ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16);
\r
351 * @brief Activate BatteryCharging feature.
\r
352 * @param hpcd PCD handle
\r
353 * @retval HAL status
\r
355 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
\r
357 USB_TypeDef *USBx = hpcd->Instance;
\r
358 hpcd->battery_charging_active = 1U;
\r
360 /* Enable DCD : Data Contact Detect */
\r
361 USBx->BCDR &= ~(USB_BCDR_PDEN);
\r
362 USBx->BCDR &= ~(USB_BCDR_SDEN);
\r
363 USBx->BCDR |= USB_BCDR_DCDEN;
\r
369 * @brief Deactivate BatteryCharging feature.
\r
370 * @param hpcd PCD handle
\r
371 * @retval HAL status
\r
373 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
\r
375 USB_TypeDef *USBx = hpcd->Instance;
\r
376 hpcd->battery_charging_active = 0U;
\r
378 USBx->BCDR &= ~(USB_BCDR_BCDEN);
\r
384 * @brief Handle BatteryCharging Process.
\r
385 * @param hpcd PCD handle
\r
386 * @retval HAL status
\r
388 void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
\r
390 USB_TypeDef *USBx = hpcd->Instance;
\r
391 uint32_t tickstart = HAL_GetTick();
\r
393 /* Wait Detect flag or a timeout is happen*/
\r
394 while ((USBx->BCDR & USB_BCDR_DCDET) == 0U)
\r
396 /* Check for the Timeout */
\r
397 if ((HAL_GetTick() - tickstart) > 1000U)
\r
399 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
400 hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
\r
402 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
\r
403 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
411 /* Data Pin Contact ? Check Detect flag */
\r
412 if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET)
\r
414 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
415 hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
\r
417 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
\r
418 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
420 /* Primary detection: checks if connected to Standard Downstream Port
\r
421 (without charging capability) */
\r
422 USBx->BCDR &= ~(USB_BCDR_DCDEN);
\r
424 USBx->BCDR |= (USB_BCDR_PDEN);
\r
427 /* If Charger detect ? */
\r
428 if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET)
\r
430 /* Start secondary detection to check connection to Charging Downstream
\r
431 Port or Dedicated Charging Port */
\r
432 USBx->BCDR &= ~(USB_BCDR_PDEN);
\r
434 USBx->BCDR |= (USB_BCDR_SDEN);
\r
438 if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET)
\r
440 /* Dedicated Downstream Port DCP */
\r
441 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
442 hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
\r
444 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
\r
445 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
449 /* Charging Downstream Port CDP */
\r
450 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
451 hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
\r
453 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
\r
454 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
459 /* Standard Downstream Port */
\r
460 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
461 hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
\r
463 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
\r
464 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
467 /* Battery Charging capability discovery finished Start Enumeration */
\r
468 (void)HAL_PCDEx_DeActivateBCD(hpcd);
\r
469 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
470 hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
\r
472 HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
\r
473 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
478 * @brief Activate LPM feature.
\r
479 * @param hpcd PCD handle
\r
480 * @retval HAL status
\r
482 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
\r
485 USB_TypeDef *USBx = hpcd->Instance;
\r
486 hpcd->lpm_active = 1U;
\r
487 hpcd->LPM_State = LPM_L0;
\r
489 USBx->LPMCSR |= USB_LPMCSR_LMPEN;
\r
490 USBx->LPMCSR |= USB_LPMCSR_LPMACK;
\r
496 * @brief Deactivate LPM feature.
\r
497 * @param hpcd PCD handle
\r
498 * @retval HAL status
\r
500 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
\r
502 USB_TypeDef *USBx = hpcd->Instance;
\r
504 hpcd->lpm_active = 0U;
\r
506 USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN);
\r
507 USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK);
\r
512 #endif /* defined (USB) */
\r
515 * @brief Send LPM message to user layer callback.
\r
516 * @param hpcd PCD handle
\r
517 * @param msg LPM message
\r
518 * @retval HAL status
\r
520 __weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
\r
522 /* Prevent unused argument(s) compilation warning */
\r
526 /* NOTE : This function should not be modified, when the callback is needed,
\r
527 the HAL_PCDEx_LPM_Callback could be implemented in the user file
\r
532 * @brief Send BatteryCharging message to user layer callback.
\r
533 * @param hpcd PCD handle
\r
534 * @param msg LPM message
\r
535 * @retval HAL status
\r
537 __weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
\r
539 /* Prevent unused argument(s) compilation warning */
\r
543 /* NOTE : This function should not be modified, when the callback is needed,
\r
544 the HAL_PCDEx_BCD_Callback could be implemented in the user file
\r
555 #endif /* defined (USB) || defined (USB_OTG_FS) */
\r
556 #endif /* HAL_PCD_MODULE_ENABLED */
\r
566 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r