Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1529A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1703A Demonstration Board.
3 LTC2657: Octal I2C 16-/12-Bit Rail-to-Rail DACs with 10ppm/C Max Reference.
4 
5 @verbatim
6 NOTES
7  Setup:
8  Set the terminal baud rate to 115200 and select the newline terminator.
9  The program displays calculated voltages which are based on the voltage
10  of the reference used, be it internal or external. A precision voltmeter
11  is needed to verify the actual measured voltages against the calculated
12  voltage displayed. If an external reference is used, a precision voltage
13  source is required to apply the external reference voltage. A
14  precision voltmeter is also required to measure the external reference
15  voltage. No external power supply is required. Any assembly option may
16  be used: DC1529A-A, DC1529A-B
17 
18 
19  Explanation of Commands:
20  1- Select DAC: Select one of eight DACs to test : A, B, C, D, E, F, G, H.
21 
22  2- Write to DAC input register: Value is stored in the DAC for updating
23  later, allowing multiple channels to be updated at once, either
24  through a software "Update All" command or by asserting the LDAC# pin.
25  User will be prompted to enter either a code in hex or decimal, or a
26  voltage. If a voltage is entered, a code will be calculated based on
27  the active scaling and reference parameters - ideal values if no
28  calibration was ever stored.
29 
30  3- Write and Update: Similar to item 1, but DAC is updated immediately.
31 
32  4- Update DAC: Copies the value from the input register into the DAC
33  Register. Note that a "write and update" command writes the code to
34  BOTH the input register and DAC register, so subsequent "update"
35  commands will simply re-copy the same data (no change in output.)
36 
37  5- Power Down DAC: Disable DAC output. Power supply current is reduced.
38  DAC code present in DAC registers at time of shutdown are preserved.
39 
40  6- Set reference mode, either internal or external: Selecting external
41  mode prompts for the external reference voltage, which is used directly
42  if no individual DAC calibration is stored. The selection and entered
43  voltage are stored to EEPROM so it is persistent across reset / power cycles.
44 
45  7- Calibrate DAC: Use a precision voltmeter to obtain and enter VOUT
46  readings taken with different DAC codes. Set reference mode FIRST,
47  as values are stored separately for internal and external reference
48  mode. Entries are used to calculate the closest code to send to the
49  DAC to achieve an entered voltage.
50 
51  8- Enable / Disable calibration: Switch between stored calibration
52  values and defaults. Calibration parameters are stored separately
53  for internal and external reference modes. Ideal calibration will
54  be used if the calibration parameter valid key is not set.
55 
56 
57 USER INPUT DATA FORMAT:
58  decimal : 1024
59  hex : 0x400
60  octal : 02000 (leading 0 "zero")
61  binary : B10000000000
62  float : 1024.0
63 
64 @endverbatim
65 
66 http://www.linear.com/product/LTC2657
67 
68 http://www.linear.com/product/LTC2657#demoboards
69 
70 
71 Copyright 2018(c) Analog Devices, Inc.
72 
73 All rights reserved.
74 
75 Redistribution and use in source and binary forms, with or without
76 modification, are permitted provided that the following conditions are met:
77  - Redistributions of source code must retain the above copyright
78  notice, this list of conditions and the following disclaimer.
79  - Redistributions in binary form must reproduce the above copyright
80  notice, this list of conditions and the following disclaimer in
81  the documentation and/or other materials provided with the
82  distribution.
83  - Neither the name of Analog Devices, Inc. nor the names of its
84  contributors may be used to endorse or promote products derived
85  from this software without specific prior written permission.
86  - The use of this software may or may not infringe the patent rights
87  of one or more patent holders. This license does not release you
88  from the requirement that you obtain separate licenses from these
89  patent holders to use this software.
90  - Use of the software either in source or binary form, must be run
91  on or directly connected to an Analog Devices Inc. component.
92 
93 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
94 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
95 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
96 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
97 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
98 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
99 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
100 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
101 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
102 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103  */
104 
105 /*! @file
106  @ingroup LTC2657
107 */
108 
109 #include <Arduino.h>
110 #include <stdint.h>
111 #include "Linduino.h"
112 #include "LT_SPI.h"
113 #include "UserInterface.h"
114 #include "LT_I2C.h"
115 #include "QuikEval_EEPROM.h"
116 #include "LTC2657.h"
117 #include <SPI.h>
118 #include <Wire.h>
119 
120 #define EEPROM_CAL_KEY_INT 0x5678 //!< Calibration associated with internal reference
121 #define EEPROM_CAL_KEY_EXT 0x9ABC //!< Calibration associated with external reference
122 
123 // DAC Reference State
124 // Could have been zero or 1, this allows you to use the
125 // variable "reference_mode" as the command argument to a write
126 #define REF_INTERNAL LTC2657_CMD_INTERNAL_REFERENCE //!< Stored reference state is Internal
127 #define REF_EXTERNAL LTC2657_CMD_EXTERNAL_REFERENCE //!< Stored reference state is External
128 
129 // EEPROM memory locations
130 #define STORED_REF_STATE_BASE EEPROM_CAL_STATUS_ADDRESS //!< Base address of the stored reference state
131 #define INT_CAL_VALID_BASE STORED_REF_STATE_BASE + 2 //!< Base address of the "internal ref calibration valid" flag
132 #define INT_CAL_PARAMS_BASE INT_CAL_VALID_BASE + 2 //!< Base address of the internal ref calibration parameters
133 #define EXT_CAL_VALID_BASE INT_CAL_PARAMS_BASE + 32 //!< Base address of the "external ref calibration valid" flag
134 #define EXT_CAL_PARAMS_BASE EXT_CAL_VALID_BASE + 2 //!< Base address of the external ref calibration parameters
135 #define EXT_REF_V_BASE EXT_CAL_PARAMS_BASE + 32 //!< Base address of the stored external reference voltage
136 
137 // Function Declaration
138 int8_t restore_calibration(); // Read the DAC calibration from EEPROM, Return 1 if successful, 0 if not
139 void store_calibration(); // Store the DAC calibration to the EEPROM
140 void print_title(); // Print the title block
141 void print_prompt(int16_t selected_dac); // Prompt the user for an input command
142 int16_t prompt_voltage_or_code();
143 uint16_t get_voltage(float LTC2657_lsb, int16_t LTC2657_offset);
144 uint16_t get_code();
145 int8_t calibrate_dac(uint8_t index); // Calibrate the selected DAC using a voltmeter. The routine does a linear curve fit given two data points.
146 
147 int8_t menu_1_select_dac(int16_t *selected_dac);
148 int8_t menu_2_write_to_input_register(int16_t selected_dac);
149 int8_t menu_3_write_and_update_dac(int16_t selected_dac);
150 int8_t menu_4_update_power_up_dac(int16_t selected_dac);
151 int8_t menu_5_power_down_dac(int16_t selected_dac);
152 int8_t menu_6_set_reference_mode(); // int, ext, if ext, prompt for voltage
153 int8_t menu_7_calibrate_dacs();
155 
156 // Global variables
157 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
158 static uint8_t shift_count = 0; //!< The data align shift count. For 16-bit=0, for 12-bits=4
159 static uint8_t reference_mode; //!< Tells whether to set internal or external reference
160 
161 // Global calibration variables
162 static float reference_voltage; //!< Reference voltage, either internal or external
163 static int16_t LTC2657_offset[9]; //!< DAC offset - index 8 for "all DACs"
164 static float LTC2657_lsb[9]; //!< The LTC2657 lsb - index 8 for "all DACs"
165 
166 // Constants
167 
168 //! Lookup table for DAC address. Allows the "All DACs" address to be indexed right after DAC D in loops.
169 //! This technique is very useful for devices with non-monotonic channel addresses.
171 
172 //! Used to keep track to print voltage or print code
173 enum
174 {
175  PROMPT_VOLTAGE = 0, /**< 0 */
176  PROMPT_CODE = 1 /**< 1 */
177 };
178 
179 //! Initialize Linduino
180 void setup()
181 // Setup the program
182 {
183  char demo_name[] = "DC1529"; // Demo Board Name stored in QuikEval EEPROM
184 
185  quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
186  quikeval_I2C_connect(); // Connect I2C to main data port
187  Serial.begin(115200); // Initialize the serial port to the PC
188  print_title();
191  {
193  print_prompt(0);
194  }
195 }
196 
197 //! Repeats Linduino loop
198 void loop()
199 {
200  int8_t ack=0;
201  int16_t user_command;
202  static int16_t selected_dac = 0; // The selected DAC to be updated (0=A, 1=B ... 8=All). Initialized to "A".
203  // The main control loop
204  if (demo_board_connected) // Do nothing if the demo board is not connected
205  {
206  if (Serial.available()) // Check for user input
207  {
208  user_command = read_int(); // Read the user command
209  Serial.println(user_command);
210  Serial.flush();
211  ack = 0;
212  switch (user_command)
213  {
214  case 1:
215  ack |= menu_1_select_dac(&selected_dac);
216  break;
217  case 2:
218  ack |= menu_2_write_to_input_register(selected_dac);
219  break;
220  case 3:
221  ack |= menu_3_write_and_update_dac(selected_dac);
222  break;
223  case 4:
224  ack |= menu_4_update_power_up_dac(selected_dac);
225  break;
226  case 5:
227  ack |= menu_5_power_down_dac(selected_dac);
228  break;
229  case 6:
230  ack |= menu_6_set_reference_mode(); // int, ext, if ext, prompt for voltage
231  ack |= restore_calibration();
232  break;
233  case 7:
234  ack |= menu_7_calibrate_dacs();
236  break;
237  case 8:
240  break;
241  default:
242  Serial.println("Incorrect Option");
243  break;
244  }
245  if (ack) Serial.println("I2C NACK received, check address\n");
246  Serial.println("\n*****************************************************************");
247  print_prompt(selected_dac);
248  }
249  }
250 }
251 
252 // Function Definitions
253 
254 //! Select which DAC to operate on
255 //! @return 0
256 int8_t menu_1_select_dac(int16_t *selected_dac)
257 {
258  // Select a DAC to operate on
259  Serial.print("Select DAC to operate on (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H, 8=All)");
260  *selected_dac = read_int();
261  if (*selected_dac == 8)
262  Serial.println("All");
263  else
264  Serial.println(*selected_dac);
265  return (0);
266 }
267 
268 //! Write data to input register, but do not update DAC output
269 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
270 int8_t menu_2_write_to_input_register(int16_t selected_dac)
271 {
272  int8_t ack=0;
273  uint16_t dac_code;
274 
276  dac_code = get_voltage(LTC2657_lsb[selected_dac], LTC2657_offset[selected_dac]);
277  else
278  dac_code = get_code();
279 
280  ack |= LTC2657_write(LTC2657_I2C_ADDRESS, LTC2657_CMD_WRITE, address_map[selected_dac], dac_code << shift_count);
281  return (ack);
282 }
283 
284 //!Write data to DAC register (which updates output immediately)
285 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
286 int8_t menu_3_write_and_update_dac(int16_t selected_dac)
287 {
288  int8_t ack=0;
289  uint16_t dac_code;
290 
292  dac_code = get_voltage(LTC2657_lsb[selected_dac], LTC2657_offset[selected_dac]);
293  else
294  dac_code = get_code();
295 
297  return (ack);
298 }
299 
300 //! Update DAC with data that is stored in input register, power up if sleeping
301 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
302 int8_t menu_4_update_power_up_dac(int16_t selected_dac)
303 {
304  // Update DAC
305  int8_t ack=0;
306  ack |= LTC2657_write(LTC2657_I2C_ADDRESS, LTC2657_CMD_UPDATE, address_map[selected_dac], 0x0000);
307  return (ack);
308 }
309 
310 //! Power down DAC
311 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
312 int8_t menu_5_power_down_dac(int16_t selected_dac)
313 {
314  // Power down DAC
315  int8_t ack=0;
317  return (ack);
318 }
319 
320 //! Set reference mode and store to EEPROM
321 //! @return 0
322 int8_t menu_6_set_reference_mode(void) // int, ext, if ext, prompt for voltage
323 {
324  int16_t user_input;
325  Serial.println("Select reference mode - 0 for Internal, 1 for External");
326  user_input = read_int();
327  if (user_input == 1)
328  {
330  Serial.println("External reference mode; enter external reference voltage");
332  Serial.print(reference_voltage, 5);
333  Serial.println("V");
335  }
336  else
337  {
339  Serial.println("Internal reference mode selected");
340  }
341  Serial.println("Writing reference mode to EEPROM\n\n");
343  return(0);
344 }
345 
346 //! Calibrate all DACs by measuring two known outputs
347 //! @return 0
349 {
350  // Calibrate the DACs using a multi-meter
351  uint8_t i;
352  for (i = 0; i < 8; i++)
353  {
354  calibrate_dac(i); // Run calibration routine
355  }
357  return (0);
358 }
359 
360 //! Enable / Disable calibration. Use with caution - behavior is undefined if you enable calibration and an actual
361 //! calibration cycle has not been performed.
362 //! @return 0
364 {
365  int16_t user_input;
366  Serial.println(F("\n\nSelect option - 0: Enable Internal, 1: Disable Internal, 2: Enable External, 3: Disable External"));
367  user_input = read_int();
368  switch (user_input)
369  {
370  case 0:
371  Serial.println(F("Enabling Internal Cal Params"));
373  break;
374  case 1:
375  Serial.println(F("Disabling Internal Cal Params"));
377  break;
378  case 2:
379  Serial.println(F("Enabling External Cal Params"));
381  break;
382  case 3:
383  Serial.println(F("Disabling External Cal Params"));
385  break;
386  }
387  return(0);
388 }
389 
390 //! Read stored calibration parameters from nonvolatile EEPROM on demo board
391 //! @return Return 1 if successful, 0 if not
393 // Read the DAC calibration from EEPROM
394 // Return 1 if successful, 0 if not
395 {
396  int8_t ack=0;
397  int16_t intvalid, extvalid;
398  uint8_t i, eeaddr;
399  float dac_count; // The number of codes, 4096 for 12 bits, 65536 for 16 bits
400 
401  Serial.println(F("\n\nReading Calibration parameters from EEPROM..."));
402  float full_scale; // To avoid confusion - in internal ref mode, FS=Vref, in ext mode, FS=2*Vref
403  // Read the cal keys from the EEPROM.
406  // Read the stored reference state
408  // Read external ref V unconditionally, overwrite with defaults if no cal found
410 
411  if (reference_mode == REF_EXTERNAL)
412  {
413  Serial.println(F("Restored external ref. Voltage:"));
414  Serial.println(reference_voltage, 5);
415  }
416  else // EITHER reference is set to internal, OR not programmed in which case default to internal
417  {
418  reference_mode = REF_INTERNAL; // Redundant if already set
419  Serial.println("Internal reference mode set");
420  }
421 
422  // Write the reference mode to the DAC right away
423  ack |= LTC2657_write(LTC2657_I2C_ADDRESS, reference_mode, 0x0F, 0x0000);
424 
425  // Set up default values, shift count, DAC count
426  // Calibration parameters MAY be changed next, if match
427  // between reference mode and stored calibration
428  full_scale = reference_voltage * 2.0; // If external ref mode, this applies.
429 
430  // The following two IF statements are used to allow the program to run with
431  // a QuikEval string that does not contain the demo board option.
432  // If the demo board option is found then these values are overwritten.
433  if (strcmp(demo_board.product_name, "LTC2657-L") == 0)
434  {
435  // LTC2657CUF-L16, 16-bits, 2.5V full scale
436  shift_count = 0;
437  if (reference_mode == REF_INTERNAL) full_scale = 2.5;
438  dac_count = 65536;
439  }
440  if (strcmp(demo_board.product_name, "LTC2657-H") == 0)
441  {
442  // LTC2657CUF-H16, 16-bits, 4.096V full scale
443  shift_count = 0;
444  if (reference_mode == REF_INTERNAL) full_scale = 4.096;
445  dac_count = 65536;
446  }
447 
448  switch (demo_board.option)
449  {
450  case 'A':
451  // LTC2657CUF-L16, 16-bits, 2.5V full scale
452  shift_count = 0;
453  if (reference_mode == REF_INTERNAL) full_scale = 2.5;
454  dac_count = 65536;
455  break;
456  case 'B':
457  // LTC2657CUF-H16, 16-bits, 4.096V full scale
458  shift_count = 0;
459  if (reference_mode == REF_INTERNAL) full_scale = 4.096;
460  dac_count = 65536;
461  break;
462  case 'C':
463  // LTC2657CUF-L12, 12-bits, 2.5V full scale
464  // Note: There are no demo boards for the 12-bit version. These are shown to
465  // show how to implement the 12-bit versions.
466  shift_count = 4;
467  if (reference_mode == REF_INTERNAL) full_scale = 2.5;
468  dac_count = 4096;
469  break;
470  case 'D':
471  // LTC2657CUF-H12, 12-bits, 4.096V full scale
472  // Note: There are no demo boards for the 12-bit version. These are shown to
473  // show how to implement the 12-bit versions.
474  shift_count = 4;
475  if (reference_mode == REF_INTERNAL) full_scale = 4.096;
476  dac_count = 4096;
477  break;
478  }
479 
480  for (i = 0; i <= 8; i++)
481  {
482  LTC2657_offset[i] = 0;
483  LTC2657_lsb[i] = full_scale / dac_count;
484  }
485 
486  // Restore calibration IF reference mode matches stored calibration
487  eeaddr = 0; // Assume no calibration present or mismatch between cal and reference mode
488 
489  if ((intvalid == EEPROM_CAL_KEY) && (reference_mode == REF_INTERNAL))
490  {
491  eeaddr = INT_CAL_PARAMS_BASE;
492  Serial.println(F("Found internal calibration, restoring...)"));
493  }
494  else if ((extvalid == EEPROM_CAL_KEY) && (reference_mode == REF_EXTERNAL))
495  {
496  eeaddr = EXT_CAL_PARAMS_BASE;
497  Serial.println(F("Found external calibration, restoring...)"));
498  }
499  else Serial.println(F("Calibration not found for this\nreference mode, using ideal calibration"));
500 
501  if (eeaddr != 0) // If cal key was enabled and reference mode is correct, read offset and lsb
502  {
519  LTC2657_offset[8] = LTC2657_offset[0]; // Copy cal value for DAC A to cal value for
520  LTC2657_lsb[8] = LTC2657_lsb[0]; // DAC ALL
521  Serial.println("Calibration Restored");
522  }
523  for (i=0; i<=8; ++i)
524  {
525  Serial.print("DAC ");
526  Serial.print((char) ('A' + i));
527  Serial.print(" offset: ");
528  Serial.print(LTC2657_offset[i]);
529  Serial.print(" , lsb: ");
530  Serial.print(LTC2657_lsb[i]*1000, 4);
531  Serial.println(" mv");
532  }
533  Serial.println("(DAC I applies to ALL DACs selections)");
534  if (eeaddr != 0) return (1);
535  return (ack);
536 }
537 
538 //! Store measured calibration parameters to nonvolatile EEPROM on demo board
540 // Store the DAC calibration to the EEPROM
541 {
542  uint8_t eeaddr;
544  {
546  eeaddr = INT_CAL_PARAMS_BASE;
547  }
548  else
549  {
551  eeaddr = EXT_CAL_PARAMS_BASE;
552  }
553 
562  eeprom_write_float(EEPROM_I2C_ADDRESS, LTC2657_lsb[0], eeaddr + 16); // lsb
570  Serial.println(F("Calibration Stored to EEPROM"));
571 }
572 
573 //! Prompt user to enter a voltage or digital code to send to DAC
574 //! @return prompt type
576 {
577  int16_t user_input;
578  Serial.print(F("Type 1 to enter voltage, 2 to enter code:"));
579  Serial.flush();
580  user_input = read_int();
581  Serial.println(user_input);
582 
583  if (user_input != 2)
584  return(PROMPT_VOLTAGE);
585  else
586  return(PROMPT_CODE);
587 }
588 
589 //! Get voltage from user input, calculate DAC code based on lsb, offset
590 //! @return Returns DAC voltage
591 uint16_t get_voltage(float LTC2657_lsb, int16_t LTC2657_offset)
592 {
593  float dac_voltage;
594 
595  Serial.print(F("Enter Desired DAC output voltage: "));
596  dac_voltage = read_float();
597  Serial.print(dac_voltage);
598  Serial.println(" V");
599  Serial.flush();
600  return(LTC2657_voltage_to_code(dac_voltage, LTC2657_lsb, LTC2657_offset));
601 }
602 
603 //! Get code to send to DAC directly, in decimal, hex, or binary
604 //! @return Returns DAC code from user
605 uint16_t get_code()
606 {
607  uint16_t returncode;
608  Serial.println("Enter Desired DAC Code");
609  Serial.print("(Format 32768, 0x8000, 0100000, or B1000000000000000): ");
610  returncode = (uint16_t) read_int();
611  Serial.print("0x");
612  Serial.println(returncode, HEX);
613  Serial.flush();
614  return(returncode);
615 }
616 
617 //! Prints the title block when program first starts.
619 {
620  Serial.println("");
621  Serial.println(F("*****************************************************************"));
622  Serial.println(F("* DC1529 Demonstration Program *"));
623  Serial.println(F("* *"));
624  Serial.println(F("* This program demonstrates how to send data to the LTC2657 *"));
625  Serial.println(F("* Octal 16/12-bit DAC found on the DC1529 demo board. *"));
626  Serial.println(F("* *"));
627  Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
628  Serial.println(F("* *"));
629  Serial.println(F("*****************************************************************"));
630 }
631 
632 //! Prints main menu.
633 void print_prompt(int16_t selected_dac)
634 {
635  Serial.println(F("\nCommand Summary:"));
636  Serial.println(F(" 1-Select DAC"));
637  Serial.println(F(" 2-Write to input register (no update)"));
638  Serial.println(F(" 3-Write and update DAC"));
639  Serial.println(F(" 4-Update / power up DAC"));
640  Serial.println(F(" 5-Power down DAC"));
641  Serial.println(F(" 6-Set reference mode"));
642  Serial.println(F(" 7-Calibrate DAC"));
643  Serial.println(F(" 8-Enable / Disable calibration"));
644 
645  Serial.println("\nPresent Values:");
646  Serial.print(" Selected DAC: ");
647  if (selected_dac != 8)
648  Serial.println((char) (selected_dac + 0x41));
649  else
650  Serial.println("All");
651  Serial.print(" DAC Reference: ");
653  Serial.println("Internal");
654  else
655  {
656  Serial.print(F("External "));
657  Serial.print(reference_voltage, 5);
658  Serial.println(F("V reference, please verify"));
659  }
660  Serial.print(F("Enter a command:"));
661  Serial.flush();
662 }
663 
664 //! Calibrate the selected DAC using a voltmeter. The routine
665 //! does a linear curve fit given two data points.
666 //! @return ACK bit (0=acknowledge, 1=no acknowledge)
667 int8_t calibrate_dac(uint8_t index)
668 {
669  int8_t ack=0;
670  uint16_t code1 = 0x0200; //! Calibration code 1
671  uint16_t code2 = 0xFFFF; //! Calibration code 2
672  float voltage1; //! Calibration voltage 1
673  float voltage2; //! Calibration voltage 2
674  Serial.println("");
675  Serial.print("Calibrating DAC ");
676  Serial.println((char) (0x41 + index));
677  // Left align 12-bit code1 to 16 bits & write to DAC
679  Serial.print("DAC code set to 0x");
680  Serial.println(code1, HEX);
681  Serial.print("Enter measured DAC voltage:");
682  voltage1 = read_float();
683  Serial.print(voltage1, 6);
684  Serial.println(" V");
685  // Left align 12-bit code2 to 16 bits & write to DAC
687  Serial.print("DAC code set to 0x");
688  Serial.println(code2, HEX);
689  Serial.print("Enter measured DAC voltage:");
690  voltage2 = read_float();
691  Serial.print(voltage2, 6);
692  Serial.println(" V");
693  LTC2657_calibrate(code1, code2, voltage1, voltage2, &LTC2657_lsb[index], &LTC2657_offset[index]);
694  return(ack);
695 }
struct demo_board_type demo_board
Instantiate demo board structure.
static uint8_t reference_mode
Tells whether to set internal or external reference.
Definition: DC1529A.ino:159
static int8_t menu_4_update_power_up_dac(int16_t selected_dac)
Update DAC with data that is stored in input register, power up if sleeping.
Definition: DC1529A.ino:302
char option
Demo Circuit option (A)
#define LTC2657_DAC_ALL
Definition: LTC2657.h:167
uint8_t eeprom_read_int16(uint8_t i2c_address, int16_t *read_data, uint16_t address)
Read the two byte integer data from the EEPROM starting at address.
#define LTC2657_CMD_WRITE_UPDATE
Definition: LTC2657.h:148
unsigned char user_command
#define EEPROM_I2C_ADDRESS
uint8_t eeprom_write_byte(uint8_t i2c_address, char data, uint16_t address)
Write the data byte to the EEPROM with i2c_address starting at EEPROM address.
#define LTC2657_CMD_WRITE
Definition: LTC2657.h:146
uint16_t LTC2657_voltage_to_code(float dac_voltage, float LTC2657_lsb, int16_t LTC2657_offset)
Calculate a LTC2657 DAC code given the desired output voltage and DAC address (0-3) ...
Definition: LTC2657.cpp:91
Header File for Linduino Libraries and Demo Code.
#define LTC2657_DAC_F
Definition: LTC2657.h:164
uint8_t eeprom_read_float(uint8_t i2c_address, float *read_data, uint16_t address)
Read the four byte float data from the EEPROM starting at address.
#define STORED_REF_STATE_BASE
Base address of the stored reference state.
Definition: DC1529A.ino:130
#define LTC2657_DAC_H
Definition: LTC2657.h:166
#define LTC2657_DAC_B
Definition: LTC2657.h:160
static int8_t menu_1_select_dac(int16_t *selected_dac)
Select which DAC to operate on.
Definition: DC1529A.ino:256
static int8_t menu_3_write_and_update_dac(int16_t selected_dac)
Write data to DAC register (which updates output immediately)
Definition: DC1529A.ino:286
static int8_t menu_8_enable_calibration()
Enable / Disable calibration.
Definition: DC1529A.ino:363
#define EXT_CAL_VALID_BASE
Base address of the "external ref calibration valid" flag.
Definition: DC1529A.ino:133
static void print_title()
Prints the title block when program first starts.
Definition: DC1529A.ino:618
uint8_t eeprom_write_float(uint8_t i2c_address, float write_data, uint16_t address)
Write the 4 byte float data to the EEPROM starting at address.
void LTC2657_calibrate(uint16_t dac_code1, uint16_t dac_code2, float voltage1, float voltage2, float *LTC2657_lsb, int16_t *LTC2657_offset)
Calculate the LTC2657 offset and LSB voltages given two measured voltages and their corresponding cod...
Definition: LTC2657.cpp:112
#define INT_CAL_VALID_BASE
Base address of the "internal ref calibration valid" flag.
Definition: DC1529A.ino:131
uint8_t eeprom_write_int16(uint8_t i2c_address, int16_t write_data, uint16_t address)
Write the 2 byte integer data to the EEPROM starting at address.
static void setup()
Initialize Linduino.
Definition: DC1529A.ino:180
static int8_t calibrate_dac(uint8_t index)
Calibrate the selected DAC using a voltmeter.
Definition: DC1529A.ino:667
static int16_t LTC2657_offset[9]
DAC offset - index 8 for "all DACs".
Definition: DC1529A.ino:163
uint8_t eeprom_read_byte(uint8_t i2c_address, char *data, uint16_t address)
Read a data byte at address from the EEPROM with i2c_address.
static void print_prompt(int16_t selected_dac)
Prints main menu.
Definition: DC1529A.ino:633
QuikEval EEPROM Library.
int8_t LTC2657_write(uint8_t i2c_address, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code)
Write a 16-bit dac_code to the LTC2657.
Definition: LTC2657.cpp:82
#define EXT_REF_V_BASE
Base address of the stored external reference voltage.
Definition: DC1529A.ino:135
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
static uint16_t get_code()
Get code to send to DAC directly, in decimal, hex, or binary.
Definition: DC1529A.ino:605
#define LTC2657_CMD_POWER_DOWN
Definition: LTC2657.h:149
static uint8_t shift_count
The data align shift count.
Definition: DC1529A.ino:158
static int8_t menu_2_write_to_input_register(int16_t selected_dac)
Write data to input register, but do not update DAC output.
Definition: DC1529A.ino:270
#define LTC2657_DAC_E
Definition: LTC2657.h:163
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1529A.ino:157
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
const uint8_t address_map[9]
Lookup table for DAC address.
Definition: DC1529A.ino:170
static void loop()
Repeats Linduino loop.
Definition: DC1529A.ino:198
static void store_calibration()
Store measured calibration parameters to nonvolatile EEPROM on demo board.
Definition: DC1529A.ino:539
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
#define LTC2657_I2C_ADDRESS
Definition: LTC2657.h:112
int32_t read_int()
static int index
float read_float()
char product_name[15]
LTC Product (LTC2654-L16)
static int16_t prompt_voltage_or_code()
Prompt user to enter a voltage or digital code to send to DAC.
Definition: DC1529A.ino:575
static int8_t restore_calibration()
Read stored calibration parameters from nonvolatile EEPROM on demo board.
Definition: DC1529A.ino:392
#define LTC2657_CMD_UPDATE
Definition: LTC2657.h:147
static int8_t menu_7_calibrate_dacs()
Calibrate all DACs by measuring two known outputs.
Definition: DC1529A.ino:348
static float reference_voltage
Reference voltage, either internal or external.
Definition: DC1529A.ino:162
static float LTC2657_lsb[9]
The LTC2657 lsb - index 8 for "all DACs".
Definition: DC1529A.ino:164
static int8_t menu_5_power_down_dac(int16_t selected_dac)
Power down DAC.
Definition: DC1529A.ino:312
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 int8_t menu_6_set_reference_mode()
Set reference mode and store to EEPROM.
Definition: DC1529A.ino:322
#define LTC2657_DAC_C
Definition: LTC2657.h:161
#define LTC2657_DAC_G
Definition: LTC2657.h:165
#define EEPROM_CAL_KEY
static uint16_t get_voltage(float LTC2657_lsb, int16_t LTC2657_offset)
Get voltage from user input, calculate DAC code based on lsb, offset.
Definition: DC1529A.ino:591
#define LTC2657_DAC_A
Definition: LTC2657.h:159
#define LTC2657_DAC_D
Definition: LTC2657.h:162
#define INT_CAL_PARAMS_BASE
Base address of the internal ref calibration parameters.
Definition: DC1529A.ino:132
#define REF_EXTERNAL
Stored reference state is External.
Definition: DC1529A.ino:127
#define EXT_CAL_PARAMS_BASE
Base address of the external ref calibration parameters.
Definition: DC1529A.ino:134
LTC2657: Octal I2C 16-/12-Bit Rail-to-Rail DACs with 10ppm/C Max Reference.
#define REF_INTERNAL
Stored reference state is Internal.
Definition: DC1529A.ino:126