Quantcast
Channel: Power management forum - Recent Threads
Viewing all 35901 articles
Browse latest View live

BQ78350-R1: Do I need an additional charge chip or can I use this IC to charge the battery?

$
0
0

Part Number:BQ78350-R1

Hello,

Im want to connect the BQ78350 to the BQ76920, this should work fine, as the datasheet is telling me.

Now, I am thinking how I want to charge the battery. Im wondering, if I need another IC to charge the battery or if the BQ78350

wil do this by itself. In the datasheet of the BQ78350-R1 there is no pin where I can put the adapter current in. So I am thinking,

to use the BQ24617 for the charging process.

In this case all the charging configurations would be done with the BQ24617. (configuring the precharge-current, charge-current etc.)

What is your opinion about this? Would this work?


BQ27510-G3: bqStudio - Automate the disharge - Learning cycle

$
0
0

Part Number:BQ27510-G3

Hello,

In the past we did a golden image with bqeasy and the Learning Cycle.

As the new chemestry is not known with bqeasy, i should do the golden image with bqstudio.

The gauge is bq27510-g3

With bqeasy, there is a sequence for "5A - Learning Cycle". I can't find it with bqStudio

With bqstudio, i can't find button to automate the discharge. with bqeasy, i use a relay conected to HDQ ouput of the EV2300 and press the button "OR - Automate the discharge and wait".

Where is the sequence for Learning cycle with bqStudio ?

Can we do a automated Learning cycle with bqstudio and automate the discharge ?

Or should i do it manually ?

Thanks

Stéphane

RE: BQ76940 high side sense resistor

$
0
0
Dear WM5295,
I use two bq76940 for 30cells~
Now I want to know if the Rsns resistance can be put on the PACK+ side?

BQ27541 RSOC and FCC change to 0 in the low temperature -20 degree

$
0
0

The battery is full charger in the normal temperature,but in the low temperature -20 degree BQ27541 RSOC and FCC jump to 0.

whether I do chemic ID in low temperature -20 degree,the problem can have improved?

If the gold image also do in the  -20 degree?

BQ20Z75: BQ20z75 software

$
0
0

Part Number:BQ20Z75

Hi. We want to produce a small BMS with chips Bq20z75. With what program we can configure and customize? The list of supported chips BqStudio they are not.

BQ27750EVM-837: ic not automatically detected, update firmware

$
0
0

Part Number:BQ27750EVM-837

Hi I have installed battery management software. I have BQ27750EVM-837 and EVM2400.

My bqStudio is not able to automatically detect IC. The .ghz file was also not there but I have now downloaded and placed it in config folder.

What should I do to update the firmware and where can I find and place the .srec file?

Thanks for your help.

BQ27320: changing battery pack to new one

$
0
0

Part Number:BQ27320

Hi Team,

My customer considers to use BQ27320 (CEDV) for their application that is system-side configuration.
 I understood programming golden file is required at production timing.

Is it required to re-program the same golden file after changing battery pack to new one if the battery degradation is occured by long usage?

Best Regards,
Yaita / Japan disty

BQ27320: Table 3. Key Data Flash Parameters for Configuration


BQ27441EVM-G1A: Can't Update Battery Percentage,Current and charging discharging status

$
0
0

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);
}

BQ27621-G1: How to enable SOC smoothing

$
0
0

Part Number:BQ27621-G1

Hello,

I'm very new with this device. I read a lot of documentation, but did not understand how can I enable the SOC smoothing (I need it, because when I start to charge, the SOC value jumps to the very high value, from 68% to 91%.)

Could you please explain me the full algorithm for the setting of this flag?

Thank you very much!

BQ34110EVM-796: Device not acknowledged and in the same time battery discharged by some 30mA in open load.

$
0
0

Part Number:BQ34110EVM-796

Hi, 

I had purchased BQ34110EVM few weeks back, and started testing it. At the first attempt, i was able to detect my device and configure it according to my setup. (FYI: i have a 3S cell configuration of Li ion, communication through EV2300) Things were fine at first, and I was able to discharge my battery through my load at 2.8A too. 

After a small break, when I restarted my setup, I was not able to detect my device anymore! and I also noticed that the BMS was consuming some 30mA from the battery pack, without a load connected across it. I am not able to establish any communication with my device anymore. 

Is my device dead?

how do i check the vitals?

Thanks for the help in advanced. 

BQ34110EVM-796: Hi,

$
0
0

Part Number:BQ34110EVM-796

Hi,

Please give me an answer to my queries.

Determining Remaining Capacity in bq34110 for NiMh 10 cells battery?

Determining  time to empty and time to full?

Remaining capacity in bq studio for bq34110  using NiMH 10 cell battery does not seem to show the right value while charging and discharging. The gauge is calibrated  for voltage current and temperature and we have got the cedv coefficients for calculating the EDV values by successfully logging for different rates and temperature.

Initially it did show the right values for RC  while charging, but eventually we had disconnected the battery from gauge and then reconnected and the Remaining capacity value had gone to zero we have  left the battery connected to the gauge in charging and now we see RC value is slowly increasing, Time to full is slowly increasing from 0 to. 5764 and the time to empty is showing default value 65535.

I am not sure if this is how the gauging values of the fuel gauge look like while determining RC, what I assumed was gauge will be able to determine the RC as soon as we connect battery to the fuel gauge.

