/**************************************************************************/
/*! 
 @file     ina219.c
 @author   K. Townsend (microBuilder.eu)
 
 @brief    Driver for the TI INA219 current/power monitor
 
 @section DESCRIPTION
 
 The INA219 is an I2C-based current/power monitor that monitors the
 voltage drop across a shunt resistor, as well as the supply voltage.
 
 @section EXAMPLE
 @code
 ina219Init();
 
 int16_t current = 0;
 int16_t power = 0;
 int16_t current_mA = 0;
 int16_t power_mW = 0;
 int16_t busvoltage = 0;
 int16_t shuntvoltage = 0;
 int16_t loadVoltage = 0;
 
 while(1)
 {
 shuntvoltage  = ina219GetShuntVoltage();
 busvoltage    = ina219GetBusVoltage();
 power         = ina219GetPower();
 current       = ina219GetCurrent();
 power_mW      = ina219GetPower_mW();
 current_mA    = ina219GetCurrent_mA();
 loadVoltage   = busvoltage + (shuntvoltage / 100);
 printf("%-15s %6d = %d.%dmV (%duV) \r\n", "Shunt Voltage:", shuntvoltage, shuntvoltage / 100, shuntvoltage % 100, shuntvoltage * 10);
 printf("%-15s %6d = %d.%dV \r\n",         "Bus Voltage:",   busvoltage, busvoltage / 1000, busvoltage % 1000);
 printf("%-15s %6d = %d.%dV \r\n",         "Load Voltage:",  loadVoltage, loadVoltage / 1000, loadVoltage % 1000);
 printf("%-15s %6d = %dmW \r\n",           "Power:",         power, power_mW);
 printf("%-15s %6d = %dmA \r\n",           "Current:",       current, current_mA);
 printf("\r\n");
 systickDelay(5000);
 }
 @endcode
 
 @section LICENSE
 
 Software License Agreement (BSD License)
 
 Copyright (c) 2012 Kevin Townsend
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 1. Redistributions of source code must retain the above copyright
 notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in the
 documentation and/or other materials provided with the distribution.
 3. Neither the name of the copyright holders nor the
 names of its contributors may be used to endorse or promote products
 derived from this software without specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**************************************************************************/
#include "ina219.h"
#include "I2C.h"
#include <stdint.h>

unsigned char   I2CMasterBuffer[I2C_BUFSIZE];
unsigned char   I2CSlaveBuffer[I2C_BUFSIZE];

// The following multipliers are used to convert raw current and power
// values to mA and mW, taking into account the current config settings
uint32_t ina219_currentDivider_mA = 0;
uint32_t ina219_powerDivider_mW   = 0;

/**************************************************************************/
/*! 
 @brief  Sends a single command byte over I2C
 */
/**************************************************************************/
static int ina219WriteRegister (uint8_t reg, uint16_t value)
{
    // Clear write buffers
    uint32_t i;
    for ( i = 0; i < I2C_BUFSIZE; i++ )
    {
        I2CMasterBuffer[i] = 0x00;
    }
    
    //I2CWriteLength = 4;
    // I2CReadLength = 0;
    I2CMasterBuffer[0] = INA219_ADDRESS;        // I2C device address
    I2CMasterBuffer[1] = reg;                   // Register
    I2CMasterBuffer[2] = value >> 8;            // Upper 8-bits
    I2CMasterBuffer[3] = value & 0xFF;          // Lower 8-bits
    
    return I2CWrite(I2CMasterBuffer,4);
    
    
    
    //i2cEngine();
}

/**************************************************************************/
/*! 
 @brief  Reads a 16 bit values over I2C
 */
/**************************************************************************/
static void ina219Read16(uint8_t reg, uint16_t *value)
{
    // Clear write buffers
    int RET = RET_OK;
    uint32_t i;
    for ( i = 0; i < I2C_BUFSIZE; i++ )
    {
        I2CMasterBuffer[i] = 0x00;
    }
    
    // I2CWriteLength = 2;
    //I2CReadLength = 2;
    I2CMasterBuffer[0] = INA219_ADDRESS;            // I2C device address
    I2CMasterBuffer[1] = reg;                       // Command register
    // Append address w/read bit
    I2CMasterBuffer[2] = INA219_ADDRESS | INA219_READ;  
    // i2cEngine();
    
    I2CWrite(I2CMasterBuffer,2);  //write pointer to the good register
    RET = I2CRead(I2CMasterBuffer[2],&I2CSlaveBuffer[0],2);    //read the data
    
    if(RET != RET_OK)
    {
        * value = 0;
        return;
    }
    // Shift values to create properly formed integer
    *value = ((I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1]);
}

