LTC2992 - Dual Wide Range Power Monitor

Features

  • Rail-to-Rail Input Range: 0V to 100V
  • Wide Input Supply Range: 2.7V to 100V
  • Measures Current, Voltage, and Power
  • Shunt Regulator for Supplies >100V
  • 8-/12-Bit ADCs with Less Than ±0.3% Total Unadjusted Error
  • Four General Purpose Inputs/Outputs Configurable as ADC Inputs
  • Continuous Scan and Snapshot Modes
  • Stores Minimum and Maximum Measurements
  • Alerts When Alarm Thresholds Exceeded
  • Shutdown Mode with IQ < 50μA
  • Split SDA Pin Eases Opto-Isolation
  • Available in 16-Lead 4mm × 3mm DFN and MSOP Packages

Typical Application

LTC2992 Typical Application
LTC2992 Typical Application

Description

The LTC®2992 is a rail-to-rail system monitor that measures current, voltage, and power of two supplies. It features an operating range of 2.7V to 100V and includes a shunt regulator for supplies above 100V. The voltage measurement range of 0V to 100V is independent of the input supply. Two ADCs simultaneously measure each supply’s current. A third ADC monitors the input voltages and four auxiliary external voltages. Each supply’s current and power is added for total system consumption. Minimum and maximum values are stored and an overrange alert with programmable thresholds minimizes the need for software polling. Data is reported via a standard I2C interface. Shutdown mode reduces current consumption to 25μA typically.

The LTC2992 I2C interface includes separate data input and output pins for use with standard or opto-isolated I2C connections. The LTC2992-1 has an inverted data output for use with inverting opto-isolator configurations.

Packaging

For complete and up to date package information and drawings, please refer to our packaging page

Part Number Package Code Temp Package
Drawing
RoHS
LTC2992CDE-1#PBF 4x3 DFN-16 DE C 05-08-1732 Yes
LTC2992CDE-1#TRPBF 4x3 DFN-16 DE C 05-08-1732 Yes
LTC2992CDE#PBF 4x3 DFN-16 DE C 05-08-1732 Yes
LTC2992CDE#TRPBF 4x3 DFN-16 DE C 05-08-1732 Yes
LTC2992CMS-1#PBF MS-16 MS C 05-08-1669 Yes
LTC2992CMS-1#TRPBF MS-16 MS C 05-08-1669 Yes
LTC2992CMS#PBF MS-16 MS C 05-08-1669 Yes
LTC2992CMS#TRPBF MS-16 MS C 05-08-1669 Yes
LTC2992HDE-1#PBF 4x3 DFN-16 DE H 05-08-1732 Yes
LTC2992HDE-1#TRPBF 4x3 DFN-16 DE H 05-08-1732 Yes
LTC2992HDE#PBF 4x3 DFN-16 DE H 05-08-1732 Yes
LTC2992HDE#TRPBF 4x3 DFN-16 DE H 05-08-1732 Yes
LTC2992HMS-1#PBF MS-16 MS H 05-08-1669 Yes
LTC2992HMS-1#TRPBF MS-16 MS H 05-08-1669 Yes
LTC2992HMS#PBF MS-16 MS H 05-08-1669 Yes
LTC2992HMS#TRPBF MS-16 MS H 05-08-1669 Yes
LTC2992IDE-1#PBF 4x3 DFN-16 DE I 05-08-1732 Yes
LTC2992IDE-1#TRPBF 4x3 DFN-16 DE I 05-08-1732 Yes
LTC2992IDE#PBF 4x3 DFN-16 DE I 05-08-1732 Yes
LTC2992IDE#TRPBF 4x3 DFN-16 DE I 05-08-1732 Yes
LTC2992IMS-1#PBF MS-16 MS I 05-08-1669 Yes
LTC2992IMS-1#TRPBF MS-16 MS I 05-08-1669 Yes
LTC2992IMS#PBF MS-16 MS I 05-08-1669 Yes
LTC2992IMS#TRPBF MS-16 MS I 05-08-1669 Yes


LTC2992 Package Drawing
LTC2992 Package Drawing
LTC2992 Package Drawing
LTC2992 Package Drawing

Order Info

  • Part numbers ending in PBF are lead free. Solder plated terminal finish (SnPb) versions are non-standard and special terms and conditions and pricing applies if available. Please contact LTC marketing for information.
  • Part numbers containing TR or TRM are shipped in tape and reel or 500 unit mini tape and reel, respectively
  • Please refer to our general ordering information or the product datasheet for more details

Package Variations and Pricing

Part Number Package Temp Price
(1-99)
Price
(1k)*
RoHS
LTC2992CDE-1#PBF 4x3 DFN-16 C $5.50 $3.85 Yes
LTC2992CDE-1#TRPBF 4x3 DFN-16 C $5.56 $3.91 Yes
LTC2992CDE#PBF 4x3 DFN-16 C $5.50 $3.85 Yes
LTC2992CDE#TRPBF 4x3 DFN-16 C $5.56 $3.91 Yes
LTC2992CMS-1#PBF MS-16 C $5.50 $3.85 Yes
LTC2992CMS-1#TRPBF MS-16 C $5.56 $3.91 Yes
LTC2992CMS#PBF MS-16 C $5.50 $3.85 Yes
LTC2992CMS#TRPBF MS-16 C $5.56 $3.91 Yes
LTC2992HDE-1#PBF 4x3 DFN-16 H $7.27 $5.09 Yes
LTC2992HDE-1#TRPBF 4x3 DFN-16 H $7.33 $5.15 Yes
LTC2992HDE#PBF 4x3 DFN-16 H $7.27 $5.09 Yes
LTC2992HDE#TRPBF 4x3 DFN-16 H $7.33 $5.15 Yes
LTC2992HMS-1#PBF MS-16 H $7.27 $5.09 Yes
LTC2992HMS-1#TRPBF MS-16 H $7.33 $5.15 Yes
LTC2992HMS#PBF MS-16 H $7.27 $5.09 Yes
LTC2992HMS#TRPBF MS-16 H $7.33 $5.15 Yes
LTC2992IDE-1#PBF 4x3 DFN-16 I $6.33 $4.43 Yes
LTC2992IDE-1#TRPBF 4x3 DFN-16 I $6.39 $4.49 Yes
LTC2992IDE#PBF 4x3 DFN-16 I $6.33 $4.43 Yes
LTC2992IDE#TRPBF 4x3 DFN-16 I $6.39 $4.49 Yes
LTC2992IMS-1#PBF MS-16 I $6.33 $4.43 Yes
LTC2992IMS-1#TRPBF MS-16 I $6.39 $4.49 Yes
LTC2992IMS#PBF MS-16 I $6.33 $4.43 Yes
LTC2992IMS#TRPBF MS-16 I $6.39 $4.49 Yes
Buy NowRequest Samples
* The USA list pricing shown is for BUDGETARY USE ONLY, shown in United States dollars (FOB USA per unit for the stated volume), and is subject to change. International prices may differ due to local duties, taxes, fees and exchange rates. For volume-specific price or delivery quotes, please contact your local Linear Technology sales office or authorized distributor.

Demo Boards

Linear Technology offers many demo boards free of charge to qualified customers. Contact your local sales office or distributor to inquire about a demo board. Certain demo boards are also available for sale via credit card on this website. Demo boards are for evaluation purposes only. It remains the customer’s responsibility to verify proper and reliable operation in the actual end application.

Part Number Description Price Documentation
DC2561A LTC2992 Demo Board: Dual Wide Range Power Monitor $75.00
Buy Now

Companion Boards

Part Number Description Price Documentation
DC2026C Linduino One Isolated USB Demo Board: An Arduino- and QuikEval-Compatible Code Development Platform $75.00
DC590B Isolated USB Serial Controller for Linear Technology QuikEval-Compatible Demo Boards $50.00
Buy Now
Click here to view our complete list of demo boards

Applications

  • Telecom Infrastructure
  • Industrial Equipment
  • Automotive
  • Computer Systems and Servers

Product Notifications

Please login to your MyLinear account for notifications of datasheet updates, new document releases and LTspice model announcements for your favorite products. If you do not have a MyLinear account you may Sign Up Now.

Forgot your password? Click here.
Need help? Email mylinear@linear.com with questions and comments.

Design Tools

Linduino

Linduino is an Arduino compatible platform for developing and distributing firmware libraries and code for SPI and I²C-compatible integrated circuits. The Linduino One board interfaces to more than 300 QuikEval demonstration cards, supporting a variety of product types including analog-to-digital converters (ADCs)digital-to-analog converters (DACs)power monitors, and more. Firmware libraries for individual devices are written in C and designed to be portable to a wide variety of processors and microcontrollers. Each library has a demonstration program that can be uploaded to the Linduino One platform to allow the circuit and software to be quickly and easily verified.

Click here for more information on Linduino

Code

Linduino is Linear Technology's Arduino compatible system for developing and distributing firmware libraries and example code for Linear Technology’s integrated circuits. The code below can be downloaded or copied and pasted into your project. Please visit the Linduino Home Page for demo board, manual and setup information.

This part is Code Supported: There is example code available for this part. The code below may rely on other drivers available in the full library.

Download LTC2992 - Linduino CPP File

/*!
 LTC2992: Dual Wide Range Power Monitor

@verbatim

The LTC®2992 is a rail-to-rail system monitor that measures
current, voltage, power, charge and energy. It features an
operating range of 2.7V to 100V and includes a shunt regulator
for supplies above 100V. The current measurement common mode
range of 0V to 100V is independent of the input supply.
A 12-bit ADC measures load current, input voltage and an
auxiliary external voltage. Load current and internally
calculated power are integrated over an external clock or
crystal or internal oscillator time base for charge and energy.
An accurate time base allows the LTC2992 to provide measurement
accuracy of better than ±0.6% for charge and ±1% for power and
energy. Minimum and maximum values are stored and an overrange
alert with programmable thresholds minimizes the need for software
polling. Data is reported via a standard I2C interface.
Shutdown mode reduces power consumption to 15uA.


I2C DATA FORMAT (MSB FIRST):

Data Out:
Byte #1                                    Byte #2                     Byte #3

START  SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK  X  X C5 C4 C3 C2 C1 C0 SACK D7 D6 D5 D4 D3 D2 D1 D0 SACK  STOP

Data In:
Byte #1                                    Byte #2                                    Byte #3

START  SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK  X  X  C5 C4 C3 C2 C1 C0 SACK  Repeat Start SA6 SA5 SA4 SA3 SA2 SA1 SA0 R SACK

Byte #4                                   Byte #5
MSB                                       LSB
D15 D14  D13  D12  D11  D10  D9 D8 MACK   D7 D6 D5 D4 D3  D2  D1  D0  MNACK  STOP

START       : I2C Start
Repeat Start: I2c Repeat Start
STOP        : I2C Stop
SAx         : I2C Address
SACK        : I2C Slave Generated Acknowledge (Active Low)
MACK        : I2C Master Generated Acknowledge (Active Low)
MNACK       : I2c Master Generated Not Acknowledge
W           : I2C Write (0)
R           : I2C Read  (1)
Cx          : Command Code
Dx          : Data Bits
X           : Don't care



Example Code:

Read power, current and voltage

    CTRLA = LTC2992_CHANNEL_CONFIG_V_C_3|LTC2992_SENSE_PLUS|LTC2992_OFFSET_CAL_EVERY|LTC2992_ADIN_GND;  //! Set Control A register to default value in continuous mode
    ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_CTRLA_REG, CTRLA);   //! Sets the LTC2992 to continuous mode

    resistor = .02; // Resistor Value On Demo Board

    ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_POWER_MSB2_REG, &power_code);  // Reads the ADC registers that contains V^2
    power = LTC2992_code_to_power(power_code, resistor, LTC2992_Power_lsb); // Calculates power from power code, resistor value and power lsb

    ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_DELTA_SENSE_MSB_REG, &current_code); // Reads the voltage code across sense resistor
    current = LTC2992_code_to_current(current_code, resistor, LTC2992_DELTA_SENSE_lsb); // Calculates current from current code, resistor value and current lsb

    ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_SENSE_MSB_REG, &SENSE_code);   // Reads SENSE voltage code
    SENSE = LTC2992_SENSE_code_to_voltage(SENSE_code, LTC2992_SENSE_lsb);  // Calculates SENSE voltage from SENSE code and lsb

    ack |= LTC2992_read_32_bits(LTC2992_I2C_ADDRESS, LTC2992_ENERGY_MSB3_REG, &energy_code);  // Reads energy code
  energy = LTC2992_code_to_energy(energy_code,resistor,LTC2992_Power_lsb, LTC2992_INTERNAL_TIME_lsb); //Calculates Energy in Joules from energy_code, resistor, power lsb and time lsb

  ack |= LTC2992_read_32_bits(LTC2992_I2C_ADDRESS, LTC2992_CHARGE_MSB3_REG, &charge_code);  // Reads charge code
    charge = LTC2992_code_to_coulombs(charge_code,resistor,LTC2992_DELTA_SENSE_lsb, LTC2992_INTERNAL_TIME_lsb); //Calculates charge in coulombs from charge_code, resistor, current lsb and time lsb



@endverbatim

http://www.linear.com/product/LTC2992

http://www.linear.com/product/LTC2992#demoboards

REVISION HISTORY
$Revision: 3659 $
$Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $

Copyright (c) 2013, Linear Technology Corp.(LTC)
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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/

//! @ingroup Power_Monitors
//! @{
//! @defgroup LTC2992 LTC2992: Dual Wide Range Power Monitor
//! @}
/*! @file
    @ingroup LTC2992
    Header for LTC2992: Dual Wide Range Power Monitor
*/

#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_I2C.h"
#include "LTC2992.h"
#include <Wire.h>

// Write an 8-bit code to the LTC2992.
int8_t LTC2992_write(uint8_t i2c_address, uint8_t adc_command, uint8_t code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int32_t ack;

  ack = i2c_write_byte_data(i2c_address, adc_command, code);

  return ack;

}

// Write a 16-bit code to the LTC2992.
int8_t LTC2992_write_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack;

  ack = i2c_write_word_data(i2c_address, adc_command, code);
  return(ack);
}

// Write a 24-bit code to the LTC2992.
int8_t LTC2992_write_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack;

  LT_union_int32_4bytes data;
  data.LT_int32 = code;

  ack = i2c_write_block_data(i2c_address, adc_command, (uint8_t) 3, data.LT_byte);

  return(ack);
}


// Reads an 8-bit adc_code from LTC2992
int8_t LTC2992_read(uint8_t i2c_address, uint8_t adc_command, uint8_t *adc_code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int32_t ack;

  ack = i2c_read_byte_data(i2c_address, adc_command, adc_code);

  return ack;
}

// Reads a 12-bit adc_code from LTC2992
int8_t LTC2992_read_12_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  // Use union type defined in Linduino.h to combine two uint8_t's (8-bit unsigned integers) into one uint16_t (unsigned 16-bit integer)
  // Then, shift by 4 bits and return in *adc_code
  int32_t ack;

  ack = i2c_read_word_data(i2c_address, adc_command, adc_code);

  *adc_code >>= 4;
  return ack;
}

// Reads a 16-bit adc_code from LTC2992
int8_t LTC2992_read_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int32_t ack;

  ack = i2c_read_word_data(i2c_address, adc_command, adc_code);

  return ack;
}

// Reads a 24-bit adc_code from LTC2992
int8_t LTC2992_read_24_bits(uint8_t i2c_address, uint8_t adc_command, uint32_t *adc_code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack;

  LT_union_int32_4bytes data;

  ack = i2c_read_block_data(i2c_address, adc_command, (uint8_t)3, data.LT_byte);

  *adc_code = 0x0FFFFFF & data.LT_int32;
  return(ack);
}

