From a637366b01bbf686fa909efb9ca898188acff52e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sergi=20Hern=C3=A0ndez=20Juan?= <shernand@iri.upc.edu>
Date: Wed, 4 Jul 2012 06:29:18 +0000
Subject: [PATCH] Updated the battery firmware:   - Added a bootloader.   -
 Added the I2C communication with the battery.   - Improved the capacity
 calculation. Minor chnages to the driver class.

---
 fuel_gauge.c        |  91 ++++++++++++++++++++++++++------------
 fuel_gauge.h        |   3 +-
 gpio.c              |  17 +++----
 i2c.c               |   2 +-
 tibi_dabo_battery.c | 105 +++++++++++++-------------------------------
 timer.c             |   2 +-
 6 files changed, 107 insertions(+), 113 deletions(-)

diff --git a/fuel_gauge.c b/fuel_gauge.c
index c4e1e6a..0e32e11 100755
--- a/fuel_gauge.c
+++ b/fuel_gauge.c
@@ -6,32 +6,31 @@
 #include "a2d.h"
 
 short int battery_voltage;
-short int input_current;
-short int output_current;
+float input_current;
+float output_current;
 
 // battery I2C slave address
 unsigned char battery_id;             
 unsigned char EEMEM ee_battery_id=0x31;  
 
 // remaining_capacity
-float remaining_capacity;
-//float EEMEM ee_remaining_capacity=108000000.0;//mAs
-float EEMEM ee_remaining_capacity=30000.0;//mAh
+volatile unsigned short int remaining_capacity;
+unsigned short int EEMEM ee_remaining_capacity=30000;//mAh
 // maximum capacity
-volatile float maximum_capacity;
-//float EEMEM ee_maximum_capacity=108000000.0;//mAs
-float EEMEM ee_maximum_capacity=30000.0;//mAh
+volatile unsigned short int maximum_capacity;
+unsigned short int EEMEM ee_maximum_capacity=30000;//mAh
 // charge cycles
-volatile short int charge_cycles;
-short int EEMEM ee_charge_cycles=0;
+volatile unsigned short int charge_cycles;
+unsigned short int EEMEM ee_charge_cycles=0;
+// accumutaed_capacity
+float accumulated_capacity;
 
