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!

Revision:
0:abc480f8eeab
Child:
2:0a98e081b48c
--- /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);
+}