/*
 * @Description: file content
 * @Author: CK.Zh
 * @Date: 2020-04-27 18:01:58
 * @LastEditors: CK.Zh
 * @LastEditTime: 2020-04-29 17:49:01
 */
#include "coulomb.h"
coulomb_t coulomb;


//静态方法,检测设备是否就绪
static HAL_StatusTypeDef is_coulomb_ready()
{
	return HAL_I2C_IsDeviceReady(&hi2c1,COULOMB_ADDR,3,20);
}
//静态方法,写寄存器
static HAL_StatusTypeDef coulomb_write_reg(uint8_t addr,uint8_t* pData)
{
	return HAL_I2C_Mem_Write(&hi2c1,COULOMB_ADDR ,addr,1,pData, 1, 10);
}
//静态方法,读寄存器
static HAL_StatusTypeDef coulomb_read_reg(uint8_t addr,uint8_t* pData)
{
	return HAL_I2C_Mem_Read(&hi2c1,COULOMB_ADDR ,addr,1,pData, 1, 10);
}
/**
 * @description: 静态方法,字节拼接
 * @param pData 数组指针 
 * @param msbIndex 高字节在数组中的位置 
 * @param lsbIndex 低字节在数组中的位置  
 * @return: 
 */
static uint16_t uint8_to_uint16(uint8_t *pData,uint8_t msbIndex,uint8_t lsbIndex)
{
	return ((pData[msbIndex]<<8) | pData[lsbIndex]);
}
/**
 * @description: 静态方法,字节拆解
 * @param data
 * @return:
 */
static uint8_t uint16_to_uint8_msb(uint16_t data)
{
	return ((data>>8) & 0xff);
}
/**
 * @description: 静态方法,字节拆解
 * @param data
 * @return:
 */
static uint8_t uint16_to_uint8_lsb(uint16_t data)
{
	return ((data   ) & 0xff);
}
/**
 * @description: 初始化配置参数(寄存器上电后的缺省值)
 * @param {type} 
 * @return: 
 */
// void coulomb_write_config_load_default()
// {
// 	coulomb.write.raw.control =  0xEC;
// 	coulomb.write.raw.accumulated_charge = 0x7fff;
// 	coulomb.write.raw.charge_threshold_H = 0xffff;
// 	coulomb.write.raw.charge_threshold_L = 0x0000;
// 	coulomb.write.raw.voltage_threshold_H = 0xffff;
// 	coulomb.write.raw.voltage_threshold_L = 0x0000;
// 	coulomb.write.raw.current_threshold_H = 0xffff;
// 	coulomb.write.raw.current_threshold_L = 0x0000;
// 	coulomb.write.raw.temperature_threshold_H = 0xff;
// 	coulomb.write.raw.temperature_threshold_L = 0x00;
// }
/**
 * @description: 初始化配置参数
 * @param {type} 
 * @return: 
 */
void coulomb_write_config_load()
{
	//控制寄存器配置
	coulomb.write.actual.control.adc_mode = 0b00;
	coulomb.write.actual.control.prescaler = 0b111;
	coulomb.write.actual.control.alcc_configure = 0b10;
	coulomb.write.actual.control.shutdown = 0b00;

	//剩余容量重写入
	coulomb.write.actual.accumulated_charge = 2;

	//充电阈值上限
	coulomb.write.actual.charge_threshold_H = 20;
	//充电阈值下限
	coulomb.write.actual.charge_threshold_L = 1;

	//电压阈值上限
	coulomb.write.actual.voltage_threshold_H = 15;
	//电压阈值下限
	coulomb.write.actual.voltage_threshold_L = 9.5;

	//电流阈值上限
	coulomb.write.actual.current_threshold_H = 10;
	//电流阈值下限
	coulomb.write.actual.current_threshold_L = -10;

	//温度阈值上限
	coulomb.write.actual.temperature_threshold_H = 60;
	//温度阈值下限
	coulomb.write.actual.temperature_threshold_L = -15;
}
/**
 * @description: 将准备写入的目标参数转化成寄存器格式
 * @param {type} 
 * @return: 
 */