-const float current_gain=48.828125;//mA
-//const float period=0.001984*4;//s
-const float period=0.000002204444;//h
+const double current_gain=48.828125;//mA
+const double period=0.00000222222;//h (8 ms)
 
 void update_fuel_gauge(void)
 {
-  float current_ma;
+  short int increment=0;
 
   outb(TCNT0,131);// reload the timer value
   // read the voltage and temperature from the battery
@@ -39,26 +38,33 @@ void update_fuel_gauge(void)
   input_current=adc_get_averaged_channel(6)*current_gain;
   output_current=adc_get_averaged_channel(7)*current_gain;
   // update the internal variables
-  remaining_capacity=remaining_capacity-(input_current*period);
+  accumulated_capacity+=(input_current-output_current)*period;
+  increment=(short int)accumulated_capacity;
+  accumulated_capacity-=increment;
+  remaining_capacity-=increment;
+  if(remaining_capacity>maximum_capacity)
+    remaining_capacity=maximum_capacity;
+  if(remaining_capacity<0)
+    remaining_capacity=0;
 }
 
 void fuel_gauge_init(void)
 {
   // read the data from the EEPROM
   battery_id=eeprom_read_byte(&ee_battery_id);
-  remaining_capacity=eeprom_read_float(&ee_remaining_capacity);
-  maximum_capacity=eeprom_read_float(&ee_maximum_capacity);
+  remaining_capacity=eeprom_read_word(&ee_remaining_capacity);
+  maximum_capacity=eeprom_read_word(&ee_maximum_capacity);
   charge_cycles=eeprom_read_word(&ee_charge_cycles);
+  accumulated_capacity=0.0;
 
   // initialize the timer
   timerInit();
   timer0SetPrescaler(TIMER_CLK_DIV1024);
-  outb(TCNT0, 131);
+  outb(TCNT0,131);
   timerAttach(TIMER0OVERFLOW_INT,update_fuel_gauge);
   // attach timer functions
   // initialize the i2c peripheral
   i2cInit();
-  i2cSetBitrate(100);
   // initialize the a2d converter
   a2dInit();
   a2dSetPrescaler(ADC_PRESCALE_DIV128);
@@ -70,35 +76,66 @@ void fuel_gauge_init(void)
 
 short int get_time_to_charged(void)
 {
-   return ((maximum_capacity-remaining_capacity)*60)/output_current;
+   return ((maximum_capacity-remaining_capacity)*60.0)/output_current;
 }
 
 short int get_time_to_discharged(void)
 {
-   return (remaining_capacity*60)/input_current;
+   return (remaining_capacity*60.0)/input_current;
 }
 
 short int get_input_current(void)
 {
-   return input_current;
+   return (short int)input_current;
 }
 
 short int get_output_current(void)
 {
-   return output_current;
+   return (short int)output_current;
 }
 
-short int get_voltage(void)
+void get_voltage(unsigned char *voltage)
 {
-   return 0;
+  unsigned char read_cmd,i;
+  unsigned char voltage_data[18];
+
+  // read the voltage registers of the battery
+  // send the read request
+  read_cmd=0x30;
+  if(i2cMasterSendNI(0x62,1,&read_cmd)==I2C_OK)
+  {
+    if(i2cMasterReceiveNI(0x62,18,voltage_data)==I2C_OK)
+    {
+      for(i=0;i<16;i++)
+        voltage[i]=voltage_data[i+2];
+    }
+  }
+}
+
+void get_temperature(unsigned char *temp1, unsigned char *temp2)
+{
+  unsigned char temp_data[6];
+  unsigned char read_cmd;
+
+  read_cmd=0x4A;// device start read address
+  if(i2cMasterSendNI(0x62,1,&read_cmd)==I2C_OK)
+  {
+   	if(i2cMasterReceiveNI(0x62,6,temp_data)==I2C_OK)
+	{
+	  temp1[0]=temp_data[2];
+	  temp1[1]=temp_data[3];
+	  temp2[0]=temp_data[4];
+	  temp2[1]=temp_data[5];
+	}
+  }
 }
 
 short int get_remaining_capacity(void)
 {
-   return (short int)remaining_capacity;
+   return (short int)(remaining_capacity);
 }
 
 short int get_max_capacity(void)
 {
-   return maximum_capacity;
+   return (short int)(maximum_capacity);
 }
diff --git a/fuel_gauge.h b/fuel_gauge.h
index 75f9542..c3f4d5a 100755
--- a/fuel_gauge.h
+++ b/fuel_gauge.h
@@ -6,7 +6,8 @@ short int get_time_to_charged(void);
 short int get_time_to_discharged(void);
 short int get_input_current(void);
 short int get_output_current(void);
-short int get_voltage(void);
+void get_voltage(unsigned char *voltage);
+void get_temperature(unsigned char *temp1, unsigned char *temp2);
 short int get_remaining_capacity(void);
 short int get_max_capacity(void);
 
diff --git a/gpio.c b/gpio.c
index 7a3d193..37ab5b7 100755
--- a/gpio.c
+++ b/gpio.c
@@ -12,6 +12,7 @@ void InitGPIO(void)
 	               // PC1 as an output (load_control)
 	DDRC=DDRC&0xF3;// PC2 as an input (UVP)
 	 			   // Pc3 as an input (OVP)
+    
 
     PORTC=0x00;
 }