void ina219SetCalibration_13V_10A(void)
{
    // By default we use a pretty huge range for the input voltage,
    // which probably isn't the most appropriate choice for system
    // that don't use a lot of power.  But all of the calculations
    // are shown below if you want to change the settings.  You will
    // also need to change any relevant register settings, such as
    // setting the VBUS_MAX to 16V instead of 32V, etc.
    
    // VBUS_MAX = 13V             (Assumes 32V, can also be set to 16V)
    // VSHUNT_MAX = 0.32          (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
    // RSHUNT = 0.1               (Resistor value in ohms)
    
    // 1. Determine max possible current
    // MaxPossible_I = VSHUNT_MAX / RSHUNT
    // MaxPossible_I = 3.2A
    
    // 2. Determine max expected current
    // MaxExpected_I = 3.2A
    
    // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
    // MinimumLSB = MaxExpected_I/32767
    // MinimumLSB = 0.00009765              (98µA per bit)
    // MaximumLSB = MaxExpected_I/4096
    // MaximumLSB = 0,000488              (488µA per bit)
    
    // 4. Choose an LSB between the min and max values
    //    (Preferrably a roundish number close to MinLSB)
    // CurrentLSB = 0.0001 (100µA per bit)
    
    // 5. Compute the calibration register
    // Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
    // Cal = 4096 (0x1000)
    
    // 6. Calculate the power LSB
    // PowerLSB = 20 * CurrentLSB
    // PowerLSB = 0.002 (2mW per bit)
    
    // 7. Compute the maximum current and shunt voltage values before overflow
    //
    // Max_Current = Current_LSB * 32767
    // Max_Current = 3.2767A before overflow
    //
    // If Max_Current > Max_Possible_I then
    //    Max_Current_Before_Overflow = MaxPossible_I
    // Else
    //    Max_Current_Before_Overflow = Max_Current
    // End If
    //
    // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
    // Max_ShuntVoltage = 0.32V
    //
    // If Max_ShuntVoltage >= VSHUNT_MAX
    //    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
    // Else
    //    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
    // End If
    
    // 8. Computer the Maximum Power
    // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
    // MaximumPower = 3.2 * 32V
    // MaximumPower = 102.4W
    
    // Set multipliers to convert raw current/power values
    ina219_currentDivider_mA = 10;  // Current LSB = 100uA per bit (1000/100 = 10)
    ina219_powerDivider_mW = 2;     // Power LSB = 1mW per bit (2/1)
    
    // Set Calibration register to 'Cal' calculated above	
    ina219WriteRegister(INA219_REG_CALIBRATION, 0x1000);
    
    // Set Config register to take into account the settings above
    uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
            INA219_CONFIG_GAIN_8_320MV |
            INA219_CONFIG_BADCRES_12BIT |
            INA219_CONFIG_SADCRES_12BIT_1S_532US |
            // INA219_CONFIG_MODE_SVOLT_CONTINUOUS;
            INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
    
    ina219WriteRegister(INA219_REG_CONFIG, config);
}

/**************************************************************************/
/*! 
 @brief  Configures to INA219 to be able to measure up to 32V and 2A
 of current.  Each unit of current corresponds to 100uA, and
 each unit of power corresponds to 2mW. Counter overflow
 occurs at 3.2A.
 
 @note   These calculations assume a 0.1 ohm resistor is present
 */
