/*############################################################################################*/
/*############################################################################################*/
/**
 * \file    BQ27510DRZRG2.c
 * \author  Thibaut LALUQUE 3D-Ouest
 * \date    05/11/2014
 * \version 1.0
 * \brief 	Source file for Battery Management BQ27510DRZR-G2 driver.
 * \details All Right Reserved.
 */
/*############################################################################################*/
/*############################################################################################*/


/*############################################################################################*/
/*## INCLUDES ################################################################################*/
/*############################################################################################*/
#include "BQ27510DRZRG2.h"
/*############################################################################################*/
/*## END INCLUDES ############################################################################*/
/*############################################################################################*/

/*############################################################################################*/
/*## CONFIGURATION BITS ######################################################################*/
/*############################################################################################*/

/*############################################################################################*/
/*## END CONFIGURATION BITS ##################################################################*/
/*############################################################################################*/

/*############################################################################################*/
/*## LOCAL DEFINES ###########################################################################*/
/*############################################################################################*/


/*############################################################################################*/
/*## END LOCAL DEFINES ######################################################################*/
/*############################################################################################*/


/*############################################################################################*/
/*## LOCAL FONCTIONS DECLARATION #############################################################*/
/*############################################################################################*/

/*############################################################################################*/
/*## END LOCAL FONCTIONS DECLARATION #########################################################*/
/*############################################################################################*/


/*############################################################################################*/
/*## LOCAL VARIABLES #########################################################################*/
/*############################################################################################*/

/*############################################################################################*/
/*## END LOCAL VARIABLES #####################################################################*/
/*############################################################################################*/

/*############################################################################################*/
/*## GLOBAL VARIABLES ########################################################################*/
/*############################################################################################*/
tBQBatteryStatus BQBatteryStatus;
/*############################################################################################*/
/*## END GLOBAL VARIABLES ####################################################################*/
/*############################################################################################*/


/*############################################################################################*/
/*## LOCAL FONCTIONS #########################################################################*/
/*############################################################################################*/

/*############################################################################################*/
/*## END LOCAL FONCTIONS #####################################################################*/
/*############################################################################################*/


/*############################################################################################*/
/*## EXTERNAL FONCTIONS ######################################################################*/
/*############################################################################################*/
void BQ27510DRZRG2_Init (void) {

	I2C0Init();		//Init I2C
	I2C0Enable();	//Enable I2C
}

signed short BQ_batteryIsConnected (void) {
	unsigned char data;		//Dummy
	signed char result = I2C0Send(BQ_DEVICE_ADDRESS,&data,0);
	return result;		//Return 0 if battery is connected else return -1
}


signed short BQ_getCellTemperature(void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_TEMPERATURE_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return -273;		//Error
	} else {
		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);
		return (value/10) - 273;		//Convert °K to °C
	}
}


unsigned short BQ_getCellVoltage(void) {

	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_VOLTAGE_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getNominalAvailableCapacity(void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_NOMI_AVAILABLE_CAPACITY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}


unsigned short BQ_getFullAvailableCapacity (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_FULL_AVAILABLE_CAPACITY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}


unsigned short BQ_getRemainingCapacity (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_REMAINING_CAPACITY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getFullChargeCapacity (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_FULL_CHARGE_CAPACITY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

signed short BQ_getAverageCurrent (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_AVERAGE_CURRENT_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		signed short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getTimeToEmpty (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_TIME_TO_EMPTY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getTimeToFull (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_TIME_TO_FULL_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

signed short BQ_getStandbyCurrent (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_STANDBY_CURRENT_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		signed short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getStandbyTimeToEmpty (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_STANDBY_TIME_TO_EMPTY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

signed short BQ_getMaxLoadCurrent (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_MAX_LOAD_CURRENT_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		signed short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getMaxLoadTimeToEmpty (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_MAX_LOAD_TIME_TO_EMPTY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned long BQ_getAvailableEnergy (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_AVAILABLE_ENERGY_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value*10;
	}
}

signed short BQ_getAveragePower (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_AVERAGE_POWER_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		signed short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getTTEAtConstantPower (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_TTEAT_CONSTANT_POWER_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getCycleCount (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_CYCLE_COUNTE_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {

		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);

		return value;
	}
}

unsigned short BQ_getStateOfCharge (void) {
	signed char result = 0;
	unsigned char data[2] = {0};
	unsigned char command;

	command = BQ_STATE_OF_CHARGE_CMD;

	result = I2C0Read(BQ_DEVICE_ADDRESS, &command, 1, data, 2);

	if (result == -1) {
		return 0;		//Error
	} else {
		unsigned short value = (((unsigned short)data[1]) << 8 ) | ((unsigned short)data[0]);
		return value;		//Convert °K to °C
	}
}

signed short BQ_getFullInfo (void) {

	if(BQ_batteryIsConnected() == 0) {

		BQBatteryStatus.cellTemperature = BQ_getCellTemperature();
		BQBatteryStatus.cellVoltage = BQ_getCellVoltage();
		BQBatteryStatus.noLoadNominalCapacity = BQ_getNominalAvailableCapacity();
		BQBatteryStatus.noLoadFullCapacity = BQ_getFullAvailableCapacity();
		BQBatteryStatus.remainingCapacity = BQ_getRemainingCapacity();
		BQBatteryStatus.fullCapacity = BQ_getFullChargeCapacity();
		BQBatteryStatus.averageCurrent = BQ_getAverageCurrent();
		BQBatteryStatus.timeToEmpty = BQ_getTimeToEmpty();
		BQBatteryStatus.timeToFull = BQ_getTimeToFull();
		BQBatteryStatus.standbyCurrent = BQ_getTimeToFull();
		BQBatteryStatus.standbyTimeToEmpty = BQ_getStandbyTimeToEmpty();
		BQBatteryStatus.maxLoadCurrent = BQ_getMaxLoadCurrent();
		BQBatteryStatus.maxLoadTimeToEmpty = BQ_getMaxLoadTimeToEmpty();
		BQBatteryStatus.availableEnergy = BQ_getAvailableEnergy();
		BQBatteryStatus.averagePower = BQ_getAveragePower();
		BQBatteryStatus.timeToEmptyAtConstantPower = BQ_getTTEAtConstantPower();
		BQBatteryStatus.cycleCount = BQ_getCycleCount();
		BQBatteryStatus.stateOfCharge = BQ_getStateOfCharge();

		return 0;

	} else {

		//No battery detected
		BQBatteryStatus.cellTemperature = 0;
		BQBatteryStatus.cellVoltage = 0;
		BQBatteryStatus.noLoadNominalCapacity = 0;
		BQBatteryStatus.noLoadFullCapacity = 0;
		BQBatteryStatus.remainingCapacity = 0;
		BQBatteryStatus.fullCapacity = 0;
		BQBatteryStatus.averageCurrent = 0;
		BQBatteryStatus.timeToEmpty = 0;
		BQBatteryStatus.timeToFull = 0;
		BQBatteryStatus.standbyCurrent = 0;
		BQBatteryStatus.standbyTimeToEmpty = 0;
		BQBatteryStatus.maxLoadCurrent = 0;
		BQBatteryStatus.maxLoadTimeToEmpty = 0;
		BQBatteryStatus.availableEnergy = 0;
		BQBatteryStatus.averagePower = 0;
		BQBatteryStatus.timeToEmptyAtConstantPower = 0;
		BQBatteryStatus.cycleCount = 0;
		BQBatteryStatus.stateOfCharge = 0;

		return -1;
	}
}
/*############################################################################################*/
/*## END EXTERNAL FONCTIONS ##################################################################*/
/*############################################################################################*/