void coulomb_write_config_actual_to_raw()
{
	//控制寄存器
	coulomb.write.raw.control =  (coulomb.write.actual.control.adc_mode << 6) | \
										(coulomb.write.actual.control.prescaler << 3) | \
										(coulomb.write.actual.control.alcc_configure << 1) | \
										(coulomb.write.actual.control.shutdown ) 		;
	//累计电量
	coulomb.write.raw.accumulated_charge = (uint16_t)((coulomb.write.actual.accumulated_charge / 30.0) * 32767 + 32767);

	//充电阈值上限
	coulomb.write.raw.charge_threshold_H = (uint16_t)((coulomb.write.actual.charge_threshold_H / 30.0) * 32767 + 32767);
	//充电阈值下限
	coulomb.write.raw.charge_threshold_L = (uint16_t)((coulomb.write.actual.charge_threshold_L / 30.0) * 32767 + 32767);

	//电压阈值上限
	coulomb.write.raw.voltage_threshold_H = (uint16_t)((coulomb.write.actual.voltage_threshold_H / 23.6) * 65535);
	//电压阈值下限
	coulomb.write.raw.voltage_threshold_L = (uint16_t)((coulomb.write.actual.voltage_threshold_L / 23.6) * 65535);
	
	//电流阈值上限
	coulomb.write.raw.current_threshold_H = (uint16_t)((coulomb.write.actual.current_threshold_H / 30.0) * 32767 + 32767);
	//电流阈值下限
	coulomb.write.raw.current_threshold_L = (uint16_t)((coulomb.write.actual.current_threshold_L / 30.0) * 32767 + 32767);
	
	//温度阈值上限
	coulomb.write.raw.temperature_threshold_H = ((uint16_t)((coulomb.write.actual.temperature_threshold_H + 273.15) / 510.0 * 65535)) & 0xFF00;//清空低字节
	//温度阈值下限
	coulomb.write.raw.temperature_threshold_L = ((uint16_t)((coulomb.write.actual.temperature_threshold_L + 273.15) / 510.0 * 65535)) & 0xFF00;//清空低字节
}
/**
 * @description: 写入寄存器配置
 * @param {type} 
 * @return: 
 */
bool coulomb_write_config()
{
	uint8_t writeData[COULOMB_REG_NUM] = {0};
		
	//控制寄存器
	writeData[LTC2943_CONTROL_REG] = coulomb.write.raw.control;
	
	//累计电量
	writeData[LTC2943_ACCUM_CHARGE_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.accumulated_charge);
	writeData[LTC2943_ACCUM_CHARGE_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.accumulated_charge);

	//充电阈值上限
	writeData[LTC2943_CHARGE_THRESH_HIGH_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.charge_threshold_H);
	writeData[LTC2943_CHARGE_THRESH_HIGH_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.charge_threshold_H);
	//充电阈值下限
	writeData[LTC2943_CHARGE_THRESH_LOW_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.charge_threshold_L);
	writeData[LTC2943_CHARGE_THRESH_LOW_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.charge_threshold_L);

	//电压阈值上限
	writeData[LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.voltage_threshold_H);
	writeData[LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.voltage_threshold_H);
	//电压阈值下限
	writeData[LTC2943_VOLTAGE_THRESH_LOW_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.voltage_threshold_L);
	writeData[LTC2943_VOLTAGE_THRESH_LOW_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.voltage_threshold_L);
	
	//电流阈值上限
	writeData[LTC2943_CURRENT_THRESH_HIGH_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.current_threshold_H);
	writeData[LTC2943_CURRENT_THRESH_HIGH_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.current_threshold_H);
	//电流阈值下限
	writeData[LTC2943_CURRENT_THRESH_LOW_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.current_threshold_L);
	writeData[LTC2943_CURRENT_THRESH_LOW_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.current_threshold_L);

	//温度阈值上限
	writeData[LTC2943_TEMPERATURE_THRESH_HIGH_REG] = uint16_to_uint8_msb(coulomb.write.raw.temperature_threshold_H);
	//温度阈值下限
	writeData[LTC2943_TEMPERATURE_THRESH_LOW_REG] = uint16_to_uint8_msb(coulomb.write.raw.temperature_threshold_L);
	
	coulomb.ready = (is_coulomb_ready()==HAL_OK) ? true : false;
	if(coulomb.ready)
	{
		coulomb_write_reg(LTC2943_CONTROL_REG,&writeData[LTC2943_CONTROL_REG]);
		coulomb_write_reg(LTC2943_ACCUM_CHARGE_MSB_REG,&writeData[LTC2943_ACCUM_CHARGE_MSB_REG]);
		coulomb_write_reg(LTC2943_ACCUM_CHARGE_LSB_REG,&writeData[LTC2943_ACCUM_CHARGE_LSB_REG]);
		coulomb_write_reg(LTC2943_CHARGE_THRESH_HIGH_MSB_REG,&writeData[LTC2943_CHARGE_THRESH_HIGH_MSB_REG]);
		coulomb_write_reg(LTC2943_CHARGE_THRESH_HIGH_LSB_REG,&writeData[LTC2943_CHARGE_THRESH_HIGH_LSB_REG]);
		coulomb_write_reg(LTC2943_CHARGE_THRESH_LOW_MSB_REG,&writeData[LTC2943_CHARGE_THRESH_LOW_MSB_REG]);
		coulomb_write_reg(LTC2943_CHARGE_THRESH_LOW_LSB_REG,&writeData[LTC2943_CHARGE_THRESH_LOW_LSB_REG]);
		coulomb_write_reg(LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG]);
		coulomb_write_reg(LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG]);
		coulomb_write_reg(LTC2943_VOLTAGE_THRESH_LOW_MSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_LOW_MSB_REG]);
		coulomb_write_reg(LTC2943_VOLTAGE_THRESH_LOW_LSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_LOW_LSB_REG]);
		coulomb_write_reg(LTC2943_CURRENT_THRESH_HIGH_MSB_REG,&writeData[LTC2943_CURRENT_THRESH_HIGH_MSB_REG]);
		coulomb_write_reg(LTC2943_CURRENT_THRESH_HIGH_LSB_REG,&writeData[LTC2943_CURRENT_THRESH_HIGH_LSB_REG]);
		coulomb_write_reg(LTC2943_CURRENT_THRESH_LOW_MSB_REG,&writeData[LTC2943_CURRENT_THRESH_LOW_MSB_REG]);
		coulomb_write_reg(LTC2943_CURRENT_THRESH_LOW_LSB_REG,&writeData[LTC2943_CURRENT_THRESH_LOW_LSB_REG]);
		coulomb_write_reg(LTC2943_TEMPERATURE_THRESH_HIGH_REG,&writeData[LTC2943_TEMPERATURE_THRESH_HIGH_REG]);
		coulomb_write_reg(LTC2943_TEMPERATURE_THRESH_LOW_REG,&writeData[LTC2943_TEMPERATURE_THRESH_LOW_REG]);
	}
	return coulomb.ready;
}
/**
 * @description: 将读取到的 状态类的 寄存器数据转换成真实数据
 * @param {type} 
 * @return: 
 */
