#include "kit_data.h"

#include "bsp_can.h"
#include "bsp_eeprom.h"

#include "bmu_manager.h"
#include "iso_check.h"
#include "version_manager.h"
#include "soc_calculate.h"
#include "sop_calculate.h"
#include "fault_manager.h"
#include "hv_adc_manager.h"
#include "eeprom_manager.h"
#include "dido_manager.h"
#include "statistic_manager.h"
#include "run_status.h"
#include "bmu_manager.h"

#include "protocol_comm.h"


//BCU广播报文1
void bcu_send_0x18010000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint16_t tmp_16u;
	uint8_t tmp_8u,status;
	static uint8_t heart_bit = 0;
	
	switch(bms_get_run_status())
	{
		case kRunStatus_Init:
			status = 0;	
			break;
		case kRunStatus_Standby:
			status = 1;
			break;
		case kRunStatus_Chg:
			status = 2;
			break;
		case kRunStatus_Dis:
			status = 3;
		default:
			break;
	}
	
	//电池组总电压
	tmp_16u = bms_get_statistic_data(kStatisticData_TotalVolt);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//电池组充/放电总电流
	tmp_16u = bms_get_current() + 32000;
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//电池模块SOC
	tmp_8u = (uint8_t )(bms_get_soc()/100);
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//电池模块SOH
	tmp_8u = (uint8_t)(bms_get_soh()/100);
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//BMS工作状态
	tmp_8u = status;
	WRITE_LT_INT8U(buf, len, tmp_8u);	
	//BMS心跳
	tmp_8u = heart_bit++;
	WRITE_LT_INT8U(buf, len, tmp_8u);
    bsp_can_ext_data_sync_send(can, 0x18010000, buf, len);
}

//BCU广播报文2
void bcu_send_0x18020000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint16_t tmp_16u;

	//电池总容量
	tmp_16u = get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//电池剩余容量
	tmp_16u = (uint32_t)bms_get_soc()*get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)/10000;;
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//系统额定电量
	tmp_16u = get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000;
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//预留
	WRITE_LT_INT16U(buf, len, 0);	
    bsp_can_ext_data_sync_send(can, 0x18020000, buf, len);
}

//BCU广播报文3
void bcu_send_0x18030000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint16_t tmp_16u;

	//在线电池总数
	tmp_16u = bms_get_statistic_data(kStatisticData_OnlineCellNum);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//在线温感总数
	tmp_16u = get_eeprom_data(kEep_TempNum, kEepromDataType_Full);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//循环次数
	tmp_16u = bms_get_cycle();
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//预留
	tmp_16u = 0;
	WRITE_LT_INT16U(buf, len, tmp_16u);
	
    bsp_can_ext_data_sync_send(can, 0x18030000, buf, len);
}

//BCU广播报文4
void bcu_send_0x18040000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint16_t tmp_16u;

	//最大允许充电电流
	tmp_16u = bms_get_sop_data(kSopData_ChgCur);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//最大允许放电电流
	tmp_16u = bms_get_sop_data(kSopData_DisCur);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//最大允许充电功率
	tmp_16u = bms_get_sop_data(kSopData_ChgCur) * bms_get_statistic_data(kStatisticData_TotalVolt) / 10000;
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//最大允许放电功率
	tmp_16u = get_eeprom_data(kEep_DisLTVoltLTAlarm1, kEepromDataType_Full);
	WRITE_LT_INT16U(buf, len, tmp_16u);	
    bsp_can_ext_data_sync_send(can, 0x18040000, buf, len);
}

//BCU广播报文5
void bcu_send_0x18050000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint16_t tmp_16u;

	//最高单体电压
	tmp_16u = bms_get_statistic_data(kStatisticData_MaxVolt);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//最低单体电压
	tmp_16u = bms_get_statistic_data(kStatisticData_MinVolt);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//最大压差
	tmp_16u = bms_get_statistic_data(kStatisticData_VoltDiff);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//平均电压
	tmp_16u = bms_get_statistic_data(kStatisticData_AvgVolt);
	WRITE_LT_INT16U(buf, len, tmp_16u);	
    bsp_can_ext_data_sync_send(can, 0x18050000, buf, len);
}


