#include "drv_rtc.h"
#include "drv_uart.h"

#include "kit_data.h"
#include "kit_debug.h"
#include "kit_macro.h"

#include "bsp_modbus.h"

//#include "bms_bmu.h"
#include "iso_check.h"
#include "soc_calculate.h"
#include "sop_calculate.h"
#include "version_manager.h"
#include "dido_manager.h"
#include "fault_manager.h"
#include "flash_manager.h"
#include "comm_manager.h"
#include "hv_adc_manager.h"
#include "eeprom_manager.h"
#include "signal_manager.h"
#include "statistic_manager.h"
#include "bmu_manager.h"
#include "protocol_comm.h"

//#include "bms_app.h"	
#include "ucos_ii.h"


struct{
	uint16_t req_bcu_num;//请求单体信息分簇地址
	uint16_t on_off_cmd;//高压上下电指令
	uint16_t sys_time;//系统时间
  uint16_t ac_err;  //空调故障
}bcu_holding_reg;

struct tm telnet_time;

uint16_t bcu_total_msg_fill(uint16_t start_addr, uint8_t reg_num, uint8_t *buf)
{
//	static uint16_t test99 = 0;
	uint16_t index, data, i;
	uint32_t addr = 0,temp_soe;
	uint16_t relay_status_temp = 0,sw_status = 0;
	uint32_t AccChgCap,AccChgEnergy,AccDisCap,AccDisEnergy,AccChgTime,AccDisTime;
	
    uint16_t bms_stu = 0;

    if(bms_get_run_status() == kRunStatus_Init)
    {
        bms_stu = 0;
    }
    else if(bms_get_run_status() == kRunStatus_Standby)
    {
        bms_stu |= 0x1;
    }
    else if(bms_get_run_status() == kRunStatus_Chg)
    {
        bms_stu |= 0x2;
    }
    else if(bms_get_run_status() == kRunStatus_Dis)
    {
        bms_stu |= 0x3;
    }
    if(bms_get_signal(kSignalIdx_ForbidChg) == kSignalStatus_High)
    {
        bms_stu |= 0x10;
    }
    if(bms_get_signal(kSignalIdx_ForbidDis) == kSignalStatus_High)
    {
        bms_stu |= 0x20;
    }

	temp_soe = (uint32_t)bms_get_soc()*get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)/100*bms_get_statistic_data(kStatisticData_TotalVolt);
	temp_soe /= (uint32_t)get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)* get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/100;
	
	//获取累计充电容量
	AccChgCap = bms_get_cumulate_data(kCumulateData_AccChgCap);
	//累计充电电量
	AccChgEnergy = bms_get_cumulate_data(kCumulateData_AccChgEnergy);
	//累计放电容量
	AccDisCap = bms_get_cumulate_data(kCumulateData_AccDisCap);
	//累计放电电量
	AccDisEnergy = bms_get_cumulate_data(kCumulateData_AccDisEnergy);
	//累计充电时间
	AccChgTime = bms_get_cumulate_data(kCumulateData_AccChgTime);
	//累计放电时间
	AccDisTime = bms_get_cumulate_data(kCumulateData_AccDisTime);
	//继电器状态
	for(i = 0;i < 10;i++)
	{
		relay_status_temp |= bms_get_do_status_by_idx(i) << i; 
	}
	//开关量输入状态
	for(i = 0;i < kSignalIdx_DiEnd;i++)
	{
		sw_status |= (uint16_t)(bms_get_signal((SignalIdx)i)) << i; 
	}
	
	for(index = start_addr; index < start_addr + reg_num; index++)
    {
		READ_FC03_F04_BEGIN();
		//1 动力电池组总电压
		READ_FC03_F04_ITEM(1, bms_get_statistic_data(kStatisticData_TotalVolt));
		//READ_FC03_F04_ITEM(1, 5000);
			
		//READ_FC03_F04_ITEM(1, test99+=10);
		//2 动力电池组总电流
		READ_FC03_F04_ITEM(2, bms_get_show_current());
		//3 SOC
		//READ_FC03_F04_ITEM(3,get_eeprom_data(kEep_SOC,kEepromDataType_Full) / 100);
		READ_FC03_F04_ITEM(3, bms_get_soc() / 100);
		//4 SOH
		READ_FC03_F04_ITEM(4, bms_get_soh() / 100);
		//5 SOE
		READ_FC03_F04_ITEM(5, bms_get_soc() / 100);
		//6 额定总压
		READ_FC03_F04_ITEM(6, get_eeprom_data(kEep_RatedTotalVolt,kEepromDataType_Full));
		//7 额定容量
		READ_FC03_F04_ITEM(7, get_eeprom_data(kEep_RatedCapacity,kEepromDataType_Full) );
		//8 剩余容量
		READ_FC03_F04_ITEM(8, (uint32_t)bms_get_soc()*get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)/10000);
		//9 额定电量
		READ_FC03_F04_ITEM(9, get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000);
		//10 剩余电量
		READ_FC03_F04_ITEM(10, (uint32_t)bms_get_soc() * get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)/10000*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000);
		//11 从机总数
		READ_FC03_F04_ITEM(11, bms_get_bmu_num());
		//12 在线从机总数
		READ_FC03_F04_ITEM(12, bms_get_bmu_online_num());
		//13 电池总数
		READ_FC03_F04_ITEM(13, get_eeprom_data(kEep_CellNum, kEepromDataType_Full));
		//14 在线电池总数
		READ_FC03_F04_ITEM(14, bms_get_statistic_data(kStatisticData_OnlineCellNum));
		//15 温感总数
		READ_FC03_F04_ITEM(15, get_eeprom_data(kEep_TempNum, kEepromDataType_Full));
		//16 在线温感总数
		READ_FC03_F04_ITEM(16, bms_get_statistic_data(kStatisticData_OnlineTempNum));
		//17 最大允许放电电流
		READ_FC03_F04_ITEM(17, bms_get_sop_data(kSopData_DisCur));
		//18 最大允许放电功率
		READ_FC03_F04_ITEM(18, (uint32_t)bms_get_sop_data(kSopData_DisCur)*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000);
		//19 最大允许充电电流
		READ_FC03_F04_ITEM(19, bms_get_sop_data(kSopData_ChgCur));
		//20 最大允许充电功率
		READ_FC03_F04_ITEM(20, (uint32_t)bms_get_sop_data(kSopData_ChgCur)*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000);
		//21 正极绝缘阻值
		READ_FC03_F04_ITEM(21, bms_get_iso_data(kIsoData_PosRes));
		//22 负极绝缘阻值
		READ_FC03_F04_ITEM(22, bms_get_iso_data(kIsoData_NegRes));
		//23 平均电压
		READ_FC03_F04_ITEM(23, bms_get_statistic_data(kStatisticData_AvgVolt));
		//24 最大压差
		READ_FC03_F04_ITEM(24, bms_get_statistic_data(kStatisticData_VoltDiff));
		//25 最高单体电压
		READ_FC03_F04_ITEM(25, bms_get_statistic_data(kStatisticData_MaxVolt));
		//26 最高单体电压从机号
		READ_FC03_F04_ITEM(26, bms_get_statistic_data(kStatisticData_MaxVoltBmuIdx) + 1);
		//27 最高单体电压编号
		READ_FC03_F04_ITEM(27, bms_get_statistic_data(kStatisticData_MaxVoltIdx) + 1);
		//28 最低单体电压
		READ_FC03_F04_ITEM(28, bms_get_statistic_data(kStatisticData_MinVolt));
		//29 最低单体电压从机号
		READ_FC03_F04_ITEM(29, bms_get_statistic_data(kStatisticData_MinVoltBmuIdx) + 1);
		//30 最低单体电压编号
		READ_FC03_F04_ITEM(30, bms_get_statistic_data(kStatisticData_MinVoltIdx) + 1);
		//31 平均温度
		READ_FC03_F04_ITEM(31, bms_get_statistic_data(kStatisticData_AvgTemp));
		//32 最大温差
		READ_FC03_F04_ITEM(32, bms_get_statistic_data(kStatisticData_TempDiff));
		//33 最高单体温度
		READ_FC03_F04_ITEM(33, bms_get_statistic_data(kStatisticData_MaxTemp));
		//34 最高单体温度从机号
		READ_FC03_F04_ITEM(34, bms_get_statistic_data(kStatisticData_MaxTempBmuIdx) + 1);
		//35 最高单体温度编号
		READ_FC03_F04_ITEM(35, bms_get_statistic_data(kStatisticData_MaxTempIdx) + 1);
		//36 最低单体温度
		READ_FC03_F04_ITEM(36, bms_get_statistic_data(kStatisticData_MinTemp));
		//37 最低单体温度从机号
		READ_FC03_F04_ITEM(37, bms_get_statistic_data(kStatisticData_MinTempBmuIdx) + 1);
		//38 最低单体温度编号
		READ_FC03_F04_ITEM(38, bms_get_statistic_data(kStatisticData_MinTempIdx) + 1);
		//39 日充电容量
		READ_FC03_F04_ITEM(39, (uint16_t)bms_get_cumulate_data(kCumulateData_DayChgCap));
		//40 日充电电量
		READ_FC03_F04_ITEM(40, (uint16_t)bms_get_cumulate_data(kCumulateData_DayChgEnergy));
		//41 日放电容量
		READ_FC03_F04_ITEM(41, (uint16_t)bms_get_cumulate_data(kCumulateData_DayDisCap));
		//42 日放电电量
		READ_FC03_F04_ITEM(42, (uint16_t)bms_get_cumulate_data(kCumulateData_DayDisEnergy))
		//43 日充电时间 todo
		READ_FC03_F04_ITEM(43, (uint16_t)bms_get_cumulate_data(kCumulateData_DayChgTime));
		//44 日放电时间 todo
		READ_FC03_F04_ITEM(44, (uint16_t)bms_get_cumulate_data(kCumulateData_DayDisTime));
		//45 累计充电容量高位
		READ_FC03_F04_ITEM(45, (uint16_t)(AccChgCap >> 16));
		//46 累计充电容量低位
		READ_FC03_F04_ITEM(46, (uint16_t)(AccChgCap));
		//47 累计充电电量高位
		READ_FC03_F04_ITEM(47, (uint16_t)(AccChgEnergy >> 16));
		//48 累计充电电量低位
		READ_FC03_F04_ITEM(48, (uint16_t)(AccChgEnergy));
		//49 累计放电容量高位
		READ_FC03_F04_ITEM(49, (uint16_t)(AccDisCap >> 16));
		//50 累计放电容量低位
		READ_FC03_F04_ITEM(50, (uint16_t)(AccDisCap));
		//51 累计放电电量高位
		READ_FC03_F04_ITEM(51, (uint16_t)(AccDisEnergy >> 16)); 
		//52 累计放电电量低位
		READ_FC03_F04_ITEM(52, (uint16_t)(AccDisEnergy))
		//53 累计充电时间高位
		READ_FC03_F04_ITEM(53, (uint16_t)(AccChgTime >> 16));
		//54 累计充电时间低位
		READ_FC03_F04_ITEM(54, (uint16_t)(AccChgTime));
		//55 累计放电时间高位
		READ_FC03_F04_ITEM(55, (uint16_t)(AccDisTime >> 16))
		//56 累计放电时间低位
		READ_FC03_F04_ITEM(56, (uint16_t)(AccDisTime))
		//57 BCU工作状态 todo
		READ_FC03_F04_ITEM(57, bms_stu);
		//58 总负继电器状态
		READ_FC03_F04_ITEM(58, bms_get_do_status_by_type(kDoType_Negative));
		//59 总正继电器状态
		READ_FC03_F04_ITEM(59, bms_get_do_status_by_type(kDoType_Positive));
		//60 放电继电器状态
		READ_FC03_F04_ITEM(60, bms_get_do_status_by_type(kDoType_Dis));
		//61 充电继电器状态
		READ_FC03_F04_ITEM(61, bms_get_do_status_by_type(kDoType_Chg));
		//62 预充继电器状态
		READ_FC03_F04_ITEM(62, bms_get_do_status_by_type(kDoType_PreChg));
		//63 继电器状态
		READ_FC03_F04_ITEM(63, relay_status_temp);
		//64 开关量状态
		READ_FC03_F04_ITEM(64, sw_status);
		//65 故障状态
		READ_FC03_F04_ITEM(65, bms_get_max_fault_level());
		//66 故障1~8等级 todo
		READ_FC03_F04_ITEM(66, bms_get_fault_bit(0));
		//67 故障9~16等级 todo
		READ_FC03_F04_ITEM(67, bms_get_fault_bit(1));
		//68 故障17~24等级 todo
		READ_FC03_F04_ITEM(68, bms_get_fault_bit(2));
		//69 故障25~32等级 todo
		READ_FC03_F04_ITEM(69, bms_get_fault_bit(3));
		//70 故障33~40等级 todo
		READ_FC03_F04_ITEM(70, bms_get_fault_bit(4));
		//71 故障41~48等级 todo
		READ_FC03_F04_ITEM(71, bms_get_fault_bit(5));
		//72 故障49~56等级 todo 
		READ_FC03_F04_ITEM(72, bms_get_fault_bit(6));
		//73 故障57~64等级 todo
		READ_FC03_F04_ITEM(73, bms_get_fault_bit(7));
		//74 电池系统循环次数 todo
		READ_FC03_F04_ITEM(74, bms_get_cycle());
		//75 最大允许充电单体电压 todo
		READ_FC03_F04_ITEM(75, get_eeprom_data(kEep_FullChgVolt, kEepromDataType_Full));	
		//76 最小允许放电单体电压 todo
		READ_FC03_F04_ITEM(76, get_eeprom_data(kEep_FullDisVolt, kEepromDataType_Full));	
		//77 最大允许充电总压
		READ_FC03_F04_ITEM(77, get_eeprom_data(kEep_ChgHTVoltHTAlarm1, kEepromDataType_Full));
		//78 最小允许放电总压
		READ_FC03_F04_ITEM(78, get_eeprom_data(kEep_DisLTVoltHTAlarm1, kEepromDataType_Full));
		//79 软件版本号高位
		READ_FC03_F04_ITEM(79, (uint16_t)(DEVICE_SW_VERSION >> 16))
		//80 软件版本号低位
		READ_FC03_F04_ITEM(80, (uint16_t)(DEVICE_SW_VERSION))	
		//81 修订版本号
		READ_FC03_F04_ITEM(81, DEVICE_SW_BUILD_VER);
		//82 硬件版本号
		READ_FC03_F04_ITEM(82, DEVICE_HW_VERSION);
		//83 采样总压
		READ_FC03_F04_ITEM(83, bms_get_high_volt(kHvType_Bat))
        //84  一级故障(故障位1~16)
		READ_FC03_F04_ITEM(84,bms_get_fault_single_bit(0 , kFaultLevel_First))
        //85  一级故障(故障位17~32)
		READ_FC03_F04_ITEM(85,bms_get_fault_single_bit(1 , kFaultLevel_First)) 
        //86  一级故障(故障位33~48)
		READ_FC03_F04_ITEM(86,bms_get_fault_single_bit(2 , kFaultLevel_First))
        //87  一级故障(故障位49~64)
		READ_FC03_F04_ITEM(87,bms_get_fault_single_bit(3 , kFaultLevel_First))        
        //88  二级故障(故障位1~16)
		READ_FC03_F04_ITEM(88,bms_get_fault_single_bit(0 , kFaultLevel_Second))
        //89  二级故障(故障位17~32)
		READ_FC03_F04_ITEM(89,bms_get_fault_single_bit(1 , kFaultLevel_Second)) 
        //90  二级故障(故障位33~48)
		READ_FC03_F04_ITEM(90,bms_get_fault_single_bit(2 , kFaultLevel_Second))
        //91  二级故障(故障位49~64)
		READ_FC03_F04_ITEM(91,bms_get_fault_single_bit(3 , kFaultLevel_Second)) 
        //92  三级故障(故障位1~16)
		READ_FC03_F04_ITEM(92,bms_get_fault_single_bit(0 , kFaultLevel_Third))
        //93  三级故障(故障位17~32)
		READ_FC03_F04_ITEM(93,bms_get_fault_single_bit(1 , kFaultLevel_Third)) 
        //94  三级故障(故障位33~48)
		READ_FC03_F04_ITEM(94,bms_get_fault_single_bit(2 , kFaultLevel_Third))
        //95  三级故障(故障位49~64)
		READ_FC03_F04_ITEM(95,bms_get_fault_single_bit(3 , kFaultLevel_Third)) 
        //96  BCU状态机
		READ_FC03_F04_ITEM(96,bms_stu & 0x0F)        
        //97  充电状态
		READ_FC03_F04_ITEM(97,(bms_stu & 0x10) >> 4)
        //98  放电状态
		READ_FC03_F04_ITEM(98,(bms_stu & 0x20) >> 5)        
        //99  高压闭合状态
		READ_FC03_F04_ITEM(99,(bms_stu & 0x40) >> 6) 
        //100  风扇状态
		READ_FC03_F04_ITEM(100,(bms_stu & 0x80) >> 7) 
        //101  总告警
		READ_FC03_F04_ITEM(101,bms_get_max_fault_level() == kFaultLevel_First || bms_get_max_fault_level() == kFaultLevel_Second)         
        //102  总故障
		READ_FC03_F04_ITEM(102,bms_get_max_fault_level() == kFaultLevel_Third) 
        //103  BCU地址
		READ_FC03_F04_ITEM(103,get_eeprom_data(kEep_DevAddr_SlaverNum, kEepromDataType_High)) 
        //104  BCU主回路状态
		READ_FC03_F04_ITEM(104,bms_get_circuit_status(kCircuitType_Main)) 
        //105  BCU回路闭合指令
		READ_FC03_F04_ITEM(105,bms_get_circuit_cmd_status()) 
        //106  BCU是否允许闭合主回路
		READ_FC03_F04_ITEM(106,(bms_is_circuit_allow() == true)) 
		//107  T1温度
		READ_FC03_F04_ITEM(107,bms_get_en_temp((EnTemp)(kEnTemp_T1))) 
		//108  T2温度
		READ_FC03_F04_ITEM(108,bms_get_en_temp((EnTemp)(kEnTemp_T2)))      
        //109  T3温度
		READ_FC03_F04_ITEM(109,bms_get_en_temp((EnTemp)(kEnTemp_T3)))
        //109  T4温度
		READ_FC03_F04_ITEM(110,bms_get_en_temp((EnTemp)(kEnTemp_T4)))		
		//120 休眠状态
		READ_FC03_F04_ITEM(120,bms_get_signal(kSignalIdx_StandbySleep))
		
		READ_FC03_F04_END();
		
		WRITE_BT_INT16U(buf, addr, data);
	}
	return addr;
}

