From 938920ec93f74fd4bb5082aa5c184fe79341f695 Mon Sep 17 00:00:00 2001 From: wrh Date: Mon, 28 Sep 2026 11:46:27 +0800 Subject: [PATCH] fix sink protocol switch reset delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改了Sink切换协议流程:当前为主动复位,收到复位回码后断开继电器并延时100ms,再恢复继电器并设置协议。 --- apps/chrg/applications/thread/chrg_comm.c | 35 ++++-- apps/chrg/applications/thread/chrg_north.c | 4 +- apps/chrg/applications/thread/chrg_roll_nor.c | 75 +++++++++---- apps/chrg/applications/thread/chrg_roll_nor.h | 34 ++---- apps/chrg/applications/utils/chrg_def.h | 5 +- apps/chrg/applications/utils/chrg_sink.c | 41 ++++--- apps/chrg/applications/utils/chrg_sink.h | 5 +- docs/修改日志.md | 18 ++++ docs/负载流程.md | 101 ++++++++++++++++++ 9 files changed, 246 insertions(+), 72 deletions(-) create mode 100644 docs/负载流程.md diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index 2836911..5b3a06d 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -1,7 +1,6 @@ /**************************************************************************** 文件名称 : chrg_comm.c 完成日期 : -当前版本号 : V1.1.39 主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。 版本历史 : 创建原始版本 说明 : @@ -27,7 +26,7 @@ #include "stm32f4xx_hal.h" #define HOLD_REG_FIRMWARE_VERSION 0x0300U /* 协议板固件版本,只读 */ -#define CHRG_FIRMWARE_VERSION 0x0137U /* 当前协议板版本:V1.1.39 */ +#define CHRG_FIRMWARE_VERSION 0x0139U /* 当前协议板版本:V1.1.41 */ rt_uint8_t ucDiscInBuf[(TOTAL_DISC_REGS+BITS_UCHAR-1)/BITS_UCHAR]; @@ -2648,6 +2647,7 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch, rt_uint16_t old_loadc = pReal->sink.loadc; rt_uint8_t old_on_work = pReal->sink.On_work; rt_uint8_t old_work_mode = pReal->sink.work_mode; + rt_uint8_t target_sub; rt_bool_t old_test_or_load_active; rt_uint16_t sink_work = pShadow->sink.Now_State; chrg_param_diff_t diff_info; @@ -2671,6 +2671,14 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch, (old_work_mode == SINK_WORK_STOP_RELAY_WAIT))) { return MB_EX_SLAVE_BUSY; } + /* Sink Reset和继电器断开等待是一个不可覆盖的事务。 + * 相同请求视为重发成功,不同配置返回忙并由PC稍后重试。 */ + if ((sink_work == 0x01) && + ((pReal->sub == IDX_SET_SINK_RESET) || + (pReal->sub == IDX_WAIT_SINK_RESET_RELAY))) { + return chrg_comm_sink_config_equal(pReal, pShadow) ? + MB_EX_NONE : MB_EX_SLAVE_BUSY; + } chrg_comm_get_param_diff(ID_SINK, pReal, pShadow, &diff_info); /* * 协议类型、CC和协议组号变化需要完整握手;协议电压和协议电流 @@ -2755,14 +2763,22 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch, */ if (diff_info.cc_changed && protocol_data_changed) { /* Protocol-before-CC test flow is disabled in this version. */ - pReal->sub = diff_info.cv_changed ? + target_sub = diff_info.cv_changed ? IDX_SET_SINK_CC_BEFORE_PD_WITH_MODE : IDX_SET_SINK_CC_BEFORE_PD; } else if (diff_info.cc_changed) { - pReal->sub = IDX_SET_SINK_CCLINE; + target_sub = IDX_SET_SINK_CCLINE; } else { - pReal->sub = diff_info.cv_changed ? - IDX_SET_SINK_PD_WITH_MODE : IDX_SET_SINK_PD_ONLY; + target_sub = diff_info.cv_changed ? + IDX_SET_SINK_PD_WITH_MODE : IDX_SET_SINK_PD; + } + /* 仅协议类型变化需先复位Sink协议板;组号、CC、 + * 协议电压/电流和模式变化都不触发Reset。 */ + if (diff_info.protocol_changed) { + chrg_roll_nor_sink_reset_prepare(ch, target_sub); + pReal->sub = IDX_SET_SINK_RESET; + } else { + pReal->sub = target_sub; } pReal->sink.work_mode = SINK_WORK_HANDSHAKE_PREPARE; } else if (protocol_voltage_only || protocol_current_change) { @@ -2772,7 +2788,7 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch, * 则等待实际电流降到安全范围后再重发协议。 */ pReal->sub = diff_info.cv_changed ? - IDX_SET_SINK_PD_WITH_MODE : IDX_SET_SINK_PD_ONLY; + IDX_SET_SINK_PD_WITH_MODE : IDX_SET_SINK_PD; if (old_work_mode == SINK_WORK_LOAD_STANDBY) { pReal->sink.work_mode = SINK_WORK_WAIT; } else { @@ -2790,6 +2806,8 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch, return MB_EX_SLAVE_BUSY; } } else { + /* 停止优先:取消Reset计时,不在此处重新接通北向继电器。 */ + chrg_roll_nor_sink_reset_cancel(ch); pReal->sink.On_work = 0; /* 组合控制或上位机重发可能在关机尚未完成时再次提交OFF。 * 此时必须保留当前停止阶段,不能重新进入STOP并清零低电流确认次数, @@ -3072,8 +3090,9 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, g_shadow_dirty[ch] = 0; if (old_id != new_id) { pNOR->config_version[ch]++; - /* 角色切换时清除旧Source协议切换的等待上下文。 */ + /* 角色切换时清除旧协议切换的等待上下文。 */ chrg_roll_nor_source_switch_reset(ch); + chrg_roll_nor_sink_reset_cancel(ch); rt_memcpy(pReal, pSW, sizeof(struct chrg_switch_t)); if (new_id == ID_SOURCE) { /* 角色重新切到Source后,首个协议命令不需要复位。 */ diff --git a/apps/chrg/applications/thread/chrg_north.c b/apps/chrg/applications/thread/chrg_north.c index 888a245..9cf20ed 100644 --- a/apps/chrg/applications/thread/chrg_north.c +++ b/apps/chrg/applications/thread/chrg_north.c @@ -1,7 +1,6 @@ /**************************************************************************** 文件名称 : chrg_north.c 完成日期 : -当前版本号 : V1.1.39 主要功能 : 实现北向通信交互,包括接收命令解析,发送请求命令,切换通路。以独立线程处理。 版本历史 : 创建原始版本 说明 : @@ -206,7 +205,7 @@ void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx, (void)chrg_source_parse(frame_data, idx, pSW, pNOR); }else if(pSW->source.On_Flag == 0){ //chrg_source_stop(frame_data,pSW,idx,&pNOR->enable[idx]); - pSW->sub = IDX_SET_SOURCE_STOP_STATE; + pSW->sub = IDX_GET_SOURCE_VC; } } @@ -429,6 +428,7 @@ static rt_bool_t chrg_north_frame_shape_valid(eIDX_ID id, if (id == ID_SINK) { switch (command) { + case SINK_CMD_RESET: case SINK_CMD_SET_CC: case SINK_CMD_SET_LEVEL: case SINK_CMD_SET_QC20: diff --git a/apps/chrg/applications/thread/chrg_roll_nor.c b/apps/chrg/applications/thread/chrg_roll_nor.c index 30c128d..e7125b4 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.c +++ b/apps/chrg/applications/thread/chrg_roll_nor.c @@ -1,7 +1,6 @@ /**************************************************************************** 文件名称 : chrg_roll_nor.c 完成日期 : -当前版本号 : V1.1.39 主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。 版本历史 : 创建原始版本 说明 : @@ -33,6 +32,7 @@ #define NORTH_POLL_INTERVAL_MS 10U // 一个通道事务结束后到下一通道的轮询间隔 #define SOURCE_PROTOCOL_WAIT_MS 100U // 每通道0xD0应答后的协议生效保护时间 #define SINK_CC_WAIT_MS 50U // Sink设置目标CC应答后的非阻塞保护时间 +#define SINK_RESET_RELAY_WAIT_MS 100U // Sink复位回码后北向继电器断开时间 #define SINK_HANDSHAKE_FIRST_QUERY_DELAY_MS 50U // 协议/CC回码后首条0x20的等待时间 #define SINK_HANDSHAKE_QUERY_INTERVAL_MS 50U // 握手未完成时后续0x20查询间隔 #define SOURCE_CHANNEL_BIT(ch) ((rt_uint8_t)(1U << (ch))) @@ -55,6 +55,9 @@ static rt_uint8_t g_source_protocol_wait_mask = 0U; static rt_tick_t g_source_protocol_wait_start[TOTAL_NOR_CHS] = {0}; static rt_uint8_t g_sink_cc_wait_mask = 0U; static rt_tick_t g_sink_cc_wait_start[TOTAL_NOR_CHS] = {0}; +static rt_uint8_t g_sink_reset_wait_mask = 0U; +static rt_tick_t g_sink_reset_wait_start[TOTAL_NOR_CHS] = {0}; +static rt_uint8_t g_sink_reset_next_sub[TOTAL_NOR_CHS] = {0}; /* Sink协议/CC握手期间的0x20查询节流记录,按通道独立计时。 */ static rt_bool_t g_sink_query_throttle[TOTAL_NOR_CHS] = {RT_FALSE}; static rt_bool_t g_sink_query_first_pending[TOTAL_NOR_CHS] = {RT_FALSE}; @@ -116,6 +119,26 @@ void chrg_roll_nor_source_switch_reset(rt_uint8_t ch) g_source_protocol_wait_start[ch] = 0U; } +void chrg_roll_nor_sink_reset_prepare(rt_uint8_t ch, rt_uint8_t next_sub) +{ + if (ch >= TOTAL_NOR_CHS) { + return; + } + g_sink_reset_wait_mask &= (rt_uint8_t)~SOURCE_CHANNEL_BIT(ch); + g_sink_reset_wait_start[ch] = 0U; + g_sink_reset_next_sub[ch] = next_sub; +} + +void chrg_roll_nor_sink_reset_cancel(rt_uint8_t ch) +{ + if (ch >= TOTAL_NOR_CHS) { + return; + } + g_sink_reset_wait_mask &= (rt_uint8_t)~SOURCE_CHANNEL_BIT(ch); + g_sink_reset_wait_start[ch] = 0U; + g_sink_reset_next_sub[ch] = 0U; +} + /***************************************************************** 函数名称: chrg_roll_nor_source_cc_close_register 函数描述: 将Source通道登记到本轮共享CC_CLOSE等待屏障 @@ -224,6 +247,7 @@ static rt_bool_t chrg_roll_nor_sink_wait_process(rt_uint8_t ch, } if ((pSW->id != ID_SINK) || !pSW->sink.On_work) { + chrg_roll_nor_sink_reset_cancel(ch); g_sink_cc_wait_mask &= (rt_uint8_t)~bit; g_sink_cc_wait_start[ch] = 0U; g_sink_query_throttle[ch] = RT_FALSE; @@ -231,6 +255,25 @@ static rt_bool_t chrg_roll_nor_sink_wait_process(rt_uint8_t ch, g_sink_query_tick[ch] = 0U; return RT_FALSE; } + + if (pSW->sub == IDX_WAIT_SINK_RESET_RELAY) { + if ((g_sink_reset_wait_mask & bit) == 0U) { + /* 上下文异常丢失时重发Reset,禁止直接跳过断开时序。 */ + pSW->sub = IDX_SET_SINK_RESET; + return RT_TRUE; + } + elapsed = (rt_tick_t)(rt_tick_get() - + g_sink_reset_wait_start[ch]); + if (elapsed < rt_tick_from_millisecond(SINK_RESET_RELAY_WAIT_MS)) { + return RT_TRUE; + } + g_sink_reset_wait_mask &= (rt_uint8_t)~bit; + g_sink_reset_wait_start[ch] = 0U; + chrg_nor_sw_rel((eIDX_NOR_CH)ch, ID_SINK); + pSW->sub = g_sink_reset_next_sub[ch]; + g_sink_reset_next_sub[ch] = 0U; + return RT_TRUE; + } /* 普通软卸载和低电流恢复仍禁止北向;INIT_AUX_WAIT允许南北向并行。 */ if ((pSW->sink.work_mode == SINK_WORK_UNLOAD_WAIT) || (pSW->sink.work_mode == SINK_WORK_LOW_AUX_WAIT)) { @@ -571,12 +614,10 @@ static rt_uint8_t chrg_roll_nor_expected_cmd(const struct chrg_switch_t *pSW) return SINK_CMD_GET_VOLTAGE; case IDX_GET_SINK_PD: return SINK_CMD_GET_PD; + case IDX_SET_SINK_RESET: + return SINK_CMD_RESET; case IDX_SET_SINK_PD: - case IDX_SET_SINK_PD_ONLY: case IDX_SET_SINK_PD_WITH_MODE: -#if 0 - case IDX_SET_SINK_PD_BEFORE_CC: -#endif return pSW->sink.protocol; case IDX_SET_SINK_CCLINE: case IDX_SET_SINK_CC_BEFORE_PD: @@ -788,6 +829,9 @@ static int chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW, else if (pSW->id == ID_SINK) { chrg_roll_nor_sw_uart((eIDX_NOR_CH)ch, ID_SINK); switch(pSW->sub){ + case IDX_SET_SINK_RESET: + *next_sub = IDX_WAIT_SINK_RESET_RELAY; + return sink_reset(); case IDX_GET_SINK_VC: //查询 return sink_get_vc(pSW->sink.pro_loadv, pSW->sink.pro_loadc); @@ -809,18 +853,9 @@ static int chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW, /* 只有协议回码确认后,下一轮才允许进入电压查询。 */ *next_sub = IDX_WAIT_SINK_PD_ACK; return chrg_roll_nor_sink_pro_set(pSW); - case IDX_SET_SINK_PD_ONLY: - *next_sub = IDX_WAIT_SINK_PD_ACK; - return chrg_roll_nor_sink_pro_set(pSW); case IDX_SET_SINK_PD_WITH_MODE: *next_sub = IDX_SET_SINK_MODE_AFTER_PD; return chrg_roll_nor_sink_pro_set(pSW); -#if 0 - case IDX_SET_SINK_PD_BEFORE_CC: - /* 协议回码确认后再设置CC,不提前查询电压。 */ - *next_sub = IDX_SET_SINK_CCLINE; - return chrg_roll_nor_sink_pro_set(pSW); -#endif default: return -1; } @@ -921,16 +956,18 @@ static int chrg_roll_nor_auto_request(rt_uint8_t idx, chrg_roll_nor_source_protocol_wait_start(idx); chrg_comm_source_protocol_ack(idx, (rt_uint8_t)pSW->source.protocol); + } else if ((expected_id == ID_SINK) && + (request_sub == IDX_SET_SINK_RESET)) { + /* Reset回码确认后断开D+/D-和CC,每通道独立计时100ms。 */ + chrg_nor_sw_rel((eIDX_NOR_CH)idx, 0); + g_sink_reset_wait_mask |= SOURCE_CHANNEL_BIT(idx); + g_sink_reset_wait_start[idx] = rt_tick_get(); } else if ((expected_id == ID_SINK) && ((request_sub == IDX_SET_SINK_CCLINE) || (request_sub == IDX_SET_SINK_CC_BEFORE_PD) || (request_sub == IDX_SET_SINK_CC_BEFORE_PD_WITH_MODE))) { /* 北向Sink继电器保持接通,仅等待目标CC配置稳定。 */ chrg_roll_nor_sink_cc_wait_start(idx); - } else if ((expected_id == ID_SINK) && - (request_sub == IDX_SET_SINK_PD_ONLY)) { - /* 仅重发协议时没有CC回码作为节流入口,直接启动200ms计时。 */ - chrg_roll_nor_sink_query_wait_start(idx); } /* 业务解析可能主动切换sub,例如掉电恢复后要求重新设置协议。 * 只有sub仍属于本次请求时,才应用请求函数计算出的next_sub。 */ @@ -1149,7 +1186,7 @@ static int sink (int argc, char **argv) if (strcmp(argv[3], "vc") == 0) { if (0 == gset) { - pROLL->sub = IDX_SET_SINK_WORK_STATE; + pROLL->sub = IDX_GET_SINK_VC; } else { ret = -1; rt_kprintf("sink vc can't set.\r\n"); diff --git a/apps/chrg/applications/thread/chrg_roll_nor.h b/apps/chrg/applications/thread/chrg_roll_nor.h index 2886652..13957a6 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.h +++ b/apps/chrg/applications/thread/chrg_roll_nor.h @@ -1,7 +1,6 @@ /**************************************************************************** 文件名称 : chrg_roll_nor.h 完成日期 : -当前版本号 : V1.1.24 主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。 版本历史 : 创建原始版本 说明 : @@ -18,36 +17,22 @@ enum { IDX_GET_SOURCE_VC = 0, IDX_GET_SOURCE_PD, IDX_SET_SOURCE_PD, - IDX_SET_SOURCE_ID, IDX_SET_SOURCE_CC_SET, - IDX_SER_SOURCE_VOLT, - IDX_SER_SOURCE_CURR, - IDX_SET_SOURCE_WORK, IDX_SET_SOURCE_CCLVL, - IDX_SET_SOURCE_CV, - IDX_SET_SOURCE_STOP_STATE, IDX_GET_SINK_VC, IDX_GET_SINK_PD, - IDX_SET_SINK_VOLT, - IDX_SET_SINK_CURR, IDX_SET_SINK_PD, IDX_SET_SINK_CCLINE, IDX_SET_SINK_CCLVL, - IDX_SET_SINK_ID, - IDX_SET_SINK_VOLT_ON, - IDX_SET_SINK_WORK, - IDX_SET_SINK_CV, - IDX_SET_SINK_WORK_STATE, - IDX_SET_SINK_STOP_TEST,//停止负载测试 - IDX_SET_SINK_STORP_WAIT, - /* Source北向事务状态,追加在末尾以保持原有sub数值不变。 */ + /* Source北向事务状态。 */ IDX_SET_SOURCE_RESET, // PD与非PD协议跨类切换前发送Source复位 IDX_WAIT_SOURCE_PROTOCOL, // 0xD0应答后的协议生效等待 - /* Sink北向事务状态追加在末尾,避免改变已有sub数值。 */ - IDX_SET_SINK_PD_ONLY, // 仅重发协议,协议应答后直接查询协商电压 + /* Sink北向事务状态。 */ + IDX_SET_SINK_RESET, // 协议类型切换时复位Sink协议板 + IDX_WAIT_SINK_RESET_RELAY, // 复位回码后断开北向继电器100ms IDX_WAIT_SINK_CC, // CC设置应答后的非阻塞稳定等待 IDX_SET_SINK_CC_BEFORE_PD, // 先设置CC,稳定后再设置协议 IDX_WAIT_SINK_CC_BEFORE_PD, // 等待CC稳定后进入协议设置 @@ -56,10 +41,7 @@ enum { IDX_SET_SINK_CC_BEFORE_PD_WITH_MODE, IDX_WAIT_SINK_CC_BEFORE_PD_WITH_MODE, IDX_SET_SINK_MODE_AFTER_PD, - IDX_WAIT_SINK_MODE_AFTER_PD, -#if 0 - IDX_SET_SINK_PD_BEFORE_CC, // 先设置协议,协议回码后再设置CC -#endif + IDX_WAIT_SINK_MODE_AFTER_PD }; struct chrg_rollnor_t { @@ -119,6 +101,12 @@ extern void roll_nor_set(void); *****************************************************************/ extern void chrg_roll_nor_source_switch_reset(rt_uint8_t ch); +/* 保存Sink复位后应恢复的协议配置状态。 */ +extern void chrg_roll_nor_sink_reset_prepare(rt_uint8_t ch, + rt_uint8_t next_sub); +/* 停止或角色切换时取消未完成的Sink复位等待。 */ +extern void chrg_roll_nor_sink_reset_cancel(rt_uint8_t ch); + #define sink_time 3 #endif diff --git a/apps/chrg/applications/utils/chrg_def.h b/apps/chrg/applications/utils/chrg_def.h index e9f5585..50a88bb 100644 --- a/apps/chrg/applications/utils/chrg_def.h +++ b/apps/chrg/applications/utils/chrg_def.h @@ -1,7 +1,6 @@ /**************************************************************************** 文件名称 : chrg_def.h 完成日期 : -当前版本号 : V1.1.39 主要功能 : 全局宏定义,常量,及结构体。 版本历史 : 创建原始版本 说明 : @@ -15,8 +14,8 @@ /* CHRG application version. Keep this value synchronized with the changelog. */ #define CHRG_VERSION_MAJOR 1U #define CHRG_VERSION_MINOR 1U -#define CHRG_VERSION_PATCH 39U -#define CHRG_VERSION_STRING "V1.1.39" +#define CHRG_VERSION_PATCH 41U +#define CHRG_VERSION_STRING "V1.1.41" /* * Channel polling mode: diff --git a/apps/chrg/applications/utils/chrg_sink.c b/apps/chrg/applications/utils/chrg_sink.c index b86ddfa..ac378ca 100644 --- a/apps/chrg/applications/utils/chrg_sink.c +++ b/apps/chrg/applications/utils/chrg_sink.c @@ -1,7 +1,6 @@ /**************************************************************************** 文件名称 : chrg_sink.c 完成日期 : -当前版本号 : V1.1.37 主要功能 : 北向数据sink请求数据填充及发送。 版本历史 : 创建原始版本 说明 : @@ -27,11 +26,12 @@ #define SINK_INIT_NORTH_RELAY_DELAY_MS 30U // 辅助继电器回码后打开北向继电器的等待时间 #define SINK_TEST_STATUS_RETRY_MAX 3U // 测试态退出确认的连续重发计数上限 -#define SINK_INIT_STAGE_TEST_STOP 0U -#define SINK_INIT_STAGE_TEST_STATUS 1U -#define SINK_INIT_STAGE_AUX_RELAY 2U -#define SINK_INIT_STAGE_DELAY 3U -#define SINK_INIT_STAGE_REST 4U +/* Sink初始化分阶段执行,避免旧测试命令和继电器动作与新握手交叉。 */ +#define SINK_INIT_STAGE_TEST_STOP 0U // 下发WORK_STOP,退出Short/OCP/DYNA测试 +#define SINK_INIT_STAGE_TEST_STATUS 1U // 读取新量测,确认功率板测试状态已经退出 +#define SINK_INIT_STAGE_AUX_RELAY 2U // 切换负载角色并设置南向辅助继电器 +#define SINK_INIT_STAGE_DELAY 3U // 辅助继电器回码后等待30ms,再接通北向继电器 +#define SINK_INIT_STAGE_REST 4U // 下发电流、模式和V_ON等剩余初始化参数 static rt_uint8_t g_sink_init_stage[TOTAL_SOU_CHS] = {0}; static rt_tick_t g_sink_init_north_relay_tick[TOTAL_SOU_CHS] = {0}; @@ -147,16 +147,6 @@ static void chrg_sink_unload_confirm_reset(eIDX_SOU_CH idx) g_sink_unload_confirm_count[idx] = 0U; } -/***************************************************************** -函数名称: chrg_sink_handshake_north_ready -函数描述: 判断完整握手的南向安全批次是否已经执行完成 -输入参数: idx:南向功率板通道 -输出参数: - -返回说明: RT_TRUE:辅助继电器命令已完成并已建立低电流量测基线 - RT_FALSE:南向安全批次仍在执行 -其它说明: 基线建立后返回成功,实际低电流确认仍由当前状态函数继续执行; - 用于允许北向协议/CC与南向低电流确认并行推进 -*****************************************************************/ /***************************************************************** 函数名称: chrg_sink_unload_query_submit 函数描述: 按最小间隔提交当前通道的一次性P1量测请求 @@ -184,6 +174,24 @@ static int chrg_sink_unload_query_submit(eIDX_SOU_CH idx, rt_bool_t force) g_sink_unload_query_tick[idx] = now; return 0; } +/***************************************************************** +函数名称: sink_reset +函数描述: 复位Sink协议板 +输入参数: - +输出参数: - +返回说明: <0:发送失败 >0:发送长度 +其它说明: 固定帧为05 00 01 01 42 +*****************************************************************/ +int sink_reset(void) +{ + rt_uint16_t len = 0; + rt_uint8_t frame[8] = {0}; + + chrg_north_pkg_encode(ID_SINK, SINK_CMD_RESET, RT_NULL, 0, + frame, &len); + return chrg_north_send(frame, len); +} + /***************************************************************** 函数名称: sink_get_vc 函数描述: sink电压电流查询请求 @@ -424,6 +432,7 @@ static int chrg_sink_work_init_aux_wait(eIDX_SOU_CH idx, g_sink_init_north_relay_tick[idx]) < 0) { return 0; } + //打开北向Sink继电器 chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SINK); #if SOUTH_COMMAND_DEBUG rt_kprintf("-------D+D- OPEN------\n"); diff --git a/apps/chrg/applications/utils/chrg_sink.h b/apps/chrg/applications/utils/chrg_sink.h index 49d28bf..b9083e6 100644 --- a/apps/chrg/applications/utils/chrg_sink.h +++ b/apps/chrg/applications/utils/chrg_sink.h @@ -1,7 +1,6 @@ /**************************************************************************** 文件名称 : chrg_sink.c 完成日期 : -当前版本号 : V1.1.24 主要功能 : 北向数据sink请求数据填充及发送,命令字定义。 版本历史 : 创建原始版本 说明 : @@ -71,6 +70,7 @@ struct test }; #define SINK_CMD_GET_VOLTAGE 0x20 // 读取变电压板电压 +#define SINK_CMD_RESET 0x01 // 复位Sink协议板 struct sink_vc_t { @@ -366,6 +366,9 @@ struct chrg_sink_t { *****************************************************************/ extern int sink_get_vc (rt_uint16_t vol, rt_uint16_t cur); +/* 发送Sink协议板复位命令:05 00 01 01 42。 */ +extern int sink_reset(void); + /***************************************************************** 函数名称: sink_get_pd 函数描述: sink pd 协议查询请求 diff --git a/docs/修改日志.md b/docs/修改日志.md index f16e6a5..add4eba 100644 --- a/docs/修改日志.md +++ b/docs/修改日志.md @@ -1,5 +1,23 @@ # 修改日志 +## V1.1.41 - 2026-09-28 + +### Sink协议类型切换复位时序 + +- Sink协议类型变化并完成低电流确认后,先发送 `05 00 01 01 42` 并等待相同回码。 +- Reset回码后断开该通道D+/D-和CC继电器100ms,再恢复Sink路径并继续CC/协议设置。 +- 协议组号、协议电压/电流、模式和仅CC变化不触发Reset。 +- 协议板版本寄存器 `0x0300` 更新为 `0x0139`。 + +## V1.1.40 - 2026-09-28 + +### 清理北向轮询旧状态 + +- 删除北向轮询中没有发送处理分支的遗留 `sub` 枚举。 +- 合并行为相同的 `IDX_SET_SINK_PD_ONLY` 与 `IDX_SET_SINK_PD`。 +- Sink手动电压查询及停止后的空闲状态统一使用现有电压查询状态。 +- 协议板版本寄存器 `0x0300` 更新为 `0x0138`。 + ## V1.1.39 - 2026-09-24 ### 北向事务隔离逻辑注释 diff --git a/docs/负载流程.md b/docs/负载流程.md new file mode 100644 index 0000000..204c3f5 --- /dev/null +++ b/docs/负载流程.md @@ -0,0 +1,101 @@ +# 负载流程 + +本文按当前代码记录每个通道的实际指令流向。南向为功率板 Modbus 指令;北向为协议板命令。每条南向批次和北向配置命令均需收到匹配回码后才能推进对应阶段。 + +## 负载初始化 + +```text +上位机 PARAM_EFFECT(负载启动) + -> Sink INIT + -> 取消本通道未完成南向批次 + -> [功率板仍在 Short/OCP/DYNA 测试] + 南向:REG_WORK = WORK_STOP + 南向:读取新量测,确认测试态已退出;未退出则重发 WORK_STOP + -> 南向:REG_ELOAD = ELOAD_LOAD + -> 南向:REG_REL_ON = FU_REL_ON + (原测试为 Short 时,先 ALL_REL_OFF,再 FU_REL_ON) + -> 等待上述南向批次回码 + -> 等待 30ms + -> 北向继电器:chrg_nor_sw_rel(ch, ID_SINK) + 接通该通道的 D+/D-、CC Sink 路径 + -> 使能北向轮询 + -> 南向:REG_CURRENT_OUT + 1 = 0 + -> 南向:REG_MODE = CV_mode + -> 南向:Eload_Start_V_ON = max(V_ON, 500mV) + -> 北向:设置目标 CC + -> 等待 CC 回码后 50ms + -> 北向:设置负载协议(0xD0) + -> 等待协议回码;首条 0x20 延后 50ms + -> 北向:0x20 查询协商电压/电流 + -> 电压满足 V_ON 后,南向进入 RUNING,提交主继电器、电流和 WORK_START +``` + +说明:初始化最后一组南向参数与北向 CC/协议握手允许并行。北向在辅助继电器回码并等待 30ms 后已经开始,不能把“剩余南向参数完成”误认为“北向尚未开始”。 + +## 运行中切换协议 + +### 只修改协议电压或协议电流 + +```text +上位机 PARAM_EFFECT + -> 南向:REG_WORK = WORK_STOP + -> 南向:Eload_Start_V_ON = max(V_ON, 500mV) + -> 等待南向回码 + -> 北向:优先读取功率板量测,连续两帧实际电流 <= 200mA + -> 北向:设置负载协议(0xD0) + -> 等待协议回码 + -> 首条 0x20 等待 50ms,后续未稳定期间每 50ms 查询一次 + -> 电压满足条件后按公共 RUNING 路径恢复带载 +``` + +此路径不操作南向主/副继电器,也不关闭北向 D+/D-、CC 继电器。 + +### 修改协议类型、协议组号或 CC + +```text +上位机 PARAM_EFFECT + -> 取消本通道尚未发送的旧南向批次 + -> 南向:REG_WORK = WORK_STOP + -> 南向:Eload_Start_V_ON = max(V_ON, 500mV) + -> 等待南向回码,并连续两帧确认实际电流 <= 200mA + -> [协议类型变化] + 北向:Sink Reset(05 00 01 01 42) + 等待完全相同的Reset回码 + 北向继电器:chrg_nor_sw_rel(ch, 0),断开D+/D-和CC + 每通道非阻塞等待100ms + 北向继电器:chrg_nor_sw_rel(ch, ID_SINK),恢复Sink路径 + -> [CC变化] + 北向:设置目标 CC + 等待 CC 回码后 50ms + -> [协议或组号变化] + 北向:设置负载协议(0xD0) + -> [CV_mode变化] + 南向:REG_MODE = CV_mode,并等待南向回码 + -> 北向:首条 0x20 延后 50ms,后续每 50ms 查询协商结果 + -> 电压满足 V_ON 后恢复 RUNING +``` + +Reset只在协议类型变化时执行。协议组号、协议电压、协议电流、CV/CC模式或仅CC变化都不执行Reset。CC 和协议同时变化时,Reset及继电器时序完成后,顺序固定为“先 CC,等待 50ms,再协议”。仅 CC 变化时,CC 稳定后直接进入 0x20 查询;仅组号变化时不重复设置未变化的 CC。 + +## 停止负载 + +```text +上位机停止 + -> 南向:REG_WORK = WORK_STOP + -> [原 Short 测试] 南向:停止 Short/DYNA 命令 + -> 等待南向回码,并连续两帧确认实际电流 <= 200mA + -> 南向:关闭功率板继电器 + -> 等待南向回码 + -> 北向继电器断开:chrg_nor_sw_rel(ch, 0) + -> 禁用北向轮询,进入 WAIT +``` + +## 当前延时参数 + +| 位置 | 当前值 | 起点 | +| --- | ---: | --- | +| 辅助继电器后接通北向继电器 | 30ms | 辅助继电器批次成功回码后 | +| Sink Reset后断开北向继电器 | 100ms | Sink Reset回码后 | +| CC 设置稳定 | 50ms | 北向 CC 回码后 | +| 协议回码后的首条 0x20 | 50ms | 协议回码后 | +| 握手未完成时 0x20 间隔 | 50ms | 上一次查询计时点 |