Library to interface Lineair LTC2990 battery monitor.

LTC2990.cpp

Committer:
gizmo69the2nd
Date:
2013-08-07
Revision:
0:8cb0dbc1b2ba

File content as of revision 0:8cb0dbc1b2ba:

/*
 * LTC2990 voltage/temprature monitor library
 *
 *
 * Copyright (c) 2013 Davy Van Belle, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/** @file
 * @brief LTC29990 I2C
 */
 
#include "mbed.h"
#include "LTC2990.h"

LTC2990::LTC2990 (I2C* i2c, char addr)
{
    _i2c = i2c;
    _addr = addr;
}

void LTC2990::init (char control)
{
    char cmd[2];
    cmd[0] = CONTROL;
    cmd[1] = control;
    _i2c->write(_addr,cmd,2);
}    

char LTC2990::status()
{
    char status;
    _i2c->write(_addr,STATUS,1,true);
    _i2c->read(_addr+1,&status,1);
    return status;
}

void LTC2990::start()
{
    char cmd[3];
    cmd[0] = TRIGGER;
    cmd[1] = 0x55;
    cmd[2] = 0xAA;
    _i2c->write(_addr,cmd,2);
}


float LTC2990::getTemperature(T_SOURCE source)
{
    char cmd[2];
    char buff[2];
    
        
    switch (source)
    {
    case INT: cmd[0] = TINT_MSB; break;
    case TR1: cmd[0] = V1_MSB; break;
    case TR2: cmd[0] = V3_MSB; break;
    default: return 999.8;
    }
    
    cmd[1] = cmd[0]+1;
    
    bool sign;
    short tmp;
    //MSB
    _i2c->write(_addr,&cmd[0],1,true);
    _i2c->read(_addr+1,&buff[0],1); 
    //LSB
    _i2c->write(_addr,&cmd[1],1,true); 
    _i2c->read(_addr+1,&buff[1],1);
    sign = buff[0] & 0x10;
    tmp = ((buff[0] & 0x0F) << 8) | buff[1];
    if(!sign) return (float)tmp/16;                   //positive temp calulation.
    else return ((float)tmp-4096)/16;                 //negative temp calculation.

}


float LTC2990::getVoltage(V_SOURCE source)
{
    char cmd[2];
    char buff[2];
    float factor;
        
    switch (source)
    {
    case V1: cmd[0] = V1_MSB; factor = SINGLE; break;
    case V2: cmd[0] = V2_MSB; factor = SINGLE; break;
    case V3: cmd[0] = V3_MSB; factor = SINGLE; break;
    case V4: cmd[0] = V4_MSB; factor = SINGLE; break;
    case VCC: cmd[0] = VCC_MSB; factor = SINGLE; break;
    case V1_V2: cmd[0] = V1_MSB; factor = DIFF; break;
    case V3_V4: cmd[0] = V2_MSB; factor = DIFF; break;
    default: return 9999;
    }
    
    cmd[1] = cmd[0]+1;
    bool sign;
    short tmp;
    //MSB
    _i2c->write(_addr,&cmd[0],1,true);
    _i2c->read(_addr+1,&buff[0],1); 
    //LSB
    _i2c->write(_addr,&cmd[1],1,true); 
    _i2c->read(_addr+1,&buff[1],1);
    sign = buff[0] & 0x40;
    tmp = ((buff[0] & 0x3F) << 8) | buff[1];
    if (source != VCC)
    {
        if (!sign) return (float)tmp * factor;
        else return ((float)tmp - 16384) * factor;  
    }
    else
    {
        return ((float)tmp * factor) + 2.5;
    }
}

bool LTC2990::isBusy()
{
    return (status() & 0x01);
}

bool LTC2990::isReady(V_SOURCE source)
{
    switch (source)
    {
        case V1: return (status() & 0x04);
        case V2: return (status() & 0x08);
        case V3: return (status() & 0x10);
        case V4: return (status() & 0x20);
        case VCC: return (status() & 0x40);
        case V1_V2: return (status() & 0x04);
        case V3_V4: return (status() & 0x10);
        default: return 0;
    }      
}


bool LTC2990::isReady(T_SOURCE source)
{
    switch (source)
    {
        case INT: return (status() & 0x02);
        case TR1: return (status() & 0x04);
        case TR2: return (status() & 0x010);
        default: return 0;
    }
}