void bcu_cell_volt_msg_fill(uint8_t *buf)
{
	uint16_t temp,i,j;
	uint32_t addr = 0;
	//1000 电池总数
	temp = bms_get_statistic_data(kStatisticData_OnlineCellNum);
	WRITE_BT_INT16U(buf, addr, temp);	
    for(i = 0; i < bms_get_bmu_num(); i++)
    {
		for(j = 0; j < bms_get_bmu_data(i, kBmuData_CellNum); j++)
        {
            temp = bms_get_cell_volt_by_bmu(i, j);
            WRITE_BT_INT16U(buf, addr, temp);
		}
	}	
}

void bcu_cell_temperature_msg_fill(uint8_t *buf)
{
	uint16_t temp,i,j;
	uint32_t addr = 0;
	//1600 温感总数
	temp = bms_get_statistic_data(kStatisticData_OnlineTempNum);
	WRITE_BT_INT16U(buf, addr, temp);	
    for(i = 0; i < bms_get_bmu_num(); i++)
    {
		for(j = 0; j < bms_get_bmu_data(i, kBmuData_TempNum); j++)
        {
            temp = bms_get_cell_temp_by_bmu(i, j);
            WRITE_BT_INT16U(buf, addr, temp);
		}
	}	
}


uint16_t bcu_holding_data_fill(uint16_t start_addr, uint8_t reg_num, uint8_t *buf)
{
	uint16_t index, data;
	uint32_t addr = 0;
    int32_t year, month, day, hour, min, sec;
    
    drv_rtc_get_date(&year, &month, &day);
    drv_rtc_get_time(&hour, &min, &sec);

	for(index = start_addr; index < start_addr + reg_num; index++)
    {
		READ_FC03_F04_BEGIN();
		//1 高压上下电指令
		READ_FC03_F04_ITEM(3000, bcu_holding_reg.on_off_cmd);
		//2 系统时间
		READ_FC03_F04_ITEM(3001, bcu_holding_reg.sys_time);
		//3 空调故障信号
		READ_FC03_F04_ITEM(3002, 0);
		//4 年
		READ_FC03_F04_ITEM(3003, year);
		//5 月
		READ_FC03_F04_ITEM(3004, month);
		//6 日
		READ_FC03_F04_ITEM(3005, day);
		//7 时
		READ_FC03_F04_ITEM(3006, hour);
		//8 分
		READ_FC03_F04_ITEM(3007, min);
		//9 秒
		READ_FC03_F04_ITEM(3008, sec);
			
		READ_FC03_F04_END();
		
		WRITE_BT_INT16U(buf, addr, data);
	}
	return addr;
}

