Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1976A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1976A Demonstration Board
3 LTC3676: Power Management Solution for Application Processors
4 
5 @verbatim
6 
7 NOTES
8  Setup:
9  Set the terminal baud rate to 115200 and select the newline terminator.
10  External power supply is required. Any assembly option may be used:
11  DC1976A-A, DC1976A-B.
12 
13 @endverbatim
14 
15 http://www.linear.com/product/LTC3676
16 
17 http://www.linear.com/product/LTC3676#demoboards
18 
19 
20 Copyright 2018(c) Analog Devices, Inc.
21 
22 All rights reserved.
23 
24 Redistribution and use in source and binary forms, with or without
25 modification, are permitted provided that the following conditions are met:
26  - Redistributions of source code must retain the above copyright
27  notice, this list of conditions and the following disclaimer.
28  - Redistributions in binary form must reproduce the above copyright
29  notice, this list of conditions and the following disclaimer in
30  the documentation and/or other materials provided with the
31  distribution.
32  - Neither the name of Analog Devices, Inc. nor the names of its
33  contributors may be used to endorse or promote products derived
34  from this software without specific prior written permission.
35  - The use of this software may or may not infringe the patent rights
36  of one or more patent holders. This license does not release you
37  from the requirement that you obtain separate licenses from these
38  patent holders to use this software.
39  - Use of the software either in source or binary form, must be run
40  on or directly connected to an Analog Devices Inc. component.
41 
42 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
43 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
44 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
46 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
48 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */
53 
54 #include <Arduino.h>
55 #include <stdint.h>
56 #include "Linduino.h"
57 #include "UserInterface.h"
58 #include "LT_I2C.h"
59 #include "QuikEval_EEPROM.h"
60 #include "LTC3676.h"
61 
62 // Function Declarations
66 int8_t menu_4_sequencing(uint8_t *reg_phase);
67 
68 void print_title();
69 void print_prompt();
72 void read_reg_map(uint8_t *reg_map_array);
73 
74 // Global variables
75 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
76 static uint8_t i2c_address; //!< I2C address set for either -A or -B demo board
77 static char board_option; //!< Demo board option of the attached demo board
78 char demo_name[] = "DC1976"; //!< Demo Board Name stored in QuikEval EEPROM
79 uint8_t reg_phase[7] = {1,1,1,1,1,1,1}; //!< Power-up sequence phases for every regulator output
80 float delay_ms = 0; //!< Delay between power-up phases
81 
82 //! Initialize Linduino
83 void setup()
84 {
85  char eeprom_string[50];
86  uint8_t char_count;
87  quikeval_I2C_init(); //! Initializes Linduino I2C port.
88  quikeval_I2C_connect(); //! Connects I2C port to the QuikEval connector
89  Serial.begin(115200); //! Initialize the serial port to the PC
90  print_title();
91  demo_board_connected = discover_demo_board(demo_name); //! Checks if correct demo board is connected.
93  {
94 
95  char_count = read_quikeval_id_string(eeprom_string);
96  board_option = demo_board_option(eeprom_string);
99  print_prompt();
100  }
101  else
102  {
104  demo_board_connected = true;
106  }
107 }
108 
109 //! Repeats Linduino loop
110 void loop()
111 {
112  int8_t ack=0;
113  uint8_t user_command;
114  if (demo_board_connected) //! Does nothing if the demo board is not connected
115  {
116  if (Serial.available()) //! Checks for user input
117  {
118  user_command = read_int(); //! Reads the user command
119  if (user_command != 'm')
120  Serial.println(user_command);
121  ack = 0;
122  switch (user_command) //! Prints the appropriate submenu
123  {
124  case 1:
125  ack |= menu_1_read_write_registers(); // Print single-ended voltage menu
126  break;
127  case 2:
128  ack |= menu_2_regulator_settings(); // Differential voltage menu
129  break;
130  case 3:
131  ack |= menu_3_control_settings(); // Control Settings menu
132  break;
133  case 4:
134  ack |= menu_4_sequencing(reg_phase); // Sequencing menu
135  break;
136  default:
137  Serial.println("Incorrect Option");
138  break;
139  }
140  if (ack != 0)
141  {
142  Serial.print(F("Error: No Acknowledge. \n"));
143  }
144  print_prompt();
145  }
146  }
147 }
148 
149 // Function Definitions
150 
151 //! Prints the title block when program first starts.
153 {
154  Serial.print(F("\n*****************************************************************\n"));
155  Serial.print(F("* DC1976A 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 LTC3676 Power Management Solution for *\n"));
159  Serial.print(F("* Application Processors. *\n"));
160  Serial.print(F("* *\n"));
161  Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
162  Serial.print(F("* *\n"));
163  Serial.print(F("*****************************************************************\n"));
164 }
165 
166 //! Prints main menu.
168 {
169  Serial.print(F("\n 1-Read/Write Registers\n"));
170  Serial.print(F(" 2-Regulator Settings\n"));
171  Serial.print(F(" 3-Control Settings\n"));
172  Serial.print(F(" 4-Sequencing\n"));
173  Serial.print(F("\nEnter a command:"));
174 }
175 
176 //! Prints a warning if the demo board is not detected.
178 {
179  Serial.println(F("\nWarning: Demo board not detected. Linduino will attempt to proceed."));
180 }
181 
183 {
184  int8_t ack = 0;
185  uint8_t user_register = 0x01;
186  uint8_t data;
187  do
188  {
189  ack |= LTC3676_register_read(i2c_address, user_register, &data); //! Read register
190  Serial.print("Register 0x");
191  Serial.print(user_register, HEX);
192  Serial.print(":\t0x");
193  Serial.println(data, HEX);
194  user_register++;
195  }
196  while ((user_register <= 0x17) && (ack != 1));
197  return ack;
198 }
199 
200 char demo_board_option(char *eeprom_string)
201 {
202  char option='0';
203  uint8_t i;
204  for (i=0; i < strlen(eeprom_string); i++)
205  {
206  if (eeprom_string[i] == 'A' && option == '0')
207  option = eeprom_string[i+2];
208  }
209  return option;
210 }
211 
213 {
214  int8_t ack=0;
215  uint8_t user_command;
216  uint8_t data;
217  uint8_t user_register;
218  uint8_t user_bit;
219  do
220  {
221  //! Displays the Read/Write Registers menu
222  Serial.print(F("\nRead/Write Registers\n\n"));
223  Serial.print(F(" 1-Read All Registers\n"));
224  Serial.print(F(" 2-Read Single Register\n"));
225  Serial.print(F(" 3-Write Single Register\n"));
226  Serial.print(F(" 4-Set Bit\n"));
227  Serial.print(F(" 5-Clear Bit\n"));
228  Serial.print(F(" 6-Clear IRQ\n"));
229  Serial.print(F(" 7-Send Hard Reset Command\n"));
230  Serial.print(F(" m-Main Menu\n"));
231  Serial.print(F("\nEnter a command: "));
232 
233  user_command = read_int(); //! Reads the user command
234  if (user_command == 'm') // Print m if it is entered
235  {
236  Serial.print(F("m\n"));
237  }
238  else
239  Serial.println(user_command); // Print user command
240 
241  //! Reads or writes to a LTC3676 and prints result.
242  switch (user_command)
243  {
244  case 1:
245  // Read every register and print it's data.
247  break;
248  case 2:
249  // Read a single register and print it's data.
250  Serial.print(F("\nAddress (in hex with '0x' prefix) of register to read: "));
251  user_register = read_int();
252  Serial.print("0x");
253  Serial.println(user_register, HEX);
254  if (user_register < 0x01 || user_register > 0x17)
255  {
256  Serial.println(F(" Invalid input."));
257  break;
258  }
259  ack |= LTC3676_register_read(i2c_address, user_register, &data);
260  Serial.print("Register data: 0x");
261  Serial.println(data, HEX);
262  break;
263  case 3:
264  // Write a byte to a chosen register.
265  Serial.print(F("\nAddress (in hex with '0x' prefix) of register to write: "));
266  user_register = read_int();
267  Serial.print("0x");
268  Serial.println(user_register, HEX);
269  if (user_register == 0x1E)
270  {
271  Serial.println(F(" Hard Reset command sent."));
272  ack |= LTC3676_register_write(i2c_address, user_register, 0x01);
273  break;
274  }
275  else if (user_register == 0x1F)
276  {
277  Serial.println(F(" Clear IRQ command sent."));
278  ack |= LTC3676_register_write(i2c_address, user_register, 0x01);
279  break;
280  }
281  else if (user_register < 0x01 || user_register > 0x17)
282  {
283  Serial.println(F(" Invalid input."));
284  break;
285  }
286  Serial.print(F("Data (in hex with '0x' prefix) to write: "));
287  data = read_int();
288  Serial.println(data, HEX);
289  ack |= LTC3676_register_write(i2c_address, user_register, data);
290  Serial.print("0x");
291  Serial.print(data, HEX);
292  Serial.print(" written to register 0x");
293  Serial.println(user_register, HEX);
294  break;
295  case 4:
296  // Set a single bit within a chosen register.
297  Serial.print(F("\nAddress (in hex with '0x' prefix) of register: "));
298  user_register = read_int();
299  Serial.print("0x");
300  Serial.println(user_register, HEX);
301  if (user_register < 0x01 || user_register > 0x17)
302  {
303  Serial.println(F(" Invalid input."));
304  break;
305  }
306  Serial.print(F("Bit position (0-7) to set: "));
307  data = read_int();
308  if (data < 0 || data > 7)
309  {
310  Serial.println(F(" Invalid input."));
311  break;
312  }
313  Serial.println(data, DEC);
314  ack |= LTC3676_bit_set(i2c_address, user_register, data);
315  Serial.print("Bit set. Register data is now 0x");
316  ack |= LTC3676_register_read(i2c_address, user_register, &data);
317  Serial.println(data, HEX);
318  break;
319  case 5:
320  // Clear a single bit within a chosen register.
321  Serial.print(F("\nAddress (in hex with '0x' prefix) of register: "));
322  user_register = read_int();
323  Serial.print("0x");
324  Serial.println(user_register, HEX);
325  if (user_register < 0x01 || user_register > 0x17)
326  {
327  Serial.println(F(" Invalid input."));
328  break;
329  }
330  Serial.print(F("Bit position (0-7) to clear: "));
331  data = read_int();
332  if (data < 0 || data > 7)
333  {
334  Serial.println(F("Invalid input."));
335  break;
336  }
337  Serial.println(data, DEC);
338  ack |= LTC3676_bit_clear(i2c_address, user_register, data);
339  Serial.print("Bit cleared. Register data is now 0x");
340  ack |= LTC3676_register_read(i2c_address, user_register, &data);
341  Serial.println(data, HEX);
342  break;
343  case 6:
344  // Clear IRQ register
345  Serial.println(F("\n Clear IRQ command sent."));
347  break;
348  case 7:
349  // Initiate a hard reset
350  Serial.println(F("\n Hard Reset command sent."));
352  break;
353  default:
354  if (user_command != 'm')
355  Serial.println("Invalid Selection");
356  break;
357  }
358  }
359  while ((user_command != 'm') && (ack != 1));
360  return(ack);
361 }
362 
364 {
365  int8_t ack=0;
366  uint8_t user_command;
367  uint8_t data;
368  uint8_t user_register;
369  uint8_t user_int;
370  uint8_t user_buck;
371  uint8_t user_ldo;
372  int8_t user_char;
373  do
374  {
375  //! Displays the Regulator Settings menu
376  Serial.print(F("\nRegulator Settings\n\n"));
377  Serial.print(F(" 1-Enable/Disable Bucks\n"));
378  Serial.print(F(" 2-Enable/Disable LDOs\n"));
379  Serial.print(F(" 3-Set Buck Output Voltage\n"));
380  Serial.print(F(" 4-Set Buck Feedback Reference\n"));
381  Serial.print(F(" 5-Select Buck Reference\n"));
382  Serial.print(F(" 6-Set Buck Switching Mode\n"));
383  Serial.print(F(" 7-Set Start-Up Mode (300mV check)\n"));
384  Serial.print(F(" 8-Set PGOOD Slewing Mask\n"));
385  Serial.print(F(" 9-Exit Software Control Mode\n"));
386  if (board_option == 'B')
387  Serial.print(F(" 10-Set LDO4 Output Voltage\n"));
388  Serial.print(F(" m-Main Menu\n"));
389  Serial.print(F("\nEnter a command: "));
390 
391  user_command = read_int(); //! Reads the user command
392  if (user_command == 'm') // Print m if it is entered
393  Serial.print(F("m\n"));
394  else
395  Serial.println(user_command); // Print user command
396 
397  //! Reads or writes to a LTC3676 and prints result.
398  switch (user_command)
399  {
400  case 1:
401  //Enter software control mode
403  {
404  Serial.print(F("\n********** Note: LTC3676 is now in Sofware Control Mode **********\n"));
405  Serial.print(F("***************Select Option 9 to resume Pin Control *************\n"));
407  }
408  // Enable/Disable Bucks
409  Serial.print(F("\nSelect Buck(1-4, 5=all): "));
410  user_buck = read_int();
411  Serial.println(user_buck, DEC);
412  if (user_buck < 1 || user_buck > 5)
413  {
414  Serial.println(F(" Invalid input."));
415  break;
416  }
417  Serial.println(F("0=Disable, 1=Enable"));
418  Serial.print(F("Enter selection: "));
419  user_int = read_int();
420  Serial.println(user_int, DEC);
421  if (user_int > 1)
422  {
423  Serial.println(F(" Invalid input."));
424  break;
425  }
426  if (user_int == 1)
428  if (user_buck == 5)
429  {
430  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK1, 7, user_int);
431  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK2, 7, user_int);
432  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK3, 7, user_int);
433  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK4, 7, user_int);
434  }
435  else
436  ack |= LTC3676_bit_write(i2c_address, user_buck, 7, user_int);
437  Serial.println(F("Done."));
438  break;
439  case 2:
440  //Enter software control mode
442  {
443  Serial.print(F("\n********** Note: LTC3676 is now in Sofware Control Mode **********\n"));
444  Serial.print(F("***************Select Option 8 to resume Pin Control *************\n"));
446  }
447  // Enable/Disable LDOs
448  Serial.print(F("\nSelect LDO(2-4, 5=all): "));
449  user_ldo = read_int();
450  Serial.println(user_ldo, DEC);
451  if (user_ldo < 2 || user_ldo > 5)
452  {
453  Serial.println(F(" Invalid input."));
454  break;
455  }
456  Serial.println(F("0=Disable, 1=Enable"));
457  Serial.print(F("Enter selection: "));
458  user_int = read_int();
459  Serial.println(user_int, DEC);
460  if (user_int > 1)
461  {
462  Serial.println(F(" Invalid input."));
463  break;
464  }
465  if (user_int == 1)
467  if (user_ldo == 5)
468  {
469  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 2, user_int);
470  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 5, user_int);
471  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOB, 2, user_int);
472  }
473  else if (user_ldo == 2)
474  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 2, user_int);
475  else if (user_ldo == 3)
476  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 5, user_int);
477  else if (user_ldo == 4)
478  ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOB, 2, user_int);
479  Serial.println(F("Done."));
480  break;
481  case 3:
482  // Set buck output voltage in mV
483  float user_output;
484  float new_output;
485  Serial.print(F("\nSelect Buck(1-4): "));
486  user_int = read_int();
487  Serial.println(user_int, DEC);
488  if (user_int < 1 || user_int > 4)
489  {
490  Serial.println(F("Invalid input."));
491  break;
492  }
493  Serial.print(F("Select Reference (A=DVB"));
494  Serial.print(user_int, DEC);
495  Serial.print(F("A, B=DVB"));
496  Serial.print(user_int, DEC);
497  Serial.print(F("B): "));
498  user_char = read_char();
499  Serial.write(user_char);
500  if (user_char == 'A' || user_char == 'a')
501  user_register = (user_int*2) + 8; //Converts selection to appropriate register address.
502  else if (user_char == 'B' || user_char == 'b')
503  user_register = (user_int*2) + 9; //Converts selection of appropriate register address.
504  else
505  {
506  Serial.println(F("\nInvalid input."));
507  break;
508  }
509  Serial.print(F("\nPotential output voltage range: "));
510  Serial.print(LTC3676_buck_vout_min(user_int), 0);
511  Serial.print(F("mV to "));
512  Serial.print(LTC3676_buck_vout_max(user_int), 0);
513  Serial.print(F("mV."));
514  Serial.print(F("\nNew output voltage in mV: "));
515  user_output = read_float();
516  Serial.println(user_output, 0);
517  if (user_output < LTC3676_buck_vout_min(user_int) | user_output > LTC3676_buck_vout_max(user_int))
518  {
519  Serial.println(F("\nInvalid input."));
520  break;
521  }
522  new_output = LTC3676_set_buck_output_voltage(i2c_address, user_register, user_output);
523  Serial.print(F("Output voltage set to "));
524  Serial.print(new_output, 0);
525  Serial.println(F("mV."));
526  Serial.print(F("New Feedback Reference Bits: 0x"));
527  ack |= LTC3676_register_read(i2c_address, user_register, &data);
528  Serial.println(data & 0x1F, HEX);
529  break;
530  case 4:
531  // Set buck feedback reference voltage in mV
532  float user_reference;
533  float new_reference;
534  Serial.print(F("\nSelect Buck(1-4): "));
535  user_int = read_int();
536  Serial.println(user_int, DEC);
537  if (user_int < 1 || user_int > 4)
538  {
539  Serial.println(F("Invalid input."));
540  break;
541  }
542  Serial.print(F("Select Reference (A=DVB"));
543  Serial.print(user_int);
544  Serial.print(F("A, B=DVB"));
545  Serial.print(user_int);
546  Serial.print(F("B): "));
547  user_char = read_char();
548  Serial.write(user_char);
549  if (user_char == 'A' || user_char == 'a')
550  user_register = (user_int*2) + 8; //Converts selection to appropriate register address.
551  else if (user_char == 'B' || user_char == 'b')
552  user_register = (user_int*2) + 9; //Converts selection of appropriate register address.
553  else
554  {
555  Serial.println(F("\nInvalid input."));
556  break;
557  }
558  Serial.print(F("\nNew feedback reference input in mV (412.5-800): "));
559  user_reference = read_float();
560  Serial.println(user_reference);
561  if (user_reference < 412.5 | user_reference > 800)
562  {
563  Serial.println(F("\nInvalid input."));
564  break;
565  }
566  new_reference = LTC3676_set_buck_fb_ref(i2c_address, user_register, user_reference);
567  Serial.print(F("Feedback reference input set to "));
568  Serial.print(new_reference, 0);
569  Serial.println(F("mV"));
570  Serial.print(F("New Feedback Reference Bits: 0x"));
571  ack |= LTC3676_register_read(i2c_address, user_register, &data);
572  Serial.println(data & 0x1F, HEX);
573  break;
574  case 5:
575  // Select buck reference (A or B)
576  Serial.print(F("\nSelect Buck(1-4, 5=all): "));
577  user_buck = read_int();
578  Serial.println(user_buck, DEC);
579  if (user_buck < 1 || user_buck > 5)
580  {
581  Serial.println(F(" Invalid input."));
582  break;
583  }
584  Serial.print(F("Select Reference (A or B): "));
585  user_char = read_char();
586  Serial.write(user_char);
587  if (user_char == 'A' || user_char == 'a' || user_char == 'B' || user_char == 'b')
588  {
589  if (user_buck == 5)
590  ack |= LTC3676_select_buck_reference(i2c_address, 0xFF, user_char);
591  else
592  ack |= LTC3676_select_buck_reference(i2c_address, user_buck, user_char);
593  Serial.println(F("\nDone."));
594  break;
595  }
596  Serial.println(F("\n Invalid input."));
597  break;
598  case 6:
599  // Set buck switching mode
600  Serial.print(F("\nSelect Buck(1-4, 5=all): "));
601  user_register = read_int();
602  Serial.println(user_register, DEC);
603  if (user_register < 1 || user_register > 5)
604  {
605  Serial.println(F(" Invalid input."));
606  break;
607  }
608  Serial.print(F("Select mode (0=Pulse Skipping, 1=Burst, 2=Forced Continuous): "));
609  user_int = read_int();
610  Serial.println(user_int, DEC);
611  if (user_int < 0 || user_int > 2)
612  {
613  Serial.println(F(" Invalid input."));
614  break;
615  }
616  if (user_register == 5)
617  ack |= LTC3676_set_buck_mode(i2c_address, 0xFF, user_int);
618  else
619  ack |= LTC3676_set_buck_mode(i2c_address, user_register, user_int);
620  Serial.println(F("Switching mode(s) set."));
621  break;
622  case 7:
623  // Sets the startup mode for all bucks
624  Serial.print(F("\nSelect Buck(1-4, 5=all): "));
625  user_buck = read_int();
626  Serial.println(user_buck, DEC);
627  if (user_buck < 1 || user_buck > 5)
628  {
629  Serial.println(F(" Invalid input."));
630  break;
631  }
632  Serial.println(F("0=Enable at any output voltage, 1=Enable only if output <300mV"));
633  Serial.print(F("Enter selection: "));
634  user_int = read_int();
635  Serial.println(user_int, DEC);
636  if (user_int < 0 || user_int > 1)
637  {
638  Serial.println(F(" Invalid input."));
639  break;
640  }
641  if (user_buck == 5)
642  ack |= LTC3676_set_startup_mode(i2c_address, 0xFF, user_int);
643  else
644  ack |= LTC3676_set_startup_mode(i2c_address, user_buck, user_int);
645  Serial.println(F("Start-up mode(s) set."));
646  break;
647  case 8:
648  // Sets PGOOD masks bit for all bucks.
649  Serial.print(F("\nSelect Buck(1-4, 5=all): "));
650  user_buck = read_int();
651  Serial.println(user_buck, DEC);
652  if (user_buck < 1 || user_buck > 5)
653  {
654  Serial.println(F(" Invalid input."));
655  break;
656  }
657  Serial.println(F("0=PGOOD low when slewing, 1=PGOOD not forced low when slewing"));
658  Serial.print(F("Enter selection: "));
659  user_int = read_int();
660  Serial.println(user_int, DEC);
661  if (user_int < 0 || user_int > 1)
662  {
663  Serial.println(F(" Invalid input."));
664  break;
665  }
666  if (user_buck == 5)
667  ack |= LTC3676_set_buck_pgood_mask(i2c_address, 0xFF, user_int);
668  else
669  ack |= LTC3676_set_buck_pgood_mask(i2c_address, user_buck, user_int);
670  Serial.println(F("PGOOD Mask bit(s) set."));
671  break;
672  case 9:
673  // Exit software control mode
675  break;
676  case 10:
677  // Set LDO4 Output Voltage for DC1976A-B
678  if (board_option == 'B')
679  {
680  Serial.print(F("Select LDO4 Voltage (0=1.2V, 1=2.5V, 2=2.8V, 3=3.0V): "));
681  user_int = read_int();
682  Serial.println(user_int, DEC);
683  if (user_int > 3)
684  {
685  Serial.println(F(" Invalid input."));
686  break;
687  }
688  ack |= LTC3676_1_set_ldo4_voltage(i2c_address, user_int);
689  Serial.println(F("LDO4 Voltage Set."));
690  break;
691  }
692  Serial.println(" Invalid Selection");
693  break;
694  default:
695  if (user_command != 'm')
696  Serial.println(" Invalid Selection");
697  break;
698  }
699  }
700  while ((user_command != 'm') && (ack != 1));
701  return (ack);
702 }
703 
705 {
706  int8_t ack=0;
707  uint8_t user_command;
708  uint8_t data;
709  uint8_t user_register;
710  uint8_t user_int;
711  int8_t user_char;
712  do
713  {
714  //! Displays the Control Settings menu
715  Serial.print(F("\nControl Settings\n\n"));
716  Serial.print(F(" 1-Set UV Warning Threshold\n"));
717  Serial.print(F(" 2-Set Over-Temperature Warning Level\n"));
718  Serial.print(F(" m-Main Menu\n"));
719  Serial.print(F("\nEnter a command: "));
720 
721  user_command = read_int(); // Reads the user command
722  if (user_command == 'm') // Print m if it is entered
723  Serial.print(F("m\n"));
724  else
725  Serial.println(user_command); // Print user command
726 
727  //! Reads or writes to a LTC3676 and prints result.
728  switch (user_command)
729  {
730  case 1:
731  // Set UV warning threshold
732  float user_threshold;
733  Serial.print(F("\nEnter new UV warning threshold in Volts (2.7 - 3.4): "));
734  user_threshold = read_float();
735  Serial.println(user_threshold, 1);
736  if (user_threshold < 2.7 | user_threshold > 3.4)
737  {
738  Serial.println(F("Invalid input."));
739  break;
740  }
741  ack = LTC3676_set_uv_warning_threshold(i2c_address, user_threshold);
742  Serial.print(F("UV warning threshold set to "));
743  Serial.print(user_threshold,1);
744  Serial.println(F("V"));
745  break;
746  case 2:
747  // Set over-temperature warning level
748  Serial.print(F("Enter warning level in deg C below over-temperature shutdown(10,20,30,40): "));
749  user_int = read_int();
750  Serial.println(user_int, DEC);
751  if (user_int < 10 | user_int > 40)
752  {
753  Serial.println(F("Invalid input."));
754  break;
755  }
757  Serial.print(F("Warning level set to "));
758  Serial.print(((uint8_t)((user_int + 5)/10))*10);
759  Serial.println(F("C below Over-temperature"));
760  break;
761  default:
762  if (user_command != 'm')
763  Serial.println(" Invalid Selection");
764  break;
765  }
766  }
767  while ((user_command != 'm') && (ack != 1));
768  return (ack);
769 }
770 
771 
772 int8_t menu_4_sequencing(uint8_t *reg_phase)
773 {
774  int8_t ack=0;
775  uint8_t user_command;
776  uint8_t data;
777  uint8_t user_sequence;
778  uint8_t user_int;
779  uint8_t reg_map[6];
780  uint8_t reg_address[7] = {1,2,3,4,5,5,6};
781  uint8_t reg_bit_position[7] = {7,7,7,7,2,5,2};
782  int count;
783 
784  //Enter software control mode
786  {
787  Serial.print(F("\n********** Note: LTC3676 is now in Sofware Control Mode **********\n"));
788  Serial.print(F("************** Select Option 8 to resume Pin Control *************\n"));
790  }
791  do
792  {
793  //! Displays the Startup Sequencing menu
794 
795  Serial.print(F("\nPowerup Sequencing\n\n"));
796  Serial.print(F(" 1-Set Power-up Sequence\n"));
797  Serial.print(F(" 2-Print Power-up Sequence\n"));
798  Serial.print(F(" 3-Set Buck Power-down Sequence\n"));
799  Serial.print(F(" 4-Set LDO Power-down Sequence\n"));
800  Serial.print(F(" 5-Print Power-down Sequence\n"));
801  Serial.print(F(" 6-Power-up Regulators\n"));
802  Serial.print(F(" 7-Power-down Regulators\n"));
803  Serial.print(F(" 8-Exit Software Control Mode\n"));
804  Serial.print(F(" m-Main Menu\n"));
805  Serial.print(F("\nEnter a command: "));
806 
807  user_command = read_int(); //! Reads the user command
808  if (user_command == 'm') // Print m if it is entered
809  Serial.print(F("m\n"));
810  else
811  Serial.println(user_command); // Print user command
812 
813  switch (user_command)
814  {
815  case 1:
816  Serial.println(F("\nRegulators will power-up in 4 phases"));
817  Serial.println(F("Select a phase for each"));
818  Serial.println(F("1=First phase, 2=Second phase, 3=Third phase, 4=Fourth phase, 0=Don't enable"));
819  Serial.print(F("Buck1: "));
820  user_int = read_int();
821  Serial.println(user_int, DEC);
822  if (user_int < 5)
823  reg_phase[0] = user_int;
824  Serial.print(F("Buck2: "));
825  user_int = read_int();
826  Serial.println(user_int, DEC);
827  if (user_int < 5)
828  reg_phase[1] = user_int;
829  Serial.print(F("Buck3: "));
830  user_int = read_int();
831  Serial.println(user_int, DEC);
832  if (user_int < 5)
833  reg_phase[2] = user_int;
834  Serial.print(F("Buck4: "));
835  user_int = read_int();
836  Serial.println(user_int, DEC);
837  if (user_int < 5)
838  reg_phase[3] = user_int;
839  Serial.print(F("LDO2: "));
840  user_int = read_int();
841  Serial.println(user_int, DEC);
842  if (user_int < 5)
843  reg_phase[4] = user_int;
844  Serial.print(F("LDO3: "));
845  user_int = read_int();
846  Serial.println(user_int, DEC);
847  if (user_int < 5)
848  reg_phase[5] = user_int;
849  Serial.print(F("LDO4: "));
850  user_int = read_int();
851  Serial.println(user_int, DEC);
852  if (user_int < 5)
853  reg_phase[6] = user_int;
854  Serial.print(F("Enter delay between phases in milliseconds: "));
855  delay_ms = read_float();
856  if (delay_ms >= 0 && delay_ms <= 10000)
857  Serial.println(delay_ms, 1);
858  else
859  Serial.println(F("Values less than 0 or greater than 10s not allowed."));
860  break;
861  case 2:
862  Serial.print(F("\nBuck1: "));
863  Serial.println(reg_phase[0]);
864  Serial.print(F("Buck2: "));
865  Serial.println(reg_phase[1]);
866  Serial.print(F("Buck3: "));
867  Serial.println(reg_phase[2]);
868  Serial.print(F("Buck4: "));
869  Serial.println(reg_phase[3]);
870  Serial.print(F("LDO2: "));
871  Serial.println(reg_phase[4]);
872  Serial.print(F("LDO3: "));
873  Serial.println(reg_phase[5]);
874  Serial.print(F("LDO4: "));
875  Serial.println(reg_phase[6]);
876  Serial.print(F("Delay: "));
877  Serial.print(delay_ms, 1);
878  Serial.println(F("ms"));
879  break;
880  case 3:
881  // Set Buck Power-down Sequence
882  Serial.print(F("\nSelect Buck(1-4): "));
883  user_int = read_int();
884  Serial.println(user_int, DEC);
885  if (user_int < 1 || user_int > 4)
886  {
887  Serial.println(F("Invalid input."));
888  break;
889  }
890  Serial.println(F("0=with WAKE, 1=WAKE+100ms, 2=WAKE+200ms, 3=WAKE+300ms"));
891  Serial.print(F("Enter selection: "));
892  user_sequence = read_int();
893  Serial.println(user_sequence, DEC);
894  if (user_sequence > 3)
895  {
896  Serial.println(F("Invalid input."));
897  break;
898  }
899  ack |= LTC3676_set_buck_sequence_down(i2c_address, user_int, user_sequence);
900  Serial.print(F("Sequence down set for Buck"));
901  Serial.println(user_int, DEC);
902  break;
903  case 4:
904  // Set LDO Power-down Sequence
905  Serial.print(F("\nSelect LDO(2-4): "));
906  user_int = read_int();
907  Serial.println(user_int, DEC);
908  if (user_int < 2 || user_int > 4)
909  {
910  Serial.println(F("Invalid input."));
911  break;
912  }
913  Serial.println(F("0=with WAKE, 1=WAKE+100ms, 2=WAKE+200ms, 3=WAKE+300ms"));
914  Serial.print(F("Enter selection: "));
915  user_sequence = read_int();
916  Serial.println(user_sequence, DEC);
917  if (user_sequence > 3)
918  {
919  Serial.println(F("Invalid input."));
920  break;
921  }
922  ack |= LTC3676_set_ldo_sequence_down(i2c_address, user_int, user_sequence);
923  Serial.print(F("Sequence down set for LDO"));
924  Serial.println(user_int, DEC);
925  break;
926  case 5:
927  //Print power-down sequence
929  Serial.print(F("\nBuck1: "));
930  Serial.println(data & LTC3676_BUCK1_SEQ_MASK, DEC);
931  Serial.print(F("Buck2: "));
932  Serial.println((data & LTC3676_BUCK2_SEQ_MASK)>>2, DEC);
933  Serial.print(F("Buck3: "));
934  Serial.println((data & LTC3676_BUCK3_SEQ_MASK)>>4, DEC);
935  Serial.print(F("Buck4: "));
936  Serial.println((data & LTC3676_BUCK4_SEQ_MASK)>>6, DEC);
938  Serial.print(F("LDO2: "));
939  Serial.println(data & LTC3676_LDO2_SEQ_MASK, DEC);
940  Serial.print(F("LDO3: "));
941  Serial.println((data & LTC3676_LDO3_SEQ_MASK)>>2, DEC);
942  Serial.print(F("LDO4: "));
943  Serial.println((data & LTC3676_LDO4_SEQ_MASK)>>4, DEC);
944  Serial.print(F("Delay between phases(fixed): 100ms\n"));
945  break;
946  case 6:
947  //Power-up regulators
949  delay(100);
950  read_reg_map(reg_map);
951  //Start Phase 1 Regulators
952 
953  for (count=0; count<7; count++)
954  {
955  if (reg_phase[count] == 1)
956  ack |= LTC3676_register_write(i2c_address, reg_address[count], ((0x01<<reg_bit_position[count]) | reg_map[reg_address[count]-1]));
957  }
958 
959  delay(delay_ms);
960 
961 
962  //Start Phase 2 Regulators
963 
964  for (count=0; count<7; count++)
965  {
966  if (reg_phase[count] == 2)
967  ack |= LTC3676_register_write(i2c_address, reg_address[count], ((0x01<<reg_bit_position[count]) | reg_map[reg_address[count]-1]));
968  }
969 
970  delay(delay_ms);
971 
972  //Start Phase 3 Regulators
973 
974 
975 
976  for (count=0; count<7; count++)
977  {
978  if (reg_phase[count] == 3)
979  ack |= LTC3676_register_write(i2c_address, reg_address[count], ((0x01<<reg_bit_position[count]) | reg_map[reg_address[count]-1]));
980  }
981 
982  delay(delay_ms);
983 
984  //Start Phase 4 Regulators
985 
986 
987  for (count=0; count<7; count++)
988  {
989  if (reg_phase[count] == 4)
990  ack |= LTC3676_register_write(i2c_address, reg_address[count], ((0x01<<reg_bit_position[count]) | reg_map[reg_address[count]-1]));
991  }
992 
993  break;
994  case 7:
995  // Power-down by clearing the PWR_ON bit
996  Serial.print(F("\n******** Note: On DC1976, set SW2 for uC control of PWR_ON *******\n"));
997  Serial.print(F("*** Otherwise, PWR_ON bit may not initiate power-down sequence ***\n\n"));
999  break;
1000  case 8:
1001  // Exit software control mode
1003  break;
1004  default:
1005  if (user_command != 'm')
1006  Serial.println(" Invalid Selection");
1007  break;
1008  }
1009  }
1010  while ((user_command != 'm') && (ack != 1));
1011  return (ack);
1012 }
1013 
1014 //! Reads the first 6 registers and stores them in an array
1015 void read_reg_map(uint8_t *reg_map_array)
1016 {
1017  uint8_t count;
1018  uint8_t data;
1019  int8_t ack;
1020  for (count=0; count<6; count++)
1021  {
1022  ack |= LTC3676_register_read(i2c_address, count+1, &data);
1023  reg_map_array[count] = data;
1024  }
1025 }
1026 
1027 
int8_t LTC3676_set_buck_mode(uint8_t i2c_address, uint8_t buck_number, uint8_t mode)
Sets the switching mode for the specified Buck regulator.
Definition: LTC3676.cpp:255
#define LTC3676_REG_CLIRQ
Definition: LTC3676.h:124
uint8_t LTC3676_bit_is_set(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
Reads the value of any bit in any register or the LTC3676.
Definition: LTC3676.cpp:137
int8_t LTC3676_set_startup_mode(uint8_t i2c_address, uint8_t buck_number, uint8_t startup_bit)
Sets the start-up mode for all bucks.
Definition: LTC3676.cpp:276
#define LTC3676_REG_BUCK1
Definition: LTC3676.h:100
static void read_reg_map(uint8_t *reg_map_array)
Reads the first 6 registers and stores them in an array.
Definition: DC1976A.ino:1015
#define LTC3676_REG_BUCK2
Definition: LTC3676.h:101
unsigned char user_command
#define LTC3676_I2C_ADDRESS
Definition: LTC3676.h:79
#define LTC3676_REG_LDOB
Definition: LTC3676.h:105
#define LTC3676_BUCK1_SEQ_MASK
Definition: LTC3676.h:260
static void print_warning_prompt()
Prints a warning if the demo board is not detected.
Definition: DC1976A.ino:177
#define LTC3676_LDO2_SEQ_MASK
Definition: LTC3676.h:263
int8_t LTC3676_register_write(uint8_t i2c_address, uint8_t register_address, uint8_t register_data)
Writes to an 8-bit register inside the LTC3676 using the standard I2C repeated start format...
Definition: LTC3676.cpp:86
int8_t LTC3676_set_ldo_sequence_down(uint8_t i2c_address, uint8_t ldo_number, uint8_t sequence_phase)
Sets the Sequence Down bits for any buck in the SQD1 register.
Definition: LTC3676.cpp:368
#define LTC3676_LDO4_SEQ_MASK
Definition: LTC3676.h:261
float LTC3676_buck_vout_max(uint8_t buck_number)
Calculates the maximum output voltage of any buck in mV based on the feedback resistors.
Definition: LTC3676.cpp:191
Header File for Linduino Libraries and Demo Code.
float LTC3676_set_buck_fb_ref(uint8_t i2c_address, uint8_t register_address, float fb_ref_voltage)
Writes the Feedback Reference Voltage of any buck.
Definition: LTC3676.cpp:176
char demo_board_option(char *eeprom_string)
Definition: DC1976A.ino:200
int8_t LTC3676_select_buck_reference(uint8_t i2c_address, uint8_t buck_number, int8_t ref_char)
Selects the reference for the specified buck regulator(s).
Definition: LTC3676.cpp:233
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1976A.ino:78
int8_t LTC3676_set_buck_sequence_down(uint8_t i2c_address, uint8_t buck_number, uint8_t sequence_phase)
Sets the Sequence Down bits for any buck in the SQD1 register.
Definition: LTC3676.cpp:354
float LTC3676_buck_vout_min(uint8_t buck_number)
Calculates the minimum output voltage of any buck in mV based on the feedback resistors.
Definition: LTC3676.cpp:212
#define LTC3676_REG_CNTRL
Definition: LTC3676.h:108
int8_t LTC3676_bit_write(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number, uint8_t bit_data)
Writes any bit inside the LTC3676 using the standard I2C repeated start format.
Definition: LTC3676.cpp:122
static char board_option
Demo board option of the attached demo board.
Definition: DC1976A.ino:77
int8_t LTC3676_bit_clear(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
Clears any bit inside the LTC3676 using the standard I2C repeated start format.
Definition: LTC3676.cpp:108
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
int8_t LTC3676_register_read(uint8_t i2c_address, uint8_t register_address, uint8_t *register_data)
Reads an 8-bit register from the LTC3676 using the standard repeated start format.
Definition: LTC3676.cpp:78
static uint8_t reg_phase[7]
Power-up sequence phases for every regulator output.
Definition: DC1976A.ino:79
static void loop()
Repeats Linduino loop.
Definition: DC1976A.ino:110
LTC3676: Power management solution for application processors.
#define LTC3676_1_I2C_ADDRESS
Definition: LTC3676.h:80
#define LTC3676_REG_LDOA
Definition: LTC3676.h:104
int8_t LTC3676_set_uv_warning_threshold(uint8_t i2c_address, float uv_warning_threshold)
Writes a new UV warning threshold voltage in the CTRL register.
Definition: LTC3676.cpp:311
QuikEval EEPROM Library.
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
#define LTC3676_REG_SQD2
Definition: LTC3676.h:107
static void print_prompt()
Prints main menu.
Definition: DC1976A.ino:167
static void setup()
Initialize Linduino.
Definition: DC1976A.ino:83
#define LTC3676_BUCK4_SEQ_MASK
Definition: LTC3676.h:257
int8_t LTC3676_bit_set(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
Sets any bit inside the LTC3676 using the standard I2C repeated start format.
Definition: LTC3676.cpp:95
#define LTC3676_REG_BUCK3
Definition: LTC3676.h:102
#define LTC3676_REG_HRST
Definition: LTC3676.h:123
float LTC3676_set_buck_output_voltage(uint8_t i2c_address, uint8_t register_address, float output_voltage)
Sets the output voltage of any buck.
Definition: LTC3676.cpp:147
int8_t LTC3676_set_buck_pgood_mask(uint8_t i2c_address, uint8_t buck_number, uint8_t pgood_bit)
Sets the PGOOD mask bit in the DVBxB register for all bucks.
Definition: LTC3676.cpp:293
static int8_t menu_4_sequencing(uint8_t *reg_phase)
Definition: DC1976A.ino:772
static uint8_t i2c_address
I2C address set for either -A or -B demo board.
Definition: DC1976A.ino:76
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
static int8_t menu_1_read_write_registers()
Linear Technology DC1976A Demonstration Board LTC3676: Power Management Solution for Application Proc...
Definition: DC1976A.ino:212
#define LTC3676_BUCK2_SEQ_MASK
Definition: LTC3676.h:259
int32_t read_int()
float read_float()
#define LTC3676_BUCK3_SEQ_MASK
Definition: LTC3676.h:258
#define LTC3676_LDO3_SEQ_MASK
Definition: LTC3676.h:262
static int8_t menu_2_regulator_settings()
Definition: DC1976A.ino:363
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
void quikeval_I2C_connect(void)
Switch MUX to connect I2C pins to QuikEval connector.
Definition: LT_I2C.cpp:401
static int i
Definition: DC2430A.ino:184
static float delay_ms
Delay between power-up phases.
Definition: DC1976A.ino:80
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1976A.ino:75
int8_t LTC3676_1_set_ldo4_voltage(uint8_t i2c_address, uint8_t ldo4_output_voltage_code)
Sets LDO4 output voltage on the LTC3676-1.
Definition: LTC3676.cpp:341
#define LTC3676_REG_SQD1
Definition: LTC3676.h:106
#define LTC3676_PWR_ON
Definition: LTC3676.h:160
int8_t read_char()
#define LTC3676_REG_BUCK4
Definition: LTC3676.h:103
static int8_t menu_3_control_settings()
Definition: DC1976A.ino:704
uint8_t read_quikeval_id_string(char *buffer)
Read the id string from the EEPROM, then parse the product name, demo board name, and demo board opti...
int8_t LTC3676_set_overtemp_warning_level(uint8_t i2c_address, uint8_t ot_warning_level)
Writes the UV warning threshold of any buck.
Definition: LTC3676.cpp:326
static int8_t LTC3676_print_all_registers(uint8_t i2c_address)
Definition: DC1976A.ino:182
static void print_title()
Prints the title block when program first starts.
Definition: DC1976A.ino:152
#define LTC3676_SOFTWARE_CNTRL
Definition: LTC3676.h:162