I2C not yet integrated

Dependencies:   mbed

Tested working with single and differential voltages.

Connect SCL (pin 11) to D15 Connect SDA (pin 10) to D14 Connect pin 16 to +5v Connect pin 9 to gnd

Committer:
lrdawg99
Date:
Wed Nov 16 15:54:08 2016 +0000
Revision:
0:1473318f27b6
Child:
1:4e4194db7cd6
Ready to integrate I2C into LT_I2C

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lrdawg99 0:1473318f27b6 1 /*!
lrdawg99 0:1473318f27b6 2 LTC2991: 14-bit Octal I2C Voltage, Current, and Temperature Monitor
lrdawg99 0:1473318f27b6 3
lrdawg99 0:1473318f27b6 4 @verbatim
lrdawg99 0:1473318f27b6 5
lrdawg99 0:1473318f27b6 6 The LTC2991 is used to monitor system temperatures, voltages and currents.
lrdawg99 0:1473318f27b6 7 Through the I2C serial interface, the eight monitors can individually measure
lrdawg99 0:1473318f27b6 8 supply voltages and can be paired for differential measurements of current sense
lrdawg99 0:1473318f27b6 9 resistors or temperature sensing transistors. Additional measurements include
lrdawg99 0:1473318f27b6 10 internal temperature and internal VCC. The internal 10ppm reference minimizes
lrdawg99 0:1473318f27b6 11 the number of supporting components and area required. Selectable address and
lrdawg99 0:1473318f27b6 12 configurable functionality give the LTC2991 flexibility to be incorporated in
lrdawg99 0:1473318f27b6 13 various systems needing temperature, voltage or current data. The LTC2991 fits
lrdawg99 0:1473318f27b6 14 well in systems needing submillivolt voltage resolution, 1% current measurement
lrdawg99 0:1473318f27b6 15 and 1 degree Celsius temperature accuracy or any combination of the three.
lrdawg99 0:1473318f27b6 16
lrdawg99 0:1473318f27b6 17 @endverbatim
lrdawg99 0:1473318f27b6 18
lrdawg99 0:1473318f27b6 19 http://www.linear.com/product/LTC2991
lrdawg99 0:1473318f27b6 20
lrdawg99 0:1473318f27b6 21 http://www.linear.com/product/LTC2991#demoboards
lrdawg99 0:1473318f27b6 22
lrdawg99 0:1473318f27b6 23 REVISION HISTORY
lrdawg99 0:1473318f27b6 24 $Revision: 3659 $
lrdawg99 0:1473318f27b6 25 $Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $
lrdawg99 0:1473318f27b6 26
lrdawg99 0:1473318f27b6 27 Copyright (c) 2013, Linear Technology Corp.(LTC)
lrdawg99 0:1473318f27b6 28 All rights reserved.
lrdawg99 0:1473318f27b6 29
lrdawg99 0:1473318f27b6 30 Redistribution and use in source and binary forms, with or without
lrdawg99 0:1473318f27b6 31 modification, are permitted provided that the following conditions are met:
lrdawg99 0:1473318f27b6 32
lrdawg99 0:1473318f27b6 33 1. Redistributions of source code must retain the above copyright notice, this
lrdawg99 0:1473318f27b6 34 list of conditions and the following disclaimer.
lrdawg99 0:1473318f27b6 35 2. Redistributions in binary form must reproduce the above copyright notice,
lrdawg99 0:1473318f27b6 36 this list of conditions and the following disclaimer in the documentation
lrdawg99 0:1473318f27b6 37 and/or other materials provided with the distribution.
lrdawg99 0:1473318f27b6 38
lrdawg99 0:1473318f27b6 39 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
lrdawg99 0:1473318f27b6 40 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
lrdawg99 0:1473318f27b6 41 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
lrdawg99 0:1473318f27b6 42 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
lrdawg99 0:1473318f27b6 43 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
lrdawg99 0:1473318f27b6 44 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
lrdawg99 0:1473318f27b6 45 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
lrdawg99 0:1473318f27b6 46 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
lrdawg99 0:1473318f27b6 47 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
lrdawg99 0:1473318f27b6 48 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
lrdawg99 0:1473318f27b6 49
lrdawg99 0:1473318f27b6 50 The views and conclusions contained in the software and documentation are those
lrdawg99 0:1473318f27b6 51 of the authors and should not be interpreted as representing official policies,
lrdawg99 0:1473318f27b6 52 either expressed or implied, of Linear Technology Corp.
lrdawg99 0:1473318f27b6 53
lrdawg99 0:1473318f27b6 54 The Linear Technology Linduino is not affiliated with the official Arduino team.
lrdawg99 0:1473318f27b6 55 However, the Linduino is only possible because of the Arduino team's commitment
lrdawg99 0:1473318f27b6 56 to the open-source community. Please, visit http://www.arduino.cc and
lrdawg99 0:1473318f27b6 57 http://store.arduino.cc , and consider a purchase that will help fund their
lrdawg99 0:1473318f27b6 58 ongoing work.
lrdawg99 0:1473318f27b6 59 */
lrdawg99 0:1473318f27b6 60
lrdawg99 0:1473318f27b6 61 //! @defgroup LTC2991 LTC2991: 14-bit Octal I2C Voltage, Current, and Temperature Monitor
lrdawg99 0:1473318f27b6 62
lrdawg99 0:1473318f27b6 63 /*! @file
lrdawg99 0:1473318f27b6 64 @ingroup LTC2991
lrdawg99 0:1473318f27b6 65 Library for LTC2991: 14-bit Octal I2C Voltage, Current, and Temperature Monitor
lrdawg99 0:1473318f27b6 66 */
lrdawg99 0:1473318f27b6 67
lrdawg99 0:1473318f27b6 68 //#include <Arduino.h>
lrdawg99 0:1473318f27b6 69 #include <stdint.h>
lrdawg99 0:1473318f27b6 70 #include "Linduino.h"
lrdawg99 0:1473318f27b6 71 #include "LT_I2C.h"
lrdawg99 0:1473318f27b6 72 #include "LTC2991.h"
lrdawg99 0:1473318f27b6 73 #include "mbed.h"
lrdawg99 0:1473318f27b6 74
lrdawg99 0:1473318f27b6 75 //#include <Wire.h>
lrdawg99 0:1473318f27b6 76
lrdawg99 0:1473318f27b6 77 // Reads a 14-bit adc_code from LTC2991.
lrdawg99 0:1473318f27b6 78 int8_t LTC2991_adc_read(uint8_t i2c_address, uint8_t msb_register_address, int16_t *adc_code, int8_t *data_valid)
lrdawg99 0:1473318f27b6 79 {
lrdawg99 0:1473318f27b6 80 int8_t ack = 0;
lrdawg99 0:1473318f27b6 81 uint16_t code;
lrdawg99 0:1473318f27b6 82 ack = i2c_read_word_data(i2c_address, msb_register_address, &code);
lrdawg99 0:1473318f27b6 83
lrdawg99 0:1473318f27b6 84 *data_valid = (code >> 15) & 0x01; // Place Data Valid Bit in *data_valid
lrdawg99 0:1473318f27b6 85
lrdawg99 0:1473318f27b6 86 *adc_code = code & 0x7FFF; // Removes data valid bit to return proper adc_code value
lrdawg99 0:1473318f27b6 87
lrdawg99 0:1473318f27b6 88 return(ack);
lrdawg99 0:1473318f27b6 89 }
lrdawg99 0:1473318f27b6 90
lrdawg99 0:1473318f27b6 91 // Reads a 14-bit adc_code from the LTC2991 but enforces a maximum timeout.
lrdawg99 0:1473318f27b6 92 // Similar to LTC2991_adc_read except it repeats until the data_valid bit is set, it fails to receive an I2C acknowledge, or the timeout (in milliseconds)
lrdawg99 0:1473318f27b6 93 // expires. It keeps trying to read from the LTC2991 every millisecond until the data_valid bit is set (indicating new data since the previous
lrdawg99 0:1473318f27b6 94 // time this register was read) or until it fails to receive an I2C acknowledge (indicating an error on the I2C bus).
lrdawg99 0:1473318f27b6 95 int8_t LTC2991_adc_read_timeout(uint8_t i2c_address, uint8_t msb_register_address, int16_t *adc_code, int8_t *data_valid, uint16_t timeout, uint8_t status_bit)
lrdawg99 0:1473318f27b6 96 {
lrdawg99 0:1473318f27b6 97 int8_t ack = 0;
lrdawg99 0:1473318f27b6 98 uint8_t reg_data;
lrdawg99 0:1473318f27b6 99 uint16_t timer_count; // Timer count for data_valid
lrdawg99 0:1473318f27b6 100
lrdawg99 0:1473318f27b6 101 for (timer_count = 0; timer_count < timeout; timer_count++)
lrdawg99 0:1473318f27b6 102 {
lrdawg99 0:1473318f27b6 103
lrdawg99 0:1473318f27b6 104 if (status_bit<8)
lrdawg99 0:1473318f27b6 105 {
lrdawg99 0:1473318f27b6 106 ack |= LTC2991_register_read(i2c_address, LTC2991_STATUS_LOW_REG, &reg_data); //! 1)Read status register until correct data valid bit is set
lrdawg99 0:1473318f27b6 107 }
lrdawg99 0:1473318f27b6 108 else
lrdawg99 0:1473318f27b6 109 {
lrdawg99 0:1473318f27b6 110 ack |= LTC2991_register_read(i2c_address, LTC2991_STATUS_HIGH_REG, &reg_data); //! 1)Read status register until correct data valid bit is set
lrdawg99 0:1473318f27b6 111 if (status_bit==8)
lrdawg99 0:1473318f27b6 112 {
lrdawg99 0:1473318f27b6 113 status_bit =1;
lrdawg99 0:1473318f27b6 114 }
lrdawg99 0:1473318f27b6 115 else
lrdawg99 0:1473318f27b6 116 {
lrdawg99 0:1473318f27b6 117 status_bit = 0;
lrdawg99 0:1473318f27b6 118 }
lrdawg99 0:1473318f27b6 119 }
lrdawg99 0:1473318f27b6 120
lrdawg99 0:1473318f27b6 121 if ((ack) || (((reg_data>>status_bit)&0x1)==1))
lrdawg99 0:1473318f27b6 122 {
lrdawg99 0:1473318f27b6 123 break;
lrdawg99 0:1473318f27b6 124 }
lrdawg99 0:1473318f27b6 125
lrdawg99 0:1473318f27b6 126 wait_ms(1);
lrdawg99 0:1473318f27b6 127 }
lrdawg99 0:1473318f27b6 128
lrdawg99 0:1473318f27b6 129 ack |= LTC2991_adc_read(i2c_address, msb_register_address, &(*adc_code), &(*data_valid)); //! 2) It's either valid or it's timed out, we read anyways
lrdawg99 0:1473318f27b6 130 if (*data_valid !=1)
lrdawg99 0:1473318f27b6 131 {
lrdawg99 0:1473318f27b6 132 ////Serial.print("Data not valid: ");
lrdawg99 0:1473318f27b6 133 //Serial.println(*data_valid);
lrdawg99 0:1473318f27b6 134 return (1);
lrdawg99 0:1473318f27b6 135 }
lrdawg99 0:1473318f27b6 136 return(ack);
lrdawg99 0:1473318f27b6 137 }
lrdawg99 0:1473318f27b6 138
lrdawg99 0:1473318f27b6 139 // Reads new data (even after a mode change) by flushing old data and waiting for the data_valid bit to be set.
lrdawg99 0:1473318f27b6 140 // This function simplifies adc reads when modes are changing. For example, if V1-V2 changes from temperature mode
lrdawg99 0:1473318f27b6 141 // to differential voltage mode, the data in the register may still correspond to the temperature reading immediately
lrdawg99 0:1473318f27b6 142 // after the mode change. Flushing one reading and waiting for a new reading guarantees fresh data is received.
lrdawg99 0:1473318f27b6 143 // If the timeout is reached without valid data (*data_valid=1) the function exits.
lrdawg99 0:1473318f27b6 144 int8_t LTC2991_adc_read_new_data(uint8_t i2c_address, uint8_t msb_register_address, int16_t *adc_code, int8_t *data_valid, uint16_t timeout)
lrdawg99 0:1473318f27b6 145 {
lrdawg99 0:1473318f27b6 146 int8_t ack = 0;
lrdawg99 0:1473318f27b6 147
lrdawg99 0:1473318f27b6 148 ack |= LTC2991_adc_read_timeout(i2c_address, msb_register_address, &(*adc_code), &(*data_valid), timeout, ((msb_register_address/2) - 0x05)); //! 1) Throw away old data
lrdawg99 0:1473318f27b6 149 ack |= LTC2991_adc_read_timeout(i2c_address, msb_register_address, &(*adc_code), &(*data_valid), timeout, ((msb_register_address/2) - 0x05)); //! 2) Read new data
lrdawg99 0:1473318f27b6 150
lrdawg99 0:1473318f27b6 151 return(ack);
lrdawg99 0:1473318f27b6 152 }
lrdawg99 0:1473318f27b6 153
lrdawg99 0:1473318f27b6 154 // Reads an 8-bit register from the LTC2991 using the standard repeated start format.
lrdawg99 0:1473318f27b6 155 int8_t LTC2991_register_read(uint8_t i2c_address, uint8_t register_address, uint8_t *register_data)
lrdawg99 0:1473318f27b6 156 {
lrdawg99 0:1473318f27b6 157 int8_t ack = 0;
lrdawg99 0:1473318f27b6 158
lrdawg99 0:1473318f27b6 159 ack = i2c_read_byte_data(i2c_address, register_address, register_data);
lrdawg99 0:1473318f27b6 160 return(ack);
lrdawg99 0:1473318f27b6 161 }
lrdawg99 0:1473318f27b6 162
lrdawg99 0:1473318f27b6 163 // Write one byte to an LTC2991 register.
lrdawg99 0:1473318f27b6 164 // Writes to an 8-bit register inside the LTC2991 using the standard I2C repeated start format.
lrdawg99 0:1473318f27b6 165 int8_t LTC2991_register_write(uint8_t i2c_address, uint8_t register_address, uint8_t register_data)
lrdawg99 0:1473318f27b6 166 {
lrdawg99 0:1473318f27b6 167 int8_t ack = 0;
lrdawg99 0:1473318f27b6 168
lrdawg99 0:1473318f27b6 169 ack = i2c_write_byte_data(i2c_address, register_address, register_data);
lrdawg99 0:1473318f27b6 170 return(ack);
lrdawg99 0:1473318f27b6 171 }
lrdawg99 0:1473318f27b6 172
lrdawg99 0:1473318f27b6 173 // Used to set and clear bits in a control register. bits_to_set will be bitwise OR'd with the register.
lrdawg99 0:1473318f27b6 174 // bits_to_clear will be inverted and bitwise AND'd with the register so that every location with a 1 will result in a 0 in the register.
lrdawg99 0:1473318f27b6 175 int8_t LTC2991_register_set_clear_bits(uint8_t i2c_address, uint8_t register_address, uint8_t bits_to_set, uint8_t bits_to_clear)
lrdawg99 0:1473318f27b6 176 {
lrdawg99 0:1473318f27b6 177 uint8_t register_data;
lrdawg99 0:1473318f27b6 178 int8_t ack = 0;
lrdawg99 0:1473318f27b6 179
lrdawg99 0:1473318f27b6 180 ack |= LTC2991_register_read(i2c_address, register_address, &register_data); //! 1) Read register
lrdawg99 0:1473318f27b6 181 register_data = register_data & (~bits_to_clear); //! 2) Clear bits that were set to be cleared
lrdawg99 0:1473318f27b6 182 register_data = register_data | bits_to_set;
lrdawg99 0:1473318f27b6 183 ack |= LTC2991_register_write(i2c_address, register_address, register_data); //! 3) Write to register with the cleared bits
lrdawg99 0:1473318f27b6 184 return(ack);
lrdawg99 0:1473318f27b6 185 }
lrdawg99 0:1473318f27b6 186
lrdawg99 0:1473318f27b6 187 // Calculates the LTC2991 single-ended input voltages
lrdawg99 0:1473318f27b6 188 float LTC2991_code_to_single_ended_voltage(int16_t adc_code, float LTC2991_single_ended_lsb)
lrdawg99 0:1473318f27b6 189 {
lrdawg99 0:1473318f27b6 190 float voltage;
lrdawg99 0:1473318f27b6 191 int16_t sign = 1;
lrdawg99 0:1473318f27b6 192 if (adc_code >> 14)
lrdawg99 0:1473318f27b6 193 {
lrdawg99 0:1473318f27b6 194 adc_code = (adc_code ^ 0x7FFF) + 1; //! 1) Converts two's complement to binary
lrdawg99 0:1473318f27b6 195 sign = -1;
lrdawg99 0:1473318f27b6 196 }
lrdawg99 0:1473318f27b6 197 adc_code = (adc_code & 0x3FFF);
lrdawg99 0:1473318f27b6 198 voltage = ((float) adc_code) * LTC2991_single_ended_lsb * sign; //! 2) Convert code to voltage from lsb
lrdawg99 0:1473318f27b6 199 return (voltage);
lrdawg99 0:1473318f27b6 200 }
lrdawg99 0:1473318f27b6 201
lrdawg99 0:1473318f27b6 202 // Calculates the LTC2991 Vcc voltage
lrdawg99 0:1473318f27b6 203 float LTC2991_code_to_vcc_voltage(int16_t adc_code, float LTC2991_single_ended_lsb)
lrdawg99 0:1473318f27b6 204 {
lrdawg99 0:1473318f27b6 205 float voltage;
lrdawg99 0:1473318f27b6 206 int16_t sign = 1;
lrdawg99 0:1473318f27b6 207 if (adc_code >> 14)
lrdawg99 0:1473318f27b6 208 {
lrdawg99 0:1473318f27b6 209 adc_code = (adc_code ^ 0x7FFF) + 1; //! 1) Converts two's complement to binary
lrdawg99 0:1473318f27b6 210 sign = -1;
lrdawg99 0:1473318f27b6 211 }
lrdawg99 0:1473318f27b6 212
lrdawg99 0:1473318f27b6 213 voltage = (((float) adc_code) * LTC2991_single_ended_lsb * sign) + 2.5; //! 2) Convert code to Vcc Voltage from single-ended lsb
lrdawg99 0:1473318f27b6 214 return (voltage);
lrdawg99 0:1473318f27b6 215 }
lrdawg99 0:1473318f27b6 216
lrdawg99 0:1473318f27b6 217 // Calculates the LTC2991 differential input voltage.
lrdawg99 0:1473318f27b6 218 float LTC2991_code_to_differential_voltage(int16_t adc_code, float LTC2991_differential_lsb)
lrdawg99 0:1473318f27b6 219 {
lrdawg99 0:1473318f27b6 220 float voltage;
lrdawg99 0:1473318f27b6 221 int16_t sign = 1;
lrdawg99 0:1473318f27b6 222 if (adc_code >> 14)
lrdawg99 0:1473318f27b6 223 {
lrdawg99 0:1473318f27b6 224 adc_code = (adc_code ^ 0x7FFF) + 1; //! 1)Converts two's complement to binary
lrdawg99 0:1473318f27b6 225 sign = -1;
lrdawg99 0:1473318f27b6 226 }
lrdawg99 0:1473318f27b6 227 voltage = ((float) adc_code) * LTC2991_differential_lsb * sign; //! 2) Convert code to voltage form differential lsb
lrdawg99 0:1473318f27b6 228 return (voltage);
lrdawg99 0:1473318f27b6 229 }
lrdawg99 0:1473318f27b6 230
lrdawg99 0:1473318f27b6 231 // Calculates the LTC2991 temperature
lrdawg99 0:1473318f27b6 232 float LTC2991_temperature(int16_t adc_code, float LTC2991_temperature_lsb, boolean unit)
lrdawg99 0:1473318f27b6 233 {
lrdawg99 0:1473318f27b6 234 float temperature;
lrdawg99 0:1473318f27b6 235 adc_code = (adc_code & 0x1FFF); //! 1) Removes first 3 bits
lrdawg99 0:1473318f27b6 236 if (!unit) //! 2)Checks to see if it's Kelvin
lrdawg99 0:1473318f27b6 237 {
lrdawg99 0:1473318f27b6 238 if (adc_code >>12)
lrdawg99 0:1473318f27b6 239 {
lrdawg99 0:1473318f27b6 240 adc_code = (adc_code | 0xE000); //! Sign extend if it's not Kelvin (Celsius)
lrdawg99 0:1473318f27b6 241 }
lrdawg99 0:1473318f27b6 242 }
lrdawg99 0:1473318f27b6 243 temperature = ((float) adc_code) * LTC2991_temperature_lsb; //! 3) Converts code to temperature from temperature lsb
lrdawg99 0:1473318f27b6 244
lrdawg99 0:1473318f27b6 245 return (temperature);
lrdawg99 0:1473318f27b6 246 }
lrdawg99 0:1473318f27b6 247
lrdawg99 0:1473318f27b6 248 // Calculates the LTC2991 diode voltage
lrdawg99 0:1473318f27b6 249 float LTC2991_code_to_diode_voltage(int16_t adc_code, float LTC2991_diode_voltage_lsb)
lrdawg99 0:1473318f27b6 250 {
lrdawg99 0:1473318f27b6 251 float voltage;
lrdawg99 0:1473318f27b6 252 adc_code = (adc_code & 0x1FFF); //! 1) Removes first 3 bits
lrdawg99 0:1473318f27b6 253 voltage = ((float) adc_code) * LTC2991_diode_voltage_lsb; //! 2) Convert code to voltage from diode voltage lsb
lrdawg99 0:1473318f27b6 254 return (voltage);
lrdawg99 0:1473318f27b6 255 }