refactor: 重构南向充电控制与参数管理逻辑
1. apps/chrg/applications/thread/chrg_south.c: 新增支持YM_CAN应答类型处理 2. apps/chrg/applications/utils/chrg_source.h: 移除冗余的max_vol、protective_curr字段 3. apps/chrg/applications/utils/chrg_sink.h: 新增OCP测试状态枚举与注释 4. apps/chrg/applications/thread/chrg_comm.h: 移除废弃的sink_proto_diff_t结构体及相关声明 5. apps/chrg/applications/thread/chrg_roll_sou.h/.c: 重构南向升级逻辑,新增帧缓存与安全发送机制 6. apps/chrg/applications/utils/chrg_eload.c: 重构Ymodem应答队列,优化并发访问处理 7. apps/chrg/applications/utils/chrg_sink.c: 新增OCP测试功能实现与状态切换逻辑 8. apps/chrg/applications/utils/chrg_source.c: 替换protective_curr为vc.set_current,移除冗余enable标志 9. apps/chrg/applications/thread/chrg_north.c: 重构电源电压控制逻辑,简化快充输出流程 10. apps/chrg/applications/thread/chrg_comm.c: 全面重构Ymodem升级协议与参数差异处理逻辑
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -19,24 +19,6 @@
|
||||
|
||||
#define MB_HANDLERS_MAX (16)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//北向协议设置
|
||||
rt_uint8_t proto_changed;
|
||||
rt_uint8_t group_changed;
|
||||
rt_uint16_t pro_volt_changed;
|
||||
rt_uint16_t pro_curr_changed;
|
||||
//南向功率设置
|
||||
rt_uint8_t volt_changed;
|
||||
rt_uint8_t curr_changed;
|
||||
rt_uint8_t ccset_changed;
|
||||
rt_uint8_t cvmode_changed;
|
||||
} sink_proto_diff_t;
|
||||
static void chrg_sink_get_proto_diff(struct chrg_switch_t *pReal,
|
||||
struct chrg_switch_t *pShadow,
|
||||
sink_proto_diff_t *pDiff,
|
||||
rt_uint8_t *pNoChange);
|
||||
|
||||
typedef enum {
|
||||
MB_REG_READ, /*!< Read register values and pass to protocol stack. */
|
||||
MB_REG_WRITE /*!< Update register values. */
|
||||
@@ -228,8 +210,6 @@ extern void chrg_comm_thread_entry (void *data);
|
||||
|
||||
extern rt_uint8_t chrg_com_sink_on(rt_uint8_t ch, struct chrg_switch_t *pSW, rt_uint8_t *enable);
|
||||
extern rt_uint8_t chrg_com_source_on(rt_uint8_t ch, rt_uint8_t protoCmd, struct chrg_switch_t *pSW, rt_uint8_t *enable);
|
||||
extern int chrg_sink_diff_send_reg(eIDX_SOU_CH ch, sink_proto_diff_t *pDiff, struct chrg_switch_t *pReal);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -27,100 +27,6 @@
|
||||
#define SOURCE_VOLT_ERROR_MV 200U
|
||||
#define SOURCE_VOLT_RETRY_FRAMES 3U
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_source_voltage_control
|
||||
函数描述: 统一处理Source目标电压、误差判断和状态机切换
|
||||
输入参数: idx:当前通道 pSW:通道控制结构体 volt_mv:目标电压(mV)
|
||||
curr_ma:目标电流(mA)
|
||||
输出参数: 更新source.vc及source.work_mode
|
||||
返回说明: 0:状态处理成功 <0:参数错误或命令提交失败
|
||||
其它说明: 目标电压变化时立即进入RUNING;实际电压与目标值的绝对误差
|
||||
小于等于200mV时进入WAIT;连续3次超过误差范围时重发
|
||||
*****************************************************************/
|
||||
static int chrg_source_voltage_control(eIDX_SOU_CH idx,
|
||||
struct chrg_switch_t *pSW,
|
||||
rt_uint16_t volt_mv,
|
||||
rt_uint16_t curr_ma)
|
||||
{
|
||||
rt_uint16_t volt_error;
|
||||
static rt_uint16_t last_volt_mv[TOTAL_SOU_CHS] = {0};
|
||||
static rt_uint8_t last_volt_valid[TOTAL_SOU_CHS] = {0};
|
||||
static rt_uint8_t last_protocol[TOTAL_SOU_CHS] = {0};
|
||||
static rt_uint8_t volt_retry_count[TOTAL_SOU_CHS] = {0};
|
||||
rt_bool_t need_set = RT_FALSE;
|
||||
int ret;
|
||||
|
||||
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 保存本次目标值,RUNING状态只使用其中的目标电压下发命令。 */
|
||||
pSW->source.vc.set_voltage = volt_mv;
|
||||
pSW->source.vc.set_current = curr_ma;
|
||||
|
||||
if (!pSW->source.On_Flag) {
|
||||
/* 关机后清除历史缓存,下一次启动必须重新设置目标电压。 */
|
||||
last_volt_valid[idx] = 0;
|
||||
volt_retry_count[idx] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 使用绝对误差,避免实际电压低于目标值时发生无符号下溢。 */
|
||||
volt_error = (pSW->Now_voltage >= volt_mv) ?
|
||||
(pSW->Now_voltage - volt_mv) :
|
||||
(volt_mv - pSW->Now_voltage);
|
||||
|
||||
if (!last_volt_valid[idx] ||
|
||||
(last_protocol[idx] != (rt_uint8_t)pSW->source.protocol) ||
|
||||
(volt_mv != last_volt_mv[idx])) {
|
||||
/* 首次设置、协议切换或目标变化时立即下发新电压。 */
|
||||
need_set = RT_TRUE;
|
||||
} else if (volt_error <= SOURCE_VOLT_ERROR_MV) {
|
||||
/* 实际电压误差不超过200mV即可视为设置成功。 */
|
||||
volt_retry_count[idx] = 0;
|
||||
} else {
|
||||
/* 给功率板三个反馈周期的稳定时间,避免每帧重复写电压。 */
|
||||
if (volt_retry_count[idx] < SOURCE_VOLT_RETRY_FRAMES) {
|
||||
volt_retry_count[idx]++;
|
||||
}
|
||||
if (volt_retry_count[idx] >= SOURCE_VOLT_RETRY_FRAMES) {
|
||||
need_set = RT_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
pSW->source.work_mode = need_set ?
|
||||
SOURCE_WORK_RUNING : SOURCE_WORK_WAIT;
|
||||
ret = chrg_source_work_state(idx, pSW);
|
||||
if ((ret == 0) && need_set) {
|
||||
/* 只有命令成功提交后才更新缓存,失败时下一次继续重试。 */
|
||||
last_volt_mv[idx] = volt_mv;
|
||||
last_protocol[idx] = (rt_uint8_t)pSW->source.protocol;
|
||||
last_volt_valid[idx] = 1;
|
||||
volt_retry_count[idx] = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_source_standard_output
|
||||
函数描述: 使用COM配置值驱动标准协议电源输出
|
||||
输入参数: idx:当前通道 pSW:通道控制结构体
|
||||
输出参数: 更新source.vc及source.work_mode
|
||||
返回说明: 无返回值
|
||||
其它说明: 外部协议值0x20映射为PRO_NONE;本函数不解析北向协议返回
|
||||
数据,目标电压和保护电流直接使用COM配置值
|
||||
*****************************************************************/
|
||||
void chrg_source_standard_output(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
{
|
||||
if (pSW == RT_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
(void)chrg_source_voltage_control(idx, pSW,
|
||||
pSW->source.max_vol, pSW->source.protective_curr);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_source_parse
|
||||
函数描述: 按电源协议类型处理目标电压并驱动Source状态机
|
||||
@@ -128,9 +34,8 @@ void chrg_source_standard_output(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
pNOR:北向总控结构体
|
||||
输出参数: 更新电压、电流、source.work_mode及电压重试计数
|
||||
返回说明: -
|
||||
其它说明: 标准协议不解析frame_data,直接使用COM配置值;快充协议读取
|
||||
frame_data[8~11]中的协商目标值。新目标立即进入RUNING,
|
||||
实际误差连续3帧超过200mV时重发
|
||||
其它说明: 标准协议只在本函数中识别,不使用北向返回值控制输出;快充协议
|
||||
读取frame_data[8~11]中的协商目标值,并统一交给RUNING状态比较
|
||||
*****************************************************************/
|
||||
void chrg_source_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
||||
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
|
||||
@@ -142,19 +47,22 @@ void chrg_source_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
||||
return;
|
||||
}
|
||||
|
||||
/* 标准协议使用COM设定值,不读取北向协议返回帧。 */
|
||||
/* 标准协议仍在北向解析入口处判断,但输出已经由INIT/COM直接完成。
|
||||
* 不读取北向返回电压,也不在这里重复下发南向电压。 */
|
||||
if (pSW->source.protocol == PRO_NONE) {
|
||||
chrg_source_standard_output(idx, pSW);
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame_data == RT_NULL) {
|
||||
if ((frame_data == RT_NULL) || !pSW->source.On_Flag) {
|
||||
return;
|
||||
}
|
||||
volt_mv = (frame_data[8] << 8) | frame_data[9];
|
||||
curr_ma = (frame_data[10] << 8) | frame_data[11];
|
||||
/* 快充只负责解析北向协商结果,后续控制逻辑与标准协议共用。 */
|
||||
(void)chrg_source_voltage_control(idx, pSW, volt_mv, curr_ma);
|
||||
pSW->source.vc.set_voltage = volt_mv;
|
||||
pSW->source.vc.set_current = curr_ma;
|
||||
/* 北向只负责提取本次返回值;新旧电压比较放在RUNING状态完成。 */
|
||||
pSW->source.work_mode = SOURCE_WORK_RUNING;
|
||||
(void)chrg_source_work_state(idx, pSW);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -171,12 +79,9 @@ void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
||||
{
|
||||
//执行输出调整
|
||||
if (pSW->source.On_Flag == 1) {
|
||||
if(pSW->source.protocol == PRO_NONE){//标准下输出设定值
|
||||
chrg_source_standard_output(idx, pSW);
|
||||
}
|
||||
else{ //快充部分按协商结果输出
|
||||
if (pSW->source.protocol != PRO_NONE) {
|
||||
/* 标准协议不依赖北向返回值;快充协议继续解析协商结果。 */
|
||||
chrg_source_parse(frame_data, idx, pSW, pNOR);
|
||||
// rt_kprintf("set_end\r\n");
|
||||
}
|
||||
}else if(pSW->source.On_Flag == 0){
|
||||
//chrg_source_stop(frame_data,pSW,idx,&pNOR->enable[idx]);
|
||||
|
||||
@@ -34,6 +34,42 @@ struct chrg_rollsou_t chrgrollsou = {
|
||||
.part = MB_R_PART1,
|
||||
|
||||
};
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_send_sou_upadata_data
|
||||
函数描述: 缓存一帧升级数据并切换南向线程到升级发送状态
|
||||
输入参数: buf:升级帧数据 leng:升级帧长度
|
||||
输出参数: -
|
||||
返回说明: 0:提交成功 -1:参数错误 -2:上一帧尚未发送 -3:互斥锁超时
|
||||
其它说明: 使用结构体内部数组保存数据,防止COM接收缓存变化导致升级帧损坏
|
||||
*****************************************************************/
|
||||
int chrg_send_sou_upadata_data(const rt_uint8_t *buf, rt_uint16_t leng)
|
||||
{
|
||||
struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU];
|
||||
struct chrg_rollsou_t *pROLL = &chrgrollsou;
|
||||
|
||||
if ((buf == RT_NULL) || (leng == 0) || (leng > sizeof(pROLL->updata_buf)) ||
|
||||
(pTHR->mutex == RT_NULL)) {
|
||||
return -1;
|
||||
}
|
||||
if (rt_mutex_take(pTHR->mutex,
|
||||
rt_tick_from_millisecond(SOU_MUTEX_TIMEOUT_MS)) != RT_EOK) {
|
||||
return -3;
|
||||
}
|
||||
if (pROLL->send_flag != 0) {
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
return -2;
|
||||
}
|
||||
|
||||
memcpy(pROLL->updata_buf, buf, leng);
|
||||
pROLL->leng = leng;
|
||||
pROLL->updata_result = 0;
|
||||
pROLL->send_flag = 1;
|
||||
pROLL->run = RUN_UPDATA;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//向通道批量缓存添加一条寄存器
|
||||
int chrg_sou_com_batch_submit(eIDX_SOU_CH ch, const rt_uint16_t *regs,
|
||||
const rt_uint16_t *vals, rt_uint8_t count)
|
||||
@@ -523,7 +559,7 @@ void chrg_roll_sou_thread_entry (void *data)
|
||||
single_value = pROLL->value;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
command_valid = RT_FALSE;
|
||||
if (run != RUN_COM) {
|
||||
if ((run != RUN_COM) && (run != RUN_UPDATA)) {
|
||||
retry_count = 0;
|
||||
}
|
||||
// rt_kprintf("------ROLL SOU START \n--------");
|
||||
@@ -570,6 +606,28 @@ void chrg_roll_sou_thread_entry (void *data)
|
||||
}
|
||||
break;
|
||||
|
||||
case RUN_UPDATA:
|
||||
{
|
||||
/*
|
||||
* 升级响应是单字节ACK/NAK/C,不是Modbus消息,因此本分支发送后
|
||||
* 直接返回循环,由COM升级状态机读取响应,不能进入下方邮箱等待。
|
||||
*/
|
||||
if ((pROLL->mode != 1) || (pROLL->send_flag == 0) ||
|
||||
(pROLL->leng == 0) || (pROLL->leng > sizeof(pROLL->updata_buf))) {
|
||||
rt_thread_mdelay(1);
|
||||
continue;
|
||||
}
|
||||
chrg_south_switch((eIDX_SOU_CH)single_ch);
|
||||
ret = chrg_eload_send_ymodem_data(pROLL->updata_buf, pROLL->leng);
|
||||
|
||||
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
|
||||
pROLL->updata_result = (rt_int16_t)ret;
|
||||
pROLL->send_flag = 0;
|
||||
rt_mutex_release(pTHR->mutex);
|
||||
rt_thread_mdelay(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
case RUN_CONSOLE: {
|
||||
chrg_south_switch((eIDX_SOU_CH)single_ch);
|
||||
chrg_eload_refresh(ID_ELOAD, single_part);
|
||||
|
||||
@@ -48,9 +48,10 @@ struct chrg_rollsou_t {
|
||||
rt_uint16_t reg; // LCD 触发时,寄存器地址
|
||||
rt_uint16_t value; // LCD 触发时,寄存器值
|
||||
|
||||
rt_uint8_t *updata_data;//南向升级的数据
|
||||
rt_uint16_t leng;
|
||||
rt_uint8_t send_flag; //发送标志位
|
||||
rt_uint8_t updata_buf[YMODEM_STX_SIZE];/* 南向升级帧缓存,避免上层缓冲区被提前覆盖 */
|
||||
rt_uint16_t leng; /* 当前待发送升级帧的实际长度 */
|
||||
rt_int16_t updata_result;/* 最近一次升级帧发送结果 */
|
||||
rt_uint8_t send_flag; /* 1:升级帧待发送或正在发送,0:允许提交下一帧 */
|
||||
rt_uint8_t mode;// 0 为正常轮询,1为升级,2为校准
|
||||
};
|
||||
|
||||
@@ -84,7 +85,15 @@ extern void chrg_set_sou_reg_com (eIDX_SOU_CH idx, rt_uint16_t reg, rt_uint16_t
|
||||
*****************************************************************/
|
||||
extern void chrg_roll_sou_thread_entry (void *data);
|
||||
|
||||
extern void chrg_send_sou_upadata_data (rt_uint8_t *buf,rt_uint16_t leng);
|
||||
/*****************************************************************
|
||||
函数名称: chrg_send_sou_upadata_data
|
||||
函数描述: 将一帧升级数据复制到南向升级缓存并唤醒升级发送分支
|
||||
输入参数: buf:升级帧数据 leng:升级帧长度
|
||||
输出参数: -
|
||||
返回说明: 0:提交成功 -1:参数错误 -2:上一帧尚未发送 -3:互斥锁超时
|
||||
其它说明: 数据在函数内完成复制,调用者返回后可以立即复用原缓冲区
|
||||
*****************************************************************/
|
||||
extern int chrg_send_sou_upadata_data(const rt_uint8_t *buf, rt_uint16_t leng);
|
||||
extern int chrg_sou_com_batch_add_reg(eIDX_SOU_CH ch, rt_uint16_t reg, rt_uint16_t val);
|
||||
extern int chrg_sou_com_batch_submit(eIDX_SOU_CH ch, const rt_uint16_t *regs,
|
||||
const rt_uint16_t *vals, rt_uint8_t count);
|
||||
|
||||
@@ -448,7 +448,8 @@ void chrg_south_thread_entry (void *data)
|
||||
rt_uint8_t resp_byte;
|
||||
while (rt_ringbuffer_data_len(pSOU->rb) > 0) {
|
||||
rt_ringbuffer_getchar(pSOU->rb, &resp_byte);
|
||||
if (resp_byte == ACK || resp_byte == NAK || resp_byte == ACK_C) {
|
||||
if (resp_byte == ACK || resp_byte == NAK ||
|
||||
resp_byte == ACK_C || resp_byte == YM_CAN) {
|
||||
chrg_eload_set_ymodem_resp(resp_byte);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,31 @@ static rt_uint8_t g_eload_ymodem_ready = 0; // 应答就绪标志(1=有新应
|
||||
函数描述: 存储南向板返回的ymodem应答字节(由chrg_roll_sou在RUN_UPDATA调用)
|
||||
输入参数: resp: 南向ymodem应答 (ACK=0x06 / NAK=0x15 / 'C'=0x43)
|
||||
*****************************************************************/
|
||||
#define ELOAD_YMODEM_RESP_DEPTH 8
|
||||
static rt_uint8_t g_ymodem_resp_queue[ELOAD_YMODEM_RESP_DEPTH];
|
||||
static rt_uint8_t g_ymodem_resp_read = 0;
|
||||
static rt_uint8_t g_ymodem_resp_write = 0;
|
||||
static rt_uint8_t g_ymodem_resp_count = 0;
|
||||
|
||||
void chrg_eload_set_ymodem_resp(rt_uint8_t resp)
|
||||
{
|
||||
g_eload_ymodem_resp = resp;
|
||||
g_eload_ymodem_ready = 1;
|
||||
rt_base_t level = rt_hw_interrupt_disable();
|
||||
|
||||
/* 队列已满时丢弃周期性的C,保留更关键的ACK/NAK/CAN。 */
|
||||
if (g_ymodem_resp_count >= ELOAD_YMODEM_RESP_DEPTH) {
|
||||
if (resp == ACK_C) {
|
||||
rt_hw_interrupt_enable(level);
|
||||
return;
|
||||
}
|
||||
g_ymodem_resp_read = (g_ymodem_resp_read + 1) % ELOAD_YMODEM_RESP_DEPTH;
|
||||
g_ymodem_resp_count--;
|
||||
}
|
||||
g_ymodem_resp_queue[g_ymodem_resp_write] = resp;
|
||||
g_ymodem_resp_write = (g_ymodem_resp_write + 1) % ELOAD_YMODEM_RESP_DEPTH;
|
||||
g_ymodem_resp_count++;
|
||||
g_eload_ymodem_resp = resp;
|
||||
g_eload_ymodem_ready = 1;
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -45,13 +66,19 @@ void chrg_eload_set_ymodem_resp(rt_uint8_t resp)
|
||||
*****************************************************************/
|
||||
rt_uint8_t chrg_eload_get_ymodem_resp(void)
|
||||
{
|
||||
rt_uint8_t resp = 0;
|
||||
if (g_eload_ymodem_ready) {
|
||||
resp = g_eload_ymodem_resp;
|
||||
g_eload_ymodem_ready = 0;
|
||||
g_eload_ymodem_resp = 0;
|
||||
}
|
||||
return resp;
|
||||
rt_uint8_t resp = 0;
|
||||
rt_base_t level = rt_hw_interrupt_disable();
|
||||
|
||||
if (g_ymodem_resp_count > 0) {
|
||||
resp = g_ymodem_resp_queue[g_ymodem_resp_read];
|
||||
g_ymodem_resp_read = (g_ymodem_resp_read + 1) % ELOAD_YMODEM_RESP_DEPTH;
|
||||
g_ymodem_resp_count--;
|
||||
}
|
||||
g_eload_ymodem_ready = (g_ymodem_resp_count > 0);
|
||||
g_eload_ymodem_resp = g_eload_ymodem_ready ?
|
||||
g_ymodem_resp_queue[g_ymodem_resp_read] : 0;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -60,8 +87,15 @@ rt_uint8_t chrg_eload_get_ymodem_resp(void)
|
||||
*****************************************************************/
|
||||
void chrg_eload_clear_ymodem_resp(void)
|
||||
{
|
||||
g_eload_ymodem_resp = 0;
|
||||
g_eload_ymodem_ready = 0;
|
||||
rt_base_t level = rt_hw_interrupt_disable();
|
||||
|
||||
g_ymodem_resp_read = 0;
|
||||
g_ymodem_resp_write = 0;
|
||||
g_ymodem_resp_count = 0;
|
||||
g_eload_ymodem_resp = 0;
|
||||
g_eload_ymodem_ready = 0;
|
||||
rt_memset(g_ymodem_resp_queue, 0, sizeof(g_ymodem_resp_queue));
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
static int memcmp_8bytes(const rt_uint8_t *buf1, const rt_uint8_t *buf2)
|
||||
|
||||
@@ -144,10 +144,14 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
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) {
|
||||
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 == 3) {
|
||||
} else if (pSW->sink.test.test_mode_old == SINK_TEST_OCP) {
|
||||
/* 从OCP测试返回普通负载时,先停止功率板的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;
|
||||
}
|
||||
@@ -159,7 +163,6 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
}
|
||||
|
||||
pSW->sink.On_work = 1;
|
||||
pSOU->enable[idx] = 1;
|
||||
pSOU->online[idx] = 1;
|
||||
pNOR->enable[idx] = 1;
|
||||
|
||||
@@ -315,6 +318,36 @@ static int chrg_sink_TEST_SHORT_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||
return chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 3);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_sink_TEST_OCP_ON
|
||||
函数描述: 配置并启动负载OCP过流保护测试
|
||||
输入参数: ch:南向功率通道编号 pSW:当前通道控制结构体
|
||||
输出参数: -
|
||||
返回说明: 0:命令提交成功 非0:命令提交失败
|
||||
其它说明: 一次提交功率继电器、OCP参数、测试命令和WORK_START;
|
||||
set_mode为0时保持指定时间后恢复,为1时一直保持
|
||||
*****************************************************************/
|
||||
static int chrg_sink_TEST_OCP_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
||||
{
|
||||
struct test_OCP *pOCP = &pSW->sink.test.OCP_test;
|
||||
rt_uint16_t regs[11] = {REG_REL_ON, REG_REL_ON,
|
||||
ModbusRTU_OCPTest_StartCurrent, ModbusRTU_OCPTest_StopCurrent,
|
||||
ModbusRTU_OCPTest_Step_CURR, ModbusRTU_OCPTest_Step_Hold_Time,
|
||||
ModbusRTU_OCPTest_Vtrig_Stop, ModbusRTU_OCPTest_Hold_Time,
|
||||
ModbusRTU_OCPTest_HOLD_CURR, ModbusRTU_OCPTest_CMD_MODE_FLAG,
|
||||
REG_WORK};
|
||||
rt_uint16_t vals[11] = {0x02, 0x03,
|
||||
pOCP->start_curr, pOCP->end_curr, pOCP->change_curr,
|
||||
pOCP->change_keep_time, pOCP->stop_volt, pOCP->hold_time,
|
||||
pOCP->hold_curr, ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR,
|
||||
WORK_START};
|
||||
|
||||
if (pOCP->set_mode != 0) {
|
||||
vals[9] = ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP;
|
||||
}
|
||||
return chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 11);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
函数名称: chrg_sink_work
|
||||
@@ -354,6 +387,9 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
case SINK_WORK_ON_TEST_SHORT:
|
||||
ret = chrg_sink_TEST_SHORT_ON(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_ON_TEST_OCP:
|
||||
ret = chrg_sink_TEST_OCP_ON(idx,pSW);
|
||||
break;
|
||||
case SINK_WORK_LOW:
|
||||
ret = chrg_sink_nor_work_low(idx,pSW);
|
||||
break;
|
||||
|
||||
@@ -211,6 +211,7 @@ enum {
|
||||
SINK_WORK_SWITCH, // 停止旧电源后进入负载INIT
|
||||
SINK_WORK_ON_TEST_DYNA,
|
||||
SINK_WORK_ON_TEST_SHORT,
|
||||
SINK_WORK_ON_TEST_OCP, // 配置并启动OCP过流保护测试
|
||||
};
|
||||
|
||||
// sink 参数结构
|
||||
@@ -234,11 +235,9 @@ struct chrg_sink_t {
|
||||
rt_uint8_t work_mode; // 0=停止 1=工作 2=低电压
|
||||
};
|
||||
|
||||
|
||||
//纹波寄存器
|
||||
#define ModbusRTU_Ripple_Value 0x35 //读取纹波
|
||||
|
||||
|
||||
/******************** 负载测试 ************************* */
|
||||
#define ModbusRTU_CAL_WriteEnable 0x34 //使能写入;0x4361代表使能写入;C+a ASCII码
|
||||
#define ModbusRTU_Test_CMD 0x4361 //
|
||||
|
||||
@@ -41,7 +41,7 @@ int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW)
|
||||
pSW->CV_mode,
|
||||
0x03,
|
||||
0,
|
||||
pSW->source.protective_curr,
|
||||
pSW->source.vc.set_current,
|
||||
WORK_START
|
||||
};
|
||||
|
||||
@@ -72,8 +72,7 @@ static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||
}
|
||||
|
||||
pSW->source.On_Flag = 1;
|
||||
pSOU->enable[idx] = 1;
|
||||
pNOR->enable[idx] = 1;
|
||||
pNOR->enable[idx] = 1;
|
||||
pSOU->online[idx] = 1;
|
||||
chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SOURCE);
|
||||
pSW->source.work_mode = SOURCE_WORK_WAIT;
|
||||
@@ -902,8 +901,8 @@ rt_uint8_t pd_fill_single_group_need_src_com(rt_uint8_t *data, rt_uint8_t start_
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
data[idx++] = source->vc.set_current >> 8;
|
||||
data[idx++] = source->vc.set_current & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
@@ -914,11 +913,11 @@ rt_uint8_t pd_fill_single_group_need_src_com(rt_uint8_t *data, rt_uint8_t start_
|
||||
data[idx++] = source->min_vol >> 8;
|
||||
data[idx++] = source->min_vol & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
data[idx++] = source->vc.set_voltage >> 8;
|
||||
data[idx++] = source->vc.set_voltage & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
data[idx++] = source->vc.set_current >> 8;
|
||||
data[idx++] = source->vc.set_current & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
@@ -936,11 +935,11 @@ rt_uint8_t pd_fill_single_group_no_src_com(rt_uint8_t *data, rt_uint8_t start_id
|
||||
data[idx++] = source->min_vol >> 8;
|
||||
data[idx++] = source->min_vol & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
data[idx++] = source->vc.set_voltage >> 8;
|
||||
data[idx++] = source->vc.set_voltage & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
data[idx++] = source->vc.set_current >> 8;
|
||||
data[idx++] = source->vc.set_current & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
@@ -961,8 +960,8 @@ rt_uint8_t pd_fill_single_group_FCP_AFC(rt_uint8_t *data, rt_uint8_t start_idx,s
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
data[idx++] = source->vc.set_current >> 8;
|
||||
data[idx++] = source->vc.set_current & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
@@ -970,14 +969,14 @@ rt_uint8_t pd_fill_single_group_FCP_AFC(rt_uint8_t *data, rt_uint8_t start_idx,s
|
||||
data[idx++] = 0x00;
|
||||
data[idx++] = 0x00;
|
||||
// 2. 最小电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
data[idx++] = source->vc.set_voltage >> 8;
|
||||
data[idx++] = source->vc.set_voltage & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
data[idx++] = source->vc.set_voltage >> 8;
|
||||
data[idx++] = source->vc.set_voltage & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
data[idx++] = source->vc.set_current >> 8;
|
||||
data[idx++] = source->vc.set_current & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
@@ -998,8 +997,8 @@ rt_uint8_t pd_fill_single_group_UFCS(rt_uint8_t *data, rt_uint8_t start_idx,stru
|
||||
data[idx++] = 0x13;
|
||||
data[idx++] = 0x88;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
data[idx++] = source->vc.set_current >> 8;
|
||||
data[idx++] = source->vc.set_current & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
@@ -1010,11 +1009,11 @@ rt_uint8_t pd_fill_single_group_UFCS(rt_uint8_t *data, rt_uint8_t start_idx,stru
|
||||
data[idx++] = source->min_vol >> 8;
|
||||
data[idx++] = source->min_vol & 0xFF;
|
||||
// 3. 最大电压(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->max_vol >> 8;
|
||||
data[idx++] = source->max_vol & 0xFF;
|
||||
data[idx++] = source->vc.set_voltage >> 8;
|
||||
data[idx++] = source->vc.set_voltage & 0xFF;
|
||||
// 4. 电流/功率(高+低,直接取已拆分好的值)
|
||||
data[idx++] = source->protective_curr >> 8;
|
||||
data[idx++] = source->protective_curr & 0xFF;
|
||||
data[idx++] = source->vc.set_current >> 8;
|
||||
data[idx++] = source->vc.set_current & 0xFF;
|
||||
// 5. 保留位6字节(直接填0)
|
||||
memset(&data[idx], 0x00, 6);
|
||||
idx+=6;
|
||||
|
||||
@@ -150,10 +150,8 @@ struct chrg_src_t {
|
||||
rt_uint8_t pps; // PPS类型
|
||||
rt_uint8_t pro_gear_idx; // 挡位
|
||||
rt_uint16_t min_vol; // 最小电压 mV
|
||||
rt_uint16_t max_vol; // 最大电压 mV
|
||||
rt_uint8_t vol_lvl; // CC线电平
|
||||
rt_uint8_t cc_set; // cc线选择 //0代表1+2,1代表cc1,2代表cc2
|
||||
rt_uint16_t protective_curr; // 保护电流
|
||||
rt_uint8_t Now_State; // 当前状态
|
||||
rt_uint8_t On_Flag; // 启动总标志(0/1)
|
||||
rt_uint8_t LCD_Set_Pro_Flag; // LCD设置协议标志位
|
||||
|
||||
Reference in New Issue
Block a user