USB论坛
直播中

张强

8年用户 1457经验值
私信 关注
[问答]

请问CCG5中怎么做DR_SWAP?

请教个问题,在 CCG5代码中怎么实现DR_SWAP?我们配置了端口 0 作为源对外充电,但是我们希望 PORT0 做了 UFP。我们是这样写的代码:案例 APP_EVT_PD_合同谈判_完成: if(端口 == PORT_0 & & dpm_get_info(端口)-> cur_port_type == PRT_TYPE_DFP){                                           dpm_pd_command(port, DPM_CMD_SEND_DR_SWAP, NULL, NULL);                                       } 休息;不起作用。

回帖(1)

陈伟

2025-5-30 17:48:29

在 CCG5 中实现 DR_SWAP 需要综合考虑协议规范、硬件配置和代码逻辑。以下是分步解决方案:




1. 确认硬件配置和初始化



  • 配置工具检查:确保在 CCG5 的 EZ-PD Configuration Utility 中:

    • PORT0 的 Data Role 设置为 DRP(Dual Role Port)而非固定 DFP

    • 启用 Dual Role Data 功能(允许动态切换数据角色)。


  • 固件初始化:在代码中验证端口初始化逻辑,例如 cy_pdport_configure() 是否配置了正确的角色策略。




2. 添加对方设备支持检查


在发送 DR_SWAP 前,需确认对方设备支持数据角色交换。通过检查 PDOGet_Status 响应中的标志位:


case APP_EVT_PD_CONTRACT_NEGOTIATION_COMPLETE:
    if (port == PORT_0 && dpm_get_info(port)->cur_port_type == PRT_TYPE_DFP) {
        // 检查对方是否支持 DR_SWAP
        const dpm_port_partner_info_t *partner_info = dpm_get_partner_info(port);
        if (partner_info && (partner_info->flags & DPM_PARTNER_FLAG_DATA_SWAP)) {
            dpm_pd_command(port, DPM_CMD_SEND_DR_SWAP, NULL, NULL);
        }
    }
    break;



3. 调整发送时机


合同谈判完成事件(APP_EVT_PD_CONTRACT_NEGOTIATION_COMPLETE)可能过早,建议在端口进入就绪状态后发送:


case APP_EVT_PD_PORT_STATUS_UPDATE:
    if (port == PORT_0 && dpm_get_info(port)->cur_port_type == PRT_TYPE_DFP) {
        // 延迟发送(例如 100ms),确保状态稳定
        start_timer(port, TIMER_DR_SWAP, 100);
    }
    break;

case APP_EVT_TIMER_EXPIRY:
    if (timer_id == TIMER_DR_SWAP) {
        dpm_pd_command(port, DPM_CMD_SEND_DR_SWAP, NULL, NULL);
    }
    break;



4. 处理命令回调


注册回调函数处理 DR_SWAP 的响应:


case APP_EVT_PD_COMMAND_COMPLETE:
    if (cmd == DPM_CMD_SEND_DR_SWAP) {
        if (status == CY_PD_STAT_SUCCESS) {
            // 交换成功,更新本地数据角色
        } else {
            // 处理失败(如重试或回退)
        }
    }
    break;



5. 调试与日志



  • 启用调试输出:在 app_handler.c 中启用 CY_PD_LOG_MSG,观察 DR_SWAP 是否被发送及响应状态。

  • 硬件监控:使用协议分析仪(如 Ellisys、LeCroy)抓取 PD 报文,确认 DR_SWAP 请求是否发出及对方响应。




6. 关键代码示例


// 在 app_handler.c 中添加以下逻辑
case APP_EVT_PD_PORT_STATUS_UPDATE:
    if (port == PORT_0 && dpm_get_info(port)->cur_port_type == PRT_TYPE_DFP) {
        const dpm_port_partner_info_t *partner_info = dpm_get_partner_info(port);
        if (partner_info && (partner_info->flags & DPM_PARTNER_FLAG_DATA_SWAP)) {
            // 避免频繁重试,可添加重试计数器
            static uint8_t retry_count = 0;
            if (retry_count < 3) {
                dpm_pd_command(port, DPM_CMD_SEND_DR_SWAP, dr_swap_callback, NULL);
                retry_count++;
            }
        }
    }
    break;

// 回调函数示例
void dr_swap_callback(uint8_t port, cy_en_pd_status_t status, void *context) {
    if (status == CY_PD_STAT_SUCCESS) {
        CY_PD_LOG_MSG("DR_SWAP success on port %dn", port);
    } else {
        CY_PD_LOG_MSG("DR_SWAP failed (status=0x%x)n", status);
    }
}



常见问题排查



  1. 对方设备不支持 DR_SWAP:通过日志或协议分析仪确认对方 PDO 是否包含 DataSwap 标志。

  2. 电源角色冲突:若 PORT0 是 Source,某些设备可能拒绝切换为 UFP,需测试不同设备兼容性。

  3. 配置工具未启用 DR_SWAP:重新生成代码前务必保存配置。


通过以上步骤,应能正确触发 DR_SWAP 并实现 PORT0 切换为 UFP。如仍失败,建议提供协议日志进一步分析。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分