/**************************************************************************/
void ina219SetCalibration_32V_2A(void)
{
    // By default we use a pretty huge range for the input voltage,
    // which probably isn't the most appropriate choice for system
    // that don't use a lot of power.  But all of the calculations
    // are shown below if you want to change the settings.  You will
    // also need to change any relevant register settings, such as
    // setting the VBUS_MAX to 16V instead of 32V, etc.
    
    // VBUS_MAX = 32V             (Assumes 32V, can also be set to 16V)
    // VSHUNT_MAX = 0.32          (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
    // RSHUNT = 0.1               (Resistor value in ohms)
    
    // 1. Determine max possible current
    // MaxPossible_I = VSHUNT_MAX / RSHUNT
    // MaxPossible_I = 3.2A
    
    // 2. Determine max expected current
    // MaxExpected_I = 2.0A
    
    // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
    // MinimumLSB = MaxExpected_I/32767
    // MinimumLSB = 0.000061              (61µA per bit)
    // MaximumLSB = MaxExpected_I/4096
    // MaximumLSB = 0,000488              (488µA per bit)
    
    // 4. Choose an LSB between the min and max values
    //    (Preferrably a roundish number close to MinLSB)
    // CurrentLSB = 0.0001 (100µA per bit)
    
    // 5. Compute the calibration register
    // Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
    // Cal = 4096 (0x1000)
    
    // 6. Calculate the power LSB
    // PowerLSB = 20 * CurrentLSB
    // PowerLSB = 0.002 (2mW per bit)
    
    // 7. Compute the maximum current and shunt voltage values before overflow
    //
    // Max_Current = Current_LSB * 32767
    // Max_Current = 3.2767A before overflow
    //
    // If Max_Current > Max_Possible_I then
    //    Max_Current_Before_Overflow = MaxPossible_I
    // Else
    //    Max_Current_Before_Overflow = Max_Current
    // End If
    //
    // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
    // Max_ShuntVoltage = 0.32V
    //
    // If Max_ShuntVoltage >= VSHUNT_MAX
    //    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
    // Else
    //    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
    // End If
    
    // 8. Computer the Maximum Power
    // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
    // MaximumPower = 3.2 * 32V
    // MaximumPower = 102.4W
    
    // Set multipliers to convert raw current/power values
    ina219_currentDivider_mA = 10;  // Current LSB = 100uA per bit (1000/100 = 10)
    ina219_powerDivider_mW = 2;     // Power LSB = 1mW per bit (2/1)
    
    // Set Calibration register to 'Cal' calculated above	
    ina219WriteRegister(INA219_REG_CALIBRATION, 0x1000);
    
    // Set Config register to take into account the settings above
    uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
            INA219_CONFIG_GAIN_8_320MV |
            INA219_CONFIG_BADCRES_12BIT |
            INA219_CONFIG_SADCRES_12BIT_1S_532US |
            INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
    ina219WriteRegister(INA219_REG_CONFIG, config);
}

/**************************************************************************/
/*! 
 @brief  Configures to INA219 to be able to measure up to 32V and 1A
 of current.  Each unit of current corresponds to 40uA, and each
 unit of power corresponds to 800µW. Counter overflow occurs at
 1.3A.
 
 @note   These calculations assume a 0.1 ohm resistor is present
 */
/**************************************************************************/
void ina219SetCalibration_32V_1A(void)
{
    // By default we use a pretty huge range for the input voltage,
    // which probably isn't the most appropriate choice for system
    // that don't use a lot of power.  But all of the calculations
    // are shown below if you want to change the settings.  You will
    // also need to change any relevant register settings, such as
    // setting the VBUS_MAX to 16V instead of 32V, etc.
    
    // VBUS_MAX = 32V		(Assumes 32V, can also be set to 16V)
    // VSHUNT_MAX = 0.32	(Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
    // RSHUNT = 0.1			(Resistor value in ohms)
    
    // 1. Determine max possible current
    // MaxPossible_I = VSHUNT_MAX / RSHUNT
    // MaxPossible_I = 3.2A
    
    // 2. Determine max expected current
    // MaxExpected_I = 1.0A
    
    // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
    // MinimumLSB = MaxExpected_I/32767
    // MinimumLSB = 0.0000305             (30.5µA per bit)
    // MaximumLSB = MaxExpected_I/4096
    // MaximumLSB = 0.000244              (244µA per bit)
    
    // 4. Choose an LSB between the min and max values
    //    (Preferrably a roundish number close to MinLSB)
    // CurrentLSB = 0.0000400 (40µA per bit)
    
    // 5. Compute the calibration register
    // Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
    // Cal = 10240 (0x2800)
    
    // 6. Calculate the power LSB
    // PowerLSB = 20 * CurrentLSB
    // PowerLSB = 0.0008 (800µW per bit)
    
    // 7. Compute the maximum current and shunt voltage values before overflow
    //
    // Max_Current = Current_LSB * 32767
    // Max_Current = 1.31068A before overflow
    //
    // If Max_Current > Max_Possible_I then
    //    Max_Current_Before_Overflow = MaxPossible_I
    // Else
    //    Max_Current_Before_Overflow = Max_Current
    // End If
    //
    // ... In this case, we're good though since Max_Current is less than MaxPossible_I
    //
    // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
    // Max_ShuntVoltage = 0.131068V
    //
    // If Max_ShuntVoltage >= VSHUNT_MAX
    //    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
    // Else
    //    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
    // End If
    
    // 8. Computer the Maximum Power
    // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
    // MaximumPower = 1.31068 * 32V
    // MaximumPower = 41.94176W
    
    // Set multipliers to convert raw current/power values
    ina219_currentDivider_mA = 25;      // Current LSB = 40uA per bit (1000/40 = 25)
    ina219_powerDivider_mW = 1;         // Power LSB = 800µW per bit
    
    // Set Calibration register to 'Cal' calculated above	
    ina219WriteRegister(INA219_REG_CALIBRATION, 0x2800);
    
    // Set Config register to take into account the settings above
    uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
            INA219_CONFIG_GAIN_8_320MV |
            INA219_CONFIG_BADCRES_12BIT |
            INA219_CONFIG_SADCRES_12BIT_1S_532US |
            INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
    ina219WriteRegister(INA219_REG_CONFIG, config);
}

