| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC2467.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC2467 Demonstration Board (Linduino Shield)
3
4 LTC2970: Dual I2C Power Supply Monitor and Margining Controller
5
6 @verbatim
7 Setup:
8 Set the terminal baud rate to 115200 and select the newline terminator.
9
10 @endverbatim
11
12 http://www.linear.com/product/LTC2970
13
14 http://www.linear.com/demo/#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 /*! @file
52 @ingroup LTC2970
53 */
54
55 #include <Arduino.h>
56 #include <stdint.h>
57 #include "Linduino.h"
58 #include "UserInterface.h"
59 #include "LT_SMBusNoPec.h"
60 #include "LTC2970.h"
61
62 #define LTC2970_I2C_ADDRESS 0x5B //global 7-bit address
63 //#define LTC2970_I2C_ADDRESS 0x5C //SLAVE_LL 7-bit address
64 //#define LTC2970_I2C_ADDRESS 0x6F //SLAVE_HH 7-bit address
65
66
67 /****************************************************************************/
68 // Global variables
69 static uint8_t ltc2970_i2c_address;
70
71 static LT_SMBusNoPec *smbus = new LT_SMBusNoPec(400000);
72
73 // variables used for keeping track of the LTC2970 state
74 uint16_t servo0_value_low;
75 uint16_t servo0_value_hi;
76 uint16_t servo0_value_nom;
77 uint16_t servo1_value_low;
78 uint16_t servo1_value_hi;
79 uint16_t servo1_value_nom;
80
81 /****************************************************************************/
82 //! Initialize Linduino
83 //! @return void
84 void setup()
85 {
86
87 // NOTE: we do NOT initialize the LTC2970 here (though we could with the ltc2970_configure() function)
88 // Assume that there might be another bus master talking to it on the I2C bus.
89
90 // initialize the i2c port
91 Serial.begin(115200); //! Initialize the serial port to the PC
92 print_title();
93 print_prompt();
94
95 ltc2970_i2c_address = LTC2970_I2C_ADDRESS;
96
97 servo0_value_nom = 0x2710; // 5.0V
98 servo1_value_nom = 0x0F9C; // 2.0V -> -5.0V
99 servo0_value_low = 0x2328; // 10% low
100 servo1_value_low = 0x0ED4; // 10% low
101 servo0_value_hi = 0x2AF8; // 10% high
102 servo1_value_hi = 0x1063; // 10% high
103
104 }
105
106 //! Main Linduino loop
107 //! @return void
108 void loop()
109 {
110 uint8_t user_command;
111 uint16_t return_val;
112
113 if (Serial.available()) //! Checks for user input
114 {
115 user_command = read_int(); //! Reads the user command
116
117 switch (user_command) //! Prints the appropriate submenu
118 {
119
120 case 1 :
121 Serial.print(F("\n****INITIALIZING THE LTC2970****\n"));
122 ltc2970_configure();
123 break;
124
125 case 2 :
126 Serial.print(F("\n****ENABLE LTC2970 CHANNEL 0 AND CHANNEL 1****\n"));
127 ltc2970_dac_disconnect(smbus, ltc2970_i2c_address, 0);
128 ltc2970_gpio_up(smbus, ltc2970_i2c_address, 0);
129
130 ltc2970_dac_disconnect(smbus, ltc2970_i2c_address, 1);
131 ltc2970_gpio_up(smbus, ltc2970_i2c_address, 1);
132 break;
133
134 case 3 :
135 Serial.print(F("\n****SOFT CONNECT LTC2970 DAC0 and DAC1****\n"));
136 ltc2970_soft_connect_dac(smbus, ltc2970_i2c_address, 0);
137 ltc2970_soft_connect_dac(smbus, ltc2970_i2c_address, 1);
138 break;
139
140 case 4 :
141 Serial.print(F("\n****SERVO CHANNEL 0 and 1 VOLTAGES 10% LOW****\n"));
142 ltc2970_servo_to_adc_val(smbus, ltc2970_i2c_address, 0, servo0_value_low);
143 ltc2970_servo_to_adc_val(smbus, ltc2970_i2c_address, 1, servo1_value_low);
144 break;
145
146 case 5 :
147 Serial.print(F("\n****SERVO CHANNEL 0 and 1 VOLTAGES TO NOMINAL****\n"));
148 ltc2970_servo_to_adc_val(smbus, ltc2970_i2c_address, 0, servo0_value_nom);
149 ltc2970_servo_to_adc_val(smbus, ltc2970_i2c_address, 1, servo1_value_nom);
150 break;
151
152 case 6 :
153 Serial.print(F("\n****SERVO CHANNEL 0 and 1 VOLTAGES 10% HIGH****\n"));
154 ltc2970_servo_to_adc_val(smbus, ltc2970_i2c_address, 0, servo0_value_hi);
155 ltc2970_servo_to_adc_val(smbus, ltc2970_i2c_address, 1, servo1_value_hi);
156 break;
157
158 case 7 :
159 Serial.print(F("\n****ADC CH_0 VOLTAGE (HEX VALUE)\n"));
160 return_val = smbus->readWord(ltc2970_i2c_address,LTC2970_CH0_A_ADC);
161 Serial.print(((return_val & 0x7FFF)*500e-6), DEC);
162 Serial.print(F("\t(0x"));
163 Serial.print(return_val, HEX);
164 Serial.println(F(")"));
165
166 Serial.print(F("\n****ADC CH_1 VOLTAGE (HEX VALUE)\n"));
167 return_val = smbus->readWord(ltc2970_i2c_address,LTC2970_CH1_A_ADC);
168 // interpret the hex code as a negative voltage
169 Serial.print(5.035 - 5.025*((return_val & 0x7FFF)*500e-6), DEC);
170 Serial.print(F("\t(0x"));
171 Serial.print(return_val, HEX);
172 Serial.println(F(")"));
173
174 Serial.print(F("\n****ADC CH_0 CURRENT (HEX VALUE)\n"));
175 return_val = smbus->readWord(ltc2970_i2c_address,LTC2970_CH0_B_ADC);
176 // interpret the hex value as a current through the sense resistor
177 // 0.02 ohms adjusted for inaccuracies
178 Serial.print((((return_val & 0x7FFF)*500e-6)/0.0215), DEC);
179 Serial.print(F("\t(0x"));
180 Serial.print(return_val, HEX);
181 Serial.println(F(")"));
182
183 Serial.print(F("\n****ADC CH_1 CURRENT (HEX VALUE)\n"));
184 return_val = smbus->readWord(ltc2970_i2c_address,LTC2970_CH1_B_ADC);
185 // filter out negative values to avoid confusion
186 return_val = ((return_val & 0x4000) == 0x4000) ? 0x0000 : return_val;
187 // hex voltage is 1V/A, so no interpretation necessary
188 Serial.print((0.965*(return_val & 0x7FFF)*500e-6), DEC);
189 Serial.print(F("\t(0x"));
190 Serial.print(return_val, HEX);
191 Serial.println(F(")"));
192 break;
193
194 case 8 :
195 Serial.print(F("\n****PRINT FAULTS, CLEAR LATCHED FAULTS \n"));
196 ltc2970_read_faults(smbus, ltc2970_i2c_address);
197 break;
198
199 case 9 :
200 Serial.print(F("\n****PRINT DIE TEMPERATURE \n"));
201 ltc2970_print_die_temp (smbus, ltc2970_i2c_address);
202 break;
203
204 default:
205 Serial.println(F("Incorrect Option"));
206 break;
207 }
208 print_prompt();
209 }
210 }
211
212
213 /************************************************************************/
214 // Function Definitions
215
216 //! Prints the title block when program first starts.
217 //! @return void
218 void print_title()
219 {
220 Serial.print(F("\n***************************************************************\n"));
221 Serial.print(F("* DC2467 Control Program *\n"));
222 Serial.print(F("* *\n"));
223 Serial.print(F("* This program provides a simple interface to control the *\n"));
224 Serial.print(F("* the DC2467 regulators through the LTC2970 *\n"));
225 Serial.print(F("* REQUIRES +12V POWER TO THE LINDUINO *\n"));
226 Serial.print(F("* *\n"));
227 Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
228 Serial.print(F("* *\n"));
229 Serial.print(F("*****************************************************************\n"));
230 }
231
232 //! Prints main menu.
233 //! @return void
234 void print_prompt()
235 {
236 Serial.print(F("\n"));
237 Serial.print(F(" 1 - Reset the LTC2970, Disable Regulators\n"));
238 Serial.print(F(" 2 - Enable Channel 0 and Channel 1; DACs disconnected\n"));
239 Serial.print(F(" 3 - Soft-Connect DAC0 and DAC1, and Confirm Connection\n"));
240 Serial.print(F(" 4 - Servo Channel 0 and Channel 1 Voltages 10% low\n"));
241 Serial.print(F(" 5 - Servo Channel 0 and Channel 1 Voltages to nominal\n"));
242 Serial.print(F(" 6 - Servo Channel 0 and Channel 1 Voltages 10% high\n"));
243 Serial.print(F(" 7 - Print Channel 0 & 1 Voltages and Currents\n"));
244 Serial.print(F(" 8 - Print Fault Register Contents\n"));
245 Serial.print(F(" 9 - Print LTC2970 Temperature\n"));
246 Serial.print(F("\nEnter a command number:"));
247 }
248
249
250 //! Writes configuration values to the LTC2970 registers
251 //! @return void
252 void ltc2970_configure()
253 {
254 //configure all of the LTC2970 registers for this application
255 // use SMbus commands
256 smbus->writeWord(ltc2970_i2c_address, LTC2970_FAULT_EN, 0x0DEF);
257 smbus->writeWord(ltc2970_i2c_address, LTC2970_IO, 0x00CA);
258 smbus->writeWord(ltc2970_i2c_address, LTC2970_ADC_MON, 0x007F);
259 smbus->writeWord(ltc2970_i2c_address, LTC2970_VDD_OV, 0x2CEC);
260 smbus->writeWord(ltc2970_i2c_address, LTC2970_VDD_UV, 0x2328);
261 smbus->writeWord(ltc2970_i2c_address, LTC2970_V12_OV, 0x0FA0);
262 smbus->writeWord(ltc2970_i2c_address, LTC2970_V12_UV, 0x0A6B);
263
264 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH0_A_OV, 0x2AF8);
265 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH0_A_UV, 0x2328);
266 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH0_A_SERVO, 0x2710);
267 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH0_A_IDAC, 0x0880); // IDAC set by the servo
268 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH0_B_OV, 0x0078);
269 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH0_B_UV, 0x7FD8);
270
271 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH1_A_OV, 0x1068);
272 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH1_A_UV, 0x0BB8);
273 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH1_A_SERVO, 0x0FA0); // 0x0F88 is servo to -5V
274 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH1_A_IDAC, 0x0480); // IDAC set by the servo
275 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH1_B_OV, 0x0960);
276 smbus->writeWord(ltc2970_i2c_address, LTC2970_CH1_B_UV, 0x7F38);
277 }
278
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
LTC2970_CH1_A_SERVO
#define LTC2970_CH1_A_SERVO
Definition: LTC2970.h:128
LT_SMBusBase::writeWord
void writeWord(uint8_t address, uint8_t command, uint16_t data)
SMBus write word command.
Definition: LT_SMBusBase.cpp:265
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC2467.ino:234
LTC2970_CH1_A_OV
#define LTC2970_CH1_A_OV
Definition: LTC2970.h:126
LTC2970_CH1_B_OV
#define LTC2970_CH1_B_OV
Definition: LTC2970.h:136
setup
static void setup()
Initialize Linduino.
Definition: DC2467.ino:84
LTC2970_CH1_A_UV
#define LTC2970_CH1_A_UV
Definition: LTC2970.h:127
Linduino.h
Header File for Linduino Libraries and Demo Code.
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC2467.ino:218
LT_SMBusNoPec
Definition: LT_SMBusNoPec.h:60
LTC2970_CH1_B_UV
#define LTC2970_CH1_B_UV
Definition: LTC2970.h:137
LTC2970_CH0_A_SERVO
#define LTC2970_CH0_A_SERVO
Definition: LTC2970.h:114
LTC2970_V12_OV
#define LTC2970_V12_OV
Definition: LTC2970.h:106
LTC2970_VDD_OV
#define LTC2970_VDD_OV
Definition: LTC2970.h:100
ltc2970_print_die_temp
void ltc2970_print_die_temp(LT_SMBus *smbus, uint8_t ltc2970_i2c_address)
Prints die temperature on the LTC2970.
Definition: LTC2970.cpp:265
ltc2970_read_faults
void ltc2970_read_faults(LT_SMBus *smbus, uint8_t ltc2970_i2c_address)
Read FAULT, FAULT_LA, and FAULT_LA_INDEX registers print the results.
Definition: LTC2970.cpp:289
LTC2970_CH0_B_ADC
#define LTC2970_CH0_B_ADC
Definition: LTC2970.h:119
LTC2970_ADC_MON
#define LTC2970_ADC_MON
Definition: LTC2970.h:91
LTC2970_VDD_UV
#define LTC2970_VDD_UV
Definition: LTC2970.h:101
LTC2970_CH0_A_ADC
#define LTC2970_CH0_A_ADC
Definition: LTC2970.h:111
smbus
static LT_SMBusNoPec * smbus
Definition: DC2467.ino:71
ltc2970_i2c_address
static uint8_t ltc2970_i2c_address
Definition: DC2467.ino:69
servo1_value_hi
static uint16_t servo1_value_hi
Definition: DC2467.ino:78
LTC2970_CH0_A_OV
#define LTC2970_CH0_A_OV
Definition: LTC2970.h:112
ltc2970_dac_disconnect
void ltc2970_dac_disconnect(LT_SMBus *smbus, uint8_t ltc2970_i2c_address, int dac_number)
Disconnect a DAC from its channel.
Definition: LTC2970.cpp:51
LTC2970_I2C_ADDRESS
#define LTC2970_I2C_ADDRESS
Definition: DC2467.ino:62
ltc2970_servo_to_adc_val
void ltc2970_servo_to_adc_val(LT_SMBus *smbus, uint8_t ltc2970_i2c_address, int channel_number, uint16_t code)
Servo once to a given ADC value.
Definition: LTC2970.cpp:227
LTC2970_CH0_A_IDAC
#define LTC2970_CH0_A_IDAC
Definition: LTC2970.h:115
LT_SMBusNoPec.h
LTC SMBus Support: Implementation for a shared SMBus layer.
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
servo0_value_low
static uint16_t servo0_value_low
Definition: DC2467.ino:74
LTC2970_CH0_B_UV
#define LTC2970_CH0_B_UV
Definition: LTC2970.h:121
LTC2970_IO
#define LTC2970_IO
Definition: LTC2970.h:90
LTC2970_CH0_B_OV
#define LTC2970_CH0_B_OV
Definition: LTC2970.h:120
LTC2970.h
Header for LTC2970: Dual I2C Power Supply Monitor and Margining Controller.
ltc2970_configure
static void ltc2970_configure()
Writes configuration values to the LTC2970 registers.
Definition: DC2467.ino:252
servo1_value_nom
static uint16_t servo1_value_nom
Definition: DC2467.ino:79
ltc2970_soft_connect_dac
int ltc2970_soft_connect_dac(LT_SMBus *smbus, uint8_t ltc2970_i2c_address, int dac_number)
soft-connect DACn to its controlled node
Definition: LTC2970.cpp:114
servo0_value_nom
static uint16_t servo0_value_nom
Definition: DC2467.ino:76
LTC2970_CH1_B_ADC
#define LTC2970_CH1_B_ADC
Definition: LTC2970.h:135
servo0_value_hi
static uint16_t servo0_value_hi
Definition: DC2467.ino:75
servo1_value_low
static uint16_t servo1_value_low
Definition: DC2467.ino:77
LTC2970_V12_UV
#define LTC2970_V12_UV
Definition: LTC2970.h:107
LTC2970_CH1_A_IDAC
#define LTC2970_CH1_A_IDAC
Definition: LTC2970.h:129
loop
static void loop()
Main Linduino loop.
Definition: DC2467.ino:108
LTC2970_CH1_A_ADC
#define LTC2970_CH1_A_ADC
Definition: LTC2970.h:125
LTC2970_FAULT_EN
#define LTC2970_FAULT_EN
Definition: LTC2970.h:83
ltc2970_gpio_up
void ltc2970_gpio_up(LT_SMBus *smbus, uint8_t ltc2970_i2c_address, int gpio_number)
Set GPIO_n high.
Definition: LTC2970.cpp:5
LTC2970_CH0_A_UV
#define LTC2970_CH0_A_UV
Definition: LTC2970.h:113
LT_SMBusBase::readWord
uint16_t readWord(uint8_t address, uint8_t command)
SMBus read word command.
Definition: LT_SMBusBase.cpp:301