Files
chrg/apps/chrg/applications/utils/chrg_sink.c
T
wrh 684ad2e20e feat: 新增电源/负载切换功能,优化通道切换逻辑
1. 新增SINK_WORK_SWITCH和SOURCE_WORK_SWITCH状态,实现切换流程
2. 实现chrg_sink_work_switch和chrg_source_work_switch切换处理函数
3. 修改Keil工程ROM起始地址为0x8000000
4. 开启north线程调试输出,调整初始通道使能状态
5. 简化串口包编码调试打印,优化source初始化寄存器配置
6. 重构modbus通道切换逻辑,支持活跃状态下的角色切换
7. 清理部分冗余调试代码和注释
8. 重构bootloader代码,简化启动流程
2026-07-22 10:05:47 +08:00

633 lines
22 KiB
C

/****************************************************************************
文件名称 : chrg_sink.c
完成日期 :
当前版本号 : V1.0
主要功能 : 北向数据sink请求数据填充及发送。
版本历史 : 创建原始版本
说明 :
******************************************************************************/
#include <rtthread.h>
#include "chrg_sink.h"
#include "chrg_north.h"
#include "chrg_north_pkg.h"
#include "chrg_utils.h"
#include "chrg_roll_sou.h"
#include "chrg_roll_nor.h"
#include "chrg_def.h"
#include "chrg_rel.h"
#include "chrg_comm.h"
/*****************************************************************
函数名称: sink_get_vc
函数描述: sink电压电流查询请求
输入参数: vol:电压 cur:电流
输出参数: -
返回说明: <0: 错误 >0:发送长度
其它说明: -
*****************************************************************/
int sink_get_vc (rt_uint16_t vol, rt_uint16_t cur)
{
rt_uint16_t len = 0;
rt_uint8_t data[12] = {0};
rt_uint8_t frame[16] = {0};
u16_to_u8v(vol, &data[0]);
u16_to_u8v(cur, &data[2]);
data[4] = 0x00;
data[5] = 0x00;
chrg_north_pkg_encode(ID_SINK, SINK_CMD_GET_VOLTAGE, data, 6, frame, &len);
return chrg_north_send(frame, len);
}
/*****************************************************************
函数名称: sink_get_pd
函数描述: sink pd 协议查询请求
输入参数: -
输出参数: -
返回说明: <0: 错误 >0:发送长度
其它说明: -
*****************************************************************/
int sink_get_pd (void)
{
rt_uint16_t len = 0;
rt_uint8_t frame[16] = {0};
chrg_north_pkg_encode(ID_SINK, SINK_CMD_GET_PD, RT_NULL, 0, frame, &len);
return chrg_north_send(frame, len);
}
/*****************************************************************
函数名称: sink_set_cc_line
函数描述: sink 设置 cc 线
输入参数: line:线
输出参数: -
返回说明: <0: 错误 >0:发送长度
其它说明: -
*****************************************************************/
int sink_set_cc_line (rt_uint8_t line)
{
rt_uint16_t len = 0;
rt_uint8_t data[8] = {0};
rt_uint8_t frame[16] = {0};
data[0] = line;
chrg_north_pkg_encode(ID_SINK, SINK_CMD_SET_CC, data, 1, frame, &len);
// for(int i = 0; i < len; i++) {
// rt_kprintf("data[%d]=%02x\r\n", i, frame[i]);
// }
return chrg_north_send(frame, len);
}
/*****************************************************************
函数名称: sink_set_cc_lvl
函数描述: sink 设置 cc 等级
输入参数: lvl:等级
输出参数: -
返回说明: <0: 错误 >0:发送长度
其它说明: -
*****************************************************************/
int sink_set_cc_lvl (rt_uint8_t lvl)
{
rt_uint16_t len = 0;
rt_uint8_t data[8] = {0};
rt_uint8_t frame[16] = {0};
data[0] = lvl;
chrg_north_pkg_encode(ID_SINK, SINK_CMD_SET_LEVEL, data, 1, frame, &len);
return chrg_north_send(frame, len);
}
/*****************************************************************
函数名称: sink_set_pd
函数描述: sink 设置 PD 协议
输入参数: pd:协议命令号 *buf:协议数据,5字节
输出参数: -
返回说明: <0: 错误 >0:发送长度
其它说明: -
*****************************************************************/
int sink_set_pd (rt_uint8_t pd, rt_uint8_t *buf)
{
rt_uint16_t len = 0;
rt_uint8_t data[8] = {0};
rt_uint8_t frame[16] = {0};
int i = 0;
for (i = 0; i < 5; i++) {
data[i] = buf[i];
}
chrg_north_pkg_encode(ID_SINK, pd, data, 5, frame, &len);
return chrg_north_send(frame, len);
}
//// 短路测试参数解析 指令码:0x01
//void sink_test_short_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
//{
// struct test_short *pTest = &pSW->sink.test.short_test;
// // 解析报文:高字节pData[1]、低字节pData[2] → 测试保持时间
// pTest->hold_time = (pData[1] << 8) | pData[2];
// pTest->set_mode = pData[3]; // 模式选择:0=测试后一直保持;1=保持指定时长后恢复原有电流
// rt_kprintf("[SINK] Short Test: time=%d, mode=%d\n",
// pTest->hold_time, pTest->set_mode);
//}
////=============================================================================
//// OCP过流保护测试参数解析 指令码:0x02
////=============================================================================
//void sink_test_ocp_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
//{
// struct test_OCP *pTest = &pSW->sink.test.OCP_test;
// pTest->start_curr = (pData[1] << 8) | pData[2]; // 解析:OCP测试起始电流
// pTest->end_curr = (pData[3] << 8) | pData[4]; // 解析:OCP测试终止电流
// pTest->change_curr = (pData[5] << 8) | pData[6]; // 解析:电流步进值
// pTest->change_keep_time = (pData[7] << 8) | pData[8]; // 解析:单步电流保持时间
// pTest->hold_time = (pData[9] << 8) | pData[10]; // 解析:OCP触发后保持时间
// pTest->stop_volt = (pData[11]<< 8) | pData[12]; // 解析:停止判定电压
// pTest->set_mode = pData[13]; // 测试结束模式:0=保持设定时间后恢复;1=一直保持
// pTest->hold_curr = pData[14]; // OCP触发后是否带载,0=带载,1=不带载
// // pTest->change_mode = pData[11]; // 电流变化模式(预留):0=置0;1=达标立即置0;2=保持当前电流
// // pTest->interval_time = pData[12]; // 指令保护间隔时间(预留)
// pSW->sink.loadc = pTest->start_curr; // 负载电流初始化为OCP起始电流
//#if SINK_TEST_DEBUG
// rt_kprintf("[SINK] OCP Test: start=%d, end=%d\n",
// pTest->start_curr, pTest->end_curr);
//#endif
//}
////=============================================================================
//// 动态负载测试参数解析 指令码:0x03
////=============================================================================
//void sink_test_dynamic_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
//{
// struct test_change *pTest = &pSW->sink.test.change_test;
//// rt_uint16_t change_curr = 0;
// pTest->curr1_set = (pData[1] << 8) | pData[2]; // 解析:第一阶段设定电流
// pTest->time1_set = (pData[3] << 8) | pData[4]; // 解析:第一阶段保持时长
// pTest->curr2_set = (pData[5] << 8) | pData[6]; // 解析:第二阶段设定电流
// pTest->time2_set = (pData[7]<< 8) | pData[8]; // 解析:第二阶段保持时长
// pTest->k_Rise = (pData[9] << 8) | pData[10]; // 电流上升斜率
// pTest->k_Fall = (pData[11]<< 8) | pData[12]; // 电流下降斜率
// // pTest->start_time = (pData[14]<< 8) | pData[13]; // 产品稳定时长(预留)
// // pSW->sink.loadc = pTest->curr1_set;
//#if SINK_TEST_DEBUG
// rt_kprintf("[SINK] Dynamic Test: curr1=%d, curr2=%d\n",
// pTest->curr1_set, pTest->curr2_set);
//#endif
//}
////=============================================================================
//// 短路测试状态机执行函数
//// 依据 work_step 分步配置寄存器,启动短路测试
////=============================================================================
//void chrg_nor_sink_short_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
//{
// struct test *pTest = &pSW->sink.test;
//
// switch (pTest->work_step)
// {
// case 0:
// // 第一步:切换为电子负载模式,吸合负载开关
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
//// rt_kprintf("first\r\n");
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
// pTest->work_step = 1;
// break;
// case 1:
// // 根据模式分支配置参数
// if(pTest->short_test.set_mode == 0x00) { //直接释放
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR); //直接为0
// pTest->work_step = 2;
// }
// else{ //按设定的时间后释放
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP); //保持
// pTest->work_step = 4;
// }
//
// rt_kprintf("set_mode = %d",pTest->short_test.set_mode);
// break;
// case 2:
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_Hold_Time , pTest->short_test.hold_time);
// pTest->work_step = 4;
// break;
// case 4:
// // 启动整机工作,清零状态标志
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
// pTest->work_step = 5;
// pSW->change_flag = 0;
// break;
// case 5:
// break;
// default:
// pTest->work_step = 0;
// break;
// }
//}
////=============================================================================
//// OCP过流保护测试状态机执行函数
//// 分步配置电流、时长、模式寄存器,最终启动OCP测试
////=============================================================================
//// OCP测试执行
//void chrg_nor_sink_OCP_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->work_step)
// {
// case 0: // 初始化:切负载模式、闭合负载开关
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
//// rt_kprintf("first\r\n");
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
// pTest->work_step = SET_OCP_STARTCURR;
// break;
// case SET_OCP_STARTCURR: // 设置OCP起始电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_StartCurrent, pTest->OCP_test.start_curr);
// pTest->work_step = SET_OCP_ENDCURR;
// break;
// case SET_OCP_ENDCURR: // 设置OCP终止电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_StopCurrent , pTest->OCP_test.end_curr);
// pTest->work_step = SET_OCP_STEP;
// break;
// case SET_OCP_STEP: // 设置电流步进值
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Step_CURR , pTest->OCP_test.change_curr);
// pTest->work_step = SET_OCP_STEP_HOLD_TIME;
// break;
// case SET_OCP_STEP_HOLD_TIME: // 设置单步保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Step_Hold_Time , pTest->OCP_test.change_keep_time);
// pTest->work_step = SINK_OCP_STOP_VOLT;
// break;
// case SINK_OCP_STOP_VOLT: //设置截止电压
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Vtrig_Stop , pTest->OCP_test.stop_volt);
// pTest->work_step = SET_OCP_CMD_MODE_RUN;
// break;
// case SET_OCP_CMD_MODE_RUN: // 标记测试运行模式
// if(pTest->OCP_test.set_mode == 0x00) { //释放
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR); //直接为0
// pTest->work_step = SET_OCP_HOLD_TIME;
// }
// else{ //保持
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP); //保持
// pTest->work_step = SET_OCP_RUNNING;
// }
// break;
// case SET_OCP_HOLD_TIME: // 设置OCP触发后保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Hold_Time , pTest->OCP_test.hold_time);
// pTest->work_step = SET_OCP_RUNNING;
// break;
// case SET_OCP_RUNNING: // 启动OCP测试
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
// pSW->change_flag = 0;
// pTest->work_step = 0x10;
// break;
// case 0x10:
// break;
// default:
// break;
// }
//}
////=============================================================================
//// 动态负载测试状态机执行函数
//// 依次配置两段电流、时长、升降斜率,启动动态负载测试
////=============================================================================
//void chrg_nor_sink_change_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->work_step)
// {
// case 0: // 初始步骤:切换电子负载模式、闭合负载开关
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
// pTest->work_step = SET_DYNA_CURR1;
// break;
// case SET_DYNA_CURR1: // 设置第一路输出电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L1, pTest->change_test.curr1_set);
// pTest->work_step = SET_DYNA_TIME1;
// #if SINK_TEST_DEBUG
// rt_kprintf("Curr1: %d\n", pTest->change_test.curr1_set);
// #endif
// break;
// case SET_DYNA_TIME1: // 设置第一阶段保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T1 , pTest->change_test.time1_set);
// pTest->work_step = SET_DYNA_CURR2;
// #if SINK_TEST_DEBUG
// rt_kprintf("Time1: %d\n", pTest->change_test.time1_set);
// #endif
// break;
// case SET_DYNA_CURR2: // 设置第二路输出电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L2 , pTest->change_test.curr2_set);
// pTest->work_step = SET_DYNA_TIME2;
// #if SINK_TEST_DEBUG
// rt_kprintf("Curr2: %d\n", pTest->change_test.curr2_set);
// #endif
// break;
// case SET_DYNA_TIME2: // 设置第二阶段保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T2 , pTest->change_test.time2_set);
// pTest->work_step = SET_DYNA_RISE_SLEW_RATE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Time2: %d\n", pTest->change_test.time2_set);
// #endif
// break;
// case SET_DYNA_RISE_SLEW_RATE: // 设置电流上升斜率
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_Rise_Slew_Rate , pTest->change_test.k_Rise);
// pTest->work_step = SET_DYNA_FALL_SLEW_RATE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Rise Slew Rate: %d\n", pTest->change_test.k_Rise);
// #endif
// break;
// case SET_DYNA_FALL_SLEW_RATE: // 设置电流下降斜率
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_Fall_Slew_Rate , pTest->change_test.k_Fall);
// pTest->work_step = SET_DYNA_CND_MODE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Fall Slew Rate: %d\n", pTest->change_test.k_Fall);
// #endif
// break;
// case SET_DYNA_CND_MODE: // 标记动态测试为运行状态
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN);
// pTest->work_step = SET_DYNA_RUNNING;
// pTest->work_step = SET_DYNA_CND_MODE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Fall Slew Rate: %d\n", pTest->change_test.k_Fall);
// #endif
// break;
// case SET_DYNA_RUNNING: // 启动整机工作,锁定当前运行步骤、清空标志位
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
// pTest->work_step = SET_DYNA_RUNNING;
// pTest->work_step = 0x11;
// pSW->change_flag = 0;
// break;
// case 0x11:
// break;
// default:
// #if SINK_TEST_DEBUG
// rt_kprintf("Invalid work step: %d\n", pTest->work_step);
// #endif
// break;
// }
//}
////=============================================================================
//// 短路测试停止处理函数
//// 依据 stop_step 分步执行停止流程,清除测试标记并跳转状态
////=============================================================================
//void chrg_nor_sink_short_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->stop_step)
// {
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭短路测试运行模式
// chrg_set_sou_reg(idx, ModbusRTU_ShortTest_CMD_MODE_FLAG, ModbusRTU_DYNA_CMD_MODE_STOP);
// // pTest->stop_step = TEST_STOP_RUN;
// // break;
// // case TEST_STOP_RUN: // 清除测试标志,切换至负载状态管理流程
// //chrg_set_sou_reg(idx, REG_WORK, WORK_STOP);
// //pTest->stop_step = TEST_STOP_REL;
// //chrg_nor_sw_rel((eIDX_NOR_CH)idx,0);
// //*enable = 0;
// pSW->change_flag = 0;
// pSW->sink.test.test_mode = 0; // 清空短路测试标记
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE; 跳转至负载工作状态处理
// break;
// default:
// break;
// }
//}
////=============================================================================
//// OCP过流保护测试停止处理函数
////=============================================================================
//void chrg_nor_sink_OCP_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->stop_step)
// {
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭OCP测试运行模式
// chrg_set_sou_reg((eIDX_SOU_CH)idx, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
// pSW->change_flag = 0;
// pSW->sink.test.test_mode = 0; // 清空OCP测试标记
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE;
// break;
// default:
// break;
// }
//}
////=============================================================================
//// 动态负载测试停止处理函数
////=============================================================================
//void chrg_nor_sink_change_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->stop_step)
// {
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭动态测试运行模式
// chrg_set_sou_reg((eIDX_SOU_CH)idx, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
// pSW->change_flag = 0;
// pSW->sink.test.test_mode = 0; // 清空动态测试标记
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE;
// break;
// default:
// break;
// }
//}
//sink开机初始化
static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
struct chrg_south_t *pSOU = &chrgsouth;
struct chrg_north_t *pNOR = &chrgnorth;
rt_uint16_t regs[5] = {REG_CURRENT_OUT + 1, REG_MODE,Eload_Start_V_ON,0, 0};
rt_uint16_t vals[5] = {0, pSW->CV_mode,pSW->sink.volt_on, 0, 0};
rt_uint8_t count = 3;
if (pSW->sink.test.test_mode_old == 1) {
regs[count] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
} else if (pSW->sink.test.test_mode_old == 3) {
regs[count] = ModbusRTU_DYNA_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
}
/* Close both power-board relays before starting sink init. */
regs[count] = REG_REL_ON;
vals[count++] = ALL_REL_OFF;
if (chrg_sou_com_batch_submit(idx, regs, vals, count) != 0) {
return -1;
}
pSW->sink.On_work = 1;
pSOU->enable[idx] = 1;
pSOU->online[idx] = 1;
pNOR->enable[idx] = 1;
chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SINK); //打开北向继电器
pSW->sink.test.test_mode_old = 0;
pSW->sink.work_mode = SINK_WORK_WAIT;
return 0;
}
//sink进入运行状态
static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[4] = {0x01, 0x01, 0, REG_WORK};
rt_uint16_t vals[4] = {0x02, 0x03, 0, WORK_START};
if (pSW->CV_mode == MODE_CONSTANT_VOLTAGE) {
regs[2] = REG_VOLTAGE_OUT + 1;
vals[2] = pSW->sink.loadv;
} else {
regs[2] = REG_CURRENT_OUT + 1;
vals[2] = pSW->sink.loadc;
}
return chrg_sou_com_batch_submit(idx, regs, vals, 4);
}
//sink进入低电压状态
static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[2] = {0x01, REG_WORK};
rt_uint16_t vals[2] = {0x00, WORK_STOP};
return chrg_sou_com_batch_submit(idx, regs, vals, 2);
}
//com端关机流程
static int chrg_sink_nor_work_off(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
struct chrg_south_t *pSOU = &chrgsouth;
struct chrg_north_t *pNOR = &chrgnorth;
rt_uint16_t regs[2] = {0x01, REG_WORK};
rt_uint16_t vals[2] = {0x00, WORK_STOP};
if (chrg_sou_com_batch_submit(idx, regs, vals, 2) != 0) {
return -1;
}
pSW->sink.On_work = 0;
pSOU->enable[idx] = 0;
pSOU->online[idx] = 0;
pNOR->enable[idx] = 0;
chrg_nor_sw_rel((eIDX_NOR_CH)idx, 0); //关闭北向继电器
return 0;
}
// 切换进入负载:停止旧电源后,从负载初始化状态开始运行
static int chrg_sink_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t reg = REG_WORK;
rt_uint16_t value = WORK_STOP;
int ret;
ret = chrg_sou_com_batch_submit(idx, &reg, &value, 1);
if (ret != 0) {
return ret;
}
pSW->source.On_Flag = 0;
pSW->sub = IDX_SET_SINK_CCLINE;
pSW->sink.work_mode = SINK_WORK_INIT;
return 0;
}
//动态测试启动
static int chrg_sink_TEST_DYNA_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
{
struct test *pTest = &pSW->sink.test;
rt_uint16_t regs[8] = {REG_REL_ON, REG_REL_ON,
ModbusRTU_DYNA_L1, ModbusRTU_DYNA_T1, ModbusRTU_DYNA_L2,
ModbusRTU_DYNA_T2, ModbusRTU_DYNA_CMD_MODE_FLAG, REG_WORK};
rt_uint16_t vals[8] = {0x02, 0x03,
pTest->change_test.curr1_set, pTest->change_test.time1_set,
pTest->change_test.curr2_set, pTest->change_test.time2_set,
ModbusRTU_DYNA_CMD_MODE_RUN, WORK_START};
/*
* 动态测试可能在普通 RUNING 状态打开功率板继电器之前进入。
* 因此动态启动流程必须自行打开两路继电器,避免快速从 PD 设置
* 切换到动态测试时,负载已经启动但功率板继电器仍处于关闭状态。
*/
return chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 8);
}
//短路测试启动
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;
}
vals[2] = WORK_START;
return chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 3);
}
//负载工作
int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
static uint8_t last_state[TOTAL_SOU_CHS] ={100,100,100,100};
rt_uint8_t work_mode;
int ret = -1;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
work_mode = pSW->sink.work_mode;
// 本次状态和上次一致,直接跳过,不重复下发寄存器
if (work_mode == last_state[idx]) {
return 0;
}
switch(work_mode){
case SINK_WORK_INIT:
ret = chrg_sink_work_init(idx,pSW);
break;
case SINK_WORK_WAIT:
ret = 0;
break;
case SINK_WORK_RUNING:
ret = chrg_sink_work_volt_runing(idx,pSW);
break;
case SINK_WORK_ON_TEST_DYNA:
ret = chrg_sink_TEST_DYNA_ON(idx,pSW);
break;
case SINK_WORK_ON_TEST_SHORT:
ret = chrg_sink_TEST_SHORT_ON(idx,pSW);
break;
case SINK_WORK_LOW:
ret = chrg_sink_nor_work_low(idx,pSW);
break;
case SINK_WORK_STOP:
ret = chrg_sink_nor_work_off(idx,pSW);
break;
case SINK_WORK_SWITCH:
ret = chrg_sink_work_switch(idx,pSW);
break;
default:
break;
}
if (ret == 0) {
last_state[idx] = work_mode;
}
return ret;
}