Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Low_Power_Long_Distance_IR_Vision_Robot MAX17055_EZconfig MAX17055_EZconfig_Sample Low_Power_Long_Distance_IR_Vision_Robot
Fork of max17055 by
max17055.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 ******************************************************************************* 00032 */ 00033 00034 #include "mbed.h" 00035 #include "max17055.h" 00036 00037 /* POR Mask */ 00038 #define MAX17055_POR_MASK (0xFFFD) 00039 #define MAX17055_CYCLE_MASK (0x0002) 00040 00041 00042 /* MODELCFG register bits */ 00043 #define MAX17055_MODELCFG_REFRESH (1 << 15) 00044 00045 00046 /* FSTAT register bits */ 00047 #define MAX17055_FSTAT_DNR (1) 00048 00049 /* LIBRARY FUNCTION SUCCESS*/ 00050 #define F_SUCCESS_0 0 00051 00052 /* LIBRARY FUNCTION ERROR CODES */ 00053 #define F_ERROR_1 -1 //-1 if I2C read/write errors exist 00054 #define F_ERROR_2 -2 //-2 if device is not present 00055 #define F_ERROR_3 -3 //-3 if function error 00056 #define F_ERROR_4 -4 //-4 if other error 00057 #define F_ERROR_5 -5 //-5 if POR not detected 00058 00059 00060 00061 /** 00062 * @brief max17055 Constructor 00063 * @details max17055 Constructor with battery and i2c as parameters 00064 */ 00065 MAX17055::MAX17055(I2C &i2c): 00066 m_i2cBus(i2c) 00067 { 00068 //empty block 00069 } 00070 00071 /** 00072 * @brief Fuel Gauge Destructor 00073 */ 00074 MAX17055::~MAX17055() 00075 { 00076 //empty block 00077 } 00078 00079 /** 00080 * @brief Writes a register. 00081 * 00082 * @param[in] reg_addr The register address 00083 * @param[in] reg_data The register data 00084 * 00085 * @retval 0 on success 00086 * @retval non-0 for errors 00087 */ 00088 int MAX17055::writeReg(Registers_e reg_addr, uint16_t reg_data) 00089 { 00090 00091 uint16_t mask = 0x00FF; 00092 uint8_t dataLSB; 00093 uint8_t dataMSB; 00094 00095 dataLSB = reg_data & mask; 00096 dataMSB = (reg_data >> 8) & mask; 00097 00098 char addr_plus_data[3] = {reg_addr, dataLSB, dataMSB}; 00099 00100 if ( m_i2cBus.write(I2C_W_ADRS, addr_plus_data, 3, false) == F_SUCCESS_0) 00101 return F_SUCCESS_0; 00102 else 00103 return F_ERROR_1; 00104 } 00105 00106 /** 00107 * @brief Reads from MAX17055 register. 00108 * 00109 * @param[in] reg_addr The register address 00110 * @param value The value 00111 * 00112 * @retval 0 on success 00113 * @retval non-0 for errors 00114 */ 00115 int32_t MAX17055::readReg(Registers_e reg_addr, uint16_t &value) 00116 { 00117 int32_t result; 00118 uint16_t mask = 0x00FF; 00119 char local_data[1]; 00120 local_data[0] = reg_addr; 00121 char read_data[2]; 00122 00123 result = m_i2cBus.write(I2C_W_ADRS, local_data, 1); 00124 if(result == F_SUCCESS_0) { 00125 result = m_i2cBus.read(I2C_R_ADRS, read_data , 2, false); 00126 if (result == F_SUCCESS_0) { 00127 value = ( ((read_data[1] & mask) << 8) + (read_data[0])); 00128 result = F_SUCCESS_0; 00129 } 00130 } 00131 return result; 00132 } 00133 00134 /** 00135 * @brief Reads an specified register from the MAX17055 register. 00136 * 00137 * @param[in] reg_addr The register address 00138 * @param value The value 00139 * 00140 * @retval reg_data register data 00141 * @retval statusRead non-0 for errors 00142 */ 00143 00144 int16_t MAX17055::get_regInfo(Registers_e reg_addr) 00145 { 00146 uint16_t read_data; 00147 int statusRead; 00148 00149 statusRead = readReg(reg_addr, read_data); 00150 if (statusRead != F_SUCCESS_0) 00151 return statusRead; 00152 else 00153 return read_data; 00154 00155 } 00156 00157 /** 00158 * @brief Write and Verify a MAX17055 register 00159 * @par Details 00160 * This function writes and verifies if the writing process was successful 00161 * 00162 * @param[in] reg_addr - register address 00163 * @param[out] reg_data - the variable that contains the data to write 00164 * to the register address 00165 * 00166 * @retval 0 on success 00167 * @retval non-0 for errors 00168 */ 00169 int MAX17055::write_and_verify_reg(Registers_e reg_addr, uint16_t reg_data2write) 00170 { 00171 int retries = 0; 00172 int ret; 00173 int statusRead; 00174 int statusWrite; 00175 uint16_t read_data; 00176 00177 00178 do { 00179 statusWrite = writeReg(reg_addr, reg_data2write); 00180 if (statusWrite != F_SUCCESS_0) 00181 return F_ERROR_1; 00182 wait_ms(1); 00183 statusRead = readReg(reg_addr, read_data); 00184 if (statusRead != F_SUCCESS_0) 00185 return F_ERROR_1; 00186 } while (reg_data2write != read_data && retries++<3); 00187 00188 return F_SUCCESS_0; 00189 } 00190 00191 /** 00192 * @brief Initialization Function for MAX17055. 00193 * @par Details 00194 * This function initializes the MAX17055 for the implementation of the EZconfig model.\n 00195 * The library needs to be customized for the implementation of customize model.\n 00196 * 00197 * @retval 0 on success 00198 * @retval non-0 for errors 00199 */ 00200 int MAX17055::init(platform_data des_data) 00201 { 00202 00203 int ret; 00204 int time_out = 10; 00205 int32_t status; 00206 uint16_t hibcfg_value; 00207 uint16_t read_data; 00208 00209 00210 status = readReg(VERSION_REG , read_data); 00211 if (status != F_SUCCESS_0) 00212 return status; 00213 00214 ///STEP 0. Check for POR (Skip load model if POR bit is cleared) 00215 00216 if (check_POR_func() == F_ERROR_5) 00217 return F_ERROR_5; //POR not detected. Skip Initialization. 00218 00219 ///STEP 1. Check if FStat.DNR == 0 (Do not continue until FSTAT.DNR == 0) 00220 ret = poll_flag_clear(FSTAT_REG , MAX17055_FSTAT_DNR, time_out); 00221 if (ret < F_SUCCESS_0) { 00222 return ret; 00223 } 00224 00225 ///STEP 1.2. Force exit from hibernate 00226 hibcfg_value = forcedExitHiberMode(); 00227 00228 00229 ///STEP 2. Initialize configuration 00230 ///STEP 2.1. Load EZ Config 00231 EZconfig(des_data); 00232 00233 ///STEP 2.2. Poll ModelCFG.ModelRefresh bit for clear 00234 ret = poll_flag_clear(MODELCFG_REG , MAX17055_MODELCFG_REFRESH, time_out); 00235 if(ret < F_SUCCESS_0) { 00236 return ret; 00237 } 00238 ///STEP3. Restore original HibCfg 00239 writeReg(HIBCFG_REG , hibcfg_value); 00240 00241 00242 /* Clear Status.POR */ 00243 ret = clear_POR_bit(); 00244 if (ret < F_SUCCESS_0) 00245 return ret; //See errors 00246 return F_SUCCESS_0; 00247 00248 } 00249 00250 /** 00251 * @brief Check POR function 00252 * @par Details 00253 * This function check is there was a power on reset event for the 00254 * MAX17055 00255 * 00256 * @retval 0 on success (POR detected) 00257 * @retval non-0 for errors (POR not detected) 00258 * 00259 */ 00260 int MAX17055::check_POR_func() 00261 { 00262 uint16_t read_data; 00263 00264 readReg(STATUS_REG , read_data); 00265 // printf("STATUS REF = %X \r\n", read_data); 00266 if (!(read_data & MAX17055_STATUS_POR ) ) { 00267 return F_ERROR_5; //POR not detected. 00268 } else 00269 return F_SUCCESS_0; 00270 } 00271 00272 /** 00273 * @brief clear POR bit function 00274 * @par Details 00275 * This function clear the indicating bit for POR - MAX17055 00276 * 00277 * @retval 0 for Success 00278 * @retval non-0 for errors 00279 */ 00280 int MAX17055::clear_POR_bit() 00281 { 00282 int status; 00283 uint16_t read_data; 00284 00285 00286 status = readReg(STATUS_REG , read_data); 00287 if (status != F_SUCCESS_0) 00288 return F_ERROR_2; //Device is not present in the i2c Bus 00289 status = write_and_verify_reg(STATUS_REG , (read_data & MAX17055_POR_MASK)); 00290 if (status != F_SUCCESS_0) 00291 return F_ERROR_1; //read or write error 00292 else 00293 return F_SUCCESS_0; 00294 } 00295 00296 /** 00297 * @brief Poll Flag clear Function. 00298 * @par Details 00299 * This function clears status flags for the MAX17055 00300 * 00301 * @param[in] reg_addr - register address 00302 * @param[in] mask - register address 00303 * @param[in] timeout - register data 00304 * 00305 * @retval 0 on success 00306 * @retval non-0 negative for errors 00307 */ 00308 int MAX17055::poll_flag_clear (Registers_e reg_addr, int mask, int timeout) 00309 { 00310 uint16_t data; 00311 int ret; 00312 00313 do { 00314 wait_ms(50); 00315 ret = readReg(reg_addr, data); 00316 // printf("read reg %X\r\n", data); 00317 // printf("mask %X\r\n", mask); 00318 if(ret < F_SUCCESS_0) 00319 return F_ERROR_1; 00320 00321 00322 if(!(data & mask)) 00323 return F_SUCCESS_0; 00324 00325 timeout -= 1; 00326 // printf("end timeout %d \r\n", timeout); 00327 } while(timeout > 0); 00328 00329 return F_ERROR_4; 00330 } 00331 00332 /** 00333 * @brief Get Temperature Function from the MAX17055 TEMP register. 00334 * @par Details 00335 * This function sends a request to access the TEMP register 00336 * of the MAX17055, which reflects the temperature measured for the fuel gauge. 00337 * The temperature values will reflect the Config Register (0x1D) selections for Tsel bit (D15). 00338 * For this library the setting are for die temperature. 00339 * The MAX32620FTHR thermistor bias pin is not connected. The biasing of the thermistor is 00340 * done by the MAX77650. See MAX77650 library for how to enable the thermistor biasing. 00341 * 00342 * 00343 * @retval temp - Temperature value from TEMP register in °C 00344 * @retval non-0 negative values check for errors 00345 */ 00346 int MAX17055::get_temperature() 00347 { 00348 00349 int ret; 00350 uint16_t temp; 00351 00352 ret = readReg(TEMP_REG , temp); 00353 if (ret < F_SUCCESS_0) 00354 return ret; 00355 00356 /* The value is signed. */ 00357 if (temp & 0x8000) 00358 temp |= 0xFFFF0000; 00359 00360 /* The value is converted into centigrade scale */ 00361 /* Units of LSB = 1 / 256 degree Celsius */ 00362 temp >>= 8; 00363 00364 return temp; 00365 } 00366 00367 /** 00368 * @brief Forced Exit Hibernate Mode Function for MAX17055 00369 * @par Details 00370 * This function executes a force exit from hibernate mode. 00371 * 00372 * @retval HibCFG original value before forced Exit Hibernate mode * 00373 */ 00374 uint16_t MAX17055::forcedExitHiberMode() 00375 { 00376 uint16_t hibcfg; 00377 00378 /* Force exit from hibernate */ 00379 //STEP 0: Store original HibCFG value 00380 readReg(HIBCFG_REG , hibcfg); 00381 00382 //STEP 1: Write to Soft-Wakeup Command Register 00383 writeReg(VFSOC0_QH0_LOCK_REG , 0x90); //Soft-Wakeup from hibernate 00384 00385 //STEP 2: Write to Hibernate Configuration register 00386 writeReg(HIBCFG_REG , 0x0); //disable hibernate mode 00387 00388 //STEP 3:Write to Soft-Wakeup Command Register 00389 writeReg(VFSOC0_QH0_LOCK_REG , 0x0); //Clear All commands 00390 00391 return hibcfg; 00392 } 00393 00394 /** 00395 * @brief EZ Config function 00396 * @par Details 00397 * This function implements the steps for the EZ config m5 FuelGauge 00398 * @param[in] des_data - Plataform_data struct with information about the design. 00399 * @retval 0 on success 00400 * @retval non-zero for errors 00401 */ 00402 uint16_t MAX17055::EZconfig(platform_data des_data) 00403 { 00404 ///STEP 2.1.1 EZ config values suggested by manufacturer. 00405 const int charger_th = 4275; 00406 const int chg_V_high = 51200; // scaling factor high voltage charger 00407 const int chg_V_low = 44138; 00408 const int param_EZ_FG1 = 0x8400; // Sets config bit for the charge voltage for the m5 00409 const int param_EZ_FG2 = 0x8000; 00410 uint16_t dpacc, ret; 00411 const int DIV_32 = 5;//DesignCap divide by 32 for EZ config 00412 const int DIV_16 = 4;//DesignCap divide by 16 only for custom ini files 00413 00414 ///STEP 2.1.2 Store the EZ Config values into the appropriate registers. 00415 ret = writeReg(DESIGNCAP_REG , des_data.designcap ); 00416 ret = writeReg(DQACC_REG , des_data.designcap >> DIV_32); 00417 ret = writeReg(ICHGTERM_REG , des_data.ichgterm ); 00418 ret = writeReg(VEMPTY_REG , des_data.vempty ); 00419 00420 if (des_data.vcharge > charger_th) { 00421 dpacc = (des_data.designcap >> DIV_32) * chg_V_high / des_data.designcap ; 00422 ret = writeReg(DPACC_REG , dpacc); 00423 ret = writeReg(MODELCFG_REG , param_EZ_FG1); // 00424 } else { 00425 dpacc = (des_data.designcap >> DIV_32) * chg_V_low / des_data.designcap ; 00426 ret = writeReg(DPACC_REG , dpacc); 00427 ret = writeReg(MODELCFG_REG , param_EZ_FG2); 00428 } 00429 return ret; 00430 } 00431 00432 00433 /** 00434 * @brief Get reported Battery Capacity Function from MAX17055 Fuel Gauge 00435 * @par Details 00436 * This function sends a request to access the RepCAP register 00437 * of the MAX17055. RepCAP is the reported Battery Capacity in mAh of the battery based on the calculation by the Fuel Gauge algorithm. 00438 * 00439 * @retval repcap_data - Reported SOC data from the RepSOC register in % value. 00440 * @retval non-0 negative values check for errors 00441 */ 00442 00443 int MAX17055::get_battCAP(platform_data des_data) 00444 { 00445 int ret, design_rsense; 00446 uint16_t repcap_data; 00447 00448 ret = readReg(REPCAP_REG , repcap_data); 00449 if (ret < F_SUCCESS_0) 00450 return ret; 00451 else 00452 design_rsense = des_data.rsense; 00453 ret = raw_cap_to_uAh((uint32_t)repcap_data, design_rsense); 00454 if (ret < F_SUCCESS_0) 00455 return ret; 00456 else 00457 return ret; 00458 } 00459 00460 /** 00461 * @brief Get reported State Of Charge(SOC) Function from MAX17055 Fuel Gauge. 00462 * @par Details 00463 * This function sends a request to access the RepSOC register 00464 * of the MAX17055. RepSOC is the reported state-of-charge percentage output of the fuel gauge. 00465 * 00466 * @retval soc_data - Reported SOC data from the RepSOC register in % value. 00467 * @retval non-0 negative values check for errors 00468 */ 00469 int MAX17055::get_SOC() 00470 { 00471 00472 int ret; 00473 uint16_t soc_data; 00474 00475 ret = readReg(REPSOC_REG , soc_data); 00476 if (ret < F_SUCCESS_0) 00477 return ret; 00478 00479 soc_data = soc_data >> 8; /* RepSOC LSB: 1/256 % */ 00480 00481 return soc_data; 00482 } 00483 00484 /** 00485 * @brief Get at rate Average State Of Charge(SOC) Function from MAX17055 Fuel Gauge. 00486 * @par Details 00487 * This function sends a request to access the atAvSOC register of the MAX17055. 00488 * The AvSOC registers hold the calculated available capacity and percentage of the 00489 * battery based on all inputs from the ModelGauge m5 algorithm including empty 00490 * compensation. These registers provide unfiltered results. Jumps in the reported 00491 * values can be caused by abrupt changes in load current or temperature. 00492 * 00493 * @retval atAvSOC_data - Average SOC data from the atAVSOC register in % value. 00494 * @retval non-0 negative values check for errors 00495 */ 00496 int MAX17055::get_atAvSOC() 00497 { 00498 int ret; 00499 uint16_t atAvSOC_data; 00500 00501 ret = readReg(AVSOC_REG , atAvSOC_data); 00502 if (ret < F_SUCCESS_0) 00503 return ret; //Check errors if data is not correct 00504 00505 atAvSOC_data = atAvSOC_data >> 8; /* avSOC LSB: 1/256 % */ 00506 00507 return atAvSOC_data; 00508 } 00509 00510 /** 00511 * @brief Get mix State Of Charge(SOC) Function for MAX17055 Fuel Gauge. 00512 * @par Details 00513 * This function sends a request to access mixSOC register 00514 * of the MAX17055. The MixSOC registers holds the calculated 00515 * remaining capacity and percentage of the cell before any empty compensation 00516 * adjustments are performed. 00517 * 00518 * @retval mixSOC_data - Mixed SOC register values from the mixSOC register in % value. 00519 * @retval non-0 for errors 00520 */ 00521 int MAX17055::get_mixSOC() 00522 { 00523 int ret; 00524 uint16_t mixSOC_data; 00525 00526 ret = readReg(MIXSOC_REG , mixSOC_data); 00527 if (ret < F_SUCCESS_0) 00528 return ret; 00529 00530 mixSOC_data = mixSOC_data >> 8; /* RepSOC LSB: 1/256 % */ 00531 00532 return mixSOC_data; 00533 } 00534 00535 /** 00536 * @brief Get the Time to Empty(TTE) Function form MAX17055 Fuel Gauge. 00537 * @par Details 00538 * This function sends a request to access the TTE register 00539 * of the MAX17055 00540 * The TTE register holds the estimated time to empty for the 00541 * application under present temperature and load conditions. The TTE value is 00542 * determined by relating AvCap with AvgCurrent. The corresponding AvgCurrent 00543 * filtering gives a delay in TTE, but provides more stable results. 00544 * 00545 * @retval tte_data - Time to Empty data from the TTE register in seconds. 00546 * @retval non-0 negative values check for errors 00547 */ 00548 float MAX17055::get_TTE() 00549 { 00550 00551 int ret; 00552 uint16_t tte_data; 00553 float f_tte_data; 00554 00555 ret = readReg(TTE_REG , tte_data); 00556 if (ret < F_SUCCESS_0) 00557 return ret; 00558 else 00559 f_tte_data = ((float)tte_data * 5.625); /* TTE LSB: 5.625 sec */ 00560 00561 return f_tte_data; 00562 } 00563 00564 /** 00565 * @brief Get the at Time to Empty(atTTE) value Function for MAX17055 Fuel Gauge. 00566 * @par Details 00567 * This function sends a request to access the internal register 00568 * of the MAX17055 00569 * 00570 * @retval atTTE_data - Time to Empty data from the atTTE register in seconds. 00571 * @retval non-0 negative values check for errors 00572 */ 00573 float MAX17055::get_atTTE() 00574 { 00575 00576 int ret; 00577 uint16_t atTTE_data; 00578 float f_atTTE_data; 00579 00580 ret = readReg(ATTTE_REG , atTTE_data); 00581 if (ret < F_SUCCESS_0) 00582 return ret; //Check for errors 00583 else 00584 f_atTTE_data = ((float)atTTE_data * 5.625); /* TTE LSB: 5.625 sec */ 00585 00586 return f_atTTE_data; 00587 } 00588 00589 /** 00590 * @brief Get the Time to Full(TTE) values Function for MAX17055 Fuel Gauge. 00591 * @par Details 00592 * This function sends a request to access the internal register of the MAX17055 00593 * The TTF register holds the estimated time to full for the application 00594 * under present conditions. The TTF value is determined by learning the 00595 * constant current and constant voltage portions of the charge cycle based 00596 * on experience of prior charge cycles. Time to full is then estimate 00597 * by comparing present charge current to the charge termination current. 00598 * Operation of the TTF register assumes all charge profiles are consistent in the application. 00599 * 00600 * @retval ttf_data - Time to Full data from the TTF register in seconds. 00601 * @retval non-0 negative values check for errors 00602 */ 00603 float MAX17055::get_TTF() 00604 { 00605 00606 int ret; 00607 uint16_t ttf_data; 00608 float f_ttf_data; 00609 00610 ret = readReg(TTF_REG , ttf_data); 00611 if (ret < F_SUCCESS_0) 00612 return ret; 00613 else 00614 f_ttf_data = ((float)ttf_data * 5.625); /* TTE LSB: 5.625 sec */ 00615 00616 return f_ttf_data; 00617 } 00618 00619 /** 00620 * @brief Get voltage of the cell Function for MAX17055 Fuel Gauge. 00621 * @par Details 00622 * This function sends a request to access the VCell Register 00623 * of the MAX17055 to read the measured voltage from the cell. 00624 * 00625 * @retval vcell_data - vcell data from the VCELL_REG register in uVolts. 00626 * @retval non-0 negative values check for errors 00627 */ 00628 int MAX17055::get_Vcell() 00629 { 00630 00631 int ret; 00632 uint16_t vcell_data; 00633 00634 ret = readReg(VCELL_REG , vcell_data); 00635 if (ret < F_SUCCESS_0) 00636 return ret; 00637 else 00638 ret = lsb_to_uvolts(vcell_data); 00639 return ret; 00640 } 00641 00642 /** 00643 * @brief Gets Average voltage of the cell Function for MAX17055 Fuel Gauge. 00644 * @par Details 00645 * This function sends a request to access the AvgVCell Register 00646 * of the MAX17055 to read the measured voltage from the cell. 00647 * 00648 * @retval avgVcell_data - avgvcell data from the AVGVCELL_REG register in uVolts. 00649 * @retval non-0 negative values check for errors 00650 */ 00651 int MAX17055::get_avgVcell() 00652 { 00653 00654 int ret; 00655 uint16_t avgVcell_data; 00656 00657 ret = readReg(AVGVCELL_REG , avgVcell_data); 00658 if (ret < F_SUCCESS_0) 00659 return ret; 00660 else 00661 ret = lsb_to_uvolts(avgVcell_data); 00662 return ret; 00663 } 00664 00665 /** 00666 * @brief Get current Function for MAX17055 Fuel Gauge. 00667 * @par Details 00668 * This function sends a request to access the CURRENT register 00669 * of the MAX17055 to read the current readings. 00670 * 00671 * @param[in] des_data - Plataform_data struct with information about the design. 00672 * 00673 * @retval curr_data - current data from the CURRENT register in uAmps. 00674 * @retval non-0 negative values check for errors. 00675 */ 00676 float MAX17055::get_Current( platform_data des_data ) 00677 { 00678 00679 int ret,design_rsense; 00680 uint16_t curr_data; 00681 float f_ret; 00682 00683 ret = readReg(CURRENT_REG , curr_data); 00684 if (ret < F_SUCCESS_0) 00685 return ret; 00686 else 00687 design_rsense = des_data.rsense; 00688 f_ret = raw_current_to_uamps((uint32_t)curr_data, design_rsense); 00689 return f_ret; 00690 } 00691 00692 /** 00693 * @brief Get average current Function for MAX17055 Fuel Gauge. 00694 * @par Details 00695 * This function sends a request to access the aveCURRENT register 00696 * of the MAX17055 to read the average current readings. 00697 * 00698 * @param[in] des_data - Plataform_data struct with information about the design. 00699 * 00700 * @retval aveCurr_data - current data from the AVGCURRENT register in uAmps. 00701 * @retval non-0 negative values check for errors. 00702 */ 00703 float MAX17055::get_AvgCurrent( platform_data des_data ) 00704 { 00705 int ret, design_rsense; 00706 uint16_t data; 00707 float avgCurr_data; 00708 00709 ret = readReg(AVGCURRENT_REG , data); 00710 if (ret < F_SUCCESS_0) 00711 return ret; 00712 else 00713 avgCurr_data = data; 00714 design_rsense = des_data.rsense; 00715 avgCurr_data = raw_current_to_uamps((uint32_t)data, design_rsense); 00716 return avgCurr_data; 00717 } 00718 00719 /** 00720 * @brief lsb_to_uvolts Conversion Function 00721 * @par Details 00722 * This function takes the lsb value of the register and convert it 00723 * to uvolts 00724 * 00725 * @param[in] lsb - value of register lsb 00726 * @retval conv_2_uvolts - value converted lsb to uvolts 00727 */ 00728 int MAX17055:: lsb_to_uvolts(uint16_t lsb) 00729 { 00730 int conv_2_uvolts; 00731 conv_2_uvolts = (lsb * 625) / 8; /* 78.125uV per bit */ 00732 return conv_2_uvolts; 00733 } 00734 00735 /** 00736 * @brief raw_current_to_uamp Conversion Function 00737 * @par Details 00738 * This function takes the raw current value of the register and 00739 * converts it to uamps 00740 * 00741 * @param[in] curr - raw current value of register 00742 * @retval res - converted raw current to uamps (Signed 2's complement) 00743 */ 00744 float MAX17055::raw_current_to_uamps(uint32_t curr, int rsense_value) 00745 { 00746 int res = curr; 00747 float final_res; 00748 /* Negative Check*/ 00749 if (res & 0x8000){ 00750 res |= 0xFFFF0000; 00751 } 00752 final_res = (float)res; 00753 final_res *= 1562500 /(float)(rsense_value*10000); 00754 00755 return final_res; 00756 } 00757 00758 /** 00759 * @brief raw_cap_to_uAh Conversion Function 00760 * @par Details 00761 * This function takes the raw battery capacity value of the register and 00762 * converts it to uAh 00763 * 00764 * @param[in] raw_cap - raw capacity value of register 00765 * @retval res - converted raw capacity to uAh 00766 */ 00767 int MAX17055::raw_cap_to_uAh(uint32_t raw_cap, int rsense_value) 00768 { 00769 int res = raw_cap ; 00770 res *= 5000000/(rsense_value * 1000000); 00771 return res; 00772 } 00773 00774 /** 00775 * @brief Save Learned Parameters Function for battery Fuel Gauge model. 00776 * @par Details 00777 * It is recommended to save the learned capacity parameters every 00778 * time bit 2 of the Cycles register toggles 00779 * (so that it is saved every 64% change in the battery) 00780 * so that if power is lost the values can easily be restored. Make sure 00781 * the data is saved on a non-volatile memory. Call this function after first initialization for reference in future function calls. 00782 * Max number of cycles is 655.35 cycles with a LSB of 1% for the cycles register. 00783 * 00784 * @param[in] FG_params Fuel Gauge Parameters based on design details. 00785 * 00786 * @retval 0 for success 00787 * @retval non-0 negative for errors 00788 */ 00789 int MAX17055::save_Params(saved_FG_params_t FG_params) 00790 { 00791 int ret; 00792 uint16_t data[5], value; 00793 ///STEP 1. Checks if the cycle register bit 2 has changed. 00794 ret = readReg(CYCLES_REG , data[3]); 00795 value = data[3]; 00796 if (ret < F_SUCCESS_0) 00797 return ret; 00798 //Check if the stored cycles value is different from the read Cycles_reg value 00799 else if (FG_params.cycles == value) 00800 return ret; //exits the function without saving, when initializing or value did not change (calculate when the function is called in you application). 00801 else { 00802 value = FG_params.cycles^value; 00803 //check with mask 00804 value = (value & MAX17055_POR_MASK); 00805 00806 if (value == 0) 00807 return ret; 00808 00809 ///STEP 2. Save the capacity parameters for the specific battery. 00810 ret = readReg(RCOMP0_REG , data[0]); 00811 if (ret < F_SUCCESS_0) 00812 return ret; 00813 else 00814 FG_params.rcomp0 = data[0]; 00815 00816 ret = readReg(TEMPCO_REG , data[1]); 00817 if (ret < F_SUCCESS_0) 00818 return ret; 00819 else 00820 FG_params.temp_co = data[1]; 00821 00822 ret = readReg(FULLCAPREP_REG , data[2]); 00823 if (ret < F_SUCCESS_0) 00824 return ret; 00825 else 00826 FG_params.full_cap_rep = data[2]; 00827 00828 FG_params.cycles = data[3]; 00829 00830 ret = readReg(FULLCAPNOM_REG , data[4]); 00831 if (ret < F_SUCCESS_0) 00832 return ret; 00833 else 00834 FG_params.full_cap_nom = data[4]; 00835 return ret; 00836 } 00837 } 00838 00839 00840 00841 /** 00842 * @brief Restore Parameters Function for battery Fuel Gauge model. 00843 * @par Details 00844 * If power is lost, then the capacity information 00845 * can be easily restored with this function. 00846 * 00847 * @param[in] FG_params Struct for Fuel Gauge Parameters 00848 * @retval 0 for success 00849 * @retval non-0 negative for errors 00850 */ 00851 int MAX17055::restore_Params(saved_FG_params_t FG_params) 00852 { 00853 int ret; 00854 uint16_t temp_data, fullcapnom_data, mixCap_calc, dQacc_calc; 00855 uint16_t dPacc_value = 0x0C80;//Set it to 200% 00856 00857 ///STEP 1. Restoring capacity parameters 00858 write_and_verify_reg(RCOMP0_REG , FG_params.rcomp0); 00859 write_and_verify_reg(TEMPCO_REG , FG_params.temp_co); 00860 write_and_verify_reg(FULLCAPNOM_REG , FG_params.full_cap_nom); 00861 00862 wait_ms(350);//check the type of wait 00863 00864 ///STEP 2. Restore FullCap 00865 ret = readReg(FULLCAPNOM_REG , fullcapnom_data); 00866 if (ret < F_SUCCESS_0) 00867 return ret; 00868 00869 ret = readReg(MIXSOC_REG , temp_data); 00870 if (ret < F_SUCCESS_0) 00871 return ret; 00872 00873 mixCap_calc = (temp_data*fullcapnom_data)/25600; 00874 00875 write_and_verify_reg(MIXCAP_REG , mixCap_calc); 00876 write_and_verify_reg(FULLCAPREP_REG , FG_params.full_cap_rep); 00877 00878 ///STEP 3. Write DQACC to 200% of Capacity and DPACC to 200% 00879 dQacc_calc = (FG_params.full_cap_nom/ 16) ; 00880 00881 write_and_verify_reg(DPACC_REG , dPacc_value); 00882 write_and_verify_reg(DQACC_REG , dQacc_calc); 00883 00884 wait_ms(350); 00885 00886 ///STEP 4. Restore Cycles register 00887 ret = write_and_verify_reg(CYCLES_REG , FG_params.cycles); 00888 if (ret < F_SUCCESS_0) 00889 return ret; 00890 return ret; 00891 } 00892 00893 /** 00894 * @brief Function to Save Average Current to At Rate register. 00895 * @par Details 00896 * For User friendliness display of atTTE, atAvSOC, atAvCAP 00897 * write the average current to At Rate registers every 10sec 00898 * when the battery is in use. 00899 * NOTE: do not use this function when the Battery is charging. 00900 * 00901 * @retval 0 for success 00902 * @retval non-0 negative for errors 00903 */ 00904 int MAX17055::avCurr_2_atRate() 00905 { 00906 int ret; 00907 uint16_t avCurr_data; 00908 00909 ret = readReg(AVGCURRENT_REG , avCurr_data); 00910 if (ret < F_SUCCESS_0) { 00911 return ret = -3; 00912 } 00913 00914 //Write avCurrent to atRate Register 00915 ret = writeReg(ATRATE_REG , avCurr_data); 00916 if (ret < F_SUCCESS_0) { 00917 return ret; 00918 } 00919 return F_SUCCESS_0; 00920 }
Generated on Sat Jul 16 2022 18:51:08 by
