A feature complete driver for the MAX17048 lithium fuel gauge from Maxim.

Dependents:   MAX17048_HelloWorld ECGAFE_copy MAX17048_HelloWorld Orion_newPCB_test_LV ... more

Now fully tested!

Files at this revision

API Documentation at this revision

Comitter:
neilt6
Date:
Wed Aug 07 22:19:36 2013 +0000
Child:
1:734b1a089a9c
Commit message:
Initial commit

Changed in this revision

MAX17048.cpp Show annotated file Show diff for this revision Revisions of this file
MAX17048.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX17048.cpp	Wed Aug 07 22:19:36 2013 +0000
@@ -0,0 +1,504 @@
+/* MAX17048 Driver Library
+ * Copyright (c) 2013 Neil Thiessen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MAX17048.h"
+#include "mbed.h"
+
+MAX17048::MAX17048(PinName sda, PinName scl) : _i2c(sda, scl)
+{
+    //Nothing else to initialize
+}
+
+void MAX17048::reset(void)
+{
+    //Write the POR command
+    _write(__MAX17048_REG_CMD, 0x5400);
+}
+
+void MAX17048::quickStart(void)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_MODE);
+
+    //Set the QuickStart bit
+    value |= (1 << 14);
+
+    //Write the value back out
+    _write(__MAX17048_REG_MODE, value);
+}
+
+bool MAX17048::isSleepEnabled(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_MODE);
+
+    //Return the status of the EnSleep bit
+    if (value & (1 << 13))
+        return true;
+    else
+        return false;
+}
+
+void MAX17048::setSleepEnabled(bool enabled)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_MODE);
+
+    //Set or clear the EnSleep bit
+    if (enabled)
+        value |= (1 << 13);
+    else
+        value &= ~(1 << 13);
+
+    //Write the value back out
+    _write(__MAX17048_REG_MODE, value);
+}
+
+bool MAX17048::isHibernating(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_MODE);
+
+    //Return the status of the HibStat bit
+    if (value & (1 << 12))
+        return true;
+    else
+        return false;
+}
+
+float MAX17048::getHibernateThreshold(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_HIBRT);
+
+    //Extract the hibernate threshold
+    return (value >> 8) * 0.208;
+}
+
+void MAX17048::setHibernateThreshold(float threshold)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_HIBRT);
+
+    //Mask off the old value
+    value &= 0x00FF;
+
+    //Do a smart update
+    if (threshold > 0.0) {
+        if (threshold < 53.04)
+            value |= (unsigned short)(threshold / 0.208) << 8;
+        else
+            value |= 0xFF00;
+    }
+
+    //Write the 16-bit register
+    _write(__MAX17048_REG_HIBRT, value);
+}
+
+float MAX17048::getActiveThreshold(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_HIBRT);
+
+    //Extract the active threshold
+    return (value & 0x00FF) * 0.00125;
+}
+
+void MAX17048::setActiveThreshold(float threshold)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_HIBRT);
+
+    //Mask off the old value
+    value &= 0xFF00;
+
+    //Do a smart update
+    if (threshold > 0.0) {
+        if (threshold < 0.31875)
+            value |= (char)(threshold / 0.00125);
+        else
+            value |= 0x00FF;
+    }
+
+    //Write the 16-bit register
+    _write(__MAX17048_REG_HIBRT, value);
+}
+
+unsigned short MAX17048::getVersion(void)
+{
+    //Return the 16-bit production version
+    return _read(__MAX17048_REG_VERSION);
+}
+
+void MAX17048::setTempCompensation(float temp)
+{
+    //Calculate the new RCOMP value
+    char rcomp;
+    if (temp > 20.0) {
+        rcomp = __MAX17048_RCOMP0 + (temp - 20.0) * -0.5;
+    } else {
+        rcomp = __MAX17048_RCOMP0 + (temp - 20.0) * -5.0;
+    }
+
+    //Update the RCOMP value
+    _writeRCOMP(rcomp);
+}
+
+bool MAX17048::isSleeping(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Return the status of the SLEEP bit
+    if (value & (1 << 7))
+        return true;
+    else
+        return false;
+}
+
+void MAX17048::setSleep(bool sleep)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Set or clear the SLEEP bit
+    if (sleep)
+        value |= (1 << 7);
+    else
+        value &= ~(1 << 7);
+
+    //Write the value back out
+    _write(__MAX17048_REG_CONFIG, value);
+}
+
+bool MAX17048::isSOCChangeAlertEnabled(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Return the status of the ALSC bit
+    if (value & (1 << 6))
+        return true;
+    else
+        return false;
+}
+
+void MAX17048::setSOCChangeAlertEnabled(bool enabled)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Set or clear the ALSC bit
+    if (enabled)
+        value |= (1 << 6);
+    else
+        value &= ~(1 << 6);
+
+    //Write the value back out
+    _write(__MAX17048_REG_CONFIG, value);
+}
+
+bool MAX17048::isAlerting(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Return the status of the ALRT bit
+    if (value & (1 << 5))
+        return true;
+    else
+        return false;
+}
+
+void MAX17048::clearAlert(void)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Clear the ALRT bit
+    value &= ~(1 << 5);
+
+    //Write the value back out
+    _write(__MAX17048_REG_CONFIG, value);
+}
+
+char MAX17048::getEmptyAlertThreshold(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Extract the threshold
+    return 32 - (value & 0x001F);
+}
+
+void MAX17048::setEmptyAlertThreshold(char threshold)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Range check threshold
+    if (threshold < 1)
+        threshold = 1;
+    else if (threshold > 32)
+        threshold = 32;
+
+    //Update the register value
+    value &= 0xFFE0;
+    value |= 32 - threshold;
+
+    //Write the 16-bit register
+    _write(__MAX17048_REG_CONFIG, value);
+}
+
+float MAX17048::getVAlertMinThreshold(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VALRT);
+
+    //Extract the alert threshold
+    return (value >> 8) * 0.02;
+}
+
+void MAX17048::setVAlertMinThreshold(float threshold)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VALRT);
+
+    //Mask off the old value
+    value &= 0x00FF;
+
+    //Do a smart update
+    if (threshold > 0.0) {
+        if (threshold < 5.1)
+            value |= (unsigned short)(threshold / 0.02) << 8;
+        else
+            value |= 0xFF00;
+    }
+
+    //Write the 16-bit register
+    _write(__MAX17048_REG_VALRT, value);
+}
+
+float MAX17048::getVAlertMaxThreshold(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VALRT);
+
+    //Extract the active threshold
+    return (value & 0x00FF) * 0.02;
+}
+
+void MAX17048::setVAlertMaxThreshold(float threshold)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VALRT);
+
+    //Mask off the old value
+    value &= 0xFF00;
+
+    //Do a smart update
+    if (threshold > 0.0) {
+        if (threshold < 5.1)
+            value |= (char)(threshold / 0.02);
+        else
+            value |= 0x00FF;
+    }
+
+    //Write the 16-bit register
+    _write(__MAX17048_REG_VALRT, value);
+}
+
+float MAX17048::getVResetThreshold(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VRESET_ID);
+
+    //Extract the threshold
+    return (value >> 9) * 0.04;
+}
+
+void MAX17048::setVResetThreshold(float threshold)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VRESET_ID);
+
+    //Mask off the old value
+    value &= 0x01FF;
+
+    //Do a smart update
+    if (threshold > 0.0) {
+        if (threshold < 5.08)
+            value |= (unsigned short)(threshold / 0.04) << 9;
+        else
+            value |= 0xFE00;
+    }
+
+    //Write the 16-bit register
+    _write(__MAX17048_REG_VRESET_ID, value);
+}
+
+bool MAX17048::isComparatorEnabled(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VRESET_ID);
+
+    //Return the status of the Dis bit
+    if (value & (1 << 8))
+        return false;
+    else
+        return true;
+}
+
+void MAX17048::setComparatorEnabled(bool enabled)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VRESET_ID);
+
+    //Set or clear the Dis bit
+    if (enabled)
+        value &= ~(1 << 8);
+    else
+        value |= (1 << 8);
+
+    //Write the value back out
+    _write(__MAX17048_REG_VRESET_ID, value);
+}
+
+char MAX17048::getID(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_VRESET_ID);
+
+    //Return only the ID bits
+    return value;
+}
+
+bool MAX17048::isVResetAlertEnabled(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_STATUS);
+
+    //Return the status of the EnVR bit
+    if (value & (1 << 14))
+        return true;
+    else
+        return false;
+}
+
+void MAX17048::setVResetAlertEnabled(bool enabled)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_STATUS);
+
+    //Set or clear the EnVR bit
+    if (enabled)
+        value |= (1 << 14);
+    else
+        value &= ~(1 << 14);
+
+    //Write the value back out
+    _write(__MAX17048_REG_STATUS, value);
+}
+
+char MAX17048::getAlertFlags(void)
+{
+    //Read the 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_STATUS);
+
+    //Return only the flag bits
+    return (value >> 8) & 0x3F;
+}
+
+void MAX17048::clearAlertFlags(char flags)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_STATUS);
+
+    //Clear the specified flag bits
+    value &= ~((flags & 0x3F) << 8);
+
+    //Write the value back out
+    _write(__MAX17048_REG_STATUS, value);
+}
+
+float MAX17048::getVcell(void)
+{
+    //Read the 16-bit raw Vcell value
+    unsigned short value = _read(__MAX17048_REG_VCELL);
+
+    //Return Vcell in volts
+    return value * 0.000078125;
+}
+
+float MAX17048::getSOC(void)
+{
+    //Read the 16-bit raw SOC value
+    unsigned short value = _read(__MAX17048_REG_SOC);
+
+    //Return SOC in percent
+    return value * 0.00390625;
+}
+
+float MAX17048::getCRate(void)
+{
+    //Read the 16-bit raw C/Rate value
+    short value = _read(__MAX17048_REG_CRATE);
+
+    //Return C/Rate in %/hr
+    return value * 0.208;
+}
+
+unsigned short MAX17048::_read(char reg)
+{
+    //Create a temporary buffer
+    char buff[2];
+
+    //Select the register
+    _i2c.write(__MAX17048_ADDR, &reg, 1);
+
+    //Read the 16-bit register
+    _i2c.read(__MAX17048_ADDR, buff, 2);
+
+    //Return the combined 16-bit value
+    return (buff[0] << 8) | buff[1];
+}
+
+void MAX17048::_write(char reg, unsigned short data)
+{
+    //Create a temporary buffer
+    char buff[3];
+
+    //Load the register address and 16-bit data
+    buff[0] = reg;
+    buff[1] = data >> 8;
+    buff[2] = data;
+
+    //Write the data
+    _i2c.write(__MAX17048_ADDR, buff, 3);
+}
+
+void MAX17048::_writeRCOMP(char rcomp)
+{
+    //Read the current 16-bit register value
+    unsigned short value = _read(__MAX17048_REG_CONFIG);
+
+    //Update the register value
+    value &= 0x00FF;
+    value |= rcomp << 8;
+
+    //Write the value back out
+    _write(__MAX17048_REG_CONFIG, value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX17048.h	Wed Aug 07 22:19:36 2013 +0000
@@ -0,0 +1,313 @@
+/* MAX17048 Driver Library
+ * Copyright (c) 2013 Neil Thiessen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MAX17048_H
+#define MAX17048_H
+
+#include "mbed.h"
+
+//i2c address definition
+#define __MAX17048_ADDR             (0x36 << 1)
+
+//i2c register definitions
+#define __MAX17048_REG_VCELL        0x02
+#define __MAX17048_REG_SOC          0x04
+#define __MAX17048_REG_MODE         0x06
+#define __MAX17048_REG_VERSION      0x08
+#define __MAX17048_REG_HIBRT        0x0A
+#define __MAX17048_REG_CONFIG       0x0C
+#define __MAX17048_REG_VALRT        0x14
+#define __MAX17048_REG_CRATE        0x16
+#define __MAX17048_REG_VRESET_ID    0x18
+#define __MAX17048_REG_STATUS       0x1A
+#define __MAX17048_REG_TABLE        0x40
+#define __MAX17048_REG_CMD          0xFE
+
+//RCOMP0 value definition
+#define __MAX17048_RCOMP0           0x97
+
+/** MAX17048 class.
+ *  Used for controlling a MAX17048 fuel gauge connected via I2C.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "MAX17048.h"
+ *
+ * Serial pc(USBTX, USBRX);
+ * MAX17048 gauge(p28, p27);
+ *
+ * int main() {
+ *     while (1) {
+ *         //Read the cell voltage
+ *         float vcell = gauge.getVcell();
+ *
+ *         //Print the cell voltage
+ *         pc.printf("Vcell = %f\n", vcell);
+ *
+ *         //Sleep for 0.5 seconds
+ *         wait(0.5);
+ *     }
+ * }
+ * @endcode
+ */
+class MAX17048
+{
+public:
+    /** Represents the different alert flags for the MAX17048
+     */
+    enum AlertFlags {
+        ALERT_RI = (1 << 0),  /**< Reset indicator */
+        ALERT_VH = (1 << 1),  /**< Voltage high alert */
+        ALERT_VL = (1 << 2),  /**< Voltage low alert */
+        ALERT_VR = (1 << 3),  /**< Voltage reset alert */
+        ALERT_HD = (1 << 4),  /**< SOC low alert */
+        ALERT_SC = (1 << 5)   /**< SOC change alert */
+    };
+
+    /** Create a MAX17048 object connected to the specified I2C pins
+     *
+     * @param sda I2C data pin
+     * @param scl I2C clock pin
+     */
+    MAX17048(PinName sda, PinName scl);
+
+    /** Command the MAX17048 to perform a power-on reset
+     */
+    void reset(void);
+
+    /** Command the MAX17048 to perform a QuickStart
+     */
+    void quickStart(void);
+
+    /** Determine whether sleep mode is enabled on the MAX17048
+    *
+    * @returns
+    *   'true' if sleep mode is enabled,
+    *   'false' if sleep mode is disabled.
+    */
+    bool isSleepEnabled(void);
+
+    /** Enable or disable sleep mode on the MAX17048
+     *
+     * @param enabled Whether or not sleep mode is enabled.
+     */
+    void setSleepEnabled(bool enabled);
+    
+    /** Determine whether or not the MAX17048 is hibernating
+    *
+    * @returns
+    *   'true' if hibernating,
+    *   'false' if not hibernating.
+    */
+    bool isHibernating(void);
+    
+    /** Get the current hibernate threshold of the MAX17048
+    *
+    * @returns The current hibernate threshold in \%/hr.
+    */
+    float getHibernateThreshold(void);
+    
+    /** Set the hibernate threshold of the MAX17048
+     *
+     * @param threshold The new hibernate threshold in \%/hr.
+     */
+    void setHibernateThreshold(float threshold);
+    
+    /** Get the current active threshold of the MAX17048
+    *
+    * @returns The current active threshold in volts.
+    */
+    float getActiveThreshold(void);
+    
+    /** Set the active threshold of the MAX17048
+     *
+     * @param threshold The new active threshold in volts.
+     */
+    void setActiveThreshold(float threshold);
+    
+    /** Get the production version of the MAX17048
+    *
+    * @returns The 16-bit production version.
+    */
+    unsigned short getVersion(void);
+    
+    /** Set the cell temperature compensation of the MAX17048
+     *
+     * @param temp The current cell temperature in °C.
+     */
+    void setTempCompensation(float temp);
+    
+    /** Determine whether or not the MAX17048 is in sleep mode
+    *
+    * @returns
+    *   'true' if in sleep mode,
+    *   'false' if not in sleep mode.
+    */
+    bool isSleeping(void);
+    
+    /** Enter or exit sleep mode on the MAX17048 (sleep mode must be enabled first)
+     *
+     * @param sleep Whether or not to sleep.
+     */
+    void setSleep(bool sleep);
+    
+    /** Determine whether or not the SOC 1% change alert is enabled on the MAX17048
+    *
+    * @returns
+    *   'true' if enabled,
+    *   'false' if not enabled.
+    */
+    bool isSOCChangeAlertEnabled(void);
+    
+    /** Enable or disable the SOC 1% change alert on the MAX17048
+     *
+     * @param enabled Whether or the SOC 1% change alert is enabled.
+     */
+    void setSOCChangeAlertEnabled(bool enabled);
+    
+    /** Determine whether or not the MAX17048 is asserting the ALRT pin
+    *
+    * @returns
+    *   'true' if alerting,
+    *   'false' if not alerting.
+    */
+    bool isAlerting(void);
+    
+    /** Command the MAX17048 to de-assert the ALRT pin
+    */
+    void clearAlert(void);
+    
+    /** Get the current SOC empty alert threshold of the MAX17048
+    *
+    * @returns The current SOC empty alert threshold in %.
+    */
+    char getEmptyAlertThreshold(void);
+    
+    /** Set the SOC empty alert threshold of the MAX17048
+     *
+     * @param threshold The new SOC empty alert threshold in %.
+     */
+    void setEmptyAlertThreshold(char threshold);
+    
+    /** Get the current low voltage alert threshold of the MAX17048
+    *
+    * @returns The current low voltage alert threshold in volts.
+    */
+    float getVAlertMinThreshold(void);
+    
+    /** Set the low voltage alert threshold of the MAX17048
+     *
+     * @param threshold The new low voltage alert threshold in volts.
+     */
+    void setVAlertMinThreshold(float threshold);
+    
+    /** Get the current high voltage alert threshold of the MAX17048
+    *
+    * @returns The current high voltage alert threshold in volts.
+    */
+    float getVAlertMaxThreshold(void);
+    
+    /** Set the high voltage alert threshold of the MAX17048
+     *
+     * @param threshold The new high voltage alert threshold in volts.
+     */
+    void setVAlertMaxThreshold(float threshold);
+    
+    /** Get the current reset voltage threshold of the MAX17048
+    *
+    * @returns The current reset voltage threshold in volts.
+    */
+    float getVResetThreshold(void);
+    
+    /** Set the reset voltage threshold of the MAX17048
+     *
+     * @param threshold The new reset voltage threshold in volts.
+     */
+    void setVResetThreshold(float threshold);
+    
+    /** Determine whether or not the reset voltage comparator is enabled on the MAX17048
+    *
+    * @returns
+    *   'true' if enabled,
+    *   'false' if not enabled.
+    */
+    bool isComparatorEnabled(void);
+    
+    /** Enable or disable the reset voltage comparator on the MAX17048
+     *
+     * @param enabled Whether or not the reset voltage comparator is enabled.
+     */
+    void setComparatorEnabled(bool enabled);
+    
+    /** Get the factory programmed 8-bit ID of the MAX17048
+    *
+    * @returns The 8-bit ID.
+    */
+    char getID(void);
+    
+    /** Determine whether or not the voltage reset alert is enabled on the MAX17048
+    *
+    * @returns
+    *   'true' if enabled,
+    *   'false' if not enabled.
+    */
+    bool isVResetAlertEnabled(void);
+    
+    /** Enable or disable the voltage reset alert on the MAX17048
+     *
+     * @param enabled Whether or the voltage reset alert is enabled.
+     */
+    void setVResetAlertEnabled(bool enabled);
+    
+    /** Get the current alert flags on the MAX17048
+    *
+    * @returns The current alert flags as AlertFlags enum values OR'd together.
+    */
+    char getAlertFlags(void);
+    
+    /** Clear the specified alert flags on the MAX17048
+     *
+     * @param flags The alert flags to clear as AlertFlags enum values OR'd together.
+     */
+    void clearAlertFlags(char flags);
+
+    /** Get the current cell voltage measurement of the MAX17048
+    *
+    * @returns The cell voltage measurement as a float.
+    */
+    float getVcell(void);
+
+    /** Get the current state of charge measurement of the MAX17048
+     *
+     * @returns The state of charge measurement as a float.
+     */
+    float getSOC(void);
+
+    /** Get the current C rate measurement of the MAX17048
+     *
+     * @returns The C rate measurement as a float.
+     */
+    float getCRate(void);
+
+private:
+    I2C _i2c;
+    unsigned short _read(char reg);
+    void _write(char reg, unsigned short data);
+    void _writeRCOMP(char rcomp);
+};
+
+#endif