#include "kit_data.h"
#include "kit_debug.h"
#include "bsp_task.h"

#include "iso_check.h"
#include "soc_calculate.h"
#include "adc_manager.h"
#include "gpio_manager.h"
#include "eeprom_manager.h"
#include "hv_adc_manager.h"
#include "table_comm.h"

//#include "drv_mcp3208.h"
#include "drv_ads8688.h"

#define CUR_FILTER_ENABLE (0u)
#define ADCIC_SAMPLE_CNT (4u)

ADS8688_STATIC_INIT(ads8688, kSpiDev_2, kGpioType_ADC_Cs);

typedef enum
{
	kAdIc_Hv1,
    kAdIc_HvBat,
	kAdIc_Cur,
	kAdIc_HvIso,
	kAdIc_HvIsoNagtive,
    kAdIc_End
} AdIcEnum;

typedef struct
{
    bool is_simulate;
    uint8_t filter_pos;
    uint8_t ad_buf_pos[kAdIc_End];
    int16_t current;
    uint16_t en_temp[kEnTemp_End];
    int32_t can_current;
    int16_t show_current;
#if CUR_FILTER_ENABLE
    int16_t filter_current[MCP3208_SAMPLE_CNT];
#endif
    int32_t value[kAdIc_End];
    int32_t ad_avg[kAdIc_End];
    int32_t ad_buf[kAdIc_End][ADCIC_SAMPLE_CNT];

} CurHvItem;

CurHvItem cur_hv_item;

typedef enum
{
    kCurSensor_Shunt,
    kCurSensor_SigHall,
    kCurSensor_DualHall,
    kCurSensor_SigHall_Base,
    kCurSensor_End,
} CurSensorType;

typedef struct
{
    int8_t dir;
    CurSensorType type;
    int16_t filter;
    int16_t offset;
    int32_t scale;
} CurProp;

typedef struct
{
    uint8_t shunt_volt;
    int8_t chg_cur_dir;
    CurChannel channel;
    int16_t swing_volt;
    CurProp prop[kCurChannel_End];
} CurItem;

CurItem cur_item;

void bms_init_current(void)
{
    cur_item.swing_volt = get_eeprom_data(kEep_HallSwingVolt, kEepromDataType_Full);
    cur_item.shunt_volt = get_eeprom_data(kEep_ChgCurDir_ShuntRatedVolt, kEepromDataType_Low);

    cur_item.prop[0].filter = cur_item.prop[1].filter = 0;
    // 上位机下发时缩小10倍
    cur_item.prop[0].scale = get_eeprom_data(kEep_CurSensor2_1Range, kEepromDataType_Low) * 10;
    cur_item.prop[1].scale = get_eeprom_data(kEep_CurSensor2_1Range, kEepromDataType_High) * 10;

    cur_item.prop[0].type = (CurSensorType)get_eeprom_data(kEep_CurSensor2_1Type, kEepromDataType_Low);
    cur_item.prop[1].type = (CurSensorType)get_eeprom_data(kEep_CurSensor2_1Type, kEepromDataType_High);

    cur_item.prop[0].offset = cur_item.prop[1].offset = 0;
    // 电流方向
    cur_item.chg_cur_dir = 1 - (int8_t)((get_eeprom_data(kEep_ChgCurDir_ShuntRatedVolt, kEepromDataType_High) & 0x01) << 1);
    cur_item.prop[0].dir = 1 - (int8_t)((get_eeprom_data(kEep_CurSensor2_1Dir, kEepromDataType_High) & 0x01) << 1);
    cur_item.prop[1].dir = 1 - (int8_t)((get_eeprom_data(kEep_CurSensor2_1Dir, kEepromDataType_Low) & 0x01) << 1);
}

