Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
LTM9100.cpp
Go to the documentation of this file.
1 /*!
2 LTM9100: Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry
3 
4 @verbatim
5 
6 The LTM9100 μModule controller is a complete, galvanically isolated switch controller
7 with I2C interface, for use as a load switch or hot swap controller. The load is soft
8 started and controlled by an external N-channel MOSFET switch.
9 
10 @endverbatim
11 
12 http://www.linear.com/product/LTM9100
13 
14 http://www.linear.com/product/LTC9100#demoboards
15 
16 
17 Copyright 2018(c) Analog Devices, Inc.
18 
19 All rights reserved.
20 
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions are met:
23  - Redistributions of source code must retain the above copyright
24  notice, this list of conditions and the following disclaimer.
25  - Redistributions in binary form must reproduce the above copyright
26  notice, this list of conditions and the following disclaimer in
27  the documentation and/or other materials provided with the
28  distribution.
29  - Neither the name of Analog Devices, Inc. nor the names of its
30  contributors may be used to endorse or promote products derived
31  from this software without specific prior written permission.
32  - The use of this software may or may not infringe the patent rights
33  of one or more patent holders. This license does not release you
34  from the requirement that you obtain separate licenses from these
35  patent holders to use this software.
36  - Use of the software either in source or binary form, must be run
37  on or directly connected to an Analog Devices Inc. component.
38 
39 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
40 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
41 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
42 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
43 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
45 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
46 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
47 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
48 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 */
50 
51 //! @ingroup Switching_Regulators
52 //! @{
53 //! @defgroup LTM9100 LTM9100: Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry.
54 
55 //! @}
56 
57 /*! @file
58  @ingroup LTM9100
59  Library for LTM9100 Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry.
60 */
61 
62 #include <Arduino.h>
63 #include <stdint.h>
64 #include "Linduino.h"
65 #include "LT_I2C.h"
66 #include "LTM9100.h"
67 
68 uint8_t reg_read_list[10] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
69 uint8_t reg_write_list[9] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
70 
71 // Reads an 8-bit register from the LTM9100 using the standard repeated start format.
72 int8_t LTM9100_register_read(uint8_t i2c_address, uint8_t register_address, uint8_t *register_data)
73 {
74  int8_t ack = 0;
75  ack = i2c_read_byte_data(i2c_address, register_address, register_data);
76  return(ack);
77 }
78 
79 // Read the specified ADC value (SENSE, ADIN, ADIN2) and output in human readable format to the serial console.
80 int8_t LTM9100_adc_read(uint8_t i2c_address, uint8_t base_address, float *register_data)
81 {
82  uint8_t data_LSBs, data_MSBs;
83  uint16_t data_ten_bit;
84  int8_t ack = 0;
85  ack |= LTM9100_register_read(i2c_address, base_address, &data_MSBs);
86  ack |= LTM9100_register_read(i2c_address, base_address+1, &data_LSBs);
87  data_ten_bit = ((uint16_t)data_MSBs<<2) | ((uint16_t)data_LSBs>>6);
88 
89  switch (base_address)
90  {
92  *register_data = ((float)data_ten_bit * LTM_9100_SENSE_mV_PER_TICK)/sense_resistor;
93  Serial.print(F("ADC Current Sense Voltage(mA): "));
94  break;
96  *register_data = ((float)data_ten_bit * LTM_9100_ADIN_V_PER_TICK)/adin_gain;
97  Serial.print(F("ADIN Voltage(V): "));
98  break;
100  *register_data = ((float)data_ten_bit * LTM_9100_ADIN2_V_PER_TICK)/adin2_gain;
101  Serial.print(F("ADIN2 Voltage(V or K): "));
102  break;
103  default:
104  return ack;
105  }
106 
107  Serial.println(*register_data, 4);
108  return ack;
109 }
110 
111 // Writes to an 8-bit register inside the LTM9100 using the standard I2C repeated start format.
112 int8_t LTM9100_register_write(uint8_t i2c_address, uint8_t register_address, uint8_t register_data)
113 {
114  int8_t ack = 0;
115  ack = i2c_write_byte_data(i2c_address, register_address, register_data);
116  return(ack);
117 }
118 
119 // Sets any bit inside the LTM9100 using the standard I2C repeated start format.
120 int8_t LTM9100_bit_set(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
121 {
122  uint8_t register_data;
123  uint8_t bit_mask;
124  int8_t ack = 0;
125  bit_mask = 0x01 << bit_number;
126  ack |= LTM9100_register_read(i2c_address, register_address, &register_data); //Read register
127  register_data = register_data | bit_mask; //Set the bit at bit_address
128  ack |= LTM9100_register_write(i2c_address, register_address, register_data); //Write new data to register
129  return(ack);
130 }
131 
132 // Clears any bit inside the LTM9100 using the standard I2C repeated start format.
133 int8_t LTM9100_bit_clear(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
134 {
135  uint8_t register_data;
136  uint8_t bit_mask;
137  int8_t ack = 0;
138  bit_mask = 0x01 << bit_number;
139  ack |= LTM9100_register_read(i2c_address, register_address, &register_data); //Read register
140  register_data = register_data & (~bit_mask); //Clears the bit at bit_address
141  ack |= LTM9100_register_write(i2c_address, register_address, register_data); //Write new data to register
142  return(ack);
143 }
144 
145 // Read the bit specified by bit_number from the LTM9100.
146 int8_t LTM9100_bit_read(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number, uint8_t *register_data)
147 {
148  int8_t ack = 0;
149  ack = LTM9100_register_read(i2c_address, register_address, register_data);
150  *register_data = (*register_data >> bit_number) & 0x1;
151  return ack;
152 }
153 
154 // Attempts to read a byte from the I2C bus using the alert address (0xC) to ascertain pending alerts on the bus.
155 int8_t LTM9100_alert_read(uint8_t *register_data)
156 {
157  int8_t ack = 0;
158  ack = i2c_read_byte(0x0C, register_data);
159  return(ack);
160 }
161 
162 // Read all LTM9100 registers and output to the serial console.
164 {
165  int8_t ack = 0;
166  uint8_t data;
167  uint8_t i;
168  for (i=0; i<sizeof(reg_read_list); i++)
169  {
170  ack |= LTM9100_register_read(i2c_address, reg_read_list[i], &data); //! Read register
171  Serial.print("Register 0x");
172  Serial.print(reg_read_list[i], HEX);
173  Serial.print(":\t");
174  if (!ack)
175  {
176  Serial.print("0x");
177  Serial.println(data, HEX);
178  }
179  else
180  {
181  Serial.println("No Acknowledge");
182  }
183  }
184  return ack;
185 }
186 
187 // Read all LTM9100 registers and output to the serial console every second until a key press is detected.
189 {
190  int8_t ack = 0;
191  uint8_t count = 0;
192  float data = 0;
193  char anykey[1];
194 
195  //Note: Arduino serial monitor doesn't support all VT100 commands,
196  //thus the continuous_read can't scrollback and rewrite the latest register values.
197  while (count < 1)
198  {
199  ack |= LTM9100_print_all_registers(i2c_address);
200  ack |= LTM9100_adc_read(i2c_address, LTM_9100_SENSE_E_REG, &data);
201  ack |= LTM9100_adc_read(i2c_address, LTM_9100_ADIN_I_REG, &data);
202  ack |= LTM9100_adc_read(i2c_address, LTM_9100_ADIN2_G_REG, &data);
203  Serial.println("");
204 
205  count = Serial.readBytes(anykey, 1); //default timeout is 1000 milliseconds. Change via the setTimeout method of Serial.
206  }
207 
208  return ack;
209 }
210 
211 // Check if user_register is a valid register for the LTM9100.
212 boolean valid_register(uint8_t user_register, uint8_t register_array[], uint8_t array_length)
213 {
214  uint8_t i=0;
215  for (i=0; i<array_length; i++)
216  {
217  if (register_array[i] == user_register)
218  {
219  return true;
220  }
221  }
222  return false;
223 }
uint8_t i2c_address
#define LTM_9100_SENSE_mV_PER_TICK
Definition: LTM9100.h:97
int8_t i2c_read_byte_data(uint8_t address, uint8_t command, uint8_t *value)
Read a byte of data at register specified by "command", store in "value".
Definition: LT_I2C.cpp:124
int8_t LTM9100_bit_clear(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
Clears any bit inside the LTM9100 using the standard I2C repeated start format.
Definition: LTM9100.cpp:133
Header File for Linduino Libraries and Demo Code.
float adin_gain
#define LTM_9100_ADIN_V_PER_TICK
Definition: LTM9100.h:98
int8_t LTM9100_bit_set(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
Sets any bit inside the LTM9100 using the standard I2C repeated start format.
Definition: LTM9100.cpp:120
int8_t LTM9100_bit_read(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number, uint8_t *register_data)
Read the bit specified by bit_number from the LTM9100.
Definition: LTM9100.cpp:146
#define LTM_9100_SENSE_E_REG
Definition: LTM9100.h:63
int8_t LTM9100_register_read(uint8_t i2c_address, uint8_t register_address, uint8_t *register_data)
Reads an 8-bit register from the LTM9100 using the standard repeated start format.
Definition: LTM9100.cpp:72
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
#define LTM_9100_ADIN2_V_PER_TICK
Definition: LTM9100.h:99
int8_t LTM9100_alert_read(uint8_t *register_data)
Attempts to read a byte from the I2C bus using the alert address (0xC) to ascertain pending alerts on...
Definition: LTM9100.cpp:155
float sense_resistor
uint8_t reg_read_list[10]
Definition: LTM9100.cpp:68
int8_t i2c_write_byte_data(uint8_t address, uint8_t command, uint8_t value)
Write a byte of data to register specified by "command".
Definition: LT_I2C.cpp:155
int8_t LTM9100_register_write(uint8_t i2c_address, uint8_t register_address, uint8_t register_data)
Writes to an 8-bit register inside the LTM9100 using the standard I2C repeated start format...
Definition: LTM9100.cpp:112
boolean valid_register(uint8_t user_register, uint8_t register_array[], uint8_t array_length)
Check if user_register is a valid register for the LTM9100.
Definition: LTM9100.cpp:212
float adin2_gain
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
int8_t LTM9100_continuous_read_all_registers(uint8_t i2c_address)
Read all LTM9100 registers and output to the serial console every second until a key press is detecte...
Definition: LTM9100.cpp:188
#define LTM_9100_ADIN_I_REG
Definition: LTM9100.h:67
uint8_t reg_write_list[9]
Definition: LTM9100.cpp:69
#define LTM_9100_ADIN2_G_REG
Definition: LTM9100.h:65
static int i
Definition: DC2430A.ino:184
int8_t LTM9100_print_all_registers(uint8_t i2c_address)
Read all LTM9100 registers and output to the serial console.
Definition: LTM9100.cpp:163
LTM9100: Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry.
int8_t LTM9100_adc_read(uint8_t i2c_address, uint8_t base_address, float *register_data)
Read the specified ADC value (SENSE, ADIN, ADIN2) and output in human readable format to the serial c...
Definition: LTM9100.cpp:80
int8_t i2c_read_byte(uint8_t address, uint8_t *value)
Read a byte, store in "value".
Definition: LT_I2C.cpp:93