void bcu_holding_data_fill_msg(uint8_t *buf)
{
	uint16_t temp;
	uint32_t addr = 0;
	//3000 高压上下电指令
	temp = bcu_holding_reg.on_off_cmd;
	WRITE_BT_INT16U(buf, addr, temp);	
	//3001 系统时间
	temp = bcu_holding_reg.sys_time;
	WRITE_BT_INT16U(buf, addr, temp);
	//3002 空调故障
	temp = bcu_holding_reg.ac_err;
	WRITE_BT_INT16U(buf, addr, temp);      
	//3003 系统时间
	temp = telnet_time.tm_year + 1900;
	WRITE_BT_INT16U(buf, addr, temp);
	//3004 
	temp = telnet_time.tm_mon + 1;
	WRITE_BT_INT16U(buf, addr, temp);
	//3005 
	temp = telnet_time.tm_mday;
	WRITE_BT_INT16U(buf, addr, temp);	
	//3006
	temp = telnet_time.tm_hour;
	WRITE_BT_INT16U(buf, addr, temp);	
	//3007 
	temp = telnet_time.tm_min;
	WRITE_BT_INT16U(buf, addr, temp);		
	//3008 
	temp = telnet_time.tm_sec;
	WRITE_BT_INT16U(buf, addr, temp);   
    
}

#include "kit_time.h"