void bms_adjust_cur(void)
{
    uint32_t i;
    int32_t cur, max_cur = INT32_MIN, min_cur = INT32_MAX;

    for (i = 0; i < 20; i++)
    {
        bms_poll_adc(10);
        cur = bms_poll_cur_hv(0);
        if (cur > max_cur)
        {
            max_cur = cur;
        }

        if (cur < min_cur)
        {
            min_cur = cur;
        }

        kit_time_dly_ms(5);
    }

    cur = 0;
    if ((min_cur > -500) && (max_cur < 500))
    {
        // 计算滤波 + 0.1A
        cur = ((max_cur - min_cur) >> 1) + 10;
    }
    // 电流滤波单位 0.1A/bit 计算电流0.01A/bit 需要*10
    cur_item.prop[0].filter = get_eeprom_data(kEep_ZeroFilter2_1Filter, kEepromDataType_Low) * 10;
    cur_item.prop[1].filter = get_eeprom_data(kEep_ZeroFilter2_1Filter, kEepromDataType_High) * 10;
    if (cur_item.prop[0].filter == 0)
    {
        cur_item.prop[0].filter = cur;
    }

    if (cur_item.prop[1].filter == 0)
    {
        cur_item.prop[1].filter = cur;
    }

    bsp_eeprom_set_data(kEep_ZeroFilter2_1Filter, cur / 10, kEepromDataType_Low);
    bsp_eeprom_set_data(kEep_ZeroFilter2_1Filter, cur / 10, kEepromDataType_High);

    cur = 0;
    if ((min_cur > -500) && (max_cur < 500))
    {
        // 计算偏移
        cur = ((max_cur + min_cur) >> 1);
    }
    // 电流偏移单位 0.1A/bit，偏移12A 计算电流0.01A/bit 需要*10
    cur_item.prop[0].offset = ((int8_t)get_eeprom_data(kEep_CurSensor2_1Offset, kEepromDataType_Low)) * 10;
    cur_item.prop[1].offset = ((int8_t)get_eeprom_data(kEep_CurSensor2_1Offset, kEepromDataType_High)) * 10;

    if (cur_item.prop[0].offset == 0)
    {
        cur_item.prop[0].offset = cur;
    }

    if (cur_item.prop[1].offset == 0)
    {
        cur_item.prop[1].offset = cur;
    }

    bsp_eeprom_set_data(kEep_CurSensor2_1Offset, cur / 10, kEepromDataType_Low);
    bsp_eeprom_set_data(kEep_CurSensor2_1Offset, cur / 10, kEepromDataType_High);

    // 根据校准值再计算下电流
    bms_poll_adc(10);
    bms_poll_cur_hv(10);
}

// 分流器转换
uint32_t HighResCurTrans(int32_t voldata)
{
    uint16_t Rsense = 39;
    uint32_t highResCurdata = 0;

    highResCurdata = voldata * Rsense * 100;//扩大100倍

    return highResCurdata;
}

