负载running触发逻辑功率板返回电压与V_On点比较,拉载速度从2秒变成100ms

短路模式增加持续发送启动指令,能稳定短路充电头

1. 修改工作电压下限从3000mV调整为500mV
2. 迁移Sink电压稳定确认参数到chrg_sink.h
3. 将chrg_sink_volt_judge函数实现电压判定逻辑
4. 在北向线程中简化chrg_sink_parse函数
5. 新增短路测试保活机制,定期补发WORK_START
6. 重构chrg_sink_work_init的寄存器配置逻辑
7. 新增docs/HC_DFCD_Protocol_V3_0.brd和hc_dfcd_protocol.opj文件
This commit is contained in:
wrh
2026-09-04 21:19:22 +08:00
parent 3b0087c956
commit 2bf408472c
10 changed files with 3657 additions and 2622 deletions
+8 -108
View File
@@ -28,11 +28,8 @@
#define SOURCE_VOLT_RETRY_FRAMES 3U // Source电压持续超差后的重发确认帧数
#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_ERROR_MV 2000U // Sink实际电压与协议目标电压的最大允许误差
#define SINK_VOLT_5V_TARGET_MV 5000U // VSafe5V目标电压,需延长稳定确认时间
#define SINK_VOLT_CONFIRM_NORMAL_COUNT 5U // 非5V目标连续有效电压确认帧数
#define SINK_VOLT_CONFIRM_5V_COUNT 15U // 5V目标连续有效电压确认帧数,避免把握手阶段VSafe5V误判为协议稳定
/* Sink电压稳定确认参数已迁移至chrg_sink.h,供chrg_sink_volt_judge使用。 */
/*****************************************************************
函数名称: chrg_source_apply_protocol_voltage_rule
@@ -84,22 +81,6 @@ static rt_bool_t chrg_sink_voltage_is_stable(rt_uint16_t actual_volt_mv,
RT_TRUE : RT_FALSE;
}
/*****************************************************************
函数名称: chrg_sink_voltage_confirm_count
函数描述: 根据Sink协议目标电压选择进入RUNING前所需的连续稳定帧数
输入参数: target_volt_mv:当前协议申请的目标电压,单位mV
输出参数: -
返回说明: 5V目标返回延长确认帧数,其它目标返回普通确认帧数
其它说明: 快充协议切换时总线会先经过VSafe5V;当目标本身也是5V时,
单凭电压值无法区分过渡阶段和协议稳定阶段,因此增加确认时间,
防止电子负载提前启动后导致协议板复位
*****************************************************************/
static rt_uint8_t chrg_sink_voltage_confirm_count(rt_uint16_t target_volt_mv)
{
return (target_volt_mv == SINK_VOLT_5V_TARGET_MV) ?
SINK_VOLT_CONFIRM_5V_COUNT : SINK_VOLT_CONFIRM_NORMAL_COUNT;
}
/*****************************************************************
函数名称: chrg_source_voltage_control
函数描述: 根据目标电压与实际电压统一控制Source电压下发和重试
@@ -231,110 +212,29 @@ void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
/*****************************************************************
函数名称: chrg_sink_parse
函数描述: 解析北向负载板回码并根据电压、电流反馈驱动Sink状态机
函数描述: 解析北向负载板0x20回码,提取D+/D-电压到VZ/VF
输入参数: frame_data:完整北向回码 idx:当前通道 pSW:通道控制结构体
pNOR:北向总控结构体
输出参数: 更新VZ、VF、低压计数、稳定电压计数、无电流计数及sink.work_mode
输出参数: 更新pSW->VZ(D+)、pSW->VF(D-)
返回说明: -
其它说明: 电压连续低于门槛进入LOW;掉电处理恢复副继电器后,电压重新
出现时先重设协议和CC;一帧有效电压达到目标附近即进入RUNING
其它说明: Sink电压状态机判定已迁移至chrg_sink_volt_judge,
由北向轮询线程基于eload.c更新的Now_voltage驱动
*****************************************************************/
void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
rt_uint16_t volt_mv = ((frame_data[4] << 8) | frame_data[5]) * 10;
rt_uint8_t stable_confirm_count;
static rt_uint8_t volt_low[TOTAL_SOU_CHS] = {0};
static rt_uint8_t no_curr[TOTAL_SOU_CHS] = {0};
static rt_uint8_t volt_set_ok[TOTAL_SOU_CHS] = {0};
static rt_uint8_t volt_stable_count[TOTAL_SOU_CHS] = {0};
static rt_tick_t running_start_tick[TOTAL_SOU_CHS] = {0};
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return;
}
stable_confirm_count = chrg_sink_voltage_confirm_count(
pSW->sink.pro_loadv);
pSW->VZ = ((frame_data[14] << 8) | frame_data[15]);
pSW->VF = ((frame_data[16] << 8) | frame_data[17]);
#if NORTH_SINK_DEBUG
LOG_D("Sink[%d] real volt: %d mV", idx, volt_mv);
LOG_D("Sink[%d] real volt: %d mV", idx,
((frame_data[4] << 8) | frame_data[5]) * 10);
#endif
if(pSW->sink.On_work == 1 && pSW->sink.test.test_mode == 0) {
if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
volt_stable_count[idx] = 0;
if (volt_set_ok[idx] == 1) {
if (++volt_low[idx] >= 50) {
volt_set_ok[idx] = 0;
no_curr[idx] = 0;
//pSW->sink.work_mode = SINK_WORK_LOW;
}
}
}
else{ // 电压稳定时执行工作状态机(继电器/工作模式切换)
volt_low[idx] = 0;
volt_set_ok[idx] = 1;
pSW->change_flag = 0;
if (pSW->sink.work_mode == SINK_WORK_LOW_MONITOR) {
/* 副继电器恢复后首次重新检测到输入电压,只启动协议重握手。
* 当前回码不计入稳定电压次数,防止跳过协议设置直接带载。 */
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
//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 (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_LOAD_STANDBY)) {
if (volt_stable_count[idx] < stable_confirm_count) {
volt_stable_count[idx]++;
}
if (volt_stable_count[idx] >= stable_confirm_count) {
/* 回码已经过CRC、ID、命令和配置版本校验,并连续达到当前
* 目标对应的确认帧数;5V采用更长窗口过滤VSafe5V过渡阶段。 */
volt_stable_count[idx] = 0;
pSW->sink.work_mode = SINK_WORK_RUNING;
running_start_tick[idx] = rt_tick_get();
no_curr[idx] = 0;
}
} else if (pSW->sink.work_mode == SINK_WORK_LOAD_STANDBY) {
/* 协议保持在线但电子负载主动停止,不执行无电流重试。 */
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
} else if ((pSW->Now_current > 200) ||
(pSW->sink.loadc < 200)) {
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
} else if ((rt_tick_t)(rt_tick_get() - running_start_tick[idx]) >=
rt_tick_from_millisecond(SINK_CURRENT_START_GRACE_MS)) {
volt_stable_count[idx] = 0;
if (++no_curr[idx] >= 2) {
pSW->sink.work_mode = SINK_WORK_WAIT;
no_curr[idx] = 0;
}
}
} else {
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
}
}
}
else{
volt_low[idx] = 0;
no_curr[idx] = 0;
volt_set_ok[idx] = 0;
volt_stable_count[idx] = 0;
}
chrg_sink_work(idx,pSW);
(void)pNOR;
}
struct chrg_north_t chrgnorth = {
+1 -1
View File
@@ -21,7 +21,7 @@
#define LEN_FRAME_HEAD (4) // [帧长, 0x00, id, 命令]
#define MIN_FRAME_LENGTH (5) // 帧最短5字节
#define WORK_MIN_VOLT 3000 // 工作电压下限,单位mV
#define WORK_MIN_VOLT 500 // 工作电压下限,单位mV
#define NORTH_FRAME_DEBUG 0x00 // 北向UART原始收发帧
#define NORTH_SOURCE_DEBUG 0x01 // Source协议解析及组帧
#define NORTH_SINK_DEBUG 0x00 // Sink协议解析及组帧
+11 -2
View File
@@ -992,8 +992,17 @@ void chrg_roll_nor_thread_entry (void *data)
* 协议切换等待只推进时间状态,不发送串口命令。该检查位于enable
* 过滤前,使停止或角色切换后的通道也能及时清理残留事务记录。
*/
source_waiting = chrg_roll_nor_source_wait_process(idx, pSW);
sink_waiting = chrg_roll_nor_sink_wait_process(idx, pSW);
source_waiting = chrg_roll_nor_source_wait_process(idx, pSW);
sink_waiting = chrg_roll_nor_sink_wait_process(idx, pSW);
/* 全通道Sink电压判定:使用eload实际电压Now_voltage与V_On比较,
* 判定后统一由chrg_sink_work执行;短路测试由该入口负责WORK_START保活。 */
for (i = 0; i < TOTAL_NOR_CHS; i++) {
struct chrg_switch_t *psw = &pNOR->sw[i];
if ((psw->id == ID_SINK) && psw->sink.On_work) {
(void)chrg_sink_volt_judge((eIDX_SOU_CH)i, psw);
}
}
rt_mutex_release(pTHR->mutex);
if (state_work_ret != 0) {
/* 南向状态动作未成功入队时保留原状态,下轮重试且禁止北向先行。 */
+164 -24
View File
@@ -38,6 +38,8 @@ static rt_uint32_t g_sink_unload_sample_seq[TOTAL_SOU_CHS] = {0};
static rt_bool_t g_sink_unload_batch_confirmed[TOTAL_SOU_CHS] = {RT_FALSE};
static rt_tick_t g_sink_unload_query_tick[TOTAL_SOU_CHS] = {0};
static rt_uint8_t g_sink_unload_confirm_count[TOTAL_SOU_CHS] = {0};
/* 记录各通道短路测试最近一次WORK_START的发送时间。 */
static rt_tick_t g_sink_short_start_tick[TOTAL_SOU_CHS] = {0};
enum {
SINK_UNLOAD_NEXT_RUNNING = 0,
@@ -244,11 +246,10 @@ int sink_set_pd (rt_uint8_t pd, rt_uint8_t *buf)
static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
struct chrg_north_t *pNOR = &chrgnorth;
rt_uint16_t regs[5] = {REG_REL_ON, REG_CURRENT_OUT + 1,
REG_MODE, Eload_Start_V_ON, 0};
rt_uint16_t vals[5] = {FU_REL_ON, 0, 0, 0, 0};
rt_uint16_t regs[6];
rt_uint16_t vals[6];
rt_bool_t first_start;
rt_uint8_t count = 4U;
rt_uint8_t count;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
@@ -256,17 +257,31 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
/* COM进入INIT前已经设置On_work,使用原工作状态区分首次提交和后台重试。 */
first_start = (pSW->sink.work_mode != SINK_WORK_INIT_AUX_WAIT) ?
RT_TRUE : RT_FALSE;
vals[2] = pSW->CV_mode;
vals[3] = pSW->sink.volt_on <= 500 ? 500 : pSW->sink.volt_on;
if (pSW->sink.test.test_mode_old == SINK_TEST_SHORT) {
regs[count] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
} else if (pSW->sink.test.test_mode_old == SINK_TEST_OCP) {
regs[count] = ModbusRTU_OCPTest_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
} else if (pSW->sink.test.test_mode_old == SINK_TEST_DYNA) {
regs[count] = ModbusRTU_DYNA_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
/* 短路测试退出:先断开全部继电器,再打开辅助继电器,最后停止短路测试。 */
regs[0] = REG_REL_ON; vals[0] = ALL_REL_OFF;
regs[1] = REG_REL_ON; vals[1] = FU_REL_ON;
regs[2] = REG_CURRENT_OUT + 1; vals[2] = 0;
regs[3] = REG_MODE; vals[3] = pSW->CV_mode;
regs[4] = Eload_Start_V_ON; vals[4] =
(pSW->sink.volt_on <= 500) ? 500 : pSW->sink.volt_on;
regs[5] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
vals[5] = ModbusRTU_DYNA_CMD_MODE_STOP;
count = 6U;
} else {
regs[0] = REG_REL_ON; vals[0] = FU_REL_ON;
regs[1] = REG_CURRENT_OUT + 1; vals[1] = 0;
regs[2] = REG_MODE; vals[2] = pSW->CV_mode;
regs[3] = Eload_Start_V_ON; vals[3] =
(pSW->sink.volt_on <= 500) ? 500 : pSW->sink.volt_on;
count = 4U;
if (pSW->sink.test.test_mode_old == SINK_TEST_OCP) {
regs[count] = ModbusRTU_OCPTest_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
} else if (pSW->sink.test.test_mode_old == SINK_TEST_DYNA) {
regs[count] = ModbusRTU_DYNA_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
}
}
if (chrg_sou_com_batch_submit(idx, regs, vals, count) != 0) {
return -1;
@@ -814,16 +829,133 @@ static int chrg_sink_TEST_SHORT_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[3] = {ModbusRTU_ShortTest_Hold_Time,ModbusRTU_ShortTest_CMD_MODE_FLAG, REG_WORK};
rt_uint16_t vals[3] = {0,0,0};
if(pSW->sink.test.short_test.set_mode == 0)
{
vals[0] = pSW->sink.test.short_test.hold_time;
vals[1] = ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR;
}
else{
vals[1] = ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP;
}
/* 外部工程固定短路测试保持60秒且不带载。 */
vals[0] = 60000;
vals[1] = ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR;
vals[2] = WORK_START;
return chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 3);
if (chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 3) == 0) {
g_sink_short_start_tick[ch] = rt_tick_get();
return 0;
}
return -1;
}
/* 短路测试保持期间只补发WORK_START,避免重复写入测试配置并堆积批次。 */
static int chrg_sink_TEST_SHORT_KEEPALIVE(rt_uint8_t ch)
{
rt_uint16_t reg = REG_WORK;
rt_uint16_t val = WORK_START;
rt_tick_t now = rt_tick_get();
if ((rt_tick_t)(now - g_sink_short_start_tick[ch]) <
rt_tick_from_millisecond(SINK_SHORT_START_INTERVAL_MS)) {
return 0;
}
if (chrg_sou_com_batch_is_pending((eIDX_SOU_CH)ch)) {
return 0;
}
if (chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, &reg, &val, 1U) == 0) {
g_sink_short_start_tick[ch] = now;
}
return 0;
}
/*****************************************************************
函数名称: chrg_sink_voltage_confirm_count
函数描述: 根据Sink协议目标电压选择进入RUNING前所需的连续稳定帧数
输入参数: target_volt_mv:当前协议申请的目标电压,单位mV
输出参数: -
返回说明: 5V目标返回延长确认帧数,其它目标返回普通确认帧数
其它说明: 由chrg_sink_volt_judge调用
*****************************************************************/
static rt_uint8_t chrg_sink_voltage_confirm_count(rt_uint16_t target_volt_mv)
{
return (target_volt_mv == SINK_VOLT_5V_TARGET_MV) ?
SINK_VOLT_CONFIRM_5V_COUNT : SINK_VOLT_CONFIRM_NORMAL_COUNT;
}
/*****************************************************************
函数名称: chrg_sink_volt_judge
函数描述: 使用南向功率板实际电压Now_voltage与V_On比较,驱动负载进入RUNING
输入参数: idx:南向通道 pSW:通道控制结构体
输出参数: 更新sink.work_mode并调用chrg_sink_work
返回说明: 0:处理完成 <0:参数错误
*****************************************************************/
int chrg_sink_volt_judge(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint8_t stable_confirm_count;
static rt_uint8_t volt_low[TOTAL_SOU_CHS] = {0};
static rt_uint8_t no_curr[TOTAL_SOU_CHS] = {0};
static rt_uint8_t volt_set_ok[TOTAL_SOU_CHS] = {0};
static rt_uint8_t volt_stable_count[TOTAL_SOU_CHS] = {0};
static rt_tick_t running_start_tick[TOTAL_SOU_CHS] = {0};
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
stable_confirm_count = chrg_sink_voltage_confirm_count(
pSW->sink.pro_loadv);
if ((pSW->sink.On_work == 1) && (pSW->sink.test.test_mode == 0)) {
if (pSW->Now_voltage <= WORK_MIN_VOLT) {
volt_stable_count[idx] = 0;
if (volt_set_ok[idx] == 1 && ++volt_low[idx] >= 50) {
volt_set_ok[idx] = 0;
no_curr[idx] = 0;
}
} else {
volt_low[idx] = 0;
volt_set_ok[idx] = 1;
pSW->change_flag = 0;
if (pSW->sink.work_mode == SINK_WORK_LOW_MONITOR) {
/* 副继电器恢复后首次重新检测到输入电压,只启动协议重握手。 */
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
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 (pSW->Now_voltage > pSW->sink.volt_on) {
if ((pSW->sink.work_mode != SINK_WORK_RUNING) &&
(pSW->sink.work_mode != SINK_WORK_LOAD_STANDBY)) {
if (volt_stable_count[idx] < stable_confirm_count) {
volt_stable_count[idx]++;
}
if (volt_stable_count[idx] >= stable_confirm_count) {
/* 连续达到当前目标对应的确认帧数后进入RUNING。 */
volt_stable_count[idx] = 0;
pSW->sink.work_mode = SINK_WORK_RUNING;
running_start_tick[idx] = rt_tick_get();
no_curr[idx] = 0;
}
} else if (pSW->sink.work_mode == SINK_WORK_LOAD_STANDBY) {
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
} else if ((pSW->Now_current > 200) || (pSW->sink.loadc < 200)) {
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
} else if ((rt_tick_t)(rt_tick_get() - running_start_tick[idx]) >=
rt_tick_from_millisecond(SINK_CURRENT_START_GRACE_MS)) {
volt_stable_count[idx] = 0;
if (++no_curr[idx] >= 2) {
pSW->sink.work_mode = SINK_WORK_WAIT;
no_curr[idx] = 0;
}
}
} else {
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
}
}
} else {
volt_low[idx] = 0;
no_curr[idx] = 0;
volt_set_ok[idx] = 0;
volt_stable_count[idx] = 0;
}
return chrg_sink_work(idx, pSW);
}
/*****************************************************************
@@ -877,8 +1009,12 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
}
work_mode = pSW->sink.work_mode;
workmode = work_mode;
if (work_mode != SINK_WORK_ON_TEST_SHORT) {
g_sink_short_start_tick[idx] = 0;
}
/* 异步等待状态需要持续检查批次或新量测,其余相同状态保持去重。 */
if ((work_mode == last_state[idx]) &&
(work_mode != SINK_WORK_ON_TEST_SHORT) &&
(work_mode != SINK_WORK_INIT_AUX_WAIT) &&
(work_mode != SINK_WORK_STOP_WAIT) &&
(work_mode != SINK_WORK_STOP_RELAY_WAIT) &&
@@ -904,7 +1040,11 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
ret = chrg_sink_TEST_DYNA_ON(idx,pSW);
break;
case SINK_WORK_ON_TEST_SHORT:
ret = chrg_sink_TEST_SHORT_ON(idx,pSW);
if (work_mode != last_state[idx]) {
ret = chrg_sink_TEST_SHORT_ON(idx, pSW);
} else {
ret = chrg_sink_TEST_SHORT_KEEPALIVE(idx);
}
break;
case SINK_WORK_ON_TEST_OCP:
ret = chrg_sink_TEST_OCP_ON(idx,pSW);
+9
View File
@@ -21,6 +21,8 @@ struct chrg_switch_t;
#define SINK_TEST_SHORT 1
#define SINK_TEST_OCP 2
#define SINK_TEST_DYNA 3
/* 短路测试期间按该周期补发WORK_START,防止功率板因超时停止。 */
#define SINK_SHORT_START_INTERVAL_MS 30U
//短路测试结构体
struct test_short {
rt_uint16_t hold_time; // 短路测试时间
@@ -208,6 +210,12 @@ enum {
*/
#define SINK_LOAD_ENABLE_MIN_MA 100U
/* Sink电压稳定确认参数,供chrg_sink_volt_judge使用。 */
#define SINK_VOLT_5V_TARGET_MV 5000U
#define SINK_VOLT_CONFIRM_NORMAL_COUNT 5U
#define SINK_VOLT_CONFIRM_5V_COUNT 15U
#define SINK_CURRENT_START_GRACE_MS 200U
/* 主继电器闭合后的0V持续监控:由北向轮询线程每轮调用,掉电立即转掉电保护。 */
extern int chrg_sink_volt_low_protect(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
@@ -409,6 +417,7 @@ extern void chrg_nor_sink_test_run(rt_uint8_t ch, struct chrg_switch_t *pSW);
/* 判断普通负载的当前设定是否允许启动电子负载。 */
extern rt_bool_t chrg_sink_load_should_start(const struct chrg_switch_t *pSW);
extern int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
extern int chrg_sink_volt_judge(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
#endif