uint16_t bcu_total_cfg_fill(uint16_t start_addr, uint8_t reg_num, uint8_t *buf)
{
	uint16_t address = 0,data = 0;
	int32_t year,mon,day,hour,min,sec;
	uint32_t addr = 0;
	//drv_rtc_get_date(&year, &mon, &day);
	//drv_rtc_get_time(&hour, &min, &sec);
	
	for(address = start_addr; address < start_addr + reg_num; address++)
    {
		switch(address)
		{
			case 3000:
				data = get_eeprom_data(kEep_DevAddr_SlaverNum,kEepromDataType_Low);
				break;
			case 3001:
			case 3002:
				data = get_eeprom_data(kEep_CellNum + address - 3001, kEepromDataType_Full);
				break;
			case 3003:
				data = get_eeprom_data(kEep_Standby_LowVoltSleepDly, kEepromDataType_Full);
				break;
			case 3004:
			case 3005:
				//data = get_eeprom_data(kEep_HeatStartTemp + address - 3004 , kEepromDataType_Full);
			    data = get_eeprom_data(kEep_HeatOn_OffTemp,(EepromDataType)(1 -(address % 2)));
				break;    
			case 3006: //制冷开启温度(℃)
			case 3007: //制冷关闭温度(℃)
				//data = get_eeprom_data(kEep_HeatStartTemp + address - 3004 , kEepromDataType_Full);
			    data = get_eeprom_data(kEep_CoolOn_OffTemp,(EepromDataType)(1 -(address % 2)));
				break; 
			case 3008: //额定容量
				data = get_eeprom_data(kEep_RatedCapacity,kEepromDataType_Full);
				break; 
			
			case 3009:
			case 3010:
				data = get_eeprom_data(kEep_InterCanProtocol_Baudrate, (EepromDataType)(1 - (address % 2)));
				break; 
			case 3011: //485_1波特率  485_1校验位
			case 3012:
				data = get_eeprom_data(kEep_InterCanProtocol_Baudrate, (EepromDataType)(1 - (address % 2)));
				break; 
			case 3013: //485_1设备地址 
			case 3014: //485_1设备协议
				data = get_eeprom_data(kEep_InterRS485_SlaveID_Protocol, (EepromDataType)(address % 2));
				break; 
			case 3015: //485_1波特率  485_1校验位
			case 3016:
				data = get_eeprom_data(kEep_Exter485_2Parity_Baudrate, (EepromDataType)(1 - (address % 2)));
				break; 
			case 3017: //485_1设备地址 
			case 3018: //485_1设备协议
				data = get_eeprom_data(kEep_ExterRS485_1SlaveID_Protocol, (EepromDataType)(address % 2));
				break; 
			
			case 3019: //485_2波特率  485_2校验位
			case 3020:
				data = get_eeprom_data(kEep_Exter485_2Parity_Baudrate, (EepromDataType)(1 - (address % 2)));
				break; 
			case 3021: //485_2设备地址 
			case 3022: //485_2设备协议
				data = get_eeprom_data(kEep_ExterRS485_2SlaveID_Protocol, (EepromDataType)(address % 2));
				break; 
			
			case 3023: //电流传感器1类型
			case 3030: //电流传感器2类型
				data = get_eeprom_data(kEep_CurSensor2_1Type, (EepromDataType)(1 - (address % 2)));
				break;
			case 3024: //霍尔摆幅电压(mV)
				data = get_eeprom_data(kEep_HallSwingVolt, kEepromDataType_Full);
				break;
			case 3025: //电流传感器1量程(A)
			case 3032: //电流传感器2量程(A)
				data = get_eeprom_data(kEep_CurSensor2_1Range, (EepromDataType)(1 - (address % 2)));
				break;
			case 3026: //电流传感器1方向
			case 3033: //电流传感器2方向
				data = get_eeprom_data(kEep_CurSensor2_1Dir, (EepromDataType)(1 - (address % 2)));
				break;
			case 3027: //电流传感器1滤波(A)
			case 3034: //电流传感器2滤波(A)
				data = get_eeprom_data(kEep_ZeroFilter2_1Filter, (EepromDataType)(1 - (address % 2)));
				break;
			case 3028: //电流传感器1偏移(A)(A)
			case 3035: //电流传感器2偏移(A)(A)
				data = get_eeprom_data(kEep_CurSensor2_1Offset, (EepromDataType)(1 - (address % 2)));
				break;
			case 3029: //霍尔1矫正增益
				data = get_eeprom_data(kEep_Shunt1CaliGain, kEepromDataType_Full);
				break;
			case 3036: //霍尔2矫正增益
				data = get_eeprom_data(kEep_Shunt2CaliGain, kEepromDataType_Full);
				break;
			case 3037: //分流器额定电压(mV)
			case 3038: //充电电流方向
				data = get_eeprom_data(kEep_ChgCurDir_ShuntRatedVolt, (EepromDataType)(1 - (address % 2)));
				break;
			case 3039: //目标电流
				data = get_eeprom_data(kEep_TargetCurrent, kEepromDataType_Full);
				break;	
			case 3040: //循环次数
			case 3041: //SOC设置
			case 3042: //SOE设置
			case 3043: //日充放电累计时间
			case 3044: //日放电累计容量L
			case 3045: //日放电累计容量H
			case 3046: //日放电电量L
			case 3047: //日放电电量H
			case 3048: //日充电电电量L
			case 3049: //日充电电电量H
			case 3050: //日充电累计时间L
			case 3051: //日充电累计时间H
			case 3052: //日充电电电量L
			case 3053: //日充电电电量H
			case 3054: //放电累计时间L
			case 3055: //放电累计时间H
			case 3056: //放电累计容量L
			case 3057: //放电累计容量H
			case 3058: //放电累计电量L
			case 3059: //放电累计电量H
			case 3060: //充电累计时间L
			case 3061: //充电累计时间H
			case 3062: //充电累计容量L
			case 3063: //充电累计容量H
			case 3064: //放电累计电量L
			case 3065: //放电累计电量H
			case 3066: //下电时间L
			case 3067: //下电时间H
				data = get_eeprom_data(kEep_CycleTimes + address - 3040, kEepromDataType_Full);
				break;
			case 3068:	//SOC满放校准电压(mV)
			case 3069:	//SOC满充校准电压(mV)
				data = get_eeprom_data(kEep_FullDisVolt + address - 3068, kEepromDataType_Full);
				break;
			case 3070:	//SOC满放校准平均电压(mV)
			case 3071:	//SOC满充校准平均电压(mV)
				data = get_eeprom_data(kEep_FullDisAvgVolt + address - 3070, kEepromDataType_Full);
				break;
			case 3072:	//SOC过充校准总压电压值
			case 3073:	//SOC过放校准总压电压值
				data = get_eeprom_data(kEep_FullChgTotalVolt + address - 3072, kEepromDataType_Full);
				break;
			case 3074:	//SOC过充校准总压电压值
				data = get_eeprom_data(kEep_ForbidChgRelVolt, kEepromDataType_Full);
				break;
			case 3075:	//SOC过放校准总压电压值
				data = get_eeprom_data(kEep_ForbidDisRelVolt, kEepromDataType_Full);
				break;
			case 3076:	//禁放释放时间(min)
			case 3077:	//禁充释放时间(min)
				data = get_eeprom_data(kEep_ForbidDisRelDelay + address - 3076, kEepromDataType_Full);
				break;
			case 3078:	//	OCV表索引
			case 3079:	//	SOP表索引
				data = get_eeprom_data(kEep_Sop_OcvIndex,  (EepromDataType)(address % 2));
				break;

			case 3080:	//	OCV静置时间(h)
			case 3081:	//	OCV静置电流(A)
				data = get_eeprom_data(kEep_OcvStandbyCur_Time, (EepromDataType)(address % 2));
				break;
			case 3082:	//	OCV禁校上限(%)
			case 3083:	//	OCV禁校下限(%)
				data = get_eeprom_data(kEep_OcvDisRangeLower_Upper,  (EepromDataType)(address % 2));
				break;
			case 3084:	//	SOC上限(%)
			case 3085:	//	SOC下限(%)
				data = get_eeprom_data(kEep_SOCRunMax_Min,  (EepromDataType)(1 - (address % 2)));
				break;
			case 3086:	//	额定总压(V)
			case 3087:	//	请求充电电压(V)
				data = get_eeprom_data(kEep_RatedTotalVolt + address - 3086,  kEepromDataType_Full);
				break;
			case 3088:	//	额定充电电流(A)(A)
			case 3089:	//	额定放电电流(A)(V)
				data = get_eeprom_data(kEep_RatedChgCur + address - 3088,  kEepromDataType_Full);
				break;
			
			case 3090:	//	额定充电功率(kw)(kw)
			case 3091:	//	额定放电功率(kw)
				data = get_eeprom_data(kEep_RatedChgPower + address - 3090,  kEepromDataType_Full);
				break;
			case 3092:	//	充电末端一段降流电压(V)
			case 3093:	//	充电末端二段降流电压(V)
				data = get_eeprom_data(kEep_ChgFstCurDownVolt + address - 3092,  kEepromDataType_Full);
				break;
			case 3094:	//	充电末端一段降流系数
			case 3095:	//	充电末端二段降流系数
				data = get_eeprom_data(kEep_ChgSnd_FstCurDownRate,  (EepromDataType)(address % 2));
				break;
			case 3096:	//	充放电模式
				data = get_eeprom_data(kEep_ChgDisMode_HighVoltStrategy,  kEepromDataType_High);
				break;
			case 3097:	//	目标电压
				data = get_eeprom_data(kEep_TargetVolt,  kEepromDataType_Full);
				break;
			case 3098:	//	高压控制策略
				data = get_eeprom_data(kEep_ChgDisMode_HighVoltStrategy,  kEepromDataType_Low);
				break;
			
			case 3099:	//	放电上电自检故障L
			case 3100:	//	放电上电自检故障H
			case 3101:	//	充电上电自检故障L
			case 3102:	//	充电上电自检故障H
				data = get_eeprom_data(kEep_DisSelfFaultLow + address - 3099,  kEepromDataType_Full);
				break;
			case 3103://	绝缘使能
				data = get_eeprom_data(kEep_InsuPeriod_Enable,  kEepromDataType_Low);
				break;
			case 3104://	上下电模式
				data = get_eeprom_data(kEep_ChgDisChangeBasis_RelayOnOffMode,  kEepromDataType_Low);
				break;
			case 3105: //上下电模式
			case 3106: //	DO2控制
			case 3107: //	DO3控制
			case 3108: //	DO4控制
			case 3109: //	DO5控制
			case 3110: //	DO6控制
			case 3111: //	DO7控制
			case 3112: //	DO8控制
				data = get_eeprom_data(kEep_Relay2_1Type + (address - 3105)/ 2 ,  (EepromDataType)(1 - (address % 2)));
				break;
			case 3113: //	DO1类型
			case 3114: //	DO2类型
			case 3115: //	DO3类型
			case 3116: //	DO4类型
			case 3117: //	DO5类型
			case 3118: //	DO6类型
			case 3119: //	DO7类型
			case 3120: //	DO8类型
				data = get_eeprom_data(kRelay2_1ForceCtrlStatus + (address - 3113) / 2 ,  (EepromDataType)(1 - (address % 2)));
				break;

			case 3121: //	DI1控制
			case 3122: //	DI2控制
			case 3123: //	DI3控制
			case 3124: //	DI4控制
			case 3125: //	DI5控制
			case 3126: //	DI6控制
			case 3127: //	DI7控制
			case 3128: //	DI8控制
				data = get_eeprom_data(kEep_Di2_1Type + (address - 3121) / 2 ,  (EepromDataType)(1 - (address % 2)));
				break;
			case 3129: //	DI1类型
			case 3130: //	DI2类型
			case 3131: //	DI3类型
			case 3132: //	DI4类型
			case 3133: //	DI5类型
			case 3134: //	DI6类型
			case 3135: //	DI7类型
			case 3136: //	DI8类型
				data = get_eeprom_data(kEep_Di2_1Polarity + (address - 3129) / 2 ,  (EepromDataType)(1 - (address % 2)));
				break;
			
			case 3137: //	DO1故障检测源
			case 3138: //	DO2故障检测源
			case 3139: //	DO3故障检测源
			case 3140: //	DO4故障检测源
			case 3141: //	DO5故障检测源
			case 3142: //	DO6故障检测源
			case 3143: //	DO7故障检测源
			case 3144: //	DO8故障检测源
				data = get_eeprom_data(kEep_DO2_DO1_ErrSrc + (address - 3137) / 2 , (EepromDataType) (1 - (address % 2)));
				break;

			case 3145: //		预充次数
			case 3146: //		预充超时时间(s)
				data = get_eeprom_data(kEep_PreChgTimeout_Count ,  (EepromDataType)(1 - (address % 2)));
				break;
			case 3147: //		预充电压比例(%)
			case 3148: //		预充类型
					data = get_eeprom_data(kEep_PreChgVoltType_Rate ,  (EepromDataType)(1 - (address % 2)));
				break;
			case 3149:  //	系统时间(s)
				data = 0;
				//drv_rtc_set_tick(bcu_holding_reg.sys_time);
				break;
			case 3150:  //	系统时间(s)
				data = year;
				break;
			case 3151:  //	系统时间(s)
				data = mon;
				break;
			case 3152:  //	系统时间(s)
				data = day;
				break;
			case 3153:  //	系统时间(s)
				data = hour;
				break;
			case 3154:  //	系统时间(s)
				data = min;
				break;
			case 3155:  //	系统时间(s)
				data = sec;
				break;
			case 3156:  //	系统复位
				//data = get_eeprom_data(kEep_IsSoftReset ,  kEepromDataType_Full);
				data = 0;
				break;
			case 3157:  //	均衡开启电压(mv)
			case 3158:  //	均衡关闭电压(mv)(mv)
				data = get_eeprom_data(kEep_DataBanlenceStartVolt + address - 3157 ,  kEepromDataType_Full);
				break;
			case 3159:  //	均衡开启压差(mv)(mv)
			case 3160:  //	均衡关闭压差(mv)(mv)
				data = get_eeprom_data(kEep_BalanceOpenVolDiff_CloseVolDiff , (EepromDataType) (1 - (address % 2)));
				break;
			case 3161:  //	均衡路数
				data = get_eeprom_data(kEep_BalanceNum ,  kEepromDataType_Full);
				break;
			case 3162:  //	均衡时间
				data = get_eeprom_data(kEep_BalanceTime ,  kEepromDataType_Full);
				break;	
			case 3163:  //	DO9控制
			case 3164:  //	DO10控制
				data = get_eeprom_data(kEep_Relay10_9Type + (address - 3163)/ 2 ,  (EepromDataType)(1 - (address % 2)));
				break;
			case 3165:  //	DO9类型
			case 3166:  //	DO10类型
				data = get_eeprom_data(kRelay10_9ForceCtrlStatus + (address - 3165) / 2 , (EepromDataType) (1 - (address % 2)));
				break;
			case 3167:  //	DO9故障源
			case 3168:  //	DO10故障源
				data = get_eeprom_data(kEep_DO10_DO9_ErrSrc + (address - 3167) / 2 , (EepromDataType) (1 - (address % 2)));
				break;
			default:
				break;
		}	
		WRITE_BT_INT16U(buf, addr, data);
	}
	return addr;
}
static uint8_t fill_buf[1000];
BspMdExCode bcu_modbus_485_0x03_fun(uint16_t start_addr, uint16_t reg_num, uint8_t *buf, uint16_t *len)
{
    BspMdExCode err = kBspMdEx_None;
    //kit_time_dly_ms(50);
    if((start_addr >=  3000) && (start_addr + reg_num <= 3169))
	{
        *len = bcu_total_cfg_fill(start_addr, reg_num, buf);
	} 
    else if((start_addr >= 4000) && ((start_addr + reg_num ) <= 4999))
    {
        hmi_fill_modbus_cfg(fill_buf);
        *len = reg_num << 1;
        kit_copy_buf(buf, &fill_buf[(start_addr - 4000) << 1],  *len);        
    }	
    else
    {
        err = kBspMdEx_InvalidAddr;
    }
    return err;	
}