@@ -40,9 +41,9 @@ void handle_battery(void)
 {
 	if(is_battery_present())
 	{
-		if(under_voltage_protection())
-			disable_battery();
-		else
+//		if(under_voltage_protection())
+//			disable_battery();
+//		else
 			enable_battery();
 	}
 	else
@@ -53,15 +54,15 @@ void handle_load(void)
 {
 	if(is_battery_present())
 	{
-		if(under_voltage_protection())
-			disable_load();
-		else
-		{
+//		if(under_voltage_protection())
+//			disable_load();
+//		else
+//		{
 			if(is_load_on())
 				enable_load();
 			else
 				disable_load();
-		}
+//		}
 	}
 	else
 	{
diff --git a/i2c.c b/i2c.c
index bcdc5d4..00a527e 100755
--- a/i2c.c
+++ b/i2c.c
@@ -234,7 +234,7 @@ u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
 	// transmit stop condition
 	// leave with TWEA on for slave receiving
 	i2cSendStop();
-	while( !(inb(TWCR) & BV(TWSTO)) );
+	while( !(inb(TWCR) & BV(TWEA)) );
 
 	// enable TWI interrupt
 	sbi(TWCR, TWIE);
diff --git a/tibi_dabo_battery.c b/tibi_dabo_battery.c
index 2304774..3cab20c 100755
--- a/tibi_dabo_battery.c
+++ b/tibi_dabo_battery.c
@@ -12,12 +12,14 @@
 
 #include "fuel_gauge.h"
 
+#include "i2c.h"
+
 typedef struct
 {
    unsigned char header[2];
-   short int battery_voltage;
-   short int temperature1;
-   short int temperature2;
+   unsigned char battery_voltage[16];
+   unsigned char temperature1[2];
+   unsigned char temperature2[2];
    unsigned char status;
    // bit 0: battery_present
    // bit 1: charger_present;
@@ -33,11 +35,8 @@ typedef struct
 
 int main (void)
 {
-//   unsigned char read_cmd[2];
-//   unsigned char voltage_data[18];
-//   unsigned char temp_data[6];
+   unsigned char i;
    TBatteryInfo info;
-   int i=0;
 
    // initialize the GPIO
    InitGPIO();
@@ -53,74 +52,30 @@ int main (void)
    info.header[1]=0xAA;
    while(1)
    {
-      // read the voltage registers of the battery
-	  // send the read request
-/*      read_cmd[0]=0x30;// device start read address
-	  read_cmd[1]=18;// read length
-	  if(i2cMasterSendNI(0x60,2,read_cmd)==I2C_OK)
-	  {
-	     if(i2cMasterReceiveNI(0x60,18,voltage_data)==I2C_OK)
-		 {
-		    info.cell1_voltage[0]=voltage_data[2];
-			info.cell1_voltage[1]=voltage_data[3];
-			info.cell2_voltage[0]=voltage_data[4];
-			info.cell2_voltage[1]=voltage_data[5];
-			info.cell3_voltage[0]=voltage_data[6];
-			info.cell3_voltage[1]=voltage_data[7];
-			info.cell4_voltage[0]=voltage_data[8];
-			info.cell4_voltage[1]=voltage_data[9];
-			info.cell5_voltage[0]=voltage_data[10];
-			info.cell5_voltage[1]=voltage_data[11];
-			info.cell6_voltage[0]=voltage_data[12];
-			info.cell6_voltage[1]=voltage_data[13];
-			info.cell7_voltage[0]=voltage_data[14];
-			info.cell7_voltage[1]=voltage_data[15];
-			info.cell8_voltage[0]=voltage_data[16];
-			info.cell8_voltage[1]=voltage_data[17];
-		    // read the voltage registers of the battery
-			// send the read request
-			read_cmd[0]=0x4A;// device start read address
-	  		read_cmd[1]=6;// read length
-	  		if(i2cMasterSendNI(0x60,2,read_cmd)==I2C_OK)
-	  		{
-	     		if(i2cMasterReceiveNI(0x60,6,temp_data)==I2C_OK)
-		 		{
-				    info.temperature1[0]=temp_data[2];
-					info.temperature1[1]=temp_data[3];
-					info.temperature2[0]=temp_data[4];
-					info.temperature2[1]=temp_data[5];
-					info.battery_present=is_battery_present();
-					info.charger_present=is_charger_present();
-					info.load_on=is_load_on();
-					info.UVP=under_voltage_protection();
-					info.OVP=over_voltage_protection();
-         		}
-			}
-         }
-	  }*/
-       _delay_ms(1000);
-	   handle_battery();
-	   handle_load();
-	   info.battery_voltage=get_voltage();
-	   info.status=0x00;
-	   if(is_battery_present())
-	      info.status|=0x01;
-	   if(is_charger_present())
-	      info.status|=0x02;
-	   if(is_load_on())
-	      info.status|=0x04;
-       if(under_voltage_protection())
-	      info.status|=0x08;
-       if(over_voltage_protection())
-	      info.status|=0x10;
-       info.current_in=get_input_current();
-	   info.current_out=get_output_current();
-	   info.rem_capacity=get_remaining_capacity();
-	   info.time_to_charged=get_time_to_charged();
-	   info.time_to_discharged=get_time_to_discharged();
-	   // send tha information packet
-	   for(i=0;i<sizeof(TBatteryInfo);i++)
-	      uartSendByte(((unsigned char *)&info)[i]);
+      _delay_ms(1000);
+	  handle_battery();
+	  handle_load();
+	  get_voltage(info.battery_voltage);
+	  get_temperature(info.temperature1,info.temperature2);
+	  info.status=0x00;
+	  if(is_battery_present())
+	     info.status|=0x01;
+	  if(is_charger_present())
+	     info.status|=0x02;
+	  if(is_load_on())
+	     info.status|=0x04;
+      if(under_voltage_protection())
+	     info.status|=0x08;
+      if(over_voltage_protection())
+	     info.status|=0x10;
+      info.current_in=get_input_current();
+	  info.current_out=get_output_current();
+	  info.rem_capacity=get_remaining_capacity();
+	  info.time_to_charged=get_time_to_charged();
+	  info.time_to_discharged=get_time_to_discharged();
+	  // send tha information packet
+	  for(i=0;i<sizeof(TBatteryInfo);i++)
+	     uartSendByte(((unsigned char *)&info)[i]);
 	}
 }
 
diff --git a/timer.c b/timer.c
index 07398e0..434685b 100755
--- a/timer.c
+++ b/timer.c
@@ -235,7 +235,7 @@ void timerPause(unsigned short pause_ms)
 		}
 	}
 
-	/* old inaccurate code, for reference 
+	//old inaccurate code, for reference 
 	
 	// calculate delay for [pause_ms] milliseconds
 	u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0)));
-- 
GitLab