Part Number:BQ27441EVM-G1A
Hello,
I am working with BQ27441EVM-G1A(Fuelgauge) which is interfaced by I2C with microcontroller. I2C works correctly and i am able to read and write data to BQ27441EVM-G1A but i am facing some issues which i mentioned below :
1) Battery percentage is not getting update(for ex: when discharging it should be decrease and when charging it should be increase as per bq27441 TRM(www.ti.com/.../sluuac9a.pdf)).
2) Average current value is not getting update. I am getting 0(zero) average current always whenever i read.(it should not be 0 when charging/discharging ).
3) Average power value is not getting update. I am getting 0(zero) average power always whenever i read.(i used this value to detect charging/discharging).
I set battery capacity 5000mAh and read that value through I2C and it gives me correct value which is 5000mAh. So in Fualguage_initialize() function of my code i set battery capacity(5000mAh),opconfig register(0x3DFC),design energy(21000).For your reference i attached my code and its hardware schematic.please help me so that i can get battery percentage,current and power updated values.
It is really appreciated if anyone can help. Looking forward for your positive response.
Thanks,
Bhavin Maru
========================================= HW Schematic ====================================================
![]()
========================================================== main.c =============================================================================
#include <stdio.h>
#include "Nano1X2Series.h"
void my_delay(void)
{
uint32_t i = 800000;
while(i--);
i = 800000;
while(i--);
i = 800000;
while(i--);
i = 800000;
while(i--);
i = 800000;
while(i--);
}
/*---------------------------------------------------------------------------------------------------------*/
/* Main Function */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main (void)
{
SYS_Init(); /* Init System, IP clock and multi-function I/O */
UART_Open(UART0, 115200); /* Init UART to 115200-8n1 for print message */
I2C0_Init(); /* Init I2C0 as Master */
my_delay();
my_delay();
my_delay();
my_delay();
Fualguage_initialize();
my_delay();
my_delay();
my_delay();
my_delay();
my_delay();
printf("opconfig : %X\n",opConfig());
while(1)
{
my_delay();
my_delay();
my_delay();
my_delay();
my_delay();
my_delay();
my_delay();
my_delay();
Fualguage_Parameter();
}
}
================================================================ Fualguage.h =======================================================================
#ifndef __FUALGUAGE_H
#define __FUALGUAGE_H
#define TIMEOUT 10000
#define BQ72441_I2C_TIMEOUT 2000
//----------------------- Battery parameters macros ---------------------------
#define BATTERY_CAPACITY 5000 // e.g. 5000mAh battery
// DesignEnergy = BATTERY_CAPACITY(mAh) * 4.2V
#define DESIGN_ENERGY 21000
#define TERMINATE_VOLTAGE 3300 //TerminateVoltage = 3300mV
#define TAPER_CURRENT 115 //TaperCurrent = 115mA
// TAPER_RATE = (int)(BATTERY_CAPACITY / (0.1 * TAPER_CURRENT))
#define TAPER_RATE 434
#define TAPER_VOLTAGE 4200
#define SOC1_SET_THRESHOLD 10 //low battery threshold percentage interrupt
#define SOC1_CLEAR_THRESHOLD 11 //low battery threshold interrupt clear after reaching this percentage
#define FC_SET 98 //Charging terminates after this percentage
#define FC_CLEAR 95 //Flag's FC bit clear below this percentage
#define OPCONFIG 0x3DFC
//-----------------------------------------------------------------------------
typedef struct
{
uint8_t charging : 1;
uint8_t discharge : 1;
uint8_t Bat_Low : 1;
int16_t Percentage;
int16_t Current;
int16_t Design_Capacity;
int16_t Full_Capacity;
int16_t Avail_Capacity;
float Voltage;
}Battery;
typedef enum
{
SET_BATTERY_CAPACITY,
SET_OPCONFIG,
SET_DESIGN_ENERGY,
SET_TERMINATE_VOLTAGE,
SET_TAPER_RATE,
SET_TAPER_VOLTAGE,
SET_SOC1_THRESHOLD,
SET_FC_SET,
SET_FC_CLEAR,
SET_SOC1_CLEAR_THRESHOLD
}Fual_Guage_Init;
typedef enum
{
ENTER_CONFIG,
COMPUTE_BLOCK_CHKSUM,
GET_CHECKSUM,
WRITE_CHECKSUM,
EXIT_CONFIG
}Write_ExtendedData;
#define TIMER_EXPIRE FG_Timer_Flag >= 2
/* This delay is required for I2C read */
#define DELAY for(j = 0;j < 500;j++)
#define SOC1_CLR_THRESHOLD ((offset == 1) && (classID == 49))
#define DEDIGN_CAPACITY ((offset == 10) && (classID == 82))
#define DESIGN_ENERGY_E ((offset == 12) && (classID == 82))
#define FG_INITIALIZATION_COMPLETE FG_Init > SET_SOC1_CLEAR_THRESHOLD
// Parameters for the current() function, to specify which current to read
typedef enum {
AVG, // Average Current (DEFAULT)
STBY, // Standby Current
MAX // Max Current
} current_measure;
// Parameters for the capacity() function, to specify which capacity to read
typedef enum {
REMAIN, // Remaining Capacity (DEFAULT)
FULL, // Full Capacity
AVAIL, // Available Capacity
AVAIL_FULL, // Full Available Capacity
REMAIN_F, // Remaining Capacity Filtered
REMAIN_UF, // Remaining Capacity Unfiltered
FULL_F, // Full Capacity Filtered
FULL_UF, // Full Capacity Unfiltered
DESIGN // Design Capacity
} capacity_measure;
// Parameters for the soc() function
typedef enum {
FILTERED, // State of Charge Filtered (DEFAULT)
UNFILTERED // State of Charge Unfiltered
} soc_measure;
// Parameters for the soh() function
typedef enum {
PERCENT, // State of Health Percentage (DEFAULT)
SOH_STAT // State of Health Status Bits
} soh_measure;
// Parameters for the temperature() function
typedef enum {
BATTERY, // Battery Temperature (DEFAULT)
INTERNAL_TEMP // Internal IC Temperature
} temp_measure;
// Parameters for the setGPOUTFunction() funciton
typedef enum {
SOC_INT, // Set GPOUT to SOC_INT functionality
// BAT_LOW // Set GPOUT to BAT_LOW functionality <----- This is commented
} gpout_function;
///////////////////////
// General Constants //
///////////////////////
#define BQ27441_UNSEAL_KEY 0x8000 // Secret code to unseal the BQ27441-G1A
#define BQ27441_DEVICE_ID 0x0421 // Default device ID
///////////////////////
// Standard Commands //
///////////////////////
// The fuel gauge uses a series of 2-byte standard commands to enable system
// reading and writing of battery information. Each command has an associated
// sequential command-code pair.
#define BQ27441_COMMAND_CONTROL 0x00 // Control()
#define BQ27441_COMMAND_TEMP 0x02 // Temperature()
#define BQ27441_COMMAND_VOLTAGE 0x04 // Voltage()
#define BQ27441_COMMAND_FLAGS 0x06 // Flags()
#define BQ27441_COMMAND_NOM_CAPACITY 0x08 // NominalAvailableCapacity()
#define BQ27441_COMMAND_AVAIL_CAPACITY 0x0A // FullAvailableCapacity()
#define BQ27441_COMMAND_REM_CAPACITY 0x0C // RemainingCapacity()
#define BQ27441_COMMAND_FULL_CAPACITY 0x0E // FullChargeCapacity()
#define BQ27441_COMMAND_AVG_CURRENT 0x10 // AverageCurrent()
#define BQ27441_COMMAND_STDBY_CURRENT 0x12 // StandbyCurrent()
#define BQ27441_COMMAND_MAX_CURRENT 0x14 // MaxLoadCurrent()
#define BQ27441_COMMAND_AVG_POWER 0x18 // AveragePower()
#define BQ27441_COMMAND_SOC 0x1C // StateOfCharge()
#define BQ27441_COMMAND_INT_TEMP 0x1E // InternalTemperature()
#define BQ27441_COMMAND_SOH 0x20 // StateOfHealth()
#define BQ27441_COMMAND_REM_CAP_UNFL 0x28 // RemainingCapacityUnfiltered()
#define BQ27441_COMMAND_REM_CAP_FIL 0x2A // RemainingCapacityFiltered()
#define BQ27441_COMMAND_FULL_CAP_UNFL 0x2C // FullChargeCapacityUnfiltered()
#define BQ27441_COMMAND_FULL_CAP_FIL 0x2E // FullChargeCapacityFiltered()
#define BQ27441_COMMAND_SOC_UNFL 0x30 // StateOfChargeUnfiltered()
//////////////////////////
// Control Sub-commands //
//////////////////////////
// Issuing a Control() command requires a subsequent 2-byte subcommand. These
// additional bytes specify the particular control function desired. The
// Control() command allows the system to control specific features of the fuel
// gauge during normal operation and additional features when the device is in
// different access modes.
#define BQ27441_CONTROL_STATUS 0x00
#define BQ27441_CONTROL_DEVICE_TYPE 0x01
#define BQ27441_CONTROL_FW_VERSION 0x02
#define BQ27441_CONTROL_DM_CODE 0x04
#define BQ27441_CONTROL_PREV_MACWRITE 0x07
#define BQ27441_CONTROL_CHEM_ID 0x08
#define BQ27441_CONTROL_BAT_INSERT 0x0C
#define BQ27441_CONTROL_BAT_REMOVE 0x0D
#define BQ27441_CONTROL_SET_HIBERNATE 0x11
#define BQ27441_CONTROL_CLEAR_HIBERNATE 0x12
#define BQ27441_CONTROL_SET_CFGUPDATE 0x13
#define BQ27441_CONTROL_SHUTDOWN_ENABLE 0x1B
#define BQ27441_CONTROL_SHUTDOWN 0x1C
#define BQ27441_CONTROL_SEALED 0x20
#define BQ27441_CONTROL_PULSE_SOC_INT 0x23
#define BQ27441_CONTROL_RESET 0x41
#define BQ27441_CONTROL_SOFT_RESET 0x42
#define BQ27441_CONTROL_EXIT_CFGUPDATE 0x43
#define BQ27441_CONTROL_EXIT_RESIM 0x44
///////////////////////////////////////////
// Control Status Word - Bit Definitions //
///////////////////////////////////////////
// Bit positions for the 16-bit data of CONTROL_STATUS.
// CONTROL_STATUS instructs the fuel gauge to return status information to
// Control() addresses 0x00 and 0x01. The read-only status word contains status
// bits that are set or cleared either automatically as conditions warrant or
// through using specified subcommands.
#define BQ27441_STATUS_SHUTDOWNEN (1<<15)
#define BQ27441_STATUS_WDRESET (1<<14)
#define BQ27441_STATUS_SS (1<<13)
#define BQ27441_STATUS_CALMODE (1<<12)
#define BQ27441_STATUS_CCA (1<<11)
#define BQ27441_STATUS_BCA (1<<10)
#define BQ27441_STATUS_QMAX_UP (1<<9)
#define BQ27441_STATUS_RES_UP (1<<8)
#define BQ27441_STATUS_INITCOMP (1<<7)
#define BQ27441_STATUS_HIBERNATE (1<<6)
#define BQ27441_STATUS_SLEEP (1<<4)
#define BQ27441_STATUS_LDMD (1<<3)
#define BQ27441_STATUS_RUP_DIS (1<<2)
#define BQ27441_STATUS_VOK (1<<1)
////////////////////////////////////
// Flag Command - Bit Definitions //
////////////////////////////////////
// Bit positions for the 16-bit data of Flags()
// This read-word function returns the contents of the fuel gauging status
// register, depicting the current operating status.
#define BQ27441_FLAG_OT (1<<15)
#define BQ27441_FLAG_UT (1<<14)
#define BQ27441_FLAG_FC (1<<9)
#define BQ27441_FLAG_CHG (1<<8)
#define BQ27441_FLAG_OCVTAKEN (1<<7)
#define BQ27441_FLAG_ITPOR (1<<5)
#define BQ27441_FLAG_CFGUPMODE (1<<4)
#define BQ27441_FLAG_BAT_DET (1<<3)
#define BQ27441_FLAG_SOC1 (1<<2)
#define BQ27441_FLAG_SOCF (1<<1)
#define BQ27441_FLAG_DSG (1<<0)
////////////////////////////
// Extended Data Commands //
////////////////////////////
// Extended data commands offer additional functionality beyond the standard
// set of commands. They are used in the same manner; however, unlike standard
// commands, extended commands are not limited to 2-byte words.
#define BQ27441_EXTENDED_OPCONFIG 0x3A // OpConfig()
#define BQ27441_EXTENDED_CAPACITY 0x3C // DesignCapacity()
#define BQ27441_EXTENDED_DATACLASS 0x3E // DataClass()
#define BQ27441_EXTENDED_DATABLOCK 0x3F // DataBlock()
#define BQ27441_EXTENDED_BLOCKDATA 0x40 // BlockData()
#define BQ27441_EXTENDED_CHECKSUM 0x60 // BlockDataCheckSum()
#define BQ27441_EXTENDED_CONTROL 0x61 // BlockDataControl()
////////////////////////////////////////
// Configuration Offset //
////////////////////////////////////////
#define CAPACITY_OFFSET 10
#define DESIGN_ENERGY_OFFSET 12
#define TERMINATE_VTG_OFFSET 16
#define TAPERRATE_OFFSET 27
#define TAPER_VTG_OFFSET 29
#define OPCONFIG_OFFSET 0
#define SOC1_OFFSET 0
#define SOC1_CLEAR_OFFSET 1
#define FC_SET_OFFSET 5
#define FC_CLEAR_OFFSET 6
////////////////////////////////////////
// Configuration Class, Subclass ID's //
////////////////////////////////////////
// To access a subclass of the extended data, set the DataClass() function
// with one of these values.
// Configuration Classes
#define BQ27441_ID_SAFETY 2 // Safety
#define BQ27441_ID_CHG_TERMINATION 36 // Charge Termination
#define BQ27441_ID_CONFIG_DATA 48 // Data
#define BQ27441_ID_DISCHARGE 49 // Discharge
#define BQ27441_ID_REGISTERS 64 // Registers
#define BQ27441_ID_POWER 68 // Power
// Gas Gauging Classes
#define BQ27441_ID_IT_CFG 80 // IT Cfg
#define BQ27441_ID_CURRENT_THRESH 81 // Current Thresholds
#define BQ27441_ID_STATE 82 // State
// Ra Tables Classes
#define BQ27441_ID_R_A_RAM 89 // R_a RAM
// Calibration Classes
#define BQ27441_ID_CALIB_DATA 104 // Data
#define BQ27441_ID_CC_CAL 105 // CC Cal
#define BQ27441_ID_CURRENT 107 // Current
// Security Classes
#define BQ27441_ID_CODES 112 // Codes
/////////////////////////////////////////
// OpConfig Register - Bit Definitions //
/////////////////////////////////////////
// Bit positions of the OpConfig Register
#define BQ27441_OPCONFIG_BIE (1<<13)
#define BQ27441_OPCONFIG_BI_PU_EN (1<<12)
#define BQ27441_OPCONFIG_GPIOPOL (1<<11)
#define BQ27441_OPCONFIG_SLEEP (1<<5)
#define BQ27441_OPCONFIG_RMFCC (1<<4)
#define BQ27441_OPCONFIG_BATLOWEN (1<<2)
#define BQ27441_OPCONFIG_TEMPS (1<<0)
// Function Declaration
uint8_t begin(void);
uint8_t setCapacity(uint16_t capacity);
uint16_t voltage(void);
int16_t current(current_measure type);
uint16_t capacity(capacity_measure type);
int16_t power(void);
uint16_t soc(soc_measure type);
uint8_t soh(soh_measure type);
uint16_t temperature(temp_measure type);
uint16_t deviceType(void);
uint8_t enterConfig(uint8_t userControl);
uint8_t exitConfig(uint8_t resim);
uint16_t flags(void);
uint16_t status(void);
uint8_t sealed(void);
uint8_t seal(void);
uint8_t unseal(void);
uint16_t opConfig(void);
uint16_t readWord(uint16_t subAddress);
uint16_t readControlWord(uint16_t function);
uint8_t executeControlWord(uint16_t function);
uint8_t blockDataControl(void);
uint8_t blockDataClass(uint8_t id);
uint8_t blockDataOffset(uint8_t offset);
uint8_t blockDataChecksum(void);
uint8_t readBlockData(uint8_t offset);
uint8_t writeBlockData(uint8_t offset, uint8_t data);
uint8_t computeBlockChecksum(void);
uint8_t writeBlockChecksum(uint8_t csum);
uint16_t readExtendedData(uint8_t classID, uint8_t offset);
uint8_t writeExtendedData(uint8_t classID, uint8_t offset, uint8_t * data, uint8_t len);
uint8_t softReset(void);
uint8_t setDesign_Energy(uint16_t capacity);
uint8_t setTerminate_Voltage(uint16_t capacity);
uint8_t setTaper_Rate(uint16_t capacity);
uint16_t my_readBlockData(uint8_t offset);
void Fualguage_initialize(void);
void Fualguage_Parameter(void);
uint8_t setTaper_Voltage(uint16_t capacity);
uint8_t setGPOUT(uint16_t capacity);
uint8_t Set_SOC1_Threshold(uint16_t capacity);
uint8_t Clear_SOC1_Threshold(uint16_t capacity);
void read_battery_percentage(void);
void Check_Battery_Chg_Dischg(void);
uint8_t Set_FcSet_Threshold(uint16_t capacity);
uint8_t Set_FcClear_Threshold(uint16_t capacity);
void FG_I2C_Read(uint8_t Address,uint8_t read_bytes);
void FG_I2C_Write(uint8_t Address,uint8_t write_bytes,uint8_t *data);
#endif
=============================================================== Fualguage.c ===========================================================================
#include "Nano1X2Series.h"
#include "Fualguage.h"
#define TRUE 1
#define FALSE 0
#define READ 1
#define WRITE 0
uint8_t bat_percentage;
Battery Bat_Parameter = {0};
uint8_t FG_Init = SET_BATTERY_CAPACITY,WriteExtended_Case = ENTER_CONFIG;
uint16_t FG_Timer_Flag = 0;
uint8_t newCsum = 0;
uint8_t _sealFlag = 0; // Global to identify that IC was previously sealed
uint8_t _userConfigControl = 0; // Global to identify that user has control over
// entering/exiting config
/*-----------------------------------------------------------------------------------------*/
/* Fuelguage variables */
/*-----------------------------------------------------------------------------------------*/
extern volatile I2C_FUNC s_I2C0HandlerFn;
extern volatile uint8_t address;
extern volatile uint8_t RW;
extern volatile uint8_t TxRxdata[50];
extern volatile uint8_t TxRxindex;
extern volatile uint8_t Read_Write_Bytes;
extern volatile uint8_t transfer_complete;
/*****************************************************************************
************************** Initialization Functions *************************
*****************************************************************************/
/*
@func: begin(void)
@param : none
@return val: uint8_t
@descrition:
Read BQ27441_DEVICE_ID
*/
uint8_t begin(void)
{
uint16_t deviceID = 0;
deviceID = deviceType(); // Read deviceType from BQ27441
if(deviceID == BQ27441_DEVICE_ID)
{
return TRUE; // If device ID is valid, return true
}
return FALSE; // Otherwise return false
}
/*
@func: setCapacity(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures the design capacity of the connected battery.
*/
uint8_t setCapacity(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_STATE, CAPACITY_OFFSET, capacityData, 2);
}
/*
@func: setDesign_Energy(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures the design Energy of the connected battery.
*/
uint8_t setDesign_Energy(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_STATE, DESIGN_ENERGY_OFFSET, capacityData, 2);
}
/*
@func: setTerminate_Voltage(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures the Terminate Voltage of the connected battery.
*/
uint8_t setTerminate_Voltage(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_STATE, TERMINATE_VTG_OFFSET, capacityData, 2);
}
/*
@func: setTaper_Rate(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures the Taper Rate of the connected battery.
*/
uint8_t setTaper_Rate(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_STATE, TAPERRATE_OFFSET, capacityData, 2);
}
/*
@func: setTaper_Voltage(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures the Taper Voltage of the connected battery.
*/
uint8_t setTaper_Voltage(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_STATE, TAPER_VTG_OFFSET, capacityData, 2);
}
/*
@func: setGPOUT(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures the BQ72441's GPOUT pin for interrupt
*/
uint8_t setGPOUT(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_REGISTERS, OPCONFIG_OFFSET, capacityData, 2);
}
/*
@func: Set_SOC1_Threshold(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures BQ72441's low battery's threshold percentage
*/
uint8_t Set_SOC1_Threshold(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_DISCHARGE, SOC1_OFFSET, capacityData, 1);
}
/*
@func: Set_FcSet_Threshold(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures BQ72441's low battery's threshold percentage
*/
uint8_t Set_FcSet_Threshold(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_CHG_TERMINATION, FC_SET_OFFSET, capacityData, 1);
}
/*
@func: Set_FcSet_Threshold(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures BQ72441's low battery's threshold percentage
*/
uint8_t Set_FcClear_Threshold(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_CHG_TERMINATION, FC_CLEAR_OFFSET, capacityData, 1);
}
/*
@func: Clear_SOC1_Threshold(uint16_t capacity)
@param : uint16_t
@return val: uint8_t
@descrition:
Configures BQ72441's clear threshold percentage
*/
uint8_t Clear_SOC1_Threshold(uint16_t capacity)
{
// Write to STATE subclass (82) of BQ27441 extended memory.
// Offset 0x0A (10)
// Design capacity is a 2-byte piece of data - MSB first
uint8_t capMSB;
uint8_t capLSB;
uint8_t capacityData[2] = {0};
capMSB = capacity >> 8;
capLSB = capacity & 0x00FF;
capacityData[0] = capMSB;
capacityData[1] = capLSB;
return writeExtendedData(BQ27441_ID_DISCHARGE, SOC1_CLEAR_OFFSET, capacityData, 1);
}
/*****************************************************************************
********************** Battery Characteristics Functions ********************
*****************************************************************************/
/*
@func: voltage(void)
@param : none
@return val: uint16_t
@descrition:
Reads and returns the battery voltage
*/
uint16_t voltage(void)
{
return readWord(BQ27441_COMMAND_VOLTAGE);
}
/*
@func: current(current_measure type)
@param : current_measure
@return val: int16_t
@descrition:
Reads and returns the specified current measurement
*/
int16_t current(current_measure type)
{
int16_t current = 0;
switch (type)
{
case AVG:
current = (int16_t) readWord(BQ27441_COMMAND_AVG_CURRENT);
break;
case STBY:
current = (int16_t) readWord(BQ27441_COMMAND_STDBY_CURRENT);
break;
case MAX:
current = (int16_t) readWord(BQ27441_COMMAND_MAX_CURRENT);
break;
}
return current;
}
/*
@func: capacity(capacity_measure type)
@param : capacity_measure
@return val: uint16_t
@descrition:
Reads and returns the specified capacity measurement
*/
uint16_t capacity(capacity_measure type)
{
uint16_t capacity = 0;
switch (type)
{
case REMAIN:
return readWord(BQ27441_COMMAND_REM_CAPACITY);
break;
case FULL:
return readWord(BQ27441_COMMAND_FULL_CAPACITY);
break;
case AVAIL:
capacity = readWord(BQ27441_COMMAND_NOM_CAPACITY);
break;
case AVAIL_FULL:
capacity = readWord(BQ27441_COMMAND_AVAIL_CAPACITY);
break;
case REMAIN_F:
capacity = readWord(BQ27441_COMMAND_REM_CAP_FIL);
break;
case REMAIN_UF:
capacity = readWord(BQ27441_COMMAND_REM_CAP_UNFL);
break;
case FULL_F:
capacity = readWord(BQ27441_COMMAND_FULL_CAP_FIL);
break;
case FULL_UF:
capacity = readWord(BQ27441_COMMAND_FULL_CAP_UNFL);
break;
case DESIGN:
capacity = readWord(BQ27441_EXTENDED_CAPACITY);
}
return capacity;
}
/*
@func: power(void)
@param : none
@return val: int16_t
@descrition:
Reads and returns measured average power
*/
int16_t power(void)
{
return (int16_t) readWord(BQ27441_COMMAND_AVG_POWER);
}
/*
@func: soc(soc_measure type)
@param : soc_measure
@return val: uint16_t
@descrition:
Reads and returns specified state of charge measurement
*/
uint16_t soc(soc_measure type)
{
uint16_t socRet = 0;
switch (type)
{
case FILTERED:
socRet = readWord(BQ27441_COMMAND_SOC);
break;
case UNFILTERED:
socRet = readWord(BQ27441_COMMAND_SOC_UNFL);
break;
}
return socRet;
}
/*
@func: soh(soh_measure type)
@param : soh_measure
@return val: uint8_t(State of health)
@descrition:
Reads and returns specified state of health measurement
*/
uint8_t soh(soh_measure type)
{
uint16_t sohRaw;
uint8_t sohStatus;
uint8_t sohPercent;
sohRaw = readWord(BQ27441_COMMAND_SOH);
sohStatus = sohRaw >> 8;
sohPercent = sohRaw & 0x00FF;
if (type == PERCENT)
return sohPercent;
else
return sohStatus;
}
/*
@func: temperature(temp_measure type)
@param : temp_measure
@return val: uint16_t(temperature measurement)
@descrition:
Reads and returns specified temperature measurement
*/
uint16_t temperature(temp_measure type)
{
uint16_t temp = 0;
switch (type)
{
case BATTERY:
temp = readWord(BQ27441_COMMAND_TEMP);
break;
case INTERNAL_TEMP:
temp = readWord(BQ27441_COMMAND_INT_TEMP);
break;
}
return temp;
}
/*****************************************************************************
*************************** Control Sub-Commands ****************************
*****************************************************************************/
/*
@func: deviceType(void)
@param : none
@return val: uint16_t(device type)
@descrition:
Read the device type - should be 0x0421
*/
uint16_t deviceType(void)
{
return readControlWord(BQ27441_CONTROL_DEVICE_TYPE);
}
/*
@func: enterConfig(uint8_t)
@param : uint8_t(userControl)
@return val: uint8_t
@descrition:
-- if seal then unseal
-- Enter configuration mode - Set CFGUPMODE bit in Flags()
*/
uint8_t enterConfig(uint8_t userControl)
{
int i = 0;
if (userControl) _userConfigControl = TRUE;
if (sealed())
{
#ifdef _ENABLE_PRINTF_
uint16_t stat = status();
printf("\n\rBefore Unsealed Control_STATUS :");
for(i=0x0F; i >= 0; i--)
{
printf("%d",(stat >> i) & 1);
}
#endif
unseal(); // Must be unsealed before making changes
while(status() & 0x2000)
CLK_SysTickDelay(100);
#ifdef _ENABLE_PRINTF_
stat = status();
printf("\n\rAfter Unsealed Control_STATUS :");
for(i=0x0F; i >= 0; i--)
{
printf("%d",(stat >> i) & 1);
}
#endif
}
if (executeControlWord(BQ27441_CONTROL_SET_CFGUPDATE))
{
uint16_t timeout = BQ72441_I2C_TIMEOUT;
uint16_t j = 0;
while ((timeout--) && (!(flags() & BQ27441_FLAG_CFGUPMODE)))
DELAY;
if (timeout > 0)
{
return TRUE;
}
}
return FALSE;
}
/*
@func: exitConfig(uint8_t)
@param : uint8_t(resim)
@return val: uint8_t(TRUE or FALSE)
@descrition:
-- Exit configuration mode with the option to perform a resimulation
-- There are two methods for exiting config mode:
1. Execute the EXIT_CFGUPDATE command
2. Execute the SOFT_RESET command
-- EXIT_CFGUPDATE exits config mode _without_ an OCV (open-circuit voltage)
-- measurement, and without resimulating to update unfiltered-SoC and SoC.
-- If a new OCV measurement or resimulation is desired, SOFT_RESET or
-- EXIT_RESIM should be used to exit config mode.
*/
uint8_t exitConfig(uint8_t resim)
{
if (resim)
{
if (softReset())
{
uint16_t j = 0;
CLK_SysTickDelay(7);
while (flags() & BQ27441_FLAG_CFGUPMODE)
// DELAY;
CLK_SysTickDelay(5000);
if(FG_Init == SET_SOC1_CLEAR_THRESHOLD)
{
seal(); // Seal back up if we IC was sealed coming in
while(!(status() & 0x2000))
CLK_SysTickDelay(1000);
}
return TRUE;
}
return FALSE;
}
else
{
return executeControlWord(BQ27441_CONTROL_EXIT_CFGUPDATE);
}
}
/*
@func: flags(void)
@param : none
@return val: uint16_t
@descrition:
-- Read the flags() command
*/
uint16_t flags(void)
{
return readWord(BQ27441_COMMAND_FLAGS);
}
/*
@func: status(void)
@param : none
@return val: uint16_t
@descrition:
-- Read the CONTROL_STATUS subcommand of control()
*/
uint16_t status(void)
{
return readControlWord(BQ27441_CONTROL_STATUS);
}
/*
@func: sealed(void)
@param : none
@return val: uint8_t
@descrition:
-- Check if the BQ27441-G1A is sealed or not.
*/
uint8_t sealed(void)
{
uint16_t stat = status();
int i = 0;
#ifdef _ENABLE_PRINTF_
printf("\n\rin sealed Control_STATUS :");
for(i=0x0F; i >= 0; i--)
{
printf("%d",(stat >> i) & 1);
}
printf("\n\r");
#endif
return ((stat >> 13) & 1);
}
/*
@func: seal(void)
@param : none
@return val: uint8_t
@descrition:
-- Seal the BQ27441-G1A
*/
uint8_t seal(void)
{
return readControlWord(BQ27441_CONTROL_SEALED);
}
/*
@func: unseal(void)
@param : none
@return val: uint8_t
@descrition:
-- unseal the BQ27441-G1A
*/
uint8_t unseal(void)
{
// To unseal the BQ27441, write the key to the control
// command. Then immediately write the same key to control again.
if (readControlWord(BQ27441_UNSEAL_KEY))
{
return readControlWord(BQ27441_UNSEAL_KEY);
}
return FALSE;
}
/*
@func: opConfig(void)
@param : none
@return val: uint16_t
@descrition:
-- Read the 16-bit register from extended data
*/
uint16_t opConfig(void)
{
return readWord(BQ27441_EXTENDED_OPCONFIG);
}
/*
@func: softReset(void)
@param : none
@return val: uint8_t
@descrition:
-- Issue a soft-reset to the BQ27441-G1A
*/
uint8_t softReset(void)
{
return executeControlWord(BQ27441_CONTROL_SOFT_RESET);
}
/*
@func: readWord(uint16_t subAddress)
@param : uint16_t(subAddress)
@return val: uint16_t
@descrition:
-- Read a 16-bit command word from the BQ27441-G1A
*/
uint16_t readWord(uint16_t subAddress)
{
uint8_t data[2];
// HAL_I2C_Mem_Read(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,subAddress,1,(unsigned char *)data,2,100);
FG_I2C_Read(subAddress,2);
return ((uint16_t) TxRxdata[1] << 8) | TxRxdata[0];
}
/*
@func: readControlWord(uint16_t function)
@param : uint16_t(function)
@return val: uint16_t
@descrition:
-- Read a 16-bit subcommand() from the BQ27441-G1A's control()
*/
uint16_t readControlWord(uint16_t function)
{
uint8_t subCommandMSB;
uint8_t subCommandLSB;
uint8_t command[2] = {0};
uint8_t data[2] = {0, 0};
subCommandMSB = (function >> 8);
subCommandLSB = (function & 0x00FF);
command[0] = subCommandLSB;
command[1] = subCommandMSB;
FG_I2C_Write(0,2,command);
// HAL_I2C_Mem_Write(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,(uint8_t) 0,1,command,2,100);
CLK_SysTickDelay(7);
FG_I2C_Read(0,2);
if(transfer_complete == 1)
{
// if(!(HAL_I2C_Mem_Read(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,(uint8_t)0,1,(unsigned char *)data,2,100)))
return ((uint16_t)TxRxdata[1] << 8) | TxRxdata[0];
}
return FALSE;
}
/*
@func: executeControlWord(uint16_t function)
@param : uint16_t(function)
@return val: uint8_t
@descrition:
-- Execute a subcommand() from the BQ27441-G1A's control()
*/
uint8_t executeControlWord(uint16_t function)
{
uint8_t subCommandMSB;
uint8_t subCommandLSB;
uint8_t command[2] = {0};
uint8_t data[2] = {0, 0};
subCommandMSB = (function >> 8);
subCommandLSB = (function & 0x00FF);
command[0] = subCommandLSB;
command[1] = subCommandMSB;
FG_I2C_Write(0,2,command);
if(transfer_complete == 1)
// if(!(HAL_I2C_Mem_Write(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,(uint8_t) 0,1,command,2,100)))
{
return TRUE;
}
return FALSE;
}
/*****************************************************************************
************************** Extended Data Commands ***************************
*****************************************************************************/
/*
@func: blockDataControl(void)
@param : none
@return val: uint8_t
@descrition:
-- Issue a BlockDataControl() command to enable BlockData access
*/
uint8_t blockDataControl(void)
{
uint8_t enableByte = 0x00;
FG_I2C_Write(BQ27441_EXTENDED_CONTROL,1,&enableByte);
// return (!(HAL_I2C_Mem_Write(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,BQ27441_EXTENDED_CONTROL,1,&enableByte,1,100)));
if(transfer_complete == 1)
{
return TRUE;
}
return FALSE;
}
/*
@func: blockDataClass(uint8_t id)
@param : uint8_t
@return val: uint8_t
@descrition:
-- Issue a DataClass() command to set the data class to be accessed
*/
uint8_t blockDataClass(uint8_t id)
{
FG_I2C_Write(BQ27441_EXTENDED_DATACLASS,1,&id);
// return (!(HAL_I2C_Mem_Write(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,BQ27441_EXTENDED_DATACLASS,1,&id,1,100)));
if(transfer_complete == 1)
{
return TRUE;
}
return FALSE;
}
/*
@func: blockDataOffset(uint8_t offset)
@param : uint8_t
@return val: uint8_t
@descrition:
-- Issue a DataBlock() command to set the data block to be accessed
*/
uint8_t blockDataOffset(uint8_t offset)
{
FG_I2C_Write(BQ27441_EXTENDED_DATABLOCK,1,&offset);
// return (!(HAL_I2C_Mem_Write(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,BQ27441_EXTENDED_DATABLOCK,1,&offset,1,100)));
if(transfer_complete == 1)
{
return TRUE;
}
return FALSE;
}
/*
@func: blockDataChecksum(void)
@param : none
@return val: uint8_t
@descrition:
-- Read the current checksum using BlockDataCheckSum()
*/
uint8_t blockDataChecksum(void)
{
uint8_t csum;
FG_I2C_Read(BQ27441_EXTENDED_CHECKSUM,1);
// HAL_I2C_Mem_Read(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,BQ27441_EXTENDED_CHECKSUM,1,&csum,1,100);
csum = TxRxdata[0];
return csum;
}
/*
@func: readBlockData(uint8_t offset)
@param : uint8_t
@return val: uint8_t
@descrition:
-- Use BlockData() to read a byte from the loaded extended data
*/
uint8_t readBlockData(uint8_t offset)
{
uint8_t ret;
uint8_t address = offset + BQ27441_EXTENDED_BLOCKDATA;
FG_I2C_Read(address,1);
// HAL_I2C_Mem_Read(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,address,1,&ret,1,100);
ret = TxRxdata[0];
return ret;
}
/*
@func: my_readBlockData(uint8_t offset)
@param : uint8_t
@return val: uint8_t
@descrition:
-- Use BlockData() to read a byte from the loaded extended data
*/
uint16_t my_readBlockData(uint8_t offset)
{
uint8_t ret[2] = {0};
uint8_t address = offset + BQ27441_EXTENDED_BLOCKDATA;
FG_I2C_Read(address,2);
// HAL_I2C_Mem_Read(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,address,1,ret,2,100);
return ((TxRxdata[0] << 8) | TxRxdata[1]);
}
/*
@func: writeBlockData(uint8_t offset, uint8_t data)
@param : uint8_t,uint8_t
@return val: uint8_t
@descrition:
-- Use BlockData() to write a byte to an offset of the loaded data
*/
uint8_t writeBlockData(uint8_t offset, uint8_t data)
{
uint8_t address = offset + BQ27441_EXTENDED_BLOCKDATA;
FG_I2C_Write(address,1,&data);
// return (!(HAL_I2C_Mem_Write(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,address,1,&data,1,100)));
if(transfer_complete == 1)
{
return TRUE;
}
return FALSE;
}
/*
@func: computeBlockChecksum(void)
@param : none
@return val: uint8_t
@descrition:
-- Read all 32 bytes of the loaded extended data and compute a
checksum based on the values.
*/
uint8_t computeBlockChecksum(void)
{
uint8_t data[32] = {0};
uint8_t csum = 0;
int i=0;
FG_I2C_Read(BQ27441_EXTENDED_BLOCKDATA,32);
// HAL_I2C_Mem_Read(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,BQ27441_EXTENDED_BLOCKDATA,1,data,32,100);
for (i=0; i<32; i++)
{
csum += TxRxdata[i];
}
csum = 255 - csum;
#ifdef _ENABLE_PRINTF_
printf("\r\ncsum :%d\r\n",csum);
#endif
return csum;
}
/*
@func: writeBlockChecksum(uint8_t csum)
@param : uint8_t
@return val: uint8_t
@descrition:
-- Use the BlockDataCheckSum() command to write a checksum value
*/
uint8_t writeBlockChecksum(uint8_t csum)
{
FG_I2C_Write(BQ27441_EXTENDED_CHECKSUM,1,&csum);
// return (!(HAL_I2C_Mem_Write(&Fualguage_I2C2descriptor,BQ27741_I2C_ADDRESS,BQ27441_EXTENDED_CHECKSUM,1,&csum,1,100)));
if(transfer_complete == 1)
{
return TRUE;
}
return FALSE;
}
/*
@func: readExtendedData(uint8_t classID, uint8_t offset)
@param : uint8_t,uint8_t
@return val: uint16_t
@descrition:
-- Read from extended data specifying a class ID and position offset
*/
uint16_t readExtendedData(uint8_t classID, uint8_t offset)
{
uint16_t retData = 0;
uint8_t oldCsum = 0;
if (!_userConfigControl) enterConfig(FALSE);
if (!blockDataControl()) // // enable block data memory control
return FALSE; // Return false if enable fails
CLK_SysTickDelay(200000);
if (!blockDataClass(classID)) // Write class ID using DataBlockClass()
return FALSE;
CLK_SysTickDelay(200000);
blockDataOffset(offset / 32); // Write 32-bit block offset (usually 0)
CLK_SysTickDelay(200000);
computeBlockChecksum(); // Compute checksum going in
CLK_SysTickDelay(200000);
oldCsum = blockDataChecksum();
// retData = readBlockData(offset % 32); // Read from offset (limit to 0-31)
retData = my_readBlockData(offset % 32); // Read from offset (limit to 0-31)
if (!_userConfigControl) exitConfig(TRUE);
CLK_SysTickDelay(200000);
return retData;
}
/*
@func: writeExtendedData
@param : uint8_t,uint8_t,uint8_t *,uint8_t
@return val: uint8_t
@descrition:
-- Write a specified number of bytes to extended data specifying a
class ID, position offset.
*/
uint8_t writeExtendedData(uint8_t classID, uint8_t offset, uint8_t * data, uint8_t len)
{
switch(WriteExtended_Case)
{
case ENTER_CONFIG :
{
if (len > 32)
return FALSE;
if (!_userConfigControl) enterConfig(FALSE);
if (!blockDataControl()) // // enable block data memory control
return FALSE; // Return false if enable fails
CLK_SysTickDelay(7);
if (!blockDataClass(classID)) // Write class ID using DataBlockClass()
return FALSE;
CLK_SysTickDelay(7);
blockDataOffset(offset / 32); // Write 32-bit block offset (usually 0)
FG_Timer_Flag = 0;
WriteExtended_Case = COMPUTE_BLOCK_CHKSUM;
}
break;
case COMPUTE_BLOCK_CHKSUM :
{
computeBlockChecksum(); // Compute checksum going in
FG_Timer_Flag = 0;
WriteExtended_Case = GET_CHECKSUM;
}
break;
case GET_CHECKSUM :
{
int i = 0;
uint8_t oldCsum = blockDataChecksum();
#ifdef _ENABLE_PRINTF_
printf("\n\roldCsum :%u\n\r",oldCsum);
#endif
// Write data bytes:
for (i = 0; i < len; i++)
{
// Write to offset, mod 32 if offset is greater than 32
// The blockDataOffset above sets the 32-bit block
writeBlockData((offset % 32) + i, data[i]);
CLK_SysTickDelay(7);
}
// Write new checksum using BlockDataChecksum (0x60)
newCsum = computeBlockChecksum(); // Compute the new checksum
#ifdef _ENABLE_PRINTF_
printf("\n\rnewCsum :%u\n\r",newCsum);
#endif
FG_Timer_Flag = 0;
WriteExtended_Case = WRITE_CHECKSUM;
}
break;
case WRITE_CHECKSUM:
{
writeBlockChecksum(newCsum);
if(DESIGN_ENERGY_E)
{
WriteExtended_Case = EXIT_CONFIG;
}
else
{
WriteExtended_Case = ENTER_CONFIG;
return TRUE;
}
}
break;
case EXIT_CONFIG :
{
exitConfig(TRUE);
WriteExtended_Case = ENTER_CONFIG;
return TRUE;
}
break;
} //Switch
return FALSE;
}
/*
@func: read_battery_percentage(void)
@param : none
@return val: none
@descrition:
-- read battery percentage
*/
void read_battery_percentage(void)
{
do
{
Bat_Parameter.Percentage = soc(FILTERED);
if(Bat_Parameter.Percentage <= 100)
break;
}while(Bat_Parameter.Percentage > 100);
bat_percentage =((Bat_Parameter.Percentage*100)/833);
#ifdef _ENABLE_PRINTF_
printf("Percentage : %u %\n\r",Bat_Parameter.Percentage);
#endif
}
/*
@func: Fualguage_initialize(void)
@param : none
@return val: none
@descrition:
-- Fualguage Initialization set Design Capacity,Design Energy,
Terminate Voltage and Taper Rate
*/
void Fualguage_initialize(void)
{
while(FG_Init <= SET_DESIGN_ENERGY)
{
switch(FG_Init)
{
case SET_BATTERY_CAPACITY :
{
#ifdef _ENABLE_PRINTF_
printf("\n\r-------------------in Set Design Capacity...\n\r\n\r");
#endif
if(setCapacity(BATTERY_CAPACITY))
{
FG_Init = SET_OPCONFIG;
}
}
break;
case SET_OPCONFIG :
{
#ifdef _ENABLE_PRINTF_
printf("\n\r-------------------in Set GPOUT Pin Config...\n\r\n\r");
#endif
if(setGPOUT(OPCONFIG))
FG_Init = SET_DESIGN_ENERGY;
}
break;
case SET_DESIGN_ENERGY :
{
#ifdef _ENABLE_PRINTF_
printf("\n\r-------------------in Set Design Energy...\n\r\n\r");
#endif
if(setDesign_Energy(DESIGN_ENERGY))
{
FG_Init++;
}
}
break;
} //Switch
}
// CLK_SysTickDelay(900);
// CLK_SysTickDelay(50000);
}
void Check_Battery_Chg_Dischg(void)
{
int Avg_Power = 0;
Avg_Power = power();
/* Discharging */
if(Avg_Power < 0)
{
Bat_Parameter.discharge = 1;
Bat_Parameter.charging = 0;
#ifdef _ENABLE_PRINTF_
printf("Battery is Discharging\n");
#endif
}
/* Charging */
else if(Avg_Power > 0)
{
Bat_Parameter.charging = 1;
Bat_Parameter.discharge = 0;
#ifdef _ENABLE_PRINTF_
printf("Battery is Charging\n");
#endif
}
/* Not Discharging */
else if(Avg_Power == 0)
{
Bat_Parameter.charging = 0;
Bat_Parameter.discharge = 0;
#ifdef _ENABLE_PRINTF_
printf("Battery is not Charging and not Discharging\n");
#endif
}
}
/*
@func: Fualguage_Parameter(void)
@param : none
@return val: none
@descrition:
read Fualguage parameters
- Battery Percentage
- Battery Current
- Battery Voltage
- Fualguage Design Capacity
- Fualguage Full Capacity
- Fualguage Available Capacity
*/
void Fualguage_Parameter(void)
{
uint16_t flg = 0,opcnfg = 0,Battery_Voltage = 0;
int8_t i = 0;
uint16_t stat = 0;
Bat_Parameter.Percentage = soc(FILTERED);
bat_percentage =((Bat_Parameter.Percentage*100)/833);
#ifdef _ENABLE_PRINTF_
printf("Percentage : %u %\n\r",Bat_Parameter.Percentage);
#endif
Bat_Parameter.Current = current(AVG);
if(Bat_Parameter.Current < 0)
Bat_Parameter.Current = -(Bat_Parameter.Current);
#ifdef _ENABLE_PRINTF_
printf("Current : %d mAh\n\r",Bat_Parameter.Current);
#endif
Battery_Voltage = voltage();
Bat_Parameter.Voltage = (float)Battery_Voltage/1000;
#ifdef _ENABLE_PRINTF_
printf("Voltage : %f V\n\r",Bat_Parameter.Voltage);
#endif
Bat_Parameter.Design_Capacity = capacity(DESIGN);
#ifdef _ENABLE_PRINTF_
printf("DESIGN Capacity : %u mAh\n\r",Bat_Parameter.Design_Capacity);
#endif
Bat_Parameter.Full_Capacity = capacity(FULL);
#ifdef _ENABLE_PRINTF_
printf("FULL Capacity : %u mAh\n\r",Bat_Parameter.Full_Capacity);
#endif
Bat_Parameter.Avail_Capacity = capacity(AVAIL);
#ifdef _ENABLE_PRINTF_
printf("AVAIL Capacity : %u mAh\n\r",Bat_Parameter.Avail_Capacity);
#endif
#ifdef _ENABLE_PRINTF_
flg = flags();
printf("\nFlags : ");
for(i=15;i>=0;i--)
printf("%d",(flg>>i) & 1);
printf("\n\r");
#endif
#ifdef _ENABLE_PRINTF_
stat = status();
printf("\n\rControl_STATUS :");
for(i=0x0F; i >= 0; i--)
{
printf("%d",(stat >> i) & 1);
}
printf("\n\r");
#endif
#ifdef _ENABLE_PRINTF_
opcnfg = opConfig();
printf("\nOpConfig : ");
for(i=15;i>=0;i--)
printf("%d",(opcnfg>>i) & 1);
printf("\n\r");
#endif
Check_Battery_Chg_Dischg();
}
void FG_I2C_Read(uint8_t Address,uint8_t read_bytes)
{
memset(TxRxdata,0,sizeof(TxRxdata));
TxRxindex = 0;
transfer_complete = 0;
Read_Write_Bytes = read_bytes;
address = Address;
RW = READ;
/* I2C as master sends START signal */
I2C_SET_CONTROL_REG(I2C0, I2C_STA);
while(transfer_complete == 0);
}
void FG_I2C_Write(uint8_t Address,uint8_t write_bytes,uint8_t *data)
{
uint8_t i = 0;
memset(TxRxdata,0,sizeof(TxRxdata));
for(i=0;i < write_bytes;i++)
TxRxdata[i] = data[i];
TxRxindex = 0;
transfer_complete = 0;
Read_Write_Bytes = write_bytes;
address = Address;
RW = WRITE;
/* I2C as master sends START signal */
I2C_SET_CONTROL_REG(I2C0, I2C_STA);
while(transfer_complete == 0);
}