diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index fcb73a1..c1e7eaa 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -2474,16 +2474,24 @@ static rt_bool_t chrg_comm_handle_sink_load_current( if (old_work_mode == SINK_WORK_LOAD_STANDBY) { if (should_start) { - /* 独立入口可避开RUNING相同状态去重,并执行完整继电器启动。 */ - pReal->sink.work_mode = SINK_WORK_LOAD_START; + /* + * 低电流待机恢复带载时,不允许由COM直接打开电子负载。 + * 先强制回到北向电压查询入口,确认实际电压稳定后再进入RUNING开载。 + */ + pReal->sub = IDX_GET_SINK_VC; + pReal->sink.work_mode = SINK_WORK_WAIT; } return RT_TRUE; } if (old_work_mode == SINK_WORK_LOAD_SOFT_STANDBY) { if (should_start) { - /* 继电器和协议保持不变,只恢复目标电流和WORK_START。 */ - pReal->sink.work_mode = SINK_WORK_LOAD_RESUME; + /* + * 软待机恢复同样必须先读取北向实际电压。 + * 电压稳定后由解析流程进入SOFT_RESUME,再下发目标电流和WORK_START。 + */ + pReal->sub = IDX_GET_SINK_VC; + pReal->sink.work_mode = SINK_WORK_SOFT_RESUME_WAIT; } return RT_TRUE; } diff --git a/apps/chrg/applications/thread/chrg_north.c b/apps/chrg/applications/thread/chrg_north.c index 3c5622d..3ecbaeb 100644 --- a/apps/chrg/applications/thread/chrg_north.c +++ b/apps/chrg/applications/thread/chrg_north.c @@ -29,7 +29,8 @@ #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 5U // Sink一帧有效稳定电压即进入RUNING +#define SINK_VOLT_STABLE_ERROR_MV 2000U // Sink实际电压与协议目标电压的最大允许误差 +#define SINK_VOLT_STABLE_CONFIRM_COUNT 3U // Sink连续有效稳定电压帧数达到此值后进入RUNING /***************************************************************** 函数名称: chrg_source_apply_protocol_voltage_rule @@ -56,6 +57,31 @@ static rt_uint16_t chrg_source_apply_protocol_voltage_rule( return volt_mv; } +/***************************************************************** +函数名称: chrg_sink_voltage_is_stable +函数描述: 判断北向返回的Sink实际电压是否已进入协议目标电压允许范围 +输入参数: actual_volt_mv:北向返回的实际电压(mV) + target_volt_mv:当前协议申请的目标电压(mV) +输出参数: - +返回说明: RT_TRUE:实际电压与目标电压差值不大于允许误差 + RT_FALSE:实际电压尚未到达目标范围或仍保留旧协议电压 +其它说明: 使用差值的绝对值比较,避免只判断下限时将20V残压误判为5V已稳定 +*****************************************************************/ +static rt_bool_t chrg_sink_voltage_is_stable(rt_uint16_t actual_volt_mv, + rt_uint16_t target_volt_mv) +{ + rt_uint16_t voltage_error_mv; + + if (actual_volt_mv >= target_volt_mv) { + voltage_error_mv = actual_volt_mv - target_volt_mv; + } else { + voltage_error_mv = target_volt_mv - actual_volt_mv; + } + + return (voltage_error_mv <= SINK_VOLT_STABLE_ERROR_MV) ? + RT_TRUE : RT_FALSE; +} + /***************************************************************** 函数名称: chrg_source_voltage_control 函数描述: 根据目标电压与实际电压统一控制Source电压下发和重试 @@ -220,7 +246,7 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx, if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机 volt_stable_count[idx] = 0; if (volt_set_ok[idx] == 1) { - if (++volt_low[idx] >= 100) { + if (++volt_low[idx] >= 20) { volt_set_ok[idx] = 0; no_curr[idx] = 0; pSW->sink.work_mode = SINK_WORK_LOW; @@ -244,7 +270,8 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx, volt_stable_count[idx] = 0; no_curr[idx] = 0; } - else if ((rt_uint32_t)volt_mv + 2000 >= pSW->sink.pro_loadv) { + else if (chrg_sink_voltage_is_stable(volt_mv, + 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) && @@ -257,7 +284,8 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx, * 电压附近后立即进入RUNING,不再增加额外稳定等待。 */ volt_stable_count[idx] = 0; pSW->sink.work_mode = - (pSW->sink.work_mode == SINK_WORK_SOFT_RESUME_WAIT) ? + ((pSW->sink.work_mode == SINK_WORK_SOFT_RESUME_WAIT) || + (pSW->sink.work_mode == SINK_WORK_LOAD_RESUME)) ? SINK_WORK_SOFT_RESUME : SINK_WORK_RUNING; running_start_tick[idx] = rt_tick_get(); no_curr[idx] = 0; diff --git a/apps/chrg/applications/thread/chrg_roll_sou.c b/apps/chrg/applications/thread/chrg_roll_sou.c index c9c26e7..5b4a706 100644 --- a/apps/chrg/applications/thread/chrg_roll_sou.c +++ b/apps/chrg/applications/thread/chrg_roll_sou.c @@ -591,7 +591,7 @@ static int sou_com_batch_complete(rt_uint8_t ch, rt_uint16_t reg, rt_uint16_t va return 0; } -static int sou_com_batch_cancel(rt_uint8_t ch) +int chrg_sou_com_batch_cancel(eIDX_SOU_CH ch) { struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU]; sou_com_batch_ch_t *pBatch; @@ -606,6 +606,8 @@ static int sou_com_batch_cancel(rt_uint8_t ch) pBatch->cur_idx = 0; pBatch->reg_cnt = 0; pBatch->next_send_tick = 0U; + /* 已取消事务对应的优先P1量测同样失效,后续状态会重新申请新量测。 */ + g_sou_measure_once_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch); rt_mutex_release(pTHR->mutex); return 0; } @@ -660,9 +662,46 @@ static void sou_msg_free(struct mb_msg_t **ppMB) *ppMB = RT_NULL; } +/***************************************************************** +函数名称: sou_com_batch_current_matches +函数描述: 判断当前南向批次正在等待的命令是否仍与指定命令一致 +输入参数: ch:南向通道 reg:寄存器地址 value:寄存器值 +输出参数: - +返回说明: RT_TRUE:指定命令仍是该通道当前批次的等待项 + RT_FALSE:批次已取消、已替换或当前等待项不同 +其它说明: 用于忽略取消旧批次后迟到的回码,防止旧回码触发新安全批次重试或取消 +*****************************************************************/ +static rt_bool_t sou_com_batch_current_matches(rt_uint8_t ch, + rt_uint16_t reg, rt_uint16_t value) +{ + struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU]; + sou_com_batch_ch_t *pBatch; + rt_bool_t matched; + + if ((ch >= TOTAL_SOU_CHS) || (RT_NULL == pTHR->mutex) || + (rt_mutex_take(pTHR->mutex, + rt_tick_from_millisecond(SOU_MUTEX_TIMEOUT_MS)) != RT_EOK)) { + return RT_FALSE; + } + + pBatch = &g_sou_com_batch.ch[ch]; + matched = (pBatch->pending == RT_TRUE) && + (pBatch->cur_idx < pBatch->reg_cnt) && + (pBatch->reg_list[pBatch->cur_idx] == reg) && + (pBatch->val_list[pBatch->cur_idx] == value); + rt_mutex_release(pTHR->mutex); + return matched; +} + static void sou_com_command_failed(rt_uint8_t ch, rt_uint16_t reg, rt_uint16_t value, const char *reason, rt_uint8_t *retry_count) { + /* 该命令所属批次已被安全状态替换时,迟到回码或超时不得影响新批次。 */ + if (!sou_com_batch_current_matches(ch, reg, value)) { + *retry_count = 0; + return; + } + (*retry_count)++; if (*retry_count < SOU_COM_MAX_ATTEMPTS) { return; @@ -670,7 +709,7 @@ static void sou_com_command_failed(rt_uint8_t ch, rt_uint16_t reg, rt_uint16_t v LOG_E("com batch failed after %d attempts: ch=%d reg=0x%04x value=0x%04x (%s)", SOU_COM_MAX_ATTEMPTS, ch, reg, value, reason); - if (sou_com_batch_cancel(ch) == 0) { + if (chrg_sou_com_batch_cancel((eIDX_SOU_CH)ch) == 0) { *retry_count = 0; } } diff --git a/apps/chrg/applications/thread/chrg_roll_sou.h b/apps/chrg/applications/thread/chrg_roll_sou.h index 4287cf5..f1427b8 100644 --- a/apps/chrg/applications/thread/chrg_roll_sou.h +++ b/apps/chrg/applications/thread/chrg_roll_sou.h @@ -98,7 +98,17 @@ extern void chrg_roll_sou_thread_entry (void *data); extern int chrg_send_sou_upadata_data(const rt_uint8_t *buf, rt_uint16_t leng); extern int chrg_sou_com_batch_add_reg(eIDX_SOU_CH ch, rt_uint16_t reg, rt_uint16_t val); extern int chrg_sou_com_batch_submit(eIDX_SOU_CH ch, const rt_uint16_t *regs, - const rt_uint16_t *vals, rt_uint8_t count); + const rt_uint16_t *vals, rt_uint8_t count); +/***************************************************************** +函数名称: chrg_sou_com_batch_cancel +函数描述: 取消指定通道尚未完成的南向COM批次 +输入参数: ch:南向功率板通道 +输出参数: - +返回说明: 0:批次已取消 <0:参数或互斥锁错误 +其它说明: 已发送到功率板的当前命令无法撤回,但其后续未发送命令将被清除; + 当前命令的迟到回码会按批次已变更处理,不再推进旧批次 +*****************************************************************/ +extern int chrg_sou_com_batch_cancel(eIDX_SOU_CH ch); extern rt_bool_t chrg_sou_com_batch_is_pending(eIDX_SOU_CH ch); /***************************************************************** 函数名称: chrg_sou_com_batch_get_result diff --git a/apps/chrg/applications/utils/chrg_sink.c b/apps/chrg/applications/utils/chrg_sink.c index efcc815..fa6d1f2 100644 --- a/apps/chrg/applications/utils/chrg_sink.c +++ b/apps/chrg/applications/utils/chrg_sink.c @@ -21,8 +21,9 @@ #include "chrg_eload.h" #define SINK_UNLOAD_QUERY_INTERVAL_MS 20U // 卸载期间两次优先量测请求的最小间隔 -#define SINK_UNLOAD_CURRENT_MAX_MA 100U // 判定负载已安全卸载的最大实际电流 +#define SINK_UNLOAD_CURRENT_MAX_MA 200U // 判定负载已安全卸载的最大实际电流 #define SINK_UNLOAD_CONFIRM_COUNT 2U // 连续满足低电流条件的量测帧数 +#define SINK_CLOSE_CURRENT_MA 1000U // 安全关闭阶段写入功率板的电流设定值 /* 卸载确认只接受停止批次成功后产生的新P1量测。 */ static rt_uint32_t g_sink_unload_sample_seq[TOTAL_SOU_CHS] = {0}; @@ -322,8 +323,8 @@ static int chrg_sink_work_init_aux_wait(eIDX_SOU_CH idx, *****************************************************************/ static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) { - rt_uint16_t regs[4] = {REG_REL_ON, REG_REL_ON, 0, REG_WORK}; - rt_uint16_t vals[4] = {FU_REL_ON, ALL_REL_ON, 0, WORK_START}; + rt_uint16_t regs[3] = {REG_REL_ON, 0, REG_WORK}; + rt_uint16_t vals[3] = {ALL_REL_ON, 0, WORK_START}; int ret; if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { @@ -332,14 +333,13 @@ static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW if (!chrg_sink_load_should_start(pSW)) { /* * 北向协议已完成,低电流设定仍需要接通主继电器,使负载通路 - * 处于完整连接状态;但禁止电子负载带载,随后发送WORK_STOP并 - * 清零电流,避免0A或几十mA设定造成启动冲击。 + * 处于完整连接状态;但禁止电子负载带载,仅发送WORK_STOP, + * 不改写电流设定,避免空载待机影响下一次有效电流设置。 */ - rt_uint16_t stop_regs[3] = {REG_REL_ON, REG_WORK, - REG_CURRENT_OUT + 1}; - rt_uint16_t stop_vals[3] = {ALL_REL_ON, WORK_STOP, 0}; + rt_uint16_t stop_regs[2] = {REG_REL_ON, REG_WORK}; + rt_uint16_t stop_vals[2] = {ALL_REL_ON, WORK_STOP}; - ret = chrg_sou_com_batch_submit(idx, stop_regs, stop_vals, 3U); + ret = chrg_sou_com_batch_submit(idx, stop_regs, stop_vals, 2U); if (ret == 0) { pSW->sink.work_mode = SINK_WORK_LOAD_STANDBY; } @@ -353,7 +353,7 @@ static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW regs[2] = REG_CURRENT_OUT + 1; vals[2] = pSW->sink.loadc; } - return chrg_sou_com_batch_submit(idx, regs, vals, 4U); + return chrg_sou_com_batch_submit(idx, regs, vals, 3U); } /***************************************************************** @@ -370,20 +370,18 @@ static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW static int chrg_sink_work_soft_resume(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) { - rt_uint16_t regs[4] = {REG_REL_ON, REG_REL_ON, 0, REG_WORK}; - rt_uint16_t vals[4] = {FU_REL_ON, ALL_REL_ON, 0, WORK_START}; + rt_uint16_t regs[3] = {REG_REL_ON, 0, REG_WORK}; + rt_uint16_t vals[3] = {ALL_REL_ON, 0, WORK_START}; int ret; if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { return -1; } if (!chrg_sink_load_should_start(pSW)) { - /* 软卸载未切继电器,低电流下继续保持原继电器和协议状态。 */ + /* 软卸载未切继电器,低电流下保持原继电器和协议,只关闭电子负载。 */ regs[0] = REG_WORK; vals[0] = WORK_STOP; - regs[1] = REG_CURRENT_OUT + 1; - vals[1] = 0; - ret = chrg_sou_com_batch_submit(idx, regs, vals, 2U); + ret = chrg_sou_com_batch_submit(idx, regs, vals, 1U); if (ret == 0) { pSW->sink.work_mode = SINK_WORK_LOAD_SOFT_STANDBY; } @@ -396,7 +394,7 @@ static int chrg_sink_work_soft_resume(eIDX_SOU_CH idx, regs[2] = REG_CURRENT_OUT + 1; vals[2] = pSW->sink.loadc; } - if (chrg_sou_com_batch_submit(idx, regs, vals, 4U) != 0) { + if (chrg_sou_com_batch_submit(idx, regs, vals, 3U) != 0) { return -1; } pSW->sink.work_mode = SINK_WORK_SOFT_RUNNING; @@ -409,19 +407,19 @@ static int chrg_sink_work_soft_resume(eIDX_SOU_CH idx, 输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体 输出参数: 命令入队成功后进入SINK_WORK_LOAD_SOFT_STANDBY 返回说明: 0:命令提交成功 <0:参数或命令提交失败 -其它说明: 命令顺序固定为WORK_STOP、CURRENT=0;不改变北向协议、CC和 +其它说明: 命令只发送WORK_STOP;不改变北向协议、CC、电流设定和 主副继电器,保证后续恢复有效电流时无需重新协议握手 *****************************************************************/ static int chrg_sink_work_load_stop(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) { - rt_uint16_t regs[2] = {REG_WORK, REG_CURRENT_OUT + 1}; - rt_uint16_t vals[2] = {WORK_STOP, 0}; + rt_uint16_t reg = REG_WORK; + rt_uint16_t val = WORK_STOP; if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { return -1; } - if (chrg_sou_com_batch_submit(idx, regs, vals, 2U) != 0) { + if (chrg_sou_com_batch_submit(idx, ®, &val, 1U) != 0) { return -1; } pSW->sink.work_mode = SINK_WORK_LOAD_SOFT_STANDBY; @@ -434,51 +432,38 @@ static int chrg_sink_work_load_stop(eIDX_SOU_CH idx, 输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体 输出参数: 命令入队成功后进入SINK_WORK_SOFT_RUNNING 返回说明: 0:命令提交成功 <0:参数或命令提交失败 -其它说明: 命令顺序为ALL_REL_ON、目标负载电流、WORK_START;不重新设置 - 协议或CC;低电流待机可能由软卸载进入且主继电器未闭合,恢复时 - 必须先把继电器打开再启动,防止电子负载先于主继电器带载 +其它说明: 本状态只作为待恢复标记,不直接下发WORK_START;必须由北向解析确认 + 实际电压稳定后转入SINK_WORK_SOFT_RESUME,再恢复目标电流和WORK_START *****************************************************************/ static int chrg_sink_work_load_resume(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) { - rt_uint16_t regs[4] = {REG_REL_ON, REG_REL_ON, - REG_CURRENT_OUT + 1, REG_WORK}; - rt_uint16_t vals[4] = {FU_REL_ON, ALL_REL_ON, 0, WORK_START}; - if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL) || !chrg_sink_load_should_start(pSW)) { return -1; } - vals[2] = pSW->sink.loadc; - if (chrg_sou_com_batch_submit(idx, regs, vals, 4U) != 0) { - return -1; - } - pSW->sink.work_mode = SINK_WORK_SOFT_RUNNING; return 0; } /***************************************************************** 函数名称: chrg_sink_work_load_start -函数描述: 从主继电器未打开的低电流待机状态执行完整负载启动 +函数描述: 从主继电器未打开的低电流待机状态等待北向电压稳定后再启动负载 输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体 输出参数: 命令入队成功后进入SINK_WORK_RUNING 返回说明: 0:命令提交成功 <0:参数或命令提交失败 -其它说明: 使用独立入口避开状态机对RUNING的重复状态去重;执行副继电器、 - 全部继电器、目标负载值和WORK_START的标准启动顺序 +其它说明: 本状态只作为待启动标记,不直接下发继电器或WORK_START;必须由北向 + 解析确认实际电压稳定后转入SINK_WORK_RUNING,再执行标准启动顺序 *****************************************************************/ static int chrg_sink_work_load_start(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) { - int ret; - if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { return -1; } - ret = chrg_sink_work_volt_runing(idx, pSW); - if ((ret == 0) && (pSW->sink.work_mode == SINK_WORK_LOAD_START)) { - pSW->sink.work_mode = SINK_WORK_RUNING; + if (!chrg_sink_load_should_start(pSW)) { + return -1; } - return ret; + return 0; } /***************************************************************** @@ -487,7 +472,7 @@ static int chrg_sink_work_load_start(eIDX_SOU_CH idx, 输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体 输出参数: - 返回说明: 0:命令提交成功 非0:命令提交失败 -其它说明: 命令顺序为WORK_STOP、CURRENT=0、ALL_REL_OFF、FU_REL_ON; +其它说明: 命令顺序为WORK_STOP、CURRENT=1000mA、ALL_REL_OFF、FU_REL_ON; ALL_REL_OFF后立即恢复副继电器,为协议板重新得电保留通路 *****************************************************************/ static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) @@ -496,12 +481,16 @@ static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) REG_WORK, REG_CURRENT_OUT + 1, REG_REL_ON, REG_REL_ON }; rt_uint16_t vals[4] = { - WORK_STOP, 0, ALL_REL_OFF, FU_REL_ON + WORK_STOP, SINK_CLOSE_CURRENT_MA, ALL_REL_OFF, FU_REL_ON }; if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { return -1; } + /* 低压保护优先级最高,先丢弃该通道残留的启动或设定命令。 */ + if (chrg_sou_com_batch_cancel(idx) != 0) { + return -1; + } if (chrg_sou_com_batch_submit(idx, regs, vals, 4U) != 0) { return -1; } @@ -609,7 +598,7 @@ static int chrg_sink_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) 输出参数: - 返回说明: 0:命令提交成功 <0:命令提交失败 其它说明: 不操作北向和南向功率继电器;WORK_STOP完成后进入UNLOAD_WAIT, - 连续确认两帧实际电流不大于100mA,才允许北向重配协议并使用软恢复流程 + 连续确认两帧实际电流不大于200mA,才允许北向重配协议并使用软恢复流程 *****************************************************************/ static int chrg_sink_work_protocol_unload(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) { @@ -632,7 +621,8 @@ static int chrg_sink_work_protocol_unload(eIDX_SOU_CH idx, struct chrg_switch_t 输入参数: idx:南向功率板通道 pSW:当前通道控制结构体 输出参数: 命令提交成功后进入SINK_WORK_HANDSHAKE_WAIT 返回说明: 0:四条命令提交成功 <0:参数或命令提交失败 -其它说明: 命令顺序固定为WORK_STOP、CURRENT=0、ALL_REL_OFF、FU_REL_ON; +其它说明: 命令顺序固定为WORK_STOP、CURRENT=1000mA、ALL_REL_OFF、FU_REL_ON; + WORK_STOP已关闭电子负载,1000mA仅为功率板停止阶段保存的电流设定值; 主副继电器全部断开并确认回码后再单独打开副继电器; 北向Sink继电器保持接通,低电流确认完成后才允许重新握手 *****************************************************************/ @@ -643,17 +633,21 @@ static int chrg_sink_work_handshake_prepare(eIDX_SOU_CH idx, REG_WORK, REG_CURRENT_OUT + 1, REG_REL_ON, REG_REL_ON }; rt_uint16_t vals[4] = { - WORK_STOP, 0, ALL_REL_OFF, FU_REL_ON + WORK_STOP, SINK_CLOSE_CURRENT_MA, ALL_REL_OFF, FU_REL_ON }; if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { return -1; } + /* 新CC/协议事务必须抢占本通道尚未发送的旧启动和设定命令。 */ + if (chrg_sou_com_batch_cancel(idx) != 0) { + return -1; + } if (chrg_sou_com_batch_submit(idx, regs, vals, 4) != 0) { return -1; } - /* 四条写回码完成后,还必须连续确认两帧实际电流不大于100mA。 */ + /* 四条写回码完成后,还必须连续确认两帧实际电流不大于200mA。 */ chrg_sink_unload_confirm_reset(idx); pSW->sink.work_mode = SINK_WORK_HANDSHAKE_WAIT; return 0; @@ -661,13 +655,13 @@ static int chrg_sink_work_handshake_prepare(eIDX_SOU_CH idx, /***************************************************************** 函数名称: chrg_sink_work_current_wait -函数描述: 等待负载安全断开批次完成,并连续确认两帧实际电流不大于100mA +函数描述: 等待负载安全断开批次完成,并连续确认两帧实际电流不大于200mA 输入参数: idx:南向功率板通道 pSW:当前通道控制结构体 full_handshake:RT_TRUE为完整重握手 RT_FALSE为协议参数软卸载 输出参数: 确认成功后将sink.work_mode切换为SINK_WORK_WAIT 返回说明: 0:继续等待或确认成功 <0:状态查询或优先量测请求失败 其它说明: 软卸载只要求WORK_STOP收到匹配回码后建立量测基线;完整重握手 - 还要求CURRENT=0、ALL_REL_OFF和FU_REL_ON回码成功,但保持北向Sink继电器接通 + 还要求CURRENT=1000mA、ALL_REL_OFF和FU_REL_ON回码成功,但保持北向Sink继电器接通 *****************************************************************/ static int chrg_sink_work_current_wait(eIDX_SOU_CH idx, struct chrg_switch_t *pSW, rt_bool_t full_handshake) diff --git a/apps/chrg/applications/utils/chrg_sink.h b/apps/chrg/applications/utils/chrg_sink.h index 270e396..cec49ec 100644 --- a/apps/chrg/applications/utils/chrg_sink.h +++ b/apps/chrg/applications/utils/chrg_sink.h @@ -203,7 +203,7 @@ enum { /* * 普通恒流负载允许执行WORK_START的最低设定电流,单位mA。 - * 小于该值时北向仍完成协议握手,但南向保持WORK_STOP且设定电流为0, + * 小于该值时北向仍完成协议握手,但南向保持WORK_STOP且不改写电流设定, * 避免功率板在零电流或几十mA的小电流设定下启动电子负载产生冲击。 */ #define SINK_LOAD_ENABLE_MIN_MA 100U @@ -222,7 +222,7 @@ enum { SINK_WORK_STOP, // 用户主动停止负载 SINK_WORK_SWITCH, // 停止旧电源后进入负载INIT SINK_WORK_PROTOCOL_UNLOAD, // 协议电压或电流变化:掉载但不切换继电器 - SINK_WORK_UNLOAD_WAIT, // 等待软卸载完成并连续两次确认电流不大于100mA + SINK_WORK_UNLOAD_WAIT, // 等待软卸载完成并连续两次确认电流不大于200mA SINK_WORK_SOFT_RESUME_WAIT, // 继电器保持闭合,等待协议电压稳定后恢复负载 SINK_WORK_SOFT_RESUME, // 只恢复目标电流/电压和WORK_START,不写继电器 SINK_WORK_SOFT_RUNNING, // 软恢复后的稳定运行状态,禁止重复切换继电器 @@ -233,9 +233,9 @@ enum { SINK_WORK_HANDSHAKE_WAIT, // 南向低电流确认与北向协议/CC并行 SINK_WORK_LOAD_STANDBY, // 协议已就绪但主继电器未打开,低设定电流下保持停止 SINK_WORK_LOAD_SOFT_STANDBY, // 协议和继电器保持不变,运行中降至低电流后的停止状态 - SINK_WORK_LOAD_STOP, // 运行中跨到低电流:发送WORK_STOP后将设定电流清零 - SINK_WORK_LOAD_START, // 主继电器未打开的低电流待机恢复:执行完整RUNING动作 - SINK_WORK_LOAD_RESUME, // 软待机跨回有效电流:不切继电器,直接恢复电流和WORK_START + SINK_WORK_LOAD_STOP, // 运行中跨到低电流:只发送WORK_STOP关闭电子负载 + SINK_WORK_LOAD_START, // 主继电器未打开的低电流待机恢复:等待北向电压稳定后进入RUNING + SINK_WORK_LOAD_RESUME, // 软待机跨回有效电流:等待北向电压稳定后进入SOFT_RESUME }; // sink 参数结构 diff --git a/docs/修改日志.md b/docs/修改日志.md index e37bb6e..78e638a 100644 --- a/docs/修改日志.md +++ b/docs/修改日志.md @@ -145,6 +145,7 @@ - 低电流待机期间仅修改协议电压时不重复卸载,并保持原有主继电器状态语义。 - 将 COM 端运行电流跨门限判断封装为 `chrg_comm_handle_sink_load_current()`,避免生效分支继续膨胀。 - 北向解析将两种低电流待机状态作为稳定状态,不因实际电流为零反复进入 `RUNING`。 +- 低电流待机恢复有效电流时,`SINK_WORK_LOAD_START`/`SINK_WORK_LOAD_RESUME` 只作为待启动标记,必须等北向实际电压稳定后才下发 `WORK_START`。 ### 涉及文件