BspMdExCode bcu_modbus_485_0x04_fun(uint16_t start_addr, uint16_t reg_num, uint8_t *buf, uint16_t *len)
{

    BspMdExCode err = kBspMdEx_None;

    //kit_time_dly_ms(50);
    if((start_addr + reg_num ) <= 200)
    {
        *len = bcu_total_msg_fill(start_addr, reg_num, buf);
    }
	else if((start_addr >= 1000) && ((start_addr + reg_num ) <= 1500))
	{
        bcu_cell_volt_msg_fill(fill_buf);
        *len = reg_num << 1;
        kit_copy_buf(buf, &fill_buf[(start_addr - 1000) << 1],  *len);		
	}
	else if((start_addr >= 1600) && ((start_addr + reg_num ) <= 2100))
	{
        bcu_cell_temperature_msg_fill(fill_buf);
        *len = reg_num << 1;
        kit_copy_buf(buf, &fill_buf[(start_addr - 1600) << 1],  *len);		
	}
	else if((start_addr >= 5000) && ((start_addr + reg_num ) <= 5699))
	{
        bms_fill_gate_read_data(fill_buf);
        *len = reg_num << 1;
        kit_copy_buf(buf, &fill_buf[(start_addr - 5000) << 1],  *len);		
	}       
    else
    {
        err = kBspMdEx_InvalidAddr;
    }
    return err;	
}

