#pragma once

/*!
 LTC2946: 12-Bit Wide Range Power, Charge and Energy Monitor
The LTC®2946 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 LTC2946 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, voltage, charge and energy.
	CTRLA =
LTC2946_CHANNEL_CONFIG_V_C_3|LTC2946_SENSE_PLUS|LTC2946_OFFSET_CAL_EVERY|LTC2946_ADIN_GND;  //! Set
Control A register to default value in continuous mode ack |= LTC2946_write(LTC2946_I2C_ADDRESS,
LTC2946_CTRLA_REG, CTRLA);   //! Sets the LTC2946 to continuous mode resistor = .02; // Resistor
Value On Demo Board ack |= LTC2946_read_24_bits(LTC2946_I2C_ADDRESS, LTC2946_POWER_MSB2_REG,
&power_code);  // Reads the ADC registers that contains V^2 power =
LTC2946_code_to_power(power_code, resistor, LTC2946_Power_lsb); // Calculates power from power code,
resistor value and power lsb ack |= LTC2946_read_12_bits(LTC2946_I2C_ADDRESS,
LTC2946_DELTA_SENSE_MSB_REG, &current_code); // Reads the voltage code across sense resistor current
= LTC2946_code_to_current(current_code, resistor, LTC2946_DELTA_SENSE_lsb); // Calculates current
from current code, resistor value and current lsb ack |= LTC2946_read_12_bits(LTC2946_I2C_ADDRESS,
LTC2946_VIN_MSB_REG, &VIN_code);   // Reads VIN voltage code VIN =
LTC2946_VIN_code_to_voltage(VIN_code, LTC2946_VIN_lsb);  // Calculates VIN voltage from VIN code and
lsb ack |= LTC2946_read_32_bits(LTC2946_I2C_ADDRESS, LTC2946_ENERGY_MSB3_REG, &energy_code);	//
Reads energy code energy = LTC2946_code_to_energy(energy_code,resistor,LTC2946_Power_lsb,
LTC2946_INTERNAL_TIME_lsb); //Calculates Energy in Joules from energy_code, resistor, power lsb and
time lsb ack |= LTC2946_read_32_bits(LTC2946_I2C_ADDRESS, LTC2946_CHARGE_MSB3_REG, &charge_code);
// Reads charge code charge = LTC2946_code_to_coulombs(charge_code,resistor,LTC2946_DELTA_SENSE_lsb,
LTC2946_INTERNAL_TIME_lsb);	//Calculates charge in coulombs from charge_code, resistor, current lsb
and time lsb
*/

//! Use table to select address
/*!
| LTC2946 I2C Address Assignment    | Value |   AD0    |   AD1    |
| :-------------------------------- | :---: | :------: | :------: |
| LTC2946_I2C_ADDRESS               | 0xCE  |   High   |   Low    |
| LTC2946_I2C_ADDRESS               | 0xD0  |   Float  |   High   |
| LTC2946_I2C_ADDRESS               | 0xD2  |   High   |   High   |
| LTC2946_I2C_ADDRESS               | 0xD4  | 	Float  |   Float  |
| LTC2946_I2C_ADDRESS               | 0xD6  | 	Float  |   Low    |
| LTC2946_I2C_ADDRESS               | 0xD8  | 	Low    |   High   |
| LTC2946_I2C_ADDRESS               | 0xDA  | 	High   |   Float  |
| LTC2946_I2C_ADDRESS               | 0xDC  | 	Low    |   Float  |
| LTC2946_I2C_ADDRESS               | 0xDE  | 	Low    |   Low    |
|                                   |       |          |          |
| LTC2946_I2C_MASS_WRITE            | 0xCC  | X        | X        |
| LTC2946_I2C_ALERT_RESPONSE        | 0x19  | X        | X        |
*/

/*! @name LTC2946 Registers
@{ */
#define LTC2946_CTRLA_REG 0x00
#define LTC2946_CTRLB_REG 0x01
#define LTC2946_ALERT1_REG 0x02
#define LTC2946_STATUS1_REG 0x03
#define LTC2946_FAULT1_REG 0x04

#define LTC2946_POWER_MSB2_REG 0x05
#define LTC2946_POWER_MSB1_REG 0x06
#define LTC2946_POWER_LSB_REG 0x07
#define LTC2946_MAX_POWER_MSB2_REG 0x08
#define LTC2946_MAX_POWER_MSB1_REG 0x09
#define LTC2946_MAX_POWER_LSB_REG 0x0A
#define LTC2946_MIN_POWER_MSB2_REG 0x0B
#define LTC2946_MIN_POWER_MSB1_REG 0x0C
#define LTC2946_MIN_POWER_LSB_REG 0x0D
#define LTC2946_MAX_POWER_THRESHOLD_MSB2_REG 0x0E
#define LTC2946_MAX_POWER_THRESHOLD_MSB1_REG 0x0F
#define LTC2946_MAX_POWER_THRESHOLD_LSB_REG 0x10
#define LTC2946_MIN_POWER_THRESHOLD_MSB2_REG 0x11
#define LTC2946_MIN_POWER_THRESHOLD_MSB1_REG 0x12
#define LTC2946_MIN_POWER_THRESHOLD_LSB_REG 0x13

