diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index 759c562..e36b42a 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -55,6 +55,28 @@ static rt_tick_t g_ymodem_c_tick = 0; static struct chrg_switch_t g_shadow_sw[TOTAL_NOR_CHS]; static rt_uint8_t g_shadow_dirty[TOTAL_NOR_CHS] = {0}; /* 0=已生效 1=待生效,防止重复覆盖 */ +/* Source协议类别缓存:0xFF表示本通道尚未成功下发过协议。 */ +#define SOURCE_PD_STATE_UNKNOWN 0xFFU +#define SOURCE_PD_STATE_NON_PD 0x00U +#define SOURCE_PD_STATE_PD 0x01U +static rt_uint8_t last_pd_pro[TOTAL_NOR_CHS] = { + SOURCE_PD_STATE_UNKNOWN, SOURCE_PD_STATE_UNKNOWN, + SOURCE_PD_STATE_UNKNOWN, SOURCE_PD_STATE_UNKNOWN +}; + +static rt_uint8_t chrg_comm_source_pd_state(rt_uint8_t protocol) +{ + return ((protocol == PRO_PD0PSS) || (protocol == PRO_PD31AVS)) ? + SOURCE_PD_STATE_PD : SOURCE_PD_STATE_NON_PD; +} + +void chrg_comm_source_protocol_ack(rt_uint8_t ch, rt_uint8_t protocol) +{ + if (ch < TOTAL_NOR_CHS) { + last_pd_pro[ch] = chrg_comm_source_pd_state(protocol); + } +} + /* * Source和Sink共用的参数差异结果。前五项是两个角色都具备的控制属性, * pd_changed用于Source完整协议参数比较,后三项用于Sink快充协议配置。 @@ -2519,9 +2541,8 @@ static eMBException chrg_comm_apply_source_effect(rt_uint8_t ch, rt_bool_t cc_changed; rt_bool_t north_config_changed; rt_bool_t protocol_switch_requested; - rt_bool_t old_is_pd; - rt_bool_t new_is_pd; - rt_bool_t need_cc_close; + rt_bool_t need_source_reset; + rt_uint8_t new_pd_state; struct vc_pd_t old_pd_set; eSRC_PRO old_protocol = pReal->source.protocol; rt_uint8_t old_cc_set = pReal->source.CC_Set; @@ -2546,12 +2567,10 @@ static eMBException chrg_comm_apply_source_effect(rt_uint8_t ch, cc_changed = diff_info.cc_changed; north_config_changed = protocol_config_changed || cc_changed; protocol_switch_requested = north_config_changed; - old_is_pd = (old_protocol == PRO_PD0PSS) || - (old_protocol == PRO_PD31AVS); - new_is_pd = (pShadow->source.protocol == PRO_PD0PSS) || - (pShadow->source.protocol == PRO_PD31AVS); - need_cc_close = (new_is_pd && north_config_changed) || - (old_is_pd && !new_is_pd && diff_info.protocol_changed); + new_pd_state = chrg_comm_source_pd_state( + (rt_uint8_t)pShadow->source.protocol); + need_source_reset = (last_pd_pro[ch] != SOURCE_PD_STATE_UNKNOWN) && + (last_pd_pro[ch] != new_pd_state); target_curr = pShadow->source.pd_set.mm.max_cur; /* 影子区只拥有COM配置;北向解析产生的运行目标和回读数据继续由pReal持有。 */ @@ -2565,6 +2584,8 @@ static eMBException chrg_comm_apply_source_effect(rt_uint8_t ch, if (source_work == 0x01) { if (pReal->source.On_Flag == 0) { + /* 每次重新启动的第一次协议下发不发送复位。 */ + last_pd_pro[ch] = SOURCE_PD_STATE_UNKNOWN; /* * 停止状态启动不需要先断开CC,直接从设置协议开始; * 收到0xD0应答并等待保护时间后,再连接目标CC。 @@ -2585,12 +2606,8 @@ static eMBException chrg_comm_apply_source_effect(rt_uint8_t ch, */ if (north_config_changed) { chrg_roll_nor_source_switch_reset(ch); - if (need_cc_close) { - pReal->sub = IDX_SET_SOURCE_CC_CLOSE; - chrg_roll_nor_source_cc_close_register(ch); - } else { - pReal->sub = IDX_SET_SOURCE_PD; - } + pReal->sub = need_source_reset ? + IDX_SET_SOURCE_RESET : IDX_SET_SOURCE_PD; } pReal->source.work_mode = SOURCE_WORK_WAIT; @@ -2709,6 +2726,8 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, chrg_roll_nor_source_switch_reset(ch); rt_memcpy(pReal, pSW, sizeof(struct chrg_switch_t)); if (new_id == ID_SOURCE) { + /* 角色重新切到Source后,首个协议命令不需要复位。 */ + last_pd_pro[ch] = SOURCE_PD_STATE_UNKNOWN; pReal->source.work_mode = SOURCE_WORK_SWITCH; switch_ret = chrg_source_work_state(ch, pReal); } else { diff --git a/apps/chrg/applications/thread/chrg_comm.h b/apps/chrg/applications/thread/chrg_comm.h index 6a440ea..c1a5b09 100644 --- a/apps/chrg/applications/thread/chrg_comm.h +++ b/apps/chrg/applications/thread/chrg_comm.h @@ -19,6 +19,9 @@ #define MB_HANDLERS_MAX (16) +/* 北向Source协议设置成功后,通知COM保存本通道的PD/非PD类别。 */ +extern void chrg_comm_source_protocol_ack(rt_uint8_t ch, rt_uint8_t protocol); + typedef enum { MB_REG_READ, /*!< Read register values and pass to protocol stack. */ MB_REG_WRITE /*!< Update register values. */ diff --git a/apps/chrg/applications/thread/chrg_north.c b/apps/chrg/applications/thread/chrg_north.c index fffcacf..2e21a6f 100644 --- a/apps/chrg/applications/thread/chrg_north.c +++ b/apps/chrg/applications/thread/chrg_north.c @@ -471,6 +471,7 @@ static rt_bool_t chrg_north_frame_shape_valid(eIDX_ID id, if (id == ID_SOURCE) { if ((command == SRC_CMD_SET_CC_LEVEL) || (command == SRC_CMD_SET_CC_CHOOSE) || + (command == SRC_CMD_RESET) || (command == SRC_CMD_SET_PROTOCOL)) { return (length == MIN_FRAME_LENGTH) ? RT_TRUE : RT_FALSE; } diff --git a/apps/chrg/applications/thread/chrg_north.h b/apps/chrg/applications/thread/chrg_north.h index b3c9a78..532c1aa 100644 --- a/apps/chrg/applications/thread/chrg_north.h +++ b/apps/chrg/applications/thread/chrg_north.h @@ -22,7 +22,7 @@ #define LEN_FRAME_HEAD (4) // [帧长, 0x00, id, 命令] #define MIN_FRAME_LENGTH (5) // 帧最短5字节 #define WORK_MIN_VOLT 3000 // 工作电压下限,单位mV -#define NORTH_FRAME_DEBUG 0x00 // 北向UART原始收发帧 +#define NORTH_FRAME_DEBUG 0x01 // 北向UART原始收发帧 #define NORTH_SOURCE_DEBUG 0x00 // Source协议解析及组帧 #define NORTH_SINK_DEBUG 0x00 // Sink协议解析及组帧 #define SOUTH_FRAME_DEBUG 0x00 // 南向UART原始收发帧 diff --git a/apps/chrg/applications/thread/chrg_roll_nor.c b/apps/chrg/applications/thread/chrg_roll_nor.c index 4e14190..de818e7 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.c +++ b/apps/chrg/applications/thread/chrg_roll_nor.c @@ -18,6 +18,7 @@ #include "chrg_source.h" #include "chrg_roll_nor.h" #include "chrg_roll_sou.h" +#include "chrg_comm.h" #include "chrg_north.h" #include "chrg_switch.h" #include "chrg_utils.h" @@ -31,8 +32,6 @@ #define NORTH_MEASURE_MAX_ATTEMPTS 1U // 0x20量测查询失败后直接留给下一轮轮询重发 #define NORTH_RETRY_INTERVAL_MS 5U // 相同请求两次发送之间的保护间隔 #define NORTH_POLL_INTERVAL_MS 10U // 一个通道事务结束后到下一通道的轮询间隔 -#define SOURCE_CC_CLOSE_VALUE 0x03U // 0x17命令参数:同时断开CC1和CC2 -#define SOURCE_CC_CLOSE_WAIT_MS 300U // 本轮所有CC_CLOSE应答后的共享保护时间 #define SOURCE_PROTOCOL_WAIT_MS 100U // 每通道0xD0应答后的协议生效保护时间 #define SINK_CC_WAIT_MS 50U // Sink设置目标CC应答后的非阻塞保护时间 #define SINK_HANDSHAKE_FIRST_QUERY_DELAY_MS 50U // 协议/CC回码后首条0x20的等待时间 @@ -53,10 +52,6 @@ struct chrg_rollnor_t chrgrollnor = { }; /* 所有参与CC_CLOSE的通道共享300ms屏障;协议等待仍按通道独立计时。 */ -static rt_uint8_t g_source_cc_close_pending_mask = 0U; -static rt_uint8_t g_source_cc_close_acked_mask = 0U; -static rt_bool_t g_source_cc_close_wait_active = RT_FALSE; -static rt_tick_t g_source_cc_close_wait_start = 0U; 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; @@ -114,25 +109,12 @@ static void chrg_roll_nor_sink_query_wait_start(rt_uint8_t ch) *****************************************************************/ void chrg_roll_nor_source_switch_reset(rt_uint8_t ch) { - rt_uint8_t bit; - if (ch >= TOTAL_NOR_CHS) { return; } - bit = SOURCE_CHANNEL_BIT(ch); - g_source_cc_close_pending_mask &= (rt_uint8_t)~bit; - g_source_cc_close_acked_mask &= (rt_uint8_t)~bit; - g_source_protocol_wait_mask &= (rt_uint8_t)~bit; + g_source_protocol_wait_mask &= + (rt_uint8_t)~SOURCE_CHANNEL_BIT(ch); g_source_protocol_wait_start[ch] = 0U; - if (g_source_cc_close_pending_mask == 0U) { - g_source_cc_close_wait_active = RT_FALSE; - g_source_cc_close_wait_start = 0U; - } else if (!g_source_cc_close_wait_active && - ((g_source_cc_close_acked_mask & g_source_cc_close_pending_mask) == - g_source_cc_close_pending_mask)) { - g_source_cc_close_wait_active = RT_TRUE; - g_source_cc_close_wait_start = rt_tick_get(); - } } /***************************************************************** @@ -143,41 +125,6 @@ void chrg_roll_nor_source_switch_reset(rt_uint8_t ch) 返回说明: - 其它说明: 新通道加入已经开始的屏障时重新等待,保证所有登记通道共享完整保护时间 *****************************************************************/ -void chrg_roll_nor_source_cc_close_register(rt_uint8_t ch) -{ - rt_uint8_t bit; - - if (ch >= TOTAL_NOR_CHS) { - return; - } - bit = SOURCE_CHANNEL_BIT(ch); - g_source_cc_close_pending_mask |= bit; - g_source_cc_close_acked_mask &= (rt_uint8_t)~bit; - g_source_protocol_wait_mask &= (rt_uint8_t)~bit; - g_source_cc_close_wait_active = RT_FALSE; - g_source_cc_close_wait_start = 0U; -} - -static void chrg_roll_nor_source_cc_close_ack(rt_uint8_t ch) -{ - rt_uint8_t bit; - - if (ch >= TOTAL_NOR_CHS) { - return; - } - bit = SOURCE_CHANNEL_BIT(ch); - if ((g_source_cc_close_pending_mask & bit) == 0U) { - return; - } - g_source_cc_close_acked_mask |= bit; - if (!g_source_cc_close_wait_active && - ((g_source_cc_close_acked_mask & g_source_cc_close_pending_mask) == - g_source_cc_close_pending_mask)) { - g_source_cc_close_wait_active = RT_TRUE; - g_source_cc_close_wait_start = rt_tick_get(); - } -} - static void chrg_roll_nor_source_protocol_wait_start(rt_uint8_t ch) { if (ch >= TOTAL_NOR_CHS) { @@ -211,23 +158,6 @@ static rt_bool_t chrg_roll_nor_source_wait_process(rt_uint8_t ch, return RT_FALSE; } - if (pSW->sub == IDX_WAIT_SOURCE_CC_CLOSE) { - if ((g_source_cc_close_pending_mask & bit) == 0U) { - pSW->sub = IDX_SET_SOURCE_PD; - return RT_FALSE; - } - if (!g_source_cc_close_wait_active) { - return RT_TRUE; - } - elapsed = (rt_tick_t)(rt_tick_get() - g_source_cc_close_wait_start); - if (elapsed < rt_tick_from_millisecond(SOURCE_CC_CLOSE_WAIT_MS)) { - return RT_TRUE; - } - chrg_roll_nor_source_switch_reset(ch); - pSW->sub = IDX_SET_SOURCE_PD; - return RT_FALSE; - } - if (pSW->sub == IDX_WAIT_SOURCE_PROTOCOL) { if ((g_source_protocol_wait_mask & bit) == 0U) { pSW->sub = IDX_SET_SOURCE_CC_SET; @@ -592,7 +522,8 @@ static rt_uint8_t chrg_roll_nor_expected_cmd(const struct chrg_switch_t *pSW) return SRC_CMD_GET_PROTOCOL; case IDX_SET_SOURCE_PD: return SRC_CMD_SET_PROTOCOL; - case IDX_SET_SOURCE_CC_CLOSE: + case IDX_SET_SOURCE_RESET: + return SRC_CMD_RESET; case IDX_SET_SOURCE_CC_SET: return SRC_CMD_SET_CC_CHOOSE; case IDX_SET_SOURCE_CCLVL: @@ -793,9 +724,9 @@ static int chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW, if(pSW->id==ID_SOURCE){ //电源 chrg_roll_nor_sw_uart((eIDX_NOR_CH)ch, ID_SOURCE); switch(pSW->sub){ - case IDX_SET_SOURCE_CC_CLOSE: - *next_sub = IDX_WAIT_SOURCE_CC_CLOSE; - return source_set_cc_choose(SOURCE_CC_CLOSE_VALUE); + case IDX_SET_SOURCE_RESET: + *next_sub = IDX_SET_SOURCE_PD; + return source_reset(); case IDX_SET_SOURCE_PD: *next_sub = IDX_WAIT_SOURCE_PROTOCOL; return chrg_roll_nor_source_pro_set(pSW); @@ -936,13 +867,14 @@ static int chrg_roll_nor_auto_request(rt_uint8_t idx, } /* ID、命令、CRC和配置版本均确认有效后,才正式推进实时sub。 */ if ((expected_id == ID_SOURCE) && - (request_sub == IDX_SET_SOURCE_CC_CLOSE)) { + (request_sub == IDX_SET_SOURCE_RESET)) { /* 参与通道全部收到0x17=3应答后,共享一次300ms保护等待。 */ - chrg_roll_nor_source_cc_close_ack(idx); } else if ((expected_id == ID_SOURCE) && (request_sub == IDX_SET_SOURCE_PD)) { /* 0xD0应答后每通道独立等待100ms,再连接目标CC。 */ 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_CCLINE) || (request_sub == IDX_SET_SINK_CC_BEFORE_PD))) { diff --git a/apps/chrg/applications/thread/chrg_roll_nor.h b/apps/chrg/applications/thread/chrg_roll_nor.h index e11def5..21c58ae 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.h +++ b/apps/chrg/applications/thread/chrg_roll_nor.h @@ -43,8 +43,7 @@ enum { IDX_SET_SINK_STORP_WAIT, /* Source北向事务状态,追加在末尾以保持原有sub数值不变。 */ - IDX_SET_SOURCE_CC_CLOSE, // 协议切换前发送0x17=0x03断开CC - IDX_WAIT_SOURCE_CC_CLOSE, // 等待参与切换的Source通道完成共享保护时间 + IDX_SET_SOURCE_RESET, // PD与非PD协议跨类切换前发送Source复位 IDX_WAIT_SOURCE_PROTOCOL, // 0xD0应答后的协议生效等待 /* Sink北向事务状态追加在末尾,避免改变已有sub数值。 */ @@ -105,8 +104,6 @@ extern void roll_nor_set(void); 返回说明: - 其它说明: 仅需要在协议切换入口为IDX_SET_SOURCE_CC_CLOSE时调用 *****************************************************************/ -extern void chrg_roll_nor_source_cc_close_register(rt_uint8_t ch); - /***************************************************************** 函数名称: chrg_roll_nor_source_switch_reset 函数描述: 清理指定Source通道的CC_CLOSE及协议等待记录 diff --git a/apps/chrg/applications/utils/chrg_source.c b/apps/chrg/applications/utils/chrg_source.c index 792952d..b2a7d69 100644 --- a/apps/chrg/applications/utils/chrg_source.c +++ b/apps/chrg/applications/utils/chrg_source.c @@ -148,7 +148,7 @@ static int chrg_source_work_protocol_switch(eIDX_SOU_CH idx, int ret; if ((pSW->sub != IDX_SET_SOURCE_PD) && - (pSW->sub != IDX_SET_SOURCE_CC_CLOSE)) { + (pSW->sub != IDX_SET_SOURCE_RESET)) { return -1; } @@ -316,6 +316,18 @@ int source_get_pd (void) return chrg_north_send(frame, len); } +int source_reset (void) +{ + rt_uint16_t len = 0; + rt_uint8_t data[8] = {0}; + rt_uint8_t frame[16] = {0}; + + data[0] = 0x00; + chrg_north_pkg_encode(ID_SOURCE, SRC_CMD_RESET, data, 1, frame, &len); + + return chrg_north_send(frame, len); +} + /***************************************************************** 函数名称: source_set_cc_lvl 函数描述: source 设置 cc 等级 @@ -1017,8 +1029,8 @@ rt_uint8_t pd_fill_single_group_no_src_com(rt_uint8_t *data, rt_uint8_t start_id data[idx++] = 0x00; data[idx++] = 0x00; // 2. 最小电压(高+低,直接取已拆分好的值) - data[idx++] = mm->min_vol >> 8; - data[idx++] = mm->min_vol & 0xFF; + data[idx++] = 0x13;//mm->min_vol >> 8; + data[idx++] = 0x18;//mm->min_vol & 0xFF; // 3. 最大电压(高+低,直接取已拆分好的值) data[idx++] = mm->max_vol >> 8; data[idx++] = mm->max_vol & 0xFF; diff --git a/apps/chrg/applications/utils/chrg_source.h b/apps/chrg/applications/utils/chrg_source.h index 14ef4d5..1ae00da 100644 --- a/apps/chrg/applications/utils/chrg_source.h +++ b/apps/chrg/applications/utils/chrg_source.h @@ -25,6 +25,8 @@ struct chrg_switch_t; #define SRC_CMD_SET_CC_CHOOSE 0x17 +#define SRC_CMD_RESET 0x18 + #define SRC_CMD_SET_PROTOCOL 0xD0 #define PROTOCOL_NONE 0x00 // 无快充 @@ -192,6 +194,8 @@ extern int source_get_vc (rt_uint16_t vol, rt_uint16_t cur); *****************************************************************/ extern int source_get_pd (void); +extern int source_reset (void); + /***************************************************************** 函数名称: source_set_cc_lvl 函数描述: source 设置 cc 等级