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!

MAX17048.cpp

Committer:
neilt6
Date:
2013-08-07
Revision:
0:abc480f8eeab
Child:
2:0a98e081b48c

File content as of revision 0:abc480f8eeab:

/* 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);
}