void coulomb_read_status_raw_to_actual()
{
	//status 转换到 对应位
	coulomb.read.actual.status.current_alret = 				((coulomb.read.raw.status>>6) & 0b00000001) ? true : false;
	coulomb.read.actual.status.accumulated_charge_alert = 	((coulomb.read.raw.status>>5) & 0b00000001) ? true : false;
	coulomb.read.actual.status.temperature_alret =	 		((coulomb.read.raw.status>>4) & 0b00000001) ? true : false;
	coulomb.read.actual.status.charge_alert_H = 			((coulomb.read.raw.status>>3) & 0b00000001) ? true : false;
	coulomb.read.actual.status.charge_alert_L = 			((coulomb.read.raw.status>>2) & 0b00000001) ? true : false;
	coulomb.read.actual.status.voltage_alert = 				((coulomb.read.raw.status>>1) & 0b00000001) ? true : false;
	coulomb.read.actual.status.uvlo_alert = 				( coulomb.read.raw.status 	 & 0b00000001) ? true : false;

	//剩余电量转换
	coulomb.read.actual.accumulated_charge = (coulomb.read.raw.accumulated_charge - 32767) / 32767.0 * 30 ;
	//电压转换
	coulomb.read.actual.voltage = coulomb.read.raw.voltage / 65535.0 *23.6;
	//电流转换
	coulomb.read.actual.current = (coulomb.read.raw.current - 32767) / 32767.0 * 30 ;
	//温度转换
	coulomb.read.actual.temperature = (coulomb.read.raw.temperature / 65535.0 * 510 ) - 273.15;
}
/**
 * @description: 将读取到的 配置类的 寄存器数据转换成真实参数
 * @param {type} 
 * @return: 
 */
