Defines | Functions | Variables

xpal_bat.h File Reference

Battery Management Routines for the eXPal Prototype A. More...

#include <avr/io.h>

Go to the source code of this file.


#define HL_BAT_VOLT_INVALID   0x7fff
 Invalid Voltage Value.
#define HL_BAT_MEASURE_ACTIVE   0x8000
 MSB in voltage value used to indicate measurement in progress.
#define HL_BAT_FULL_VOLT   4500
 Voltage to recognize full battery.
#define HL_BAT_MIN_VOLT   2500
 Voltage to recognize an empty battery.
#define HL_BAT_MIN_GPS_VOLT   3500
 Min voltage to allow GPS power on When the system voltage is below this value, the GPS will not be activated.
 Gradient Threshold Gradient value when battery state is checked.
 Voltage Gradient Counter Variables.
 9 hours, Value will not be incremented beyond this limit
#define HL_BAT_ST_FOPMAX   0x09
 BatteryStates and Limits.
#define HL_BAT_ST_FOP4   0x08
 Battery full (8).
#define HL_BAT_ST_FOP3   0x07
 Battery full (7).
#define HL_BAT_ST_FOP2   0x06
 Battery full (6).
#define HL_BAT_ST_FOP1   0x05
 Battery full (5).
#define HL_BAT_ST_FOPMIN   0x04
 Min Level for full operation (4).
#define HL_BAT_ST_LIM3   0x03
 Battery Limited (3).
#define HL_BAT_ST_LIM2   0x02
 Battery Limited (2).
#define HL_BAT_ST_LIM1   0x01
 Battery Limited (1).
#define HL_BAT_ST_EMPTY   0x00
 Battery Limited (0).
#define HL_BAT_ST_MASK   0x0F
 BatteryStatus byte section.
#define HL_BAT_UPDATE   0x80
 Check Bat Condition when set (xpal_bat internal bit).
#define HL_BAT_NEWSTAT   0x40
 Status is new and returned for the first time.
#define HL_BAT_BLED_OFF   0x20
 Notice that Battery level is fast decreasing.
#define HL_BAT_GPS_STOP   0x10
 Notice that GPS will be powered off.
#define HL_BAT_MV_PER_DIGIT   5
 convert ADC result into millivolt


void hl_InitBatMan (void)
 Init battery management system.
uint8_t hl_bat_GetBatStatus (void)
 Estimate the Battery condition and return the state for the.
uint16_t hl_pwr_GetBatVoltage (void)
 Request current bat voltage.
uint16_t hl_pwr_GetBatGradient (void)
 Request current bat voltage gradient.
uint16_t hl_adc_correct (uint16_t r)
 correct the value read from ADC
uint16_t hl_adc_convert (uint16_t r)


volatile uint8_t BatStatus
 Battery status byte.
volatile uint16_t BatVoltage
 voltage in mV
volatile int16_t BatGradient
 voltage gradient in mV
volatile int16_t BatGradientTimer
 BatGradient was collected over this time [s].
int8_t adc_calibration
 ADC calibration value.

Detailed Description

Battery Management Routines for the eXPal Prototype A.

Define Documentation


Voltage Gradient Counter Variables.

Loaded at power up to ignore the first 5 cycles

#define HL_BAT_MV_PER_DIGIT   5

convert ADC result into millivolt

mV per digits 2.56V reference / 10bit -> 1024 = 2.5mV per digit The board implements a 1/2 Voltage divider -> 5mV per digit

r output from ADC
voltage, [mV]
#define HL_BAT_ST_FOPMAX   0x09

BatteryStates and Limits.

Battery full (9)

#define HL_BAT_ST_MASK   0x0F

BatteryStatus byte section.

Battery State bits

#define HL_BAT_VOLT_INVALID   0x7fff

Invalid Voltage Value.

Voltage unknown or not measured yet

Function Documentation

uint16_t hl_adc_correct ( uint16_t  r  )  [inline]

correct the value read from ADC

hl_adc_correct() adjusts the value read from ADC according to the calibration value stored in adc_calibration.

The correction is performed by adding the fraction specified by adc_calibration to the value read from ADC.

The range (factor 0.5 .. 1.5) should be sufficient.

  return r + ((int32_t)r * adc_calibration >> 8);