#define LTC2946_DELTA_SENSE_MSB_REG 0x14
#define LTC2946_DELTA_SENSE_LSB_REG 0x15
#define LTC2946_MAX_DELTA_SENSE_MSB_REG 0x16
#define LTC2946_MAX_DELTA_SENSE_LSB_REG 0x17
#define LTC2946_MIN_DELTA_SENSE_MSB_REG 0x18
#define LTC2946_MIN_DELTA_SENSE_LSB_REG 0x19
#define LTC2946_MAX_DELTA_SENSE_THRESHOLD_MSB_REG 0x1A
#define LTC2946_MAX_DELTA_SENSE_THRESHOLD_LSB_REG 0x1B
#define LTC2946_MIN_DELTA_SENSE_THRESHOLD_MSB_REG 0x1C
#define LTC2946_MIN_DELTA_SENSE_THRESHOLD_LSB_REG 0x1D

#define LTC2946_VIN_MSB_REG 0x1E
#define LTC2946_VIN_LSB_REG 0x1F
#define LTC2946_MAX_VIN_MSB_REG 0x20
#define LTC2946_MAX_VIN_LSB_REG 0x21
#define LTC2946_MIN_VIN_MSB_REG 0x22
#define LTC2946_MIN_VIN_LSB_REG 0x23
#define LTC2946_MAX_VIN_THRESHOLD_MSB_REG 0x24
#define LTC2946_MAX_VIN_THRESHOLD_LSB_REG 0x25
#define LTC2946_MIN_VIN_THRESHOLD_MSB_REG 0x26
#define LTC2946_MIN_VIN_THRESHOLD_LSB_REG 0x27

#define LTC2946_ADIN_MSB_REG 0x28
#define LTC2946_ADIN_LSB_REG 0x29
#define LTC2946_MAX_ADIN_MSB_REG 0x2A
#define LTC2946_MAX_ADIN_LSB_REG 0x2B
#define LTC2946_MIN_ADIN_MSB_REG 0x2C
#define LTC2946_MIN_ADIN_LSB_REG 0x2D
#define LTC2946_MAX_ADIN_THRESHOLD_MSB_REG 0x2E
#define LTC2946_MAX_ADIN_THRESHOLD_LSB_REG 0x2F
#define LTC2946_MIN_ADIN_THRESHOLD_MSB_REG 0x30
#define LTC2946_MIN_ADIN_THRESHOLD_LSB_REG 0x31

#define LTC2946_ALERT2_REG 0x32
#define LTC2946_GPIO_CFG_REG 0x33

#define LTC2946_TIME_COUNTER_MSB3_REG 0x34
#define LTC2946_TIME_COUNTER_MSB2_REG 0x35
#define LTC2946_TIME_COUNTER_MSB1_REG 0x36
#define LTC2946_TIME_COUNTER_LSB_REG 0x37

#define LTC2946_CHARGE_MSB3_REG 0x38
#define LTC2946_CHARGE_MSB2_REG 0x39
#define LTC2946_CHARGE_MSB1_REG 0x3A
#define LTC2946_CHARGE_LSB_REG 0x3B

#define LTC2946_ENERGY_MSB3_REG 0x3C
#define LTC2946_ENERGY_MSB2_REG 0x3D
#define LTC2946_ENERGY_MSB1_REG 0x3E
#define LTC2946_ENERGY_LSB_REG 0x3F

#define LTC2946_STATUS2_REG 0x40
#define LTC2946_FAULT2_REG 0x41
#define LTC2946_GPIO3_CTRL_REG 0x42
#define LTC2946_CLK_DIV_REG 0x43
//! @}

/*! @name LTC2946 Voltage Selection Command
@{ */
// Voltage Selection Command
#define LTC2946_DELTA_SENSE 0x00
#define LTC2946_VDD 0x08
#define LTC2946_ADIN 0x10
#define LTC2946_SENSE_PLUS 0x18
//! @}

/*! @name LTC2946 Command Codes
@{ */
#define LTC2946_ADIN_INTVCC 0x80
#define LTC2946_ADIN_GND 0x00

#define LTC2946_OFFSET_CAL_LAST 0x60
#define LTC2946_OFFSET_CAL_128 0x40
#define LTC2946_OFFSET_CAL_16 0x20
#define LTC2946_OFFSET_CAL_EVERY 0x00

#define LTC2946_CHANNEL_CONFIG_SNAPSHOT 0x07
#define LTC2946_CHANNEL_CONFIG_V_C 0x06
#define LTC2946_CHANNEL_CONFIG_A_V_C_1 0x05
#define LTC2946_CHANNEL_CONFIG_A_V_C_2 0x04
#define LTC2946_CHANNEL_CONFIG_A_V_C_3 0x03
#define LTC2946_CHANNEL_CONFIG_V_C_1 0x02
#define LTC2946_CHANNEL_CONFIG_V_C_2 0x01
#define LTC2946_CHANNEL_CONFIG_V_C_3 0x00

