| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC1978.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1978A Demonstration System (2-Board Set)
3 DC1809 - LTC2974 Board (manager)
4 DC1810 - LTM4620 Board (4 rails)
5
6 @verbatim
7
8 NOTES
9 Setup:
10 Set the terminal baud rate to 115200 and select the newline terminator.
11
12 @endverbatim
13
14 http://www.linear.com/product/LTC2974
15
16 http://www.linear.com/demo/DC1978
17
18
19 Copyright 2018(c) Analog Devices, Inc.
20
21 All rights reserved.
22
23 Redistribution and use in source and binary forms, with or without
24 modification, are permitted provided that the following conditions are met:
25 - Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 - Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 - Neither the name of Analog Devices, Inc. nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34 - The use of this software may or may not infringe the patent rights
35 of one or more patent holders. This license does not release you
36 from the requirement that you obtain separate licenses from these
37 patent holders to use this software.
38 - Use of the software either in source or binary form, must be run
39 on or directly connected to an Analog Devices Inc. component.
40
41 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
42 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
43 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
45 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
47 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
48 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 */
52
53 /*! @file
54 @ingroup LTC2974
55 */
56
57 #include <Arduino.h>
58 #include <stdint.h>
59 #include "Linduino.h"
60 #include "UserInterface.h"
61 #include "LT_I2CBus.h"
62 #include "LT_SMBusNoPec.h"
63 #include "LT_SMBusPec.h"
64 #include "LT_PMBusMath.h"
65 #include "LT_PMBus.h"
66
67 #define LTC2974_I2C_ADDRESS 0x5C
68
69 // Global variables
70 static uint8_t ltc2974_i2c_address;
71 static LT_PMBusMath *math = new LT_PMBusMath();
72 static LT_SMBus *smbus = new LT_SMBusPec();
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 ltc2974_i2c_address = LTC2974_I2C_ADDRESS;
82 print_prompt();
83 }
84
85 //! Repeats Linduino loop
86 //! @return void
87 void loop()
88 {
89 uint8_t user_command;
90 uint8_t res;
91 uint8_t model[7];
92 uint8_t revision[10];
93 uint8_t *addresses = NULL;
94
95 if (Serial.available()) //! Checks for user input
96 {
97 user_command = read_int(); //! Reads the user command
98 if (user_command != 'm')
99 Serial.println(user_command);
100
101 switch (user_command) //! Prints the appropriate submenu
102 {
103 case 1:
104 menu_1_basic_commands(); // Print single-ended voltage menu
105 break;
106 case 2:
107 menu_2_vid_commands(); // Print VID menu
108 break;
109 case 3:
110 menu_3_vid_commands(); // Print VID menu
111 break;
112 case 4:
113 pmbus->enablePec(ltc2974_i2c_address);
114 delete smbus;
115 delete pmbus;
116 smbus = new LT_SMBusPec();
117 pmbus = new LT_PMBus(smbus);
118 break;
119 case 5:
120 pmbus->disablePec(ltc2974_i2c_address);
121 delete smbus;
122 delete pmbus;
123 smbus = new LT_SMBusNoPec();
124 pmbus = new LT_PMBus(smbus);
125 break;
126 case 6:
127 addresses = smbus->probe(0);
128 while (*addresses != 0)
129 {
130 Serial.print(F("ADDR 0x"));
131 Serial.println(*addresses++, HEX);
132 }
133 break;
134 case 7 :
135 pmbus->startGroupProtocol();
136 pmbus->restoreFromNvm(ltc2974_i2c_address);
137 pmbus->executeGroupProtocol();
138 break;
139 default:
140 Serial.println(F("Incorrect Option"));
141 break;
142 }
143 print_prompt();
144 }
145
146 }
147
148 // Function Definitions
149
150 //! Prints the title block when program first starts.
151 //! @return void
152 void print_title()
153 {
154 Serial.print(F("\n*****************************************************************\n"));
155 Serial.print(F("* DC1978A Hello World Demonstration Program *\n"));
156 Serial.print(F("* *\n"));
157 Serial.print(F("* This program demonstrates how to send and receive data from *\n"));
158 Serial.print(F("* the LTC2974 on the demo board. *\n"));
159 Serial.print(F("* *\n"));
160 Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
161 Serial.print(F("* *\n"));
162 Serial.print(F("*****************************************************************\n"));
163 }
164
165 //! Prints main menu.
166 //! @return void
167 void print_prompt()
168 {
169 Serial.print(F("\n 1-Basic Commands\n"));
170 Serial.print(F(" 2-VID Commands (L16)\n"));
171 Serial.print(F(" 3-VID Commands (float) \n"));
172 Serial.print(F(" 4-PEC On\n"));
173 Serial.print(F(" 5-PEC Off\n"));
174 Serial.print(F(" 6-Bus Probe\n"));
175 Serial.print(F(" 7-Reset\n"));
176 Serial.print(F("\nEnter a command:"));
177 }
178
179 //! Prints a warning if the demo board is not detected.
180 //! @return void
181 void print_warning_prompt()
182 {
183 Serial.println(F("\nWarning: Demo board not detected. Linduino will attempt to proceed."));
184 }
185
186 //! Prints all voltages
187 //! @return void
188 void print_all_voltages()
189 {
190 float voltage;
191 uint8_t page;
192
193 for (page = 0; page < 4; page++)
194 {
195 pmbus->setPage(ltc2974_i2c_address, page);
196 voltage = pmbus->readVout(ltc2974_i2c_address, false);
197 Serial.print(F("LTC2974 VOUT "));
198 Serial.println(voltage, DEC);
199 }
200 }
201
202 //! Prints all currents
203 //! @return void
204 void print_all_currents()
205 {
206 float current;
207 uint8_t page;
208
209 for (page = 0; page < 4; page++)
210 {
211 pmbus->setPage(ltc2974_i2c_address, page);
212 current = pmbus->readIout(ltc2974_i2c_address, false);
213 Serial.print(F("LTC2974 IOUT "));
214 Serial.println(current, DEC);
215 }
216 }
217
218 //! Prints all status bytes and words
219 //! @return void
220 void print_all_status()
221 {
222 uint8_t b;
223 uint16_t w;
224 uint8_t page;
225
226 for (page = 0; page < 4; page++)
227 {
228 Serial.print(F("PAGE "));
229 Serial.println(page, DEC);
230 pmbus->setPage(ltc2974_i2c_address, page);
231 b = pmbus->readStatusByte(ltc2974_i2c_address);
232 Serial.print(F("LTC2974 STATUS BYTE 0x"));
233 Serial.println(b, HEX);
234 w = pmbus->readStatusWord(ltc2974_i2c_address);
235 Serial.print(F("LTC2974 STATUS WORD 0x"));
236 Serial.println(w, HEX);
237 }
238 }
239
240 // Sequence off then on
241 //! @return void
242 void sequence_off_on()
243 {
244 pmbus->sequenceOffGlobal();
245 delay (2000);
246 pmbus->sequenceOnGlobal();
247 }
248
249 //! Margin high
250 //! @return void
251 void margin_high()
252 {
253 pmbus->marginHighGlobal();
254 }
255
256 //! Margin low
257 //! @return void
258 void margin_low()
259 {
260 pmbus->marginLowGlobal();
261 }
262
263 //! Go to nominal
264 //! @return void
265 void margin_off()
266 {
267 pmbus->sequenceOnGlobal();
268 }
269
270 void increment_page()
271 {
272 uint8_t reg_page;
273 reg_page = smbus->readByte (ltc2974_i2c_address, 0x00); // Read current page number
274 reg_page = (reg_page < 0x02) ? reg_page + 0x01 : 0x00 ;
275 smbus->writeByte (ltc2974_i2c_address, 0x00, reg_page); // Write current page number
276 reg_page = smbus->readByte (ltc2974_i2c_address, 0x00); // Read current page number
277 Serial.print(F("LTC2974 PAGE SET TO : "));
278 Serial.println(reg_page, HEX);
279
280 }
281
282 //! Display menu 1
283 //! @return void
284 void menu_1_basic_commands()
285 {
286 uint8_t user_command;
287
288 do
289 {
290 //! Displays the Read/Write menu
291 Serial.print(F(" 1-Read All Voltages\n"));
292 Serial.print(F(" 2-Read All Currents\n"));
293 Serial.print(F(" 3-Read All Status\n"));
294 Serial.print(F(" 4-Sequence Off/On\n"));
295 Serial.print(F(" 5-Margin High\n"));
296 Serial.print(F(" 6-Margin Low\n"));
297 Serial.print(F(" 7-Margin Off\n"));
298 Serial.print(F(" 8-Increment Page Number\n"));
299 Serial.print(F(" m-Main Menu\n"));
300 Serial.print(F("\nEnter a command: "));
301
302 user_command = read_int(); //! Reads the user command
303 if (user_command == 'm') // Print m if it is entered
304 {
305 Serial.print(F("m\n"));
306 }
307 else
308 Serial.println(user_command); // Print user command
309
310 switch (user_command)
311 {
312 case 1:
313 print_all_voltages();
314 break;
315 case 2:
316 print_all_currents();
317 break;
318 case 3:
319 print_all_status();
320 break;
321 case 4:
322 sequence_off_on();
323 break;
324 case 5:
325 margin_high();
326 break;
327 case 6:
328 margin_low();
329 break;
330 case 7:
331 margin_off();
332 break;
333 case 8:
334 increment_page();
335 break;
336 default:
337 if (user_command != 'm')
338 Serial.println(F("Invalid Selection"));
339 break;
340 }
341 }
342 while (user_command != 'm');
343 }
344
345 //! Display menu 2
346 //! @return void
347 void menu_2_vid_commands()
348 {
349 uint8_t user_command;
350 uint16_t vcode;
351 float voltage;
352
353 voltage = pmbus->readVout(ltc2974_i2c_address, false);
354 vcode = math->float_to_lin16 (voltage, 0x13);
355
356 do
357 {
358 //! Displays the Read/Write menu
359 Serial.print(F(" 1-VID UP 40 LSB\n"));
360 Serial.print(F(" 2-VID DN 40 LSB\n"));
361 Serial.print(F(" m-Main Menu\n"));
362 Serial.print(F("\nEnter a command: "));
363
364 user_command = read_int(); //! Reads the user command
365 if (user_command == 'm') // Print m if it is entered
366 {
367 Serial.print(F("m\n"));
368 }
369 else
370 Serial.println(user_command); // Print user command
371
372 switch (user_command)
373 {
374 case 1:
375 vcode += 40;
376 smbus->writeWord (ltc2974_i2c_address, 0x21, vcode);
377 Serial.print(F("LTC2974 VOUT Code "));
378 Serial.println(vcode, HEX);
379 delay (1000);
380 voltage = pmbus->readVout(ltc2974_i2c_address, false);
381 Serial.print(F("LTC2974 VOUT Telemetry "));
382 Serial.println(voltage, DEC);
383 break;
384 case 2:
385 vcode -= 40;
386 smbus->writeWord (ltc2974_i2c_address, 0x21, vcode);
387 Serial.print(F("LTC2974 VOUT Code "));
388 Serial.println(vcode, HEX);
389 delay (1000);
390 voltage = pmbus->readVout(ltc2974_i2c_address, false);
391 Serial.print(F("LTC2974 VOUT Telemetry "));
392 Serial.println(voltage, DEC);
393 Serial.print(F("\n"));
394 break;
395 default:
396 if (user_command != 'm')
397 Serial.println(F("Invalid Selection"));
398 break;
399 }
400 }
401 while (user_command != 'm');
402 }
403
404 //! Display menu 3
405 void menu_3_vid_commands()
406 {
407 uint8_t user_command;
408 float vid_value;
409 float voltage;
410
411 vid_value = pmbus->readVout(ltc2974_i2c_address, false);
412
413 do
414 {
415 //! Displays the Read/Write menu
416 Serial.print(F(" 1-VID UP 4mV\n"));
417 Serial.print(F(" 2-VID DN 4mV\n"));
418 Serial.print(F(" m-Main Menu\n"));
419 Serial.print(F("\nEnter a command: "));
420
421 user_command = read_int(); //! Reads the user command
422 if (user_command == 'm') // Print m if it is entered
423 {
424 Serial.print(F("m\n"));
425 }
426 else
427 Serial.println(user_command); // Print user command
428
429 switch (user_command)
430 {
431 case 1:
432 vid_value += 0.004;
433 pmbus->setVout (ltc2974_i2c_address, vid_value);
434 Serial.print(F("LTC2974 VOUT "));
435 Serial.println(vid_value, DEC);
436 delay (1000);
437 voltage = pmbus->readVout(ltc2974_i2c_address, false);
438 Serial.print(F("LTC2974 VOUT Telemetry "));
439 Serial.println(voltage, DEC);
440 break;
441 case 2:
442 vid_value -= 0.004;
443 pmbus->setVout (ltc2974_i2c_address, vid_value);
444 Serial.print(F("LTC2974 VOUT "));
445 Serial.println(vid_value, DEC);
446 delay (1000);
447 voltage = pmbus->readVout(ltc2974_i2c_address, false);
448 Serial.print(F("LTC2974 VOUT Telemetry "));
449 Serial.println(voltage, DEC);
450 Serial.print(F("\n"));
451 break;
452 default:
453 if (user_command != 'm')
454 Serial.println(F("Invalid Selection"));
455 break;
456 }
457 }
458 while (user_command != 'm');
459 }
460
ltc2974_i2c_address
static uint8_t ltc2974_i2c_address
Definition: DC1978.ino:70
sequence_off_on
static void sequence_off_on()
Definition: DC1978.ino:242
LT_PMBusMath::float_to_lin16
lin16_t float_to_lin16(float xin, lin16m_t vout_mode)
Definition: LT_PMBusMath.cpp:451
menu_1_basic_commands
static void menu_1_basic_commands()
Display menu 1.
Definition: DC1978.ino:284
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
pmbus
static LT_PMBus * pmbus
Definition: DC1978.ino:73
LT_SMBusPec.h
LTC SMBus Support: Implementation for a shared SMBus layer.
LT_PMBus::readStatusByte
uint8_t readStatusByte(uint8_t address)
Get the status byte.
Definition: LT_PMBus.cpp:2423
Linduino.h
Header File for Linduino Libraries and Demo Code.
LT_PMBus::enablePec
void enablePec(uint8_t address)
Enable pec for all transactions.
Definition: LT_PMBus.cpp:3173
LT_SMBusNoPec
Definition: LT_SMBusNoPec.h:60
LT_PMBus::readStatusWord
uint16_t readStatusWord(uint8_t address)
Get the status word.
Definition: LT_PMBus.cpp:2470
LT_PMBus::readIout
float readIout(uint8_t address, bool polling)
Get the measured output current.
Definition: LT_PMBus.cpp:1898
print_all_currents
static void print_all_currents()
Prints all currents.
Definition: DC1978.ino:204
LT_PMBus::disablePec
void disablePec(uint8_t address)
Disable pec for all transactions.
Definition: LT_PMBus.cpp:3210
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC1978.ino:167
LT_SMBus::writeWord
virtual void writeWord(uint8_t address, uint8_t command, uint16_t data)=0
SMBus write word command.
LT_SMBusPec
Definition: LT_SMBusPec.h:61
LT_SMBus
Definition: LT_SMBus.h:61
LTC2974_I2C_ADDRESS
#define LTC2974_I2C_ADDRESS
Definition: DC1978.ino:67
loop
static void loop()
Repeats Linduino loop.
Definition: DC1978.ino:87
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC1978.ino:152
LT_PMBus::startGroupProtocol
void startGroupProtocol(void)
starts group protocol
Definition: LT_PMBus.cpp:3350
print_all_voltages
static void print_all_voltages()
Prints all voltages.
Definition: DC1978.ino:188
LT_PMBus::readVout
float readVout(uint8_t address, bool polling)
Get the measured output voltage.
Definition: LT_PMBus.cpp:1598
print_all_status
static void print_all_status()
Prints all status bytes and words.
Definition: DC1978.ino:220
margin_high
static void margin_high()
Margin high.
Definition: DC1978.ino:251
LT_I2CBus.h
LT_I2CBus: Routines to communicate to I2C by Wire Library.
margin_low
static void margin_low()
Margin low.
Definition: DC1978.ino:258
margin_off
static void margin_off()
Go to nominal.
Definition: DC1978.ino:265
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.
menu_3_vid_commands
static void menu_3_vid_commands()
Display menu 3.
Definition: DC1978.ino:405
LT_PMBus::setPage
void setPage(uint8_t address, uint8_t page)
Set the page.
Definition: LT_PMBus.cpp:3156
LT_PMBus::marginLowGlobal
void marginLowGlobal(void)
Margin all rails low.
Definition: LT_PMBus.cpp:3078
setup
static void setup()
Initialize Linduino.
Definition: DC1978.ino:77
print_warning_prompt
static void print_warning_prompt()
Prints a warning if the demo board is not detected.
Definition: DC1978.ino:181
LT_PMBus::sequenceOnGlobal
void sequenceOnGlobal(void)
Sequence on all rails.
Definition: LT_PMBus.cpp:2896
LT_SMBus::probe
virtual uint8_t * probe(uint8_t command)=0
SMBus bus probe.
menu_2_vid_commands
static void menu_2_vid_commands()
Display menu 2.
Definition: DC1978.ino:347
math
static LT_PMBusMath * math
Definition: DC1978.ino:71
LT_SMBusNoPec.h
LTC SMBus Support: Implementation for a shared SMBus layer.
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
smbus
static LT_SMBus * smbus
Definition: DC1978.ino:72
LT_PMBus::sequenceOffGlobal
void sequenceOffGlobal(void)
Sequence off all rails.
Definition: LT_PMBus.cpp:2876
LT_PMBus::setVout
void setVout(uint8_t address, float voltage)
Set output voltage.
Definition: LT_PMBus.cpp:239
LT_PMBus::executeGroupProtocol
void executeGroupProtocol(void)
ends group protocol
Definition: LT_PMBus.cpp:3356
LT_PMBusMath
Definition: LT_PMBusMath.h:53
LT_PMBus::restoreFromNvm
void restoreFromNvm(uint8_t address)
Restore device from NVM.
Definition: LT_PMBus.cpp:2663
LT_PMBus.h
LTC PMBus Support.
voltage
static float voltage
Definition: DC2289AA.ino:71
current
static uint16_t current
the current measurement from the LTC3335&#39;s counter test mode.
Definition: DC2343A.ino:114
LT_PMBus::marginHighGlobal
void marginHighGlobal(void)
Margin all rails high.
Definition: LT_PMBus.cpp:3068
increment_page
static void increment_page()
Definition: DC1978.ino:270
LT_PMBusMath.h
LTC PMBus Support: Math conversion routines.
LT_PMBus
PMBus communication.
Definition: LT_PMBus.h:370