uint8_t hl_bat_GetBatStatus ( void   ) 

Estimate the Battery condition and return the state for the.

The battery voltage is evaluated to estimate the battery status


        // return old value when no reevaluation event happened
        if((BatStatus & HL_BAT_UPDATE) == 0){

                // return old value when no reevaluation event happened
                BatStatus &= ~(HL_BAT_NEWSTAT);

                // clear update state
                BatStatus &= ~(HL_BAT_UPDATE);

                // clear battery state
                BatStatus &= ~(HL_BAT_ST_MASK);                 

                if(BatVoltage >= HL_BAT_V_FOPMIN){
                        // we have enough power for full operation              
                        if (BatVoltage > HL_BAT_V_FOPMAX){
                                BatStatus |= HL_BAT_ST_FOPMAX;
                        }else if(BatVoltage > HL_BAT_V_FOP4){
                                BatStatus |= HL_BAT_ST_FOP4;
                        }else if(BatVoltage > HL_BAT_V_FOP3){
                                BatStatus |= HL_BAT_ST_FOP3;
                        }else if(BatVoltage > HL_BAT_V_FOP2){
                                BatStatus |= HL_BAT_ST_FOP2;
                        }else if(BatVoltage > HL_BAT_V_FOP1){
                                BatStatus |= HL_BAT_ST_FOP1;
                                BatStatus |= HL_BAT_ST_FOPMIN;
                        // we are in limited op mode now
                        if (BatVoltage > HL_BAT_V_LIM3){
                                BatStatus |= HL_BAT_ST_LIM3;
                        }else if(BatVoltage > HL_BAT_V_LIM2){
                                BatStatus |= HL_BAT_ST_LIM2;
                        }else if(BatVoltage > HL_BAT_V_LIM1){
                                BatStatus |= HL_BAT_ST_LIM1;
                        }else if(BatVoltage > HL_BAT_V_EMPTY){
                                BatStatus |= HL_BAT_ST_LIM1;
                                BatStatus |= HL_BAT_ST_EMPTY;
                // mark status as new value
                BatStatus |= HL_BAT_NEWSTAT;

                // !!!! debug
                printf("\n\r.%X %imV", BatStatus, BatVoltage);

        // Evaluate discharge Gradient
        if(BatGradient < HL_BAT_MAX_VOLT_GRADIENT){
                // Need to collect data on this value
                // useful code comming soon

                // !!!! debug
                printf(":%imV_%is \n\r", BatGradient, BatGradientTimer);

                BatGradientTimer = 1;
                BatGradient = 0;        

        return BatStatus;

void hl_InitBatMan ( void   ) 

Init battery management system.


  • Variables
  • Bat Voltage measurement
  • Timer Registration


  • Variables
  • Bat Voltage measurement
  • Timer Registration

This function needs to be called early in main(), before the 1s timer is running to ensure that there is an initial value for the battery voltage available

The init function will take some time to do the first measurement.

    int8_t calvalue;
        BatVoltage = HL_BAT_VOLT_INVALID;
        BatGradient= 0;
        BatGradientTimer = HL_BAT_GRADIENT_COUNT_PON;

        // Start with low bat setting and activate update
        BatStatus = HL_BAT_ST_FOP1 & HL_BAT_UPDATE; 

        // Start initial voltage measurement

        // Do the initial measurement
        // This is required for the later gradient calculation

        /* read calibration value from EEPROM */
        calvalue = eeprom_read_byte (CFG_CALIB_BATT_VOLT);
        if (calvalue != 0xFF)
          adc_calibration = calvalue;

        BatVoltage = adc_calibration + hl_adc_convert(hl_adc_result ());

        // register 1s timer call back
        hl_asyn_Register1sTimer( (&hl_bat_slow), NULL);

uint16_t hl_pwr_GetBatGradient ( void   )  [inline]

Request current bat voltage gradient.

Voltage gradient to application voltage in mV

        return BatGradient;

uint16_t hl_pwr_GetBatVoltage ( void   )  [inline]

Request current bat voltage.

Voltage to application Voltage in mV

        return (BatVoltage & ~HL_BAT_MEASURE_ACTIVE);

Variable Documentation

ADC calibration value.

The calibration value is read from EEPROM during initialization. To get the corrected ADC output, use hl_adc_correct().