cancel
Showing results for 
Search instead for 
Did you mean: 

Does the latest STM USB-PD Core stack support Electronically Marked Cable ?

ADoro.2
Associate III

If it does support EMC, how can I read some ID information from the cable?

1 ACCEPTED SOLUTION

Accepted Solutions
Yohann M.
ST Employee

Dear @ADoro.2​ 

I confirm than STM USB-PD core stack supports EMC cable.

Please find the associated Message Sequence Chart:

0693W00000BZd6HQAT.jpg 

The option '_VCONN_SUPPORT' should be enabled in your workspace.

With this switch, "DPM_Params[PortNum].VconnStatus" variable is set to USBPD_TRUE and will be used to activate VCONN and start VDM negotiation on EMC cable (VDM Discovery message).

You could refer to demonstration code on STM32G081B-EVAL board to see where this flag is enabled:

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Projects/STM32G081B-EVAL/Demonstrations/DemoUCPD/

This activation is necessary to enable VCONN on the CC line used to power on the cable like this

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Projects/STM32G081B-EVAL/Demonstrations/DemoUCPD/Src/usbpd_pwr_if.c#L441

USBPD_StatusTypeDef USBPD_PWR_IF_VBUSEnable(uint8_t PortNum)
{
/* USER CODE BEGIN USBPD_PWR_IF_VBUSEnable */
  USBPD_StatusTypeDef _status = USBPD_ERROR;
 
  /* check for valid port */
  if (USBPD_PORT_IsValid(PortNum))
  {
    POWER_IF_TRACE(PortNum, "EN_VBUS", 7);
    /* Set the new state */
#ifdef _TRACE
    char str[20];
    sprintf(str, "CC:%d VCONN:%d", DPM_Params[PortNum].VconnCCIs, DPM_Params[PortNum].VconnStatus);
    POWER_IF_TRACE(PortNum, (uint8_t*)str, strlen(str));
#endif /* _TRACE */
    _status = (USBPD_StatusTypeDef)HW_IF_PWR_Enable(PortNum, USBPD_ENABLE, DPM_Params[PortNum].VconnCCIs, DPM_Params[PortNum].VconnStatus, USBPD_PORTPOWERROLE_SRC);
  }
  return _status;
/* USER CODE END USBPD_PWR_IF_VBUSEnable */
}

And

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Middlewares/ST/STM32_USBPD_Library/Devices/STM32G0XX/src/usbpd_pwr_hw_if.c#L74

