#ifndef _SOFT_BMS_H
#define _SOFT_BMS_H

#include "common.h"
#include "stdint.h"

//VK电池协议 0x1E0958
#define VK_BMS_FILTER_ID 0xE0800           //0 0000 0000 1110 0000 1000 0000 0000   flag 111 目标节点0x1
#define VK_BMS_MASK_ID   0x1C0FF800       //1 1100 0000 1111 1111 1000 0000 0000
  //0x1C0E0800
#define VK_MSG_MASK_ID 0X3F00000
#define VK_SRC_MASK_ID 0X7E0

/***************************************herewin********************************************/
#define HEREWIN_HEART_ID         0x004300F0  //心跳数据包
#define HEREWIN_VOL_ID           0x008400F0  //单体电压包
#define HEREWIN_TEM_ID           0x008200F0  //单体温度包
#define HEREWIN_SEARCH_ID        0x008000F0  //定值查询
#define HEREWIN_CIRCULATION_ID   0x008600F0  //循环次数查询
#pragma pack(1)
typedef struct 
{
    uint8_t herewin_buf[64]; //临时buf
    uint8_t message_num;  //报文序号
    uint8_t message_total;//总帧数
    uint16_t byte_num;    //有效字节数
    int last_frame_num;  //最后一包有效字节数
    uint16_t crc;         //和校验
    uint8_t i;
    bool crc_is_ok;       //校验通过
}herewin_can_info;
#pragma pack()

#pragma pack(1)
typedef struct 
{
    char battery_temp[3];   //每个电芯温度°C
    uint16_t battery_vol[14];   //每个电芯电压 0.001V
    uint16_t    alarm_info;        //报警信息
    uint16_t warn_info;         //警告信息
    uint16_t total_vol;         //总电压 0.01V 
    uint16_t tolal_ele;         //总电流 0.01A
    uint8_t SOC_info;           //剩余电量%
    uint8_t SOH_info;           //健康状态%
    uint8_t SOP_info;           //功率状态%
    uint32_t serial_number;     //序列号
    uint16_t hard_version;      //硬件版本
    uint16_t soft_version;      //软件版本
    uint8_t  battery_num;       //电芯个数
    uint16_t circulation_num;   //循环次数
    
    //充电请求相关参数
    uint16_t re_vol;            //请求电压
    uint16_t re_ele;            //请求电流
    uint16_t max_vol;           //单体最大电压
    uint16_t power_status;      //充电状态

    bool get_temp_flag;        //温度是单独一包，并且有偏移，没获取到温度之前会显示负数

}herewin_bms;
#pragma pack()
extern herewin_bms herewin_info;
extern Connect_check Herewin_Link;
void HerewinCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len);
void send_msg_to_herewin(void);
/***********************************************************************************/


/***************************************Okcell********************************************/
#pragma pack(1)
typedef struct
{
    uint16_t cell_d0[33];  //13s字节到20，扩展到15s。
}_CELL_D0;
#pragma pack()

#pragma pack(1)
typedef struct
{
    uint16_t cell_d1[3];
}_CELL_D1;
#pragma pack()



#pragma pack(1)
typedef struct
{
    uint16_t cell_d2[2];
}_CELL_D2;
#pragma pack()

#pragma pack(1)
typedef struct
{
    uint16_t cell_d3[9];
}_CELL_D3;
#pragma pack()


#pragma pack(1)
typedef struct
{
    uint16_t cell_d4[4];
}_CELL_D4;
#pragma pack()


#pragma pack(1)
typedef struct
{
    uint8_t cell_p2[4];
}_CELL_P2;
#pragma pack()


#pragma pack(1)
typedef struct
{
    uint8_t cell_p3[12];
}_CELL_P3;
#pragma pack()


#pragma pack(1)
typedef struct
{
    uint32_t cell_CanID;
    _CELL_D0 cell_D0;
    _CELL_D1 cell_D1;
    _CELL_D2 cell_D2;
    _CELL_D3 cell_D3;
    _CELL_D4 cell_D4;
    _CELL_P2 cell_P2;
    _CELL_P3 cell_P3;
}_CELL_INF;
#pragma pack()
#define OKCELL_MAXLEN 200
#pragma pack(1)
typedef struct {
    uint32_t deviceCanID;

    unsigned char Okcell_recv_buf[OKCELL_MAXLEN];
    short Okcell_recv_index;
    
    //获取到起始标志位
    bool Okcell_get_s;
    
    Connect_check Okcell_Link;
    
    
    //获取电池编号
    bool get_cellNumber;
    //获取电池SHA1加密文
    bool get_cellEncryption;
    uint32_t get_cellEncryption_counts;
    //电池波特率是否锁定
    bool cell_bps_lock_success;
    //由于锁定波特率缺少反馈应答，5s内收到多于10包正确的数据则认为波特率锁定成功。
    short recv_celldata_counts;
    uint32_t recv_celldata_time;
    
    _CELL_INF okcell_inf;

}_OKCELL_DEVICE;