/**************************************************************************/
/*! 
 @brief  Configures to INA219 to be able to measure up to 16V and 500mA
 of current.  Each unit of current corresponds to 25uA, and each
 unit of power corresponds to 500µW. Counter overflow occurs at
 800mA.
 
 @note   These calculations assume a 0.1 ohm resistor is present
 */
/**************************************************************************/
void ina219SetCalibration_16V_500mA(void)
{
    // VBUS_MAX = 16V
    // VSHUNT_MAX = 0.08	(Assumes Gain 2, 80mV, can also be 0.32, 0.16, 0.04)
    // RSHUNT = 0.1			(Resistor value in ohms)
    
    // 1. Determine max possible current
    // MaxPossible_I = VSHUNT_MAX / RSHUNT
    // MaxPossible_I = 0.8A
    
    // 2. Determine max expected current
    // MaxExpected_I = 0.5A
    
    // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
    // MinimumLSB = MaxExpected_I/32767
    // MinimumLSB = 0.0000153             (15.3µA per bit)
    // MaximumLSB = MaxExpected_I/4096
    // MaximumLSB = 0.0001221             (122µA per bit)
    
    // 4. Choose an LSB between the min and max values
    //    (Preferrably a roundish number close to MinLSB)
    // CurrentLSB = 0.0000250 (25µA per bit)
    
    // 5. Compute the calibration register
    // Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
    // Cal = 16384 (0x4000)
    
    // 6. Calculate the power LSB
    // PowerLSB = 20 * CurrentLSB
    // PowerLSB = 0.0005 (500µW per bit)
    
    // 7. Compute the maximum current and shunt voltage values before overflow
    //
    // Max_Current = Current_LSB * 32767
    // Max_Current = 0.819175 (819 mA before overflow)
    //
    // If Max_Current > Max_Possible_I then
    //    Max_Current_Before_Overflow = MaxPossible_I
    // Else
    //    Max_Current_Before_Overflow = Max_Current
    // End If
    //
    // Max_Current_Before_Overflow = 0.8A
    //
    // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
    // Max_ShuntVoltage = 0.8 * 0.1
    // Max_ShuntVoltage = 0.08V
    //
    // If Max_ShuntVoltage >= VSHUNT_MAX
    //    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
    // Else
    //    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
    // End If
    
    // 8. Computer the Maximum Power
    // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
    // MaximumPower = 0.8 * 16V
    // MaximumPower = 12.8W
    
    // Set multipliers to convert raw current/power values
    ina219_currentDivider_mA = 40;    // Current LSB = 25uA per bit (1000/25 = 40)
    ina219_powerDivider_mW =    1;    // Power LSB = 500µW per bit
    
    // Set Calibration register to 'Cal' calculated above	
    ina219WriteRegister(INA219_REG_CALIBRATION, 0x4000);
    
    // Set Config register to take into account the settings above
    uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
            INA219_CONFIG_GAIN_2_80MV |
            INA219_CONFIG_BADCRES_12BIT |
            INA219_CONFIG_SADCRES_12BIT_1S_532US |
            INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
    ina219WriteRegister(INA219_REG_CONFIG, config);
}

/**************************************************************************/
/*! 
 @brief  Configures to INA219 to be able to measure up to 16V and 200mA
 of current.  Each unit of current corresponds to 10uA, and each
 unit of power corresponds to 200µW. Counter overflow occurs at
 327mA.
 
 @note   These calculations assume a 0.1 ohm resistor is present
 */
