How do I send extended PD messages?

Announcements

Live Webinar: USB-C adoption. Simple & Cost-efficient solutions | April 18th @9am or 5pm CEST. Register now !

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
NiMc_4245981
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted

I'm trying to send an extended message from a CY4531 acting as a source to a device with a CCG3.  I see that the dpm_pd_command can take DPM_CMD_SEND_EXTENDED as an argument, but I can't get that to work.  Here is what I have.

static uint8_t g_buffer[2] = {0};

bool get_fw_id()

{

dpm_pd_cmd_buf_t cmd = {0};

// USB Power Deliver Firmware Update

g_buffer[0] = 1;    // Protocol Version

g_buffer[1] = 0x81; // GET_FW_ID

cmd.cmd_sop = SOP;

cmd.extd_type = EXTD_MSG_FW_UPDATE_REQ;

cmd.extd_hdr.val = 0;

cmd.extd_hdr.extd.data_size = 2;

cmd.no_of_cmd_do = 0;

cmd.dat_ptr = g_buffer;

cmd.timeout = PD_SENDER_RESPONSE_TIMER_PERIOD;

if (dpm_pd_command(0, DPM_CMD_SEND_EXTENDED, &cmd, NULL) != CCG_STAT_SUCCESS)

   return false;

return true;

}

I see the command is sent using the EZ-PD protocol analyzer, as in the screenshot below.  The header (0x8DAA) looks correct, but it is missing the extended message header and the two bytes of payload.

2019_07_03_16_22_29_EZ_PD_Analyzer_Utility.png

What else do I need to do to send a full extended message?

0 Likes
1 Solution
ShifangZ_26
Moderator
Moderator
Moderator
10 likes given 250 sign-ins 1000 replies posted

Hi ,

I could like to recommend you refer below example to send DPM_CMD_SEND_EXTENDED.  This is implemented in app.c function void app_event_handler(uint8_t port, app_evt_t evt, const void* dat).

        case APP_EVT_ALERT_RECEIVED:

            /* Respond to ALERT message only if there is the number of object is one. */

            if (((pd_packet_t*)dat)->len == 1)

            {

                alert_ado = ((pd_packet_t*)dat)->dat[0];

                if(alert_ado.ado_alert.bat_status_change == false)

                {

                    dpm_pd_command(port, DPM_CMD_GET_STATUS, NULL, NULL);

                }

                else

                {

                    uint8_t i = alert_ado.ado_alert.fixed_bats |

                        (alert_ado.ado_alert.hot_swap_bats << 4);

                    dpm_pd_cmd_buf_t cmd;

                    /* Identify the first battery for which the change is intended. */

                    get_bat_status[port] = 0;

                    while ((i != 0) && ((i & 0x01) == 0))

                    {

                        get_bat_status[port]++;

                        i >>= 1;

                    }

                    cmd.cmd_sop = SOP;

                    cmd.extd_hdr.val = 0x1;

                    cmd.timeout = PD_SENDER_RESPONSE_TIMER_PERIOD;

                    cmd.extd_type = EXTD_MSG_GET_BAT_STATUS;

                    cmd.dat_ptr = (uint8_t*)&get_bat_status[port];

                    dpm_pd_command(port, DPM_CMD_SEND_EXTENDED, &cmd, NULL);

                }

            }

            break;

Before you fill the "cmd", you can see the structure in pd.h. And then, you should fill the structure as per your message.

/**

* @brief Struct to hold PD command buffer.

* @warning When providing pointer to the extended data make sure original buffer

* is always 4-byte aligned. i.e, even if 1 byte data is required, 4 bytes should be used to

* store that data.

*/

typedef struct

{

    sop_t               cmd_sop;                /**< SOP type */

    extd_msg_t          extd_type;              /**< Extended Message Type */

    pd_extd_hdr_t       extd_hdr;               /**< Extended Header */

    uint8_t             no_of_cmd_do;           /**< No of data objects including VDM header */

    uint8_t*            dat_ptr;                /**< Data Pointer in case of extended message only*/

    uint8_t             timeout;                /**< Timeout value, in ms, for a response.

                                                 *   If set to zero, the PD stack will not wait for a VDM response

                                                 *   and jump to ready state after this buffer has been sent.

                                                 */

    pd_do_t             cmd_do[MAX_NO_OF_DO];   /**< Command data objects. */

} dpm_pd_cmd_buf_t;

Best Regards,

Lisa

View solution in original post

2 Replies
ShifangZ_26
Moderator
Moderator
Moderator
10 likes given 250 sign-ins 1000 replies posted

Hi ,

I could like to recommend you refer below example to send DPM_CMD_SEND_EXTENDED.  This is implemented in app.c function void app_event_handler(uint8_t port, app_evt_t evt, const void* dat).

        case APP_EVT_ALERT_RECEIVED:

            /* Respond to ALERT message only if there is the number of object is one. */

            if (((pd_packet_t*)dat)->len == 1)

            {

                alert_ado = ((pd_packet_t*)dat)->dat[0];

                if(alert_ado.ado_alert.bat_status_change == false)

                {

                    dpm_pd_command(port, DPM_CMD_GET_STATUS, NULL, NULL);

                }

                else

                {

                    uint8_t i = alert_ado.ado_alert.fixed_bats |

                        (alert_ado.ado_alert.hot_swap_bats << 4);

                    dpm_pd_cmd_buf_t cmd;

                    /* Identify the first battery for which the change is intended. */

                    get_bat_status[port] = 0;

                    while ((i != 0) && ((i & 0x01) == 0))

                    {

                        get_bat_status[port]++;

                        i >>= 1;

                    }

                    cmd.cmd_sop = SOP;

                    cmd.extd_hdr.val = 0x1;

                    cmd.timeout = PD_SENDER_RESPONSE_TIMER_PERIOD;

                    cmd.extd_type = EXTD_MSG_GET_BAT_STATUS;

                    cmd.dat_ptr = (uint8_t*)&get_bat_status[port];

                    dpm_pd_command(port, DPM_CMD_SEND_EXTENDED, &cmd, NULL);

                }

            }

            break;

Before you fill the "cmd", you can see the structure in pd.h. And then, you should fill the structure as per your message.

/**

* @brief Struct to hold PD command buffer.

* @warning When providing pointer to the extended data make sure original buffer

* is always 4-byte aligned. i.e, even if 1 byte data is required, 4 bytes should be used to

* store that data.

*/

typedef struct

{

    sop_t               cmd_sop;                /**< SOP type */

    extd_msg_t          extd_type;              /**< Extended Message Type */

    pd_extd_hdr_t       extd_hdr;               /**< Extended Header */

    uint8_t             no_of_cmd_do;           /**< No of data objects including VDM header */

    uint8_t*            dat_ptr;                /**< Data Pointer in case of extended message only*/

    uint8_t             timeout;                /**< Timeout value, in ms, for a response.

                                                 *   If set to zero, the PD stack will not wait for a VDM response

                                                 *   and jump to ready state after this buffer has been sent.

                                                 */

    pd_do_t             cmd_do[MAX_NO_OF_DO];   /**< Command data objects. */

} dpm_pd_cmd_buf_t;

Best Regards,

Lisa

I have trouble even when I use the APP_EVT_ALERT_RECEIVED code.   The data that is sent is 0x9DAA, 0x8400.  The last two zeros should be the extd.data_size, but it is zero.  Therefore the data byte is missing.  the data_size is set in the command passed to dpm_pd_command(), but it seems like that function is setting it to zero before sending it.

2019-07-05 09_37_10-EZ-PD Analyzer Utility.png

0 Likes