| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

fast_telemetry.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology LTC3887 Telemetry
3 LTC3887: Power Management Solution for Application Processors
4
5 @verbatim
6
7 Demonstrates Fast Telemetry
8
9 NOTES
10 Setup:
11 Set the terminal baud rate to 115200 and select the newline terminator.
12
13 @endverbatim
14
15 http://www.linear.com/product/LTC3887
16
17
18 Copyright 2018(c) Analog Devices, Inc.
19
20 All rights reserved.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions are met:
24 - Redistributions of source code must retain the above copyright
25 notice, this list of conditions and the following disclaimer.
26 - Redistributions in binary form must reproduce the above copyright
27 notice, this list of conditions and the following disclaimer in
28 the documentation and/or other materials provided with the
29 distribution.
30 - Neither the name of Analog Devices, Inc. nor the names of its
31 contributors may be used to endorse or promote products derived
32 from this software without specific prior written permission.
33 - The use of this software may or may not infringe the patent rights
34 of one or more patent holders. This license does not release you
35 from the requirement that you obtain separate licenses from these
36 patent holders to use this software.
37 - Use of the software either in source or binary form, must be run
38 on or directly connected to an Analog Devices Inc. component.
39
40 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
41 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
42 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
43 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
44 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
46 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
47 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
49 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51
52 /*! @file
53 @ingroup LTC3887
54 */
55
56 #include <Arduino.h>
57 #include <stdint.h>
58 #include "Linduino.h"
59 #include "UserInterface.h"
60 #include "LT_I2CBus.h"
61 #include "LT_SMBusNoPec.h"
62 #include "LT_SMBusPec.h"
63 #include "LT_PMBus.h"
64
65 #define LTC3887_I2C_ADDRESS 0x4E
66 #define MFR_ADC_CONTROL 0xD8
67 #define ADC_MFR_TELEMETRY_STATUS 0xDA
68 #define MFR_REAL_TIME 0xFB
69 #define NUM_MEAS 10
70 // Global variables
71 static uint8_t ltc3887_i2c_address;
72 static LT_SMBus *smbus = new LT_SMBusNoPec();
73 static LT_PMBus *pmbus = new LT_PMBus(smbus);
74
75 //! Initialize Linduino
76 //! @return void
77 void setup()
78 {
79 Serial.begin(115200); //! Initialize the serial port to the PC
80 print_title();
81 ltc3887_i2c_address = LTC3887_I2C_ADDRESS;
82 print_prompt();
83
84 pmbus->setPage(ltc3887_i2c_address, 0);
85 pmbus->setVout(ltc3887_i2c_address, 5.0);
86 smbus->writeByte(ltc3887_i2c_address, 0xD8, 0x00); // Slow
87 }
88
89 //! Repeats Linduino loop
90 //! @return void
91 void loop()
92 {
93 uint8_t user_command;
94 uint8_t model[7];
95 uint8_t *addresses = NULL;
96 float voltage0[NUM_MEAS], voltage1[NUM_MEAS];
97 float current0[NUM_MEAS], current1[NUM_MEAS];
98 float meas[NUM_MEAS];
99 uint64_t start_time, current_time;
100 uint64_t max_time = 2^64-1; // Suspect
101 uint16_t voltage0_time[NUM_MEAS], voltage1_time[NUM_MEAS];
102 uint16_t current0_time[NUM_MEAS], current1_time[NUM_MEAS];
103 int i,j;
104 uint8_t b;
105
106 if (Serial.available()) //! Checks for user input
107 {
108 user_command = read_int(); //! Reads the user command
109 if (user_command != 'm')
110 Serial.println(user_command);
111 uint8_t b;
112
113 switch (user_command) //! Prints the appropriate submenu
114 {
115 case 0:
116 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x0D); // Fast
117 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F); // Clear status
118 start_time = micros();
119 for (i = 0; i < NUM_MEAS; i++)
120 {
121 pmbus->setPage(ltc3887_i2c_address, 0);
122 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x01) == 0);
123 current_time = micros();
124 voltage0[i] = pmbus->readVout(ltc3887_i2c_address, false);
125 voltage0_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
126 start_time = current_time;
127 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0E); // Clear remaining status
128 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x02) == 0);
129 current_time = micros();
130 current0[i] = pmbus->readIout(ltc3887_i2c_address, false);
131 current0_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
132 start_time = current_time;
133 pmbus->setPage(ltc3887_i2c_address, 1);
134 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x04) == 0);
135 current_time = micros();
136 voltage1[i] = pmbus->readVout(ltc3887_i2c_address, false);
137 voltage1_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
138 start_time = current_time;
139 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x08) == 0);
140 current_time = micros();
141 current1[i] = pmbus->readIout(ltc3887_i2c_address, false);
142 current1_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
143 start_time = current_time;
144
145 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F); // Clear status
146 }
147 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
148 delay(110);
149
150 for (i = 0; i < NUM_MEAS; i++)
151 {
152 Serial.print(voltage0_time[i]);
153 Serial.print(F("us\t"));
154 Serial.print(voltage0[i]);
155 Serial.print(F("\t"));
156 Serial.print(current0_time[i]);
157 Serial.print(F("us\t"));
158 Serial.print(current0[i]);
159 Serial.print(F("\t"));
160 Serial.print(voltage1_time[i]);
161 Serial.print(F("us\t"));
162 Serial.print(voltage1[i]);
163 Serial.print(F("\t"));
164 Serial.print(current1_time[i]);
165 Serial.print(F("us\t"));
166 Serial.println(current1[i]);
167 }
168 break;
169 case 1:
170 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F); // Clear status
171 start_time = micros();
172 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x01); // Vin
173 for (i = 0; i < NUM_MEAS; i++)
174 {
175 meas[i] = pmbus->readVin(ltc3887_i2c_address, false);
176 }
177 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
178 delay(110);
179
180 for (i = 0; i < NUM_MEAS; i++)
181 {
182 Serial.println(meas[i]);
183 }
184 break;
185 case 2:
186 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x05); // Vout0
187 pmbus->setPage(ltc3887_i2c_address, 0);
188
189 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F); // Clear status
190 start_time = micros();
191 for (i = 0; i < NUM_MEAS; i++)
192 {
193 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x01) == 0);
194 current_time = micros();
195 voltage0[i] = pmbus->readVout(ltc3887_i2c_address, false);
196 voltage0_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
197 start_time = current_time;
198 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F);
199 }
200 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
201 delay(110);
202
203 for (i = 0; i < NUM_MEAS; i++)
204 {
205 Serial.print(voltage0_time[i]);
206 Serial.print("us\t");
207 Serial.println(voltage0[i]);
208 }
209 break;
210 case 3:
211 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x09); // Vout1
212 pmbus->setPage(ltc3887_i2c_address, 1);
213
214 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F); // Clear status
215 start_time = micros();
216 for (i = 0; i < NUM_MEAS; i++)
217 {
218 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x04) == 0);
219 current_time = micros();
220 voltage1[i] = pmbus->readVout(ltc3887_i2c_address, false);
221 voltage1_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
222 start_time = current_time;
223 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F);
224 }
225 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
226 delay(110);
227
228 for (i = 0; i < NUM_MEAS; i++)
229 {
230 Serial.print(voltage1_time[i]);
231 Serial.print("us\t");
232 Serial.println(voltage1[i]);
233 }
234 break;
235 case 4:
236 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x06); // Iout0
237 pmbus->setPage(ltc3887_i2c_address, 0);
238
239 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F); // Clear status
240 start_time = micros();
241 for (i = 0; i < NUM_MEAS; i++)
242 {
243 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x02) == 0);
244 current_time = micros();
245 current0[i] = pmbus->readIout(ltc3887_i2c_address, false);
246 current0_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
247 start_time = current_time;
248 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F);
249 }
250 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
251 delay(110);
252
253 for (i = 0; i < NUM_MEAS; i++)
254 {
255 Serial.print(current0_time[i]);
256 Serial.print("us\t");
257 Serial.println(current0[i]);
258 }
259 break;
260 case 5:
261 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x0A); // Iout1
262 pmbus->setPage(ltc3887_i2c_address, 1);
263
264 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F); // Clear status
265 start_time = micros();
266 for (i = 0; i < NUM_MEAS; i++)
267 {
268 while ((smbus->readByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS) & 0x08) == 0);
269 current_time = micros();
270 current1[i] = pmbus->readIout(ltc3887_i2c_address, false);
271 current1_time[i] = current_time > start_time ? current_time - start_time : max_time - start_time + current_time;
272 start_time = current_time;
273 smbus->writeByte(ltc3887_i2c_address, ADC_MFR_TELEMETRY_STATUS, 0x0F);
274 }
275 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
276 delay(110);
277
278 for (i = 0; i < NUM_MEAS; i++)
279 {
280 Serial.print(current1_time[i]);
281 Serial.print("us\t");
282 Serial.println(current1[i]);
283 }
284 break;
285 case 6:
286 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x08); // Temp Ext 0
287 pmbus->setPage(ltc3887_i2c_address, 0);
288 for (i = 0; i < NUM_MEAS; i++)
289 {
290 meas[i] = pmbus->readExternalTemperature(ltc3887_i2c_address, false);
291 }
292 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
293
294 for (i = 0; i < NUM_MEAS; i++)
295 {
296 Serial.println(meas[i]);
297 }
298 break;
299 case 7:
300 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x0C); // Temp Ext 1
301 pmbus->setPage(ltc3887_i2c_address, 1);
302 for (i = 0; i < NUM_MEAS; i++)
303 {
304 meas[i] = pmbus->readExternalTemperature(ltc3887_i2c_address, false);
305 }
306 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
307 delay(110);
308
309 for (i = 0; i < NUM_MEAS; i++)
310 {
311 Serial.println(meas[i]);
312 }
313 break;
314 case 8:
315 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x04); // Temp Int
316 for (i = 0; i < NUM_MEAS; i++)
317 {
318 meas[i] = pmbus->readInternalTemperature(ltc3887_i2c_address, false);
319 }
320 smbus->writeByte(ltc3887_i2c_address, MFR_ADC_CONTROL, 0x00); // Standard
321 delay(110);
322
323 for (i = 0; i < NUM_MEAS; i++)
324 {
325 Serial.println(meas[i]);
326 }
327 break;
328 case 9:
329 addresses = smbus->probe(0);
330 while (*addresses != 0)
331 {
332 Serial.print(F("ADDR 0x"));
333 Serial.println(*addresses++, HEX);
334 }
335 break;
336 default:
337 Serial.println("Incorrect Option");
338 break;
339 }
340 print_prompt();
341 }
342 }
343
344 // Function Definitions
345
346 //! Prints the title block when program first starts.
347 //! @return void
348 void print_title()
349 {
350 Serial.print(F("\n***************************************************************\n"));
351 Serial.print(F("* LTC3887 Fast Telemetry Program *\n"));
352 Serial.print(F("* *\n"));
353 Serial.print(F("* This program demonstrates how program fast telemetry *\n"));
354 Serial.print(F("* *\n"));
355 Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
356 Serial.print(F("* *\n"));
357 Serial.print(F("*****************************************************************\n"));
358 }
359
360 //! Prints main menu.
361 //! @return void
362 void print_prompt()
363 {
364 Serial.print(F("\n 0-Loop Fast Out\n"));
365 Serial.print(F(" 1-Loop Fast Vin 0\n"));
366 Serial.print(F(" 2-Loop Fast Vout 0\n"));
367 Serial.print(F(" 3-Loop Fast Vout 1\n"));
368 Serial.print(F(" 4-Loop Fast Iout 0\n"));
369 Serial.print(F(" 5-Loop Fast Iout 1\n"));
370 Serial.print(F(" 6-Loop Fast Temp Ext 0\n"));
371 Serial.print(F(" 7-Loop Fast Temp Ext 1\n"));
372 Serial.print(F(" 8-Loop Fast Temp Int\n"));
373 Serial.print(F(" 9-Bus Probe\n"));
374 Serial.print(F("\nEnter a command:"));
375 }
376
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
LT_SMBusPec.h
LTC SMBus Support: Implementation for a shared SMBus layer.
Linduino.h
Header File for Linduino Libraries and Demo Code.
LT_SMBusNoPec
Definition: LT_SMBusNoPec.h:60
LT_PMBus::readIout
float readIout(uint8_t address, bool polling)
Get the measured output current.
Definition: LT_PMBus.cpp:1898
print_prompt
static void print_prompt()
Prints main menu.
Definition: fast_telemetry.ino:362
ltc3887_i2c_address
static uint8_t ltc3887_i2c_address
Definition: fast_telemetry.ino:71
LT_SMBus
Definition: LT_SMBus.h:61
LT_PMBus::readVout
float readVout(uint8_t address, bool polling)
Get the measured output voltage.
Definition: LT_PMBus.cpp:1598
LT_I2CBus.h
LT_I2CBus: Routines to communicate to I2C by Wire Library.
setup
static void setup()
Initialize Linduino.
Definition: fast_telemetry.ino:77
print_title
static void print_title()
Prints the title block when program first starts.
Definition: fast_telemetry.ino:348
LT_SMBus::writeByte
virtual void writeByte(uint8_t address, uint8_t command, uint8_t data)=0
SMBus write byte command.
LT_SMBus::readByte
virtual uint8_t readByte(uint8_t address, uint8_t command)=0
SMBus read byte command.
LT_PMBus::setPage
void setPage(uint8_t address, uint8_t page)
Set the page.
Definition: LT_PMBus.cpp:3156
loop
static void loop()
Repeats Linduino loop.
Definition: fast_telemetry.ino:91
LT_PMBus::readExternalTemperature
float readExternalTemperature(uint8_t address, bool polling)
Get the measured external temperature.
Definition: LT_PMBus.cpp:2052
smbus
static LT_SMBus * smbus
Definition: fast_telemetry.ino:72
LT_SMBus::probe
virtual uint8_t * probe(uint8_t command)=0
SMBus bus probe.
LT_PMBus::readInternalTemperature
float readInternalTemperature(uint8_t address, bool polling)
Get the measured internal temperature.
Definition: LT_PMBus.cpp:2077
LT_SMBusNoPec.h
LTC SMBus Support: Implementation for a shared SMBus layer.
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
LT_PMBus::readVin
float readVin(uint8_t address, bool polling)
Get the input voltage.
Definition: LT_PMBus.cpp:1487
LT_PMBus::setVout
void setVout(uint8_t address, float voltage)
Set output voltage.
Definition: LT_PMBus.cpp:239
pmbus
static LT_PMBus * pmbus
Definition: fast_telemetry.ino:73
MFR_ADC_CONTROL
#define MFR_ADC_CONTROL
Definition: fast_telemetry.ino:66
LT_PMBus.h
LTC PMBus Support.
ADC_MFR_TELEMETRY_STATUS
#define ADC_MFR_TELEMETRY_STATUS
Definition: fast_telemetry.ino:67
i
static int i
Definition: DC2430A.ino:184
NUM_MEAS
#define NUM_MEAS
Definition: fast_telemetry.ino:69
LTC3887_I2C_ADDRESS
#define LTC3887_I2C_ADDRESS
Definition: fast_telemetry.ino:65
LT_PMBus
PMBus communication.
Definition: LT_PMBus.h:370