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: example-battery-charger-bq24295 example-C030-out-of-box-demo example-C030-out-of-box-demo Amit
bq24295.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 u-blox 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /** 00018 * @file bq24295.cpp 00019 * This file defines the API to the TI BQ24295 battery charging chip. 00020 */ 00021 00022 // Define this to print debug information 00023 //#define DEBUG_BQ24295 00024 00025 #include <mbed.h> 00026 #include <battery_charger_bq24295.h> 00027 00028 #ifdef DEBUG_BQ24295 00029 # include <stdio.h> 00030 #endif 00031 00032 /* ---------------------------------------------------------------- 00033 * COMPILE-TIME MACROS 00034 * -------------------------------------------------------------- */ 00035 00036 /* ---------------------------------------------------------------- 00037 * PRIVATE VARIABLES 00038 * -------------------------------------------------------------- */ 00039 00040 /* ---------------------------------------------------------------- 00041 * GENERIC PRIVATE FUNCTIONS 00042 * -------------------------------------------------------------- */ 00043 00044 // Read from a register. 00045 bool BatteryChargerBq24295::getRegister(char address, char *pValue) 00046 { 00047 bool success = false; 00048 00049 if (gpI2c != NULL) { 00050 // Move the address pointer 00051 if (gpI2c->write(gAddress, &address, 1) == 0) { 00052 if (pValue != NULL) { 00053 // Read from the address 00054 if (gpI2c->read(gAddress, pValue, 1) == 0) { 00055 success = true; 00056 #ifdef DEBUG_BQ24295 00057 printf("BatteryChargerBq24295 (I2C 0x%02x): read 0x%02x from register 0x%02x.\r\n", gAddress >> 1, *pValue, address); 00058 #endif 00059 } 00060 } else { 00061 success = true; 00062 } 00063 } 00064 } 00065 00066 return success; 00067 } 00068 00069 // Write to a register. 00070 bool BatteryChargerBq24295::setRegister(char address, char value) 00071 { 00072 bool success = false; 00073 char data[2]; 00074 00075 if (gpI2c != NULL) { 00076 data[0] = address; 00077 data[1] = value; 00078 if (gpI2c->write(gAddress, &(data[0]), 2) == 0) { 00079 success = true; 00080 #ifdef DEBUG_BQ24295 00081 printf("BatteryChargerBq24295 (I2C 0x%02x): wrote 0x%02x to register 0x%02x.\r\n", gAddress >> 1, value, address); 00082 #endif 00083 } 00084 } 00085 00086 return success; 00087 } 00088 00089 // Set a mask of bits in a register. 00090 bool BatteryChargerBq24295::setRegisterBits(char address, char mask) 00091 { 00092 bool success = false; 00093 char value; 00094 00095 if (getRegister(address, &value)) { 00096 value |= mask; 00097 if (setRegister(address, value)) { 00098 success = true; 00099 } 00100 } 00101 00102 return success; 00103 } 00104 00105 // Clear a mask of bits in a register. 00106 bool BatteryChargerBq24295::clearRegisterBits(char address, char mask) 00107 { 00108 bool success = false; 00109 char value; 00110 00111 if (getRegister(address, &value)) { 00112 value &= ~mask; 00113 if (setRegister(address, value)) { 00114 success = true; 00115 } 00116 } 00117 00118 return success; 00119 } 00120 00121 /* ---------------------------------------------------------------- 00122 * PUBLIC FUNCTIONS 00123 * -------------------------------------------------------------- */ 00124 00125 // Constructor. 00126 BatteryChargerBq24295::BatteryChargerBq24295(void) 00127 { 00128 gpI2c = NULL; 00129 gReady = false; 00130 } 00131 00132 // Destructor. 00133 BatteryChargerBq24295::~BatteryChargerBq24295(void) 00134 { 00135 } 00136 00137 // Initialise ourselves. 00138 bool BatteryChargerBq24295::init (I2C * pI2c, uint8_t address) 00139 { 00140 char reg; 00141 00142 gpI2c = pI2c; 00143 gAddress = address << 1; 00144 00145 if (gpI2c != NULL) { 00146 gpI2c->lock(); 00147 00148 // Read the revision status register 00149 if (getRegister(0x0a, ®)) { 00150 // The expected response is 0xc0 00151 if (reg == 0xc0) { 00152 gReady = true; 00153 } 00154 } 00155 gpI2c->unlock(); 00156 } 00157 00158 #ifdef DEBUG_BQ24295 00159 if (gReady) { 00160 printf("BatteryChargerBq24295 (I2C 0x%02x): handler initialised.\r\n", gAddress >> 1); 00161 } else { 00162 printf("BatteryChargerBq24295 (I2C 0x%02x): chip NOT initialised.\r\n", gAddress >> 1); 00163 } 00164 #endif 00165 00166 return gReady; 00167 } 00168 00169 // Get the charge state. 00170 BatteryChargerBq24295::ChargerState BatteryChargerBq24295::getChargerState(void) 00171 { 00172 BatteryChargerBq24295::ChargerState chargerState = CHARGER_STATE_UNKNOWN; 00173 char powerOnConfiguration; 00174 char systemStatus; 00175 00176 if (gReady && (gpI2c != NULL)) { 00177 gpI2c->lock(); 00178 // Read the power-on configuration register 00179 if (getRegister(0x01, &powerOnConfiguration)) { 00180 // Read the system status register 00181 if (getRegister(0x08, &systemStatus)) { 00182 // Check the charge enable bit 00183 if ((powerOnConfiguration & (1 << 4)) == 0) { 00184 chargerState = CHARGER_STATE_DISABLED; 00185 #ifdef DEBUG_BQ24295 00186 printf("BatteryChargerBq24295 (I2C 0x%02x): charging is disabled.\r\n", gAddress >> 1); 00187 #endif 00188 } else { 00189 // BatteryCharger is not disabled, so see if we have 00190 // external power (bit 3) 00191 if ((systemStatus & 0x04) == 0) { 00192 chargerState = CHARGER_STATE_NO_EXTERNAL_POWER; 00193 #ifdef DEBUG_BQ24295 00194 printf("BatteryChargerBq24295 (I2C 0x%02x): no external power.\r\n", gAddress >> 1); 00195 #endif 00196 } else { 00197 // Have power, so see how we're cooking (bits 4 & 5) 00198 switch ((systemStatus >> 4) & 0x03) { 00199 case 0: 00200 chargerState = CHARGER_STATE_NOT_CHARGING; 00201 #ifdef DEBUG_BQ24295 00202 printf("BatteryChargerBq24295 (I2C 0x%02x): not charging.\r\n", gAddress >> 1); 00203 #endif 00204 break; 00205 case 1: 00206 chargerState = CHARGER_STATE_PRECHARGE; 00207 #ifdef DEBUG_BQ24295 00208 printf("BatteryChargerBq24295 (I2C 0x%02x): pre-charge.\r\n", gAddress >> 1); 00209 #endif 00210 break; 00211 case 2: 00212 chargerState = CHARGER_STATE_FAST_CHARGE; 00213 #ifdef DEBUG_BQ24295 00214 printf("BatteryChargerBq24295 (I2C 0x%02x): fast charge.\r\n", gAddress >> 1); 00215 #endif 00216 break; 00217 case 3: 00218 chargerState = CHARGER_STATE_COMPLETE; 00219 #ifdef DEBUG_BQ24295 00220 printf("BatteryChargerBq24295 (I2C 0x%02x): charging complete.\r\n", gAddress >> 1); 00221 #endif 00222 break; 00223 default: 00224 break; 00225 } 00226 } 00227 } 00228 } 00229 } 00230 gpI2c->unlock(); 00231 } 00232 00233 return chargerState; 00234 } 00235 00236 // Get whether external power is present or not. 00237 bool BatteryChargerBq24295::isExternalPowerPresent(void) 00238 { 00239 bool isPresent = false; 00240 char reg; 00241 00242 if (gReady && (gpI2c != NULL)) { 00243 gpI2c->lock(); 00244 // Read the system status register 00245 if (getRegister(0x08, ®)) { 00246 // See if we have external power (bit 3) 00247 if ((reg & 0x04) != 0) { 00248 isPresent = true; 00249 } 00250 00251 #ifdef DEBUG_BQ24295 00252 if (isPresent) { 00253 printf("BatteryChargerBq24295 (I2C 0x%02x): external power is present.\r\n", gAddress >> 1); 00254 } else { 00255 printf("BatteryChargerBq24295 (I2C 0x%02x): external power is NOT present.\r\n", gAddress >> 1); 00256 } 00257 #endif 00258 } 00259 gpI2c->unlock(); 00260 } 00261 00262 return isPresent; 00263 } 00264 00265 // Enable charging. 00266 bool BatteryChargerBq24295::enableCharging (void) 00267 { 00268 bool success = false; 00269 00270 if (gReady && (gpI2c != NULL)) { 00271 gpI2c->lock(); 00272 // Charge enable is bit 4 of the power-on configuration register 00273 success = setRegisterBits(0x01, (1 << 4)); 00274 #ifdef DEBUG_BQ24295 00275 if (success) { 00276 printf("BatteryChargerBq24295 (I2C 0x%02x): charging now ENABLED.\r\n", gAddress >> 1); 00277 } 00278 #endif 00279 gpI2c->unlock(); 00280 } 00281 00282 return success; 00283 } 00284 00285 // Disable charging. 00286 bool BatteryChargerBq24295::disableCharging (void) 00287 { 00288 bool success = false; 00289 00290 if (gReady && (gpI2c != NULL)) { 00291 gpI2c->lock(); 00292 // Charge enable is bit 4 of the power-on configuration register 00293 success = clearRegisterBits(0x01, (1 << 4)); 00294 #ifdef DEBUG_BQ24295 00295 if (success) { 00296 printf("BatteryChargerBq24295 (I2C 0x%02x): charging now DISABLED.\r\n", gAddress >> 1); 00297 } 00298 #endif 00299 gpI2c->unlock(); 00300 } 00301 00302 return success; 00303 } 00304 00305 // Get the whether charging is enabled or disabled. 00306 bool BatteryChargerBq24295::isChargingEnabled (void) 00307 { 00308 bool isEnabled = false; 00309 char reg; 00310 00311 if (gReady && (gpI2c != NULL)) { 00312 gpI2c->lock(); 00313 // Read the power-on configuration register 00314 if (getRegister(0x01, ®)) { 00315 // Charge enable is bit 4 of the power-on configuration register 00316 if ((reg & (1 << 4)) != 0) { 00317 isEnabled = true; 00318 } 00319 #ifdef DEBUG_BQ24295 00320 if (isEnabled) { 00321 printf("BatteryChargerBq24295 (I2C 0x%02x): charging is ENABLED.\r\n", gAddress >> 1); 00322 } else { 00323 printf("BatteryChargerBq24295 (I2C 0x%02x): charging is DISABLED.\r\n", gAddress >> 1); 00324 } 00325 #endif 00326 } 00327 gpI2c->unlock(); 00328 } 00329 00330 return isEnabled; 00331 } 00332 00333 // Enable OTG charging. 00334 bool BatteryChargerBq24295::enableOtg (void) 00335 { 00336 bool success = false; 00337 00338 if (gReady && (gpI2c != NULL)) { 00339 gpI2c->lock(); 00340 // OTG enable is bit 5 of the power-on configuration register 00341 success = setRegisterBits(0x01, (1 << 5)); 00342 #ifdef DEBUG_BQ24295 00343 if (success) { 00344 printf("BatteryChargerBq24295 (I2C 0x%02x): OTG charging now ENABLED.\r\n", gAddress >> 1); 00345 } 00346 #endif 00347 gpI2c->unlock(); 00348 } 00349 00350 return success; 00351 } 00352 00353 // Disable OTG charging. 00354 bool BatteryChargerBq24295::disableOtg (void) 00355 { 00356 bool success = false; 00357 00358 if (gReady && (gpI2c != NULL)) { 00359 gpI2c->lock(); 00360 // OTG enable is bit 5 of the power-on configuration register 00361 success = clearRegisterBits(0x01, (1 << 5)); 00362 #ifdef DEBUG_BQ24295 00363 if (success) { 00364 printf("BatteryChargerBq24295 (I2C 0x%02x): OTG charging now DISABLED.\r\n", gAddress >> 1); 00365 } 00366 #endif 00367 gpI2c->unlock(); 00368 } 00369 00370 return success; 00371 } 00372 00373 // Get whether OTG charging is enabled or not. 00374 bool BatteryChargerBq24295::isOtgEnabled (void) 00375 { 00376 bool isEnabled = false; 00377 char reg; 00378 00379 if (gReady && (gpI2c != NULL)) { 00380 gpI2c->lock(); 00381 // Read the power-on configuration register 00382 if (getRegister(0x01, ®)) { 00383 // OTG enable is bit 5 of the power-on configuration register 00384 if ((reg & (1 << 5)) != 0) { 00385 isEnabled = true; 00386 } 00387 #ifdef DEBUG_BQ24295 00388 if (isEnabled) { 00389 printf("BatteryChargerBq24295 (I2C 0x%02x): OTG charging is ENABLED.\r\n", gAddress >> 1); 00390 } else { 00391 printf("BatteryChargerBq24295 (I2C 0x%02x): OTG charging is DISABLED.\r\n", gAddress >> 1); 00392 } 00393 #endif 00394 } 00395 gpI2c->unlock(); 00396 } 00397 00398 return isEnabled; 00399 } 00400 00401 // Set the system voltage. 00402 bool BatteryChargerBq24295::setSystemVoltage (int32_t voltageMV) 00403 { 00404 bool success = false; 00405 char reg; 00406 int32_t codedValue; 00407 00408 if (gReady && (gpI2c != NULL)) { 00409 gpI2c->lock(); 00410 // Read the power-on configuration register 00411 if (getRegister(0x01, ®)) { 00412 // System voltage is in bits 1 to 3, 00413 // coded to base "100 mV" with 00414 // an offset of 3000 mV. 00415 if ((voltageMV >= 3000) && (voltageMV <= 3700)) { 00416 codedValue = voltageMV; 00417 codedValue = (codedValue - 3000) / 100; 00418 // If the voltage minus the base is not an exact multiple of 100, 00419 // add one to the coded value to make sure we don't 00420 // go under the requested system voltage 00421 if ((voltageMV - 3000) % 100 != 0) { 00422 codedValue++; 00423 } 00424 00425 reg &= ~(0x07 << 1); 00426 reg |= (char) ((codedValue & 0x07) << 1); 00427 00428 // Write to the power-on configuration register 00429 success = setRegister (0x01, reg); 00430 #ifdef DEBUG_BQ24295 00431 if (success) { 00432 printf("BatteryChargerBq24295 (I2C 0x%02x): system voltage now set to %.3f V.\r\n", gAddress >> 1, (float) voltageMV / 1000); 00433 } 00434 #endif 00435 } 00436 } 00437 gpI2c->unlock(); 00438 } 00439 00440 return success; 00441 } 00442 00443 // Get the system voltage. 00444 bool BatteryChargerBq24295::getSystemVoltage (int32_t *pVoltageMV) 00445 { 00446 bool success = false; 00447 char reg; 00448 00449 if (gReady && (gpI2c != NULL)) { 00450 gpI2c->lock(); 00451 // Read the power-on configuration register 00452 if (getRegister(0x01, ®)) { 00453 success = true; 00454 if (pVoltageMV != NULL) { 00455 // Input voltage limit is in bits 1 to 3 00456 // Base voltage 00457 *pVoltageMV = 3000; 00458 // Shift reg down and add the number of multiples 00459 // of 100 mV 00460 reg = (reg >> 1) & 0x07; 00461 *pVoltageMV += ((int32_t) reg) * 100; 00462 #ifdef DEBUG_BQ24295 00463 printf("BatteryChargerBq24295 (I2C 0x%02x): system voltage is %.3f V.\r\n", gAddress >> 1, (float) *pVoltageMV / 1000); 00464 #endif 00465 } 00466 } 00467 gpI2c->unlock(); 00468 } 00469 00470 return success; 00471 } 00472 00473 // Set the fast charging current limit. 00474 bool BatteryChargerBq24295::setFastChargingCurrentLimit (int32_t currentMA) 00475 { 00476 bool success = false; 00477 char reg; 00478 int32_t codedValue; 00479 00480 if (gReady && (gpI2c != NULL)) { 00481 gpI2c->lock(); 00482 // Read the charge current control register 00483 if (getRegister(0x02, ®)) { 00484 // Fast charging current limit is in 00485 // bits 2 to 7, coded to base "64 mA" with 00486 // an offset of 512 mA. 00487 if ((currentMA >= 512) && (currentMA <= 3008)) { 00488 codedValue = currentMA; 00489 codedValue = (codedValue - 512) / 64; 00490 00491 reg &= ~(0x3f << 2); 00492 reg |= (char) ((codedValue & 0x3f) << 2); 00493 00494 // Write to the charge current control register 00495 success = setRegister (0x02, reg); 00496 #ifdef DEBUG_BQ24295 00497 if (success) { 00498 printf("BatteryChargerBq24295 (I2C 0x%02x): fast charging current limit now set to %.3f A.\r\n", gAddress >> 1, (float) currentMA / 1000); 00499 } 00500 #endif 00501 } 00502 } 00503 gpI2c->unlock(); 00504 } 00505 00506 return success; 00507 } 00508 00509 // Get the fast charging current limit. 00510 bool BatteryChargerBq24295::getFastChargingCurrentLimit (int32_t *pCurrentMA) 00511 { 00512 bool success = false; 00513 char reg; 00514 00515 if (gReady && (gpI2c != NULL)) { 00516 gpI2c->lock(); 00517 // Read the charge current control register 00518 if (getRegister(0x02, ®)) { 00519 success = true; 00520 if (pCurrentMA != NULL) { 00521 // Fast charging current limit is in bits 2 to 7 00522 // Base current 00523 *pCurrentMA = 512; 00524 // Shift reg down and add the number of multiples 00525 // of 64 mA 00526 reg = (reg >> 2) & 0x3f; 00527 *pCurrentMA += ((int32_t) reg) * 64; 00528 #ifdef DEBUG_BQ24295 00529 printf("BatteryChargerBq24295 (I2C 0x%02x): fast charge current limit is %.3f A.\r\n", gAddress >> 1, (float) *pCurrentMA / 1000); 00530 #endif 00531 } 00532 } 00533 gpI2c->unlock(); 00534 } 00535 00536 return success; 00537 } 00538 00539 // Enable the ICHG/IPRECH margin. 00540 bool BatteryChargerBq24295::enableIcghIprechMargin (void) 00541 { 00542 bool success = false; 00543 00544 if (gReady && (gpI2c != NULL)) { 00545 gpI2c->lock(); 00546 // FORCE_20PCT is bit 0 of the charge current control register 00547 success = setRegisterBits(0x02, (1 << 0)); 00548 #ifdef DEBUG_BQ24295 00549 if (success) { 00550 printf("BatteryChargerBq24295 (I2C 0x%02x): ICGH/IPRECH margin now ENABLED.\r\n", gAddress >> 1); 00551 } 00552 #endif 00553 gpI2c->unlock(); 00554 } 00555 00556 return success; 00557 } 00558 00559 // Disable the ICHG/IPRECH margin. 00560 bool BatteryChargerBq24295::disableIcghIprechMargin (void) 00561 { 00562 bool success = false; 00563 00564 if (gReady && (gpI2c != NULL)) { 00565 gpI2c->lock(); 00566 // FORCE_20PCT is bit 0 of the charge current control register 00567 success = clearRegisterBits(0x02, (1 << 0)); 00568 #ifdef DEBUG_BQ24295 00569 if (success) { 00570 printf("BatteryChargerBq24295 (I2C 0x%02x): ICGH/IPRECH margin now DISABLED.\r\n", gAddress >> 1); 00571 } 00572 #endif 00573 gpI2c->unlock(); 00574 } 00575 00576 return success; 00577 } 00578 00579 // Check if the ICHG/IPRECH margin is set. 00580 bool BatteryChargerBq24295::isIcghIprechMarginEnabled (void) 00581 { 00582 bool isEnabled = false; 00583 char reg; 00584 00585 if (gReady && (gpI2c != NULL)) { 00586 gpI2c->lock(); 00587 // Read the charge current control register 00588 if (getRegister(0x02, ®)) { 00589 // FORCE_20PCT is bit 0 00590 if ((reg & (1 << 0)) != 0) { 00591 isEnabled = true; 00592 } 00593 #ifdef DEBUG_BQ24295 00594 if (isEnabled) { 00595 printf("BatteryChargerBq24295 (I2C 0x%02x): ICGH/IPRECH margin is ENABLED.\r\n", gAddress >> 1); 00596 } else { 00597 printf("BatteryChargerBq24295 (I2C 0x%02x): ICGH/IPRECH margin is DISABLED.\r\n", gAddress >> 1); 00598 } 00599 #endif 00600 } 00601 gpI2c->unlock(); 00602 } 00603 00604 return isEnabled; 00605 } 00606 00607 // Set the fast charging safety timer. 00608 bool BatteryChargerBq24295::setFastChargingSafetyTimer (int32_t timerHours) 00609 { 00610 bool success = false; 00611 char reg; 00612 int32_t codedValue; 00613 00614 if (gReady && (gpI2c != NULL)) { 00615 gpI2c->lock(); 00616 // Mustn't be silly 00617 if (timerHours >= 0) { 00618 // Read the charge termination/timer control register 00619 if (getRegister(0x05, ®)) { 00620 // Timer setting is in bits 1 & 2, enable is in bit 3 00621 if (timerHours == 0) { 00622 reg &= ~(1 << 3); 00623 } else { 00624 reg |= (1 << 3); 00625 if (timerHours < 8) { 00626 codedValue = 0; 00627 } else if (timerHours < 12) { 00628 codedValue = 1; 00629 } else if (timerHours < 20) { 00630 codedValue = 2; 00631 } else { 00632 codedValue = 3; 00633 } 00634 reg &= ~(0x03 << 1); 00635 reg |= (char) (codedValue << 1); 00636 } 00637 // Write to the charge termination/timer control register 00638 success = setRegister (0x05, reg); 00639 #ifdef DEBUG_BQ24295 00640 if (success) { 00641 printf("BatteryChargerBq24295 (I2C 0x%02x): fast charging safety timer now set to %d hours.\r\n", gAddress >> 1, (int) timerHours); 00642 } 00643 #endif 00644 } 00645 } 00646 gpI2c->unlock(); 00647 } 00648 00649 return success; 00650 } 00651 00652 // Get the value of the fast charging safety timer. 00653 bool BatteryChargerBq24295::getFastChargingSafetyTimer (int32_t *pTimerHours) 00654 { 00655 bool success = false; 00656 char reg; 00657 00658 if (gReady && (gpI2c != NULL)) { 00659 gpI2c->lock(); 00660 // Read the charge termination/timer control register 00661 if (getRegister(0x05, ®)) { 00662 success = true; 00663 if (pTimerHours != NULL) { 00664 *pTimerHours = 0; 00665 // Timer enable is in bit 3 00666 if ((reg & (1 << 3)) != 0) { 00667 // Timer value is in bits 1 & 2 00668 switch ((reg >> 1) & 0x03) { 00669 case 0: 00670 *pTimerHours = 5; 00671 break; 00672 case 1: 00673 *pTimerHours = 8; 00674 break; 00675 case 2: 00676 *pTimerHours = 12; 00677 break; 00678 case 3: 00679 *pTimerHours = 20; 00680 break; 00681 default: 00682 MBED_ASSERT(false); 00683 break; 00684 } 00685 } 00686 #ifdef DEBUG_BQ24295 00687 printf("BatteryChargerBq24295 (I2C 0x%02x): fast charging safety timer is %d hours.\r\n", gAddress >> 1, (int) *pTimerHours); 00688 #endif 00689 } 00690 } 00691 gpI2c->unlock(); 00692 } 00693 00694 return success; 00695 } 00696 00697 // Set the charging termination current. 00698 bool BatteryChargerBq24295::setChargingTerminationCurrent (int32_t currentMA) 00699 { 00700 bool success = false; 00701 char reg; 00702 int32_t codedValue; 00703 00704 if (gReady && (gpI2c != NULL)) { 00705 gpI2c->lock(); 00706 // Read the pre-charge/termination current control register 00707 if (getRegister(0x03, ®)) { 00708 // Charging termination current limit is in 00709 // bits 0 to 3, coded to base "128 mA" with 00710 // an offset of 128 mA. 00711 if ((currentMA >= 128) && (currentMA <= 2048)) { 00712 codedValue = currentMA; 00713 codedValue = (codedValue - 128) / 128; 00714 00715 reg &= ~0x0f; 00716 reg |= (char) (codedValue & 0x0f); 00717 00718 // Write to the pre-charge/termination current control register 00719 success = setRegister (0x03, reg); 00720 #ifdef DEBUG_BQ24295 00721 if (success) { 00722 printf("BatteryChargerBq24295 (I2C 0x%02x): charging termination current now set to %.3f A.\r\n", gAddress >> 1, (float) currentMA / 1000); 00723 } 00724 #endif 00725 } 00726 } 00727 gpI2c->unlock(); 00728 } 00729 00730 return success; 00731 } 00732 00733 // Get the charging termination current. 00734 bool BatteryChargerBq24295::getChargingTerminationCurrent (int32_t *pCurrentMA) 00735 { 00736 bool success = false; 00737 char reg; 00738 00739 if (gReady && (gpI2c != NULL)) { 00740 gpI2c->lock(); 00741 // Read the pre-charge/termination current control register 00742 if (getRegister(0x03, ®)) { 00743 success = true; 00744 if (pCurrentMA != NULL) { 00745 // Pre-charging current limit is in bits 0 to 3 00746 // Base current 00747 *pCurrentMA = 128; 00748 // Add the number of multiples of 128 mA 00749 reg = reg & 0x0f; 00750 *pCurrentMA += ((int32_t) reg) * 128; 00751 #ifdef DEBUG_BQ24295 00752 printf("BatteryChargerBq24295 (I2C 0x%02x): charging termination current is %.3f A.\r\n", gAddress >> 1, (float) *pCurrentMA / 1000); 00753 #endif 00754 } 00755 } 00756 gpI2c->unlock(); 00757 } 00758 00759 return success; 00760 } 00761 00762 // Enable charging termination. 00763 bool BatteryChargerBq24295::enableChargingTermination (void) 00764 { 00765 bool success = false; 00766 00767 if (gReady && (gpI2c != NULL)) { 00768 gpI2c->lock(); 00769 // EN_TERM is bit 7 of the charge termination/timer control register 00770 success = setRegisterBits(0x05, (1 << 7)); 00771 #ifdef DEBUG_BQ24295 00772 if (success) { 00773 printf("BatteryChargerBq24295 (I2C 0x%02x): charging termination now ENABLED.\r\n", gAddress >> 1); 00774 } 00775 #endif 00776 gpI2c->unlock(); 00777 } 00778 00779 return success; 00780 } 00781 00782 // Disable charging termination. 00783 bool BatteryChargerBq24295::disableChargingTermination (void) 00784 { 00785 bool success = false; 00786 00787 if (gReady && (gpI2c != NULL)) { 00788 gpI2c->lock(); 00789 // EN_TERM is bit 7 of the charge termination/timer control register 00790 success = clearRegisterBits(0x05, (1 << 7)); 00791 #ifdef DEBUG_BQ24295 00792 if (success) { 00793 printf("BatteryChargerBq24295 (I2C 0x%02x): charging termination now DISABLED.\r\n", gAddress >> 1); 00794 } 00795 #endif 00796 gpI2c->unlock(); 00797 } 00798 00799 return success; 00800 } 00801 00802 // Get the state of charging termination (enabled or disabled) 00803 bool BatteryChargerBq24295::isChargingTerminationEnabled (void) 00804 { 00805 bool isEnabled = false; 00806 char reg; 00807 00808 if (gReady && (gpI2c != NULL)) { 00809 gpI2c->lock(); 00810 // Read the charge termination/timer control register 00811 if (getRegister(0x05, ®)) { 00812 // EN_TERM is bit 7 00813 if ((reg & (1 << 7)) != 0) { 00814 isEnabled = true; 00815 } 00816 #ifdef DEBUG_BQ24295 00817 if (isEnabled) { 00818 printf("BatteryChargerBq24295 (I2C 0x%02x): charging termination is ENABLED.\r\n", gAddress >> 1); 00819 } else { 00820 printf("BatteryChargerBq24295 (I2C 0x%02x): charging termination is DISABLED.\r\n", gAddress >> 1); 00821 } 00822 #endif 00823 } 00824 gpI2c->unlock(); 00825 } 00826 00827 return isEnabled; 00828 } 00829 00830 // Set the pre-charging current limit. 00831 bool BatteryChargerBq24295::setPrechargingCurrentLimit (int32_t currentMA) 00832 { 00833 bool success = false; 00834 char reg; 00835 int32_t codedValue; 00836 00837 if (gReady && (gpI2c != NULL)) { 00838 gpI2c->lock(); 00839 // Read the pre-charge/termination current control register 00840 if (getRegister(0x03, ®)) { 00841 // Pre-charging current limit is in 00842 // bits 4 to 7, coded to base "128 mA" with 00843 // an offset of 128 mA. 00844 if ((currentMA >= 128) && (currentMA <= 2048)) { 00845 codedValue = currentMA; 00846 codedValue = (codedValue - 128) / 128; 00847 00848 reg &= ~(0x0f << 4); 00849 reg |= (char) ((codedValue & 0x0f) << 4); 00850 00851 // Write to the pre-charge/termination current control register 00852 success = setRegister (0x03, reg); 00853 #ifdef DEBUG_BQ24295 00854 if (success) { 00855 printf("BatteryChargerBq24295 (I2C 0x%02x): pre-charging current limit now set to %.3f A.\r\n", gAddress >> 1, (float) currentMA / 1000); 00856 } 00857 #endif 00858 } 00859 } 00860 gpI2c->unlock(); 00861 } 00862 00863 return success; 00864 } 00865 00866 // Get the pre-charging current limit. 00867 bool BatteryChargerBq24295::getPrechargingCurrentLimit (int32_t *pCurrentMA) 00868 { 00869 bool success = false; 00870 char reg; 00871 00872 if (gReady && (gpI2c != NULL)) { 00873 gpI2c->lock(); 00874 // Read the pre-charge/termination current control register 00875 if (getRegister(0x03, ®)) { 00876 success = true; 00877 if (pCurrentMA != NULL) { 00878 // Pre-charging current limit is in bits 4 to 7 00879 // Base current 00880 *pCurrentMA = 128; 00881 // Shift reg down and add the number of multiples 00882 // of 128 mA 00883 reg = (reg >> 4) & 0x0f; 00884 *pCurrentMA += ((int32_t) reg) * 128; 00885 #ifdef DEBUG_BQ24295 00886 printf("BatteryChargerBq24295 (I2C 0x%02x): pre-charging current limit is %.3f A.\r\n", gAddress >> 1, (float) *pCurrentMA / 1000); 00887 #endif 00888 } 00889 } 00890 gpI2c->unlock(); 00891 } 00892 00893 return success; 00894 } 00895 00896 // Set the charging voltage limit. 00897 bool BatteryChargerBq24295::setChargingVoltageLimit (int32_t voltageMV) 00898 { 00899 bool success = false; 00900 char reg; 00901 int32_t codedLimit; 00902 00903 if (gReady && (gpI2c != NULL)) { 00904 gpI2c->lock(); 00905 // Read the charging voltage control register 00906 if (getRegister(0x04, ®)) { 00907 // Charging voltage limit is in bits 2 to 7 00908 // but it is coded to base "16 mV" with 00909 // an offset of 3504 mV. 00910 if ((voltageMV >= 3504) && (voltageMV <= 4400)) { 00911 codedLimit = voltageMV; 00912 codedLimit = (codedLimit - 3504) / 16; 00913 00914 reg &= ~(0x3f << 2); 00915 reg |= (char) ((codedLimit & 0x3f) << 2); 00916 00917 // Write to the charging voltage control register 00918 success = setRegister (0x04, reg); 00919 #ifdef DEBUG_BQ24295 00920 if (success) { 00921 printf("BatteryChargerBq24295 (I2C 0x%02x): charging voltage limit now set to %.3f V.\r\n", gAddress >> 1, (float) voltageMV / 1000); 00922 } 00923 #endif 00924 } 00925 } 00926 gpI2c->unlock(); 00927 } 00928 00929 return success; 00930 } 00931 00932 // Get the charging voltage limit. 00933 bool BatteryChargerBq24295::getChargingVoltageLimit (int32_t *pVoltageMV) 00934 { 00935 bool success = false; 00936 char reg; 00937 00938 if (gReady && (gpI2c != NULL)) { 00939 gpI2c->lock(); 00940 // Read the charging voltage control register 00941 if (getRegister(0x04, ®)) { 00942 success = true; 00943 if (pVoltageMV != NULL) { 00944 // Charging voltage limit is in bits 2 to 7 00945 // Base voltage 00946 *pVoltageMV = 3504; 00947 // Shift reg down and add the number of multiples 00948 // of 16 mV 00949 reg = (reg >> 2) & 0x3f; 00950 *pVoltageMV += ((int32_t) reg) * 16; 00951 #ifdef DEBUG_BQ24295 00952 printf("BatteryChargerBq24295 (I2C 0x%02x): charging voltage limit is %.3f V.\r\n", gAddress >> 1, (float) *pVoltageMV / 1000); 00953 #endif 00954 } 00955 } 00956 gpI2c->unlock(); 00957 } 00958 00959 return success; 00960 } 00961 00962 // Set the pre-charge to fast-charge voltage threshold. 00963 bool BatteryChargerBq24295::setFastChargingVoltageThreshold (int32_t voltageMV) 00964 { 00965 bool success = false; 00966 00967 if (gReady && (gpI2c != NULL)) { 00968 gpI2c->lock(); 00969 // There are only two possible values, 2.8 V and 3.0 V. 00970 // BATLOWV is bit 1 of the charging voltage control register 00971 if (voltageMV > 2800) { 00972 success = setRegisterBits(0x04, (1 << 1)); 00973 #ifdef DEBUG_BQ24295 00974 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold now set to 3.000 V.\r\n", gAddress >> 1); 00975 #endif 00976 } else { 00977 success = clearRegisterBits(0x04, (1 << 1)); 00978 #ifdef DEBUG_BQ24295 00979 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold now set to 2.800 V.\r\n", gAddress >> 1); 00980 #endif 00981 } 00982 gpI2c->unlock(); 00983 } 00984 00985 return success; 00986 } 00987 00988 // Get the pre-charge to fast-charge voltage threshold. 00989 bool BatteryChargerBq24295::getFastChargingVoltageThreshold (int32_t *pVoltageMV) 00990 { 00991 bool success = false; 00992 char reg; 00993 00994 if (gReady && (gpI2c != NULL)) { 00995 gpI2c->lock(); 00996 // BATLOWV is bit 1 of the charging voltage control register 00997 if (getRegister(0x04, ®)) { 00998 success = true; 00999 if (pVoltageMV != NULL) { 01000 *pVoltageMV = 2800; 01001 if ((reg & (1 << 1)) != 0) { 01002 *pVoltageMV = 3000; 01003 } 01004 } 01005 } 01006 01007 #ifdef DEBUG_BQ24295 01008 if (reg & (1 << 1)) { 01009 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold is 3.000 V.\r\n", gAddress >> 1); 01010 } else { 01011 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold is 2.800 V.\r\n", gAddress >> 1); 01012 } 01013 #endif 01014 gpI2c->unlock(); 01015 } 01016 01017 return success; 01018 } 01019 01020 // Set the recharging voltage threshold. 01021 bool BatteryChargerBq24295::setRechargingVoltageThreshold (int32_t voltageMV) 01022 { 01023 bool success = false; 01024 01025 if (gReady && (gpI2c != NULL)) { 01026 gpI2c->lock(); 01027 // There are only two possible values, 100 mV and 300 mV. 01028 // VRECHG is bit 0 of the charging voltage control register 01029 if (voltageMV > 100) { 01030 success = setRegisterBits(0x04, (1 << 0)); 01031 #ifdef DEBUG_BQ24295 01032 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold now set to 0.300 V.\r\n", gAddress >> 1); 01033 #endif 01034 } else { 01035 success = clearRegisterBits(0x04, (1 << 0)); 01036 #ifdef DEBUG_BQ24295 01037 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold now set to 0.100 V.\r\n", gAddress >> 1); 01038 #endif 01039 } 01040 gpI2c->unlock(); 01041 } 01042 01043 return success; 01044 } 01045 01046 // Get the recharging voltage threshold. 01047 bool BatteryChargerBq24295::getRechargingVoltageThreshold (int32_t *pVoltageMV) 01048 { 01049 bool success = false; 01050 char reg; 01051 01052 if (gReady && (gpI2c != NULL)) { 01053 gpI2c->lock(); 01054 // VRECHG is bit 0 of the charging voltage control register 01055 if (getRegister(0x04, ®)) { 01056 success = true; 01057 if (pVoltageMV != NULL) { 01058 *pVoltageMV = 100; 01059 if ((reg & (1 << 0)) != 0) { 01060 *pVoltageMV = 300; 01061 } 01062 } 01063 } 01064 01065 #ifdef DEBUG_BQ24295 01066 if (reg & (1 << 1)) { 01067 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold is 0.300 V.\r\n", gAddress >> 1); 01068 } else { 01069 printf("BatteryChargerBq24295 (I2C 0x%02x): recharge voltage threshold is 0.100 V.\r\n", gAddress >> 1); 01070 } 01071 #endif 01072 gpI2c->unlock(); 01073 } 01074 01075 return success; 01076 } 01077 01078 // Set the boost voltage. 01079 bool BatteryChargerBq24295::setBoostVoltage (int32_t voltageMV) 01080 { 01081 bool success = false; 01082 char reg; 01083 int32_t codedValue; 01084 01085 if (gReady && (gpI2c != NULL)) { 01086 gpI2c->lock(); 01087 // Read the boost voltage/thermal regulation control register 01088 if (getRegister(0x06, ®)) { 01089 // Boost voltage is in bits 4 to 7, coded to base "64 mV" 01090 // with an offset of 4550 mV. 01091 if ((voltageMV >= 4550) && (voltageMV <= 5510)) { 01092 codedValue = voltageMV; 01093 codedValue = (codedValue - 4550) / 64; 01094 // If the voltage minus the base is not an exact multiple of 64, 01095 // add one to the coded value to make sure we don't 01096 // go under the requested boost voltage 01097 if ((voltageMV - 4550) % 64 != 0) { 01098 codedValue++; 01099 } 01100 01101 reg &= ~(0x0f << 4); 01102 reg |= (char) ((codedValue & 0x0f) << 4); 01103 01104 // Write to the boost voltage/thermal regulation control register 01105 success = setRegister (0x06, reg); 01106 #ifdef DEBUG_BQ24295 01107 if (success) { 01108 printf("BatteryChargerBq24295 (I2C 0x%02x): boost voltage now set to %.3f V.\r\n", gAddress >> 1, (float) voltageMV / 1000); 01109 } 01110 #endif 01111 } 01112 } 01113 gpI2c->unlock(); 01114 } 01115 01116 return success; 01117 } 01118 01119 // Get the boost voltage. 01120 bool BatteryChargerBq24295::getBoostVoltage (int32_t *pVoltageMV) 01121 { 01122 bool success = false; 01123 char reg; 01124 01125 if (gReady && (gpI2c != NULL)) { 01126 gpI2c->lock(); 01127 // Read the boost voltage/thermal regulation control register 01128 if (getRegister(0x06, ®)) { 01129 success = true; 01130 if (pVoltageMV != NULL) { 01131 // Boost voltage is in bits 4 to 7 01132 // Base voltage 01133 *pVoltageMV = 4550; 01134 // Shift reg down and add the number of multiples 01135 // of 64 mV 01136 reg = (reg >> 4) & 0x0f; 01137 *pVoltageMV += ((int32_t) reg) * 64; 01138 #ifdef DEBUG_BQ24295 01139 printf("BatteryChargerBq24295 (I2C 0x%02x): boost voltage is %.3f V.\r\n", gAddress >> 1, (float) *pVoltageMV / 1000); 01140 #endif 01141 } 01142 } 01143 gpI2c->unlock(); 01144 } 01145 01146 return success; 01147 } 01148 01149 // Set the boost mode low temperature limit. 01150 bool BatteryChargerBq24295::setBoostUpperTemperatureLimit (int32_t temperatureC) 01151 { 01152 bool success = false; 01153 char reg; 01154 char codedValue; 01155 01156 if (gReady && (gpI2c != NULL)) { 01157 gpI2c->lock(); 01158 // Read the boost voltage/thermal regulation control register 01159 if (getRegister(0x06, ®)) { 01160 // BHOT is in bits 2 & 3 01161 if (temperatureC < 60) { 01162 codedValue = 0; 01163 } else if (temperatureC < 65) { 01164 codedValue = 1; 01165 } else { 01166 codedValue = 2; 01167 } 01168 reg &= ~(0x03 << 2); 01169 reg |= (char) (codedValue << 2); 01170 // Write to boost voltage/thermal regulation control register 01171 success = setRegister (0x06, reg); 01172 #ifdef DEBUG_BQ24295 01173 if (success) { 01174 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode lower temperature limit now set to %d C.\r\n", gAddress >> 1, (int) temperatureC); 01175 } 01176 #endif 01177 } 01178 gpI2c->unlock(); 01179 } 01180 01181 return success; 01182 } 01183 01184 // Get the boost mode upper temperature limit. 01185 bool BatteryChargerBq24295::getBoostUpperTemperatureLimit (int32_t *pTemperatureC) 01186 { 01187 bool success = false; 01188 char reg; 01189 01190 if (gReady && (gpI2c != NULL)) { 01191 gpI2c->lock(); 01192 // BHOT is in bits 2 & 3 of the boost voltage/thermal regulation control register 01193 if (getRegister(0x06, ®)) { 01194 // Only proceed (and return true) if the limit is enabled 01195 if (((reg >> 2) & 0x03) != 0x03) { 01196 success = true; 01197 if (pTemperatureC != NULL) { 01198 switch ((reg >> 2) & 0x03) { 01199 case 0: 01200 *pTemperatureC = 55; 01201 break; 01202 case 1: 01203 *pTemperatureC = 60; 01204 break; 01205 case 2: 01206 *pTemperatureC = 65; 01207 break; 01208 default: 01209 MBED_ASSERT(false); 01210 break; 01211 } 01212 #ifdef DEBUG_BQ24295 01213 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode upper temperature limit is %d C.\r\n", gAddress >> 1, (int) *pTemperatureC); 01214 #endif 01215 } 01216 } 01217 } 01218 gpI2c->unlock(); 01219 } 01220 01221 return success; 01222 } 01223 01224 // Check whether the boost mode upper temperature limit is enabled. 01225 bool BatteryChargerBq24295::isBoostUpperTemperatureLimitEnabled (void) 01226 { 01227 bool isEnabled = false; 01228 char reg; 01229 01230 if (gReady && (gpI2c != NULL)) { 01231 gpI2c->lock(); 01232 // BHOT is in bits 2 & 3 of the boost voltage/thermal regulation control register 01233 // and it is enabled if any bit is 0 01234 if (getRegister(0x06, ®)) { 01235 if (((reg >> 2) & 3) != 3) { 01236 isEnabled = true; 01237 } 01238 #ifdef DEBUG_BQ24295 01239 if (isEnabled) { 01240 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode upper temperature limit is ENABLED.\r\n", gAddress >> 1); 01241 } else { 01242 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode upper temperature limit is DISABLED.\r\n", gAddress >> 1); 01243 } 01244 #endif 01245 } 01246 gpI2c->unlock(); 01247 } 01248 01249 return isEnabled; 01250 } 01251 01252 // Disable the boost mode upper temperature limit. 01253 bool BatteryChargerBq24295::disableBoostUpperTemperatureLimit (void) 01254 { 01255 bool success = false; 01256 01257 if (gReady && (gpI2c != NULL)) { 01258 gpI2c->lock(); 01259 // BHOT is in bits 2 & 3 of the boost voltage/thermal regulation control register 01260 // and setting all the bits indicates disabled 01261 success = setRegisterBits(0x06, (3 << 2)); 01262 #ifdef DEBUG_BQ24295 01263 if (success) { 01264 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode upper temperature limit now DISABLED.\r\n", gAddress >> 1); 01265 } 01266 #endif 01267 gpI2c->unlock(); 01268 } 01269 01270 return success; 01271 } 01272 01273 // Set the boost mode upper temperature limit. 01274 bool BatteryChargerBq24295::setBoostLowerTemperatureLimit (int32_t temperatureC) 01275 { 01276 bool success = false; 01277 01278 if (gReady && (gpI2c != NULL)) { 01279 gpI2c->lock(); 01280 // There are only two possible values, -10 C and -20 C. 01281 // BCOLD is bit 1 of the charge current control register 01282 if (temperatureC < -10) { 01283 success = setRegisterBits(0x02, (1 << 1)); 01284 #ifdef DEBUG_BQ24295 01285 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode lower temperature limit now set to -20 C.\r\n", gAddress >> 1); 01286 #endif 01287 } else { 01288 success = clearRegisterBits(0x02, (1 << 1)); 01289 #ifdef DEBUG_BQ24295 01290 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode lower temperature limit now set to -10 C.\r\n", gAddress >> 1); 01291 #endif 01292 } 01293 gpI2c->unlock(); 01294 } 01295 01296 return success; 01297 } 01298 01299 // Get the boost mode low temperature limit. 01300 bool BatteryChargerBq24295::getBoostLowerTemperatureLimit (int32_t *pTemperatureC) 01301 { 01302 bool success = false; 01303 char reg; 01304 01305 if (gReady && (gpI2c != NULL)) { 01306 gpI2c->lock(); 01307 // BCOLD is bit 1 of the charge current control register 01308 if (getRegister(0x02, ®)) { 01309 success = true; 01310 if (pTemperatureC != NULL) { 01311 *pTemperatureC = -10; 01312 if ((reg & (1 << 1)) != 0) { 01313 *pTemperatureC = -20; 01314 } 01315 } 01316 } 01317 01318 #ifdef DEBUG_BQ24295 01319 if (reg & (1 << 1)) { 01320 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode lower temperature limit is -20 C.\r\n", gAddress >> 1); 01321 } else { 01322 printf("BatteryChargerBq24295 (I2C 0x%02x): boost mode lower temperature limit is -10 C.\r\n", gAddress >> 1); 01323 } 01324 #endif 01325 gpI2c->unlock(); 01326 } 01327 01328 return success; 01329 } 01330 01331 // Set the input voltage limit. 01332 bool BatteryChargerBq24295::setInputVoltageLimit (int32_t voltageMV) 01333 { 01334 bool success = false; 01335 char reg; 01336 int32_t codedValue; 01337 01338 if (gReady && (gpI2c != NULL)) { 01339 gpI2c->lock(); 01340 // Read the input source control register 01341 if (getRegister(0x00, ®)) { 01342 // Input voltage limit is in bits 3 to 6 01343 // but it is coded to base "80 mV" with 01344 // an offset of 3880 mV. 01345 if ((voltageMV >= 3880) && (voltageMV <= 5080)) { 01346 codedValue = voltageMV; 01347 codedValue = (codedValue - 3880) / 80; 01348 01349 reg &= ~(0x0f << 3); 01350 reg |= (char) ((codedValue & 0x0f) << 3); 01351 01352 // Write to the input source control register 01353 success = setRegister (0x00, reg); 01354 #ifdef DEBUG_BQ24295 01355 if (success) { 01356 printf("BatteryChargerBq24295 (I2C 0x%02x): input voltage limit now set to %.3f V.\r\n", gAddress >> 1, (float) voltageMV / 1000); 01357 } 01358 #endif 01359 } 01360 } 01361 gpI2c->unlock(); 01362 } 01363 01364 return success; 01365 } 01366 01367 // Get the input voltage limit. 01368 bool BatteryChargerBq24295::getInputVoltageLimit (int32_t *pVoltageMV) 01369 { 01370 bool success = false; 01371 char reg; 01372 01373 if (gReady && (gpI2c != NULL)) { 01374 gpI2c->lock(); 01375 // Read the input source control register 01376 if (getRegister(0x00, ®)) { 01377 success = true; 01378 if (pVoltageMV != NULL) { 01379 // Input voltage limit is in bits 3 to 6 01380 // Base voltage 01381 *pVoltageMV = 3880; 01382 // Shift reg down and add the number of multiples 01383 // of 80 mV 01384 reg = (reg >> 3) & 0x0f; 01385 *pVoltageMV += ((int32_t) reg) * 80; 01386 #ifdef DEBUG_BQ24295 01387 printf("BatteryChargerBq24295 (I2C 0x%02x): input voltage limit is %.3f V.\r\n", gAddress >> 1, (float) *pVoltageMV / 1000); 01388 #endif 01389 } 01390 } 01391 gpI2c->unlock(); 01392 } 01393 01394 return success; 01395 } 01396 01397 // Set the input current limit. 01398 bool BatteryChargerBq24295::setInputCurrentLimit (int32_t currentMA) 01399 { 01400 bool success = false; 01401 char reg; 01402 char codedValue; 01403 01404 if (gReady && (gpI2c != NULL)) { 01405 gpI2c->lock(); 01406 // Read the input source control register 01407 if (getRegister(0x00, ®)) { 01408 // Input current limit is in bits 0 to 2, coded 01409 // such that the smallest limit is applied for 01410 // a range (e.g. 120 mA ends up as 100 mA rather 01411 // than 150 mA) 01412 if ((currentMA >= 100) && (currentMA <= 3000)) { 01413 if (currentMA < 150) { 01414 codedValue = 0; 01415 } else if (currentMA < 500) { 01416 codedValue = 1; 01417 } else if (currentMA < 900) { 01418 codedValue = 2; 01419 } else if (currentMA < 1000) { 01420 codedValue = 3; 01421 } else if (currentMA < 1500) { 01422 codedValue = 4; 01423 } else if (currentMA < 2000) { 01424 codedValue = 5; 01425 } else if (currentMA < 3000) { 01426 codedValue = 6; 01427 } else { 01428 codedValue = 7; 01429 } 01430 reg &= ~(0x07 << 0); 01431 reg |= codedValue; 01432 01433 // Write to the input source control register 01434 success = setRegister (0x00, reg); 01435 #ifdef DEBUG_BQ24295 01436 if (success) { 01437 printf("BatteryChargerBq24295 (I2C 0x%02x): input current limit now set to %.3f A.\r\n", gAddress >> 1, (float) currentMA / 1000); 01438 } 01439 #endif 01440 } 01441 } 01442 gpI2c->unlock(); 01443 } 01444 01445 return success; 01446 } 01447 01448 // Get the input current limit. 01449 bool BatteryChargerBq24295::getInputCurrentLimit (int32_t *pCurrentMA) 01450 { 01451 bool success = false; 01452 char reg; 01453 01454 if (gReady && (gpI2c != NULL)) { 01455 gpI2c->lock(); 01456 // Read the input source control register 01457 if (getRegister(0x00, ®)) { 01458 success = true; 01459 if (pCurrentMA != NULL) { 01460 *pCurrentMA = 0; 01461 // Input current limit is in bits 0 to 2 01462 switch (reg & 0x07) { 01463 case 0: 01464 *pCurrentMA = 100; 01465 break; 01466 case 1: 01467 *pCurrentMA = 150; 01468 break; 01469 case 2: 01470 *pCurrentMA = 500; 01471 break; 01472 case 3: 01473 *pCurrentMA = 900; 01474 break; 01475 case 4: 01476 *pCurrentMA = 1000; 01477 break; 01478 case 5: 01479 *pCurrentMA = 1500; 01480 break; 01481 case 6: 01482 *pCurrentMA = 2000; 01483 break; 01484 case 7: 01485 *pCurrentMA = 3000; 01486 break; 01487 default: 01488 MBED_ASSERT(false); 01489 break; 01490 } 01491 #ifdef DEBUG_BQ24295 01492 printf("BatteryChargerBq24295 (I2C 0x%02x): input current limit is %.3f A.\r\n", gAddress >> 1, (float) *pCurrentMA / 1000); 01493 #endif 01494 } 01495 } 01496 gpI2c->unlock(); 01497 } 01498 01499 return success; 01500 } 01501 01502 // Enable input voltage or current limits. 01503 bool BatteryChargerBq24295::enableInputLimits (void) 01504 { 01505 bool success = false; 01506 01507 if (gReady && (gpI2c != NULL)) { 01508 gpI2c->lock(); 01509 // Input limit enable is bit 7 of the source control register 01510 success = setRegisterBits(0x00, (1 << 7)); 01511 #ifdef DEBUG_BQ24295 01512 if (success) { 01513 printf("BatteryChargerBq24295 (I2C 0x%02x): input limits now ENABLED.\r\n", gAddress >> 1); 01514 } 01515 #endif 01516 gpI2c->unlock(); 01517 } 01518 01519 return success; 01520 } 01521 01522 // Remove any input voltage or current limits. 01523 bool BatteryChargerBq24295::disableInputLimits (void) 01524 { 01525 bool success = false; 01526 01527 if (gReady && (gpI2c != NULL)) { 01528 gpI2c->lock(); 01529 // Input limit enable is bit 7 of the source control register 01530 success = clearRegisterBits(0x00, (1 << 7)); 01531 #ifdef DEBUG_BQ24295 01532 if (success) { 01533 printf("BatteryChargerBq24295 (I2C 0x%02x): input limits now DISABLED.\r\n", gAddress >> 1); 01534 } 01535 #endif 01536 gpI2c->unlock(); 01537 } 01538 01539 return success; 01540 } 01541 01542 // Check if input limits are enabled. 01543 bool BatteryChargerBq24295::areInputLimitsEnabled (void) 01544 { 01545 bool areEnabled = false; 01546 char reg; 01547 01548 if (gReady && (gpI2c != NULL)) { 01549 gpI2c->lock(); 01550 // Read the input source control register 01551 if (getRegister(0x00, ®)) { 01552 // Input limit enable is bit 7 of the source control register 01553 if ((reg & (1 << 7)) != 0) { 01554 areEnabled = true; 01555 } 01556 #ifdef DEBUG_BQ24295 01557 if (areEnabled) { 01558 printf("BatteryChargerBq24295 (I2C 0x%02x): input limits are ENABLED.\r\n", gAddress >> 1); 01559 } else { 01560 printf("BatteryChargerBq24295 (I2C 0x%02x): input limits are DISABLED.\r\n", gAddress >> 1); 01561 } 01562 #endif 01563 } 01564 gpI2c->unlock(); 01565 } 01566 01567 return areEnabled; 01568 } 01569 01570 // Set the thermal regulation threshold for the chip. 01571 bool BatteryChargerBq24295::setChipThermalRegulationThreshold (int32_t temperatureC) 01572 { 01573 bool success = false; 01574 char reg; 01575 char codedValue; 01576 01577 if (gReady && (gpI2c != NULL)) { 01578 gpI2c->lock(); 01579 // Read the boost voltage/thermal regulation control register 01580 if (getRegister(0x06, ®)) { 01581 // TREG is in bits 0 & 1 01582 if (temperatureC < 80) { 01583 codedValue = 0; 01584 } else if (temperatureC < 100) { 01585 codedValue = 1; 01586 } else if (temperatureC < 120) { 01587 codedValue = 2; 01588 } else { 01589 codedValue = 3; 01590 } 01591 reg &= ~0x03; 01592 reg |= (char) codedValue; 01593 // Write to boost voltage/thermal regulation control register 01594 success = setRegister (0x06, reg); 01595 #ifdef DEBUG_BQ24295 01596 if (success) { 01597 printf("BatteryChargerBq24295 (I2C 0x%02x): chip thermal regulation threshold now set to %d C.\r\n", gAddress >> 1, (int) temperatureC); 01598 } 01599 #endif 01600 } 01601 gpI2c->unlock(); 01602 } 01603 01604 return success; 01605 } 01606 01607 // Get the thermal regulation threshold for the chip. 01608 bool BatteryChargerBq24295::getChipThermalRegulationThreshold (int32_t *pTemperatureC) 01609 { 01610 bool success = false; 01611 char reg; 01612 01613 if (gReady && (gpI2c != NULL)) { 01614 gpI2c->lock(); 01615 /// TREG is in bits 0 & 1 of the boost voltage/thermal regulation control register 01616 if (getRegister(0x06, ®)) { 01617 success = true; 01618 if (pTemperatureC != NULL) { 01619 switch (reg & 0x03) { 01620 case 0: 01621 *pTemperatureC = 60; 01622 break; 01623 case 1: 01624 *pTemperatureC = 80; 01625 break; 01626 case 2: 01627 *pTemperatureC = 100; 01628 break; 01629 case 3: 01630 *pTemperatureC = 120; 01631 break; 01632 default: 01633 MBED_ASSERT(false); 01634 break; 01635 } 01636 #ifdef DEBUG_BQ24295 01637 printf("BatteryChargerBq24295 (I2C 0x%02x): chip thermal regulation threshold is %d C.\r\n", gAddress >> 1, (int) *pTemperatureC); 01638 #endif 01639 } 01640 } 01641 gpI2c->unlock(); 01642 } 01643 01644 return success; 01645 } 01646 01647 // Get the charger fault status as a bitmap. 01648 char BatteryChargerBq24295::getChargerFaults(void) 01649 { 01650 char bitmap = (char) CHARGER_FAULT_NONE; 01651 char reg; 01652 01653 if (gReady && (gpI2c != NULL)) { 01654 gpI2c->lock(); 01655 // Read the fault register 01656 if (getRegister(0x09, ®)) { 01657 bitmap = reg; 01658 #ifdef DEBUG_BQ24295 01659 printf("BatteryChargerBq24295 (I2C 0x%02x): charge fault register 0x%02x.\r\n", gAddress >> 1, bitmap); 01660 #endif 01661 } 01662 gpI2c->unlock(); 01663 } 01664 01665 return bitmap; 01666 } 01667 01668 // Feed the watchdog timer of the BQ24295 chip. 01669 bool BatteryChargerBq24295::feedWatchdog (void) 01670 { 01671 bool success = false; 01672 01673 if (gReady && (gpI2c != NULL)) { 01674 gpI2c->lock(); 01675 // Watchdog reset is done by setting bit 6 of the power on control register 01676 // to 1 01677 success = setRegisterBits(0x01, (1 << 6)); 01678 #ifdef DEBUG_BQ24295 01679 if (success) { 01680 printf("BatteryChargerBq24295 (I2C 0x%02x): watchdog fed.\r\n", gAddress >> 1); 01681 } 01682 #endif 01683 gpI2c->unlock(); 01684 } 01685 01686 return success; 01687 } 01688 01689 // Get the watchdog timer of the BQ24295 chip. 01690 bool BatteryChargerBq24295::getWatchdog (int32_t *pWatchdogS) 01691 { 01692 bool success = false; 01693 char reg; 01694 01695 if (gReady && (gpI2c != NULL)) { 01696 gpI2c->lock(); 01697 // Watchdog timer is in bits 4 and 5 of the charger termination/timer control 01698 // register, where 0 is disabled 01 is 40 secs, 10 is 80 secs and 11 is 160 secs 01699 success = getRegister(0x05, ®); 01700 if (pWatchdogS != NULL) { 01701 switch ((reg >> 4) & 0x03) { 01702 case 0x00: 01703 *pWatchdogS = 0; 01704 break; 01705 case 0x01: 01706 *pWatchdogS = 40; 01707 break; 01708 case 0x02: 01709 *pWatchdogS = 80; 01710 break; 01711 case 0x03: 01712 *pWatchdogS = 160; 01713 break; 01714 default: 01715 MBED_ASSERT(false); 01716 break; 01717 } 01718 #ifdef DEBUG_BQ24295 01719 if (success) { 01720 printf("BatteryChargerBq24295 (I2C 0x%02x): watchdog is %d seconds.\r\n", gAddress >> 1, (int) *pWatchdogS); 01721 } 01722 #endif 01723 } 01724 gpI2c->unlock(); 01725 } 01726 01727 return success; 01728 } 01729 01730 // Set the watchdog timer of the BQ24295 chip. 01731 bool BatteryChargerBq24295::setWatchdog (int32_t watchdogS) 01732 { 01733 bool success = false; 01734 char reg; 01735 char regValue = 0; 01736 01737 if (gReady && (gpI2c != NULL)) { 01738 gpI2c->lock(); 01739 // Watchdog timer is in bits 4 and 5 of the charger termination/timer control 01740 // register, where 0 is disabled 01 is 40 secs, 10 is 80 secs and 11 is 160 secs 01741 if (watchdogS > 80) { 01742 regValue = 0x03; 01743 } else if (watchdogS > 40) { 01744 regValue = 0x02; 01745 } else if (watchdogS > 0) { 01746 regValue = 0x01; 01747 } 01748 if (getRegister(0x05, ®)) { 01749 // Clear the bits then set them 01750 reg &= ~(0x03 << 4); 01751 reg |= regValue << 4; 01752 success = setRegister(0x05, reg); 01753 #ifdef DEBUG_BQ24295 01754 if (success) { 01755 printf("BatteryChargerBq24295 (I2C 0x%02x): watchdog set to %d seconds.\r\n", gAddress >> 1, (int) watchdogS); 01756 } 01757 #endif 01758 } 01759 gpI2c->unlock(); 01760 } 01761 01762 return success; 01763 } 01764 01765 // Enable shipping mode. 01766 bool BatteryChargerBq24295::enableShippingMode (void) 01767 { 01768 bool success = false; 01769 01770 if (gReady && (gpI2c != NULL)) { 01771 gpI2c->lock(); 01772 // Have to disable the watchdog (bits 4 & 5 of charge termination/timer control register) 01773 if (clearRegisterBits(0x05, (1 << 4) || (1 << 5))) { 01774 // Now disable the BATFET, bit 5 of the misc operation control register 01775 success = setRegisterBits(0x07, (1 << 5)); 01776 #ifdef DEBUG_BQ24295 01777 if (success) { 01778 printf("BatteryChargerBq24295 (I2C 0x%02x): shipping mode is now ENABLED.\r\n", gAddress >> 1); 01779 } 01780 #endif 01781 } 01782 gpI2c->unlock(); 01783 } 01784 01785 return success; 01786 } 01787 01788 // Disable shipping mode. 01789 bool BatteryChargerBq24295::disableShippingMode (void) 01790 { 01791 bool success = false; 01792 01793 if (gReady && (gpI2c != NULL)) { 01794 gpI2c->lock(); 01795 // Set the watchdog timer back to default (bit 4 of charge termination/timer control register) 01796 if (setRegisterBits(0x05, (1 << 4))) { 01797 // Now enable the BATFET, bit 5 of the misc operation control register 01798 success = clearRegisterBits(0x07, (1 << 5)); 01799 #ifdef DEBUG_BQ24295 01800 if (success) { 01801 printf("BatteryChargerBq24295 (I2C 0x%02x): shipping mode is now DISABLED.\r\n", gAddress >> 1); 01802 } 01803 #endif 01804 } 01805 gpI2c->unlock(); 01806 } 01807 01808 return success; 01809 } 01810 01811 // Check if shipping mode is enabled. 01812 bool BatteryChargerBq24295::isShippingModeEnabled (void) 01813 { 01814 bool isEnabled = false; 01815 char reg; 01816 01817 if (gReady && (gpI2c != NULL)) { 01818 gpI2c->lock(); 01819 // To be in shipping mode the watchdog has to be disabled 01820 if (getRegister(0x05, ®)) { 01821 // Check bits 4 & 5 of the charge termination/timer control register for zero 01822 if ((reg & ((1 << 4) || (1 << 5))) == 0) { 01823 // Now see if the BATFET is disabled (bit 5 of the misc operation control register) 01824 if (getRegister(0x07, ®) && ((reg & (1 << 5)) != 0)) { 01825 isEnabled = true; 01826 } 01827 } 01828 #ifdef DEBUG_BQ24295 01829 if (isEnabled) { 01830 printf("BatteryChargerBq24295 (I2C 0x%02x): shipping mode is ENABLED.\r\n", gAddress >> 1); 01831 } else { 01832 printf("BatteryChargerBq24295 (I2C 0x%02x): shipping mode is DISABLED.\r\n", gAddress >> 1); 01833 } 01834 #endif 01835 } 01836 gpI2c->unlock(); 01837 } 01838 01839 return isEnabled; 01840 } 01841 01842 // Read a register on the chip. 01843 bool BatteryChargerBq24295::advancedGet(char address, char *pValue) 01844 { 01845 bool success = false; 01846 char value; 01847 01848 if (gReady && (gpI2c != NULL)) { 01849 gpI2c->lock(); 01850 // Read the register 01851 if (getRegister(address, &value)) { 01852 success = true; 01853 #ifdef DEBUG_BQ24295 01854 printf("BatteryChargerBq24295 (I2C 0x%02x): read 0x%02x from address 0x%02x.\n", gAddress >> 1, value, address); 01855 #endif 01856 if (pValue != NULL) { 01857 *pValue = value; 01858 } 01859 } 01860 gpI2c->unlock(); 01861 } 01862 01863 return success; 01864 } 01865 01866 // Set a register on the chip. 01867 // TODO test 01868 bool BatteryChargerBq24295::advancedSet(char address, char value) 01869 { 01870 bool success = false; 01871 01872 if (gReady && (gpI2c != NULL)) { 01873 gpI2c->lock(); 01874 // Set the register 01875 success = setRegister (address, value); 01876 #ifdef DEBUG_BQ24295 01877 if (success) { 01878 printf("BatteryChargerBq24295 (I2C 0x%02x): wrote 0x%02x to address 0x%02x.\n", gAddress >> 1, value, address); 01879 } 01880 #endif 01881 gpI2c->unlock(); 01882 } 01883 01884 return success; 01885 } 01886 01887 /* End Of File */
Generated on Thu Jul 14 2022 05:28:56 by
1.7.2