// Calculate the LTC2992 SENSE voltage
float LTC2992_SENSE_code_to_voltage(uint16_t adc_code, float LTC2992_SENSE_lsb)
// Returns the SENSE Voltage in Volts
{
  float voltage;
  voltage = (float)adc_code*LTC2992_SENSE_lsb;    //! 1) Calculate voltage from code and lsb
  return(voltage);
}

// Calculate the LTC2992 GPIO voltage
float LTC2992_GPIO_code_to_voltage(uint16_t adc_code, float LTC2992_GPIO_lsb)
// Returns the GPIO Voltage in Volts
{
  float adc_voltage;
  adc_voltage = (float)adc_code*LTC2992_GPIO_lsb;   //! 1) Calculate voltage from code and ADIN lsb
  return(adc_voltage);
}

// Calculate the LTC2992 current with a sense resistor
float LTC2992_code_to_current(uint16_t adc_code, float resistor, float LTC2992_DELTA_SENSE_lsb)
// Returns the LTC2992 current in Amps
{
  float voltage, current;
  voltage = (float)adc_code*LTC2992_DELTA_SENSE_lsb;    //! 1) Calculate voltage from ADC code and delta sense lsb
  current = voltage/resistor;                           //! 2) Calculate current, I = V/R
  return(current);
}

// Calculate the LTC2992 current with a sense resistor
float LTC2992_code_to_current_sum(uint16_t adc_code, float resistor, float LTC2992_DELTA_SENSE_lsb)
// Returns the LTC2992 current in Amps
{
  float voltage, current;
  voltage = (float)(adc_code<<1)*LTC2992_DELTA_SENSE_lsb;    //! 1) Calculate voltage from ADC code and delta sense lsb
  current = voltage/resistor;                           //! 2) Calculate current, I = V/R
  return(current);
}

