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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bq24295.cpp Source File

bq24295.cpp

Go to the documentation of this file.
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg);
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, &reg)) {
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, &reg)) {
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) && ((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 */