Texas Instruments INA230 hi/lo side, bi-directional current and voltage monitor with I2C. Code hacked and enhanced from the INA219 driver from TI

Fork of INA219 by Kenji Arai

Files at this revision

API Documentation at this revision

Comitter:
loopsva
Date:
Fri Mar 24 00:13:28 2017 +0000
Parent:
2:088b8d5de7e9
Commit message:
Initial release of the INA230 I2C driver

Changed in this revision

INA219.cpp Show diff for this revision Revisions of this file
INA219.h Show diff for this revision Revisions of this file
INA230.cpp Show annotated file Show diff for this revision Revisions of this file
INA230.h Show annotated file Show diff for this revision Revisions of this file
diff -r 088b8d5de7e9 -r 3ee11c82acdb INA219.cpp
--- a/INA219.cpp	Tue May 05 07:47:02 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/*
- * mbed library program
- *  INA219 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface
- *  by Texas Instruments
- *
- * Copyright (c) 2015 Kenji Arai / JH1PJL
- *  http://www.page.sannet.ne.jp/kenjia/index.html
- *  http://mbed.org/users/kenjiArai/
- *      Created: January   25th, 2015
- *      Revised: May        5th, 2015
- *
- * 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.
- */
-
-#include    "mbed.h"
-#include    "INA219.h"
-
-INA219::INA219 (PinName p_sda, PinName p_scl, const INA219_TypeDef *ina219_parameter) :
-    _i2c(p_sda, p_scl)
-{
-    _i2c.frequency(400000);
-    ina219_set_data = *ina219_parameter;
-    initialize();
-}
-
-INA219::INA219 (PinName p_sda, PinName p_scl, uint8_t addr) :
-    _i2c(p_sda, p_scl)
-{
-    _i2c.frequency(400000);
-    // Use standard setting
-    ina219_set_data = ina219_std_paramtr;
-    // Change user defined address
-    ina219_set_data.addr = addr;
-    initialize();
-}
-
-INA219::INA219 (PinName p_sda, PinName p_scl) :
-    _i2c(p_sda, p_scl)
-{
-    _i2c.frequency(400000);
-    // Use standard setting
-    ina219_set_data = ina219_std_paramtr;
-    initialize();
-}
-
-INA219::INA219 (I2C& p_i2c, const INA219_TypeDef *ina219_parameter) : _i2c(p_i2c)
-{
-    _i2c.frequency(400000);
-    ina219_set_data = *ina219_parameter;
-    initialize();
-}
-
-INA219::INA219 (I2C& p_i2c, uint8_t addr) : _i2c(p_i2c)
-{
-    _i2c.frequency(400000);
-    // Use standard setting
-    ina219_set_data = ina219_std_paramtr;
-    // Change user defined address
-    ina219_set_data.addr = addr;
-    initialize();
-}
-
-INA219::INA219 (I2C& p_i2c) : _i2c(p_i2c)
-{
-    _i2c.frequency(400000);
-    // Use standard setting
-    ina219_set_data = ina219_std_paramtr;
-    initialize();
-}
-
-/////////////// Read Current //////////////////////////////
-float INA219::read_current()
-{
-    dt[0] = INA219_CURRENT;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false);
-    int16_t data = (dt[0] << 8) | dt[1];
-    return (float)data * 25 /1000;
-}
-
-/////////////// Read Power ////////////////////////////////
-float INA219::read_power()
-{
-    dt[0] = INA219_POWER;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false);
-    int16_t data = (dt[0] << 8) | dt[1];
-    return (float)data / 2000;
-}
-
-/////////////// Read Bus_volt /////////////////////////////
-float INA219::read_bus_voltage()
-{
-    dt[0] = INA219_BUS_VOLT;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false);
-    int16_t data = ((dt[0] << 8) | dt[1]) >> 3;
-    return (float)data * 4 / 1000;
-}
-
-/////////////// Read Shunt volt ///////////////////////////
-float INA219::read_shunt_voltage()
-{
-    dt[0] = INA219_SHUNT_V;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false);
-    int16_t data = (dt[0] << 8) | dt[1];
-    return (float)data;
-}
-
-float INA219::read_current_by_shuntvolt()
-{
-    dt[0] = INA219_SHUNT_V;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false);
-    int16_t data = (dt[0] << 8) | dt[1];
-    return (float)data / 10;
-//    return ((float)data / ina219_set_data.shunt_register) / 1000;
-}
-
-/////////////// Read configulation ////////////////////////
-uint16_t INA219::read_config()
-{
-    dt[0] = INA219_CONFIG;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false);
-    uint16_t data = (dt[0] << 8) | dt[1];
-    return data;
-}
-
-/////////////// Set configulation /////////////////////////
-uint16_t INA219::set_config(uint16_t cfg)
-{
-    uint16_t data = cfg;
-    dt[0] = INA219_CONFIG;
-    dt[1] = data >> 8;    // MSB 1st
-    dt[2] = data & 0xff;  // LSB 2nd
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false);
-    return data;
-}
-
-/////////////// Read Calibration reg. /////////////////////
-uint16_t INA219::read_calb(void)
-{
-    dt[0] = INA219_CALBLATION;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 2, false);
-    uint16_t data = (dt[0] << 8) | dt[1];
-    return data;
-}
-
-/////////////// Set Calibration reg. //////////////////////
-uint16_t INA219::set_calb(uint16_t clb)
-{
-    uint16_t data = clb;
-    dt[0] = INA219_CALBLATION;
-    dt[1] = data >> 8;    // MSB 1st
-    dt[2] = data & 0xff;  // LSB 2nd
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false);
-    return data;
-}
-
-/////////////// Read/Write specific register //////////////
-uint8_t INA219::read_reg(uint8_t addr)
-{
-    dt[0] = addr;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 1, true);
-    _i2c.read((int)ina219_set_data.addr, (char *)dt, 1, false);
-    return dt[0];
-}
-
-uint8_t INA219::write_reg(uint8_t addr, uint8_t data)
-{
-    dt[0] = addr;
-    dt[1] = data;
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 2, false);
-    return dt[1];
-}
-
-/////////////// Initialize ////////////////////////////////
-void INA219::initialize()
-{
-    uint16_t data = 0;
-    data  = (ina219_set_data.v_max & 0x01) << 13;
-    data |= (ina219_set_data.gain & 0x03) << 11;
-    data |= (ina219_set_data.bus_adc_resolution & 0x0f) << 6;
-    data |= (ina219_set_data.Shunt_adc_resolution & 0x0f) << 3;
-    data |= (ina219_set_data.mode & 0x07);
-    dt[0] = INA219_CONFIG;
-    dt[1] = data >> 8;    // MSB 1st
-    dt[2] = data & 0xff;  // LSB 2nd
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false);
-    dt[0] = INA219_CALBLATION;
-    dt[1] = ina219_set_data.calibration_data >> 8;    // MSB 1st
-    dt[2] = ina219_set_data.calibration_data & 0xff;  // LSB 2nd
-    _i2c.write((int)ina219_set_data.addr, (char *)dt, 3, false);
-    scale_factor = 0;
-}
-
-/////////////// I2C Freq. /////////////////////////////////
-void INA219::frequency(int hz)
-{
-    _i2c.frequency(hz);
-}
diff -r 088b8d5de7e9 -r 3ee11c82acdb INA219.h
--- a/INA219.h	Tue May 05 07:47:02 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,326 +0,0 @@
-/*
- * mbed library program
- *  INA219 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface
- *  by Texas Instruments
- *
- * Copyright (c) 2015 Kenji Arai / JH1PJL
- *  http://www.page.sannet.ne.jp/kenjia/index.html
- *  http://mbed.org/users/kenjiArai/
- *      Created: January   25th, 2015
- *      Revised: May        5th, 2015
- *
- * 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.
- */
-/*
- *---------------- REFERENCE ----------------------------------------------------------------------
- * Original Information
- *  http://www.ti.com/product/INA219/description
- *  http://www.ti.com/lit/ds/sbos448f/sbos448f.pdf
- * Device kit
- *  https://learn.adafruit.com/adafruit-ina219-current-sensor-breakout/overview
- *  http://akizukidenshi.com/catalog/g/gM-08221/
- */
-
-#ifndef        MBED_INA219
-#define        MBED_INA219
-
-/////////// ADDRESS /////////////////////////////
-//  7bit address = 0b1000000(0x40)
-//  G=GND, V=VS+, A=SDA, L=SCL
-//  e.g. _VG: A1=VS+, A0=GND
-//    -> Please make sure your H/W configuration
-// Set data into "addr"
-#define INA219_ADDR_GG             (0x40 << 1)
-#define INA219_ADDR_GV             (0x41 << 1)
-#define INA219_ADDR_GA             (0x42 << 1)
-#define INA219_ADDR_GL             (0x43 << 1)
-#define INA219_ADDR_VG             (0x44 << 1)
-#define INA219_ADDR_VV             (0x45 << 1)
-#define INA219_ADDR_VA             (0x46 << 1)
-#define INA219_ADDR_VL             (0x47 << 1)
-#define INA219_ADDR_AG             (0x48 << 1)
-#define INA219_ADDR_AV             (0x49 << 1)
-#define INA219_ADDR_AA             (0x4a << 1)
-#define INA219_ADDR_AL             (0x4b << 1)
-#define INA219_ADDR_LG             (0x4c << 1)
-#define INA219_ADDR_LV             (0x4d << 1)
-#define INA219_ADDR_LA             (0x4e << 1)
-#define INA219_ADDR_LL             (0x4f << 1)
-
-/////////// REGISTER DEFINITION /////////////////
-#define INA219_CONFIG              0x00
-#define INA219_SHUNT_V             0x01
-#define INA219_BUS_VOLT            0x02
-#define INA219_POWER               0x03
-#define INA219_CURRENT             0x04
-#define INA219_CALBLATION          0x05
-
-/////////// PARAMETER SETTING ///////////////////
-// Set data into "shunt_register"
-#define INA219_PAR_R_100MOHM       100
-#define INA219_PAR_R_200MORM       200
-#define INA219_PAR_R_MORM(x)       (x)
-// Set data into "v_max"
-#define INA219_PAR_V_16V           0
-#define INA219_PAR_V_32V           1    // Default
-// Set data into "gain"
-#define INA219_PAR_G_40MV          0    // 400[mA] max if R=0.1[Ohm]
-#define INA219_PAR_G_80MV          1
-#define INA219_PAR_G_160MV         2
-#define INA219_PAR_G_320MV         3    // Default
-// Set data into "bus_adc_resolution"
-#define INA219_PAR_B_9B_X1_84US    0x0
-#define INA219_PAR_B_10B_X1_148US  0x1
-#define INA219_PAR_B_11B_X1_276US  0x2
-#define INA219_PAR_B_12B_X1_532US  0x3  // Default
-#define INA219_PAR_B_12B_X2_1R06MS 0x9
-#define INA219_PAR_B_12B_X4_2R13MS 0xa
-#define INA219_PAR_B_12B_X8_4R26MS 0xb
-#define INA219_PAR_B_12B_X16_8MS   0xc
-#define INA219_PAR_B_12B_X32_17MS  0xd
-#define INA219_PAR_B_12B_X64_34MS  0xe
-#define INA219_PAR_B_12B_X128_68MS 0xf
-// Set data into "shunt_adc_resolution"
-#define INA219_PAR_S_9B_X1_84US    0x0
-#define INA219_PAR_S_10B_X1_148US  0x1
-#define INA219_PAR_S_11B_X1_276US  0x2
-#define INA219_PAR_S_12B_X1_532US  0x3  // Default
-#define INA219_PAR_S_12B_X2_1R06MS 0x9
-#define INA219_PAR_S_12B_X4_2R13MS 0xa
-#define INA219_PAR_S_12B_X8_4R26MS 0xb
-#define INA219_PAR_S_12B_X16_8MS   0xc
-#define INA219_PAR_S_12B_X32_17MS  0xd
-#define INA219_PAR_S_12B_X64_34MS  0xe
-#define INA219_PAR_S_12B_X128_68MS 0xf
-// Set data into "mode"
-#define INA219_PAR_M_PDWN          0
-#define INA219_PAR_M_SHNT_TRG      1
-#define INA219_PAR_M_BUS_TRG       2
-#define INA219_PAR_M_SHNTBUS_TRG   3
-#define INA219_PAR_M_ADC_OFF       4
-#define INA219_PAR_M_SHNT_CONT     5
-#define INA219_PAR_M_BUS_CONT      6
-#define INA219_PAR_M_SHNTBUS_CONT  7    // Default
-
-////////////// DATA TYPE DEFINITION ///////////////////////
-typedef struct {
-    // I2C Address
-    uint8_t addr;
-    // CONFIG REG
-    uint8_t shunt_register;
-    uint8_t v_max;
-    uint8_t gain;
-    uint8_t bus_adc_resolution;
-    uint8_t Shunt_adc_resolution;
-    uint8_t mode;
-    // CALBLATION REG
-    uint16_t calibration_data;
-} INA219_TypeDef;
-
-////////////// DEFAULT SETTING ////////////////////////////
-// Standard parameter for easy set-up
-const INA219_TypeDef ina219_std_paramtr = {
-    // I2C Address
-    INA219_ADDR_VV,
-    // CONFIG REG
-    INA219_PAR_R_100MOHM,       // 100 milli-ohm
-    INA219_PAR_V_16V,           // 16V max
-    INA219_PAR_G_40MV,          // Gain x1 (40mV -> 400mA max with 100 milliOhm)
-    INA219_PAR_B_12B_X1_532US,  // Bus/resolution 12bit & one time convertion
-    INA219_PAR_S_12B_X1_532US,  // Shunt/resolution 12bit & one time convertion
-    INA219_PAR_M_SHNTBUS_CONT,  // Measure continuously both Shunt voltage and Bus voltage
-    // CALBLATION REG
-    16384                       // Calibration data
-};
-
-/** INA219 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface
- *
- * @code
- * //--------- Default setting -----------------
- * #include "mbed.h"
- * #include "INA219.h"
- *
- * // I2C Communication
- * INA219 current(dp5, dp27, INA219_ADDR_GG);
- * // If you connected I2C line not only this device but also other devices,
- * //     you need to declare following method.
- * I2C    i2c(dp5, dp27);
- * INA219 current(I2C& p_i2c, INA219_ADDR_GG);
- *
- * int main() {
- *     while(1){
- *         printf("I=%+6.3f [mA]\r\n", current.read_current());
- *         wait(1.0):
- *     }
- * }
- * //--------- Detail setting -----------------
- * #include "mbed.h"
- * #include "INA219.h"
- *
- * const INA219_TypeDef ina219_my_paramtr = {
- *    // I2C Address
- *    INA219_ADDR_GG,
- *    // CONFIG Reg.
- *    INA219_PAR_R_100MOHM,     // 100 milli-ohm
- *    INA219_CFG_B16V,          // 16V max
- *    INA219_PAR_G_40MV,        // Gain x1
- *    INA219_PAR_M_SHNTBUS_CONT,// Measure continuously
- *    // CALIB
- *    16384                     // Calibration data is nothing
- * };
- *
- * I2C    i2c(dp5,dp27);
- * INA219 current(I2C& p_i2c, &ina219_my_paramtr);
- *
- * int main() {
- *     while(1){
- *         printf("I=%+6.3f [mA]\r\n", current.read_current());
- *         wait(1.0):
- *     }
- * }
- * @endcode
- */
-
-class INA219
-{
-public:
-    /** Configure data pin
-      * @param data SDA and SCL pins
-      * @param parameter address chip (INA219_TypeDef)
-      * @param or just set address or just port
-      */
-    INA219(PinName p_sda, PinName p_scl, const INA219_TypeDef *ina219_parameter);
-    INA219(PinName p_sda, PinName p_scl, uint8_t addr);
-    INA219(PinName p_sda, PinName p_scl);
-
-    /** Configure data pin (with other devices on I2C line)
-      * @param I2C previous definition
-      * @param parameter address chip (INA219_TypeDef)
-      * @param or just set address or just port
-      */
-    INA219(I2C& p_i2c, const INA219_TypeDef *ina219_parameter);
-    INA219(I2C& p_i2c, uint8_t addr);
-    INA219(I2C& p_i2c);
-
-    /** Read Current data
-      * @param none
-      * @return current [mA]
-      */
-    float read_current(void);
-    float read_current_by_shuntvolt(void);
-
-    /** Read Power data
-      * @param none
-      * @return power [w]
-      */
-    float read_power(void);
-
-    /** Read Bus voltage
-      * @param none
-      * @return voltage [v]
-      */
-    float read_bus_voltage(void);
-
-    /** Read Shunt voltage data
-      * @param none
-      * @return voltage [v]
-      */
-    float read_shunt_voltage(void);
-
-    /** Read configration reg.
-      * @param none
-      * @return configrartion register value
-      */
-    uint16_t read_config(void);
-
-    /** Set configration reg.
-      * @param
-      * @return configrartion register value
-      */
-    uint16_t set_config(uint16_t cfg);
-
-    /** Read calibration reg.
-      * @param none
-      * @return calibration register value
-      */
-    uint16_t read_calb(void);
-
-    /** Set calibration reg.
-      * @param
-      * @return calibration register value
-      */
-    uint16_t set_calb(uint16_t clb);
-
-    /** Set I2C clock frequency
-      * @param freq.
-      * @return none
-      */
-    void frequency(int hz);
-
-    /** Read register (general purpose)
-      * @param register's address
-      * @return register data
-      */
-    uint8_t read_reg(uint8_t addr);
-
-    /** Write register (general purpose)
-      * @param register's address
-      * @param data
-      * @return register data
-      */
-    uint8_t write_reg(uint8_t addr, uint8_t data);
-
-protected:
-    I2C  _i2c;
-
-    void initialize(void);
-
-private:
-    INA219_TypeDef ina219_set_data;
-    int32_t scale_factor;
-    uint8_t dt[4];
-
-};
-
-//-------------------------------------------------------------------------------------------------
-// Following parts are only internal use and you only use it if you manage an internal config reg.
-//-------------------------------------------------------------------------------------------------
-/////////// BIT DEFINITION ////////////////////////////////
-#define INA219_CFG_RESET           (1UL << 15)
-
-#define INA219_CFG_B32V            (1UL << 13)
-#define INA219_CFG_B16V            (0UL << 13)
-
-#define INA219_CFG_PGA_DIV_1       (0UL << 11)
-#define INA219_CFG_PGA_DIV_2       (1UL << 11)
-#define INA219_CFG_PGA_DIV_4       (2UL << 11)
-#define INA219_CFG_PGA_DIV_8       (3UL << 11)
-
-#define INA219_CFG_BADC            (0xf << 7)
-
-#define INA219_CFG_SADC_9B_84U     (0x0 << 3)
-#define INA219_CFG_SADC_10B_148U   (0x1 << 3)
-#define INA219_CFG_SADC_11B_276U   (0x2 << 3)
-#define INA219_CFG_SADC_12B_532U   (0x3 << 3)
-#define INA219_CFG_SADC_2S_1R06M   (0x9 << 3)
-#define INA219_CFG_SADC_4S_2R13M   (0xa << 3)
-#define INA219_CFG_SADC_8S_4R26M   (0xb << 3)
-#define INA219_CFG_SADC_16S_8R51M  (0xc << 3)
-#define INA219_CFG_SADC_32S_17M    (0xd << 3)
-#define INA219_CFG_SADC_64S_34M    (0xe << 3)
-#define INA219_CFG_SADC_128S_68M   (0xf << 3)
-
-#define INA219_CFG_MODE_PDWN       (0UL << 0)
-#define INA219_CFG_MODE_SHNTTRG    (1UL << 0)
-#define INA219_CFG_MODE_BUSTRG     (2UL << 0)
-#define INA219_CFG_MODE_SBTRG      (3UL << 0)
-#define INA219_CFG_MODE_ADC_OFF    (4UL << 0)
-#define INA219_CFG_MODE_SHNT_CONT  (5UL << 0)
-#define INA219_CFG_MODE_BUS_CONT   (6UL << 0)
-#define INA219_CFG_MODE_SB_CONT    (7UL << 0)
-
-#endif  //  MBED_INA219
diff -r 088b8d5de7e9 -r 3ee11c82acdb INA230.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INA230.cpp	Fri Mar 24 00:13:28 2017 +0000
@@ -0,0 +1,321 @@
+/*
+ * mbed library program
+ *  INA230 High-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface
+ *  by Texas Instruments
+ *
+ * Copyright (c) 2015 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created: January   25th, 2015
+ *      Revised: May        5th, 2015
+ *
+ * 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.
+ */
+
+#include    "mbed.h"
+#include    "INA230.h"
+
+INA230::INA230 (PinName p_sda, PinName p_scl, const INA230_TypeDef *ina230_parameter) :
+    _i2c(p_sda, p_scl)
+{
+    _i2c.frequency(400000);
+    ina230_set_data = *ina230_parameter;
+    initialize();
+}
+
+INA230::INA230 (PinName p_sda, PinName p_scl, uint8_t addr) :
+    _i2c(p_sda, p_scl)
+{
+    _i2c.frequency(400000);
+    // Use standard setting
+    ina230_set_data = ina230_std_paramtr;
+    // Change user defined address
+    ina230_set_data.addr = addr;
+    initialize();
+}
+
+INA230::INA230 (PinName p_sda, PinName p_scl) :
+    _i2c(p_sda, p_scl)
+{
+    _i2c.frequency(400000);
+    // Use standard setting
+    ina230_set_data = ina230_std_paramtr;
+    initialize();
+}
+
+INA230::INA230 (I2C& p_i2c, const INA230_TypeDef *ina230_parameter) : _i2c(p_i2c)
+{
+    _i2c.frequency(400000);
+    ina230_set_data = *ina230_parameter;
+    initialize();
+}
+
+INA230::INA230 (I2C& p_i2c, uint8_t addr) : _i2c(p_i2c)
+{
+    _i2c.frequency(400000);
+    // Use standard setting
+    ina230_set_data = ina230_std_paramtr;
+    // Change user defined address
+    ina230_set_data.addr = addr;
+    initialize();
+}
+
+INA230::INA230 (I2C& p_i2c) : _i2c(p_i2c)
+{
+    _i2c.frequency(400000);
+    // Use standard setting
+    ina230_set_data = ina230_std_paramtr;
+    initialize();
+}
+
+/////////////// Read Current //////////////////////////////
+//int16_t rawIreg = 0;
+float INA230::read_current()
+{
+    dt[0] = INA230_CURRENT;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    int16_t data = (dt[0] << 8) | dt[1];
+    //rawIreg = data;
+    return (double)data * 0.08255;
+    // 0.06605 & CalReg = 0xF000 works to 2.16A (25.9W) with 2512 0.01ohm, cal'd @ 1.500A
+    // 0.07075 & CalReg = 0xE000 works to 2.31A (27.7W)
+    // 0.07617 & CalReg = 0xD000 works to 2.50A (30.0W)
+    // 0.08255 & CalReg = 0xC000 works to 2.70A (32.4W)
+    //was
+    // 0.06065 & CalReg = 0xF000 works to 1.98A (23.8W) with 1206 0.01ohm
+    // 0.06500 & CalReg = 0xE000 works to 2.15A (25.9W)
+    // 0.07570 & CalReg = 0xC000 works to 2.48A (29.4W)
+}
+
+/////////////// Read Current //////////////////////////////
+int16_t INA230::read_current_reg()
+{
+    dt[0] = INA230_CURRENT;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    uint16_t data = (dt[0] << 8) | dt[1];
+    return data;
+}
+
+/////////////// Read Power ////////////////////////////////
+float INA230::read_power()
+{
+    dt[0] = INA230_POWER;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    int16_t data = (dt[0] << 8) | dt[1];
+    return (float)data / 2000;
+}
+
+//---------------------------------------------------------------------
+// Read Bus_volt
+
+float INA230::read_bus_voltage()
+{
+    dt[0] = INA230_BUS_VOLT;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    int16_t data = (dt[0] << 8) | dt[1];
+    //pc.printf("\r\nG = %+9.3f [V]   0x%x\r\n", (float)data * 0.00125f, data);
+    return (float)data * 0.00125f;
+}
+
+/////////////// Read Shunt volt ///////////////////////////
+float INA230::read_shunt_voltage()
+{
+    dt[0] = INA230_SHUNT_V;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    int16_t data = (dt[0] << 8) | dt[1];
+    return (float)data;
+}
+
+float INA230::read_current_by_shuntvolt()
+{
+    dt[0] = INA230_SHUNT_V;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    int16_t data = (dt[0] << 8) | dt[1];
+    return (float)data / 10;
+//    return ((float)data / ina230_set_data.shunt_register) / 1000;
+}
+
+/////////////// Read configulation ////////////////////////
+uint16_t INA230::read_config()
+{
+    dt[0] = INA230_CONFIG;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    uint16_t data = (dt[0] << 8) | dt[1];
+    return data;
+}
+
+//---------------------------------------------------------------------
+// get mask enable reg
+
+uint16_t INA230::read_mask_enable()
+{
+    dt[0] = INA230_MASK_ENABLE;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    uint16_t data = (dt[0] << 8) | dt[1];
+    ina230_set_data.die_id_data = data;
+    return data;
+}
+
+//---------------------------------------------------------------------
+// get alert limit register
+
+uint16_t INA230::read_alert_limit()
+{
+    dt[0] = INA230_ALERT_LIMIT;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    uint16_t data = (dt[0] << 8) | dt[1];
+    ina230_set_data.die_id_data = data;
+    return data;
+}
+
+//---------------------------------------------------------------------
+// get die ID
+
+uint16_t INA230::read_die_id()
+{
+    dt[0] = INA230_DIE_ID;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    uint16_t data = (dt[0] << 8) | dt[1];
+    ina230_set_data.die_id_data = data;
+    return data;
+}
+
+//---------------------------------------------------------------------
+// set mask enable register
+
+uint16_t INA230::set_mask_enable(uint16_t cfg)
+{
+    uint16_t data = cfg;
+    dt[0] = INA230_MASK_ENABLE;
+    dt[1] = data >> 8;    // MSB 1st
+    dt[2] = data & 0xff;  // LSB 2nd
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false);
+    return data;
+}
+
+//---------------------------------------------------------------------
+// set mask enable register
+
+uint16_t INA230::set_alert_limit(uint16_t cfg)
+{
+    uint16_t data = cfg;
+    dt[0] = INA230_ALERT_LIMIT;
+    dt[1] = data >> 8;    // MSB 1st
+    dt[2] = data & 0xff;  // LSB 2nd
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false);
+    return data;
+}
+
+//---------------------------------------------------------------------
+// get shunt resistor value
+
+int16_t INA230::get_shunt_res() { return ina230_set_data.shunt_res; }
+
+/*
+//---------------------------------------------------------------------
+// print stuff for degugging
+
+extern RawSerial pc;
+
+void INA230::dumpStructure() {
+    pc.printf("Addr: %02x   A: %04x   B: %04x   S: %04x   M: %04x   Conf: %04x   Cal: %04x    Die: %04x    SR: %d\r\n", ina230_set_data.addr, ina230_set_data.average, ina230_set_data.bus_ct, 
+                ina230_set_data.shunt_ct, ina230_set_data.mode,
+                ina230_set_data.average | ina230_set_data.bus_ct | ina230_set_data.shunt_ct | ina230_set_data.mode,
+                ina230_set_data.cal_data, ina230_set_data.die_id_data, ina230_set_data.shunt_res);
+}
+*/
+
+/////////////// Set configulation /////////////////////////
+uint16_t INA230::set_config(uint16_t cfg)
+{
+    uint16_t data = cfg;
+    dt[0] = INA230_CONFIG;
+    dt[1] = data >> 8;    // MSB 1st
+    dt[2] = data & 0xff;  // LSB 2nd
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false);
+    return data;
+}
+
+/////////////// Read Calibration reg. /////////////////////
+uint16_t INA230::read_calb(void)
+{
+    dt[0] = INA230_CALIB;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 2, false);
+    uint16_t data = (dt[0] << 8) | dt[1];
+    return data;
+}
+
+/////////////// Set Calibration reg. //////////////////////
+uint16_t INA230::set_calb(uint16_t clb)
+{
+    uint16_t data = clb;
+    dt[0] = INA230_CALIB;
+    dt[1] = data >> 8;    // MSB 1st
+    dt[2] = data & 0xff;  // LSB 2nd
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false);
+    return data;
+}
+
+/////////////// Read/Write specific register //////////////
+uint8_t INA230::read_reg(uint8_t addr)
+{
+    dt[0] = addr;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 1, true);
+    _i2c.read((int)ina230_set_data.addr, (char *)dt, 1, false);
+    return dt[0];
+}
+
+uint8_t INA230::write_reg(uint8_t addr, uint8_t data)
+{
+    dt[0] = addr;
+    dt[1] = data;
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 2, false);
+    return dt[1];
+}
+
+/////////////// Initialize ////////////////////////////////
+void INA230::initialize()
+{
+/*
+    uint16_t data = 0;
+    data  = (ina230_set_data.v_max & 0x01) << 13;
+    data |= (ina230_set_data.gain & 0x03) << 11;
+    data |= (ina230_set_data.bus_adc_resolution & 0x0f) << 7;
+    data |= (ina230_set_data.Shunt_adc_resolution & 0x0f) << 3;
+    data |= (ina230_set_data.mode & 0x07);
+*/
+    uint16_t data = ina230_set_data.average | ina230_set_data.bus_ct | ina230_set_data.shunt_ct | ina230_set_data.bus_ct | ina230_set_data.mode;
+    dt[0] = INA230_CONFIG;
+    dt[1] = data >> 8;    // MSB 1st
+    dt[2] = data & 0xff;  // LSB 2nd
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false);
+    dt[0] = INA230_CALIB;
+    dt[1] = ina230_set_data.cal_data >> 8;    // MSB 1st
+    dt[2] = ina230_set_data.cal_data & 0xff;  // LSB 2nd
+    _i2c.write((int)ina230_set_data.addr, (char *)dt, 3, false);
+    scale_factor = 0;
+}
+
+/////////////// I2C Freq. /////////////////////////////////
+void INA230::frequency(int hz)
+{
+    _i2c.frequency(hz);
+}
+
+
+
diff -r 088b8d5de7e9 -r 3ee11c82acdb INA230.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INA230.h	Fri Mar 24 00:13:28 2017 +0000
@@ -0,0 +1,311 @@
+/*
+ * mbed library program
+ *  INA230 High/Low-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface
+ *  by Texas Instruments
+ *
+ * Kevin Braun hack of INA219 code by TI
+ * 23-MAR-2017
+*/
+
+#ifndef        MBED_INA230
+#define        MBED_INA230
+
+// Set data into "addr"
+#define INA230_ADDR_GG              0x80
+#define INA230_ADDR_GV              0x82
+#define INA230_ADDR_GA              0x84
+#define INA230_ADDR_GL              0x86
+#define INA230_ADDR_VG              0x88
+#define INA230_ADDR_VV              0x8a
+#define INA230_ADDR_VA              0x8c
+#define INA230_ADDR_VL              0x8e
+#define INA230_ADDR_AG              0x90
+#define INA230_ADDR_AV              0x92
+#define INA230_ADDR_AA              0x94
+#define INA230_ADDR_AL              0x96
+#define INA230_ADDR_LG              0x98
+#define INA230_ADDR_LV              0x9a
+#define INA230_ADDR_LA              0x9c
+#define INA230_ADDR_LL              0x9e
+
+// INA230 ID
+#define INA_219_DIE                 0x4000
+#define INA_230_DIE                 0x2260
+
+// INA230 register set
+#define INA230_CONFIG               0x00
+#define INA230_SHUNT_V              0x01
+#define INA230_BUS_VOLT             0x02
+#define INA230_POWER                0x03
+#define INA230_CURRENT              0x04
+#define INA230_CALIB                0x05
+#define INA230_MASK_ENABLE          0x06
+#define INA230_ALERT_LIMIT          0x07
+#define INA230_DIE_ID               0xff
+
+// CONFIG regisrer bits
+
+//Number of Averages in 230 CONFIG register
+#define INA230_AVG_1                0x0000
+#define INA230_AVG_4                0x0200
+#define INA230_AVG_16               0x0400
+#define INA230_AVG_64               0x0600
+#define INA230_AVG_128              0x0800
+#define INA230_AVG_256              0x0a00
+#define INA230_AVG_512              0x0c00
+#define INA230_AVG_1024             0x0e00
+
+//Bus Voltage Conv Time in 230 CONFIG REG
+#define INA230_BUS_CT_140u          0x0000
+#define INA230_BUS_CT_204u          0x0040
+#define INA230_BUS_CT_332u          0x0080
+#define INA230_BUS_CT_588u          0x00c0
+#define INA230_BUS_CT_1m100         0x0100
+#define INA230_BUS_CT_2m116         0x0140
+#define INA230_BUS_CT_4m156         0x0180
+#define INA230_BUS_CT_8m244         0x01c0
+
+//Shunt Voltage Conv Time in 230 CONFIG REG
+#define INA230_SHUNT_CT_140u        0x0000
+#define INA230_SHUNT_CT_204u        0x0008
+#define INA230_SHUNT_CT_332u        0x0010
+#define INA230_SHUNT_CT_588u        0x0018
+#define INA230_SHUNT_CT_1m100       0x0020
+#define INA230_SHUNT_CT_2m116       0x0028
+#define INA230_SHUNT_CT_4m156       0x0030
+#define INA230_SHUNT_CT_8m244       0x0038
+
+// Set data into "mode"
+#define INA230_PAR_M_PDWN           0
+#define INA230_PAR_M_SHNT_TRG       1
+#define INA230_PAR_M_BUS_TRG        2
+#define INA230_PAR_M_SHNTBUS_TRG    3
+#define INA230_PAR_M_ADC_OFF        4
+#define INA230_PAR_M_SHNT_CONT      5
+#define INA230_PAR_M_BUS_CONT       6
+#define INA230_PAR_M_SHNTBUS_CONT   7    // Default
+
+// Mask/Enable and Alert/Limit regisrer bits
+#define INA230_MEAL_SOL             0x8000
+#define INA230_MEAL_SUL             0x4000
+#define INA230_MEAL_BOL             0x2000
+#define INA230_MEAL_BUL             0x1000
+#define INA230_MEAL_POL             0x0800
+#define INA230_MEAL_CNVR            0x0400
+
+#define INA230_MEAL_AFF             0x0010
+#define INA230_MEAL_CVRF            0x0008
+#define INA230_MEAL_OVF             0x0004
+#define INA230_MEAL_APOL            0x0002
+#define INA230_MEAL_LEN             0x0001
+
+// Set data into "shunt_register"
+#define INA230_PAR_R_005MOHM        5
+#define INA230_PAR_R_010MOHM        10
+#define INA230_PAR_R_020MOHM        20
+#define INA230_PAR_R_025MOHM        25
+#define INA230_PAR_R_033MOHM        33
+#define INA230_PAR_R_050MOHM        50
+#define INA230_PAR_R_068MOHM        68
+#define INA230_PAR_R_075MOHM        75
+#define INA230_PAR_R_100MOHM        100
+
+
+    /** 
+     * Private data structure for INA230 data values.
+     * 
+    **/
+    typedef struct {
+        // I2C Address
+        uint8_t addr;           /*!< I2C address*/
+        //Alternate CONFIG
+        uint16_t average;       /*!< CONFIG Reg - Averaging bits 11-9*/
+        uint16_t bus_ct;        /*!< CONFIG Reg - Bus CT bits 8-6 */
+        uint16_t shunt_ct;      /*!< CONFIG Reg - Shunt CT bits 5-3*/
+        uint16_t mode;          /*!< CONFIG Reg - Mode bits 2-0*/
+        // CALBLATION REG
+        uint16_t cal_data;      /*!< CALIB Reg value*/
+        //DIE ID REG
+        uint16_t die_id_data;   /*!< Device ID  - s/b 0x2260*/
+        int16_t  shunt_res;     /*!< Shunt Resistor value * 100, 100 = 0.100 ohm*/
+    } INA230_TypeDef;
+
+    /** 
+     * Default values for data structure above
+     * 
+    **/
+    const INA230_TypeDef ina230_std_paramtr = {
+        // I2C Address
+        INA230_ADDR_GG,
+        // CONFIG Register
+        INA230_AVG_16,              // averages
+        INA230_BUS_CT_588u,         // bus voltage conv time
+        INA230_SHUNT_CT_588u,       // bus voltage conv time
+        INA230_PAR_M_SHNTBUS_CONT,  // Measure continuously both Shunt voltage and Bus voltage
+        // Calibration Register
+        16384,                      // Calibration data
+        //Die ID Register
+        0,                          // should be non-zero if read correctly
+        // Shuny Resistor
+        INA230_PAR_R_075MOHM        // shunt resistor value
+    };
+
+/** INA230 High/Low-Side Measurement,Bi-Directional CURRENT/POWER MONITOR with I2C Interface
+ *
+ * @code
+ *      //
+ *      // to date, only tested with...
+ *          // * 0.050 shunt resistor
+ *          // * I2C address 0x80 (1000000xb)
+ *          // * +-0-1.5A range
+ *          // * 0-2.8V range
+ *      //
+ * @endcode
+ */
+ 
+class INA230
+{
+public:
+    /** Configure data pin
+      * @param data SDA and SCL pins
+      * @param parameter address chip (INA230_TypeDef)
+      * @param or just set address or just port
+      */
+    INA230(PinName p_sda, PinName p_scl, const INA230_TypeDef *ina230_parameter);
+    INA230(PinName p_sda, PinName p_scl, uint8_t addr);
+    INA230(PinName p_sda, PinName p_scl);
+
+    /** Configure data pin (with other devices on I2C line)
+      * @param I2C previous definition
+      * @param parameter address chip (INA230_TypeDef)
+      * @param or just set address or just port
+      */
+    INA230(I2C& p_i2c, const INA230_TypeDef *ina230_parameter);
+    INA230(I2C& p_i2c, uint8_t addr);
+    INA230(I2C& p_i2c);
+
+    /** Read Current data
+      * @param none
+      * @return current [mA]
+      */
+    float read_current(void);
+    int16_t read_current_reg(void);
+    float read_current_by_shuntvolt(void);
+
+    /** Read Power data
+      * @param none
+      * @return power [w]
+      */
+    float read_power(void);
+
+    /** Read Bus voltage
+      * @param none
+      * @return voltage [v]
+      */
+    float read_bus_voltage(void);
+
+    /** Read Shunt voltage data
+      * @param none
+      * @return voltage [v]
+      */
+    float read_shunt_voltage(void);
+
+    /** Read configration reg.
+      * @param none
+      * @return configrartion register value
+      */
+    uint16_t read_config(void);
+
+    /** Set configration reg.
+      * @param
+      * @return configrartion register value
+      */
+    uint16_t set_config(uint16_t cfg);
+
+    /** Read calibration reg.
+      * @param none
+      * @return calibration register value
+      */
+    uint16_t read_calb(void);
+
+    /** Set calibration reg.
+      * @param
+      * @return calibration register value
+      */
+    uint16_t set_calb(uint16_t clb);
+
+    /** Set I2C clock frequency
+      * @param freq.
+      * @return none
+      */
+    void frequency(int hz);
+
+    /** Read register (general purpose)
+      * @param register's address
+      * @return register data
+      */
+    uint8_t read_reg(uint8_t addr);
+
+    /** Write register (general purpose)
+      * @param register's address
+      * @param data
+      * @return register data
+      */
+    uint8_t write_reg(uint8_t addr, uint8_t data);
+/*    
+    / ** Temporary display of data structure for debug
+     * - Needs "Rawserial pc;" statement
+     * @param none
+     * @return none
+     * /
+    void dumpStructure();
+*/    
+    /** Get the Die ID value
+     * @param none
+     * @return register data
+     */
+    uint16_t read_die_id();
+    
+    /** Get the Mask/Enable value
+     * @param none
+     * @return register data
+     */
+    uint16_t read_mask_enable();
+    
+    /** Get the Alert/Limit value
+     * @param none
+     * @return register data
+     */
+    uint16_t read_alert_limit();
+    
+    /** Set the Mask/Enable value
+     * @param data for register
+     * @return data sent
+     */
+    uint16_t set_mask_enable(uint16_t cfg);
+    
+    /** Set the Alert/Limit value
+     * @param data for register
+     * @return data sent
+     */
+    uint16_t set_alert_limit(uint16_t cfg);
+    
+    /** Get the Shunt Resistor value
+     * @param none
+     * @return resistor value * 100
+     */
+    int16_t  get_shunt_res();
+
+protected:
+    I2C  _i2c;
+
+    void initialize(void);
+
+private:
+    INA230_TypeDef ina230_set_data;
+    int32_t scale_factor;
+    uint8_t dt[4];
+
+};
+
+#endif  //  MBED_INA230