//BCU广播报文6
void bcu_send_0x18060000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint16_t tmp_16u;

	//最高单体温度
	tmp_16u = bms_get_statistic_data(kStatisticData_MaxTemp);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//最低单体温度
	tmp_16u = bms_get_statistic_data(kStatisticData_MinTemp);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//单体温差
	tmp_16u = bms_get_statistic_data(kStatisticData_TempDiff);
	WRITE_LT_INT16U(buf, len, tmp_16u);
	//平均温度
	tmp_16u = bms_get_statistic_data(kStatisticData_AvgTemp);
	WRITE_LT_INT16U(buf, len, tmp_16u);	
    bsp_can_ext_data_sync_send(can, 0x1806FF00, buf, len);
}

//BCU广播报文7
void bcu_send_0x18070000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint8_t tmp_8u;

	//最高单体电压从机序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MaxVoltBmuIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//最高单体电压电池序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MaxVoltIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//最低单体电压从机序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MinVoltBmuIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//最低单体电压电池序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MinVoltIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//最高单体温度从机序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MaxTempBmuIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//最高单体温度温感序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MaxTempIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//最低单体温度从机序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MinTempBmuIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//最低单体温度温感序号
	tmp_8u = bms_get_statistic_data(kStatisticData_MinTempIdx) + 1;
	WRITE_LT_INT8U(buf, len, tmp_8u);
    bsp_can_ext_data_sync_send(can, 0x18070000, buf, len);
}
#include "signal_manager.h"
//BCU广播报文8
void bcu_send_0x18080000(can_dev_e can)
{
    uint8_t len = 0, buf[8];
	uint8_t tmp_8u;

	//故障最高等级
	tmp_8u = bms_get_max_fault_level();
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//断继电器故障
	tmp_8u = (bms_get_fault_relay_off_bit() != 0);
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//禁充标志
	tmp_8u = (bms_get_signal(kSignalIdx_ForbidChg) == kSignalStatus_High);
	WRITE_LT_INT8U(buf, len, tmp_8u);
	//禁放标志
	tmp_8u = (bms_get_signal(kSignalIdx_ForbidDis) == kSignalStatus_High);
	WRITE_LT_INT8U(buf, len, tmp_8u);
	
	WRITE_LT_INT32U(buf, len, 0);

    bsp_can_ext_data_sync_send(can, 0x18080000, buf, len);
}

void bcu_can_receive(CanMsg *msg, can_dev_e can)
{
	uint8_t code = 0,value = 0;
    if(msg->id.value == 0x181CFFF4)
    {	
		code = msg->data.byte[0];
		value = msg->data.byte[1];
		if(code == 1)
		{
			bsp_eeprom_save_data(kEep_ChgDisChangeBasis_RelayOnOffMode, value,kEepromDataType_Low);
		}
        if(code == 0 && get_eeprom_data(kEep_ChgDisChangeBasis_RelayOnOffMode, kEepromDataType_Low) == kRunCtrl_Cmd)
        {
			bms_set_circuit_cmd_status((CircuitStatus)value);
        }
    }
}

void bcu_can_send(uint32_t base_time,can_dev_e can)
{
	static uint32_t dly = 0;
	
    dly += base_time;
	if((dly % 100) == 0)
	{
		dly = 0;
        bcu_send_0x18010000(can);
		bcu_send_0x18020000(can);
		bcu_send_0x18030000(can);
		bcu_send_0x18040000(can);
		bcu_send_0x18050000(can);
		bcu_send_0x18060000(can);
		bcu_send_0x18070000(can);
		bcu_send_0x18080000(can);
	}
}

void protocol_can_bcu_init(can_dev_e can)
{
    protocol_can_set_call(can, bcu_can_receive, bcu_can_send,NULL);
}