Similarly, after entering the values from the GPC calculator,  cedv parameters, the next step is to perform a qualifying discharge at 3C/32 current could you please confirm.

Regards,

Jofina Jijin

BQ27621-G1: How to check if battery is charging or not

$
0
0

Part Number:BQ27621-G1

Hello,

I try to check if the battery is charging or not, but I don't see any flag that tells it.

I tried to check flags on the device, but with/without connected charger it's returns 0x0108 (it's after initialization, at the working mode)

Could you please help me?

Thank you very much!

BQ34Z100-G1: Communication logic not in common GND?

$
0
0

Part Number:BQ34Z100-G1

Hello there,

I am currently designing a board featuring the bq34z100-G1 device. Looking at the application note I am hacing some doubts either I understand everything correctly. Please take a look at the bellow figure from the datsheet:

As you can see above, the device GND will not be equal to the other circuitry GND connected through PACK+ and PACK-. In means of communication through I2C can cause trouble, since the external driver will pull to its own GND, and BQ will pull to the local one. The difference between grounds would be the voltage drop across R_sense.

Is this by design? I would really appreciate additional explanation, I need to move on with the design.

How to connect fuel gauge(BQ34Z100-G1,BQ34110,BQ78350-R1)to PC and how to make it work


BQ27441EVM-G1A: GPC Tool for keeps hanging

$
0
0

Part Number:BQ27441EVM-G1A

I'm attempting to get a ChemID for the battery that we are using. I've collected the data and organized it as per instructions outlined in this pdf: http://www.ti.com/lit/ug/sluub45a/sluub45a.pdf . Data was collected using the bqStudio logging feature in conjunction wih the BQ27441 evaluation module. After collecting over 23 hours worth of data, I've submitted the data to the online GPC tool (http://www.ti.com/tool/gpcchem); however, within 10 minutes I get an email saying that "The Calculation Engine appeared to have hung, so it was killed." !! 

Is there something wrong in my data to may have killed the calculation engine? I would NOT like to redo the test as it took a large amount of time and our team needs an answer on whether or not the BQ27441 would work with out system and battery very soon.

I've attached the zip file that I used to upload to the GPC tool.(Please visit the site to view this file)

I'm attempting to get a ChemID for the battery that we are using. I've collected the data and organized it as per instructions outlined in this pdf: http://www.ti.com/lit/ug/sluub45a/sluub45a.pdf . Data was collected using the bqStudio logging feature. After collecting over 23 hours worth of data, I've submitted the data to the online GPC tool (http://www.ti.com/tool/gpcchem

BQ78350-R1: If I want to charge the battery with the charging parameters from the BQ78350: Must I connect BQstudio to the system every time I want to charge the battery to provide charging parameters to the charging-IC?

$
0
0

Part Number:BQ78350-R1

Hello,

I want to charge my battery with the charging parameters from the BQ78350. I can configurate this parameters with BQSTUDIO. During the charge-configuration the BQ78350 is connected to the software (to the PC).

The charging parameters will be saved in the BQ78350. So, everytime I want to charge the battery, the BQ78350 knows, what the charging paramters are.

This means: I have to configurate the charging parameters to the BQ78350 only once. Every other time, when I want to charge, the BQ78350 will already know, with which values (charging-current, charging-voltage, pre-charge-current and so on) the IC should provide the informations to the charging IC.

So BQSTUDIO dont have to be connected everytime I want to charge

Is the way Im thinking correct?

BQ27441EVM-G1A: Regarding ChemID

$
0
0

Part Number:BQ27441EVM-G1A

We are using the BQ27441 fuel gauge and while looking through the technical reference manual, it states that the default ChemID for the BQ27441-G1A is 0x0128. I verified this through bqStudio. The technical reference also mentions also mentions a ChemID of 0x1202 is also used as the default battery profile (secton 6.4.2.3.13 Voltage at Charge Termination). Is there a difference between the two ChemID's? If I would like to use the ChemID 1202, am I able to select that option for the BQ27441 fuel gauge? 

Thanks,

William

BQ20Z95: Output voltage does not match cell voltage

$
0
0

Part Number:BQ20Z95

Hi all, I am new to the forums and to gas gauging.  I have a laptop battery pack (For an MSI 2PC Dominator), the model number of the pack is BTY-M6D.  A while ago, my battery pack died, and I thought it would be a good learning experience to try to rebuild it with new cells.  (I bought a new pack for cheap, this is more of an experiment than anything else).  Since then, I've installed the new cells and setup all of the hardware the way that it was previously set up.  Using an EV2400, I have access to the bq20z95.  According to the bqEVSW, the chip is working fine (although in the course of my trouble shooting I completely reset it, and had to use bqEASY to set it back up).  I also have full access due to the manufacturer not changing the Unseal key. 

The problem is, I only get about 10% of the output voltage I expect.  The cells are fully charged and are producing 11.9V, but I only get about 1.2V on the Pack+ and Pack- pins.  This is a problem, as the laptop cannot boot with that small of a voltage.

I suspect the issue is a hardware problem, possibly a blown FET.  I'm hoping someone can help me to either confirm or deny this and to explore next steps in getting this device back up and running.  

Thanks for your help in advance!

BQSTUDIO: Chemistry ID

$
0
0

Part Number:BQSTUDIO

To whom it may concern:

We are using LG18650HD2C cell, with BQ40z50-R1. There is no chemistry file for this cell, so could you help to characterize this cell?

Thanks!

Chen

Viewing all 35901 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>