/**************************************************************************/
void ina219SetCalibration_16V_200mA(void)
{
    // VBUS_MAX = 16V
    // VSHUNT_MAX = 0.04	(Assumes Gain 1, 40mV, can also be 0.32, 0.16, 0.08)
    // RSHUNT = 0.1			(Resistor value in ohms)
    
    // 1. Determine max possible current
    // MaxPossible_I = VSHUNT_MAX / RSHUNT
    // MaxPossible_I = 0.4A
    
    // 2. Determine max expected current
    // MaxExpected_I = 0.2A
    
    // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
    // MinimumLSB = MaxExpected_I/32767
    // MinimumLSB = 0.000006104	          (6.104µA per bit)
    // MaximumLSB = MaxExpected_I/4096
    // MaximumLSB = 0,000048828           (48.82µA per bit)
    
    // 4. Choose an LSB between the min and max values
    // CurrentLSB = 0.000010 (10µA per bit)
    
    // 5. Compute the calibration register
    // Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
    // Cal = 40960 (0xA000)
    
    // 6. Calculate the power LSB
    // PowerLSB = 20 * CurrentLSB
    // PowerLSB = 0.0002 (200µW per bit)
    
    // 7. Compute the maximum current and shunt voltage values before overflow
    //
    // Max_Current = Current_LSB * 32767
    // Max_Current = 0.32767 (328 mA before overflow)
    //
    // If Max_Current > Max_Possible_I then
    //    Max_Current_Before_Overflow = MaxPossible_I
    // Else
    //    Max_Current_Before_Overflow = Max_Current
    // End If
    //
    // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
    // Max_ShuntVoltage = 0.032767V
    //
    // If Max_ShuntVoltage >= VSHUNT_MAX
    //    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
    // Else
    //    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
    // End If
    
    // 8. Computer the Maximum Power
    // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
    // MaximumPower = 0.32767 * 16V
    // MaximumPower = 5.24W
    
    // Set multipliers to convert raw current/power values
    ina219_currentDivider_mA = 100;      // Current LSB = 10uA per bit (1000/10 = 100)
    ina219_powerDivider_mW =     1;      // Power LSB = 200µW per bit
    
    // Set Calibration register to 'Cal' calculated above	
    ina219WriteRegister(INA219_REG_CALIBRATION, 0xA000);
    
    // Set Config register to take into account the settings above
    uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
            INA219_CONFIG_GAIN_1_40MV |
            INA219_CONFIG_BADCRES_12BIT |
            INA219_CONFIG_SADCRES_12BIT_1S_532US |
            INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
    ina219WriteRegister(INA219_REG_CONFIG, config);
}

/**************************************************************************/
/*! 
 @brief  Initialises the I2C block
 */
/**************************************************************************/
int ina219Init(void)
{
    int RET = RET_OK;
    uint16_t ReadBack;
    // Reset INA219 (set to default values)
    RET = ina219WriteRegister(INA219_REG_CONFIG, INA219_CONFIG_RESET);
    ina219Read16(INA219_REG_CONFIG,&ReadBack);
    
    if(ReadBack != INA219_CONFIG_RESET_READBACK)
    {
        return RET_ERROR;
    }
    
    
    
    // Setup chip for 32V and 2A by default
    // ina219SetCalibration_32V_2A();
    ina219SetCalibration_13V_10A();
    
    return RET;
}

/**************************************************************************/
/*! 
 @brief  Gets the shunt voltage (16-bit signed integer, so +-32767)
 */
/**************************************************************************/
int16_t ina219GetShuntVoltage(void)
{
    uint16_t value;
    ina219Read16(INA219_REG_SHUNTVOLTAGE, &value);
    return value;
}

/**************************************************************************/
/*! 
 @brief  Gets the shunt voltage (16-bit signed integer, so +-32767)
 */
/**************************************************************************/
int16_t ina219GetBusVoltage(void)
{
    uint16_t value;
    ina219Read16(INA219_REG_BUSVOLTAGE, &value);
    // Shift to the right 3 to drop CNVR and OVF and then multiply by LSB
    return (value >> 3) * 4;
}

/**************************************************************************/
/*! 
 @brief  Gets the raw power value (16-bit signed integer, so +-32767)
 */
/**************************************************************************/
int16_t ina219GetPower(void)
{
    uint16_t value;
    ina219Read16(INA219_REG_POWER, &value);
    return value;
}

/**************************************************************************/
/*! 
 @brief  Gets the power value in mW, taking into account the config
 settings and power LSB
 */
/**************************************************************************/
int16_t ina219GetPower_mW(void)
{
    uint16_t value;
    ina219Read16(INA219_REG_POWER, &value);
    return value / ina219_powerDivider_mW;
}

/**************************************************************************/
/*! 
 @brief  Gets the raw current value (16-bit signed integer, so +-32767)
 */
/**************************************************************************/
int16_t ina219GetCurrent(void)
{
    uint16_t value;
    ina219Read16(INA219_REG_CURRENT, &value);
    return value;
}

/**************************************************************************/
/*! 
 @brief  Gets the current value in mA, taking into account the
 config settings and current LSB
 */
/**************************************************************************/
int16_t ina219GetCurrent_mA(void)
{
    uint16_t value;
    ina219Read16(INA219_REG_CURRENT, &value);
    return value / ina219_currentDivider_mA;
}