// Calculate the LTC2992 power
float LTC2992_code_to_power(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
// Returns The LTC2992 power in Watts
{
  float power;
  power = (float)adc_code*LTC2992_Power_lsb/resistor;  //! 1) Calculate Power using Power lsb and resistor

  return(power);
}

// Calculate the LTC2992 power
float LTC2992_code_to_power_sum(int32_t adc_code, float resistor, float LTC2992_Power_lsb)
// Returns The LTC2992 power in Watts
{
  float power;
  power = (float)(adc_code<<1)*LTC2992_Power_lsb/resistor;  //! 1) Calculate Power using Power lsb and resistor

  return(power);
}

Download LTC2992 - Linduino DC2561A.ino File

/*!
LTC2992: Dual Wide Range Power Monitor

@verbatim

Setting the Thresholds:
    1. Select the Threshold Configuration from the main menu.
    2. Select the desired Threshold to be changed. Then enter the minimum and maximum
       values.
    3. If any reading exceeds the set threshold, a fault will be generated that can be viewed in
     the Read/Clear Faults Menu


Reading and Clearing a Fault:
    1. Select the Read/Clear Fault option from the main menu.
    2. To read all the faults, select Read Faults option. This will display all the faults that have occured.
  3. To clear all faults, go back to the Read/Clear Faults menu and select Clear Faults option.

NOTE: Due to memory limitations of the Atmega328 processor this sketch shows limited functionality of the LTC2992. Please
      check the datasheet for a picture of the full functionality of the LTC2992.

NOTES
 Setup:
 Set the terminal baud rate to 115200 and select the newline terminator.
 Requires a power supply.
 Refer to demo manual DC2561A.

USER INPUT DATA FORMAT:
 decimal : 1024
 hex     : 0x400
 octal   : 02000  (leGPIOg 0 "zero")
 binary  : B10000000000
 float   : 1024.0

@endverbatim
http://www.linear.com/product/LTC2992

http://www.linear.com/product/LTC2992#demoboards
REVISION HISTORY
$Revision: 3659 $
$Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $

Copyright (c) 2013, Linear Technology Corp.(LTC)
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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
 */

/*! @file
    @ingroup LTC2992
*/

#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_I2C.h"
#include "LT_SPI.h"
#include "UserInterface.h"
#include "QuikEval_EEPROM.h"
#include "LTC2992.h"
#include <Wire.h>
#include <SPI.h>

// Function Declaration
void print_title();                 // Print the title block
void print_prompt();                // Print the Prompt

int8_t menu_1_continuous_mode(int8_t CTRLA_mode,  int8_t bit_resolution, float scale);
int8_t menu_2_threshold_config(float scale, int8_t bit_resolution);
int8_t menu_3_GPIO_config();
int8_t menu_4_settings(int8_t *CTRLA_mode, int8_t *bit_resolution);
int8_t menu_5_read_clear_faults();

int8_t menu_2_threshold_menu_1_set_power(int8_t bit_resolution);
int8_t menu_2_threshold_menu_2_set_current(int8_t bit_resolution);
int8_t menu_2_threshold_menu_3_set_SENSE(int8_t bit_resolution);
int8_t menu_2_alert_menu_4_set_adin_alerts(float scale, int8_t bit_resolution);
int8_t menu_2_threshold_menu_5_reset_thresholds();

/* void store_alert_settings();        // Store the alert settings to the EEPROM
int8_t restore_alert_settings();    // Read the alert settings from EEPROM */

#define CONTINUOUS_MODE_DISPLAY_DELAY 1000                  //!< The delay between readings in continious mode

// LSB Weights
const float LTC2992_GPIO_8bit_lsb = 8.000E-3;                //!< Typical GPIO lsb weight for 8-bit mode in volts
const float LTC2992_GPIO_12bit_lsb = 0.500E-3;                //!< Typical GPIO lsb weight for 12-bit mode in volts
const float LTC2992_DELTA_SENSE_8bit_lsb = 200.00E-6;        //!< Typical Delta lsb weight for 8-bit mode in volts
const float LTC2992_DELTA_SENSE_12bit_lsb = 12.50E-6;        //!< Typical Delta lsb weight for 12-bit mode in volts
const float LTC2992_SENSE_8bit_lsb = 400.00E-3;                //!< Typical SENSE lsb weight for 8-bit mode in volts
const float LTC2992_SENSE_12bit_lsb = 25.00E-3;                //!< Typical SENSE lsb weight for 12-bit mode in volts
const float LTC2992_Power_8bit_lsb = LTC2992_DELTA_SENSE_8bit_lsb*LTC2992_SENSE_8bit_lsb;     //!< Typical POWER lsb weight for 8-bit mode in V^2
const float LTC2992_Power_12bit_lsb = LTC2992_DELTA_SENSE_12bit_lsb*LTC2992_SENSE_12bit_lsb;     //!< Typical POWER lsb weight for 12-bit mode in V^2

const float resistor = .01;         //!< resistor value on demo board

// Error string
const char ack_error[] = "Error: No Acknowledge. Check I2C Address."; //!< Error message

// Global variables
static int8_t demo_board_connected;        //!< Set to 1 if the board is connected


//! Initialize Linduino
void setup()
{
  char demo_name[] = "DC2561";      // Demo Board Name stored in QuikEval EEPROM

  quikeval_I2C_init();              //! Configure the EEPROM I2C port for 100kHz
  quikeval_I2C_connect();           //! Connects to main I2C port
  Serial.begin(115200);             //! Initialize the serial port to the PC
  print_title();
  demo_board_connected = discover_demo_board(demo_name);
  if (!demo_board_connected)
  {
    Serial.println(F("Demo board not detected, will attempt to proceed"));
    demo_board_connected = true;
  }
  if (demo_board_connected)
  {
    // restore_alert_settings();
    print_prompt();
  }
}

//! Repeats Linduino loop
void loop()
{
  int8_t ack = 0;                               //! I2C acknowledge indicator
  static uint8_t user_command;                  //! The user input command

  static int8_t CTRLA_mode = 0x00;              //! CTRLA Register Setting Default.
  static int8_t bit_resolution = 1;             //! Variable to select ADC Resolution. 1 = 12-bit, 0 = 8-bit. Settable in Settings.

  static float scale = (150/3);                 //! Stores division ratio for resistive divider on GPIO pin.  Configured inside "Settings" menu.

  if (demo_board_connected)                     //! Do nothing if the demo board is not connected
  {
    if (Serial.available())                     //! Do nothing if serial is not available
    {
      user_command = read_int();                //! Read user input command
      if (user_command != 'm')
        Serial.println(user_command);
      Serial.println();
      ack = 0;
      switch (user_command)                     //! Prints the appropriate submenu
      {
        case 1:
          ack |= menu_1_continuous_mode(CTRLA_mode, bit_resolution, scale);  //! Continuous Mode
          break;

        case 2:
          ack |= menu_2_threshold_config(scale, bit_resolution);               //! Configure Threshold Values
          break;

        case 3:
          ack |= menu_3_GPIO_config();                                         //! Toggle GPIO States
          break;

        case 4:
          ack |= menu_4_settings(&CTRLA_mode, &bit_resolution);                 //! Configure ADC Resolution and Shutdown mode in Settings.
          break;

        case 5:
          ack |= menu_5_read_clear_faults();                                    //! Read/Clear Faults
          break;

        default:
          Serial.println(F("Incorrect Option"));
          break;
      }
      if (ack != 0)
        Serial.println(ack_error);
      Serial.print(F("*************************"));
      print_prompt();
    }
  }
}

// Function Definitions

//! Print the title block
void print_title()
{
  Serial.println(F("\n*****************************************************************"));
  Serial.print(F("* DC2561 Demonstration Program                                  *\n"));
  Serial.print(F("*                                                               *\n"));
  Serial.print(F("* This program communicates with the LTC2992 12-Bit Dual Wide   *\n"));
  Serial.print(F("* Range I2C Power Monitor found on the DC2561 demo board.       *\n"));
  Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
  Serial.print(F("*                                                               *\n"));
  Serial.print(F("*****************************************************************\n"));
}

//! Print the Prompt
void print_prompt()
{
  Serial.print(F("\n1-Continuous Mode\n"));
  Serial.print(F("2-Threshold Configuration\n"));
  Serial.print(F("3-GPIO Control\n"));
  Serial.print(F("4-Settings\n"));
  Serial.print(F("5-Read/Clear Faults\n\n"));
  Serial.print(F("Enter a command: "));
}

//! Continuous Mode.
int8_t menu_1_continuous_mode(int8_t CTRLA_mode, //!< Set Continious Mode
                              int8_t bit_resolution, //!< Set ADC Resolution
                              float scale) //!< Stores division ratio for resistive divider on GPIO pin.  Configured inside "Settings" menu.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t LTC2992_mode;
  int8_t ack = 0;
  CTRLA_mode = ((CTRLA_mode & LTC2992_CTRLA_MEASUREMENT_MODE_MASK) | (LTC2992_MODE_CONTINUOUS & ~LTC2992_CTRLA_MEASUREMENT_MODE_MASK));
  Serial.println();
  ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_CTRLA_REG, LTC2992_mode); //! Sets the LTC2992 to continuous mode
  do
  {

    Serial.print(F("**********************************************************************************************\n\n"));
    Serial.print(F("	Channel 1					   Channel 2\n\n"));
    if (bit_resolution == 1)
    {
      uint32_t power1_code, power2_code, max_power1_code, max_power2_code, min_power1_code, min_power2_code;
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_POWER1_MSB2_REG, & power1_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_POWER2_MSB2_REG, & power2_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER1_MSB2_REG, & max_power1_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER2_MSB2_REG, & power2_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER1_MSB2_REG, & min_power1_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER2_MSB2_REG, & min_power2_code);

      float power1, power2, max_power1, max_power2, min_power1, min_power2; // Store power results
      power1 = LTC2992_code_to_power(power1_code, resistor, LTC2992_Power_12bit_lsb);
      power2 = LTC2992_code_to_power(power2_code, resistor, LTC2992_Power_12bit_lsb);
      max_power1 = LTC2992_code_to_power(max_power1_code, resistor, LTC2992_Power_12bit_lsb);
      max_power2 = LTC2992_code_to_power(max_power2_code, resistor, LTC2992_Power_12bit_lsb);
      min_power1 = LTC2992_code_to_power(min_power1_code, resistor, LTC2992_Power_12bit_lsb);
      min_power2 = LTC2992_code_to_power(min_power2_code, resistor, LTC2992_Power_12bit_lsb);

      Serial.print(F("      Power 1: "));
      Serial.print(power1, 4);
      Serial.print(F(" W"));

      Serial.print(F("					Power 2: "));
      Serial.print(power2, 4);
      Serial.print(F(" W\n"));

      Serial.print(F("  Max Power 1: "));
      Serial.print(max_power1, 4);
      Serial.print(F(" W"));

      Serial.print(F("				    Max Power 2: "));
      Serial.print(max_power2, 4);
      Serial.print(F(" W\n"));

      Serial.print(F("  Min Power 1: "));
      Serial.print(min_power1, 4);
      Serial.print(F(" W"));

      Serial.print(F("				    Min Power 2: "));
      Serial.print(min_power2, 4);
      Serial.print(F(" W\n"));

      uint16_t current1_code, current2_code, max_current1_code, max_current2_code, min_current1_code, min_current2_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_DELTA_SENSE1_MSB_REG, & current1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA1_SENSE_MSB_REG, & max_current1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA1_SENSE_MSB_REG, & min_current1_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_DELTA_SENSE2_MSB_REG, & current2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA2_SENSE_MSB_REG, & max_current2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA2_SENSE_MSB_REG, & min_current2_code);

      float current1, current2, max_current1, max_current2, min_current1, min_current2;
      current1 = LTC2992_code_to_current(current1_code, resistor, LTC2992_DELTA_SENSE_12bit_lsb);
      max_current1 = LTC2992_code_to_current(max_current1_code, resistor, LTC2992_DELTA_SENSE_12bit_lsb);
      min_current1 = LTC2992_code_to_current(min_current1_code, resistor, LTC2992_DELTA_SENSE_12bit_lsb);

      current2 = LTC2992_code_to_current(current2_code, resistor, LTC2992_DELTA_SENSE_12bit_lsb);
      max_current2 = LTC2992_code_to_current(max_current2_code, resistor, LTC2992_DELTA_SENSE_12bit_lsb);
      min_current2 = LTC2992_code_to_current(min_current2_code, resistor, LTC2992_DELTA_SENSE_12bit_lsb);

      Serial.print(F("\n    Current 1: "));
      Serial.print(current1, 4);
      Serial.print(F(" A"));

      Serial.print(F("                               Current 2: "));
      Serial.print(current2, 4);
      Serial.print(F(" A\n"));

      Serial.print(F("Max Current 1: "));
      Serial.print(max_current1, 4);
      Serial.print(F(" A"));

      Serial.print(F("				  Max Current 2: "));
      Serial.print(max_current2, 4);
      Serial.print(F(" A\n"));

      Serial.print(F("Min Current 1: "));
      Serial.print(min_current1, 4);
      Serial.print(F(" A"));

      Serial.print(F("			          Min Current 2: "));
      Serial.print(min_current2, 4);
      Serial.print(F(" A\n"));

      uint16_t SENSE1_code, max_SENSE1_code, min_SENSE1_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_SENSE1_MSB_REG, & SENSE1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE1_MSB_REG, & max_SENSE1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE1_MSB_REG, & min_SENSE1_code);

      float SENSE1, max_SENSE1, min_SENSE1;
      SENSE1 = LTC2992_SENSE_code_to_voltage(SENSE1_code, LTC2992_SENSE_12bit_lsb);
      max_SENSE1 = LTC2992_SENSE_code_to_voltage(max_SENSE1_code, LTC2992_SENSE_12bit_lsb);
      min_SENSE1 = LTC2992_SENSE_code_to_voltage(min_SENSE1_code, LTC2992_SENSE_12bit_lsb);

      uint16_t SENSE2_code, max_SENSE2_code, min_SENSE2_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_SENSE2_MSB_REG, & SENSE2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE2_MSB_REG, & max_SENSE2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE2_MSB_REG, & min_SENSE2_code);

      float SENSE2, max_SENSE2, min_SENSE2;
      SENSE2 = LTC2992_SENSE_code_to_voltage(SENSE2_code, LTC2992_SENSE_12bit_lsb);
      max_SENSE2 = LTC2992_SENSE_code_to_voltage(max_SENSE2_code, LTC2992_SENSE_12bit_lsb);
      min_SENSE2 = LTC2992_SENSE_code_to_voltage(min_SENSE2_code, LTC2992_SENSE_12bit_lsb);

      Serial.print(F("\n      SENSE 1: "));
      Serial.print(SENSE1, 4);
      Serial.print(F(" V"));

      Serial.print(F("			                SENSE 2: "));
      Serial.print(SENSE2, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("  Max SENSE 1: "));
      Serial.print(max_SENSE1, 4);
      Serial.print(F(" V"));

      Serial.print(F("		                    Max SENSE 2: "));
      Serial.print(max_SENSE2, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("  Min SENSE 1: "));
      Serial.print(min_SENSE1, 4);
      Serial.print(F(" V"));

      Serial.print(F("			            Min SENSE 2: "));
      Serial.print(min_SENSE2, 4);
      Serial.print(F(" V\n"));

      uint32_t power_sum_code;
      uint16_t current_sum_code;
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_PSUM_MSB1_REG, & power_sum_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_ISUM_MSB_REG, & current_sum_code);

      float power_sum, current_sum;
      power_sum = LTC2992_code_to_power_sum(power_sum_code, resistor, LTC2992_Power_12bit_lsb);
      current_sum = LTC2992_code_to_current_sum(current_sum_code, resistor, LTC2992_DELTA_SENSE_12bit_lsb);

      Serial.print(F("\n   Power Sum: "));
      Serial.print(power_sum, 4);
      Serial.print(F(" W\n"));

      Serial.print(F(" Current Sum: "));
      Serial.print(current_sum, 4);
      Serial.print(F(" A\n"));

      uint16_t GPIO1_code, max_GPIO1_code, min_GPIO1_code, GPIO2_code, max_GPIO2_code, min_GPIO2_code,
               GPIO3_code, max_GPIO3_code, min_GPIO3_code, GPIO4_code, max_GPIO4_code, min_GPIO4_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO1_MSB_REG, & GPIO1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO1_MSB_REG, & max_GPIO1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO1_MSB_REG, & min_GPIO1_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO2_MSB_REG, & GPIO2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO2_MSB_REG, & max_GPIO2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO2_MSB_REG, & min_GPIO2_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO3_MSB_REG, & GPIO3_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO3_MSB_REG, & max_GPIO3_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO3_MSB_REG, & min_GPIO3_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO4_MSB_REG, & GPIO4_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO4_MSB_REG, & max_GPIO4_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO4_MSB_REG, & min_GPIO4_code);

      float GPIO1, max_GPIO1, min_GPIO1, GPIO2, max_GPIO2, min_GPIO2, GPIO3, max_GPIO3, min_GPIO3, GPIO4, max_GPIO4, min_GPIO4;
      GPIO1 = LTC2992_GPIO_code_to_voltage(GPIO1_code, LTC2992_GPIO_12bit_lsb);
      max_GPIO1 = LTC2992_GPIO_code_to_voltage(max_GPIO1_code, LTC2992_GPIO_12bit_lsb);
      min_GPIO1 = LTC2992_GPIO_code_to_voltage(min_GPIO1_code, LTC2992_GPIO_12bit_lsb);

      GPIO2 = LTC2992_GPIO_code_to_voltage(GPIO2_code, LTC2992_GPIO_12bit_lsb);
      max_GPIO2 = LTC2992_GPIO_code_to_voltage(max_GPIO2_code, LTC2992_GPIO_12bit_lsb);
      min_GPIO2 = LTC2992_GPIO_code_to_voltage(min_GPIO2_code, LTC2992_GPIO_12bit_lsb);

      GPIO3 = LTC2992_GPIO_code_to_voltage(GPIO3_code, LTC2992_GPIO_12bit_lsb);
      max_GPIO3 = LTC2992_GPIO_code_to_voltage(max_GPIO3_code, LTC2992_GPIO_12bit_lsb);
      min_GPIO3 = LTC2992_GPIO_code_to_voltage(min_GPIO3_code, LTC2992_GPIO_12bit_lsb);

      GPIO4 = LTC2992_GPIO_code_to_voltage(GPIO4_code, LTC2992_GPIO_12bit_lsb);
      max_GPIO4 = LTC2992_GPIO_code_to_voltage(max_GPIO4_code, LTC2992_GPIO_12bit_lsb);
      min_GPIO4 = LTC2992_GPIO_code_to_voltage(min_GPIO4_code, LTC2992_GPIO_12bit_lsb);

      Serial.print(F("\n    GPIO1: "));
      Serial.print(GPIO1*scale, 4);
      Serial.print(F(" V"));

      Serial.print(F("        GPIO2: "));
      Serial.print(GPIO2*scale, 4);
      Serial.print(F(" V"));

      Serial.print(F("        GPIO3: "));
      Serial.print(GPIO3, 4);
      Serial.print(F(" V"));

      Serial.print(F("        GPIO4: "));
      Serial.print(GPIO4, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("Max GPIO1: "));
      Serial.print(max_GPIO1, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Max GPIO2: "));
      Serial.print(max_GPIO2, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Max GPIO3: "));
      Serial.print(max_GPIO3, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Max GPIO4: "));
      Serial.print(max_GPIO4, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("Min GPIO1: "));
      Serial.print(min_GPIO1, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Min GPIO2: "));
      Serial.print(min_GPIO2, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Min GPIO3: "));
      Serial.print(min_GPIO3, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Min GPIO4: "));
      Serial.print(min_GPIO4, 4);
      Serial.print(F(" V\n"));

      Serial.println();

      Serial.print(F("In 12 - bit mode\n"));


    }
    else
    {



      uint32_t power1_code, power2_code, max_power1_code, max_power2_code, min_power1_code, min_power2_code;
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_POWER1_MSB2_REG, & power1_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_POWER2_MSB2_REG, & power2_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER1_MSB2_REG, & max_power1_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER2_MSB2_REG, & power2_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER1_MSB2_REG, & min_power1_code);
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER2_MSB2_REG, & min_power2_code);

      float power1, power2, max_power1, max_power2, min_power1, min_power2; // Store power results
      power1 = LTC2992_code_to_power(power1_code>>8, resistor, LTC2992_Power_8bit_lsb);
      power2 = LTC2992_code_to_power(power2_code>>8, resistor, LTC2992_Power_8bit_lsb);
      max_power1 = LTC2992_code_to_power(max_power1_code>>8, resistor, LTC2992_Power_8bit_lsb);
      max_power2 = LTC2992_code_to_power(max_power2_code>>8, resistor, LTC2992_Power_8bit_lsb);
      min_power1 = LTC2992_code_to_power(min_power1_code>>8, resistor, LTC2992_Power_8bit_lsb);
      min_power2 = LTC2992_code_to_power(min_power2_code>>8, resistor, LTC2992_Power_8bit_lsb);

      Serial.print(F("      Power 1: "));
      Serial.print(power1, 4);
      Serial.print(F(" W"));

      Serial.print(F("					Power 2: "));
      Serial.print(power2, 4);
      Serial.print(F(" W\n"));

      Serial.print(F("  Max Power 1: "));
      Serial.print(max_power1, 4);
      Serial.print(F(" W"));

      Serial.print(F("				    Max Power 2: "));
      Serial.print(max_power2, 4);
      Serial.print(F(" W\n"));

      Serial.print(F("  Min Power 1: "));
      Serial.print(min_power1, 4);
      Serial.print(F(" W"));

      Serial.print(F("				    Min Power 2: "));
      Serial.print(min_power2, 4);
      Serial.print(F(" W\n"));

      uint16_t current1_code, current2_code, max_current1_code, max_current2_code, min_current1_code, min_current2_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_DELTA_SENSE1_MSB_REG, & current1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA1_SENSE_MSB_REG, & max_current1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA1_SENSE_MSB_REG, & min_current1_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_DELTA_SENSE2_MSB_REG, & current2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA2_SENSE_MSB_REG, & max_current2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA2_SENSE_MSB_REG, & min_current2_code);

      float current1, current2, max_current1, max_current2, min_current1, min_current2;
      current1 = LTC2992_code_to_current(current1_code>>4, resistor, LTC2992_DELTA_SENSE_8bit_lsb);
      max_current1 = LTC2992_code_to_current(max_current1_code>>4, resistor, LTC2992_DELTA_SENSE_8bit_lsb);
      min_current1 = LTC2992_code_to_current(min_current1_code>>4, resistor, LTC2992_DELTA_SENSE_8bit_lsb);

      current2 = LTC2992_code_to_current(current2_code>>4, resistor, LTC2992_DELTA_SENSE_8bit_lsb);
      max_current2 = LTC2992_code_to_current(max_current2_code>>4, resistor, LTC2992_DELTA_SENSE_8bit_lsb);
      min_current2 = LTC2992_code_to_current(min_current2_code>>4, resistor, LTC2992_DELTA_SENSE_8bit_lsb);

      Serial.print(F("\n    Current 1: "));
      Serial.print(current1, 4);
      Serial.print(F(" A"));

      Serial.print(F("                               Current 2: "));
      Serial.print(current2, 4);
      Serial.print(F(" A\n"));

      Serial.print(F("Max Current 1: "));
      Serial.print(max_current1, 4);
      Serial.print(F(" A"));

      Serial.print(F("				  Max Current 2: "));
      Serial.print(max_current2, 4);
      Serial.print(F(" A\n"));

      Serial.print(F("Min Current 1: "));
      Serial.print(min_current1, 4);
      Serial.print(F(" A"));

      Serial.print(F("			          Min Current 2: "));
      Serial.print(min_current2, 4);
      Serial.print(F(" A\n"));

      uint16_t SENSE1_code, max_SENSE1_code, min_SENSE1_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_SENSE1_MSB_REG, & SENSE1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE1_MSB_REG, & max_SENSE1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE1_MSB_REG, & min_SENSE1_code);

      float SENSE1, max_SENSE1, min_SENSE1;
      SENSE1 = LTC2992_SENSE_code_to_voltage(SENSE1_code>>4, LTC2992_SENSE_8bit_lsb);
      max_SENSE1 = LTC2992_SENSE_code_to_voltage(max_SENSE1_code>>4, LTC2992_SENSE_8bit_lsb);
      min_SENSE1 = LTC2992_SENSE_code_to_voltage(min_SENSE1_code>>4, LTC2992_SENSE_8bit_lsb);

      uint16_t SENSE2_code, max_SENSE2_code, min_SENSE2_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_SENSE2_MSB_REG, & SENSE2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE2_MSB_REG, & max_SENSE2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE2_MSB_REG, & min_SENSE2_code);

      float SENSE2, max_SENSE2, min_SENSE2;
      SENSE2 = LTC2992_SENSE_code_to_voltage(SENSE2_code>>4, LTC2992_SENSE_8bit_lsb);
      max_SENSE2 = LTC2992_SENSE_code_to_voltage(max_SENSE2_code>>4, LTC2992_SENSE_8bit_lsb);
      min_SENSE2 = LTC2992_SENSE_code_to_voltage(min_SENSE2_code>>4, LTC2992_SENSE_8bit_lsb);

      Serial.print(F("\n      SENSE 1: "));
      Serial.print(SENSE1, 4);
      Serial.print(F(" V"));

      Serial.print(F("			                SENSE 2: "));
      Serial.print(SENSE2, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("  Max SENSE 1: "));
      Serial.print(max_SENSE1, 4);
      Serial.print(F(" V"));

      Serial.print(F("		                    Max SENSE 2: "));
      Serial.print(max_SENSE2, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("  Min SENSE 1: "));
      Serial.print(min_SENSE1, 4);
      Serial.print(F(" V"));

      Serial.print(F("			            Min SENSE 2: "));
      Serial.print(min_SENSE2, 4);
      Serial.print(F(" V\n"));

      uint32_t power_sum_code;
      uint16_t current_sum_code;
      ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_PSUM_MSB1_REG, & power_sum_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_ISUM_MSB_REG, & current_sum_code);

      float power_sum, current_sum;
      power_sum = LTC2992_code_to_power_sum(power_sum_code>>8, resistor, LTC2992_Power_8bit_lsb);
      current_sum = LTC2992_code_to_current_sum(current_sum_code>>4, resistor, LTC2992_DELTA_SENSE_8bit_lsb);

      Serial.print(F("\n   Power Sum: "));
      Serial.print(power_sum, 4);
      Serial.print(F(" W\n"));

      Serial.print(F(" Current Sum: "));
      Serial.print(current_sum, 4);
      Serial.print(F(" A\n"));

      uint16_t GPIO1_code, max_GPIO1_code, min_GPIO1_code, GPIO2_code, max_GPIO2_code, min_GPIO2_code,
               GPIO3_code, max_GPIO3_code, min_GPIO3_code, GPIO4_code, max_GPIO4_code, min_GPIO4_code;
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO1_MSB_REG, & GPIO1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO1_MSB_REG, & max_GPIO1_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO1_MSB_REG, & min_GPIO1_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO2_MSB_REG, & GPIO2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO2_MSB_REG, & max_GPIO2_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO2_MSB_REG, & min_GPIO2_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO3_MSB_REG, & GPIO3_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO3_MSB_REG, & max_GPIO3_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO3_MSB_REG, & min_GPIO3_code);

      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_GPIO4_MSB_REG, & GPIO4_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO4_MSB_REG, & max_GPIO4_code);
      ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO4_MSB_REG, & min_GPIO4_code);

      float GPIO1, max_GPIO1, min_GPIO1, GPIO2, max_GPIO2, min_GPIO2, GPIO3, max_GPIO3, min_GPIO3, GPIO4, max_GPIO4, min_GPIO4;
      GPIO1 = LTC2992_GPIO_code_to_voltage(GPIO1_code>>4, LTC2992_GPIO_8bit_lsb);
      max_GPIO1 = LTC2992_GPIO_code_to_voltage(max_GPIO1_code>>4, LTC2992_GPIO_8bit_lsb);
      min_GPIO1 = LTC2992_GPIO_code_to_voltage(min_GPIO1_code>>4, LTC2992_GPIO_8bit_lsb);

      GPIO2 = LTC2992_GPIO_code_to_voltage(GPIO2_code>>4, LTC2992_GPIO_8bit_lsb);
      max_GPIO2 = LTC2992_GPIO_code_to_voltage(max_GPIO2_code>>4, LTC2992_GPIO_8bit_lsb);
      min_GPIO2 = LTC2992_GPIO_code_to_voltage(min_GPIO2_code>>4, LTC2992_GPIO_8bit_lsb);

      GPIO3 = LTC2992_GPIO_code_to_voltage(GPIO3_code>>4, LTC2992_GPIO_8bit_lsb);
      max_GPIO3 = LTC2992_GPIO_code_to_voltage(max_GPIO3_code>>4, LTC2992_GPIO_8bit_lsb);
      min_GPIO3 = LTC2992_GPIO_code_to_voltage(min_GPIO3_code>>4, LTC2992_GPIO_8bit_lsb);

      GPIO4 = LTC2992_GPIO_code_to_voltage(GPIO4_code>>4, LTC2992_GPIO_8bit_lsb);
      max_GPIO4 = LTC2992_GPIO_code_to_voltage(max_GPIO4_code>>4, LTC2992_GPIO_8bit_lsb);
      min_GPIO4 = LTC2992_GPIO_code_to_voltage(min_GPIO4_code>>4, LTC2992_GPIO_8bit_lsb);

      Serial.print(F("\n    GPIO1: "));
      Serial.print(GPIO1*scale, 4);
      Serial.print(F(" V"));

      Serial.print(F("        GPIO2: "));
      Serial.print(GPIO2*scale, 4);
      Serial.print(F(" V"));

      Serial.print(F("        GPIO3: "));
      Serial.print(GPIO3, 4);
      Serial.print(F(" V"));

      Serial.print(F("        GPIO4: "));
      Serial.print(GPIO4, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("Max GPIO1: "));
      Serial.print(max_GPIO1, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Max GPIO2: "));
      Serial.print(max_GPIO2, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Max GPIO3: "));
      Serial.print(max_GPIO3, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Max GPIO4: "));
      Serial.print(max_GPIO4, 4);
      Serial.print(F(" V\n"));

      Serial.print(F("Min GPIO1: "));
      Serial.print(min_GPIO1, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Min GPIO2: "));
      Serial.print(min_GPIO2, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Min GPIO3: "));
      Serial.print(min_GPIO3, 4);
      Serial.print(F(" V"));

      Serial.print(F("    Min GPIO4: "));
      Serial.print(min_GPIO4, 4);
      Serial.print(F(" V\n"));

      Serial.println();


      Serial.print(F("In 8 - bit mode\n"));

    }

    Serial.print(F("\n\n**********************************************************************************************\n\n"));

    Serial.print(F("m-Main Menu\n\n"));
    Serial.flush();
    delay(CONTINUOUS_MODE_DISPLAY_DELAY);
  }
  while (Serial.available() == false);
  read_int(); // clears the Serial.available
  return (ack);
}

//! Configure Threshold Values
int8_t menu_2_threshold_config(float scale, //!< Stores division ratio for resistive divider on GPIO pin.  Configured inside "Settings" menu.
                               int8_t bit_resolution) //!< Sets ADC Resolution
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack = 0;
  int8_t user_command;
  do
  {
    Serial.print(F("*************************\n\n"));
    Serial.print(F("1-Set Power Threshold\n"));
    Serial.print(F("2-Set Current Threshold\n"));
    Serial.print(F("3-Set SENSE Threshold\n"));
    Serial.print(F("4-Set GPIO Threshold\n"));
    Serial.print(F("5-Reset Thresholds To Default\n"));
    Serial.print(F("m-Main Menu\n\n"));
    Serial.print(F("Enter a command: "));

    user_command = read_int();
    if (user_command == 'm')
      Serial.println(F("m"));
    else
      Serial.println(user_command);
    Serial.println();
    switch (user_command)
    {
      case 1:
        ack |= menu_2_threshold_menu_1_set_power(bit_resolution); //! Set Power Min/Max Thresholds
        break;

      case 2:
        ack |= menu_2_threshold_menu_2_set_current(bit_resolution); //! Set Current Min/Max Thresholds
        break;

      case 3:
        ack |= menu_2_threshold_menu_3_set_SENSE(bit_resolution); //! Set Voltage Min/Max Thresholds
        break;

      case 4:
        ack |= menu_2_alert_menu_4_set_adin_alerts(scale, bit_resolution); //! Set GPIO Min/Max Thresholds
        break;
      case 5:
        ack |= menu_2_threshold_menu_5_reset_thresholds(); //! Set All Min/Max Thresholds to Default Value
        break;

      default:
        if (user_command != 'm')
          Serial.println(F("Incorrect Option"));
        break;
    }
  }
  while (!((user_command == 'm') || (ack)));
  return (ack);
}
//! Set Power Min/Max Values
int8_t menu_2_threshold_menu_1_set_power(int8_t bit_resolution) //!< Sets ADC Resolution
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{

  int8_t ack = 0;
  Serial.print(F("Enter Max Channel 1 Power Threshold:"));

  float max_power_threshold;
  max_power_threshold = read_float();
  Serial.println(max_power_threshold, 4);

  uint32_t max_power_threshold_code;
  if (bit_resolution == 1)
  {
    max_power_threshold_code = (max_power_threshold / LTC2992_Power_12bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER1_THRESHOLD_MSB2_REG, max_power_threshold_code);
  }
  else
  {
    max_power_threshold_code = (max_power_threshold / LTC2992_Power_8bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER1_THRESHOLD_MSB2_REG, max_power_threshold_code<<8);
  }
  Serial.print(F("Enter Min Channel 1 Power Threshold:"));

  float min_power_threshold;
  min_power_threshold = read_float();
  Serial.println(min_power_threshold, 4);
  Serial.println();

  uint32_t min_power_threshold_code;
  if (bit_resolution == 1)
  {
    min_power_threshold_code = (min_power_threshold / LTC2992_Power_12bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER1_THRESHOLD_MSB2_REG, min_power_threshold_code);

  }
  else
  {
    min_power_threshold_code = (min_power_threshold / LTC2992_Power_8bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER1_THRESHOLD_MSB2_REG, min_power_threshold_code<<8);
  }
  Serial.print(F("Enter Max Channel 2 Power Threshold:"));
  max_power_threshold = read_float();
  Serial.println(max_power_threshold, 4);

  if (bit_resolution == 1)
  {
    max_power_threshold_code = (max_power_threshold / LTC2992_Power_12bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER2_THRESHOLD_MSB2_REG, max_power_threshold_code);

  }
  else
  {
    max_power_threshold_code = (max_power_threshold / LTC2992_Power_8bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER2_THRESHOLD_MSB2_REG, max_power_threshold_code<<8);
  }
  Serial.print(F("Enter Min Channel 2 Power Threshold:"));

  min_power_threshold = read_float();
  Serial.println(min_power_threshold, 4);
  Serial.println();

  if (bit_resolution == 1)
  {
    min_power_threshold_code = (min_power_threshold / LTC2992_Power_12bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER2_THRESHOLD_MSB2_REG, min_power_threshold_code);

  }
  else
  {
    min_power_threshold_code = (min_power_threshold / LTC2992_Power_8bit_lsb) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER2_THRESHOLD_MSB2_REG, min_power_threshold_code<<8);
  }
  Serial.print(F("Enter Max Power SUM Threshold:"));
  max_power_threshold = read_float();
  Serial.println(max_power_threshold, 4);

  if (bit_resolution == 1)
  {
    max_power_threshold_code = (max_power_threshold / (2 * LTC2992_Power_12bit_lsb)) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_PSUM_THRESHOLD_MSB1_REG, max_power_threshold_code);

  }
  else
  {
    max_power_threshold_code = (max_power_threshold / (2 * LTC2992_Power_8bit_lsb)) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_PSUM_THRESHOLD_MSB1_REG, max_power_threshold_code<<8);
  }

  Serial.print(F("Enter Min Power Sum Threshold:"));

  min_power_threshold = read_float();
  Serial.println(min_power_threshold, 4);
  Serial.println();
  if (bit_resolution == 1)
  {
    min_power_threshold_code = (min_power_threshold / (2 * LTC2992_Power_12bit_lsb)) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_PSUM_THRESHOLD_MSB1_REG, min_power_threshold_code);
  }
  else
  {
    min_power_threshold_code = (min_power_threshold / (2 * LTC2992_Power_8bit_lsb)) * resistor;
    ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_PSUM_THRESHOLD_MSB1_REG, min_power_threshold_code<<8);
  }

  return (ack);
}