extern uint8_t group_num;
#pragma pack()
extern _OKCELL_DEVICE okcell_device1, okcell_device2;


extern unsigned char okcell_sha1_out[20];

#define CAN_OKCELL_SEND_ID    (0x15350000)

#pragma pack(1)
struct OkCell_P80{

    char ok_s[4];
    char ok_cmd[2];
    char ok_len;
    char ok_flag;
    char ok_data;
    char ok_crc[2];
    char ok_e[3];
};
#pragma pack()
extern struct OkCell_P80 okcell_p80;


#pragma pack(1)
struct OkCell_P82{

    char ok_s[4];
    char ok_cmd[2];
    char ok_len;
    char ok_flag;
    char ok_data[4];
    char ok_crc[2];
    char ok_e[3];
};
#pragma pack()
extern struct OkCell_P82 okcell_p82;


#pragma pack(1)
struct OkCell_P83{

    char ok_s[4];
    char ok_cmd[2];
    char ok_len;
    char ok_flag;
    char ok_crc[2];
    char ok_e[3];
};
#pragma pack()
extern struct OkCell_P83 okcell_p83;


void OkcellCanRecvHookFunction(uint32_t cellCanID, uint8_t* data, uint8_t len);
void send_msg_to_okcell(void);

/***********************************************************************************/

#define TATTU_MAXLEN 200
#pragma pack(1)
typedef struct 
{
    unsigned char tail_tranid:5;
    unsigned char tail_toggle:1;
    unsigned char tail_end   :1;
    unsigned char tail_start :1;
}_TAIL_BYTE;
#pragma pack()

#pragma pack(1)
typedef struct
{
    //unsigned short def_info[26];  //tattu
    unsigned short tattu_company;
    unsigned short tattu_type;
    unsigned short tattu_volt;
    short tattu_cur;
    unsigned short tattu_temp;
    unsigned short tattu_perc;
    unsigned short tattu_cycle;
    unsigned short tattu_health;
    unsigned short tattu_v1;
    unsigned short tattu_v2;
    unsigned short tattu_v3;
    unsigned short tattu_v4;
    unsigned short tattu_v5;
    unsigned short tattu_v6;
    unsigned short tattu_v7;
    unsigned short tattu_v8;
    unsigned short tattu_v9;
    unsigned short tattu_v10;
    unsigned short tattu_v11;
    unsigned short tattu_v12;
    unsigned short tattu_v13;
    unsigned short tattu_v14;
    unsigned short tattu_descapa;
    unsigned short tattu_recapa;
    unsigned int tattu_err;
    unsigned char tuattu_id[16];
    
    unsigned short tattu_cnum;  //tattu
}_TATTU_INFO;
#pragma pack()
//extern _TATTU_INFO ttu_inf;

#pragma pack(1)
typedef struct {
    uint32_t deviceCanID;

    unsigned char Tattu_recv_buf[TATTU_MAXLEN];

    Connect_check Tattu_Link;
    
    short Tattu_recv_index;

    //获取到起始标志位
    bool Tattu_get_s;

    _TAIL_BYTE ttu_tailbyte;
    
    _TATTU_INFO ttu_inf;

}_TATTU_DEVICE;
#pragma pack()
extern _TATTU_DEVICE tattu_device1, tattu_device2;


extern comp_status tattu_link_status;
void TattuCanRecvHookFunction(uint32_t ttuCanID, uint8_t data[], uint8_t len);

extern uint16_t CCITT_CRC16;
void CCITT_CRC16Init(uint8_t const *bytes, uint16_t len);
void CCITT_CRC_ARRAY(uint8_t const * bytes, uint16_t len);


/***********************************************************************************/


/***************************************VKBMS********************************************/
#pragma pack(1)
struct BMS_DATA
{
    uint8_t  bms_version[3]; //协议版本
    uint8_t  bms_group;      //电池组数
    uint8_t bms_num;         //串数