void coulomb_read_config_raw_to_actual()
{
	//control寄存器转换到对应位
	coulomb.read.actual.control.adc_mode = 		((coulomb.read.raw.control >> 6) & 0b00000011);
	coulomb.read.actual.control.prescaler = 		((coulomb.read.raw.control >> 3) & 0b00000111);
	coulomb.read.actual.control.alcc_configure = ((coulomb.read.raw.control >> 1) & 0b00000011);
	coulomb.read.actual.control.shutdown = 		( coulomb.read.raw.control   	& 0b00000001);

	//阈值累计充电转换
	coulomb.read.actual.charge_threshold_H = (coulomb.read.raw.charge_threshold_H - 32767) / 32767.0 * 30;
	coulomb.read.actual.charge_threshold_L = (coulomb.read.raw.charge_threshold_L - 32767) / 32767.0 * 30;
	//电压阈值转换
	coulomb.read.actual.voltage_threshold_H = coulomb.read.raw.voltage_threshold_H / 65535.0 *23.6;
	coulomb.read.actual.voltage_threshold_L = coulomb.read.raw.voltage_threshold_L / 65535.0 *23.6;
	//电流阈值转换
	coulomb.read.actual.current_threshold_H = (coulomb.read.raw.current_threshold_H - 32767) / 32767.0 * 30 ;
	coulomb.read.actual.current_threshold_L = (coulomb.read.raw.current_threshold_L - 32767) / 32767.0 * 30 ;
	//温度阈值转换
	coulomb.read.actual.temperature_threshold_H = (coulomb.read.raw.temperature_threshold_H / 65535.0 * 510 ) - 273.15;
	coulomb.read.actual.temperature_threshold_L = (coulomb.read.raw.temperature_threshold_L / 65535.0 * 510 ) - 273.15;
}
//读取原始寄存器数据
/**
 * @description: 读取状态类和配置类的寄存器(即所有寄存器)
 * @param {type} 
 * @return: 
 */
bool coulomb_read_status_and_config()
{
	uint8_t readData[COULOMB_REG_NUM];
	coulomb.ready = (is_coulomb_ready()==HAL_OK) ? true : false;
	if(coulomb.ready)
	{
		HAL_I2C_Mem_Read(&hi2c1,COULOMB_ADDR ,0,1,readData, 1, 10);
		HAL_I2C_Mem_Read(&hi2c1,COULOMB_ADDR ,0,COULOMB_REG_NUM,&readData[1], COULOMB_REG_NUM, 100);

		coulomb.read.raw.status = readData[LTC2943_STATUS_REG];
		coulomb.read.raw.control = readData[LTC2943_CONTROL_REG];

		coulomb.read.raw.accumulated_charge 	= uint8_to_uint16(readData,LTC2943_ACCUM_CHARGE_MSB_REG,LTC2943_ACCUM_CHARGE_LSB_REG);
		coulomb.read.raw.charge_threshold_H 	= uint8_to_uint16(readData,LTC2943_CHARGE_THRESH_HIGH_MSB_REG,LTC2943_CHARGE_THRESH_HIGH_LSB_REG);
		coulomb.read.raw.charge_threshold_L 	= uint8_to_uint16(readData,LTC2943_CHARGE_THRESH_LOW_MSB_REG,LTC2943_CHARGE_THRESH_LOW_LSB_REG);

		coulomb.read.raw.voltage 				= uint8_to_uint16(readData,LTC2943_VOLTAGE_MSB_REG,LTC2943_VOLTAGE_LSB_REG);
		coulomb.read.raw.voltage_threshold_H 	= uint8_to_uint16(readData,LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG,LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG);
		coulomb.read.raw.voltage_threshold_L 	= uint8_to_uint16(readData,LTC2943_VOLTAGE_THRESH_LOW_MSB_REG,LTC2943_VOLTAGE_THRESH_LOW_LSB_REG);

		coulomb.read.raw.current 				= uint8_to_uint16(readData,LTC2943_CURRENT_MSB_REG,LTC2943_CURRENT_LSB_REG);
		coulomb.read.raw.current_threshold_H	= uint8_to_uint16(readData,LTC2943_CURRENT_THRESH_HIGH_MSB_REG,LTC2943_CURRENT_THRESH_HIGH_LSB_REG);
		coulomb.read.raw.current_threshold_L 	= uint8_to_uint16(readData,LTC2943_CURRENT_THRESH_LOW_MSB_REG,LTC2943_CURRENT_THRESH_LOW_LSB_REG);

		coulomb.read.raw.temperature 			= uint8_to_uint16(readData,LTC2943_TEMPERATURE_MSB_REG,LTC2943_TEMPERATURE_LSB_REG);
		coulomb.read.raw.temperature_threshold_H = (readData[LTC2943_TEMPERATURE_THRESH_HIGH_REG]<<8) | 0x00;//补充低字节
		coulomb.read.raw.temperature_threshold_L = (readData[LTC2943_TEMPERATURE_THRESH_LOW_REG]<<8) | 0x00;//补充低字节
	}
	return coulomb.ready;
}

bool coulomb_read_alcc()
{
	return HAL_GPIO_ReadPin(PMB_CLOULOMB_ALCC_GPIO_Port,PMB_CLOULOMB_ALCC_Pin);
}