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代码,简化启动流程
633 lines
22 KiB
C
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, ®, &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;
|
|
}
|
|
|
|
|
|
|