STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_pcd_ex.c
Go to the documentation of this file.
1 
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32l4xx_hal.h"
26 
36 #ifdef HAL_PCD_MODULE_ENABLED
37 
38 #if defined (USB) || defined (USB_OTG_FS)
39 /* Private types -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private constants ---------------------------------------------------------*/
42 /* Private macros ------------------------------------------------------------*/
43 /* Private functions ---------------------------------------------------------*/
44 /* Exported functions --------------------------------------------------------*/
45 
63 #if defined (USB_OTG_FS)
64 
71 HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
72 {
73  uint8_t i;
74  uint32_t Tx_Offset;
75 
76  /* TXn min size = 16 words. (n : Transmit FIFO index)
77  When a TxFIFO is not used, the Configuration should be as follows:
78  case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
79  --> Txm can use the space allocated for Txn.
80  case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
81  --> Txn should be configured with the minimum space of 16 words
82  The FIFO is used optimally when used TxFIFOs are allocated in the top
83  of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
84  When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
85 
86  Tx_Offset = hpcd->Instance->GRXFSIZ;
87 
88  if (fifo == 0U)
89  {
90  hpcd->Instance->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset;
91  }
92  else
93  {
94  Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16;
95  for (i = 0U; i < (fifo - 1U); i++)
96  {
97  Tx_Offset += (hpcd->Instance->DIEPTXF[i] >> 16);
98  }
99 
100  /* Multiply Tx_Size by 2 to get higher performance */
101  hpcd->Instance->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
102  }
103 
104  return HAL_OK;
105 }
106 
113 HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
114 {
115  hpcd->Instance->GRXFSIZ = size;
116 
117  return HAL_OK;
118 }
119 
125 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
126 {
127  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
128 
129  hpcd->lpm_active = 1U;
130  hpcd->LPM_State = LPM_L0;
131  USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM;
132  USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
133 
134  return HAL_OK;
135 }
136 
143 {
144  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
145 
146  hpcd->lpm_active = 0U;
147  USBx->GINTMSK &= ~USB_OTG_GINTMSK_LPMINTM;
148  USBx->GLPMCFG &= ~(USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
149 
150  return HAL_OK;
151 }
152 
153 
160 {
161  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
162  uint32_t tickstart = HAL_GetTick();
163 
164  /* Enable DCD : Data Contact Detect */
165  USBx->GCCFG |= USB_OTG_GCCFG_DCDEN;
166 
167  /* Wait Detect flag or a timeout is happen*/
168  while ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == 0U)
169  {
170  /* Check for the Timeout */
171  if ((HAL_GetTick() - tickstart) > 1000U)
172  {
173 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
174  hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
175 #else
177 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
178 
179  return;
180  }
181  }
182 
183  /* Right response got */
184  HAL_Delay(200U);
185 
186  /* Check Detect flag*/
187  if ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == USB_OTG_GCCFG_DCDET)
188  {
189 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
190  hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
191 #else
193 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
194  }
195 
196  /*Primary detection: checks if connected to Standard Downstream Port
197  (without charging capability) */
198  USBx->GCCFG &= ~ USB_OTG_GCCFG_DCDEN;
199  HAL_Delay(50U);
200  USBx->GCCFG |= USB_OTG_GCCFG_PDEN;
201  HAL_Delay(50U);
202 
203  if ((USBx->GCCFG & USB_OTG_GCCFG_PDET) == 0U)
204  {
205  /* Case of Standard Downstream Port */
206 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
207  hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
208 #else
210 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
211  }
212  else
213  {
214  /* start secondary detection to check connection to Charging Downstream
215  Port or Dedicated Charging Port */
216  USBx->GCCFG &= ~ USB_OTG_GCCFG_PDEN;
217  HAL_Delay(50U);
218  USBx->GCCFG |= USB_OTG_GCCFG_SDEN;
219  HAL_Delay(50U);
220 
221  if ((USBx->GCCFG & USB_OTG_GCCFG_SDET) == USB_OTG_GCCFG_SDET)
222  {
223  /* case Dedicated Charging Port */
224 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
225  hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
226 #else
228 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
229  }
230  else
231  {
232  /* case Charging Downstream Port */
233 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
234  hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
235 #else
237 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
238  }
239  }
240 
241  /* Battery Charging capability discovery finished */
242  (void)HAL_PCDEx_DeActivateBCD(hpcd);
243 
244 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
245  hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
246 #else
248 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
249 }
250 
256 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
257 {
258  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
259 
260  USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
261  USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
262 
263  /* Power Down USB tranceiver */
264  USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
265 
266  /* Enable Battery charging */
267  USBx->GCCFG |= USB_OTG_GCCFG_BCDEN;
268 
269  hpcd->battery_charging_active = 1U;
270 
271  return HAL_OK;
272 }
273 
280 {
281  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
282 
283  USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN);
284  USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN);
285 
286  /* Disable Battery charging */
287  USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
288 
289  hpcd->battery_charging_active = 0U;
290 
291  return HAL_OK;
292 }
293 
294 #endif /* defined (USB_OTG_FS) */
295 #if defined (USB)
296 
313 HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
314  uint16_t ep_addr,
315  uint16_t ep_kind,
316  uint32_t pmaadress)
317 {
318  PCD_EPTypeDef *ep;
319 
320  /* initialize ep structure*/
321  if ((0x80U & ep_addr) == 0x80U)
322  {
323  ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
324  }
325  else
326  {
327  ep = &hpcd->OUT_ep[ep_addr];
328  }
329 
330  /* Here we check if the endpoint is single or double Buffer*/
331  if (ep_kind == PCD_SNG_BUF)
332  {
333  /* Single Buffer */
334  ep->doublebuffer = 0U;
335  /* Configure the PMA */
336  ep->pmaadress = (uint16_t)pmaadress;
337  }
338  else /* USB_DBL_BUF */
339  {
340  /* Double Buffer Endpoint */
341  ep->doublebuffer = 1U;
342  /* Configure the PMA */
343  ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU);
344  ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16);
345  }
346 
347  return HAL_OK;
348 }
349 
355 HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
356 {
357  USB_TypeDef *USBx = hpcd->Instance;
358  hpcd->battery_charging_active = 1U;
359 
360  /* Enable DCD : Data Contact Detect */
361  USBx->BCDR &= ~(USB_BCDR_PDEN);
362  USBx->BCDR &= ~(USB_BCDR_SDEN);
363  USBx->BCDR |= USB_BCDR_DCDEN;
364 
365  return HAL_OK;
366 }
367 
373 HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
374 {
375  USB_TypeDef *USBx = hpcd->Instance;
376  hpcd->battery_charging_active = 0U;
377 
378  USBx->BCDR &= ~(USB_BCDR_BCDEN);
379 
380  return HAL_OK;
381 }
382 
389 {
390  USB_TypeDef *USBx = hpcd->Instance;
391  uint32_t tickstart = HAL_GetTick();
392 
393  /* Wait Detect flag or a timeout is happen*/
394  while ((USBx->BCDR & USB_BCDR_DCDET) == 0U)
395  {
396  /* Check for the Timeout */
397  if ((HAL_GetTick() - tickstart) > 1000U)
398  {
399 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
400  hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
401 #else
403 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
404 
405  return;
406  }
407  }
408 
409  HAL_Delay(200U);
410 
411  /* Data Pin Contact ? Check Detect flag */
412  if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET)
413  {
414 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
415  hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
416 #else
418 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
419  }
420  /* Primary detection: checks if connected to Standard Downstream Port
421  (without charging capability) */
422  USBx->BCDR &= ~(USB_BCDR_DCDEN);
423  HAL_Delay(50U);
424  USBx->BCDR |= (USB_BCDR_PDEN);
425  HAL_Delay(50U);
426 
427  /* If Charger detect ? */
428  if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET)
429  {
430  /* Start secondary detection to check connection to Charging Downstream
431  Port or Dedicated Charging Port */
432  USBx->BCDR &= ~(USB_BCDR_PDEN);
433  HAL_Delay(50U);
434  USBx->BCDR |= (USB_BCDR_SDEN);
435  HAL_Delay(50U);
436 
437  /* If CDP ? */
438  if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET)
439  {
440  /* Dedicated Downstream Port DCP */
441 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
442  hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
443 #else
445 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
446  }
447  else
448  {
449  /* Charging Downstream Port CDP */
450 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
451  hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
452 #else
454 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
455  }
456  }
457  else /* NO */
458  {
459  /* Standard Downstream Port */
460 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
461  hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
462 #else
464 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
465  }
466 
467  /* Battery Charging capability discovery finished Start Enumeration */
468  (void)HAL_PCDEx_DeActivateBCD(hpcd);
469 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
470  hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
471 #else
473 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
474 }
475 
476 
482 HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
483 {
484 
485  USB_TypeDef *USBx = hpcd->Instance;
486  hpcd->lpm_active = 1U;
487  hpcd->LPM_State = LPM_L0;
488 
489  USBx->LPMCSR |= USB_LPMCSR_LMPEN;
490  USBx->LPMCSR |= USB_LPMCSR_LPMACK;
491 
492  return HAL_OK;
493 }
494 
500 HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
501 {
502  USB_TypeDef *USBx = hpcd->Instance;
503 
504  hpcd->lpm_active = 0U;
505 
506  USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN);
507  USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK);
508 
509  return HAL_OK;
510 }
511 
512 #endif /* defined (USB) */
513 
521 {
522  /* Prevent unused argument(s) compilation warning */
523  UNUSED(hpcd);
524  UNUSED(msg);
525 
526  /* NOTE : This function should not be modified, when the callback is needed,
527  the HAL_PCDEx_LPM_Callback could be implemented in the user file
528  */
529 }
530 
538 {
539  /* Prevent unused argument(s) compilation warning */
540  UNUSED(hpcd);
541  UNUSED(msg);
542 
543  /* NOTE : This function should not be modified, when the callback is needed,
544  the HAL_PCDEx_BCD_Callback could be implemented in the user file
545  */
546 }
547 
555 #endif /* defined (USB) || defined (USB_OTG_FS) */
556 #endif /* HAL_PCD_MODULE_ENABLED */
557 
566 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, uint16_t ep_kind, uint32_t pmaadress)
Configure PMA for EP.
HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
Set Rx FIFO.
HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
Set Tx FIFO.
This file contains all the functions prototypes for the HAL module driver.
struct __PCD_HandleTypeDef else typedef struct endif PCD_HandleTypeDef
PCD Handle Structure definition.
void HAL_Delay(uint32_t Delay)
This function provides minimum delay (in milliseconds) based on variable incremented.
uint32_t HAL_GetTick(void)
Provide a tick value in millisecond.
HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
Activate LPM feature.
PCD_BCD_MsgTypeDef
HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
Activate BatteryCharging feature.
return HAL_OK
HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
Deactivate LPM feature.
void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
Handle BatteryCharging Process.
HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
Deactivate BatteryCharging feature.
void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
Send LPM message to user layer callback.
PCD_LPM_MsgTypeDef
void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
Send BatteryCharging message to user layer callback.