This class provides APIs to all of the registers of the TI BQ24295 battery charger chip, as used on the u-blox C030 board. This class is not required to charge a battery connected to the C030 board, charging will begin automatically when a battery is connected. This class is only required if the user wishes to monitor the charger's state or change the charger's settings. The caller should instantiate an I2C interface and pass this to init(), which will initialise the chip and place it into its lowest power state. The chip may then be configured using the API calls. Once the chip is configured, battery charging can be enabled. If battery charging is disabled the chip will once more be put into its lowest power state.
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