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:
- 5:a18a189588dc
- Parent:
- 4:a4d6ae2182c2
- Child:
- 6:5ced10109ebf
diff -r a4d6ae2182c2 -r a18a189588dc max17055.cpp --- a/max17055.cpp Wed Sep 27 17:10:18 2017 +0000 +++ b/max17055.cpp Mon Oct 02 21:59:00 2017 +0000 @@ -7,7 +7,7 @@ * * Started: 11SEP17 * -* Updated: +* Updated: * * @brief Source file for MAX31855 class * @@ -47,27 +47,64 @@ #include "mbed.h" #include "max17055.h" -struct max17055_priv { - struct i2c_client *client; - struct device *dev; - struct regmap *regmap; - struct power_supply battery; - struct max17055_platform_data *pdata; - struct work_struct init_worker; - struct attribute_group *attr_grp; -}; +#define DRV_NAME "max17055" + +/* CONFIG register bits */ +#define MAX17055_CONFIG_ALRT_EN (1 << 2) +#define MAX17055_CONFIG2_LDMDL (1 << 5) + +/* STATUS register bits */ +#define MAX17055_STATUS_BST (1 << 3) +#define MAX17055_STATUS_POR (1 << 1) + +/* MODELCFG register bits */ +#define MAX17055_MODELCFG_REFRESH (1 << 15) + +/* TALRTTH register bits */ +#define MIN_TEMP_ALERT 0 +#define MAX_TEMP_ALERT 8 + +/* FSTAT register bits */ +#define MAX17055_FSTAT_DNR (1) + +/* STATUS interrupt status bits */ +#define MAX17055_STATUS_ALRT_CLR_MASK (0x88BB) +#define MAX17055_STATUS_SOC_MAX_ALRT (1 << 14) +#define MAX17055_STATUS_TEMP_MAX_ALRT (1 << 13) +#define MAX17055_STATUS_VOLT_MAX_ALRT (1 << 12) +#define MAX17055_STATUS_SOC_MIN_ALRT (1 << 10) +#define MAX17055_STATUS_TEMP_MIN_ALRT (1 << 9) +#define MAX17055_STATUS_VOLT_MIN_ALRT (1 << 8) +#define MAX17055_STATUS_CURR_MAX_ALRT (1 << 6) +#define MAX17055_STATUS_CURR_MIN_ALRT (1 << 2) + +#define MAX17055_VMAX_TOLERANCE 50 /* 50 mV */ -MAX17055::MAX17055(I2C &i2c): -m_i2cBus(i2c) +//struct battery_priv { +// struct power_supply battery; +// }; + + +MAX17055::MAX17055(I2C &i2c): + m_i2cBus(i2c) { - //empty block + //empty block } MAX17055::~MAX17055() { //empty block } + + + + + + + + + /////////////////////////////////////////////////////////////////////////////// /** @@ -84,15 +121,15 @@ int MAX17055::writeReg(Registers_e reg_addr, uint16_t reg_data) { - + uint8_t dataLSB; uint8_t dataMSB; - + dataLSB = reg_data & 0x00FF; - dataMSB = (reg_data >> 8) & 0x00FF; - + dataMSB = (reg_data >> 8) & 0x00FF; + char add_plus_data[3] = {reg_addr, dataLSB, dataMSB}; - + if ( m_i2cBus.write(I2C_W_ADRS, add_plus_data, 3, false) == 0) return 1; else @@ -120,20 +157,18 @@ char local_data[1]; local_data[0] = reg_addr; char read_data[2]; - + result = m_i2cBus.write(I2C_W_ADRS, local_data, 1); - if(result == 0) - { + if(result == 0) { result = m_i2cBus.read(I2C_R_ADRS, read_data , 2, false); - if (result == 0) - { + if (result == 0) { value = ( ((read_data[1] & 0x00FF) << 8) + (read_data[0])); result = 1; - } + } } - + return result; - + } /////////////////////////////////////////////////////////////////////////////// @@ -143,40 +178,40 @@ * This function wites and verifies if the writing process was successful * * \param[in] reg_addr - register address -* \param[out] reg_data - the variable that contains the data to write +* \param[out] reg_data - the variable that contains the data to write * to the register address * * \retval 1 on success */ -int MAX17055::write_and_verify_reg (MAX17055::Registers_e reg_addr, uint16_t reg_data) -{ +int MAX17055::write_and_verify_reg(Registers_e reg_addr, uint16_t reg_data) +{ int retries = 8; int ret; int statusRead; int statusWrite; uint16_t read_data; - + do { statusWrite = writeReg(reg_addr, reg_data); if (statusWrite != 1) ret = -1; wait_ms(3); - statusRead = readReg(reg_addr, read_data); + statusRead = readReg(reg_addr, read_data); if (statusRead != 1) ret = -2; - if (read_data != reg_data){ + if (read_data != reg_data) { ret = -3; retries--; } - }while (retries && read_data != reg_data); - - if (ret<0) - { + } while (retries && read_data != reg_data); + + if (ret<0) { return ret; - } else + } else { return 1; + } } //////////////////////////////////////////////////////////////////////////////// @@ -186,42 +221,119 @@ * \par Details * This function intitializes the MAX17055 * -* \retval 1 on success +* \retval 1 on success * 0 if device is not present * -1 if errors exist */ - - -int MAX17055::init() + + +int MAX17055::init(struct max17055_platform_data *pri) { - int status; - uint16_t read_data, hibcfg_value; - + //*batt_con = batt_info; + int status, ret; + uint16_t read_data, hibcfg_value,dpacc, reg; + + status = readReg(MAX17055_VERSION_REG, read_data); if (status == 0) return status; //Device is not present in the i2c Bus - + /* Step 0: Check for POR */ /* Skip load model if POR bit is cleared */ - + readReg(MAX17055_STATUS_REG, read_data); if (!(read_data & MAX17055_STATUS_POR ) ) - return -1; //POR is not set. Skip Initialization. + return -1; //POR is not set. Skip Initialization. /* Step 1: Check if FStat.DNR == 0 */ // Do not continue until FSTAT.DNR == 0 - - while(readReg(MAX17055_FSTAT_REG, read_data)&1) - { + + while(readReg(MAX17055_FSTAT_REG, read_data)&1) { wait_ms(10);//10 ms wait empty loop } - - /* Force exit from hibernate */ - hibcfg_value = forcedExitHyberMode(); - + + /* Force exit from hibernate */ + hibcfg_value = forcedExitHyberMode(); + + + /* Step 2: Initialize configuration */ + switch (1) { + case MODEL_LOADING_OPTION1: + /* Step 2.1: Option 1 EZ Config */ + writeReg(MAX17055_DESIGNCAP_REG, designcap); + writeReg(MAX17055_DQACC_REG, pri.designcap >> 5); + writeReg(MAX17055_ICHGTERM_REG, pri.ichgterm); + writeReg(MAX17055_VEMPTY_REG, pri.vempty); + + if (pri.vcharge > 4275) { //Need to know what this 4275 is + dpacc = (pri.designcap >> 5) * 0xC800 / pri.designcap; + writeReg(MAX17055_DPACC_REG, dpacc); + writeReg(MAX17055_MODELCFG_REG, 0x8400); //Why 0x8400 + } else { + dpacc = (pri.designcap >> 5) * 0xAC6A / pri.designcap; + writeReg(MAX17055_DPACC_REG, dpacc); + writeReg(MAX17055_MODELCFG_REG, 0x8000); + } + + /* Poll ModelCFG.ModelRefresh bit for clear */ + ret = max17055_poll_flag_clear(MAX17055_MODELCFG_REG, MAX17055_MODELCFG_REFRESH, 500); + if(ret < 0) { + //dev_err(priv->dev, "Option1 model refresh not completed!\n"); + return ret; + } + break; + } + /* Restore original HibCfg */ + writeReg(MAX17055_HIBCFG_REG, hibcfg_value); + + /* Optional step - alert threshold initialization */ + //max17055_set_alert_thresholds(priv); + + /* Clear Status.POR */ + readReg(MAX17055_STATUS_REG, reg); + write_and_verify_reg(MAX17055_STATUS_REG, (reg & ~MAX17055_STATUS_POR)); + return 1; -} +} + + +/////////////////////////////////////////////////////////////////////////////// + +/** +* \brief Poll Flag clear +* \par Details +* This function clears status flags for the MAX17055 +* +* \param[in] reg_addr - register address +* \param[in] mask - register address +* \param[in] timeout - register data +* +* \retval 1 on success +* -1 on Failure +*/ + +int max17055_poll_flag_clear(Registers_e reg_addr, int mask, int timeout) +{ + uint16_t data; + int ret; + + do { + wait(50); + ret = readReg(red_addr, data); + if(ret < 0) + return ret; + + if(!(data & mask)) + return 1; + + timeout -= 50; + } while(timeout > 0); + + return -1; +} + + //////////////////////////////////////////////////////////////////////////////// @@ -232,20 +344,20 @@ * of the MAX17055 * * \param[in] reg_addr - register address -* \param[out] reg_data - the variable that contains the data to write +* \param[out] reg_data - the variable that contains the data to write * to the register address -* \retval 1 on success -* +* \retval 1 on success +* * -1 if errors exist */ - - + + int MAX17055::get_temperature(int *temp) { - + int ret; uint16_t data; - + ret = readReg(MAX17055_TEMP_REG, data); if (ret < 0) return ret; @@ -260,7 +372,7 @@ *temp >>= 8; return 1; -} +} //////////////////////////////////////////////////////////////////////////////// @@ -268,141 +380,30 @@ /** * \brief Forced Exit Hibernate Mode Function for MAX17055 * \par Details -* This function executes a force exit from hibernate mode. +* This function executes a force exit from hibernate mode. * * \retval returns HibCFG original value before forced Exit Hybernate mode * */ - - + + uint16_t MAX17055::forcedExitHyberMode() { uint16_t hibcfg; - -/* Force exit from hibernate */ + + /* Force exit from hibernate */ //STEP 0: Store original HibCFG value readReg(MAX17055_HIBCFG_REG, hibcfg); //STEP 1: Write to Soft-Wakeup Commannd Register writeReg(MAX17055_VFSOC0_QH0_LOCK_REG, 0x90); //Soft-Wakeup from hybernate - + //STEP 2: Write to Hibernate Configuration register writeReg(MAX17055_HIBCFG_REG, 0x0); //disable hibernate mode - + //STEP 3:Write to Soft-Wakeup Commannd Register writeReg(MAX17055_VFSOC0_QH0_LOCK_REG, 0x0); //Clear All commnads - + return hibcfg; -} - -//step_1: -// // Wait until MAX17055 complete setup operations (Data is Ready) -// while(readReg(F_STAT) & 0x0001) delay(10); -// /***************************************************************/ -// // Setting up or initializing charging configurations down here , EZ CONFIG because no .INI file -// // FIXX:: DOUBLE CHECK THE INITIALIZATION VALUES -// // init values is claculated based on the register lsb's default value page 1 software implementation UG -// /* Capacity is in mAH and 1 bit is 0.5mAH)*/ -// temp = battery->capacity*2; -// writeReg(DESIGN_CAP, temp); -// writeReg(DQ_A_CC, temp/32); -// /* Current measurement, assuming current input in mA */ -// temp = battery->currentTerm*1000/1.5625; -// writeReg(ICHG_TERM, temp); -// /* FIXX: DOUBLE CHECK Vempty register (v empty | v recovery), I am assuming that -// VE resolution is 10mV and VR resolution is 40mV (programmer's guide)*/ -// temp =((battery->voltageMin/10) << 7 | (battery->voltageNom)/40); -// writeReg(V_EMPTY ,temp); -// -// data = readReg(HIB_CFG); // Store original HIB_CFG inside -// writeReg((Registers_e)0x60, 0x90); // Exit hibernate mode step 1 -// writeReg(CONFIG_2, 0x0); // Exit hibernate mode step 2 -// writeReg((Registers_e)0x60, 0x0); // Exit hibernate mode step 3 -// -// temp = battery->capacity*2; -// if (battery->voltageMax > 4.275) { -// writeReg(DP_A_CC, (temp/32)*51200/temp); // Write dPAcc -// writeReg(MODEL_CFG, 0x8400); // Write ModelCFG -// } else { -// writeReg(DP_A_CC, (temp/32)*44138/temp); -// writeReg(MODEL_CFG, 0x8000); -// } -// // Poll ModelCFG.refresh (highest bit), proceed to next step when ModelCFG.Refresh = 0. -// while(readReg(MODEL_CFG) & 0x8000) delay(10); -// writeReg(HIB_CFG, data); // Restore the original HibCFG value -// /***************************************************************/ -// } -// /***************************************************************/ -// // FIXX: DOUBLE CHECK, STEP 4 IN PROGRAMMER'S GUIDE -// data = readReg(STATUS); // read status register -// -// if (write_and_verify_reg(STATUS, data & 0xFFFD) != E_NO_ERROR) { -// return -1; -// } -// // Check whether there is saved history parameters -// temp = saved_param->rcomp0; -// temp &= saved_param ->temp_co; -// temp &= saved_param->full_cap_rep; -// temp &= saved_param->cycles; -// temp &= saved_param->full_cap_nom; -// // If there is no history setup the battery -// if (temp == 0) { -// // Check for MAX17055 reset -// StatusPOR = readReg(STATUS) & 0x0002; -// if (StatusPOR == 1) goto step_1; -// } -//step_4P3: -// // Read the reported capacity(mAH) and SOC (percentage) -// RepCap = readReg(REP_CAP); -// RepSOC = readReg(REP_SOC); -// -// // Read the TTE (in 5.625s) -// TTE_val = ((float)(readReg(TTE))) * 5.625; -// -// // Save learned parameters -// saved_param->rcomp0 = readReg(R_COMP_0); -// saved_param->temp_co = readReg(TEMP_CO); -// saved_param->full_cap_rep = readReg(FULL_CAP_REP); -// saved_param->cycles = readReg(CYCLES); -// saved_param->full_cap_nom = readReg(FULL_CAP_NOM); -// -// // Restoring Capacity Parameters -// if (write_and_verify_reg(R_COMP_0, saved_param->rcomp0) != E_NO_ERROR) { -// return -1; -// } -// if (write_and_verify_reg(TEMP_CO, saved_param->temp_co) != E_NO_ERROR) { -// return -1; -// } -// if (write_and_verify_reg(FULL_CAP_REP, saved_param->full_cap_rep) != E_NO_ERROR) { -// return -1; -// } -// -// delay(350); -// // Restore FullCap -// temp = readReg(FULL_CAP_NOM); // Read full_cap_nom -// data = (readReg(MIX_SOC)*temp)/25600; // MIXCAP -// if (write_and_verify_reg(MIX_CAP, data) != E_NO_ERROR) { -// return -1; -// } -// if (write_and_verify_reg(FULL_CAP_REP, temp) != E_NO_ERROR) { -// return -1; -// } -// data = saved_param->full_cap_nom/16; // This act as dQacc -// if (write_and_verify_reg(DP_A_CC, 0x0C80) != E_NO_ERROR) { -// return -1; -// } -// if (write_and_verify_reg(DQ_A_CC, temp) != E_NO_ERROR) { -// return -1; -// } -// -// delay(350); -// // Restore Cycles Register -// if (write_and_verify_reg(CYCLES, saved_param->cycles) != E_NO_ERROR) { -// return -1; -// } -// -//return E_NO_ERROR; -// -// -//saved_fuel_gauge_params_t default_param = {0,0,0,0,0}; \ No newline at end of file +}