Sven Lack / INA3221

Dependents:   INA3221_Tester

Files at this revision

API Documentation at this revision

Comitter:
anti007
Date:
Wed Jan 31 20:36:07 2018 +0000
Commit message:
Version 1.0

Changed in this revision

INA3221.cpp Show annotated file Show diff for this revision Revisions of this file
INA3221.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INA3221.cpp	Wed Jan 31 20:36:07 2018 +0000
@@ -0,0 +1,857 @@
+/* 
+    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.
+*/
+ 
+//=============================================================================
+// INA3221 Library
+// by Sven Lack
+//=============================================================================
+
+#include "INA3221.h"
+
+/**************************************************************************/
+/*! 
+    @brief  Instantiates a new INA3221 object
+*/
+/**************************************************************************/
+INA3221::INA3221(PinName sda, PinName scl, uint8_t addr, float shuntresistor_1, float shuntresistor_2, float shuntresistor_3) {
+
+    _INA3221_i2caddr = addr;
+    _INA3221_shuntresistor_1 = shuntresistor_1;
+    _INA3221_shuntresistor_2 = shuntresistor_2;
+    _INA3221_shuntresistor_3 = shuntresistor_3;
+    _i2c = new I2C(sda, scl);
+    //100KHz, as specified by the datasheet.
+    _i2c->frequency(100000);
+}
+
+/**************************************************************************/
+/*! 
+    @brief Set shunt resistor values (default 0.1 Ohm)
+*/
+/**************************************************************************/
+void INA3221::SetShuntValues (float shuntresistor_1, float shuntresistor_2, float shuntresistor_3)
+{
+    _INA3221_shuntresistor_1 = shuntresistor_1;
+    _INA3221_shuntresistor_2 = shuntresistor_2;
+    _INA3221_shuntresistor_3 = shuntresistor_3; 
+}
+
+/**************************************************************************/
+/*! 
+    @brief Set the I2C Address (8 Bit) (default (0x80))
+*/
+/**************************************************************************/
+void INA3221::SetI2CAdr (uint8_t addr)
+{
+    _INA3221_i2caddr = addr;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Write a 16 bit value over I2C to reg 
+*/
+/**************************************************************************/
+void INA3221::WriteRegister (uint8_t reg, uint16_t value)
+{
+    char tx[3];
+   
+    tx[0]=reg;                              // Set register pointer to reg
+    tx[1]=((value >> 8) & 0xFF);
+    tx[2]=(value & 0xFF);
+    _i2c->write(_INA3221_i2caddr,tx,3);     // Write word to pointer position 
+  
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads a 16 bit value over I2C
+*/
+/**************************************************************************/
+uint16_t INA3221::ReadRegister(uint8_t reg)
+{
+    char tx[1];
+    char rx[2];
+    
+    tx[0]=reg;
+    _i2c->write(_INA3221_i2caddr,tx,1);     // Set register pointer to reg
+    _i2c->read(_INA3221_i2caddr,rx,2);      // Read word from pointer positiom
+    return (int)rx[0]<<8|(int)rx[1];
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Manufacturer ID -> INA3221_REG_MANUFACTURER_ID_VALUE (0x5449)
+*/
+/**************************************************************************/
+uint16_t INA3221::GetManufacturerID(void)
+{
+    return ReadRegister(INA3221_REG_MANUFACTURER_ID);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Die ID -> INA3221_REG_DIE_ID_VALUE (0x3220)
+*/
+/**************************************************************************/
+uint16_t INA3221::GetDieID(void)
+{
+    return ReadRegister(INA3221_REG_DIE_ID);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Check connection
+    Return: 1 - Connection OK 
+            0 - no Connection
+*/
+/**************************************************************************/
+uint8_t INA3221::CheckConnection(void)
+{
+    return ((GetManufacturerID() == INA3221_REG_MANUFACTURER_ID_VALUE) && (GetDieID() == INA3221_REG_DIE_ID_VALUE));
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from shunt voltage register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawShuntVoltage(uint8_t channel)
+{
+    switch(channel){
+        case 1: return ((int16_t)ReadRegister(INA3221_REG_SHUNTVOLTAGE_1)>>3); 
+        case 2: return ((int16_t)ReadRegister(INA3221_REG_SHUNTVOLTAGE_2)>>3); 
+        case 3: return ((int16_t)ReadRegister(INA3221_REG_SHUNTVOLTAGE_3)>>3); 
+        default: return 0;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get voltage from Shunt voltage register (Convert raw value to voltage) 
+    Return: Voltage from Shunt voltage register 
+*/
+/**************************************************************************/
+float INA3221::GetShuntVoltage(uint8_t channel)
+{
+    return ((float)GetRawShuntVoltage(channel)*INA3221_SHUNT_VOLTAGE_LSB);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get current from Shunt voltage register (Convert voltage value to current) 
+    Return: Current through shunt resistor
+*/
+/**************************************************************************/
+float INA3221::GetCurrent(uint8_t channel)
+{
+    float voltage = GetShuntVoltage(channel);
+
+    switch(channel){
+        case 1: return (voltage / _INA3221_shuntresistor_1); 
+        case 2: return (voltage / _INA3221_shuntresistor_2);
+        case 3: return (voltage / _INA3221_shuntresistor_3); 
+        default: return 0.0;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from bus voltage register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawBusVoltage(uint8_t channel)
+{
+    switch(channel){
+        case 1: return ((int16_t)ReadRegister(INA3221_REG_BUSVOLTAGE_1)>>3);
+        case 2: return ((int16_t)ReadRegister(INA3221_REG_BUSVOLTAGE_2)>>3);
+        case 3: return ((int16_t)ReadRegister(INA3221_REG_BUSVOLTAGE_3)>>3);
+        default: return 0;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get voltage from bus voltage register (Convert raw value to voltage) 
+    Return: Voltage from Bus voltage register  
+*/
+/**************************************************************************/
+float INA3221::GetBusVoltage(uint8_t channel)
+{
+    return ((float)GetRawBusVoltage(channel)*INA3221_BUS_VOLTAGE_LSB);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from critical alert limit register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawCriticalAlertLimit(uint8_t channel)
+{
+    switch(channel){
+        case 1: return ((int16_t)ReadRegister(INA3221_REG_CRITICAL_1)>>3);
+        case 2: return ((int16_t)ReadRegister(INA3221_REG_CRITICAL_2)>>3);
+        case 3: return ((int16_t)ReadRegister(INA3221_REG_CRITICAL_3)>>3);
+        default: return 0;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get current setpoint from the critical alert limit register (Convert raw value to current) 
+    Return: Current setpoint for critical alert limit
+*/
+/**************************************************************************/
+float INA3221::GetCurrentCriticalAlertLimit(uint8_t channel)
+{
+    float voltage=((float)GetRawCriticalAlertLimit(channel))*INA3221_SHUNT_VOLTAGE_LSB; 
+    switch(channel){
+        case 1: return (voltage / _INA3221_shuntresistor_1);
+        case 2: return (voltage / _INA3221_shuntresistor_2);
+        case 3: return (voltage / _INA3221_shuntresistor_3);
+        default: return 0;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set raw register value to critical alert limit register 
+*/
+/**************************************************************************/
+void INA3221::SetRawCriticalAlertLimit(uint8_t channel, uint16_t value)
+{
+    value = value << 3;
+    switch(channel){
+        case 1: WriteRegister(INA3221_REG_CRITICAL_1,value); break;
+        case 2: WriteRegister(INA3221_REG_CRITICAL_2,value); break;
+        case 3: WriteRegister(INA3221_REG_CRITICAL_3,value); break;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set current value to critical alert register 
+*/
+/**************************************************************************/
+void INA3221::SetCurrentCriticalAlertLimit(uint8_t channel, float current )
+{
+    float value;
+    switch(channel){
+        case 1: value = _INA3221_shuntresistor_1; break;
+        case 2: value = _INA3221_shuntresistor_2; break;
+        case 3: value = _INA3221_shuntresistor_3; break;
+    }
+    
+    value = ((value*current) / (INA3221_SHUNT_VOLTAGE_LSB));
+    SetRawCriticalAlertLimit(channel, (uint16_t)value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from warning alert limit register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawWarningAlertLimit(uint8_t channel)
+{
+    switch(channel){
+        case 1: return ((int16_t)ReadRegister(INA3221_REG_WARNING_1)>>3); 
+        case 2: return ((int16_t)ReadRegister(INA3221_REG_WARNING_2)>>3); 
+        case 3: return ((int16_t)ReadRegister(INA3221_REG_WARNING_3)>>3); 
+        default: return 0;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get current setpoint from the warning alert limit register (Convert raw value to current) 
+    Return: Current setpoint for warning alert limit
+*/
+/**************************************************************************/
+float INA3221::GetCurrentWarningAlertLimit(uint8_t channel)
+{
+    float voltage =((float)GetRawWarningAlertLimit(channel))*INA3221_SHUNT_VOLTAGE_LSB; 
+    switch(channel){
+        case 1: return (voltage / _INA3221_shuntresistor_1); 
+        case 2: return (voltage / _INA3221_shuntresistor_2); 
+        case 3: return (voltage / _INA3221_shuntresistor_3);
+        default: return 0;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set raw register value to warning alert limit register 
+*/
+/**************************************************************************/
+void INA3221::SetRawWarningAlertLimit(uint8_t channel, int16_t value)
+{
+    value = value << 3;
+    switch(channel){
+        case 1: WriteRegister(INA3221_REG_WARNING_1,value); break;
+        case 2: WriteRegister(INA3221_REG_WARNING_2,value); break;
+        case 3: WriteRegister(INA3221_REG_WARNING_3,value); break;
+    }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set current value to warning alert register 
+*/
+/**************************************************************************/
+void INA3221::SetCurrentWarningAlertLimit(uint8_t channel, float current )
+{
+    float value;
+    switch(channel){
+        case 1: value = _INA3221_shuntresistor_1; break;
+        case 2: value = _INA3221_shuntresistor_2; break;
+        case 3: value = _INA3221_shuntresistor_3; break;
+    }
+    
+    value = ((value*current) / (INA3221_SHUNT_VOLTAGE_LSB));
+    SetRawWarningAlertLimit(channel, (int16_t)value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from shunt voltage sum register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawShuntVoltageSum(void)
+{
+    return ((int16_t)ReadRegister(INA3221_REG_SUM_SHUNTVOLTAGE)>>1);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get voltage value from shunt voltage sum register (Convert raw value to voltage)
+    Return: Voltage form shunt voltage sum register
+*/
+/**************************************************************************/
+float INA3221::GetShuntVoltageSum(void)
+{
+    return ((float)GetRawShuntVoltageSum() * INA3221_SHUNT_VOLTAGE_LSB);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from shunt voltage sum limit register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawShuntVoltageSumLimit(void)
+{
+    return ((int16_t)ReadRegister(INA3221_REG_SUM_LIMIT)>>1);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get voltage value from shunt voltage sum limit register (Convert raw value to voltage)
+    Return: Voltage setpoint for shunt voltage sum limit register
+*/
+/**************************************************************************/
+float INA3221::GetShuntVoltageSumLimit(void)
+{
+    return ((float)GetRawShuntVoltageSumLimit() * INA3221_SHUNT_VOLTAGE_LSB);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set raw register value to shunt voltage sum limit register 
+*/
+/**************************************************************************/
+void INA3221::SetRawShuntVoltageSumLimit(uint16_t value )
+{
+        value = value << 1;
+        WriteRegister(INA3221_REG_SUM_LIMIT,value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set voltage value to shunt voltage sum limit register 
+*/
+/**************************************************************************/
+void INA3221::SetShuntVoltageSumLimit(float value)
+{
+    value = value / INA3221_SHUNT_VOLTAGE_LSB ;
+    SetRawShuntVoltageSumLimit((uint16_t)value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from power valid upper limit register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawPowerValidUpperLimit(void)
+{
+    return ((int16_t)ReadRegister(INA3221_REG_POWERVALID_UPPER_LIMIT)>>3);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get voltage value from power valid upper limit register (Convert raw value to voltage)
+    Return: Voltage setpoint for power vaild upper limit register
+*/
+/**************************************************************************/
+float INA3221::GetPowerValidUpperLimitVoltage(void)
+{
+    return ((float)GetRawPowerValidUpperLimit() * INA3221_BUS_VOLTAGE_LSB);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set raw register value to power valid upper limit register 
+*/
+/**************************************************************************/
+void INA3221::SetRawPowerValidUpperLimit(uint16_t value )
+{
+        value = value << 3;
+        WriteRegister(INA3221_REG_POWERVALID_UPPER_LIMIT,value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set voltage value to power valid upper limit register 
+*/
+/**************************************************************************/
+void INA3221::SetPowerValidUpperLimitVoltage(float value)
+{
+    value = value / INA3221_BUS_VOLTAGE_LSB ;
+    SetRawPowerValidUpperLimit((uint16_t)value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from power valid lower limit register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+int16_t INA3221::GetRawPowerValidLowerLimit(void)
+{
+    return ((int16_t)ReadRegister(INA3221_REG_POWERVALID_LOWER_LIMIT)>>3);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get voltage value from power valid lower limit register (Convert raw value to voltage)
+    Return: Voltage setpoint for power vaild lower limit register
+*/
+/**************************************************************************/
+float INA3221::GetPowerValidLowerLimitVoltage(void)
+{
+    return ((float)GetRawPowerValidLowerLimit() * INA3221_BUS_VOLTAGE_LSB);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set raw register value to power valid lower limit register 
+*/
+/**************************************************************************/
+void INA3221::SetRawPowerValidLowerLimit(uint16_t value )
+{
+        value = value << 3;
+        WriteRegister(INA3221_REG_POWERVALID_LOWER_LIMIT,value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set voltage value to power valid lower limit register 
+*/
+/**************************************************************************/
+void INA3221::SetPowerValidLowerLimitVoltage(float value)
+{
+    value = value / INA3221_BUS_VOLTAGE_LSB ;
+    SetRawPowerValidLowerLimit((uint16_t)value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw content of configuration register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+uint16_t INA3221::GetConfiguration(void)
+{
+    return (uint16_t)ReadRegister(INA3221_REG_CONFIG);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set raw register value to configuration register 
+*/
+/**************************************************************************/
+void INA3221::SetConfiguration(uint16_t value)
+{
+    WriteRegister(INA3221_REG_CONFIG , value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set mode bits in configuration register to: 
+    INA3221_MODE_POWER_DOWN                 
+    INA3221_MODE_SHUNT_SINGLE               
+    INA3221_MODE_BUS_SINGLE                 
+    INA3221_MODE_SHUNT_BUS_SINGLE           
+    INA3221_MODE_SHUNT_CONTINUOUS           
+    INA3221_MODE_BUS_CONTINUOUS             
+    INA3221_MODE_SHUNT_BUS_CONTINUOUS        
+*/
+/**************************************************************************/
+void INA3221::SetMode(uint16_t mode)
+{   
+    uint16_t mode_reg = GetConfiguration();
+    mode_reg &= 0xFFF8;
+    mode_reg |= mode;
+    
+    SetConfiguration(mode_reg);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set conversion time bits for shunt voltage measurement in configuration register to: 
+    INA3221_140_US                      
+    INA3221_204_US                      
+    INA3221_332_US                        
+    INA3221_588_US                         
+    INA3221_1_1_MS                         
+    INA3221_2_116_MS                        
+    INA3221_4_156_MS                        
+    INA3221_8_244_MS      
+*/
+/**************************************************************************/
+void INA3221::SetShuntConversionTime(uint16_t shunt_conversion_time)
+{   
+    uint16_t mode_reg = GetConfiguration();
+    mode_reg &= 0xFFC7;
+    mode_reg |= shunt_conversion_time<<3;
+    
+    SetConfiguration(mode_reg);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set conversion time bits for bus voltage measurement in configuration register to: 
+    INA3221_140_US                      
+    INA3221_204_US                      
+    INA3221_332_US                        
+    INA3221_588_US                         
+    INA3221_1_1_MS                         
+    INA3221_2_116_MS                        
+    INA3221_4_156_MS                        
+    INA3221_8_244_MS      
+*/
+/**************************************************************************/
+void INA3221::SetBusConversionTime(uint16_t bus_conversion_time)
+{   
+    uint16_t mode_reg = GetConfiguration();
+    mode_reg &= 0xFE3F;
+    mode_reg |= bus_conversion_time<<6;
+    
+    SetConfiguration(mode_reg);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set averaging mode in configuration register to:
+    INA3221_AVERAGE_1                     
+    INA3221_AVERAGE_4                       
+    INA3221_AVERAGE_16                      
+    INA3221_AVERAGE_64                      
+    INA3221_AVERAGE_128                     
+    INA3221_AVERAGE_256                     
+    INA3221_AVERAGE_512                     
+    INA3221_AVERAGE_1024                   
+*/
+/**************************************************************************/
+void INA3221::SetAveragingMode(uint16_t averaging_mode)
+{   
+    uint16_t mode_reg = GetConfiguration();
+    mode_reg &= 0xF1FF;
+    mode_reg |= (averaging_mode<<9);
+    
+    SetConfiguration(mode_reg);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Enable measurement for single channel
+    INA3221_CONFIG_CH1            
+    INA3221_CONFIG_CH2                   
+    INA3221_CONFIG_CH3 
+*/
+/**************************************************************************/
+void INA3221::EnableChannel(uint16_t channel)
+{   
+    uint16_t mode_reg = GetConfiguration();
+    switch(channel){
+        case 1: mode_reg |= INA3221_CONFIG_CH1; break;
+        case 2: mode_reg |= INA3221_CONFIG_CH2; break;
+        case 3: mode_reg |= INA3221_CONFIG_CH3; break;
+    }
+    
+    SetConfiguration(mode_reg);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Disable measurement for single channel
+    INA3221_CONFIG_CH1            
+    INA3221_CONFIG_CH2                   
+    INA3221_CONFIG_CH3 
+*/
+/**************************************************************************/
+void INA3221::DisableChannel(uint16_t channel)
+{   
+    uint16_t mode_reg = GetConfiguration();
+    switch(channel){
+        case 1: mode_reg &= (~INA3221_CONFIG_CH1); break;
+        case 2: mode_reg &= (~INA3221_CONFIG_CH2); break;
+        case 3: mode_reg &= (~INA3221_CONFIG_CH3); break;
+    }
+    
+    SetConfiguration(mode_reg);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Generate a system reset that is the same as a power-on reset (POR).
+            This bit resets all registers to default values and self-clears.
+*/
+/**************************************************************************/
+void INA3221::Rest(void)
+{   
+    uint16_t mode_reg = GetConfiguration();
+    mode_reg &= 0xEFFF;
+    mode_reg |= INA3221_CONFIG_RST;
+    
+    SetConfiguration(mode_reg);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get raw register value from mask register 
+    Return: Raw Register Value 
+*/
+/**************************************************************************/
+uint16_t INA3221::GetMask(void)
+{
+    return (uint16_t)ReadRegister(INA3221_REG_MASK);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set raw register value to mask register 
+*/
+/**************************************************************************/
+void INA3221::SetMask(uint16_t value)
+{
+    WriteRegister (INA3221_REG_MASK , value);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Check if conversion has finished  
+    Return: 1 after all conversions are complete else 0
+*/
+/**************************************************************************/
+uint8_t INA3221::ConversionReady(void)
+{
+    uint16_t mask = GetMask();
+    mask &= INA3221_REG_MASK_CVRF;
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Timing-control-alert flag indicator 
+*/
+/**************************************************************************/
+uint8_t INA3221::GetTimingAlertFlag(void)
+{
+    uint16_t mask = GetMask();
+    mask &= INA3221_REG_MASK_TCF;
+    mask = mask >>1;
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Power-valid-alert flag indicator
+*/
+/**************************************************************************/
+uint8_t INA3221::GetPowerVaildAlertFlag(void)
+{
+    uint16_t mask = GetMask();
+    mask &= INA3221_REG_MASK_PVF;
+    mask = mask >>2;
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Warning-alert flag indicator for one channel
+*/
+/**************************************************************************/
+uint8_t INA3221::GetWarningAlertFlag(uint8_t channel)
+{
+    uint16_t mask = GetMask();
+    
+    switch(channel){
+        case 1: mask &= INA3221_REG_MASK_WF_1; mask= mask >> 5; break;
+        case 2: mask &= INA3221_REG_MASK_WF_2; mask= mask >> 4; break;
+        case 3: mask &= INA3221_REG_MASK_WF_3; mask= mask >> 3; break;
+    }
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Summation-alert flag indicator 
+*/
+/**************************************************************************/
+uint8_t INA3221::GetSummationAlertFlag(void)
+{
+    uint16_t mask = GetMask();
+    mask &= INA3221_REG_MASK_SF ;
+    mask = mask >>6;
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Critical-alert flag indicator for one channel
+*/
+/**************************************************************************/
+uint8_t INA3221::GetCriticalAlertFlag(uint8_t channel)
+{
+    uint16_t mask = GetMask();
+    
+    switch(channel){
+        case 1: mask &= INA3221_REG_MASK_CF_1; mask= mask >> 9; break;
+        case 2: mask &= INA3221_REG_MASK_CF_2; mask= mask >> 8; break;
+        case 3: mask &= INA3221_REG_MASK_CF_3; mask= mask >> 7; break;
+    }
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get Critical alert latch enable bit 
+    Return: 0 = Transparent (default)
+            1 = Latch enabled
+*/
+/**************************************************************************/
+uint8_t INA3221::GetCriticalAlertLachEnable(void)
+{
+    uint16_t mask = GetMask();
+    mask &= INA3221_REG_MASK_CEN ;
+    mask = mask >>10;
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set Critical alert latch enable bit 
+*/
+/**************************************************************************/
+void INA3221::SetCriticalAlertLachEnable(uint8_t value)
+{
+    uint16_t mask = GetMask();
+    mask &= (~INA3221_REG_MASK_CEN);
+    mask |= (value << 10);
+         
+    SetMask(mask);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Get warning alert latch enable bit 
+    Return: 0 = Transparent (default)
+            1 = Latch enabled
+*/
+/**************************************************************************/
+uint8_t INA3221::GetWarningAlertLachEnable(void)
+{
+    uint16_t mask = GetMask();
+    mask &= INA3221_REG_MASK_WEN ;
+    mask = mask >>11;
+     
+    return  (uint8_t)mask;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Set warning alert latch enable bit 
+*/
+/**************************************************************************/
+void INA3221::SetWarningAlertLachEnable(uint8_t value)
+{
+    uint16_t mask = GetMask();
+    mask &= (~INA3221_REG_MASK_WEN);
+    mask |= (value << 11);
+         
+    SetMask(mask);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Enable channel for summation 
+*/
+/**************************************************************************/
+void INA3221::EnableChannelSummation(uint16_t channel)
+{   
+    uint16_t mask = GetMask();
+    switch(channel){
+        case 1: mask |= INA3221_REG_MASK_SCC_1; break;
+        case 2: mask |= INA3221_REG_MASK_SCC_2; break;
+        case 3: mask |= INA3221_REG_MASK_SCC_3; break;
+    }
+    
+    SetMask(mask);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Disable channel for summation 
+ 
+*/
+/**************************************************************************/
+void INA3221::DisableChannelSummation(uint16_t channel)
+{   
+    uint16_t mask = GetMask();
+    switch(channel){
+        case 1: mask &= (~INA3221_REG_MASK_SCC_1 ); break;
+        case 2: mask &= (~INA3221_REG_MASK_SCC_2 ); break;
+        case 3: mask &= (~INA3221_REG_MASK_SCC_3); break;
+    }
+    
+    SetMask(mask);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INA3221.h	Wed Jan 31 20:36:07 2018 +0000
@@ -0,0 +1,225 @@
+/* 
+    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.
+*/
+ 
+//=============================================================================
+// INA3221 Library
+// by Sven Lack
+//=============================================================================
+
+
+#ifndef INA3221_H
+#define INA3221_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+    #define INA3221_SHUNT_VOLTAGE_LSB               0.00004f   // 40 uV per LSB
+    #define INA3221_BUS_VOLTAGE_LSB                 0.008f     // 8 mV per LSB
+/*=========================================================================
+    I2C ADDRESS/BITS
+-----------------------------------------------------------------------*/
+    #define INA3221_ADDRESS                         (0x80)    // 1000000 
+/*=========================================================================*/
+
+/*=========================================================================
+    Configuration Register (RW) - See table 5 spec
+---------------------------------------------------------------------*/
+    #define INA3221_CONFIG_RST                      (0x8000)  // Reset Bit
+    
+    #define INA3221_CONFIG_CH1                      (0x4000)  // Enable Channel 1
+    #define INA3221_CONFIG_CH2                      (0x2000)  // Enable Channel 2
+    #define INA3221_CONFIG_CH3                      (0x1000)  // Enable Channel 3
+    
+    #define INA3221_CONFIG_AVG2                     (0x0800)  // Averaging mode Bit 2 
+    #define INA3221_CONFIG_AVG1                     (0x0400)  // Averaging mode Bit 1 
+    #define INA3221_CONFIG_AVG0                     (0x0200)  // Averaging mode Bit 0 
+
+    #define INA3221_CONFIG_VBUS_CT2                 (0x0100)  // Bus-voltage conversion time bit 0
+    #define INA3221_CONFIG_VBUS_CT1                 (0x0080)  // Bus-voltage conversion time bit 0
+    #define INA3221_CONFIG_VBUS_CT0                 (0x0040)  // Bus-voltage conversion time bit 0
+
+    #define INA3221_CONFIG_VSH_CT2                  (0x0020)  // Shunt-voltage conversion time bit 2
+    #define INA3221_CONFIG_VSH_CT1                  (0x0010)  // Shunt-voltage conversion time bit 1
+    #define INA3221_CONFIG_VSH_CT0                  (0x0008)  // Shunt-voltage conversion time bit 0
+    
+    #define INA3221_CONFIG_MODE_3                   (0x0004)  // Operating Mode bit 2
+    #define INA3221_CONFIG_MODE_2                   (0x0002)  // Operating Mode bit 1
+    #define INA3221_CONFIG_MODE_1                   (0x0001)  // Operating Mode bit 0
+    
+    #define INA3221_MODE_POWER_DOWN                 (0x0000)  // Power-down
+    #define INA3221_MODE_SHUNT_SINGLE               (0x0001)  // Shunt voltage, single-shot (triggered)
+    #define INA3221_MODE_BUS_SINGLE                 (0x0002)  // Bus voltage, single-shot (triggered)
+    #define INA3221_MODE_SHUNT_BUS_SINGLE           (0x0003)  // Shunt and bus, single-shot (triggered)
+    #define INA3221_MODE_SHUNT_CONTINUOUS           (0x0005)  // Shunt voltage, continuous
+    #define INA3221_MODE_BUS_CONTINUOUS             (0x0006)  // Bus voltage, continuous
+    #define INA3221_MODE_SHUNT_BUS_CONTINUOUS       (0x0007)  // Shunt and bus, continuous
+    
+    #define INA3221_140_US                          (0x0000)  // Conversion time 140 us
+    #define INA3221_204_US                          (0x0001)  // Conversion time 204 us
+    #define INA3221_332_US                          (0x0002)  // Conversion time 332 us
+    #define INA3221_588_US                          (0x0003)  // Conversion time 588 us
+    #define INA3221_1_1_MS                          (0x0004)  // Conversion time 1.1 ms
+    #define INA3221_2_116_MS                        (0x0005)  // Conversion time 2.116 ms
+    #define INA3221_4_156_MS                        (0x0006)  // Conversion time 4.156 ms
+    #define INA3221_8_244_MS                        (0x0007)  // Conversion time 8.244 ms
+    
+    #define INA3221_AVERAGE_1                       (0x0000)  // Averaging mode 1
+    #define INA3221_AVERAGE_4                       (0x0001)  // Averaging mode 4
+    #define INA3221_AVERAGE_16                      (0x0002)  // Averaging mode 16
+    #define INA3221_AVERAGE_64                      (0x0003)  // Averaging mode 64
+    #define INA3221_AVERAGE_128                     (0x0004)  // Averaging mode 128
+    #define INA3221_AVERAGE_256                     (0x0005)  // Averaging mode 256
+    #define INA3221_AVERAGE_512                     (0x0006)  // Averaging mode 512
+    #define INA3221_AVERAGE_1024                    (0x0007)  // Averaging mode 1024
+/*=========================================================================    
+    Mask/ Enable Register (RW) - See table 20 spec
+---------------------------------------------------------------------*/
+
+    #define INA3221_REG_MASK_SCC_1                  (0x4000)  // Enable Channel 1 for Summation
+    #define INA3221_REG_MASK_SCC_2                  (0x2000)  // Enable Channel 2 for Summation
+    #define INA3221_REG_MASK_SCC_3                  (0x1000)  // Enable Channel 3 for Summation
+    
+    #define INA3221_REG_MASK_WEN                    (0x0800)  // Warning-alert latch enable
+    #define INA3221_REG_MASK_CEN                    (0x0400)  // Critical-alert latch enable
+    
+    #define INA3221_REG_MASK_CF_1                   (0x0200)  // Critical-alert flag indicator for Channel 1
+    #define INA3221_REG_MASK_CF_2                   (0x0100)  // Critical-alert flag indicator for Channel 2
+    #define INA3221_REG_MASK_CF_3                   (0x0080)  // Critical-alert flag indicator for Channel 3
+    
+    #define INA3221_REG_MASK_SF                     (0x0040)  // Summation-alert flag indicator
+
+    #define INA3221_REG_MASK_WF_1                   (0x0020)  // Warning-alert flag indicator for Channel 1
+    #define INA3221_REG_MASK_WF_2                   (0x0010)  // Warning-alert flag indicator for Channel 2
+    #define INA3221_REG_MASK_WF_3                   (0x0008)  // Warning-alert flag indicator for Channel 3
+
+    #define INA3221_REG_MASK_PVF                    (0x0004)  // Power-vaild-alert flag indicator
+    #define INA3221_REG_MASK_TCF                    (0x0002)  // Timing-control-alert flag indicator
+    #define INA3221_REG_MASK_CVRF                   (0x0001)  // Conversion-ready flag
+/*=========================================================================    
+    Manufacturer ID (R) - See table 23 spec
+---------------------------------------------------------------------*/
+    #define INA3221_REG_MANUFACTURER_ID_VALUE       (0x5449)  // Manufacturer ID bits
+/*=========================================================================    
+    Die ID (R) - See table 24 spec
+---------------------------------------------------------------------*/
+    #define INA3221_REG_DIE_ID_VALUE                (0x3220)  // Die ID bits
+/*=========================================================================*/
+    #define INA3221_REG_CONFIG                      (0x00)  // Configuration Register (RW)
+    #define INA3221_REG_SHUNTVOLTAGE_1              (0x01)  // Channel-1 Shunt Voltage (R)
+    #define INA3221_REG_BUSVOLTAGE_1                (0x02)  // Channel-1 Bus Voltage (R)
+    #define INA3221_REG_SHUNTVOLTAGE_2              (0x03)  // Channel-2 Shunt Voltage (R)
+    #define INA3221_REG_BUSVOLTAGE_2                (0x04)  // Channel-2 Bus Voltage (R)
+    #define INA3221_REG_SHUNTVOLTAGE_3              (0x05)  // Channel-3 Shunt Voltage (R)
+    #define INA3221_REG_BUSVOLTAGE_3                (0x06)  // Channel-3 Bus Voltage (R)
+    #define INA3221_REG_CRITICAL_1                  (0x07)  // Channel-1 Critical Alert Limit (RW)
+    #define INA3221_REG_WARNING_1                   (0x08)  // Channel-1 Warning-Alert Limit (RW) 
+    #define INA3221_REG_CRITICAL_2                  (0x09)  // Channel-2 Critical Alert Limit (RW)
+    #define INA3221_REG_WARNING_2                   (0x0A)  // Channel-2 Warning-Alert Limit (RW) 
+    #define INA3221_REG_CRITICAL_3                  (0x0B)  // Channel-3 Critical Alert Limit (RW)
+    #define INA3221_REG_WARNING_3                   (0x0C)  // Channel-3 Warning-Alert Limit (RW)  
+    #define INA3221_REG_SUM_SHUNTVOLTAGE            (0x0D)  // Shunt Voltage Sum (R)
+    #define INA3221_REG_SUM_LIMIT                   (0x0E)  // Shunt Voltage Sum Limit (RW)
+    #define INA3221_REG_MASK                        (0x0F)  // Mask/ Enable (RW)
+    #define INA3221_REG_POWERVALID_UPPER_LIMIT      (0x10)  // Power-Valid Upper Limit (RW)
+    #define INA3221_REG_POWERVALID_LOWER_LIMIT      (0x11)  // Power-Valid Lower Limit (RW)
+    #define INA3221_REG_MANUFACTURER_ID             (0xFE)  // Manufacturer ID (R)
+    #define INA3221_REG_DIE_ID                      (0xFF)  // Die ID (R)
+
+    #define SHUNT_RESISTOR_VALUE  (0.1)   // default shunt resistor value of 0.1 Ohm
+
+class INA3221{
+ public:
+    INA3221(PinName sda , PinName scl, uint8_t addr = INA3221_ADDRESS, float shuntresistor_1= SHUNT_RESISTOR_VALUE, float shuntresistor_2= SHUNT_RESISTOR_VALUE, float shuntresistor_3= SHUNT_RESISTOR_VALUE);
+   
+    void SetShuntValues (float shuntresistor_1, float shuntresistor_2, float shuntresistor_3);  
+    void SetI2CAdr(uint8_t);                                                                    
+    void WriteRegister (uint8_t reg, uint16_t value);                                          
+    uint16_t ReadRegister(uint8_t reg);                                                        
+    uint16_t GetManufacturerID(void);                                                        
+    uint16_t GetDieID(void);                                                                 
+    uint8_t CheckConnection(void);                                                           
+    int16_t GetRawShuntVoltage(uint8_t channel);                                             
+    float GetShuntVoltage(uint8_t channel);                                                  
+    float GetCurrent(uint8_t channel);                                                         
+    int16_t GetRawBusVoltage(uint8_t channel);                                                
+    float GetBusVoltage(uint8_t channel);                                                     
+    int16_t GetRawCriticalAlertLimit(uint8_t channel);                                         
+    float GetCurrentCriticalAlertLimit(uint8_t channel);                                      
+    void SetRawCriticalAlertLimit(uint8_t channel, uint16_t value);                         
+    void SetCurrentCriticalAlertLimit(uint8_t channel, float current );                    
+    int16_t GetRawWarningAlertLimit(uint8_t channel);                                          
+    float GetCurrentWarningAlertLimit(uint8_t channel);                                       
+    void SetRawWarningAlertLimit(uint8_t channel, int16_t value);                            
+    void SetCurrentWarningAlertLimit(uint8_t channel, float current );                        
+    int16_t GetRawShuntVoltageSum(void);                                                       
+    float GetShuntVoltageSum(void);                                                          
+    int16_t GetRawShuntVoltageSumLimit(void);                                                  
+    float GetShuntVoltageSumLimit(void);                                                       
+    void SetRawShuntVoltageSumLimit(uint16_t value );                                          
+    void SetShuntVoltageSumLimit(float value);                                                  
+    int16_t GetRawPowerValidUpperLimit(void);                                                   
+    float GetPowerValidUpperLimitVoltage(void);                                                 
+    void SetRawPowerValidUpperLimit(uint16_t value );                                           
+    void SetPowerValidUpperLimitVoltage(float value);                                           
+    int16_t GetRawPowerValidLowerLimit(void);                                                   
+    float GetPowerValidLowerLimitVoltage(void);                                                 
+    void SetRawPowerValidLowerLimit(uint16_t value );                                           
+    void SetPowerValidLowerLimitVoltage(float value);                                           
+    uint16_t GetConfiguration(void);                                                            
+    void SetConfiguration(uint16_t value);                                                      
+    void SetMode(uint16_t mode);                                                                
+    void SetShuntConversionTime(uint16_t shunt_conversion_time);                                
+    void SetBusConversionTime(uint16_t bus_conversion_time);                                    
+    void SetAveragingMode(uint16_t averaging_mode);                                             
+    void EnableChannel(uint16_t channel);                                                       
+    void DisableChannel(uint16_t channel);                                                      
+    void Rest(void);                                                                            
+    uint16_t GetMask(void);                                                                     
+    void SetMask(uint16_t value);                                                               
+    uint8_t ConversionReady(void);                                                              
+    uint8_t GetTimingAlertFlag(void);                                                           
+    uint8_t GetPowerVaildAlertFlag(void);                                                       
+    uint8_t GetWarningAlertFlag(uint8_t channel);                                               
+    uint8_t GetSummationAlertFlag(void);                                                        
+    uint8_t GetCriticalAlertFlag(uint8_t channel);                                              
+    uint8_t GetCriticalAlertLachEnable(void);                                                   
+    void SetCriticalAlertLachEnable(uint8_t value);                                                
+    uint8_t GetWarningAlertLachEnable(void);                                                    
+    void SetWarningAlertLachEnable(uint8_t value);                                              
+    void EnableChannelSummation(uint16_t channel);                                              
+    void DisableChannelSummation(uint16_t channel);                                             
+
+ private:
+    uint8_t _INA3221_i2caddr;
+      
+    float _INA3221_shuntresistor_1;
+    float _INA3221_shuntresistor_2;
+    float _INA3221_shuntresistor_3;
+      
+    float _Shunt_Resistor_Ch1;
+    float _Shunt_Resistor_Ch2;
+    float _Shunt_Resistor_Ch3;
+      
+    I2C* _i2c;
+};
+
+#endif /* INA3221_H */