This is a library for the MAX17055 Li+ Battery Fuel Gauge.
Dependents: Low_Power_Long_Distance_IR_Vision_Robot MAX17055_EZconfig MAX17055_EZconfig_Sample Low_Power_Long_Distance_IR_Vision_Robot
Fork of max17055 by
Diff: max17055.cpp
- Revision:
- 9:f29d5e49b190
- Parent:
- 8:ca8765c30ed2
- Child:
- 11:bdbd3104995b
--- a/max17055.cpp Thu Nov 02 18:11:16 2017 +0000 +++ b/max17055.cpp Tue Feb 06 21:10:30 2018 +0000 @@ -3,16 +3,17 @@ * * @author Felipe Neira - Maxim Integrated - TTS * -* @version 1.0 +* @version 1.2 * -* Started: 11SEP17 +* Started: 9JAN18 * -* Updated: +* Updated: +* New functions improved for continious display. Change copyright notice for 2018. +* +* * -* @brief Source file for MAX31855 class -* -******************************************************************************** -* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +/******************************************************************************* +* Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -41,8 +42,8 @@ * trademarks, maskwork rights, or any other form of intellectual * property whatsoever. Maxim Integrated Products, Inc. retains all * ownership rights. -* -******************************************************************************/ +******************************************************************************* +*/ #include "mbed.h" #include "max17055.h" @@ -57,6 +58,9 @@ #define MAX17055_STATUS_BST (1 << 3) #define MAX17055_STATUS_POR (1 << 1) +/* POR Mask */ +#define MAX17055_POR_MASK (0xFFFD) + /* MODELCFG register bits */ #define MAX17055_MODELCFG_REFRESH (1 << 15) @@ -213,6 +217,7 @@ * \retval 1 on success * 0 if device is not present * -1 if errors exist +* -2 if POR is not set */ @@ -220,6 +225,7 @@ { int status, ret; + int time_out = 10; uint16_t read_data, hibcfg_value, reg; @@ -230,26 +236,21 @@ /* Step 0: Check for POR */ /* Skip load model if POR bit is cleared */ - readReg(STATUS_REG, read_data); - - if (!(read_data & MAX17055_STATUS_POR ) ) - return -1; //POR is not set. Skip Initialization. + if (check_POR_func() == -1) + return -2; //POR is not set. Skip Initialization. /* Step 1: Check if FStat.DNR == 0 */ // Do not continue until FSTAT.DNR == 0 - printf("step 0 check \r\n"); - - int time_out = 500; ret = poll_flag_clear(FSTAT_REG, MAX17055_FSTAT_DNR, time_out); if (ret < 0) { - printf("Unsuccessful init: Data Not Ready!\n"); + //printf("Unsuccessful init: Data Not Ready!\n"); return ret; } /* Force exit from hibernate */ hibcfg_value = forcedExitHyberMode(); - printf("step 1 check \r\n"); + //printf("step 1 check \r\n"); /* Step 2: Initialize configuration */ switch (1) { @@ -258,30 +259,78 @@ EZconfig_init(des_data); /* Poll ModelCFG.ModelRefresh bit for clear */ - int time_out = 500; //msec ret = poll_flag_clear(MODELCFG_REG, MAX17055_MODELCFG_REFRESH, time_out); if(ret < 0) { //dev_err(priv->dev, "Option1 model refresh not completed!\n"); return ret; } - break; + break; } /* Restore original HibCfg */ writeReg(HIBCFG_REG, hibcfg_value); - printf("Last section check \r\n"); + //printf("Last section check \r\n"); /* Optional step - alert threshold initialization */ //set_alert_thresholds(priv); /* Clear Status.POR */ - readReg(STATUS_REG, reg); - write_and_verify_reg(STATUS_REG, (reg & ~MAX17055_STATUS_POR)); - + ret = clear_POR_bit(); + if (ret == -1) + return ret; return 1; } +//////////////////////////////////////////////////////////////////////////////// + +/** +* \brief Check POR function +* \par Details +* This function check is there was a power on reset event for the MAX17055 +* +* \retval 1 for no POR detected +* -1 for POR detected +*/ +int MAX17055::check_POR_func() +{ + uint16_t read_data; + + readReg(STATUS_REG, read_data); + + if (!(read_data & MAX17055_STATUS_POR ) ) + return -1; //POR is not set. + else + return 1; +} + +//////////////////////////////////////////////////////////////////////////////// + +/** +* \brief clear POR bit function +* \par Details +* This function clear the idicating bit for POR - MAX17055 +* +* \retval 1 for Success +* -1 for errors +*/ +int MAX17055::clear_POR_bit() +{ + int status, ret; + uint16_t read_data, hibcfg_value, reg; + + + status = readReg(STATUS_REG, read_data); + if (status != 1) + return -1; //Device is not present in the i2c Bus + status = write_and_verify_reg(STATUS_REG, (read_data & MAX17055_POR_MASK)); + if (status != 1) + return -1; + else + return 1; + + +} /////////////////////////////////////////////////////////////////////////////// @@ -303,8 +352,9 @@ uint16_t data; int ret; + do { - wait_ms(10); + wait_ms(1); ret = readReg(reg_addr, data); if(ret < 0) return ret; @@ -312,7 +362,7 @@ if(!(data & mask)) return 1; - timeout -= 10; + timeout -= 1; } while(timeout > 0); return -1; @@ -396,7 +446,7 @@ * \par Details * This function implements the steps for the EZ confing m5 FuelGauge * -* \retval returns TBD +* \retval 1 on success * */ @@ -412,19 +462,19 @@ /* Step 2.1: Option 1 EZ Config */ - writeReg(DESIGNCAP_REG, des_data.designcap); - writeReg(DQACC_REG, des_data.designcap >> 5); - writeReg(ICHGTERM_REG, des_data.ichgterm); - writeReg(VEMPTY_REG, des_data.vempty); + ret = writeReg(DESIGNCAP_REG, des_data.designcap); + ret = writeReg(DQACC_REG, des_data.designcap >> 5); //DesignCap divide by 32 + ret = writeReg(ICHGTERM_REG, des_data.ichgterm); + ret = writeReg(VEMPTY_REG, des_data.vempty); if (des_data.vcharge > charger_th) { dpacc = (des_data.designcap >> 5) * chg_V_high / des_data.designcap; - writeReg(DPACC_REG, dpacc); - writeReg(MODELCFG_REG, param_EZ_FG1); //Why 0x8400 + ret = writeReg(DPACC_REG, dpacc); + ret = writeReg(MODELCFG_REG, param_EZ_FG1); //Why 0x8400?? } else { dpacc = (des_data.designcap >> 5) * chg_V_low / des_data.designcap; - writeReg(DPACC_REG, dpacc); - writeReg(MODELCFG_REG, param_EZ_FG2); + ret = writeReg(DPACC_REG, dpacc); + ret = writeReg(MODELCFG_REG, param_EZ_FG2); } @@ -494,6 +544,36 @@ return data; } +//////////////////////////////////////////////////////////////////////////////// + +/** +* \brief Get State Of Charge(SOC) Function for MAX17055 +* \par Details +* This function sends a request to access the internal +* of the MAX17055 +* +* \param[in] reg_addr - register address +* \param[out] reg_data - SOC data from the REPSOC_REG register +* \retval 1 on success +* +* -1 if errors exist +*/ + + +int MAX17055::get_mixSOC() +{ + + int ret; + uint16_t data; + + ret = readReg(MIXSOC_REG, data); + if (ret < 0) + return ret; + + data = data >> 8; /* RepSOC LSB: 1/256 % */ + + return data; +} /////////////////////////////////////////////////////////////////////////////// /** @@ -507,13 +587,13 @@ * -1 if errors exist */ -int MAX17055::get_TTE() +int MAX17055::get_atTTE() { int ret; uint16_t data; - ret = readReg(TTE_REG, data); + ret = readReg(ATTTE_REG, data); if (ret < 0) return ret; else @@ -689,4 +769,109 @@ res *= 1562500 /(rsense_value * 1000); //Change to interact with the rsense of customer } return res; +} + +/////////////////////////////////////////////////////////////////////////////// + +/** +* \brief Save Learned Parameters Function +* \par Details +* It is recommended to save the learned capacity parameters every +* time bit 2 of the Cycles register toggles +* (so that it is saved every 64% change in the battery) +* so that if power is lost the values can easily be restored. +* +* \retval ret int -1 if fail +* +*/ + +int MAX17055::save_Params(saved_FG_params_t FG_params) +{ + int ret; + uint16_t data[5]; + ret = readReg(RCOMP0_REG, data[0]); + if (ret < 0) + return ret; + else + FG_params.rcomp0 = data[0]; + + ret = readReg(TEMPCO_REG, data[1]); + if (ret < 0) + return ret; + else + FG_params.temp_co = data[1]; + + ret = readReg(FULLCAPREP_REG, data[2]); + if (ret < 0) + return ret; + else + FG_params.full_cap_rep = data[2]; + + ret = readReg(CYCLES_REG, data[3]); + if (ret < 0) + return ret; + else + FG_params.cycles = data[3]; + + ret = readReg(FULLCAPNOM_REG, data[4]); + if (ret < 0) + return ret; + else + FG_params.full_cap_nom = data[4]; + return ret; +} + +/////////////////////////////////////////////////////////////////////////////// + +/** +* \brief Resotore Parameters Function +* \par Details +* If power is lost, then the capacity information +* can be easily restored with this function +* +* \param[in] struct saved_FG_params_t +* \retval void +* +*/ + +int MAX17055::restore_Params(saved_FG_params_t FG_params) +{ + int ret; + uint16_t temp_data, fullcapnom_data, mixCap_calc, dQacc_calc; + uint16_t dPacc_value = 0x0C80;//Why this vcalue? + + //Restoring capacity parameters + write_and_verify_reg(RCOMP0_REG, FG_params.rcomp0); + write_and_verify_reg(TEMPCO_REG, FG_params.temp_co); + write_and_verify_reg(FULLCAPNOM_REG, FG_params.full_cap_nom); + + wait_ms(350); + //Restore FullCap + + ret = readReg(FULLCAPNOM_REG, fullcapnom_data); + if (ret < 0) + return ret; + + ret = readReg(MIXSOC_REG, temp_data); //check if Error in sofware guide register incorrect + if (ret < 0) + return ret; + + mixCap_calc = (temp_data*fullcapnom_data)/25600; + + write_and_verify_reg(MIXCAP_REG, mixCap_calc); + write_and_verify_reg(FULLCAPREP_REG, FG_params.full_cap_rep); + + //Write DQACC to 200% of Capacity and DPACC to 200% + dQacc_calc = (FG_params.full_cap_nom/ 16) ; + + write_and_verify_reg(DPACC_REG, dPacc_value); + write_and_verify_reg(DQACC_REG, dQacc_calc); + + wait_ms(350); + + //Restore Cycles register + ret = write_and_verify_reg(CYCLES_REG, FG_params.cycles); + if (ret < 0) + return ret; +return ret; } \ No newline at end of file