//! Set Min/Max Current Threshold
int8_t menu_2_threshold_menu_2_set_current(int8_t bit_resolution) //!< Sets ADC Resolution
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.

{
  int8_t ack = 0;
  Serial.print(F("Enter Max Channel 1 Current Threshold:"));

  float max_current_threshold;
  max_current_threshold = read_float();
  Serial.println(max_current_threshold, 4);

  uint16_t max_current_threshold_code;
  if (bit_resolution == 1)
  {
    max_current_threshold_code = (max_current_threshold / LTC2992_DELTA_SENSE_12bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA1_SENSE_THRESHOLD_MSB_REG, (max_current_threshold_code << 4));

  }
  else
  {
    max_current_threshold_code = (max_current_threshold / LTC2992_DELTA_SENSE_8bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA1_SENSE_THRESHOLD_MSB_REG, (max_current_threshold_code << 8));
  }

  Serial.print(F("Enter Min Channel 1 Current Threshold:"));

  float min_current_threshold;
  min_current_threshold = read_float();
  Serial.println(min_current_threshold, 4);
  Serial.println();

  uint16_t min_current_threshold_code;
  if (bit_resolution == 1)
  {
    min_current_threshold_code = (min_current_threshold / LTC2992_DELTA_SENSE_12bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA1_SENSE_THRESHOLD_MSB_REG, (min_current_threshold_code << 4));
  }
  else
  {
    min_current_threshold_code = (min_current_threshold / LTC2992_DELTA_SENSE_8bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA1_SENSE_THRESHOLD_MSB_REG, (min_current_threshold_code << 8));

  }

  Serial.print(F("Enter Max Channel 2 Current Threshold:"));
  max_current_threshold = read_float();
  Serial.println(max_current_threshold, 4);

  if (bit_resolution == 1)
  {
    max_current_threshold_code = (max_current_threshold / LTC2992_DELTA_SENSE_12bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA2_SENSE_THRESHOLD_MSB_REG, (max_current_threshold_code << 4));
  }
  else
  {
    max_current_threshold_code = (max_current_threshold / LTC2992_DELTA_SENSE_8bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA2_SENSE_THRESHOLD_MSB_REG, (max_current_threshold_code << 8));
  }
  Serial.print(F("Enter Min Channel 2 Current Threshold:"));

  min_current_threshold = read_float();
  Serial.println(min_current_threshold, 4);
  Serial.println();

  if (bit_resolution == 1)
  {
    min_current_threshold_code = (min_current_threshold / LTC2992_DELTA_SENSE_12bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA2_SENSE_THRESHOLD_MSB_REG, (min_current_threshold_code << 4));

  }
  else
  {
    min_current_threshold_code = (min_current_threshold / LTC2992_DELTA_SENSE_8bit_lsb) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA2_SENSE_THRESHOLD_MSB_REG, (min_current_threshold_code << 8));
  }
  Serial.print(F("Enter Max Current Sum Threshold:"));
  max_current_threshold = read_float();
  Serial.println(max_current_threshold, 4);

  if (bit_resolution == 1)
  {
    max_current_threshold_code = (max_current_threshold / (2 * LTC2992_DELTA_SENSE_12bit_lsb)) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_ISUM_THRESHOLD_MSB_REG, (max_current_threshold_code << 4));
  }
  else
  {
    max_current_threshold_code = (max_current_threshold / (2 * LTC2992_DELTA_SENSE_8bit_lsb)) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_ISUM_THRESHOLD_MSB_REG, (max_current_threshold_code << 8));
  }
  Serial.print(F("Enter Min Current Sum Threshold:"));

  min_current_threshold = read_float();
  Serial.println(min_current_threshold, 4);
  Serial.println();
  if (bit_resolution == 1)
  {
    min_current_threshold_code = (min_current_threshold / (2 * LTC2992_DELTA_SENSE_12bit_lsb)) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_ISUM_THRESHOLD_MSB_REG, (min_current_threshold_code << 4));

  }
  else
  {
    min_current_threshold_code = (min_current_threshold / (2 * LTC2992_DELTA_SENSE_8bit_lsb)) * resistor;
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_ISUM_THRESHOLD_MSB_REG, (min_current_threshold_code << 8));
  }

  return (ack);
}

