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();
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:
114  delete smbus;
115  delete pmbus;
116  smbus = new LT_SMBusPec();
117  pmbus = new LT_PMBus(smbus);
118  break;
119  case 5:
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();
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
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
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
182 {
183  Serial.println(F("\nWarning: Demo board not detected. Linduino will attempt to proceed."));
184 }
185 
186 //! Prints all voltages
187 //! @return void
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
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
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);
232  Serial.print(F("LTC2974 STATUS BYTE 0x"));
233  Serial.println(b, HEX);
235  Serial.print(F("LTC2974 STATUS WORD 0x"));
236  Serial.println(w, HEX);
237  }
238 }
239 
240 // Sequence off then on
241 //! @return void
243 {
244  pmbus->sequenceOffGlobal();
245  delay (2000);
246  pmbus->sequenceOnGlobal();
247 }
248 
249 //! Margin high
250 //! @return void
252 {
253  pmbus->marginHighGlobal();
254 }
255 
256 //! Margin low
257 //! @return void
259 {
260  pmbus->marginLowGlobal();
261 }
262 
263 //! Go to nominal
264 //! @return void
266 {
267  pmbus->sequenceOnGlobal();
268 }
269 
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
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:
314  break;
315  case 2:
317  break;
318  case 3:
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
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
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 
static uint8_t ltc2974_i2c_address
Definition: DC1978.ino:70
static void sequence_off_on()
Definition: DC1978.ino:242
lin16_t float_to_lin16(float xin, lin16m_t vout_mode)
static void menu_1_basic_commands()
Display menu 1.
Definition: DC1978.ino:284
unsigned char user_command
static LT_PMBus * pmbus
Definition: DC1978.ino:73
LTC SMBus Support: Implementation for a shared SMBus layer.
uint8_t readStatusByte(uint8_t address)
Get the status byte.
Definition: LT_PMBus.cpp:2423
Header File for Linduino Libraries and Demo Code.
void enablePec(uint8_t address)
Enable pec for all transactions.
Definition: LT_PMBus.cpp:3173
uint16_t readStatusWord(uint8_t address)
Get the status word.
Definition: LT_PMBus.cpp:2470
float readIout(uint8_t address, bool polling)
Get the measured output current.
Definition: LT_PMBus.cpp:1898
static void print_all_currents()
Prints all currents.
Definition: DC1978.ino:204
void disablePec(uint8_t address)
Disable pec for all transactions.
Definition: LT_PMBus.cpp:3210
static void print_prompt()
Prints main menu.
Definition: DC1978.ino:167
virtual void writeWord(uint8_t address, uint8_t command, uint16_t data)=0
SMBus write word command.
#define LTC2974_I2C_ADDRESS
Definition: DC1978.ino:67
static void loop()
Repeats Linduino loop.
Definition: DC1978.ino:87
static void print_title()
Prints the title block when program first starts.
Definition: DC1978.ino:152
void startGroupProtocol(void)
starts group protocol
Definition: LT_PMBus.cpp:3350
static void print_all_voltages()
Prints all voltages.
Definition: DC1978.ino:188
float readVout(uint8_t address, bool polling)
Get the measured output voltage.
Definition: LT_PMBus.cpp:1598
static void print_all_status()
Prints all status bytes and words.
Definition: DC1978.ino:220
static void margin_high()
Margin high.
Definition: DC1978.ino:251
LT_I2CBus: Routines to communicate to I2C by Wire Library.
static void margin_low()
Margin low.
Definition: DC1978.ino:258
static void margin_off()
Go to nominal.
Definition: DC1978.ino:265
virtual void writeByte(uint8_t address, uint8_t command, uint8_t data)=0
SMBus write byte command.
virtual uint8_t readByte(uint8_t address, uint8_t command)=0
SMBus read byte command.
static void menu_3_vid_commands()
Display menu 3.
Definition: DC1978.ino:405
void setPage(uint8_t address, uint8_t page)
Set the page.
Definition: LT_PMBus.cpp:3156
void marginLowGlobal(void)
Margin all rails low.
Definition: LT_PMBus.cpp:3078
static void setup()
Initialize Linduino.
Definition: DC1978.ino:77
static void print_warning_prompt()
Prints a warning if the demo board is not detected.
Definition: DC1978.ino:181
void sequenceOnGlobal(void)
Sequence on all rails.
Definition: LT_PMBus.cpp:2896
virtual uint8_t * probe(uint8_t command)=0
SMBus bus probe.
static void menu_2_vid_commands()
Display menu 2.
Definition: DC1978.ino:347
static LT_PMBusMath * math
Definition: DC1978.ino:71
LTC SMBus Support: Implementation for a shared SMBus layer.
int32_t read_int()
static LT_SMBus * smbus
Definition: DC1978.ino:72
void sequenceOffGlobal(void)
Sequence off all rails.
Definition: LT_PMBus.cpp:2876
void setVout(uint8_t address, float voltage)
Set output voltage.
Definition: LT_PMBus.cpp:239
void executeGroupProtocol(void)
ends group protocol
Definition: LT_PMBus.cpp:3356
void restoreFromNvm(uint8_t address)
Restore device from NVM.
Definition: LT_PMBus.cpp:2663
LTC PMBus Support.
static float voltage
Definition: DC2289AA.ino:71
static uint16_t current
the current measurement from the LTC3335&#39;s counter test mode.
Definition: DC2343A.ino:114
void marginHighGlobal(void)
Margin all rails high.
Definition: LT_PMBus.cpp:3068
static void increment_page()
Definition: DC1978.ino:270
LTC PMBus Support: Math conversion routines.
PMBus communication.
Definition: LT_PMBus.h:370