void bcu_data_set_0x06_msg(uint16_t address,uint16_t data)
{
	uint16_t factor = 1000;
	switch(address)
	{
		case 3000:
			bsp_eeprom_save_data(kEep_DevAddr_SlaverNum,data,kEepromDataType_Low);
			break;
		case 3001:
		case 3002:
			bsp_eeprom_save_data(kEep_CellNum + address - 3001,data,kEepromDataType_Full);
			break;
		case 3003:
			bsp_eeprom_save_data(kEep_Standby_LowVoltSleepDly,data,kEepromDataType_Full);
			break;
		case 3004:
		case 3005:
			bsp_eeprom_save_data(kEep_HeatOn_OffTemp,data,(EepromDataType)(1 -(address % 2)));
			break;    
		case 3006: //制冷开启温度(℃)
		case 3007: //制冷关闭温度(℃)
			bsp_eeprom_save_data(kEep_CoolOn_OffTemp,data,(EepromDataType)(1 -(address % 2)));
			break; 
		case 3008: //额定容量
			bsp_eeprom_save_data(kEep_RatedCapacity,data,kEepromDataType_Full);
			break; 
		case 3009:
		case 3010:
			bsp_eeprom_save_data(kEep_InterCanProtocol_Baudrate,data,(EepromDataType)(1 - (address % 2)));
			break; 
		case 3011: //485_1波特率  485_1校验位
		case 3012:
			bsp_eeprom_save_data(kEep_InterCanProtocol_Baudrate,data,(EepromDataType)(1 - (address % 2)));
			break; 
		case 3013: //485_1设备地址 
		case 3014: //485_1设备协议
			bsp_eeprom_save_data(kEep_InterRS485_SlaveID_Protocol,data,(EepromDataType)(address % 2));
			break; 
		case 3015: //485_1波特率  485_1校验位
		case 3016:
			bsp_eeprom_save_data(kEep_Exter485_2Parity_Baudrate,data,(EepromDataType)(1 - (address % 2)));
			break; 
		case 3017: //485_1设备地址 
		case 3018: //485_1设备协议
			bsp_eeprom_save_data(kEep_ExterRS485_1SlaveID_Protocol,data,(EepromDataType)(address % 2));
			break; 
		
		case 3019: //485_2波特率  485_2校验位
		case 3020:
			bsp_eeprom_save_data(kEep_Exter485_2Parity_Baudrate,data,(EepromDataType)(1 - (address % 2)));
			break; 
		case 3021: //485_2设备地址 
		case 3022: //485_2设备协议
			bsp_eeprom_save_data(kEep_ExterRS485_2SlaveID_Protocol,data,(EepromDataType)(address % 2));
			break; 
		
		case 3023: //电流传感器1类型
		case 3030: //电流传感器2类型
			bsp_eeprom_save_data(kEep_CurSensor2_1Type,data,(EepromDataType)(1 - (address % 2)));
			break;
		case 3024: //霍尔摆幅电压(mV)
			bsp_eeprom_save_data(kEep_HallSwingVolt,data,kEepromDataType_Full);
			break;
		case 3025: //电流传感器1量程(A)
		case 3032: //电流传感器2量程(A)
			bsp_eeprom_save_data(kEep_CurSensor2_1Range,data,(EepromDataType)(1 - (address % 2)));
			break;
		case 3026: //电流传感器1方向
		case 3033: //电流传感器2方向
			bsp_eeprom_save_data(kEep_CurSensor2_1Dir,data,(EepromDataType)(1 - (address % 2)));
			break;
		case 3027: //电流传感器1滤波(A)
		case 3034: //电流传感器2滤波(A)
			bsp_eeprom_save_data(kEep_ZeroFilter2_1Filter,data,(EepromDataType)(1 - (address % 2)));
			break;
		case 3028: //电流传感器1偏移(A)(A)
		case 3035: //电流传感器2偏移(A)(A)
			bsp_eeprom_save_data(kEep_CurSensor2_1Offset,data,(EepromDataType)(1 - (address % 2)));
			break;
		case 3029: //霍尔1矫正增益
			bsp_eeprom_save_data(kEep_Shunt1CaliGain,data,kEepromDataType_Full);
			break;
		case 3036: //霍尔2矫正增益
			bsp_eeprom_save_data(kEep_Shunt2CaliGain,data,kEepromDataType_Full);
			break;
		case 3037: //分流器额定电压(mV)
		case 3038: //充电电流方向
			bsp_eeprom_save_data(kEep_ChgCurDir_ShuntRatedVolt,data,(EepromDataType)(1 - (address % 2)));
			break;
		case 3039: //目标电流
			if (KIT_ABS(bms_get_current()) != 0)
			{
				factor = (uint32_t)data * 1000 / KIT_ABS(bms_get_current()); // 扩大1000倍
			}
			bsp_eeprom_set_data(kEep_TargetCurrent, data, kEepromDataType_Full);
			if ((factor > 900) && (factor < 1100))
			{
				bsp_eeprom_save_data(kEep_Hall1CalFactor, factor, kEepromDataType_Full);
			}
			else
			{
				bsp_eeprom_save_data(kEep_Hall1CalFactor, 1000, kEepromDataType_Full);
			}
			bsp_eeprom_save_data(kEep_TargetCurrent,data,kEepromDataType_Full);
			break;	
		case 3040: //循环次数
			bms_set_cycle(data);
		    bsp_eeprom_save_data(kEep_CycleTimes, data,kEepromDataType_Full);
			break;
		case 3041: //SOC设置
			bms_set_soc(data);
		    bsp_eeprom_save_data(kEep_SOC, data,kEepromDataType_Full);
			break;
		case 3042: //SOE设置  //soc就是soe暂时替换
			bms_set_soc(data);
			break;
		case 3043: //日充放电累计时间
		case 3044: //日放电累计容量L
		case 3045: //日放电累计容量H
		case 3046: //日放电电量L
		case 3047: //日放电电量H
		case 3048: //日充电电电量L
		case 3049: //日充电电电量H
		case 3050: //日充电累计时间L
		case 3051: //日充电累计时间H
		case 3052: //日充电电电量L
		case 3053: //日充电电电量H
		case 3054: //放电累计时间L
		case 3055: //放电累计时间H
		case 3056: //放电累计容量L
		case 3057: //放电累计容量H
		case 3058: //放电累计电量L
		case 3059: //放电累计电量H
		case 3060: //充电累计时间L
		case 3061: //充电累计时间H
		case 3062: //充电累计容量L
		case 3063: //充电累计容量H
		case 3064: //放电累计电量L
		case 3065: //放电累计电量H
		case 3066: //下电时间L
		case 3067: //下电时间H
			bsp_eeprom_save_data(kEep_DayChg_DisTime + address - 3043,data,kEepromDataType_Full);
			break;
		case 3068:	//SOC满充校准电压(mV)
		case 3069:	//SOC满放校准电压(mV)
			bsp_eeprom_save_data(kEep_FullDisVolt + address - 3068,data,kEepromDataType_Full);
			break;
		case 3070:	//SOC满充校准平均电压(mV)
		case 3071:	//SOC满放校准平均电压(mV)
			bsp_eeprom_save_data(kEep_FullDisAvgVolt + address - 3070,data,kEepromDataType_Full);
			break;
		case 3072:	//SOC过充校准总压电压值
		case 3073:	//SOC过放校准总压电压值
			bsp_eeprom_save_data(kEep_FullChgTotalVolt + address - 3072,data,kEepromDataType_Full);
			break;
		case 3074:	//SOC过充校准总压电压值
			bsp_eeprom_save_data(kEep_ForbidChgRelVolt,data,kEepromDataType_Full);
			break;
		case 3075:	//SOC过放校准总压电压值
			bsp_eeprom_save_data(kEep_ForbidDisRelVolt,data,kEepromDataType_Full);
			break;
		case 3076:	//禁放释放时间(min)
		case 3077:	//禁充释放时间(min)
			bsp_eeprom_save_data(kEep_ForbidDisRelDelay + address - 3076,data,kEepromDataType_Full);
			break;
		case 3078:	//	OCV表索引
		case 3079:	//	SOP表索引
			bsp_eeprom_save_data(kEep_Sop_OcvIndex,data, (EepromDataType)(address % 2));
			break;

		case 3080:	//	OCV静置时间(h)
		case 3081:	//	OCV静置电流(A)
			bsp_eeprom_save_data(kEep_OcvStandbyCur_Time,data,(EepromDataType)(address % 2));
			break;
		case 3082:	//	OCV禁校上限(%)
		case 3083:	//	OCV禁校下限(%)
			bsp_eeprom_save_data(kEep_OcvDisRangeLower_Upper,data, (EepromDataType)(address % 2));
			break;
		case 3084:	//	SOC上限(%)
		case 3085:	//	SOC下限(%)
			bsp_eeprom_save_data(kEep_SOCRunMax_Min,data, (EepromDataType)(1 - (address % 2)));
			break;
		case 3086:	//	额定总压(V)
		case 3087:	//	请求充电电压(V)
			bsp_eeprom_save_data(kEep_RatedTotalVolt + address - 3086,data, kEepromDataType_Full);
			break;
		case 3088:	//	额定充电电流(A)(A)
		case 3089:	//	额定放电电流(A)(V)
			bsp_eeprom_save_data(kEep_RatedChgCur + address - 3088,data, kEepromDataType_Full);
			break;
		
		case 3090:	//	额定充电功率(kw)(kw)
		case 3091:	//	额定放电功率(kw)
			bsp_eeprom_save_data(kEep_RatedChgPower + address - 3090,data, kEepromDataType_Full);
			break;
		case 3092:	//	充电末端一段降流电压(V)
		case 3093:	//	充电末端二段降流电压(V)
			bsp_eeprom_save_data(kEep_ChgFstCurDownVolt + address - 3092,data, kEepromDataType_Full);
			break;
		case 3094:	//	充电末端一段降流系数
		case 3095:	//	充电末端二段降流系数
			bsp_eeprom_save_data(kEep_ChgSnd_FstCurDownRate,data, (EepromDataType)(address % 2));
			break;
		case 3096:	//	充放电模式
			bsp_eeprom_save_data(kEep_ChgDisMode_HighVoltStrategy,data, kEepromDataType_High);
			break;
		case 3097:	//	目标电压
			bsp_eeprom_save_data(kEep_TargetVolt,data, kEepromDataType_Full);
			break;
		case 3098:	//	高压控制策略
			bsp_eeprom_save_data(kEep_ChgDisMode_HighVoltStrategy,data, kEepromDataType_Low);
			break;
		
		case 3099:	//	放电上电自检故障L
		case 3100:	//	放电上电自检故障H
		case 3101:	//	充电上电自检故障L
		case 3102:	//	充电上电自检故障H
			bsp_eeprom_save_data(kEep_DisSelfFaultLow + address - 3099,data, kEepromDataType_Full);
			break;
		case 3103://	绝缘使能
			bsp_eeprom_save_data(kEep_InsuPeriod_Enable,data, kEepromDataType_Low);
			break;
		case 3104://	上下电模式
			bsp_eeprom_save_data(kEep_ChgDisChangeBasis_RelayOnOffMode,data, kEepromDataType_Low);
			break;
		case 3105: //   Do1
		case 3106: //	DO2控制
		case 3107: //	DO3控制
		case 3108: //	DO4控制
		case 3109: //	DO5控制
		case 3110: //	DO6控制
		case 3111: //	DO7控制
		case 3112: //	DO8控制
			bsp_eeprom_save_data(kEep_Relay2_1Type + ((address - 3105) / 2) ,data, (EepromDataType)(1 - (address % 2)));
			break;
		case 3113: //	DO1类型
		case 3114: //	DO2类型
		case 3115: //	DO3类型
		case 3116: //	DO4类型
		case 3117: //	DO5类型
		case 3118: //	DO6类型
		case 3119: //	DO7类型
		case 3120: //	DO8类型
			bms_force_crtl_do_status((DoType)(address - 3113), (DoCtrlStatus)data);
			bsp_eeprom_save_data(kRelay2_1ForceCtrlStatus + (address - 3113) / 2 ,data, (EepromDataType)(1 - (address % 2)));
			break;

		case 3121: //	DI1控制
		case 3122: //	DI2控制
		case 3123: //	DI3控制
		case 3124: //	DI4控制
		case 3125: //	DI5控制
		case 3126: //	DI6控制
		case 3127: //	DI7控制
		case 3128: //	DI8控制
			bsp_eeprom_save_data(kEep_Di2_1Type + (address - 3121) / 2 ,data, (EepromDataType)(1 - (address % 2)));
			break;
		case 3129: //	DI1类型
		case 3130: //	DI2类型
		case 3131: //	DI3类型
		case 3132: //	DI4类型
		case 3133: //	DI5类型
		case 3134: //	DI6类型
		case 3135: //	DI7类型
		case 3136: //	DI8类型
			bsp_eeprom_save_data(kEep_Di2_1Polarity + (address - 3129) / 2 ,data, (EepromDataType)(1 - (address % 2)));
			break;
		
		case 3137: //	DO1故障检测源
		case 3138: //	DO2故障检测源
		case 3139: //	DO3故障检测源
		case 3140: //	DO4故障检测源
		case 3141: //	DO5故障检测源
		case 3142: //	DO6故障检测源
		case 3143: //	DO7故障检测源
		case 3144: //	DO8故障检测源
			bsp_eeprom_save_data(kEep_DO2_DO1_ErrSrc + (address - 3137) / 2 ,data,(EepromDataType) (1 - (address % 2)));
			break;

		case 3145: //		预充次数
		case 3146: //		预充超时时间(s)
			bsp_eeprom_save_data(kEep_PreChgTimeout_Count ,data, (EepromDataType)(1 - (address % 2)));
			break;
		case 3147: //		HV电压比例(%)
		case 3148: //		预充电压比例(%)
			bsp_eeprom_save_data(kEep_PreChgVoltType_Rate ,data, (EepromDataType)(1 - (address % 2)));
			break;
		case 3149:  //	系统时间(s)
			bcu_holding_reg.sys_time = data;
            drv_rtc_set_tick(bcu_holding_reg.sys_time);
			break;
		
		case 3156:  //	系统复位
			//bsp_eeprom_save_data(kEep_IsSoftReset ,data, kEepromDataType_Full);
			if(data == 1)
			{
				bms_soft_reset_save(kSoftReset_CmdCtrl, NULL, 0);
				drv_misc_reset_mcu();
			}
			break;
		case 3157:  //	均衡开启电压(mv)
		case 3158:  //	均衡关闭电压(mv)(mv)
			bsp_eeprom_save_data(kEep_DataBanlenceStartVolt + address - 3157 ,data, kEepromDataType_Full);
			break;
		case 3159:  //	均衡开启压差(mv)(mv)
		case 3160:  //	均衡关闭压差(mv)(mv)
			bsp_eeprom_save_data(kEep_BalanceOpenVolDiff_CloseVolDiff ,data,(EepromDataType) (1 - (address % 2)));
			break;
		case 3161:  //	均衡路数
			bsp_eeprom_save_data(kEep_BalanceNum ,data,kEepromDataType_Full);
			break;
		case 3162:  //	均衡时间
			bsp_eeprom_save_data(kEep_BalanceTime , data, kEepromDataType_Full);
			break;	
		case 3163:  //	DO9控制
		case 3164:  //	DO10控制
			bsp_eeprom_save_data(kEep_Relay10_9Type  + (address - 3163) / 2,data,(EepromDataType)(1 - (address % 2)));
			break;
		case 3165:  //	DO9类型
		case 3166:  //	DO10类型
			bms_force_crtl_do_status((DoType)(address - 3165 + 8), (DoCtrlStatus)data);
			bsp_eeprom_save_data(kRelay10_9ForceCtrlStatus + (address - 3165) / 2 ,data, (EepromDataType)(1 - (address % 2)));
		case 3167:  //	DO9故障源
		case 3168:  //	DO10故障源
			bsp_eeprom_save_data(kEep_DO10_DO9_ErrSrc + (address - 3167) / 2 ,data, (EepromDataType)(1 - (address % 2)));
			break;		
		default:
			break;
	}	
}