// 计算电流单位
int16_t bms_caculate_current(uint32_t base_time)
{
#if CUR_FILTER_ENABLE
    static uint16_t dly = 0;
#endif
    int32_t tmp, tmp1, current ,volval = 0;
    CurProp *prop;
    if (cur_item.channel < kCurChannel_End)
    {
        prop = &cur_item.prop[cur_item.channel];
        switch (prop->type)
        {
        case kCurSensor_Shunt:
            // 分流器 cur_hv_item.cur_volt_avg / cur_prop.shunt_volt * cur_prop.cur_scale;
            //current = (int32_t)cur_hv_item.value[kAdIc_Cur] * prop->scale / cur_item.shunt_volt;
            current = HighResCurTrans(cur_hv_item.value[kAdIc_Cur]);
            break;
        case kCurSensor_SigHall:
            // 霍尔电流
            tmp = bms_get_adc_data(kAdcData_Hall1);
		    if(tmp<20)tmp = 0;
		    volval = tmp * 3300 /4095;
            //current = (int32_t)(tmp - 250000) * prop->scale / cur_item.swing_volt;
            current = tmp;
            break;
        case kCurSensor_DualHall:
            // 霍尔电流
            tmp = bms_get_adc_data(kAdcData_Hall1);
		    volval = tmp * 3300 /4095;
            //current = (int32_t)(tmp - 250000) * prop->scale / cur_item.swing_volt;
            current = tmp;
            if (KIT_ABS(current) > (int32_t)prop->scale * 90)
            {
                tmp = bms_get_adc_data(kAdcData_Hall2);
                //current = (int32_t)(tmp - 250000) * cur_item.prop[1].scale / cur_item.swing_volt;
                current = tmp;
            }
            break;
        case kCurSensor_SigHall_Base:
            // 单量程带基准
            tmp = bms_get_adc_data(kAdcData_Hall1);
            tmp1 = bms_get_adc_data(kAdcData_Hall2);
            current = (int32_t)(tmp - tmp1) * prop->scale / cur_item.swing_volt;
            break;
        default:
            break;
        }
    }
	//测试用 SFJ 7.30
	current = volval * 100 / 10;
	
    // 电流方向
    current *= prop->dir;
    // 零点偏移
    current -= prop->offset;
    // 零点滤波
    if (KIT_ABS(current) < prop->filter)
    {
        current = 0;
    }
    current = (int64_t)current * get_eeprom_data(kEep_Hall1CalFactor, kEepromDataType_Full) / 1000;
	
	//调试
	bms_integral_soc(current, base_time);

    cur_hv_item.current = current / 10;//转为 0.1

#if CUR_FILTER_ENABLE
    dly += base_time;
    if (dly >= 500)
    {
        dly = 0;
        cur_hv_item.filter_current[cur_hv_item.filter_pos] = cur_hv_item.current;
        if (++cur_hv_item.filter_pos >= MCP3208_SAMPLE_CNT)
        {
            cur_hv_item.filter_pos = 0;
        }
        cur_hv_item.show_current = kit_get_avg_filter_max_min(cur_hv_item.filter_current, MCP3208_SAMPLE_CNT) * cur_item.chg_cur_dir;
    }
#else
    cur_hv_item.show_current = cur_hv_item.current * cur_item.chg_cur_dir;
#endif
    return current;
}

uint32_t HighVolTrans(uint16_t voldata)
{
    // 10M 16.5K
    float Rsense = 10000;
    float Rvol = 16.5;
    uint32_t highvoldata = 0;

    highvoldata = voldata * (Rsense + Rvol) / Rvol;

    return highvoldata;
}


AdjustValue adIc_adjust_value[kAdIc_End];
uint16_t adIc_reg_map[kAdIc_End] = {MAN_Ch_0, MAN_Ch_1, MAN_Ch_2, MAN_Ch_3, MAN_Ch_4};


void get_ad_sample(void)
{
	static uint16_t outputdata[16] = {0};
    int32_t i =0;
	uint16_t ad =0;
	
	//auto scan mode
	drv_enter_auto_rst_mode_Data(outputdata, 6);
	
    for (i = 0; i < kAdIc_End; i++)
    {
		//ad = drv_get_ads8688_ch_data(adIc_reg_map[i]);
		cur_hv_item.ad_buf[i][cur_hv_item.ad_buf_pos[i]++] = drv_ads8688_value(outputdata[i]);
		ad = cur_hv_item.ad_avg[i] = kit_get_int32_avg_filter_max_min(cur_hv_item.ad_buf[i], ADCIC_SAMPLE_CNT);

		if (i == kAdIc_HvIso)
		{
			//cur_hv_item.value[i] = HighVolTrans2(ad)/100;
			bms_set_iso_volt_ad(kIsoVolt_Other, ad);
		}
		if(i == kAdIc_HvIsoNagtive)
		{
			
		}
		if (i == kAdIc_HvBat)
		{
			cur_hv_item.value[i] = (ad / 100) * 512 * 10 / (0x01 << 16); //单位是mv
			bms_set_iso_volt_ad(kIsoVolt_TotalVolt, cur_hv_item.value[i]);
		}
		if(i == kAdIc_Hv1)
		{
			cur_hv_item.value[i] = (ad / 100) * 512 * 10 / (0x01 << 16); //单位是mv
		}
		if(i == kAdIc_Cur)
		{
			ad = ad - adIc_adjust_value[i].zero;
			ad = (10 * ad / 82000) * 512 * 1000/ (0x01 << 16);  //单位是mv
			
			// 防止eeprom中没有设置电压校准系数
			if (get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) <= 900 || get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) >= 1100)
			{
				bsp_eeprom_save_data(kEep_Volt1CalFactor, 1000, kEepromDataType_Full);
			}
			cur_hv_item.value[i] = ad / 1000 * adIc_adjust_value[i].rate *get_eeprom_data(kEep_Volt1CalFactor, kEepromDataType_Full) / 1000;//转为V
		}

		if (cur_hv_item.ad_buf_pos[i] >= ADCIC_SAMPLE_CNT)
		{
			cur_hv_item.ad_buf_pos[i] = 0;
		}
    }
}


