Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:156866acc5e4, committed 2018-01-31
- 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 */