//gary add 高压上下电指令 20240710
void bcu_data_set_0x06_on_of_msg(uint16_t address,uint16_t data)
{
	//uint16_t factor = 1000;
	switch(address)
	{
		case 3200:
			if(get_eeprom_data(kEep_ChgDisChangeBasis_RelayOnOffMode,kEepromDataType_Low) == kRunCtrl_Cmd)
			{
				if(data == 0)
				{
					bms_set_circuit_cmd_status(kCircuitStatus_Off);
				}
				else if(data == 1)
				{
					bms_set_circuit_cmd_status(kCircuitStatus_On);
				}
			}
			break;
		//预留
		case 3201:
		case 3202:
		case 3203:
		case 3204:
			break;			
		default:
				break;
	}
	return;
}



BspMdExCode bcu_modbus_485_0x06_fun(uint16_t start_addr, uint16_t reg_num, uint8_t *buf, uint16_t *len)
{
    BspMdExCode err = kBspMdEx_None;
	uint16_t data;
	data = (buf[0] << 8) + buf[1];
    
    //kit_time_dly_ms(50);
    if((start_addr >=  3000) && (start_addr <= 3149))
    {
        bcu_data_set_0x06_msg(start_addr, data);
        *len = reg_num << 1;
    }   
	else if((start_addr >=  3157) && (start_addr <= 3169))
    {
        bcu_data_set_0x06_msg(start_addr, data);
        *len = reg_num << 1;
    } 
	else if((start_addr >=  3200) && (start_addr <= 3204))
    {
        bcu_data_set_0x06_on_of_msg(start_addr, data);
        *len = reg_num << 1;
    } 
    else if((start_addr >= 4000) && (start_addr <= 4999))
    {
        hmi_write_modbus_cfg(start_addr - 4000, data);
        *len = reg_num << 1;     
    }
    else if((start_addr >= 5700) && (start_addr <= 5999))
    {
        data = (buf[1] << 8) + buf[0];
        data = bms_set_gate_write_data(start_addr - 5700, data);
        bsp_eeprom_save_data(start_addr - 5700 + kEep_GateDataStart, data, kEepromDataType_Full);
        *len = reg_num << 1;     
    }    
    else
    {
        err = kBspMdEx_InvalidAddr;
    }
    return err;
}

