diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index 429bb4d..1e875a4 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -1022,378 +1022,6 @@ eMBException funcWriteMultipleCoils (rt_uint8_t *reqFrame, rt_uint16_t reqLen, return eStatus; } -static void parse_load_no_group(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen, struct chrg_switch_t *pSW) -{ - rt_uint16_t volt_mv = 0; // 协议请求电压(mV) - rt_uint16_t curr_ma = 0; // 负载电流(mA) - - // 数据区索引:0=状态+通道,1=CC线,2,选择恒压恒流模式3-4=电压,5-6=电流,6-7=保留 - volt_mv = u8v_to_u16(&pData[3]); // 电压(mV,大端) - curr_ma = u8v_to_u16(&pData[5]); // 电流(mA,大端) - - // 按协议命令码赋值 - switch (protoCmd) - { - case 0x11: // QC2.0 - pSW->sink.protocol = LOAD_PRO_QC20; - break; - case 0x12: // QC3.0 - pSW->sink.protocol = LOAD_PRO_QC30; - break; - case 0x13: // FCP - pSW->sink.protocol = LOAD_PRO_FCP; - break; - case 0x14: // AFC - pSW->sink.protocol = LOAD_PRO_AFC; - break; - case 0x15: // SCP - pSW->sink.protocol = LOAD_PRO_SCP; - break; - case 0x16: // VIVO - pSW->sink.protocol = LOAD_PRO_VIVO; - break; - case 0x17: // TFC - pSW->sink.protocol = LOAD_PRO_TFC_RFC; - break; - default: - rt_kprintf("无组号负载协议不支持:0x%02X\n", protoCmd); - return; - } - - // 赋值通用参数 - pSW->sink.loadv = volt_mv; - pSW->sink.loadc = curr_ma; - pSW->sink.Pro_Group = 0; // 无组号 - rt_kprintf("pro=%d,volt_mv=%d,curr=%d",pSW->sink.protocol,volt_mv,curr_ma); -} - -static void parse_load_with_group(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t reqLen, struct chrg_switch_t *pSW) -{ - rt_uint8_t group_num = 0; // 组号 - rt_uint16_t volt_mv = 0; // 协议请求电压(mV) - rt_uint16_t curr_ma = 0; // 负载电流(mA) - - // 数据区索引:0=状态+通道,1=CC线,2=恒压恒流模式,3=组号 - group_num = pData[3]; - pSW->sink.Pro_Group = group_num; - - // 按协议命令码分支 - switch (protoCmd) - { - case CMD_LOAD_PD0_MAN: // PD0(手动) - pSW->sink.protocol = LOAD_PRO_PDO_MANUAL; - // PD0特殊:组号后为3个保留2字节,无电压电流 - volt_mv = 0; - curr_ma = 0; - break; - case CMD_LOAD_PD0_AUTO: // PDO自动 - pSW->sink.protocol = LOAD_PRO_PDO_AUTO; - volt_mv = u8v_to_u16(&pData[4]); // 4-5=电压 - curr_ma = u8v_to_u16(&pData[6]); // 6-7=电流 - break; - case CMD_LOAD_PPS_MAN: // PPS(手动) - pSW->sink.protocol = LOAD_PRO_PPS_MANUAL; - volt_mv = u8v_to_u16(&pData[4]); - curr_ma = u8v_to_u16(&pData[6]); - break; - case CMD_LOAD_PPS_AUTO: // PPS(自动) - pSW->sink.protocol = LOAD_PRO_PPS_AUTO; - volt_mv = u8v_to_u16(&pData[4]); - curr_ma = u8v_to_u16(&pData[6]); - break; - case CMD_LOAD_PD31: // PD3.1 - pSW->sink.protocol = LOAD_PRO_PD31AVS; - volt_mv = u8v_to_u16(&pData[4]); - curr_ma = u8v_to_u16(&pData[6]); - break; - case CMD_LOAD_UFCS: // UFCS - pSW->sink.protocol = LOAD_PRO_UFCS; - volt_mv = u8v_to_u16(&pData[4]); - curr_ma = u8v_to_u16(&pData[6]); - break; - case CMD_LOAD_VOOC: // VOOC - pSW->sink.protocol = LOAD_PRO_VOOC; - volt_mv = 0; - curr_ma = 0; - break; - case CMD_LOAD_AVS: // AVS - pSW->sink.protocol = LOAD_PRO_AVS; - volt_mv = u8v_to_u16(&pData[4]); - curr_ma = u8v_to_u16(&pData[6]); - break; - default: - rt_kprintf("有组号负载协议不支持:0x%02X\n", protoCmd); - return; - } - rt_kprintf("volt_mv=%d,curr_ma=%d\n",volt_mv,curr_ma); - // 赋值通用参数 - pSW->sink.loadv = volt_mv; - pSW->sink.loadc = curr_ma; - -} - -// //sink开机函数 -// rt_uint8_t chrg_com_sink_on(rt_uint8_t ch, struct chrg_switch_t *pSW, rt_uint8_t *enable){ - -// *enable = 1; -// pSW->id = ID_SINK; -// pSW->sub = IDX_SET_SINK_CURR; -// pSW->change_flag = 0x01; -// pSW->sink.work_on_step = 0; -// return 0; -// } - -//source开机函数 -rt_uint8_t chrg_com_source_on(rt_uint8_t ch, rt_uint8_t protoCmd, struct chrg_switch_t *pSW, rt_uint8_t *enable){ - *enable = 1; - pSW->id = ID_SOURCE; - pSW->source.LCD_Set_Pro_Flag=3; - pSW->sub = IDX_SET_SOURCE_ID; - pSW->change_flag = 0x01; - pSW->continue_flag = 1; - return 0; -} - -/***************************************************************** -函数名称: funcWriteProtoCal -函数描述: 写入协议 -输入参数: reqFrame: 请求数据 reqLen: 请求长度 resFrame:响应数据 resLen:响应长度 -输出参数: - -返回说明: - -其它说明: - -*****************************************************************/ -eMBException funcWriteProtoCal (rt_uint8_t *reqFrame, rt_uint16_t reqLen, - rt_uint8_t *resFrame, rt_uint16_t *resLen) -{ - /************ 局部变量定义 ************/ - struct chrg_north_t *pNOR = &chrgnorth; - struct chrg_south_t *pSOU = &chrgsouth; - struct chrg_switch_t *pSW = RT_NULL; - - rt_uint8_t slaveAddr = 0; // 从机地址(0x01~0xFF) - rt_uint8_t protoCmd = 0; // 协议命令码(0x11~0x1F/0x22~0x2C/0x2F) - rt_uint16_t regAddress = 0; // 寄存器起始地址 - rt_uint8_t *pData = RT_NULL; // 协议数据区起始指针(状态+通道字段开始) - rt_uint8_t statusChByte = 0;// 状态+通道字节(reqFrame[5]) - eIDX_SOU_CH ch = IDX_SOU_CH1;// 通道号(1~4) - rt_uint8_t chNum = 0; // 通道号数值(1~4) - rt_uint8_t devStatus = 0; // 设备状态(0=不变,1=开机,2=关机) - rt_uint8_t ccSel = 0; // CC线选择(0=CC1+CC2,1=CC1,2=CC2,3=断开) -// *g_proto_pData = RT_NULL; - g_proto_reqLen = 0; - // Modbus异常码 - eMBException eStatus = MB_EX_NONE; - eMBErrorCode eRegStatus; - rt_uint16_t reg_offset = 0; - rt_uint16_t sout_reg = 0; - rt_uint16_t sou_value = 0; - - /************ 校验 ************/ - // 最小帧长度:地址(1)+命令码(1)+寄存器(2)+数据区(至少1)+校验(2) = 7字节 - if (reqLen < 7) { - rt_kprintf("The long error:%d must more 7\n", reqLen); - return MB_EX_ILLEGAL_DATA_VALUE; - } - - /************ 解析帧 ************/ - slaveAddr = reqFrame[0]; // 从机地址(0x01~0xFF) - protoCmd = reqFrame[3]; // 协议命令码(负载0x11~0x1F,电源0x22~0x2C/0x2F) - rt_kprintf("pro=%04x\n",protoCmd); - pData = &reqFrame[4]; // 数据区起始(跳过地址+命令码+寄存器) - statusChByte = pData[0]; // 状态+通道字节(数据区第1字节) - - /************ 地址校验 ************/ - if (protoCmd < PRO_REG_START || protoCmd >= TOTAL_PROTOCAL_CNT) { - rt_kprintf("Address error:0x%04X\n", protoCmd); - return MB_EX_ILLEGAL_DATA_ADDRESS; - } - - /************ 提取通道号和状态 ************/ - // bit0-3:状态(0=不变,1=开机,2=关机) - devStatus = statusChByte & 0x0F; - rt_kprintf("status=%d",devStatus); - // bit4-7:通道号(1=CH1,2=CH2,3=CH3,4=CH4) - chNum = (statusChByte >> 4) & 0x0F; - ccSel = pData[1]; - rt_uint8_t cv_mode = pData[2]; - // 通道号合法性校验 - if (chNum < 1 || chNum > 4) { - rt_kprintf("通道号非法:%d(仅支持1~4)\n", chNum); - return MB_EX_ILLEGAL_DATA_ADDRESS; - } - ch = (eIDX_SOU_CH)(chNum - 1); // 转换为枚举类型(IDX_SOU_CH1=0) - /************ 硬件结构体绑定 ************/ - if (pNOR == RT_NULL) { - rt_kprintf("ERROR: pNOR is NULL!\n"); - return MB_EX_SLAVE_DEVICE_FAILURE; - } - pSW = &pNOR->sw[ch]; // 绑定当前通道的协议配置结构体 - pSW->protoCmd = protoCmd; //com端协议命令码 - pSW->CV_mode = cv_mode; //恒压恒流模式选择 - - rt_memcpy(g_proto_pData, pData, reqLen - 4); - g_proto_reqLen = reqLen; - rt_kprintf("com_recitive\n"); - /************ 按「负载/电源」分支解析 ************/ - // ========== 负载协议解析 (0x11~0x1F) ========== - if (protoCmd >= 0x11 && protoCmd <= 0x1F) { - pSW->sink.cc_set = ccSel; //负载CC线选择 - if(pSW->source.On_Flag){ //负载切电源 - pSW->source.change_sink_Flag = 1; - chrg_sou_stop(ch,pSW,pNOR); - }else{ - if(devStatus==2){ //负载关机 - chrg_sou_stop(ch,pSW,pNOR); - } - else if(devStatus==1){ //负载开机 - //chrg_com_sink_on(ch,pSW,&pNOR->enable[ch]); - } - } - } - // ==========电源协议解析 (0x22~0x2C/0x2F) ========== - else if ((protoCmd >= 0x22 && protoCmd <= 0x2C) || protoCmd == 0x2F) { - pSW->source.cc_set = ccSel; //电源CC线选择 - if(pSW->sink.On_work){ //电源切负载 - pSW->sink.change_source_flag = 1; - chrg_sou_stop(ch,pSW,pNOR); - }else{ - if(devStatus==2){ //电源关机 - chrg_sou_stop(ch,pSW,pNOR); - }else if(devStatus==1){ //电源开机 - chrg_com_source_on(ch,pSW->protoCmd,pSW,&pNOR->enable[ch]); - } - } - } - // ========== 非法命令码 ========== - else { - rt_kprintf("非法协议命令码:0x%02X\n", protoCmd); - return MB_EX_ILLEGAL_FUNCTION; - } - - // /************ 配置参数写入保持寄存器 ************/ - eRegStatus = mb_reg_holding_cb(&reqFrame[4], &resFrame[3], regAddress, 1, MB_REG_WRITE); - if (eRegStatus != MB_ENOERR) { - eStatus = mb_error(eRegStatus); - rt_kprintf("寄存器写入失败:%d\n", eRegStatus); - } - - /************ 构建响应帧 ************/ - rt_memcpy(resFrame, reqFrame, reqLen); - *resLen = reqLen - 2; // 去掉CRC校验位 - - /************ 调试输出 ************/ -// rt_kprintf("Pro Set OK:Ch=%d,Pro0x%02X,Status%d,CC Set%d\n", -// chNum, protoCmd, devStatus, ccSel); - return eStatus; -} - -/***************************************************************** -函数名称: funcSinkTest -函数描述: 负载测试 -输入参数: reqFrame: 请求数据 reqLen: 请求长度 resFrame:响应数据 resLen:响应长度 -输出参数: - -返回说明: - -其它说明: - -*****************************************************************/ -eMBException funcSinkTest (rt_uint8_t *reqFrame, rt_uint16_t reqLen, - rt_uint8_t *resFrame, rt_uint16_t *resLen) -{ - /************ 局部变量定义 ************/ - struct chrg_north_t *pNOR = &chrgnorth; - struct chrg_south_t *pSOU = &chrgsouth; - struct chrg_switch_t *pSW = RT_NULL; - - rt_uint8_t slaveAddr = 0; // 从机地址 - rt_uint8_t test_mode = 0; // 测试模式 0x01/0x02/0x03 - rt_uint16_t regAddress = 0; // 寄存器地址 - rt_uint8_t *pData = RT_NULL; // 数据区指针 - rt_uint8_t statusChByte = 0; // 状态+通道字节 - eIDX_SOU_CH ch = IDX_SOU_CH1; // 通道枚举 - rt_uint8_t chNum = 0; // 通道号 1~4 - rt_uint8_t devStatus = 0; // 设备状态 0=启动 1=停止,2=继续,3=结束 - - // Modbus异常 - eMBException eStatus = MB_EX_NONE; - eMBErrorCode eRegStatus; - -// /************ 长度校验 ************/ -// if (reqLen < 11) { -// rt_kprintf("Len error:%d <11\n", reqLen); -// return MB_EX_ILLEGAL_DATA_VALUE; -// } - - /************ 解析帧 ************/ - slaveAddr = reqFrame[0]; - test_mode = reqFrame[3]; // 测试命令:0x01短路 0x02OCP 0x03动态 - pData = &reqFrame[4]; // 数据起始 - statusChByte= pData[0]; // 状态通道字节 - - /************ 地址校验 ************/ - if (test_mode < 0x01 || test_mode > 0x03) { - rt_kprintf("Test mode err:0x%02X\n", test_mode); - return MB_EX_ILLEGAL_DATA_ADDRESS; - } - - /************ 解析状态 & 通道 ************/ - devStatus = statusChByte & 0x0F; // 低4位:状态 - chNum = (statusChByte >> 4) & 0x0F; // 高4位:通道 - - /************ 通道校验 ************/ - if (chNum <1 || chNum>4) { - rt_kprintf("Ch err:%d\n", chNum); - return MB_EX_ILLEGAL_DATA_ADDRESS; - } - ch = (eIDX_SOU_CH)(chNum -1); - - /************ 绑定结构体 ************/ - pSW = &pNOR->sw[ch]; - pSW->sink.test.test_mode = test_mode; //测试模式 - pSW->sink.test.run_flag = devStatus; //设备状态 - pSW->change_flag = 0x01; - struct test *pTset = &pSW->sink.test; - #if SINK_TEST_DEBUG - rt_kprintf("test_mode=%d\n",test_mode); - rt_kprintf("test_flag=%d\n",pTset->test_mode); - #endif - /*********************************************************/ -// switch(test_mode) -// { -// case 0x01: -// // 短路测试(OCPC) -// sink_test_short_set(pSW, pData, devStatus); -// break; -// case 0x02: -// // OCP 测试 -// sink_test_ocp_set(pSW, pData, devStatus); -// break; -// case 0x03: -// // 动态测试 -// sink_test_dynamic_set(pSW, pData, devStatus); -// break; -// default: -// return MB_EX_ILLEGAL_FUNCTION; -// } - /************ 启动 / 停止控制 ************/ - if(devStatus == 0) //启动 - { - pNOR->enable[ch] = 1; - pSW->id = ID_SINK; - pSW->sink.test.work_step = 0; - pSOU->online[ch] = 1; - } - else if(devStatus == 1) //停止 - { - pSW->id = ID_SINK; - pSW->sink.test.stop_step = 0; - rt_kprintf("Sink Test Stop CH%d\n", chNum); - } - - /************ 响应帧 ************/ - rt_memcpy(resFrame, reqFrame, reqLen-2); - *resLen = reqLen -2; - - return eStatus; -} /***************************************************************** 函数名称: funcWriteMultipleHoldingRegister 函数描述: 写多个保持寄存器(0x10) @@ -2170,7 +1798,6 @@ static void chrg_mb_write_src(rt_uint8_t ch, rt_uint16_t reg_offset, rt_uint16_t { case SRC_REG_PROTOCOL: // 0x00: 协议 pSW->source.protocol = src_proto_lookup(sou_value); - pSW->source.Set_Pro_Flag = 1; pSW->protoCmd = (rt_uint8_t)sou_value; // rt_kprintf("[SRC CH%d] Protocol=0x%02X -> 0x%02X\n", ch + 1, sou_value, pSW->source.protocol); break; @@ -2228,7 +1855,6 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_ else if (sou_value == 0x02) { pSW->id = ID_SOURCE; - pSW->source.Set_Pro_Flag = 1; } break; @@ -2271,7 +1897,7 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_ if (sink_work == 0x01) // 负载启动 { rt_uint8_t curr_test = pReal->sink.test.test_mode; - rt_uint8_t curr_test_old = pReal->sink.test.test_mode_old; + rt_uint8_t curr_test_old = pReal->sink.test.test_mode_old; // 测试模式状态发生切换:0<->非0 if ((curr_test_old == 0 && curr_test != 0) || (curr_test == 0 && curr_test_old != 0)) { @@ -2334,11 +1960,15 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_ } else if (new_id == ID_SOURCE && source_work == 0x01) { - chrg_com_source_on(ch, pReal->protoCmd, pReal, &pNOR->enable[ch]); + /* COM只触发状态,初始化命令由Source状态机统一下发。 */ + pReal->source.On_Flag = 1; + pReal->source.work_mode = SOURCE_WORK_INIT; } else if (new_id == ID_SOURCE && source_work == 0x00) { - chrg_sou_stop(ch, pReal, pNOR); + /* 停止动作同样交给状态机处理,避免COM直接控制硬件。 */ + pReal->source.On_Flag = 0; + pReal->source.work_mode = SOURCE_WORK_STOP; } rt_mutex_release(pTHR_NOR->mutex); } diff --git a/apps/chrg/applications/thread/chrg_lcd.c b/apps/chrg/applications/thread/chrg_lcd.c index ba22ca7..90460e5 100644 --- a/apps/chrg/applications/thread/chrg_lcd.c +++ b/apps/chrg/applications/thread/chrg_lcd.c @@ -37,26 +37,6 @@ struct chrg_lcd_t chrglcd = { // 55 41 00 0D 0A 停止 // 55 41 01 0D 0A 运行 -void chrg_sou_work(eIDX_SOU_CH ch,struct chrg_switch_t *pSW) -{ - struct chrg_south_t *pSOU = &chrgsouth; - if(pSW->id == ID_SOURCE){ - chrg_set_sou_reg(ch, REG_WORK, WORK_START); -// rt_thread_mdelay(50); - pSW->source.Set_CV_Flag = 1; - pSW->source.Set_Pro_Flag = 1; - pSW->source.On_Flag = 1; - pSW->sub = IDX_SET_SOURCE_PD; - } - else if(pSW->id == ID_SINK) { - pSW->sink.On_work = 1; - pSW->sub=IDX_SET_SINK_PD; - } - pSOU->online[ch] = 1; - chrg_nor_sw_rel((eIDX_NOR_CH)ch, pSW->id); - rt_thread_mdelay(50); -} - void chrg_sou_stop(eIDX_SOU_CH ch,struct chrg_switch_t *pSW,struct chrg_north_t *pNOR) { struct chrg_south_t *pSOU = &chrgsouth; @@ -64,7 +44,6 @@ void chrg_sou_stop(eIDX_SOU_CH ch,struct chrg_switch_t *pSW,struct chrg_north_t return; } if(pSW->id == ID_SOURCE){ - pSW->source.Stop_step_flag = 0; pSW->source.On_Flag = 0; pSW->sub = IDX_GET_SOURCE_VC; } @@ -82,7 +61,6 @@ int chrg_pro_set(struct chrg_switch_t *pSW, rt_uint8_t protocol){ if (pSW->id == ID_SOURCE) { // Source端 pSW->source.protocol = protocol; - pSW->source.LCD_Set_Pro_Flag = 1; } else if (pSW->id == ID_SINK) { // Sink端 pSW->sink.protocol = protocol; @@ -211,7 +189,6 @@ static int chrg_lcd_parse (rt_uint8_t *recv, rt_uint16_t len) } pNOR->enable[ch] = 1; rt_kprintf("ch=%d\n",ch); - chrg_sou_work((eIDX_SOU_CH)ch,pSW); pSW->continue_flag = 0; } //关闭 @@ -237,7 +214,6 @@ static int chrg_lcd_parse (rt_uint8_t *recv, rt_uint16_t len) // 按角色存入source/sink pSW->source.vc.set_voltage = Recv_Data; // 电源侧电压(mV) pSW->sink.loadv = Recv_Data; // 负载侧电压(mV,) - pSW->source.Set_Pro_Flag = 1; // 写入电压寄存器 if(pSW->id==ID_SINK) { chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_VOLTAGE_OUT+1, Recv_Data); @@ -257,7 +233,6 @@ static int chrg_lcd_parse (rt_uint8_t *recv, rt_uint16_t len) //按角色存入source/sink pSW->source.vc.set_current = Recv_Data; // 电源侧电流(mA) pSW->sink.loadc = Recv_Data; // 负载侧电流(mA) - pSW->source.Set_Pro_Flag = 1; // rt_kprintf("cur=%d",Recv_Data); // 写入电流寄存器 for(int i = 0;i<10;i++){ diff --git a/apps/chrg/applications/thread/chrg_lcd.h b/apps/chrg/applications/thread/chrg_lcd.h index b229c12..b6af7ec 100644 --- a/apps/chrg/applications/thread/chrg_lcd.h +++ b/apps/chrg/applications/thread/chrg_lcd.h @@ -45,7 +45,6 @@ extern void chrg_lcd_thread_entry (void *data); extern rt_uint8_t On_Flag; extern rt_uint8_t Flag_start; -extern void chrg_sou_work(eIDX_SOU_CH ch,struct chrg_switch_t *pSW); extern void chrg_sou_stop(eIDX_SOU_CH ch,struct chrg_switch_t *pSW,struct chrg_north_t *pNOR); extern void chrg_set_eload_sink(eIDX_SOU_CH ch,struct chrg_switch_t *pSW); extern void chrg_set_eload_source(eIDX_SOU_CH ch,struct chrg_switch_t *pSW); diff --git a/apps/chrg/applications/thread/chrg_north.c b/apps/chrg/applications/thread/chrg_north.c index 6b06f2f..3dfc77f 100644 --- a/apps/chrg/applications/thread/chrg_north.c +++ b/apps/chrg/applications/thread/chrg_north.c @@ -30,42 +30,6 @@ uint16_t chrg_compare(rt_int16_t a, rt_int16_t b) else return b - a; } -/***************************************************************** -函数名称: chrg_source_stop -功能描述: 南向功率源停止流程控制函数(分步执行停止操作) -函数描述: 通过状态机分步执行南向功率停止流程:停止功率输出 -> 关闭北向继电器 -> 清空控制标志并禁用使能 -输入参数: - frame_data :原始数据帧指针,用于提取当前电压值 - pSW :北向通道控制结构体指针 - idx :通道编号(功率通道/北向通道索引) - enable :北向通道使能,停止后关掉使能 -返回说明: 无返回值 -*****************************************************************/ -void chrg_source_stop(rt_uint8_t *frame_data,struct chrg_switch_t *pSW,rt_uint8_t idx,rt_uint8_t *enable){ - switch(pSW->source.Stop_step_flag){ - case 0: // 停止工作 - chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_STOP); - rt_thread_mdelay(50); - rt_uint16_t volt_mv_Now = (frame_data[4] << 8) | frame_data[5]; - volt = volt_mv_Now; - if(volt_mv_Now < 1000){ - pSW->source.Stop_step_flag = 1; - } - break; - case 1: // 关闭北向继电器 - chrg_nor_sw_rel((eIDX_NOR_CH)idx,0); - rt_thread_mdelay(50); - pSW->source.Stop_step_flag = 2; - break; - case 2: // 状态2:已执行完停止操作,清空标志位 - pSW->source.Set_CV_Flag = 0; - *enable = 0; - break; - default: - break; - } -} - /***************************************************************** 函数名称: chrg_source_standard_output 功能描述: 南向功率源标准输出控制函数 @@ -97,49 +61,47 @@ void chrg_source_standard_output(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) } //电源快充 -void chrg_source_fast_output(rt_uint8_t *frame_data, eIDX_SOU_CH idx, - struct chrg_switch_t *pSW, struct chrg_north_t *pNOR) +void chrg_source_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx, + struct chrg_switch_t *pSW, struct chrg_north_t *pNOR) { - struct chrg_rollsou_t *pROLL = &chrgrollsou; rt_uint16_t volt_mv = (frame_data[8] << 8) | frame_data[9]; rt_uint16_t Curr_mA = (frame_data[10] << 8) | frame_data[11]; rt_uint16_t volt_mv_Now = (frame_data[4] << 8) | frame_data[5]; rt_uint16_t Curr_mA_Now = (frame_data[6] << 8) | frame_data[7]; rt_uint16_t volt_compare = chrg_compare(volt_mv, volt_mv_Now); - rt_uint16_t Curr_compare = chrg_compare(Curr_mA, Curr_mA_Now); + static rt_uint16_t last_volt_mv[TOTAL_SOU_CHS] = {0}; static rt_uint8_t number = 0; -#if LCD_OPEN - // rt_kprintf("volt_mv=%d,volt_mv_Now=%d,compare=%d\r\n",volt_mv,volt_mv_Now,volt_compare); - if(volt_compare<5000){ //比较设定值与实际值差距,小于2V认为达成设定,允许屏幕开始变换 - number++; - number = number%10; - if(number == 9) - { - pSW->change_flag = 0; - } - }else { //没有达成设定,屏幕不允许变换 - pSW->change_flag = 0x01; + int ret; + + if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { + return; } -#endif -// if(volt_mv_Now==0){ -// chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_START); -// } -// else{ - if (pSW->source.Set_CV_Flag == 0){ - { - chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_VOLTAGE_OUT+1, volt_mv); - } - pSW->source.Set_CV_Flag = 1; -#if DEBUG_NORTH - rt_kprintf("Volt_Set%d\r\n",volt_mv); -#endif - } - else if(pSW->source.Set_CV_Flag==1){ - chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_START); - pSW->source.Set_CV_Flag = 0; - }else{ - pSW->source.Set_CV_Flag=0; + pSW->source.vc.set_voltage = volt_mv; + pSW->source.vc.set_current = Curr_mA; +// #if LCD_OPEN +// // rt_kprintf("volt_mv=%d,volt_mv_Now=%d,compare=%d\r\n",volt_mv,volt_mv_Now,volt_compare); +// if(volt_compare<5000){ //比较设定值与实际值差距,小于2V认为达成设定,允许屏幕开始变换 +// number++; +// number = number%10; +// if(number == 9) +// { +// pSW->change_flag = 0; +// } +// }else { //没有达成设定,屏幕不允许变换 +// pSW->change_flag = 0x01; +// } +// #endif + if (pSW->source.On_Flag && (volt_mv_Now > 2000)) { + if ((volt_mv == last_volt_mv[idx])) { + pSW->source.work_mode = SOURCE_WORK_WAIT; + } else { + pSW->source.work_mode = SOURCE_WORK_RUNING; } + } + ret = chrg_source_work_state(idx, pSW); + if ((ret >= 0) && (pSW->source.work_mode == SOURCE_WORK_RUNING)) { + last_volt_mv[idx] = volt_mv; + } } //电源设置 @@ -152,7 +114,7 @@ void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx, chrg_source_standard_output(idx, pSW); } else{ //快充部分按协商结果输出 - chrg_source_fast_output(frame_data, idx, pSW, pNOR); + chrg_source_parse(frame_data, idx, pSW, pNOR); // rt_kprintf("set_end\r\n"); } }else if(pSW->source.On_Flag == 0){ @@ -240,7 +202,7 @@ static void chrg_north_handle_Seting_Volt(rt_uint8_t *frame_data, rt_uint16_t fr static uint8_t number = 0; //电源部分 if(pSW->id==ID_SOURCE){ - chrg_source_setting(frame_data,(eIDX_SOU_CH)idx, pSW, pNOR); + chrg_source_parse(frame_data,(eIDX_SOU_CH)idx, pSW, pNOR); } else{ chrg_sink_parse(frame_data,(eIDX_SOU_CH)idx, pSW, pNOR); @@ -262,7 +224,6 @@ struct chrg_north_t chrgnorth = { .source = { // 电源侧参数初始化 .On_Flag = 0, // 启动标志初始关闭 .Set_CV_Flag = 1, // 启停控制初始置1 - .Set_Pro_Flag = 1 // 电压/电流切换初始置1 }, // 关键:补充逗号分隔source和sink .sink = { .protocol = 0xFE, @@ -280,7 +241,6 @@ struct chrg_north_t chrgnorth = { .source = { .On_Flag = 0, .Set_CV_Flag = 1, - .Set_Pro_Flag = 1 }, .sink = { .protocol = 0xFE, @@ -297,7 +257,6 @@ struct chrg_north_t chrgnorth = { .source = { .On_Flag = 0, .Set_CV_Flag = 1, - .Set_Pro_Flag = 1 }, .sink = { .protocol = 0xFE, @@ -314,7 +273,6 @@ struct chrg_north_t chrgnorth = { .source = { .On_Flag = 0, .Set_CV_Flag = 1, - .Set_Pro_Flag = 1 }, .sink = { .protocol = 0xFE, diff --git a/apps/chrg/applications/thread/chrg_roll_nor.c b/apps/chrg/applications/thread/chrg_roll_nor.c index 736cebb..34e38a8 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.c +++ b/apps/chrg/applications/thread/chrg_roll_nor.c @@ -162,38 +162,6 @@ int sink_fill_pd_buf(rt_uint8_t group,rt_uint8_t pd_val, rt_uint16_t pd_volt, rt return 0; } -rt_uint16_t v1=0,v2=0; - - -//电源关闭 -void chrg_nor_source_stop(struct chrg_switch_t *pSW,rt_uint8_t idx,rt_uint8_t *enable){ - switch(pSW->source.Stop_step_flag){ - case 0: - chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_STOP); - pSW->source.Stop_step_flag = 1; - break; - case 1: // 停止工作 - chrg_set_sou_reg((eIDX_SOU_CH)idx, REG_WORK, WORK_STOP); - pSW->source.Stop_step_flag = 2; - break; - case 2: // 关闭北向继电器 - chrg_nor_sw_rel((eIDX_NOR_CH)idx,0); - pSW->source.Stop_step_flag = 3; - break; - case 3: // 状态2:已执行完停止操作,清空标志位 - pSW->source.Set_CV_Flag = 0; - if(pSW->source.change_sink_Flag == 1){ - pSW->source.change_sink_Flag = 0; -// chrg_com_sink_on(idx,pSW,enable); - }else{ - *enable = 0; - } - break; - default: - pSW->source.Stop_step_flag = 0; - break; - } -} /***************************************************************** 函数名称: chrg_roll_nor_sw_uart @@ -230,20 +198,7 @@ void chrg_roll_nor_sink_pro_set(struct chrg_switch_t *pSW) //设置电源协议 void chrg_roll_nor_source_pro_set(struct chrg_switch_t *pSW){ - if(pSW->source.Set_Pro_Flag == 1){ - pSW->source.Set_Pro_Flag = 0; - if(pSW->source.LCD_Set_Pro_Flag==1){ - source_set_pd(pSW->source.protocol,0,0,pSW->source.vc.set_voltage,0,pSW->source.vc.set_current); - } - else if(pSW->source.LCD_Set_Pro_Flag==2){ - source_set_pd_com(pSW->source.protocol,pSW->source.pro_gear_idx); - } - else if(pSW->source.LCD_Set_Pro_Flag==3){ - source_set_pd_new_com(pSW->source.protocol,pSW); - } - }else { - pSW->sub = IDX_GET_SOURCE_VC; - } + source_set_pro(pSW->source.protocol,pSW); } static int chrg_roll_nor_parse (struct chrg_rollnor_t *pROLL, rt_uint8_t *data) { @@ -328,52 +283,24 @@ void chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW,rt_uint8_t *enab { if(pSW->id==ID_SOURCE){ //电源 chrg_roll_nor_sw_uart((eIDX_NOR_CH)ch, ID_SOURCE); - switch(pSW->sub){ - case IDX_SET_SOURCE_ID: //角色 - chrg_set_eload_source(ch,pSW); - if(pSW->continue_flag) - pSW->sub = IDX_SET_SOURCE_CC_SET; -// rt_kprintf("set_start\r\n"); - break; + switch(pSW->sub){ case IDX_SET_SOURCE_CC_SET: source_set_cc_choose(pSW->source.cc_set); - pSW->sub = IDX_SET_SOURCE_CV; - break; - case IDX_SET_SOURCE_CV: //恒压恒流 - pSW->sub = IDX_SER_SOURCE_VOLT; - break; - case IDX_SER_SOURCE_VOLT://电压 - chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_VOLTAGE_OUT+1, 0); - pSW->sub = IDX_SER_SOURCE_CURR; - break; - case IDX_SER_SOURCE_CURR://电流 - chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_CURRENT_OUT+1, pSW->source.protective_curr); - pSW->sub = IDX_SET_SOURCE_WORK; - break; - case IDX_SET_SOURCE_WORK: - chrg_sou_work(ch,pSW); + pSW->sub = IDX_SET_SOURCE_PD; break; case IDX_SET_SOURCE_PD: chrg_roll_nor_source_pro_set(pSW); - if (pSW->sub == IDX_GET_SOURCE_VC && - chrg_source_init_submit((eIDX_SOU_CH)ch, pSW) == 0) { - pSW->source.On_Flag = 1; - } + pSW->sub = IDX_GET_SOURCE_VC; break; case IDX_GET_SOURCE_VC: source_get_vc(pSW->source.vc.set_voltage, pSW->source.vc.set_current); - break; - case IDX_SET_SOURCE_CCLVL: - source_set_cc_lvl(pSW->source.vol_lvl); - break; - case IDX_SET_SOURCE_STOP_STATE: - chrg_nor_source_stop(pSW,ch,enable); - break; + break; default: break; } - }else{ + } + else{ chrg_roll_nor_sw_uart((eIDX_NOR_CH)ch, ID_SINK); switch(pSW->sub){ case IDX_GET_SINK_VC: //查询 diff --git a/apps/chrg/applications/utils/chrg_source.c b/apps/chrg/applications/utils/chrg_source.c index 62e09dd..6d47496 100644 --- a/apps/chrg/applications/utils/chrg_source.c +++ b/apps/chrg/applications/utils/chrg_source.c @@ -15,9 +15,11 @@ #include "chrg_source.h" #include "chrg_eload.h" #include "chrg_roll_sou.h" +#include "chrg_rel.h" int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW) { + /* Source启动参数一次入队,最后发送WORK_START使功率板开始输出。 */ rt_uint16_t regs[5] = { REG_ELOAD, REG_MODE, @@ -30,7 +32,7 @@ int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW) pSW->CV_mode, pSW->source.max_vol, pSW->source.protective_curr, - WORK_STOP + WORK_START }; if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { @@ -38,6 +40,99 @@ int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW) } return chrg_sou_com_batch_submit(idx, regs, vals, 5); } + +static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) +{ + struct chrg_south_t *pSOU = &chrgsouth; + struct chrg_north_t *pNOR = &chrgnorth; + int ret; + + /* 只有整批命令成功入队后,才打开通道并进入等待状态。 */ + ret = chrg_source_init_submit(idx, pSW); + if (ret != 0) { + return ret; + } + + pSW->source.On_Flag = 1; + pSOU->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; + return 0; +} + +static int chrg_source_work_wait(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) +{ + /* WAIT状态不产生南向命令,等待下一帧北向电压数据。 */ + return 0; +} + +static int chrg_source_work_running(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) +{ + /* RUNING只下发协商后的目标电压,不重复发送启动命令。 */ + rt_uint16_t reg = REG_VOLTAGE_OUT + 1; + rt_uint16_t value = pSW->source.vc.set_voltage; + + return chrg_sou_com_batch_submit(idx, ®, &value, 1); +} + +static int chrg_source_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) +{ + /* 电压异常时先停止功率板输出,保留状态供上层判断。 */ + rt_uint16_t reg = REG_WORK; + rt_uint16_t value = WORK_STOP; + + return chrg_sou_com_batch_submit(idx, ®, &value, 1); +} + +static int chrg_source_work_stop(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) +{ + struct chrg_south_t *pSOU = &chrgsouth; + struct chrg_north_t *pNOR = &chrgnorth; + int ret; + + rt_uint16_t reg = REG_WORK; + rt_uint16_t value = WORK_STOP; + + /* 停止命令入队成功后再关闭使能和北向继电器。 */ + ret = chrg_sou_com_batch_submit(idx, ®, &value, 1); + if (ret != 0) { + return ret; + } + + pSW->source.On_Flag = 0; + pSOU->enable[idx] = 0; + pNOR->enable[idx] = 0; + pSOU->online[idx] = 0; + chrg_nor_sw_rel((eIDX_NOR_CH)idx, 0); + pSW->source.work_mode = SOURCE_WORK_WAIT; + return 0; +} + +int chrg_source_work_state(rt_uint8_t idx, struct chrg_switch_t *pSW) +{ + if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { + return -1; + } + + /* 所有Source功率板控制统一从本状态机出口执行。 */ + switch (pSW->source.work_mode) { + case SOURCE_WORK_INIT: + return chrg_source_work_init(idx, pSW); + case SOURCE_WORK_WAIT: + return chrg_source_work_wait(idx, pSW); + case SOURCE_WORK_RUNING: + return chrg_source_work_running(idx, pSW); + case SOURCE_WORK_LOW: + return chrg_source_work_low(idx, pSW); + case SOURCE_WORK_STOP: + return chrg_source_work_stop(idx, pSW); + default: + return -1; + } +} + rt_uint8_t Pro_Group_VCMM[11][8] = { {0} // 11个挡位,8个参数(src, pps, vmin_H,vmin_L, vmax_H,vmax_L,cur_set_H,cur_set_L) }; @@ -346,8 +441,6 @@ void parse_power_pdo_gear(rt_uint8_t protoCmd, rt_uint8_t *pData, rt_uint16_t re // #endif. } - - /***************************************************************** 函数名称: parse_mulit_gear_more 函数描述: 解析三-四挡位原始数据,填充8参数高低字节缓冲区(同步修改) @@ -859,34 +952,8 @@ rt_uint8_t pd_fill_single_group_UFCS(rt_uint8_t *data, rt_uint8_t start_idx,stru return idx - start_idx; // 返回填充的总字节数 } -int source_set_pd_com(rt_uint8_t pro,rt_uint8_t pro_gear_idx) -{ - rt_uint16_t len = 0; - rt_uint8_t data[150] = {0}; - rt_uint8_t frame[150] = {0}; - rt_uint8_t send_len = 0; //数据长度 - rt_uint8_t max_group_idx = 0; //挡位索引 - data[0] = pro; //协议 - rt_uint8_t idx = 1; - for(rt_uint8_t i = 0;i