//! Set Min/Max Voltage Thresholds
int8_t menu_2_threshold_menu_3_set_SENSE(int8_t bit_resolution)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack = 0;
  Serial.print(F("Enter Max Channel 1 SENSE Threshold:"));

  float max_sense_threshold;
  max_sense_threshold = read_float();
  Serial.println(max_sense_threshold, 4);

  uint16_t max_sense_threshold_code;
  if (bit_resolution == 1)
  {
    max_sense_threshold_code = (max_sense_threshold / LTC2992_SENSE_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE1_THRESHOLD_MSB_REG, (max_sense_threshold_code << 4));
  }
  else
  {
    max_sense_threshold_code = (max_sense_threshold / LTC2992_SENSE_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE1_THRESHOLD_MSB_REG, (max_sense_threshold_code << 8));
  }
  Serial.print(F("Enter Min Channel 1 SENSE Threshold:"));

  float min_sense_threshold;
  min_sense_threshold = read_float();
  Serial.println(min_sense_threshold, 4);
  Serial.println();

  uint16_t min_sense_threshold_code;
  if (bit_resolution == 1)
  {
    min_sense_threshold_code = (min_sense_threshold / LTC2992_SENSE_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE1_THRESHOLD_MSB_REG, (min_sense_threshold_code << 4));

  }
  else
  {
    min_sense_threshold_code = (min_sense_threshold / LTC2992_SENSE_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE1_THRESHOLD_MSB_REG, (min_sense_threshold_code << 8));
  }
  Serial.print(F("Enter Max Channel 2 SENSE Threshold:"));
  max_sense_threshold = read_float();
  Serial.println(max_sense_threshold, 4);

  if (bit_resolution == 1)
  {
    max_sense_threshold_code = (max_sense_threshold / LTC2992_SENSE_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE2_THRESHOLD_MSB_REG, (max_sense_threshold_code << 4));
  }
  else
  {
    max_sense_threshold_code = (max_sense_threshold / LTC2992_SENSE_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE2_THRESHOLD_MSB_REG, (max_sense_threshold_code << 8));
  }

  Serial.print(F("Enter Min Channel 2 SENSE Threshold:"));

  min_sense_threshold = read_float();
  Serial.println(min_sense_threshold, 4);
  Serial.println();

  if (bit_resolution == 1)
  {
    min_sense_threshold_code = (min_sense_threshold / LTC2992_SENSE_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE2_THRESHOLD_MSB_REG, (min_sense_threshold_code << 4));
  }
  else
  {
    min_sense_threshold_code = (min_sense_threshold / LTC2992_SENSE_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE2_THRESHOLD_MSB_REG, (min_sense_threshold_code << 8));
  }


  return (ack);
}
//Set Min/Max GPIO Thresholds
int8_t menu_2_alert_menu_4_set_adin_alerts(float scale, //!< Stores division ratio for resistive divider on GPIO pin.  Configured inside "Settings" menu.
    int8_t bit_resolution) //!< Sets ADC Resolution
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack = 0;
  Serial.print(F("Enter Max GPIO1 Threshold (Range: 0V - 100V):"));

  float max_gpio_threshold;
  max_gpio_threshold = read_float();
  Serial.println(max_gpio_threshold, 4);

  uint16_t max_gpio_threshold_code;
  if (bit_resolution == 1)
  {
    max_gpio_threshold_code = (1 / scale) * (max_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO1_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 4));
  }
  else
  {
    max_gpio_threshold_code = (1 / scale) * (max_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO1_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 8));
  }
  Serial.print(F("Enter Min GPIO1 Threshold (Range: 0V - 100V):"));

  float min_gpio_threshold;
  min_gpio_threshold = read_float();
  Serial.println(min_gpio_threshold, 4);
  Serial.println();

  uint16_t min_gpio_threshold_code;
  if (bit_resolution == 1)
  {
    min_gpio_threshold_code = (1 / scale) * (min_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO1_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 4));
  }
  else
  {
    min_gpio_threshold_code = (1 / scale) * (min_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO1_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 8));
  }

  Serial.print(F("Enter Max GPIO2 Threshold (Range: 0V - 100V):"));
  max_gpio_threshold = read_float();
  Serial.println(max_gpio_threshold, 4);

  if (bit_resolution == 1)
  {
    max_gpio_threshold_code = (1 / scale) * (max_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO2_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 4));
  }
  else
  {
    max_gpio_threshold_code = (1 / scale) * (max_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO2_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 8));
  }

  Serial.print(F("Enter Min GPIO2 Threshold (Range: 0V - 100V):"));

  min_gpio_threshold = read_float();
  Serial.println(min_gpio_threshold, 4);
  Serial.println();

  if (bit_resolution == 1)
  {
    min_gpio_threshold_code = (1 / scale) * (min_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO2_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 4));
  }
  else
  {
    min_gpio_threshold_code = (1 / scale) * (min_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO2_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 8));
  }

  Serial.print(F("Enter Max GPIO3 Threshold (Range: 0V - 2.048V):"));
  max_gpio_threshold = read_float();
  Serial.println(max_gpio_threshold, 4);

  if (bit_resolution == 1)
  {
    max_gpio_threshold_code = (max_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO3_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 4));
  }
  else
  {
    max_gpio_threshold_code = (max_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO3_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 8));
  }

  Serial.print(F("Enter Min GPIO3 Threshold (Range: 0V - 2.048V):"));

  min_gpio_threshold = read_float();
  Serial.println(min_gpio_threshold, 4);
  Serial.println();

  if (bit_resolution == 1)
  {
    min_gpio_threshold_code = (min_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO3_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 4));
  }
  else
  {
    min_gpio_threshold_code = (min_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO3_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 8));
  }

  Serial.print(F("Enter Max GPIO4 Threshold (Range: 0V - 2.048V):"));
  max_gpio_threshold = read_float();
  Serial.println(max_gpio_threshold, 4);

  if (bit_resolution == 1)
  {
    max_gpio_threshold_code = (max_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO4_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 4));
  }
  else
  {
    max_gpio_threshold_code = (max_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO4_THRESHOLD_MSB_REG, (max_gpio_threshold_code << 8));
  }

  Serial.print(F("Enter Min GPIO4 Threshold (Range: 0V - 2.048V):"));

  min_gpio_threshold = read_float();
  Serial.println(min_gpio_threshold, 4);
  Serial.println();

  if (bit_resolution == 1)
  {
    min_gpio_threshold_code = (min_gpio_threshold / LTC2992_GPIO_12bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO4_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 4));
  }
  else
  {
    min_gpio_threshold_code = (min_gpio_threshold / LTC2992_GPIO_8bit_lsb);
    ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO4_THRESHOLD_MSB_REG, (min_gpio_threshold_code << 8));
  }


  return (ack);
}
//! Set All Thresholds to Default Values
int8_t menu_2_threshold_menu_5_reset_thresholds()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{

  int8_t ack = 0;

  uint32_t max_32bit_threshold = 0xFFFFFF;
  uint16_t max_16bit_threshold = 0xFFF0;
  uint32_t min_32bit_threshold = 0x000000;
  uint16_t min_16bit_threshold = 0x00000;

  uint32_t max_power_threshold_code = 0;
  uint32_t min_power_threshold_code = 0;

  //Reset Power Thresholds

  ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER1_THRESHOLD_MSB2_REG, max_32bit_threshold);
  ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER1_THRESHOLD_MSB2_REG, min_32bit_threshold);

  ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_POWER2_THRESHOLD_MSB2_REG, max_32bit_threshold);
  ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_POWER2_THRESHOLD_MSB2_REG, min_32bit_threshold);

  ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_PSUM_THRESHOLD_MSB1_REG, max_32bit_threshold);
  ack |= LTC2992_write_24_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_PSUM_THRESHOLD_MSB1_REG, min_32bit_threshold);

  //Reset Current Thresholds

  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA1_SENSE_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA1_SENSE_THRESHOLD_MSB_REG, min_16bit_threshold);

  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_DELTA2_SENSE_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_DELTA2_SENSE_THRESHOLD_MSB_REG, min_16bit_threshold);

  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_ISUM_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_ISUM_THRESHOLD_MSB_REG, min_16bit_threshold);

  //Reset Voltage Thresholds
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE1_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE1_THRESHOLD_MSB_REG, min_16bit_threshold);

  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_SENSE2_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_SENSE2_THRESHOLD_MSB_REG, min_16bit_threshold);

  //Reset GPIO Thresholds
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO1_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO2_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO3_THRESHOLD_MSB_REG, max_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MAX_GPIO4_THRESHOLD_MSB_REG, max_16bit_threshold);

  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO1_THRESHOLD_MSB_REG, min_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO2_THRESHOLD_MSB_REG, min_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO3_THRESHOLD_MSB_REG, min_16bit_threshold);
  ack |= LTC2992_write_16_bits(LTC2992_I2C_ADDRESS, LTC2992_MIN_GPIO4_THRESHOLD_MSB_REG, min_16bit_threshold);

  if (ack == 0)
  {
    Serial.println(F("\nThresholds Reset to Defaults\n"));
  }

  return (ack);
}