void bcu_modbus_set_time_to_bms_msg(uint8_t *buf)
{
	uint16_t addr = 0, tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec; 
	tm_year = READ_BT_INT16U(buf, addr); 
	tm_mon  = READ_BT_INT16U(buf,addr);
	tm_mday = READ_BT_INT16U(buf,addr);
	tm_hour = READ_BT_INT16U(buf,addr);
	tm_min  = READ_BT_INT16U(buf,addr);
	tm_sec  = READ_BT_INT16U(buf,addr);
	drv_rtc_set_time(tm_hour, tm_min, tm_sec);
	drv_rtc_set_date(tm_year, tm_mon, tm_mday);	
}

BspMdExCode bcu_modbus_485_0x10_fun(uint16_t start_addr, uint16_t reg_num, uint8_t *buf, uint16_t *len)
{
    uint8_t fill_buf[12],i = 0;
	uint16_t data;
    BspMdExCode err = kBspMdEx_None;
	if((start_addr >= 3150)&&(start_addr <= 3155))
	{
		kit_copy_buf(&fill_buf[start_addr - 3150], &buf[0], 6 * 2);
		bcu_modbus_set_time_to_bms_msg((uint8_t *)fill_buf);
	}
	else if((start_addr >=  3000) && (start_addr <= 3161))
	{
		for(i = 0; i < reg_num;i++)
		{
			data = (buf[i * 2] << 8) + buf[i * 2 + 1];
			bcu_data_set_0x06_msg(start_addr + i, data);
		}
	}
    else
    {
        err = kBspMdEx_InvalidAddr;
    }
    return err;	
}

void protocol_modbus_bcu_init(void * const mb_item,uint16_t addr)
{
    bsp_modbus_set_slaver_addr((ModbusItem *)mb_item, addr);
    register_modbus_fun((ModbusItem *)mb_item, kModbusFun_0x03, bcu_modbus_485_0x03_fun);
	register_modbus_fun((ModbusItem *)mb_item, kModbusFun_0x04, bcu_modbus_485_0x04_fun);
	register_modbus_fun((ModbusItem *)mb_item, kModbusFun_0x06, bcu_modbus_485_0x06_fun);
    register_modbus_fun((ModbusItem *)mb_item, kModbusFun_0x10, bcu_modbus_485_0x10_fun);
}