diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index 27832af..fcb73a1 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -2383,22 +2383,22 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch, } pReal->sink.test.test_mode_old = curr_test; } else { - pReal->sub = IDX_SET_SINK_PD; + pReal->sub = IDX_SET_SINK_CC_BEFORE_PD; pReal->sink.work_mode = SINK_WORK_INIT; } } else if (pReal->sink.On_work == 0) { pReal->sink.On_work = 1; - pReal->sub = IDX_SET_SINK_PD; + pReal->sub = IDX_SET_SINK_CC_BEFORE_PD; pReal->sink.work_mode = SINK_WORK_INIT; } else if (full_handshake_change) { /* * 只有CC实际变化时才发送目标CC命令并等待;协议类型或组号 * 单独变化时直接重发PD帧,不重复设置未变化的CC。 - * 协议与CC同时变化时先发送协议,协议应答后再设置目标CC; + * 协议与CC同时变化时先设置目标CC,CC稳定后再发送协议; * 仅协议变化时不重复设置未变化的CC。 */ if (diff_info.cc_changed && protocol_data_changed) { - pReal->sub = IDX_SET_SINK_PD; + pReal->sub = IDX_SET_SINK_CC_BEFORE_PD; } else if (diff_info.cc_changed) { pReal->sub = IDX_SET_SINK_CCLINE; } else { diff --git a/apps/chrg/applications/thread/chrg_north.c b/apps/chrg/applications/thread/chrg_north.c index 227d2d1..b60fdd2 100644 --- a/apps/chrg/applications/thread/chrg_north.c +++ b/apps/chrg/applications/thread/chrg_north.c @@ -29,7 +29,7 @@ #define SOURCE_QC_MIN_VOLT_MV 5000U // QC2.0/QC3.0允许使用的最低目标电压 #define SOURCE_QC_SWITCH_ERROR 0x04U // Source协议或CC切换失败错误位 #define SINK_CURRENT_START_GRACE_MS 200U // Sink启动后暂不判断无电流的保护时间 -#define SINK_VOLT_STABLE_CONFIRM_COUNT 0U // Sink一帧有效稳定电压即进入RUNING +#define SINK_VOLT_STABLE_CONFIRM_COUNT 5U // Sink一帧有效稳定电压即进入RUNING /***************************************************************** 函数名称: chrg_source_apply_protocol_voltage_rule @@ -236,14 +236,15 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx, * 当前回码不计入稳定电压次数,防止跳过协议设置直接带载。 */ volt_stable_count[idx] = 0; no_curr[idx] = 0; - pSW->sub = IDX_SET_SINK_PD; + pSW->sub = IDX_SET_SINK_CC_BEFORE_PD; pSW->sink.work_mode = SINK_WORK_WAIT; } else if ((pSW->sink.work_mode == SINK_WORK_LOW) || (pSW->sink.work_mode == SINK_WORK_LOW_AUX_WAIT)) { /* 掉电安全批次完成前,即使收到残留回码也不得进入RUNING。 */ volt_stable_count[idx] = 0; no_curr[idx] = 0; - } else if ((rt_uint32_t)volt_mv + 2000 >= pSW->sink.pro_loadv) { + } + else if ((rt_uint32_t)volt_mv + 2000 >= pSW->sink.pro_loadv) { if ((pSW->sink.work_mode != SINK_WORK_RUNING) && (pSW->sink.work_mode != SINK_WORK_SOFT_RUNNING) && (pSW->sink.work_mode != SINK_WORK_LOAD_STANDBY) && diff --git a/apps/chrg/applications/thread/chrg_roll_nor.c b/apps/chrg/applications/thread/chrg_roll_nor.c index 65cdcc7..a70d980 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.c +++ b/apps/chrg/applications/thread/chrg_roll_nor.c @@ -311,7 +311,8 @@ static rt_bool_t chrg_roll_nor_sink_wait_process(rt_uint8_t ch, } } - if (pSW->sub != IDX_WAIT_SINK_CC) { + if ((pSW->sub != IDX_WAIT_SINK_CC) && + (pSW->sub != IDX_WAIT_SINK_CC_BEFORE_PD)) { /* COM在等待期间提交新配置时,清理旧事务留下的CC计时记录。 */ g_sink_cc_wait_mask &= (rt_uint8_t)~bit; g_sink_cc_wait_start[ch] = 0U; @@ -322,8 +323,12 @@ static rt_bool_t chrg_roll_nor_sink_wait_process(rt_uint8_t ch, } } else { if ((g_sink_cc_wait_mask & bit) == 0U) { - pSW->sub = IDX_GET_SINK_VC; - chrg_roll_nor_sink_query_wait_start(ch); + if (pSW->sub == IDX_WAIT_SINK_CC_BEFORE_PD) { + pSW->sub = IDX_SET_SINK_PD; + } else { + pSW->sub = IDX_GET_SINK_VC; + chrg_roll_nor_sink_query_wait_start(ch); + } return RT_TRUE; } elapsed = (rt_tick_t)(rt_tick_get() - g_sink_cc_wait_start[ch]); @@ -331,6 +336,17 @@ static rt_bool_t chrg_roll_nor_sink_wait_process(rt_uint8_t ch, return RT_TRUE; } + if (pSW->sub == IDX_WAIT_SINK_CC_BEFORE_PD) { + /* CC先设置完成后进入协议设置,不立即查询电压。 */ + g_sink_query_throttle[ch] = RT_FALSE; + g_sink_query_first_pending[ch] = RT_FALSE; + g_sink_query_tick[ch] = 0U; + g_sink_cc_wait_mask &= (rt_uint8_t)~bit; + g_sink_cc_wait_start[ch] = 0U; + pSW->sub = IDX_SET_SINK_PD; + return RT_TRUE; + } + /* 协议已先设置;CC应答并完成保护等待后进入电压查询。 */ g_sink_query_throttle[ch] = RT_TRUE; g_sink_query_first_pending[ch] = RT_TRUE; @@ -591,6 +607,7 @@ static rt_uint8_t chrg_roll_nor_expected_cmd(const struct chrg_switch_t *pSW) case IDX_SET_SINK_PD_ONLY: return pSW->sink.protocol; case IDX_SET_SINK_CCLINE: + case IDX_SET_SINK_CC_BEFORE_PD: return SINK_CMD_SET_CC; case IDX_SET_SINK_CCLVL: return SINK_CMD_SET_LEVEL; @@ -799,10 +816,14 @@ static int chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW, case IDX_SET_SINK_CCLINE: //CC线选择 *next_sub = IDX_WAIT_SINK_CC; return sink_set_cc_line(pSW->sink.cc_set); + case IDX_SET_SINK_CC_BEFORE_PD: + *next_sub = IDX_WAIT_SINK_CC_BEFORE_PD; + return sink_set_cc_line(pSW->sink.cc_set); case IDX_SET_SINK_CCLVL: //CC电平 return sink_set_cc_lvl(pSW->sink.cc_lvl); case IDX_SET_SINK_PD: - *next_sub = IDX_SET_SINK_CCLINE; + /* CC已经在协议前完成设置,协议回码后直接查询电压。 */ + *next_sub = IDX_GET_SINK_VC; return chrg_roll_nor_sink_pro_set(pSW); case IDX_SET_SINK_PD_ONLY: *next_sub = IDX_GET_SINK_VC; @@ -902,7 +923,8 @@ static int chrg_roll_nor_auto_request(rt_uint8_t idx, /* 0xD0应答后每通道独立等待100ms,再连接目标CC。 */ chrg_roll_nor_source_protocol_wait_start(idx); } else if ((expected_id == ID_SINK) && - (request_sub == IDX_SET_SINK_CCLINE)) { + ((request_sub == IDX_SET_SINK_CCLINE) || + (request_sub == IDX_SET_SINK_CC_BEFORE_PD))) { /* 北向Sink继电器保持接通,仅等待目标CC配置稳定。 */ chrg_roll_nor_sink_cc_wait_start(idx); } else if ((expected_id == ID_SINK) && diff --git a/apps/chrg/applications/thread/chrg_roll_nor.h b/apps/chrg/applications/thread/chrg_roll_nor.h index 48e082e..9bdfa66 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.h +++ b/apps/chrg/applications/thread/chrg_roll_nor.h @@ -50,6 +50,8 @@ enum { /* Sink北向事务状态追加在末尾,避免改变已有sub数值。 */ IDX_SET_SINK_PD_ONLY, // 仅重发协议,协议应答后直接查询协商电压 IDX_WAIT_SINK_CC, // CC设置应答后的非阻塞稳定等待 + IDX_SET_SINK_CC_BEFORE_PD, // 先设置CC,稳定后再设置协议 + IDX_WAIT_SINK_CC_BEFORE_PD, // 等待CC稳定后进入协议设置 }; struct chrg_rollnor_t { diff --git a/apps/chrg/applications/utils/chrg_sink.c b/apps/chrg/applications/utils/chrg_sink.c index 8c94d0a..7f694dd 100644 --- a/apps/chrg/applications/utils/chrg_sink.c +++ b/apps/chrg/applications/utils/chrg_sink.c @@ -231,8 +231,8 @@ int sink_set_pd (rt_uint8_t pd, rt_uint8_t *buf) 输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体 输出参数: 立即打开北向Sink继电器和enable,并进入INIT_AUX_WAIT后台确认 返回说明: 0:初始化批次提交成功 <0:参数或命令提交失败 -其它说明: 南向顺序为FU_REL_ON、CURRENT=0、MODE、VON和可选测试停止; - 北向协议握手不等待南向回码,南北向从批次入队后并行执行 + 其它说明: 南向顺序为FU_REL_ON、CURRENT=0、MODE、VON和可选测试停止; + 北向按“CC线->协议->电压查询”顺序执行,南北向从批次入队后并行执行 *****************************************************************/ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) { @@ -267,10 +267,10 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) pSW->sink.On_work = 1; if (first_start) { - /* 南向批次已入队,北向按“协议->CC”顺序立即开始完整握手。 */ + /* 南向批次已入队,北向按“CC->协议”顺序立即开始完整握手。 */ chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SINK); pNOR->enable[idx] = 1; - pSW->sub = IDX_SET_SINK_PD; + pSW->sub = IDX_SET_SINK_CC_BEFORE_PD; } pSW->sink.work_mode = SINK_WORK_INIT_AUX_WAIT; return 0; @@ -592,8 +592,8 @@ static int chrg_sink_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) /* 停止成功入队后,清除旧Source运行标志。 */ pSW->source.On_Flag = 0; - /* 首次进入Sink时先设置协议,协议应答后再设置目标CC线。 */ - pSW->sub = IDX_SET_SINK_PD; + /* 首次进入Sink时先设置目标CC线,CC稳定后再设置协议。 */ + pSW->sub = IDX_SET_SINK_CC_BEFORE_PD; /* SWITCH只负责旧角色退出,后续启动统一交给Sink INIT状态。 */ pSW->sink.work_mode = SINK_WORK_INIT; return 0;