USBPD_StatusTypeDef HW_IF_PWR_Enable(uint8_t PortNum, USBPD_FunctionalState state, CCxPin_TypeDef Cc, uint32_t VconnState, USBPD_PortPowerRole_TypeDef role)
{
  UNUSED(role);
  int32_t status;
  if (USBPD_ENABLE == state)
  {
#if defined(_VCONN_SUPPORT)
    if (USBPD_TRUE == VconnState)
    {
      POWER_DEBUG((uint8_t *)"VCONN ON", 8);
      (void)BSP_USBPD_PWR_VCONNOn(PortNum, Cc);
    }
#endif /* _VCONN_SUPPORT */

Cable ID information will be retrieved thanks to the callback in usbpd_vdm_user code:

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Projects/STM32G081B-EVAL/Demonstrations/DemoUCPD/Src/usbpd_vdm_user.c#L760

static void USBPD_VDM_InformIdentity(uint8_t PortNum, USBPD_SOPType_TypeDef SOPType, USBPD_VDM_CommandType_Typedef CommandStatus, USBPD_DiscoveryIdentity_TypeDef *pIdentity)
{
/* USER CODE BEGIN USBPD_VDM_InformIdentity */
  switch(CommandStatus)
  {
  case SVDM_RESPONDER_ACK :
    if (USBPD_SOPTYPE_SOP1 == SOPType)
    {
      uint8_t*  disco_ident;
      disco_ident = (uint8_t*)&DPM_Ports[PortNum].VDM_DiscoCableIdentify;
      memcpy(disco_ident, (uint8_t*)pIdentity, sizeof(USBPD_DiscoveryIdentity_TypeDef));
      DEMO_SetCableInfo(PortNum, pIdentity);
      if (NULL != DPM_GUI_SaveInfo)
      {
        DPM_GUI_SaveInfo(PortNum, VDM_CABLE_INFO, (uint8_t*)pIdentity, sizeof(USBPD_DiscoveryIdentity_TypeDef));
      }
    }

Regards,

Yohann

View solution in original post

7 REPLIES 7
Yohann M.
ST Employee

Dear @ADoro.2​ 

I confirm than STM USB-PD core stack supports EMC cable.

Please find the associated Message Sequence Chart:

0693W00000BZd6HQAT.jpg 

The option '_VCONN_SUPPORT' should be enabled in your workspace.

With this switch, "DPM_Params[PortNum].VconnStatus" variable is set to USBPD_TRUE and will be used to activate VCONN and start VDM negotiation on EMC cable (VDM Discovery message).

You could refer to demonstration code on STM32G081B-EVAL board to see where this flag is enabled:

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Projects/STM32G081B-EVAL/Demonstrations/DemoUCPD/

This activation is necessary to enable VCONN on the CC line used to power on the cable like this

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Projects/STM32G081B-EVAL/Demonstrations/DemoUCPD/Src/usbpd_pwr_if.c#L441

USBPD_StatusTypeDef USBPD_PWR_IF_VBUSEnable(uint8_t PortNum)
{
/* USER CODE BEGIN USBPD_PWR_IF_VBUSEnable */
  USBPD_StatusTypeDef _status = USBPD_ERROR;
 
  /* check for valid port */
  if (USBPD_PORT_IsValid(PortNum))
  {
    POWER_IF_TRACE(PortNum, "EN_VBUS", 7);
    /* Set the new state */
#ifdef _TRACE
    char str[20];
    sprintf(str, "CC:%d VCONN:%d", DPM_Params[PortNum].VconnCCIs, DPM_Params[PortNum].VconnStatus);
    POWER_IF_TRACE(PortNum, (uint8_t*)str, strlen(str));
#endif /* _TRACE */
    _status = (USBPD_StatusTypeDef)HW_IF_PWR_Enable(PortNum, USBPD_ENABLE, DPM_Params[PortNum].VconnCCIs, DPM_Params[PortNum].VconnStatus, USBPD_PORTPOWERROLE_SRC);
  }
  return _status;
/* USER CODE END USBPD_PWR_IF_VBUSEnable */
}

And

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Middlewares/ST/STM32_USBPD_Library/Devices/STM32G0XX/src/usbpd_pwr_hw_if.c#L74

USBPD_StatusTypeDef HW_IF_PWR_Enable(uint8_t PortNum, USBPD_FunctionalState state, CCxPin_TypeDef Cc, uint32_t VconnState, USBPD_PortPowerRole_TypeDef role)
{
  UNUSED(role);
  int32_t status;
  if (USBPD_ENABLE == state)
  {
#if defined(_VCONN_SUPPORT)
    if (USBPD_TRUE == VconnState)
    {
      POWER_DEBUG((uint8_t *)"VCONN ON", 8);
      (void)BSP_USBPD_PWR_VCONNOn(PortNum, Cc);
    }
#endif /* _VCONN_SUPPORT */

Cable ID information will be retrieved thanks to the callback in usbpd_vdm_user code:

https://github.com/STMicroelectronics/STM32CubeG0/blob/master/Projects/STM32G081B-EVAL/Demonstrations/DemoUCPD/Src/usbpd_vdm_user.c#L760

static void USBPD_VDM_InformIdentity(uint8_t PortNum, USBPD_SOPType_TypeDef SOPType, USBPD_VDM_CommandType_Typedef CommandStatus, USBPD_DiscoveryIdentity_TypeDef *pIdentity)
{
/* USER CODE BEGIN USBPD_VDM_InformIdentity */
  switch(CommandStatus)
  {
  case SVDM_RESPONDER_ACK :
    if (USBPD_SOPTYPE_SOP1 == SOPType)
    {
      uint8_t*  disco_ident;
      disco_ident = (uint8_t*)&DPM_Ports[PortNum].VDM_DiscoCableIdentify;
      memcpy(disco_ident, (uint8_t*)pIdentity, sizeof(USBPD_DiscoveryIdentity_TypeDef));
      DEMO_SetCableInfo(PortNum, pIdentity);
      if (NULL != DPM_GUI_SaveInfo)
      {
        DPM_GUI_SaveInfo(PortNum, VDM_CABLE_INFO, (uint8_t*)pIdentity, sizeof(USBPD_DiscoveryIdentity_TypeDef));
      }
    }

Regards,

Yohann

Thank you, @Yohann M.​ 

I'll try to figure it out.

ADoro.2
Associate III

Everything works well.

But I have a couple more questions.

  1. Is it possible to identify EMC if it is only connected to the Source, and nothing is connected to the other end of the cable?
  2. Is it possible to identify EMC in Sink mode?

Great to see I helped you to fix your issue...

No, it is not possible to detect an EMC in Sink mode. Solution is to request a VCONN_SWAP to be able to start a VDM negotiation with the cable.

Please find a example of Message Sequence Chart:

0693W00000BaczrQAB.png 

Regards,

Yohann

ADoro.2
Associate III

And is it possible to identify EMC if it is only connected to the Source, and nothing is connected to the other end of the cable?

No this is in the Type-C specification... VCONN is turn on only in Attached.SRC state and to enter in this state, Source should detect a sink.

ADoro.2
Associate III

Thanks a lot for the answers!