#define LTC2946_ENABLE_ALERT_CLEAR 0x80
#define LTC2946_ENABLE_SHUTDOWN 0x40
#define LTC2946_ENABLE_CLEARED_ON_READ 0x20
#define LTC2946_ENABLE_STUCK_BUS_RECOVER 0x10

#define LTC2946_DISABLE_ALERT_CLEAR 0x7F
#define LTC2946_DISABLE_SHUTDOWN 0xBF
#define LTC2946_DISABLE_CLEARED_ON_READ 0xDF
#define LTC2946_DISABLE_STUCK_BUS_RECOVER 0xEF

#define LTC2946_ACC_PIN_CONTROL 0x08
#define LTC2946_DISABLE_ACC 0x04
#define LTC2946_ENABLE_ACC 0x00

#define LTC2946_RESET_ALL 0x03
#define LTC2946_RESET_ACC 0x02
#define LTC2946_ENABLE_AUTO_RESET 0x01
#define LTC2946_DISABLE_AUTO_RESET 0x00

#define LTC2946_MAX_POWER_MSB2_RESET 0x00
#define LTC2946_MIN_POWER_MSB2_RESET 0xFF
#define LTC2946_MAX_DELTA_SENSE_MSB_RESET 0x00
#define LTC2946_MIN_DELTA_SENSE_MSB_RESET 0xFF
#define LTC2946_MAX_VIN_MSB_RESET 0x00
#define LTC2946_MIN_VIN_MSB_RESET 0xFF
#define LTC2946_MAX_ADIN_MSB_RESET 0x00
#define LTC2946_MIN_ADIN_MSB_RESET 0xFF

#define LTC2946_ENABLE_MAX_POWER_ALERT 0x80
#define LTC2946_ENABLE_MIN_POWER_ALERT 0x40
#define LTC2946_DISABLE_MAX_POWER_ALERT 0x7F
#define LTC2946_DISABLE_MIN_POWER_ALERT 0xBF

#define LTC2946_ENABLE_MAX_I_SENSE_ALERT 0x20
#define LTC2946_ENABLE_MIN_I_SENSE_ALERT 0x10
#define LTC2946_DISABLE_MAX_I_SENSE_ALERT 0xDF
#define LTC2946_DISABLE_MIN_I_SENSE_ALERT 0xEF

#define LTC2946_ENABLE_MAX_VIN_ALERT 0x08
#define LTC2946_ENABLE_MIN_VIN_ALERT 0x04
#define LTC2946_DISABLE_MAX_VIN_ALERT 0xF7
#define LTC2946_DISABLE_MIN_VIN_ALERT 0xFB

#define LTC2946_ENABLE_MAX_ADIN_ALERT 0x02
#define LTC2946_ENABLE_MIN_ADIN_ALERT 0x01
#define LTC2946_DISABLE_MAX_ADIN_ALERT 0xFD
#define LTC2946_DISABLE_MIN_ADIN_ALERT 0xFE

#define LTC2946_ENABLE_ADC_DONE_ALERT 0x80
#define LTC2946_DISABLE_ADC_DONE_ALERT 0x7F

#define LTC2946_ENABLE_GPIO_1_ALERT 0x40
#define LTC2946_DISABLE_GPIO_1_ALERT 0xBF

#define LTC2946_ENABLE_GPIO_2_ALERT 0x20
#define LTC2946_DISABLE_GPIO_2_ALERT 0xDF

#define LTC2946_ENABLE_STUCK_BUS_WAKE_ALERT 0x08
#define LTC2946_DISABLE_STUCK_BUS_WAKE_ALERT 0xF7

#define LTC2946_ENABLE_ENERGY_OVERFLOW_ALERT 0x04
#define LTC2946_DISABLE_ENERGY_OVERFLOW_ALERT 0xFB

#define LTC2946_ENABLE_CHARGE_OVERFLOW_ALERT 0x02
#define LTC2946_DISABLE_CHARGE_OVERFLOW_ALERT 0xFD

#define LTC2946_ENABLE_COUNTER_OVERFLOW_ALERT 0x01
#define LTC2946_DISABLE_COUNTER_OVERFLOW_ALERT 0xFE

#define LTC2946_GPIO1_IN_ACTIVE_HIGH 0xC0
#define LTC2946_GPIO1_IN_ACTIVE_LOW 0x80
#define LTC2946_GPIO1_OUT_HIGH_Z 0x40
#define LTC2946_GPIO1_OUT_LOW 0x00

#define LTC2946_GPIO2_IN_ACTIVE_HIGH 0x30
#define LTC2946_GPIO2_IN_ACTIVE_LOW 0x20
#define LTC2946_GPIO2_OUT_HIGH_Z 0x10
#define LTC2946_GPIO2_OUT_LOW 0x12
#define LTC2946_GPIO2_IN_ACC 0x00
//! @}

#define LTC2946_STATUS2_BUSY_FLAG 0x08