//Toggle and Configure GPIO Pins
int8_t menu_3_GPIO_config()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack = 0;
  int8_t user_command;
  uint8_t gpio_io_code;
  uint8_t gpio4_control_code;

  do
  {
    Serial.print(F("*************************\n\n"));
    Serial.print(F("1-Configure GPIO1\n"));
    Serial.print(F("2-Configure GPIO2\n"));
    Serial.print(F("3-Configure GPIO3\n"));
    Serial.print(F("4-Configure GPIO4\n"));
    Serial.print(F("m-Main Menu\n\n"));
    Serial.print(F("Enter a command: "));

    ack |= LTC2992_read(LTC2992_I2C_ADDRESS, LTC2992_GPIO_IO_CONT_REG, & gpio_io_code);
    ack |= LTC2992_read(LTC2992_I2C_ADDRESS, LTC2992_GPIO4_CFG_REG, & gpio4_control_code);

    user_command = read_int();
    if (user_command == 'm')
      Serial.println(F("m"));
    else
      Serial.println(user_command);
    Serial.println();
    switch (user_command)
    {
      case 1:
        Serial.print(F("1-GPIO1 Pulls Low, 2-GPIO1 High-Z\n"));
        user_command = read_int();
        if ((user_command > 2) || (user_command < 0))
          user_command = 2;
        Serial.println(user_command);
        if (user_command == 1)
          gpio_io_code = gpio_io_code | LTC2992_GPIO1_OUT_LOW;
        else
          gpio_io_code = gpio_io_code & LTC2992_GPIO1_OUT_HIGH_Z;

        break;

      case 2:
        Serial.print(F("1-GPIO2 Pulls Low, 2-GPIO2 High-Z\n"));
        user_command = read_int();
        if ((user_command > 2) || (user_command < 0))
          user_command = 2;
        Serial.println(user_command);
        if (user_command == 1)
          gpio_io_code = gpio_io_code | LTC2992_GPIO2_OUT_LOW;
        else
          gpio_io_code = gpio_io_code & LTC2992_GPIO2_OUT_HIGH_Z;
        break;

      case 3:
        Serial.print(F("*************************\n\n"));
        Serial.print(F("1-Configure GPIO3 as Data Ready (Latching)\n"));
        Serial.print(F("2-Configure GPIO3 as Data Ready (128us Pulse)\n"));
        Serial.print(F("3-Configure GPIO3 as Data Ready (16us Pulse)\n"));
        Serial.print(F("4-Configure GPIO3 as I/O Pin\n"));
        Serial.print(F("m-Main Menu\n\n"));
        Serial.print(F("Enter a command: "));
        user_command = read_int();
        Serial.println(user_command);
        switch (user_command)
        {
          case 1:
            gpio_io_code = gpio_io_code | LTC2992_GPIO3_CONFIG_LOW_DATARDY;
            break;
          case 2:
            gpio_io_code = gpio_io_code & LTC2992_GPIOCFG_GPIO3_MASK;
            gpio_io_code = gpio_io_code | LTC2992_GPIO3_CONFIG_128_LOW;
            break;
          case 3:
            gpio_io_code = gpio_io_code & LTC2992_GPIOCFG_GPIO3_MASK;
            gpio_io_code = gpio_io_code | LTC2992_GPIO3_CONFIG_16_LOW;
            break;
          case 4:
            gpio_io_code = gpio_io_code & LTC2992_GPIOCFG_GPIO3_MASK;
            gpio_io_code = gpio_io_code | LTC2992_GPIO3_CONFIG_IO;
            Serial.print(F("1-GPIO3 Pulls Low, 2-GPIO3 High-Z\n"));
            user_command = read_int();
            if ((user_command > 2) || (user_command < 0))
              user_command = 2;
            Serial.println(user_command);
            if (user_command == 1)
              gpio_io_code = gpio_io_code | LTC2992_GPIO3_OUT_LOW;
            else
              gpio_io_code = gpio_io_code & LTC2992_GPIO3_OUT_HIGH_Z;
            break;
          default:
            break;
        }
        break;
      case 4:
        Serial.print(F("1-GPIO4 Pulls Low, 2-GPIO1 High-Z\n"));
        user_command = read_int();
        if ((user_command > 2) || (user_command < 0))
          user_command = 2;
        Serial.println(user_command);
        if (user_command == 1)
          gpio4_control_code = gpio4_control_code | LTC2992_GPIO4_OUT_LOW;
        else
          gpio4_control_code = gpio4_control_code & LTC2992_GPIO4_OUT_HI_Z;
        break;
      default:
        if (user_command != 'm')
          Serial.println(F("Incorrect Option"));
        break;
    }
    ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_GPIO_IO_CONT_REG, gpio_io_code);
    ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_GPIO4_CFG_REG, gpio4_control_code);
  }
  while (!((user_command == 'm') || (ack)));

  return (ack);
}
//! Read/Clear Faults
int8_t menu_5_read_clear_faults()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{

  int8_t ack = 0;
  int8_t user_command;
  uint8_t fault_code;
  uint8_t no_fault_code = 0x00;

  do
  {
    Serial.print(F("*************************\n\n"));
    Serial.print(F("1-Real All Faults\n"));
    Serial.print(F("2-Clear All Faults\n"));
    Serial.print(F("m-Main Menu\n\n"));
    Serial.print(F("Enter a command: "));

    user_command = read_int();
    if (user_command == 'm')
      Serial.println(F("m"));
    else
      Serial.println(user_command);
    Serial.println();
    switch (user_command)
    {
      case 1:
        ack |= LTC2992_read(LTC2992_I2C_ADDRESS, LTC2992_FAULT1_REG, & fault_code);

        if ((fault_code & (1 << 7)) != 0)
          Serial.println(F("Max Channel 1 Power Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 6)) != 0)
          Serial.println(F("Min Channel 1 Power Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 5)) != 0)
          Serial.println(F("Max Channel 1 Current Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 4)) != 0)
          Serial.println(F("Min Channel 1 Current Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 3)) != 0)
          Serial.println(F("Max Channel 1 Voltage Fault Occured!"));
        else
          no_fault_code++;;
        if ((fault_code & (1 << 2)) != 0)
          Serial.println(F("Min Channel 1 Voltage Fault Occured!"));
        else
          no_fault_code++;;
        if ((fault_code & (1 << 1)) != 0)
          Serial.println(F("Max GPIO1 Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 0)) != 0)
          Serial.println(F("Min GPIO1 Fault Occured!"));
        else
          no_fault_code++;

        ack |= LTC2992_read(LTC2992_I2C_ADDRESS, LTC2992_FAULT2_REG, & fault_code);

        if ((fault_code & (1 << 7)) != 0)
          Serial.println(F("Max Channel 2 Power Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 6)) != 0)
          Serial.println(F("Min Channel 2 Power Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 5)) != 0)
          Serial.println(F("Max Channel 2 Current Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 4)) != 0)
          Serial.println(F("Min Channel 2 Current Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 3)) != 0)
          Serial.println(F("Max Channel 2 Voltage Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 2)) != 0)
          Serial.println(F("Min Channel 2 Voltage Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 1)) != 0)
          Serial.println(F("Max GPIO2 Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 0)) != 0)
          Serial.println(F("Min GPIO2 Fault Occured!"));
        else
          no_fault_code++;

        ack |= LTC2992_read(LTC2992_I2C_ADDRESS, LTC2992_FAULT3_REG, & fault_code);

        if ((fault_code & (1 << 7)) != 0)
          Serial.println(F("Max GPIO3 Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 6)) != 0)
          Serial.println(F("Min GPIO3 Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 5)) != 0)
          Serial.println(F("Max GPIO4 Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 4)) != 0)
          Serial.println(F("Min GPIO4 Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 3)) != 0)
          Serial.println(F("Max Current SUM Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 2)) != 0)
          Serial.println(F("Min Current SUM Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 1)) != 0)
          Serial.println(F("Max Power SUM Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 0)) != 0)
          Serial.println(F("Min Power SUM Fault Occured!"));
        else
          no_fault_code++;

        ack |= LTC2992_read(LTC2992_I2C_ADDRESS, LTC2992_FAULT4_REG, & fault_code);

        if ((fault_code & (1 << 4)) != 0)
          Serial.println(F("Stuck Bus Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 3)) != 0)
          Serial.println(F("GPIO1 Input Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 2)) != 0)
          Serial.println(F("GPIO2 Input Fault Occured!"));
        else
          no_fault_code++;
        if ((fault_code & (1 << 1)) != 0)
          Serial.println(F("GPIO3 Input Fault Occured!"));
        else
          no_fault_code++;

        if (no_fault_code == 28)
        {
          Serial.println(F("No Faults Occured\n"));
          Serial.println();
        }

        break;

      case 2:
        fault_code = 0;
        ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_FAULT1_REG, fault_code);
        ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_FAULT2_REG, fault_code);
        ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_FAULT3_REG, fault_code);
        ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_FAULT4_REG, fault_code);

        if (ack == 0)
        {
          Serial.println(F("\nAll Faults Cleared\n"));
        }
        break;

      default:
        if (user_command != 'm')
          Serial.println(F("Incorrect Option"));
        break;
    }
  }
  while (!((user_command == 'm') || (ack)));

  return (ack);

}
//! Settings to configure shutdown mode and ADC Resolution
int8_t menu_4_settings(int8_t *CTRLA_mode,  //! CTRLA Register. Used to set device in Shutdown
                       int8_t *bit_resolution)  //! Sets ADC Bit Resolution.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
  int8_t ack = 0;
  int8_t user_command;

  do
  {
    Serial.print(F("*************************\n\n"));
    Serial.print(F("1-Configure ADC Resolution\n"));
    Serial.print(F("2-Enable/Disable Shutdown Mode\n"));
    Serial.print(F("m-Main Menu\n\n"));
    Serial.print(F("Enter a command: "));

    user_command = read_int();
    if (user_command == 'm')
      Serial.println(F("m"));
    else
      Serial.println(user_command);
    Serial.println();
    switch (user_command)
    {
      case 1:
        Serial.print(F("1-12-bit resolution, 2-8-bit resolution\n"));
        user_command = read_int();
        if ((user_command > 2) || (user_command < 0))
          user_command = 2;
        Serial.println(user_command);
        if (user_command == 1)
        {
          * bit_resolution = 1;
          ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_NADC_REG, 0x00);
        }
        else
        {
          *bit_resolution = 0;
          ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_NADC_REG, LTC2992_ADC_RESOLUTION);
        }
        uint8_t nadc_code;
        LTC2992_read(LTC2992_I2C_ADDRESS,LTC2992_NADC_REG, &nadc_code);
        Serial.println(nadc_code);
        break;

      case 2:
        Serial.print(F("1-Enable Shutdown, 2-Disable Shutdown\n"));
        user_command = read_int();
        if ((user_command > 2) || (user_command < 0))
          user_command = 2;
        Serial.println(user_command);
        if (user_command == 1)
        {
          * CTRLA_mode = * CTRLA_mode | LTC2992_MODE_SHUTDOWN;
          Serial.print(F("Shutdown Mode is enabled. Selecting Continious Mode in main menu will disable Shutdown mode\n"));
        }
        else
        {
          * CTRLA_mode = ( * CTRLA_mode & LTC2992_CTRLA_MEASUREMENT_MODE_MASK) | LTC2992_MODE_CONTINUOUS;
          Serial.print(F("Shutdown Mode is disabled. \n"));
        }
        ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_CTRLA_REG, *CTRLA_mode);
        break;
      default:
        if (user_command != 'm')
          Serial.println(F("Incorrect Option"));
        break;
    }
  }
  while (!((user_command == 'm') || (ack)));
  return (ack);

}

Download LTC2992 - Linduino Header File

/*!
 LTC2992: Dual Wide Range Power Monitor

@verbatim

The LTC®2992 is a rail-to-rail system monitor that measures
current, voltage, power, charge and energy. It features an
operating range of 2.7V to 100V and includes a shunt regulator
for supplies above 100V. The current measurement common mode
range of 0V to 100V is independent of the input supply.
A 12-bit ADC measures load current, input voltage and an
auxiliary external voltage. Load current and internally
calculated power are integrated over an external clock or
crystal or internal oscillator time base for charge and energy.
An accurate time base allows the LTC2992 to provide measurement
accuracy of better than ±0.6% for charge and ±1% for power and
energy. Minimum and maximum values are stored and an overrange
alert with programmable thresholds minimizes the need for software
polling. Data is reported via a standard I2C interface.
Shutdown mode reduces power consumption to 15uA.


I2C DATA FORMAT (MSB FIRST):

Data Out:
Byte #1                                    Byte #2                     Byte #3

START  SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK  X  X C5 C4 C3 C2 C1 C0 SACK D7 D6 D5 D4 D3 D2 D1 D0 SACK  STOP

Data In:
Byte #1                                    Byte #2                                    Byte #3

START  SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK  X  X  C5 C4 C3 C2 C1 C0 SACK  Repeat Start SA6 SA5 SA4 SA3 SA2 SA1 SA0 R SACK

Byte #4                                   Byte #5
MSB                                       LSB
D15 D14  D13  D12  D11  D10  D9 D8 MACK   D7 D6 D5 D4 D3  D2  D1  D0  MNACK  STOP

START       : I2C Start
Repeat Start: I2c Repeat Start
STOP        : I2C Stop
SAx         : I2C Address
SACK        : I2C Slave Generated Acknowledge (Active Low)
MACK        : I2C Master Generated Acknowledge (Active Low)
MNACK       : I2c Master Generated Not Acknowledge
W           : I2C Write (0)
R           : I2C Read  (1)
Cx          : Command Code
Dx          : Data Bits
X           : Don't care



Example Code:

Read power, current and voltage

    CTRLA = LTC2992_CHANNEL_CONFIG_V_C_3|LTC2992_SENSE_PLUS|LTC2992_OFFSET_CAL_EVERY|LTC2992_ADIN_GND;  //! Set Control A register to default value in continuous mode
    ack |= LTC2992_write(LTC2992_I2C_ADDRESS, LTC2992_CTRLA_REG, CTRLA);   //! Sets the LTC2992 to continuous mode

    resistor = .02; // Resistor Value On Demo Board

    ack |= LTC2992_read_24_bits(LTC2992_I2C_ADDRESS, LTC2992_POWER_MSB2_REG, &power_code);  // Reads the ADC registers that contains V^2
    power = LTC2992_code_to_power(power_code, resistor, LTC2992_Power_lsb); // Calculates power from power code, resistor value and power lsb

    ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_DELTA_SENSE_MSB_REG, &current_code); // Reads the voltage code across sense resistor
    current = LTC2992_code_to_current(current_code, resistor, LTC2992_DELTA_SENSE_lsb); // Calculates current from current code, resistor value and current lsb

    ack |= LTC2992_read_12_bits(LTC2992_I2C_ADDRESS, LTC2992_SENSE_MSB_REG, &SENSE_code);   // Reads SENSE voltage code
    SENSE = LTC2992_SENSE_code_to_voltage(SENSE_code, LTC2992_SENSE_lsb);  // Calculates SENSE voltage from SENSE code and lsb

    ack |= LTC2992_read_32_bits(LTC2992_I2C_ADDRESS, LTC2992_ENERGY_MSB3_REG, &energy_code);  // Reads energy code
  energy = LTC2992_code_to_energy(energy_code,resistor,LTC2992_Power_lsb, LTC2992_INTERNAL_TIME_lsb); //Calculates Energy in Joules from energy_code, resistor, power lsb and time lsb

  ack |= LTC2992_read_32_bits(LTC2992_I2C_ADDRESS, LTC2992_CHARGE_MSB3_REG, &charge_code);  // Reads charge code
    charge = LTC2992_code_to_coulombs(charge_code,resistor,LTC2992_DELTA_SENSE_lsb, LTC2992_INTERNAL_TIME_lsb); //Calculates charge in coulombs from charge_code, resistor, current lsb and time lsb



@endverbatim

http://www.linear.com/product/LTC2992

http://www.linear.com/product/LTC2992#demoboards

REVISION HISTORY
$Revision: 3659 $
$Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $

Copyright (c) 2013, Linear Technology Corp.(LTC)
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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/

/*! @file
    @ingroup LTC2992
    Header for LTC2992: Dual Wide Range Power Monitor
*/

#ifndef LTC2992_H
#define LTC2992_H

#include <Wire.h>


//! Use table to select address
/*!
| LTC2992 I2C Address Assignment    | Value |   AD1    |   AD2    |
| :-------------------------------- | :---: | :------: | :------: |
| LTC2992_I2C_ADDRESS               | 0x67  |   High   |   Low    |
| LTC2992_I2C_ADDRESS               | 0x68  |   Float  |   High   |
| LTC2992_I2C_ADDRESS               | 0x69  |   High   |   High   |
| LTC2992_I2C_ADDRESS               | 0x6A  |   Float  |   Float  |
| LTC2992_I2C_ADDRESS               | 0x6B  |   Float  |   Low    |
| LTC2992_I2C_ADDRESS               | 0x6C  |   Low    |   High   |
| LTC2992_I2C_ADDRESS               | 0x6D  |   High   |   Float  |
| LTC2992_I2C_ADDRESS               | 0x6E  |   Low    |   Float  |
| LTC2992_I2C_ADDRESS               | 0x6F  |   Low    |   Low    |
|                                   |       |          |          |
| LTC2992_I2C_MASS_WRITE            | 0x66  | X        | X        |
| LTC2992_I2C_ALERT_RESPONSE        | 0x0C  | X        | X        |
*/
/*! @name LTC2992 I2C Address Assignments
@{ */
// Address Choices:
// To choose an address, comment out all options except the
// configuration on the demo board.

//  Address assignment
// LTC2992 I2C Address                 //  AD1       AD0
// #define LTC2992_I2C_ADDRESS 0x67    //  High      Low
// #define LTC2992_I2C_ADDRESS 0x68    //  Float     High
// #define LTC2992_I2C_ADDRESS 0x69    //  High      High
#define LTC2992_I2C_ADDRESS 0x6A    //  Float     Float
// #define LTC2992_I2C_ADDRESS 0x6B    //  Float     Low
// #define LTC2992_I2C_ADDRESS 0x6C    //  Low       High
// #define LTC2992_I2C_ADDRESS 0x6D    //  High      Float
// #define LTC2992_I2C_ADDRESS 0x6E    //  Low       Float
//#define LTC2992_I2C_ADDRESS 0x6F       //  Low       Low

#define LTC2992_I2C_MASS_WRITE      0x66
#define LTC2992_I2C_ALERT_RESPONSE  0x0C
//! @}


/*!
| Name                                              | Value |
| :------------------------------------------------ | :---: |
| LTC2992_CTRLA_REG                                 | 0x00  |
| LTC2992_CTRLB_REG                                 | 0x01  |
| LTC2992_ALERT1_REG                                | 0x02  |
| LTC2992_FAULT1_REG                                | 0x03  |
| LTC2992_NADC_REG                                  | 0x04  |
| LTC2992_POWER1_MSB2_REG                           | 0x05  |
| LTC2992_POWER1_MSB1_REG                           | 0x06  |
| LTC2992_POWER1_LSB_REG                            | 0x07  |
| LTC2992_MAX_POWER1_MSB2_REG                       | 0x08  |
| LTC2992_MAX_POWER1_MSB1_REG                       | 0x09  |
| LTC2992_MAX_POWER1_LSB_REG                        | 0x0A  |
| LTC2992_MIN_POWER1_MSB2_REG                       | 0x0B  |
| LTC2992_MIN_POWER1_MSB1_REG                       | 0x0C  |
| LTC2992_MIN_POWER1_LSB_REG                        | 0x0D  |
| LTC2992_MAX_POWER1_THRESHOLD_MSB2_REG             | 0x0E  |
| LTC2992_MAX_POWER1_THRESHOLD_MSB1_REG             | 0x0F  |
| LTC2992_MAX_POWER1_THRESHOLD_LSB_REG              | 0x10  |
| LTC2992_MIN_POWER1_THRESHOLD_MSB2_REG             | 0x11  |
| LTC2992_MIN_POWER1_THRESHOLD_MSB1_REG             | 0x12  |
| LTC2992_MIN_POWER1_THRESHOLD_LSB_REG              | 0x13  |
| LTC2992_DELTA_SENSE1_MSB_REG                      | 0x14  |
| LTC2992_DELTA_SENSE1_LSB_REG                      | 0x15  |
| LTC2992_MAX_DELTA1_SENSE_MSB_REG                  | 0x16  |
| LTC2992_MAX_DELTA1_SENSE_LSB_REG                  | 0x17  |
| LTC2992_MIN_DELTA1_SENSE_MSB_REG                  | 0x18  |
| LTC2992_MIN_DELTA1_SENSE_LSB_REG                  | 0x19  |
| LTC2992_MAX_DELTA1_SENSE_THRESHOLD_MSB_REG        | 0x1A  |
| LTC2992_MAX_DELTA1_SENSE_THRESHOLD_LSB_REG        | 0x1B  |
| LTC2992_MIN_DELTA1_SENSE_THRESHOLD_MSB_REG        | 0x1C  |
| LTC2992_MIN_DELTA1_SENSE_THRESHOLD_LSB_REG        | 0x1D  |
| LTC2992_SENSE1_MSB_REG                            | 0x1E  |
| LTC2992_SENSE1_LSB_REG                            | 0x1F  |
| LTC2992_MAX_SENSE1_MSB_REG                        | 0x20  |
| LTC2992_MAX_SENSE1_LSB_REG                        | 0x21  |
| LTC2992_MIN_SENSE1_MSB_REG                        | 0x22  |
| LTC2992_MIN_SENSE1_LSB_REG                        | 0x23  |
| LTC2992_MAX_SENSE1_THRESHOLD_MSB_REG              | 0x24  |
| LTC2992_MAX_SENSE1_THRESHOLD_LSB_REG              | 0x25  |
| LTC2992_MIN_SENSE1_THRESHOLD_MSB_REG              | 0x26  |
| LTC2992_MIN_SENSE1_THRESHOLD_LSB_REG              | 0x27  |
| LTC2992_GPIO1_MSB_REG                             | 0x28  |
| LTC2992_GPIO1_LSB_REG_REG                         | 0x29  |
| LTC2992_MAX_GPIO1_MSB_REG                         | 0x2A  |
| LTC2992_MAX_GPIO1_LSB_REG                         | 0x2B  |
| LTC2992_MIN_GPIO1_MSB_REG                         | 0x2C  |
| LTC2992_MIN_GPIO1_LSB_REG                         | 0x2D  |
| LTC2992_MAX_GPIO1_THRESHOLD_MSB_REG               | 0x2E  |
| LTC2992_MAX_GPIO1_THRESHOLD_LSB_REG               | 0x2F  |
| LTC2992_MIN_GPIO1_THRESHOLD_MSB_REG               | 0x30  |
| LTC2992_MIN_GPIO1_THRESHOLD_LSB_REG               | 0x31  |
| LTC2992_ADC_STATUS_REG                            | 0x32  |
| LTC2992_ALERT2_REG                                | 0x34  |
| LTC2992_FAULT2_REG                                | 0x35  |
| LTC2992_POWER2_MSB2_REG                           | 0x37  |
| LTC2992_POWER2_MSB1_REG                           | 0x38  |
| LTC2992_POWER2_LSB_REG                            | 0x39  |
| LTC2992_MAX_POWER2_MSB2_REG                       | 0x3A  |
| LTC2992_MAX_POWER2_MSB1_REG                       | 0x3B  |
| LTC2992_MAX_POWER2_LSB_REG                        | 0x3C  |
| LTC2992_MIN_POWER2_MSB2_REG                       | 0x3D  |
| LTC2992_MIN_POWER2_MSB1_REG                       | 0x3E  |
| LTC2992_MIN_POWER2_LSB_REG                        | 0x3F  |
| LTC2992_MAX_POWER2_THRESHOLD_MSB2_REG             | 0x40  |
| LTC2992_MAX_POWER2_THRESHOLD_MSB1_REG             | 0x41  |
| LTC2992_MAX_POWER2_THRESHOLD_LSB_REG              | 0x42  |
| LTC2992_MIN_POWER2_THRESHOLD_MSB2_REG             | 0x43  |
| LTC2992_MIN_POWER2_THRESHOLD_MSB1_REG             | 0x44  |
| LTC2992_MIN_POWER2_THRESHOLD_LSB_REG              | 0x45  |
| LTC2992_DELTA_SENSE2_MSB_REG                      | 0x46  |
| LTC2992_DELTA_SENSE2_LSB_REG                      | 0x47  |
| LTC2992_MAX_DELTA2_SENSE_MSB_REG                  | 0x48  |
| LTC2992_MAX_DELTA2_SENSE_LSB_REG                  | 0x49  |
| LTC2992_MIN_DELTA2_SENSE_MSB_REG                  | 0x4A  |
| LTC2992_MIN_DELTA2_SENSE_LSB_REG                  | 0x4B  |
| LTC2992_MAX_DELTA2_SENSE_THRESHOLD_MSB_REG        | 0x4C  |
| LTC2992_MAX_DELTA2_SENSE_THRESHOLD_LSB_REG        | 0x4D  |
| LTC2992_MIN_DELTA2_SENSE_THRESHOLD_MSB_REG        | 0x4E  |
| LTC2992_MIN_DELTA2_SENSE_THRESHOLD_LSB_REG        | 0x4F  |
| LTC2992_SENSE2_MSB_REG                            | 0x50  |
| LTC2992_SENSE2_LSB_REG                            | 0x51  |
| LTC2992_MAX_SENSE2_MSB_REG                        | 0x52  |
| LTC2992_MAX_SENSE2_LSB_REG                        | 0x53  |
| LTC2992_MIN_SENSE2_MSB_REG                        | 0x54  |
| LTC2992_MIN_SENSE2_LSB_REG                        | 0x55  |
| LTC2992_MAX_SENSE2_THRESHOLD_MSB_REG              | 0x56  |
| LTC2992_MAX_SENSE2_THRESHOLD_LSB_REG              | 0x57  |
| LTC2992_MIN_SENSE2_THRESHOLD_MSB_REG              | 0x58  |
| LTC2992_MIN_SENSE2_THRESHOLD_LSB_REG              | 0x59  |
| LTC2992_GPIO2_MSB_REG                             | 0x5A  |
| LTC2992_GPIO2_LSB_REG_REG                         | 0x5B  |
| LTC2992_MAX_GPIO2_MSB_REG                         | 0x5C  |
| LTC2992_MAX_GPIO2_LSB_REG                         | 0x5D  |
| LTC2992_MIN_GPIO2_MSB_REG                         | 0x5E  |
| LTC2992_MIN_GPIO2_LSB_REG                         | 0x5F  |
| LTC2992_MAX_GPIO2_THRESHOLD_MSB_REG               | 0x60  |
| LTC2992_MAX_GPIO2_THRESHOLD_LSB_REG               | 0x61  |
| LTC2992_MIN_GPIO2_THRESHOLD_MSB_REG               | 0x62  |
| LTC2992_MIN_GPIO2_THRESHOLD_LSB_REG               | 0x63  |
| LTC2992_GPIO3_MSB_REG                             | 0x64  |
| LTC2992_GPIO3_LSB_REG_REG                         | 0x65  |
| LTC2992_MAX_GPIO3_MSB_REG                         | 0x66  |
| LTC2992_MAX_GPIO3_LSB_REG                         | 0x67  |
| LTC2992_MIN_GPIO3_MSB_REG                         | 0x68  |
| LTC2992_MIN_GPIO3_LSB_REG                         | 0x69  |
| LTC2992_MAX_GPIO3_THRESHOLD_MSB_REG               | 0x6A  |
| LTC2992_MAX_GPIO3_THRESHOLD_LSB_REG               | 0x6B  |
| LTC2992_MIN_GPIO3_THRESHOLD_MSB_REG               | 0x6C  |
| LTC2992_MIN_GPIO3_THRESHOLD_LSB_REG               | 0x6D  |
| LTC2992_GPIO4_MSB_REG                             | 0x6E  |
| LTC2992_GPIO4_LSB_REG_REG                         | 0x6F  |
| LTC2992_MAX_GPIO4_MSB_REG                         | 0x70  |
| LTC2992_MAX_GPIO4_LSB_REG                         | 0x71  |
| LTC2992_MIN_GPIO4_MSB_REG                         | 0x72  |
| LTC2992_MIN_GPIO4_LSB_REG                         | 0x73  |
| LTC2992_MAX_GPIO4_THRESHOLD_MSB_REG               | 0x74  |
| LTC2992_MAX_GPIO4_THRESHOLD_LSB_REG               | 0x75  |
| LTC2992_MIN_GPIO4_THRESHOLD_MSB_REG               | 0x76  |
| LTC2992_MIN_GPIO4_THRESHOLD_LSB_REG               | 0x77  |
| LTC2992_ISUM_MSB_REG                              | 0x78  |
| LTC2992_ISUM_LSB_REG_REG                          | 0x79  |
| LTC2992_MAX_ISUM_MSB_REG                          | 0x7A  |
| LTC2992_MAX_ISUM_LSB_REG                          | 0x7B  |
| LTC2992_MIN_ISUM_MSB_REG                          | 0x7C  |
| LTC2992_MIN_ISUM_LSB_REG                          | 0x7D  |
| LTC2992_MAX_ISUM_THRESHOLD_MSB_REG                | 0x7E  |
| LTC2992_MAX_ISUM_THRESHOLD_LSB_REG                | 0x7F  |
| LTC2992_MIN_ISUM_THRESHOLD_MSB_REG                | 0x80  |
| LTC2992_MIN_ISUM_THRESHOLD_LSB_REG                | 0x81  |
| LTC2992_PSUM_MSB1_REG                             | 0x82  |
| LTC2992_PSUM_MSB_REG                              | 0x83  |
| LTC2992_PSUM_LSB_REG_REG                          | 0x84  |
| LTC2992_MAX_PSUM_MSB1_REG                         | 0x85  |
| LTC2992_MAX_PSUM_MSB_REG                          | 0x86  |
| LTC2992_MAX_PSUM_LSB_REG                          | 0x87  |
| LTC2992_MIN_PSUM_MSB1_REG                         | 0x88  |
| LTC2992_MIN_PSUM_MSB_REG                          | 0x89  |
| LTC2992_MIN_PSUM_LSB_REG                          | 0x8A  |
| LTC2992_MAX_PSUM_THRESHOLD_MSB1_REG               | 0x8B  |
| LTC2992_MAX_PSUM_THRESHOLD_MSB_REG                | 0x8C  |
| LTC2992_MAX_PSUM_THRESHOLD_LSB_REG                | 0x8D  |
| LTC2992_MIN_PSUM_THRESHOLD_MSB1_REG               | 0x8E  |
| LTC2992_MIN_PSUM_THRESHOLD_MSB_REG                | 0x8F  |
| LTC2992_MIN_PSUM_THRESHOLD_LSB_REG                | 0x90  |
| LTC2992_ALERT3_REG                                | 0x91  |
| LTC2992_FAULT3_REG                                | 0x92  |
| LTC2992_ALERT4_REG                                | 0x93  |
| LTC2992_FAULT4_REG                                | 0x94  |
| LTC2992_GPIO_STATUS_REG                           | 0x95  |
| LTC2992_GPIO_IO_CONT_REG                          | 0x96  |
| LTC2992_GPIO4_CFG_REG                             | 0x97  |
  */




/*! @name Registers
@{ */
// Registers

#define LTC2992_CTRLA_REG                                  0x00
#define LTC2992_CTRLB_REG                                  0x01
#define LTC2992_ALERT1_REG                                 0x02
#define LTC2992_FAULT1_REG                                 0x03
#define LTC2992_NADC_REG                                   0x04
#define LTC2992_POWER1_MSB2_REG                            0x05
#define LTC2992_POWER1_MSB1_REG                            0x06
#define LTC2992_POWER1_LSB_REG                             0x07
#define LTC2992_MAX_POWER1_MSB2_REG                        0x08
#define LTC2992_MAX_POWER1_MSB1_REG                        0x09
#define LTC2992_MAX_POWER1_LSB_REG                         0x0A
#define LTC2992_MIN_POWER1_MSB2_REG                        0x0B
#define LTC2992_MIN_POWER1_MSB1_REG                        0x0C
#define LTC2992_MIN_POWER1_LSB_REG                         0x0D
#define LTC2992_MAX_POWER1_THRESHOLD_MSB2_REG              0x0E
#define LTC2992_MAX_POWER1_THRESHOLD_MSB1_REG              0x0F
#define LTC2992_MAX_POWER1_THRESHOLD_LSB_REG               0x10
#define LTC2992_MIN_POWER1_THRESHOLD_MSB2_REG              0x11
#define LTC2992_MIN_POWER1_THRESHOLD_MSB1_REG              0x12
#define LTC2992_MIN_POWER1_THRESHOLD_LSB_REG               0x13
#define LTC2992_DELTA_SENSE1_MSB_REG                       0x14
#define LTC2992_DELTA_SENSE1_LSB_REG                       0x15
#define LTC2992_MAX_DELTA1_SENSE_MSB_REG                   0x16
#define LTC2992_MAX_DELTA1_SENSE_LSB_REG                   0x17
#define LTC2992_MIN_DELTA1_SENSE_MSB_REG                   0x18
#define LTC2992_MIN_DELTA1_SENSE_LSB_REG                   0x19
#define LTC2992_MAX_DELTA1_SENSE_THRESHOLD_MSB_REG         0x1A
#define LTC2992_MAX_DELTA1_SENSE_THRESHOLD_LSB_REG         0x1B
#define LTC2992_MIN_DELTA1_SENSE_THRESHOLD_MSB_REG         0x1C
#define LTC2992_MIN_DELTA1_SENSE_THRESHOLD_LSB_REG         0x1D
#define LTC2992_SENSE1_MSB_REG                             0x1E
#define LTC2992_SENSE1_LSB_REG                             0x1F
#define LTC2992_MAX_SENSE1_MSB_REG                         0x20
#define LTC2992_MAX_SENSE1_LSB_REG                         0x21
#define LTC2992_MIN_SENSE1_MSB_REG                         0x22
#define LTC2992_MIN_SENSE1_LSB_REG                         0x23
#define LTC2992_MAX_SENSE1_THRESHOLD_MSB_REG               0x24
#define LTC2992_MAX_SENSE1_THRESHOLD_LSB_REG               0x25
#define LTC2992_MIN_SENSE1_THRESHOLD_MSB_REG               0x26
#define LTC2992_MIN_SENSE1_THRESHOLD_LSB_REG               0x27
#define LTC2992_GPIO1_MSB_REG                              0x28
#define LTC2992_GPIO1_LSB_REG_REG                          0x29
#define LTC2992_MAX_GPIO1_MSB_REG                          0x2A
#define LTC2992_MAX_GPIO1_LSB_REG                          0x2B
#define LTC2992_MIN_GPIO1_MSB_REG                          0x2C
#define LTC2992_MIN_GPIO1_LSB_REG                          0x2D
#define LTC2992_MAX_GPIO1_THRESHOLD_MSB_REG                0x2E
#define LTC2992_MAX_GPIO1_THRESHOLD_LSB_REG                0x2F
#define LTC2992_MIN_GPIO1_THRESHOLD_MSB_REG                0x30
#define LTC2992_MIN_GPIO1_THRESHOLD_LSB_REG                0x31
#define LTC2992_ADC_STATUS_REG                             0x32
#define LTC2992_ALERT2_REG                                 0x34
#define LTC2992_FAULT2_REG                                 0x35
#define LTC2992_POWER2_MSB2_REG                            0x37
#define LTC2992_POWER2_MSB1_REG                            0x38
#define LTC2992_POWER2_LSB_REG                             0x39
#define LTC2992_MAX_POWER2_MSB2_REG                        0x3A
#define LTC2992_MAX_POWER2_MSB1_REG                        0x3B
#define LTC2992_MAX_POWER2_LSB_REG                         0x3C
#define LTC2992_MIN_POWER2_MSB2_REG                        0x3D
#define LTC2992_MIN_POWER2_MSB1_REG                        0x3E
#define LTC2992_MIN_POWER2_LSB_REG                         0x3F
#define LTC2992_MAX_POWER2_THRESHOLD_MSB2_REG              0x40
#define LTC2992_MAX_POWER2_THRESHOLD_MSB1_REG              0x41
#define LTC2992_MAX_POWER2_THRESHOLD_LSB_REG               0x42
#define LTC2992_MIN_POWER2_THRESHOLD_MSB2_REG              0x43
#define LTC2992_MIN_POWER2_THRESHOLD_MSB1_REG              0x44
#define LTC2992_MIN_POWER2_THRESHOLD_LSB_REG               0x45
#define LTC2992_DELTA_SENSE2_MSB_REG                       0x46
#define LTC2992_DELTA_SENSE2_LSB_REG                       0x47
#define LTC2992_MAX_DELTA2_SENSE_MSB_REG                   0x48
#define LTC2992_MAX_DELTA2_SENSE_LSB_REG                   0x49
#define LTC2992_MIN_DELTA2_SENSE_MSB_REG                   0x4A
#define LTC2992_MIN_DELTA2_SENSE_LSB_REG                   0x4B
#define LTC2992_MAX_DELTA2_SENSE_THRESHOLD_MSB_REG         0x4C
#define LTC2992_MAX_DELTA2_SENSE_THRESHOLD_LSB_REG         0x4D
#define LTC2992_MIN_DELTA2_SENSE_THRESHOLD_MSB_REG         0x4E
#define LTC2992_MIN_DELTA2_SENSE_THRESHOLD_LSB_REG         0x4F
#define LTC2992_SENSE2_MSB_REG                             0x50
#define LTC2992_SENSE2_LSB_REG                             0x51
#define LTC2992_MAX_SENSE2_MSB_REG                         0x52
#define LTC2992_MAX_SENSE2_LSB_REG                         0x53
#define LTC2992_MIN_SENSE2_MSB_REG                         0x54
#define LTC2992_MIN_SENSE2_LSB_REG                         0x55
#define LTC2992_MAX_SENSE2_THRESHOLD_MSB_REG               0x56
#define LTC2992_MAX_SENSE2_THRESHOLD_LSB_REG               0x57
#define LTC2992_MIN_SENSE2_THRESHOLD_MSB_REG               0x58
#define LTC2992_MIN_SENSE2_THRESHOLD_LSB_REG               0x59
#define LTC2992_GPIO2_MSB_REG                              0x5A
#define LTC2992_GPIO2_LSB_REG_REG                          0x5B
#define LTC2992_MAX_GPIO2_MSB_REG                          0x5C
#define LTC2992_MAX_GPIO2_LSB_REG                          0x5D
#define LTC2992_MIN_GPIO2_MSB_REG                          0x5E
#define LTC2992_MIN_GPIO2_LSB_REG                          0x5F
#define LTC2992_MAX_GPIO2_THRESHOLD_MSB_REG                0x60
#define LTC2992_MAX_GPIO2_THRESHOLD_LSB_REG                0x61
#define LTC2992_MIN_GPIO2_THRESHOLD_MSB_REG                0x62
#define LTC2992_MIN_GPIO2_THRESHOLD_LSB_REG                0x63
#define LTC2992_GPIO3_MSB_REG                              0x64
#define LTC2992_GPIO3_LSB_REG_REG                          0x65
#define LTC2992_MAX_GPIO3_MSB_REG                          0x66
#define LTC2992_MAX_GPIO3_LSB_REG                          0x67
#define LTC2992_MIN_GPIO3_MSB_REG                          0x68
#define LTC2992_MIN_GPIO3_LSB_REG                          0x69
#define LTC2992_MAX_GPIO3_THRESHOLD_MSB_REG                0x6A
#define LTC2992_MAX_GPIO3_THRESHOLD_LSB_REG                0x6B
#define LTC2992_MIN_GPIO3_THRESHOLD_MSB_REG                0x6C
#define LTC2992_MIN_GPIO3_THRESHOLD_LSB_REG                0x6D
#define LTC2992_GPIO4_MSB_REG                              0x6E
#define LTC2992_GPIO4_LSB_REG_REG                          0x6F
#define LTC2992_MAX_GPIO4_MSB_REG                          0x70
#define LTC2992_MAX_GPIO4_LSB_REG                          0x71
#define LTC2992_MIN_GPIO4_MSB_REG                          0x72
#define LTC2992_MIN_GPIO4_LSB_REG                          0x73
#define LTC2992_MAX_GPIO4_THRESHOLD_MSB_REG                0x74
#define LTC2992_MAX_GPIO4_THRESHOLD_LSB_REG                0x75
#define LTC2992_MIN_GPIO4_THRESHOLD_MSB_REG                0x76
#define LTC2992_MIN_GPIO4_THRESHOLD_LSB_REG                0x77
#define LTC2992_ISUM_MSB_REG                               0x78
#define LTC2992_ISUM_LSB_REG_REG                           0x79
#define LTC2992_MAX_ISUM_MSB_REG                           0x7A
#define LTC2992_MAX_ISUM_LSB_REG                           0x7B
#define LTC2992_MIN_ISUM_MSB_REG                           0x7C
#define LTC2992_MIN_ISUM_LSB_REG                           0x7D
#define LTC2992_MAX_ISUM_THRESHOLD_MSB_REG                 0x7E
#define LTC2992_MAX_ISUM_THRESHOLD_LSB_REG                 0x7F
#define LTC2992_MIN_ISUM_THRESHOLD_MSB_REG                 0x80
#define LTC2992_MIN_ISUM_THRESHOLD_LSB_REG                 0x81
#define LTC2992_PSUM_MSB1_REG                              0x82
#define LTC2992_PSUM_MSB_REG                               0x83
#define LTC2992_PSUM_LSB_REG_REG                           0x84
#define LTC2992_MAX_PSUM_MSB1_REG                          0x85
#define LTC2992_MAX_PSUM_MSB_REG                           0x86
#define LTC2992_MAX_PSUM_LSB_REG                           0x87
#define LTC2992_MIN_PSUM_MSB1_REG                          0x88
#define LTC2992_MIN_PSUM_MSB_REG                           0x89
#define LTC2992_MIN_PSUM_LSB_REG                           0x8A
#define LTC2992_MAX_PSUM_THRESHOLD_MSB1_REG                0x8B
#define LTC2992_MAX_PSUM_THRESHOLD_MSB_REG                 0x8C
#define LTC2992_MAX_PSUM_THRESHOLD_LSB_REG                 0x8D
#define LTC2992_MIN_PSUM_THRESHOLD_MSB1_REG                0x8E
#define LTC2992_MIN_PSUM_THRESHOLD_MSB_REG                 0x8F
#define LTC2992_MIN_PSUM_THRESHOLD_LSB_REG                 0x90
#define LTC2992_ALERT3_REG                                 0x91
#define LTC2992_FAULT3_REG                                 0x92
#define LTC2992_ALERT4_REG                                 0x93
#define LTC2992_FAULT4_REG                                 0x94
#define LTC2992_GPIO_STATUS_REG                            0x95
#define LTC2992_GPIO_IO_CONT_REG                           0x96
#define LTC2992_GPIO4_CFG_REG                              0x97


//! @}

/*! @name Command Codes
@{ */
// Command Codes

#define LTC2992_OFFSET_CAL_DEMAND                          0x80
#define LTC2992_OFFSET_CAL_EVERY                           0x00

#define LTC2992_MODE_SHUTDOWN                              0x60
#define LTC2992_MODE_SINGLE_CYCLE                          0x40
#define LTC2992_MODE_SNAPSHOT                0x20
#define LTC2992_MODE_CONTINUOUS                            0x00

#define LTC2992_CONTINUOUS_GPIO_1_2_3_4                     0x18
#define LTC2992_CONTINUOUS_GPIO_1_2                         0x10
#define LTC2992_CONTINUOUS_SENSE_1_2            0x08
#define LTC2992_CONTINUOUS_SENSE_1_2_GPIO_1_2_3_4           0x00

#define LTC2992_SNAPSHOT_GPIO_1_2                           0x07
#define LTC2992_SNAPSHOT_SENSE_1_2                          0x06
#define LTC2992_SNAPSHOT_GPIO_4                             0x05
#define LTC2992_SNAPSHOT_GPIO_3                             0x04
#define LTC2992_SNAPSHOT_GPIO_2                             0x03
#define LTC2992_SNAPSHOT_GPIO_1                             0x02
#define LTC2992_SNAPSHOT_SENSE_2                            0x01
#define LTC2992_SNAPSHOT_SENSE_1                            0x00

#define LTC2992_ENABLE_ALERT_CLEAR              0x80
#define LTC2992_ENABLE_CLEARED_ON_READ          0x20
#define LTC2992_ENABLE_STUCK_BUS_RECOVER        0x10
#define LTC2992_ENABLE_RESET_PEAK_VALUES        0x08
#define LTC2992_ENABLE_RESET_ALL                0x01

#define LTC2992_DISABLE_ALERT_CLEAR             0x7F
#define LTC2992_DISABLE_CLEARED_ON_READ         0xDF
#define LTC2992_DISABLE_STUCK_BUS_RECOVER       0xEF
#define LTC2992 DISABLE_RESET_PEAK_VALUES       0xF7
#define LTC2992_DISABLE_RESET_ALL               0xFE

#define LTC2992_ENABLE_MAX_POWER1_ALERT          0x80
#define LTC2992_ENABLE_MIN_POWER1_ALERT          0x40
#define LTC2992_DISABLE_MAX_POWER1_ALERT         0x7F
#define LTC2992_DISABLE_MIN_POWER1_ALERT         0xBF

#define LTC2992_ENABLE_MAX_I_SENSE1_ALERT        0x20
#define LTC2992_ENABLE_MIN_I_SENSE1_ALERT        0x10
#define LTC2992_DISABLE_MAX_I_SENSE1_ALERT       0xDF
#define LTC2992_DISABLE_MIN_I_SENSE1_ALERT       0xEF

#define LTC2992_ENABLE_MAX_SENSE1_ALERT            0x08
#define LTC2992_ENABLE_MIN_SENSE1_ALERT            0x04
#define LTC2992_DISABLE_MAX_SENSE1_ALERT           0xF7
#define LTC2992_DISABLE_MIN_SENSE1_ALERT           0xFB

#define LTC2992_ENABLE_MAX_GPIO1_ALERT           0x02
#define LTC2992_ENABLE_MIN_GPIO1_ALERT           0x01
#define LTC2992_DISABLE_MAX_GPIO1_ALERT          0xFD
#define LTC2992_DISABLE_MIN_GPIO1_ALERT          0xFE


//NADC
#define LTC2992_ADC_RESOLUTION                0x80

//ALERT2
#define LTC2992_ENABLE_MAX_POWER2_ALERT          0x80
#define LTC2992_ENABLE_MIN_POWER2_ALERT          0x40
#define LTC2992_DISABLE_MAX_POWER2_ALERT         0x7F
#define LTC2992_DISABLE_MIN_POWER2_ALERT         0xBF

#define LTC2992_ENABLE_MAX_I_SENSE2_ALERT        0x20
#define LTC2992_ENABLE_MIN_I_SENSE2_ALERT        0x10
#define LTC2992_DISABLE_MAX_I_SENSE2_ALERT       0xDF
#define LTC2992_DISABLE_MIN_I_SENSE2_ALERT       0xEF

#define LTC2992_ENABLE_MAX_SENSE2_ALERT            0x08
#define LTC2992_ENABLE_MIN_SENSE2_ALERT            0x04
#define LTC2992_DISABLE_MAX_SENSE2_ALERT           0xF7
#define LTC2992_DISABLE_MIN_SENSE2_ALERT           0xFB

#define LTC2992_ENABLE_MAX_GPIO2_ALERT           0x02
#define LTC2992_ENABLE_MIN_GPIO2_ALERT           0x01
#define LTC2992_DISABLE_MAX_GPIO2_ALERT          0xFD
#define LTC2992_DISABLE_MIN_GPIO2_ALERT          0xFE

//ALERT3
#define LTC2992_ENABLE_MAX_GPIO3_ALERT          0x80
#define LTC2992_ENABLE_MIN_GPIO3_ALERT          0x40
#define LTC2992_DISABLE_MAX_GPIO3_ALERT         0x7F
#define LTC2992_DISABLE_MIN_GPIO3_ALERT         0xBF

#define LTC2992_ENABLE_MAX_GPIO4_ALERT        0x20
#define LTC2992_ENABLE_MIN_GPIO4_ALERT        0x10
#define LTC2992_DISABLE_MAX_GPIO4_ALERT       0xDF
#define LTC2992_DISABLE_MIN_GPIO4_ALERT       0xEF

#define LTC2992_ENABLE_MAX_I_SUM_ALERT            0x08
#define LTC2992_ENABLE_MIN_I_SUM_ALERT            0x04
#define LTC2992_DISABLE_MAX_I_SUM_ALERT           0xF7
#define LTC2992_DISABLE_MIN_I_SUM_ALERT           0xFB

#define LTC2992_ENABLE_MAX_P_SUM_ALERT           0x02
#define LTC2992_ENABLE_MIN_P_SUM_ALERT           0x01
#define LTC2992_DISABLE_MAX_P_SUM_ALERT          0xFD
#define LTC2992_DISABLE_MIN_P_SUM_ALERT          0xFE

//ALERT4
#define LTC2992_ENABLE_V_ADC_READY_ALERT          0x80
#define LTC2992_ENABLE_I_ADC_READY_ALERT          0x40
#define LTC2992_DISABLE_V_ADC_READY_ALERT         0x7F
#define LTC2992_DISABLE_I_ADC_READY_ALERT         0xBF

#define LTC2992_ENABLE_STUCK_BUS_TIMEOUT_ALERT        0x10
#define LTC2992_DISABLE_STUCK_BUS_TIMEOUT_ALERT       0xEF

#define LTC2992_ENABLE_GPIO1_INPUT_ALERT            0x08
#define LTC2992_ENABLE_GPIO2_INPUT_ALERT            0x04
#define LTC2992_DISABLE_GPIO1_INPUT_ALERT           0xF7
#define LTC2992_DISABLE_GPIO2_INPUT_ALERT           0xFB

#define LTC2992_ENABLE_GPIO3_INPUT_ALERT           0x02
#define LTC2992_DISABLE_GPIO3_INPUT_ALERT          0xFD


//GPIO IO Control Registers
#define LTC2992_GPIO1_OUT_HIGH_Z                  0x7F
#define LTC2992_GPIO1_OUT_LOW                     0x80
#define LTC2992_GPIO2_OUT_HIGH_Z                  0xBF
#define LTC2992_GPIO2_OUT_LOW                     0x40

#define LTC2992_GPIO3_CONFIG_LOW_DATARDY          0x30
#define LTC2992_GPIO3_CONFIG_128_LOW              0x20
#define LTC2992_GPIO3_CONFIG_16_LOW               0x10
#define LTC2992_GPIO3_CONFIG_IO                   0x00

#define LTC2992_GPIO1_IN_HIGH_POL_ALERT           0x08
#define LTC2992_GPIO1_IN_LOW_POL_ALERT            0xFC
#define LTC2992_GPIO2_IN_HIGH_POL_ALERT           0x04
#define LTC2992_GPIO2_IN_LOW_POL_ALERT            0xFB
#define LTC2992_GPIO3_IN_HIGH_POL_ALERT           0x02
#define LTC2992_GPIO3_IN_LOW_POL_ALERT            0xFD
#define LTC2992_GPIO3_OUT_LOW                     0x01
#define LTC2992_GPIO3_OUT_HIGH_Z                  0xFE

//GPIO4 Control Reg
#define LTC2992_ALERT_GENERATED_TRUE              0x80
#define LTC2992_ALERT_GENERATED_CLEAR             0x7F
#define LTC2992_GPIO4_OUT_LOW                     0x40
#define LTC2992_GPIO4_OUT_HI_Z                   0xBF
//! @}

/*! @name Register Mask Command
@{ */
// Register Mask Command
#define LTC2992_CTRLA_OFFSET_MASK                      0x7F
#define LTC2992_CTRLA_MEASUREMENT_MODE_MASK            0x9F
#define LTC2992_CTRLA_VOLTAGE_SEL_CONTINIOUS_MASK      0xE7
#define LTC2992_CTRLA_VOLTAGE_SEL_SNAPSHOT_MASK        0xF8
#define LTC2992_CTRLB_ACC_MASK                         0xF3
#define LTC2992_CTRLB_RESET_MASK                       0xFC
#define LTC2992_GPIOCFG_GPIO1_MASK                     0x3F
#define LTC2992_GPIOCFG_GPIO2_MASK                     0xCF
#define LTC2992_GPIOCFG_GPIO3_MASK                     0xCF
#define LTC2992_GPIOCFG_GPIO2_OUT_MASK                 0xFD
#define LTC2992_GPIO3_CTRL_GPIO3_MASK                  0xBF
//! @}

//! Write an 8-bit code to the LTC2992.
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2992_write(uint8_t i2c_address, //!< Register address for the LTC2992
                     uint8_t adc_command, //!< The "command byte" for the LTC2992
                     uint8_t code         //!< Value that will be written to the register.
                    );
//! Write a 16-bit code to the LTC2992.
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2992_write_16_bits(uint8_t i2c_address, //!< Register address for the LTC2992
                             uint8_t adc_command, //!< The "command byte" for the LTC2992
                             uint16_t code        //!< Value that will be written to the register.
                            );

//! Write a 24-bit code to the LTC2992.
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2992_write_24_bits(uint8_t i2c_address, //!< Register address for the LTC2992
                             uint8_t adc_command, //!< The "command byte" for the LTC2992
                             uint32_t code         //!< Value that will be written to the register.
                            );

//! Reads an 8-bit adc_code from LTC2992
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2992_read(uint8_t i2c_address, //!< Register address for the LTC2992
                    uint8_t adc_command, //!< The "command byte" for the LTC2992
                    uint8_t *adc_code    //!< Value that will be read from the register.
                   );
//! Reads a 12-bit adc_code from LTC2992
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2992_read_12_bits(uint8_t i2c_address, //!< Register address for the LTC2992
                            uint8_t adc_command, //!< The "command byte" for the LTC2992
                            uint16_t *adc_code   //!< Value that will be read from the register.
                           );
//! Reads a 16-bit adc_code from LTC2992
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2992_read_16_bits(uint8_t i2c_address, //!< Register address for the LTC2992
                            uint8_t adc_command, //!< The "command byte" for the LTC2992
                            uint16_t *adc_code   //!< Value that will be read from the register.
                           );
//! Reads a 24-bit adc_code from LTC2992
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2992_read_24_bits(uint8_t i2c_address, //!< Register address for the LTC2992
                            uint8_t adc_command, //!< The "command byte" for the LTC2992
                            uint32_t *adc_code    //!< Value that will be read from the register.
                           );

//! Calculate the LTC2992 SENSE voltage
//! @return Returns the SENSE Voltage in Volts
float LTC2992_SENSE_code_to_voltage(uint16_t adc_code,        //!< The ADC value
                                    float LTC2992_SENSE_lsb     //!< SENSE lsb weight
                                   );
//! Calculate the LTC2992 GPIO voltage
//! @return Returns the GPIO Voltage in Volts
float LTC2992_GPIO_code_to_voltage(uint16_t adc_code,       //!< The ADC value
                                   float LTC2992_ADIN_lsb   //!< GPIO lsb weight
                                  );
//! Calculate the LTC2992 current with a sense resistor
//! @return The LTC2992 current in Amps
float LTC2992_code_to_current(uint16_t adc_code,                //!< The ADC value
                              float resistor,                   //!< The resistor value
                              float LTC2992_DELTA_SENSE_lsb     //!< Delta sense lsb weight
                             );

//! Calculate the LTC2992 current sum with a sense resistor
//! @return The LTC2992 current in Amps
float LTC2992_code_to_current_sum(uint16_t adc_code,                //!< The ADC value
                                  float resistor,                   //!< The resistor value
                                  float LTC2992_DELTA_SENSE_lsb     //!< Delta sense lsb weight
                                 );

//! Calculate the LTC2992 power
//! @return The LTC2992 power in Watts
float LTC2992_code_to_power(int32_t adc_code,           //!< The ADC value
                            float resistor,       //!< The resistor value
                            float LTC2992_Power_lsb);     //!< Power lsb weight

float LTC2992_code_to_power_sum(int32_t adc_code,             //!< The ADC value
                                float resistor,       //!< The Resistor Value
                                float LTC2992_Power_lsb);    //!< Power LSB Weight

#endif  // LTC2945_H

Technical Support