    uint16_t bms_v1; //mv
    uint16_t bms_v2;
    uint16_t bms_v3;
    uint16_t bms_v4;
    uint16_t bms_v5;
    uint16_t bms_v6;
    uint16_t bms_v7;
    uint16_t bms_v8;
    uint16_t bms_v9;
    uint16_t bms_v10;
    uint16_t bms_v11;
    uint16_t bms_v12;
    uint16_t bms_v13;
    uint16_t bms_v14;
    uint16_t bms_v15;
    uint16_t bms_v16;
    uint16_t bms_v17;
    uint16_t bms_v18;
    uint16_t bms_v19;
    uint16_t bms_v20;
    uint16_t bms_v21;
    uint16_t bms_v22;
    uint16_t bms_v23;
    uint16_t bms_v24;
    uint16_t bms_v25;
    uint16_t bms_v26;  //最大兼容26s电池

    uint8_t bms_ids[32]; //VK3协议 32字节  之前20字节
    uint16_t bms_cycle; //循环次数
    uint16_t bms_volt;  //电压 mv
    int16_t bms_ac;     //电流 10ma
    int16_t bms_temp;  //温度 0.1℃
    uint8_t bms_vs;     //充电百分比 1%
    uint16_t bms_ss;    //状态
    uint16_t serial_num; //VK3厂商编号
};
#pragma pack()

//msgid 0x02
#pragma pack(1)
typedef struct{
    uint16_t voltage; //10mv
    int      current;
    short    tempture;
    short    mosfet_tempture;
    uint16_t persent;
    uint32_t warn_flag;
    uint16_t bms_num;
    uint16_t bms_v1;
    uint16_t bms_v2;
    uint16_t bms_v3;
    uint16_t bms_v4;
    uint16_t bms_v5;
    uint16_t bms_v6;
    uint16_t bms_v7;
    uint16_t bms_v8;
    uint16_t bms_v9;
    uint16_t bms_v10;
    uint16_t bms_v11;
    uint16_t bms_v12;
    uint16_t bms_v13;
    uint16_t bms_v14;
    uint16_t bms_v15;
    uint16_t bms_v16;
    uint16_t bms_v17;
    uint16_t bms_v18;
    uint16_t bms_v19;
    uint16_t bms_v20;
    uint16_t bms_v21;
    uint16_t bms_v22;
    uint16_t bms_v23;
    uint16_t bms_v24;
    uint16_t bms_v25;
    uint16_t bms_v26;
}vkbms2;
#pragma pack()
extern vkbms2 vk_bms2;

//msgid 0x03
#pragma pack(1)
typedef struct{
    char bms_company_info[20];  //电池厂商信息
    char bms_type_info[20];     //电池型号信息
    char bms_id[20];            //电池ID信息
    char bms_hard_version[10];  //电池硬件版本
    char bms_soft_version[10];  //电池软件版本
}vkbms3;
#pragma pack()

//msgid 0x04
#pragma pack(1)
typedef struct{
    uint16_t capacity;        //电池设计容量
    uint16_t discharge_rate;  //电池放电倍率
    uint16_t normal_voltage;  //标称电压
    uint16_t bms_num;         //电池串数
}vkbms4;
#pragma pack()

//msgid 0x05
#pragma pack(1)
typedef struct{
    uint16_t health_percent;  //健康度%
    uint16_t circulation_time;//循环次数
    uint16_t over_recharge;   //过充次数
    uint16_t over_discharge;  //过放次数
    uint16_t over_current;    //过流次数
    uint16_t over_tempreature;//过温次数
    uint16_t SOC;
    uint16_t SOH;
    uint16_t recharge_capacity;//充电容量
    uint16_t surplus_capacity; //剩余容量
    uint16_t inter_resistance; //电池内阻值
}vkbms5;
#pragma pack()

#pragma pack(1)
typedef struct soft_bms
{
    Connect_check Vkbms_Link;

    uint32_t can_id;

    bool ack_to_bms;
    uint8_t source_id;

    bool if_mul_frame;
    bool recv_mul_freme_complete;
    uint8_t mul_frame_i;
    uint8_t mul_frame_num;
    uint8_t bms_can_buf[128];

    vkbms2 vk_bms2;
    vkbms3 vk_bms3;
    vkbms4 vk_bms4;
    vkbms5 vk_bms5;

    bool get_bms3_ack;
    bool get_bms4_ack;
    bool get_bms5_ack;

}Vkbms_Device;
#pragma pack()
extern Vkbms_Device Device1;
extern Vkbms_Device Device2;
extern uint8_t bms_step;
extern uint8_t bms_group_num;
extern struct BMS_DATA bms_data, bms_data2;
/***********************************************************************************/
void bms_function(void);
void update_bms_data( void );
void BMSCanRecvHookFunction(uint32_t CanID, uint8_t data[], uint8_t len);

#endif
