#include "soft_herewin.h"
#include "string.h"
#include "crc.h"
#include "soft_can.h"
#include "common.h"

herewin_bms herewin_info;

Connect_check Herewin_Link;

#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()

herewin_can_info can_info;

void HerewinCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len)//海盈
{

    Herewin_Link.recv_time = HAL_GetTick();
    Herewin_Link.connect_status = COMP_NORMAL;

    uint8_t i = 0;
    uint8_t canid_pf = (cellCanID >> 16) & 0xff;

    switch (canid_pf)
    {
    //定值查询包
    case 0x81:
        if((data[0] == 8 )&& (0x80 == data[2]))
        {
           herewin_info.battery_num = data[4];
        }
        break;

    case 0x83:
        herewin_info.get_temp_flag = true;
        //电芯温度传感器只有三个，取前三个字节，传给APP取平均值
        memcpy(&herewin_info.battery_temp[0],&data[0],1); 
        memcpy(&herewin_info.battery_temp[1],&data[1],1);  
        memcpy(&herewin_info.battery_temp[2],&data[2],1);   
        break;
    //单体电压
    case 0x85:
        can_info.message_num = data[0];
        //第一包
        if(can_info.message_num == 1)
        {   
            memset(&can_info,0,sizeof(can_info));
            can_info.byte_num = data[2] + data[3] * 256;
            can_info.message_total = data[1];
            //算出最后一包的有效字节数
            can_info.last_frame_num = can_info.byte_num - 4 -(can_info.message_total - 2) * 7;
            memcpy(&can_info.herewin_buf[0],&data[4],4);
            for(i = 0;i < 4;i++)
            {
                can_info.crc += can_info.herewin_buf[i];
            }
            can_info.i += 4;
        }
        //最后一包 协议校验码是最后发，12S的电池校验会单独占一个字节发送
        //14s
        else if(can_info.message_num == can_info.message_total &&  can_info.last_frame_num <= 5
                && can_info.last_frame_num > 0 )
        {
            memcpy(&can_info.herewin_buf[can_info.i],&data[1],can_info.last_frame_num);
            for(i = 0;i < can_info.last_frame_num;i++)
            {
                can_info.crc += can_info.herewin_buf[can_info.i + i];
            }
            //校验
            if(can_info.crc == data[ 1 + can_info.last_frame_num] + 256 * data[ 2 + can_info.last_frame_num])
            {
                memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
            }
            memset(&can_info,0,sizeof(can_info));
        }
        //12s电池  最后一包有效字节-1
        else if(can_info.message_num == can_info.message_total && can_info.last_frame_num <= 0 )
        {   
            //最后一包只有1字节校验
            if(can_info.last_frame_num == -1)
            {
                memcpy(&can_info.herewin_buf[can_info.i],&data[1],1);
                can_info.crc -= can_info.herewin_buf[can_info.i - 1];
                //校验
                if(can_info.crc == can_info.herewin_buf[can_info.i - 1] + 256 * can_info.herewin_buf[can_info.i])
                {
                    memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
                }
            }
            //最后一包只有两字节校验
            else if(can_info.last_frame_num == 0)
            {   
                memcpy(&can_info.herewin_buf[can_info.i],&data[1],2);
                //校验
                if(can_info.crc == can_info.herewin_buf[can_info.i] + 256 * can_info.herewin_buf[can_info.i + 1])
                {
                    memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
                }
            }
            memset(&can_info,0,sizeof(can_info));

        }
        else
        {
            memcpy(&can_info.herewin_buf[can_info.i],&data[1],7);
            for(i = 0;i < 7;i++)
            {
                can_info.crc += can_info.herewin_buf[can_info.i + i];
            }
            can_info.i += 7;
        }
        break;
    //电池循环次数查询
    case 0x87:
        memcpy(&herewin_info.circulation_num,&data[0],2);
        break;
    //充电请求
    case 0x22:
        memcpy(&herewin_info.re_vol,&data[0],2);
        memcpy(&herewin_info.re_ele,&data[2],2);
        memcpy(&herewin_info.max_vol,&data[4],2);
        memcpy(&herewin_info.power_status,&data[6],2);
        break;
    //告警信息
    case 0x24:
        memcpy(&herewin_info.alarm_info,&data[0],2);
        memcpy(&herewin_info.warn_info,&data[2],2);
        break;
    //电流 电压信息
    case 0x26:
        memcpy(&herewin_info.total_vol,&data[0],2);
        memcpy(&herewin_info.tolal_ele,&data[2],2);
        memcpy(&herewin_info.SOC_info,&data[4],1);
        memcpy(&herewin_info.SOH_info,&data[5],1);
        memcpy(&herewin_info.SOP_info,&data[6],2);
        break;
    default:
        break;
    }
}


/**
  * @brief 给海盈发送数据信息
  */
//海盈电池收不到心跳包20分后停止主动发送数据 2000ms周期给海盈电池发送心跳包
void send_msg_to_herewin(void)
{   
    static uint32_t herewin_heart_time = 0;
    static uint32_t herewin_vol_time = 0;

    static uint8_t heart_num_count = 0;

    if(Herewin_Link.connect_status == COMP_NORMAL)
    {
        //2000ms发送心跳包
        if(HAL_GetTick() - herewin_heart_time > 2000)
        {   
            uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01,
                                    0x00,0x00,0x00,0x01};
            can_send_msg_normal(heart_buf, 8, HEREWIN_HEART_ID);
       
            herewin_heart_time = HAL_GetTick();
        }
        //1000ms发送单体电压请求 和单体温度请求  发送5次电芯个数
        if(HAL_GetTick() - herewin_vol_time > 1000)
        {
            uint8_t herewin_num = 8;
            can_send_msg_normal(0, 0, HEREWIN_VOL_ID);
            can_send_msg_normal(0, 0, HEREWIN_TEM_ID);
            //请求5次电芯个数 5次循环次数
            
            can_send_msg_normal(&herewin_num, 1, HEREWIN_SEARCH_ID);
            can_send_msg_normal(0, 0, HEREWIN_CIRCULATION_ID);
            herewin_vol_time = HAL_GetTick();
            
        }

    }
    else
    {
        //上电时先发送5次心跳包 防止电池休眠
        if(HAL_GetTick() - herewin_heart_time  > 2000 && heart_num_count > 0)
        {
            uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01,
                                    0x00,0x00,0x00,0x01};
            can_send_msg_normal(heart_buf, 8, HEREWIN_HEART_ID);
       
            herewin_heart_time = HAL_GetTick();

            heart_num_count--;
        }
    }
    
}