int16_t bms_poll_cur_hv(uint32_t base_time)
{        
    get_ad_sample();
    return bms_caculate_current(base_time);
}

// A
int16_t bms_get_current(void)
{
    return cur_hv_item.current;
}

// 单位0.01A/bit
void bms_set_current(int32_t cur)
{
    cur_hv_item.can_current = cur;
}

void bms_set_current_channel(CurChannel channel)
{
    if (channel < kCurChannel_End)
    {
        cur_item.channel = channel;
    }
}

int16_t bms_get_show_current(void)
{
    return cur_hv_item.show_current;
}

// V
int16_t bms_get_high_volt(HvType type)
{
    int16_t tmp = 0;

    KIT_ASSERT_PARAM(type < kHvType_End);

    if (type < kHvType_End)
    {
        tmp = cur_hv_item.value[type];
    }

    return tmp;
}

void bms_set_high_volt(HvType type, uint16_t value)
{
    KIT_ASSERT_PARAM(type < kHvType_End);

    if ((cur_hv_item.is_simulate == false) && (type < kHvType_End))
    {
        cur_hv_item.value[type + 3] = value;
    }
}

void bms_set_sim_high_volt(HvType type, uint16_t value)
{
    KIT_ASSERT_PARAM(type < kHvType_End);

    if (type < kHvType_End)
    {
        cur_hv_item.is_simulate = true;
        cur_hv_item.value[type] = value;
    }
}

bool bms_is_high_volt_sim(void)
{
    return cur_hv_item.is_simulate;
}

uint16_t bms_get_en_temp(EnTemp idx)
{
    uint16_t tmp = 0;
    if (idx < kEnTemp_End)
    {
        tmp = cur_hv_item.en_temp[idx];
    }
    return tmp;
}

void bms_set_en_temp(EnTemp idx, uint16_t temp)
{
    if (idx < kEnTemp_End)
    {
        cur_hv_item.en_temp[idx] = temp;
    }
}

const uint32_t adIc_default_rate[kAdIc_End] = {1, 1, 1, 1, 1};

//
void bms_init_cur_hv(void)
{
    uint32_t i = 0, cnt = 30;
	#ifdef ADS_8688_EN
	while(drv_ads8688_Init())
	{
		OSTimeDly(20);
	}

	for (i = 0; i < kAdIc_End; i++)
	{
		adIc_adjust_value[i].zero = 0;
		adIc_adjust_value[i].rate = adIc_default_rate[i];
	}

	#endif
    // 填充buf
    for (i = 0; i < cnt; i++)
    {
        bms_poll_adc(10);
        // 时间参数为0，防止时间增加误校准SOC
        bms_poll_cur_hv(0);
        bsp_task_delay_ms(100);
    }
    bms_init_current();
}
