2023-02-06 04:14 PM
Hello,
I’m using STM32L412RB.
I'm trying to differentiate between the types of chargers
When the charger is connected, reboot occurs, and I run HAL_PCDEx_ActivateBCD()/HAL_PCDEx_BCD_VBUSDetect() in MX_USB_DEVICE_Init().
After that, in case of abnormality, HAL_PCDEx_ActivateBCD()/HAL_PCDEx_BCD_VBUSDetect() is used to detect charger at regular intervals.
In the example(\STM32Cube_FW_L4_V1.16.0\Projects\NUCLEO-L412RB-P\Applications\USB_Device\HID_Standalone_BCD) an interrupt occurs when Vbus detect is performed, and HAL_PCDEx_BCD_VBUSDetect() is performed within it.
My board does not detect Vbus, but performs HAL_PCDEx_ActivateBCD()/HAL_PCDEx_BCD_VBUSDetect().
I tried using the callback function within HAL_PCDEx_BCD_VBUSDetect() and also tried saving the value directly within the function.
The data identified at this time are randomly different.
1. In case of 1 byte save
- Check PCD_BCD_ERROR
2. In case of 2 byte save
- Check PCD_BCD_CONTACT_DETECTION
- Check PCD_BCD_DISCOVERY_COMPLETED
3. In case of 3 byte save
- Check PCD_BCD_CONTACT_DETECTION
- Check PCD_BCD_STD_DOWNSTREAM_PORT or PCD_BCD_CHARGING_DOWNSTREAM_PORT
- Check PCD_BCD_DISCOVERY_COMPLETED
In the above three cases, the third one seems to be normal, but the actual SDP/CDP cannot be distinguished.
In terms of HW, the DP/DM ports are connected to the MCU through the USB switch, and each TVS is installed before the USB switch.
If this method is wrong, what should I check?
thank you
void MX_USB_DEVICE_Init(void)
{
/* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
/* USER CODE END USB_DEVICE_Init_PreTreatment */
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK)
{
Error_Handler();
}
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
// charger detect enable
HAL_PCDEx_ActivateBCD(&pcd);
HAL_PCDEx_BCD_VBUSDetect(&pcd);
/* USER CODE END USB_DEVICE_Init_PostTreatment */
}
void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
{
USB_TypeDef *USBx = hpcd->Instance;
uint32_t tickstart = HAL_GetTick();
/* Wait Detect flag or a timeout is happen*/
while ((USBx->BCDR & USB_BCDR_DCDET) == 0U)
{
/* Check for the Timeout */
if ((HAL_GetTick() - tickstart) > 1000U)
{
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
#else
#if defined(BCD_Callback_USE)
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
#else
charger_state.pcdInfo[charger_state.pcdInfoOrder] = PCD_BCD_ERROR;
charger_state.pcdInfoOrder++;
#endif
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
return;
}
}
HAL_Delay(200U);
/* Data Pin Contact ? Check Detect flag */
if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET)
{
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
#else
#if defined(BCD_Callback_USE)
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
#else
charger_state.pcdInfo[charger_state.pcdInfoOrder] = PCD_BCD_CONTACT_DETECTION;
charger_state.pcdInfoOrder++;
#endif
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
/*Primary detection: checks if connected to Standard Downstream Port
(without charging capability) */
USBx->BCDR &= ~(USB_BCDR_DCDEN);
HAL_Delay(50U);
USBx->BCDR |= (USB_BCDR_PDEN);
HAL_Delay(50U);
/* If Charger detect ? */
if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET)
{
/* Start secondary detection to check connection to Charging Downstream
Port or Dedicated Charging Port */
USBx->BCDR &= ~(USB_BCDR_PDEN);
HAL_Delay(50U);
USBx->BCDR |= (USB_BCDR_SDEN);
HAL_Delay(50U);
/* If CDP ? */
if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET)
{
/* Dedicated Downstream Port DCP */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
#else
#if defined(BCD_Callback_USE)
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
#else
charger_state.pcdInfo[charger_state.pcdInfoOrder] = PCD_BCD_DEDICATED_CHARGING_PORT;
charger_state.pcdInfoOrder++;
#endif
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
else
{
/* Charging Downstream Port CDP */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
#else
#if defined(BCD_Callback_USE)
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
#else
charger_state.pcdInfo[charger_state.pcdInfoOrder] = PCD_BCD_CHARGING_DOWNSTREAM_PORT;
charger_state.pcdInfoOrder++;
#endif
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
}
else /* NO */
{
/* Standard Downstream Port */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
#else
#if defined(BCD_Callback_USE)
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
#else
charger_state.pcdInfo[charger_state.pcdInfoOrder] = PCD_BCD_STD_DOWNSTREAM_PORT;
charger_state.pcdInfoOrder++;
#endif
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
/* Battery Charging capability discovery finished Start Enumeration */
(void)HAL_PCDEx_DeActivateBCD(hpcd);
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
#else
#if defined(BCD_Callback_USE)
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
#else
charger_state.pcdInfo[charger_state.pcdInfoOrder] = PCD_BCD_DISCOVERY_COMPLETED;
charger_state.pcdInfoOrder++;
#endif
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}