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