Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
DC1397A.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1397A Demonstration Board.
3 LTC2656: Quad SPI 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 be
16  used: DC1397A-A, DC1397A-B
17 
18 
19  Explanation of Commands:
20  1- Select DAC: Select one of four 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 for
53  internal and external reference modes. Ideal calibration will be used
54  if the calibration parameter valid key is not set.
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/LTC2656
66 
67 http://www.linear.com/product/LTC2656#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 LTC2656
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 "LTC2656.h"
116 #include <SPI.h>
117 #include <Wire.h>
118 
119 #define EEPROM_CAL_KEY_INT 0x5678 //!< Calibration associated with internal reference
120 #define EEPROM_CAL_KEY_EXT 0x9ABC //!< Calibration associated with external reference
121 
122 // DAC Reference State
123 // Could have been zero or 1, this allows you to use the
124 // variable "reference_mode" as the command argument to a write
125 #define REF_INTERNAL LTC2656_CMD_INTERNAL_REFERENCE //!< Stored reference state is Internal
126 #define REF_EXTERNAL LTC2656_CMD_EXTERNAL_REFERENCE //!< Stored reference state is External
127 
128 // EEPROM memory locations
129 #define STORED_REF_STATE_BASE EEPROM_CAL_STATUS_ADDRESS //!< Base address of the stored reference state
130 #define INT_CAL_VALID_BASE STORED_REF_STATE_BASE + 2 //!< Base address of the "internal ref calibration valid" flag
131 #define INT_CAL_PARAMS_BASE INT_CAL_VALID_BASE + 2 //!< Base address of the internal ref calibration parameters
132 #define EXT_CAL_VALID_BASE INT_CAL_PARAMS_BASE + 32 //!< Base address of the "external ref calibration valid" flag
133 #define EXT_CAL_PARAMS_BASE EXT_CAL_VALID_BASE + 2 //!< Base address of the external ref calibration parameters
134 #define EXT_REF_V_BASE EXT_CAL_PARAMS_BASE + 32 //!< Base address of the stored external reference voltage
135 
136 // Function Declaration
137 int8_t restore_calibration(); // Read the DAC calibration from EEPROM, Return 1 if successful, 0 if not
138 void store_calibration(); // Store the DAC calibration to the EEPROM
139 void print_title(); // Print the title block
140 void print_prompt(int16_t selected_dac); // Prompt the user for an input command
141 int16_t prompt_voltage_or_code();
142 uint16_t get_voltage(float LTC2656_lsb, int16_t LTC2656_offset);
143 uint16_t get_code();
144 void calibrate_dac(uint8_t index); // Calibrate the selected DAC using a voltmeter. The routine does a linear curve fit given two data points.
145 
146 void menu_1_select_dac(int16_t *selected_dac);
147 void menu_2_write_to_input_register(int16_t selected_dac);
148 void menu_3_write_and_update_dac(int16_t selected_dac);
149 void menu_4_update_power_up_dac(int16_t selected_dac);
150 void menu_5_power_down_dac(int16_t selected_dac);
151 void menu_6_set_reference_mode(); // int, ext, if ext, prompt for voltage
152 void menu_7_calibrate_dacs();
154 
155 // Global variables
156 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
157 static uint8_t shift_count = 0; //!< The data align shift count. For 16-bit=0, for 12-bits=4
158 static uint8_t reference_mode; //!< Tells whether to set internal or external reference
159 
160 // Global calibration variables
161 static float reference_voltage; //!< Reference voltage, either internal or external
162 static int16_t LTC2656_offset[9]; //!< DAC offset - index 8 for "all DACs"
163 static float LTC2656_lsb[9]; //!< The LTC2656 lsb - index 8 for "all DACs"
164 
165 // Constants
166 
167 //! Lookup table for DAC address. Allows the "All DACs" address to be indexed right after DAC D in loops.
168 //! This technique is very useful for devices with non-monotonic channel addresses.
171  }; //<! Map entered option 0..2 to DAC address
172 
173 //! Used to choose between voltage and code
174 enum
175 {
176  PROMPT_VOLTAGE = 0, /**< 0 */
177  PROMPT_CODE = 1 /**< 1 */
178 };
179 
180 //! Initialize Linduino
181 void setup()
182 // Setup the program
183 {
184  char demo_name[] = "DC1397"; // Demo Board Name stored in QuikEval EEPROM
185  quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
186  quikeval_SPI_connect(); // Connect SPI to main data port
187  quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
188  Serial.begin(115200); // Initialize the serial port to the PC
189  print_title();
192  {
194  print_prompt(0);
195  }
196 }
197 
198 //! Repeats Linduino loop
199 void loop()
200 {
201  int16_t user_command;
202  static int16_t selected_dac = 0; // The selected DAC to be updated (0=A, 1=B ... 5=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  switch (user_command)
212  {
213  case 1:
214  menu_1_select_dac(&selected_dac);
215  break;
216  case 2:
217  menu_2_write_to_input_register(selected_dac);
218  break;
219  case 3:
220  menu_3_write_and_update_dac(selected_dac);
221  break;
222  case 4:
223  menu_4_update_power_up_dac(selected_dac);
224  break;
225  case 5:
226  menu_5_power_down_dac(selected_dac);
227  break;
228  case 6:
229  menu_6_set_reference_mode(); // int, ext, if ext, prompt for voltage
231  break;
232  case 7:
235  break;
236  case 8:
239  break;
240  default:
241  Serial.println("Incorrect Option");
242  break;
243  }
244  Serial.println("\n*****************************************************************");
245  print_prompt(selected_dac);
246  }
247  }
248 }
249 
250 // Function Definitions
251 
252 //! Select which DAC to operate on
253 void menu_1_select_dac(int16_t *selected_dac)
254 {
255  // Select a DAC to operate on
256  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)");
257  *selected_dac = read_int();
258  if (*selected_dac == 8)
259  Serial.println("All");
260  else
261  Serial.println(*selected_dac);
262 }
263 
264 //! Write data to input register, but do not update DAC output
265 void menu_2_write_to_input_register(int16_t selected_dac)
266 {
267  uint16_t dac_code;
268 
270  dac_code = get_voltage(LTC2656_lsb[selected_dac], LTC2656_offset[selected_dac]);
271  else
272  dac_code = get_code();
273 
274  LTC2656_write(LTC2656_CS, LTC2656_CMD_WRITE, address_map[selected_dac], dac_code << shift_count);
275 }
276 
277 //!Write data to DAC register (which updates output immediately)
278 void menu_3_write_and_update_dac(int16_t selected_dac)
279 {
280  uint16_t dac_code;
281 
283  dac_code = get_voltage(LTC2656_lsb[selected_dac], LTC2656_offset[selected_dac]);
284  else
285  dac_code = get_code();
286 
288 }
289 
290 //! Update DAC with data that is stored in input register, power up if sleeping
291 void menu_4_update_power_up_dac(int16_t selected_dac)
292 {
293  // Update DAC
294  LTC2656_write(LTC2656_CS, LTC2656_CMD_UPDATE, address_map[selected_dac], 0x0000);
295 }
296 
297 //! Power down DAC
298 void menu_5_power_down_dac(int16_t selected_dac)
299 {
300  // Power down DAC
302 }
303 
304 //! Set reference mode and store to EEPROM
305 void menu_6_set_reference_mode(void) // int, ext, if ext, prompt for voltage
306 {
307  int16_t user_input;
308  Serial.println("Select reference mode - 0 for Internal, 1 for External");
309  user_input = read_int();
310  if (user_input == 1)
311  {
313  Serial.println("External reference mode; enter external reference voltage");
315  Serial.print(reference_voltage, 5);
316  Serial.println("V");
318  }
319  else
320  {
322  Serial.println("Internal reference mode selected");
323  }
324  Serial.println("Writing reference mode to EEPROM\n\n");
326 }
327 
328 //! Calibrate all DACs by measuring two known outputs
330 {
331  // Calibrate the DACs using a multimeter
332  uint8_t i;
333  for (i = 0; i < 8; i++)
334  {
335  calibrate_dac(i); // Run calibration routine
336  }
338 }
339 
340 //! Enable / Disable calibration. Use with caution - behavior is undefined if you enable calibration and an actual
341 //! calibration cycle has not been performed.
343 {
344  int16_t user_input;
345  Serial.println(F("\n\nSelect option - 0: Enable Internal, 1: Disable Internal, 2: Enable External, 3: Disable External"));
346  user_input = read_int();
347  switch (user_input)
348  {
349  case 0:
350  Serial.println(F("Enabling Internal Cal Params"));
352  break;
353  case 1:
354  Serial.println(F("Disabling Internal Cal Params"));
356  break;
357  case 2:
358  Serial.println(F("Enabling External Cal Params"));
360  break;
361  case 3:
362  Serial.println(F("Disabling External Cal Params"));
364  break;
365  }
366 }
367 
368 //! Read stored calibration parameters from nonvolatile EEPROM on demo board
369 //! @return Return 1 if successful, 0 if not
371 // Read the DAC calibration from EEPROM
372 // Return 1 if successful, 0 if not
373 {
374  int16_t intvalid, extvalid;
375  uint8_t i, eeaddr;
376  float dac_count; // The number of codes, 4096 for 12 bits, 65536 for 16 bits
377 
378  Serial.println(F("\n\nReading Calibration parameters from EEPROM..."));
379  float full_scale; // To avoid confusion - in internal ref mode, FS=Vref, in ext mode, FS=2*Vref
380  // Read the cal keys from the EEPROM.
383  // Read the stored reference state
385  // Read external ref V unconditionally, overwrite with defaults if no cal found
387 
388  if (reference_mode == REF_EXTERNAL)
389  {
390  Serial.println(F("Restored external ref. Voltage:"));
391  Serial.println(reference_voltage, 5);
392  }
393  else // EITHER reference is set to internal, OR not programmed in which case default to internal
394  {
395  reference_mode = REF_INTERNAL; // Redundant if already set
396  Serial.println("Internal reference mode set");
397  }
398 
399  // Write the reference mode to the DAC right away
400  LTC2656_write(LTC2656_CS, reference_mode, 0x0F, 0x0000);
401 
402  // Set up default values, shift count, DAC count
403  // Calibration parameters MAY be changed next, if match
404  // between reference mode and stored calibration
405  full_scale = reference_voltage * 2.0; // If external ref mode, this applies.
406 
407  // The following two IF statements are used to allow the program to run with
408  // a QuikEval string that does not contain the demo board option.
409  // If the demo board option is found then these values are overwritten.
410  if (strcmp(demo_board.product_name, "LTC2656-L16") == 0)
411  {
412  // LTC2657CUF-L16, 16-bits, 2.5V full scale
413  shift_count = 0;
414  if (reference_mode == REF_INTERNAL) full_scale = 2.5;
415  dac_count = 65536;
416  }
417  if (strcmp(demo_board.product_name, "LTC2656-H16") == 0)
418  {
419  // LTC2657CUF-H16, 16-bits, 4.096V full scale
420  shift_count = 0;
421  if (reference_mode == REF_INTERNAL) full_scale = 4.096;
422  dac_count = 65536;
423  }
424 
425  switch (demo_board.option)
426  {
427  case 'A':
428  // LTC2656CUF-L16, 16-bits, 2.5V full scale
429  shift_count = 0;
430  if (reference_mode == REF_INTERNAL) full_scale = 2.5;
431  dac_count = 65536;
432  break;
433  case 'B':
434  // LTC2656CUF-H16, 16-bits, 4.096V full scale
435  shift_count = 0;
436  if (reference_mode == REF_INTERNAL) full_scale = 4.096;
437  dac_count = 65536;
438  break;
439  case 'C':
440  // LTC2656CUF-L12, 12-bits, 2.5V full scale
441  shift_count = 4;
442  if (reference_mode == REF_INTERNAL) full_scale = 2.5;
443  dac_count = 4096;
444  break;
445  case 'D':
446  // LTC2656CUF-H12, 12-bits, 4.096V full scale
447  shift_count = 4;
448  if (reference_mode == REF_INTERNAL) full_scale = 4.096;
449  dac_count = 4096;
450  break;
451  }
452 
453  for (i = 0; i <= 8; i++)
454  {
455  LTC2656_offset[i] = 0;
456  LTC2656_lsb[i] = full_scale / dac_count;
457  }
458 
459  // Restore calibration IF reference mode matches stored calibration
460  eeaddr = 0; // Assume no calibration present or mismatch between cal and reference mode
461 
462  if ((intvalid == EEPROM_CAL_KEY) && (reference_mode == REF_INTERNAL))
463  {
464  eeaddr = INT_CAL_PARAMS_BASE;
465  Serial.println(F("Found internal calibration, restoring...)"));
466  }
467  else if ((extvalid == EEPROM_CAL_KEY) && (reference_mode == REF_EXTERNAL))
468  {
469  eeaddr = EXT_CAL_PARAMS_BASE;
470  Serial.println(F("Found external calibration, restoring...)"));
471  }
472  else Serial.println(F("Calibration not found for this\nreference mode, using ideal calibration"));
473 
474  if (eeaddr != 0) // If cal key was enabled and reference mode is correct, read offset and lsb
475  {
492  LTC2656_offset[8] = LTC2656_offset[0]; // Copy cal value for DAC A to cal value for
493  LTC2656_lsb[8] = LTC2656_lsb[0]; // DAC ALL
494  Serial.println("Calibration Restored");
495  }
496  for (i=0; i<=8; ++i)
497  {
498  Serial.print("DAC ");
499  Serial.print((char) ('A' + i));
500  Serial.print(" offset: ");
501  Serial.print(LTC2656_offset[i]);
502  Serial.print(" , lsb: ");
503  Serial.print(LTC2656_lsb[i]*1000, 4);
504  Serial.println(" mV");
505  }
506  Serial.println("(DAC I applies to ALL DACs selections)");
507  if (eeaddr != 0) return (1);
508  return (0);
509 }
510 
511 //! Store measured calibration parameters to nonvolatile EEPROM on demo board
513 // Store the DAC calibration to the EEPROM
514 {
515  uint8_t eeaddr;
517  {
519  eeaddr = INT_CAL_PARAMS_BASE;
520  }
521  else
522  {
524  eeaddr = EXT_CAL_PARAMS_BASE;
525  }
526 
535  eeprom_write_float(EEPROM_I2C_ADDRESS, LTC2656_lsb[0], eeaddr + 16); // lsb
539  eeprom_write_float(EEPROM_I2C_ADDRESS, LTC2656_lsb[4], eeaddr + 32); // lsb
543  Serial.println(F("Calibration Stored to EEPROM"));
544 }
545 
546 //! Prompt user to enter a voltage or digital code to send to DAC
548 {
549  int16_t user_input;
550  Serial.print(F("Type 1 to enter voltage, 2 to enter code:"));
551  Serial.flush();
552  user_input = read_int();
553  Serial.println(user_input);
554 
555  if (user_input != 2)
556  return(PROMPT_VOLTAGE);
557  else
558  return(PROMPT_CODE);
559 }
560 
561 //! Get voltage from user input, calculate DAC code based on lsb, offset
562 uint16_t get_voltage(float LTC2656_lsb, int16_t LTC2656_offset)
563 {
564  float dac_voltage;
565 
566  Serial.print(F("Enter Desired DAC output voltage: "));
567  dac_voltage = read_float();
568  Serial.print(dac_voltage);
569  Serial.println(" V");
570  Serial.flush();
571  return(LTC2656_voltage_to_code(dac_voltage, LTC2656_lsb, LTC2656_offset));
572 }
573 
574 //! Get code to send to DAC directly, in decimal, hex, or binary
575 uint16_t get_code()
576 {
577  uint16_t returncode;
578  Serial.println("Enter Desired DAC Code");
579  Serial.print("(Format 32768, 0x8000, 0100000, or B1000000000000000): ");
580  returncode = (uint16_t) read_int();
581  Serial.print("0x");
582  Serial.println(returncode, HEX);
583  Serial.flush();
584  return(returncode);
585 }
586 
587 //! Prints the title block when program first starts.
589 {
590  Serial.println("");
591  Serial.println(F("*****************************************************************"));
592  Serial.println(F("* DC1397 Demonstration Program *"));
593  Serial.println(F("* *"));
594  Serial.println(F("* This program demonstrates how to send data to the LTC2656 *"));
595  Serial.println(F("* quad 16/12-bit DAC found on the DC1397 demo board. *"));
596  Serial.println(F("* *"));
597  Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
598  Serial.println(F("* *"));
599  Serial.println(F("*****************************************************************"));
600 }
601 
602 //! Prints main menu.
603 void print_prompt(int16_t selected_dac)
604 {
605  Serial.println(F("\nCommand Summary:"));
606  Serial.println(F(" 1-Select DAC"));
607  Serial.println(F(" 2-Write to input register (no update)"));
608  Serial.println(F(" 3-Write and update DAC"));
609  Serial.println(F(" 4-Update / power up DAC"));
610  Serial.println(F(" 5-Power down DAC"));
611  Serial.println(F(" 6-Set reference mode"));
612  Serial.println(F(" 7-Calibrate DAC"));
613  Serial.println(F(" 8-Enable / Disable calibration"));
614 
615  Serial.println("\nPresent Values:");
616  Serial.print(" Selected DAC: ");
617  if (selected_dac != 8)
618  Serial.println((char) (selected_dac + 0x41));
619  else
620  Serial.println("All");
621 
622  Serial.print(" DAC Reference: ");
624  Serial.println("Internal");
625  else
626  {
627  Serial.print(F("External "));
628  Serial.print(reference_voltage, 5);
629  Serial.println(F("V reference, please verify"));
630  }
631  Serial.print(F("Enter a command:"));
632  Serial.flush();
633 }
634 
635 //! Calibrate the selected DAC using a voltmeter. The routine
636 //! does a linear curve fit given two data points.
637 void calibrate_dac(uint8_t index)
638 {
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  LTC2656_calibrate(code1, code2, voltage1, voltage2, &LTC2656_lsb[index], &LTC2656_offset[index]);
663 }
struct demo_board_type demo_board
Instantiate demo board structure.
#define EXT_CAL_VALID_BASE
Base address of the "external ref calibration valid" flag.
Definition: DC1397A.ino:132
char option
Demo Circuit option (A)
static float LTC2656_lsb[9]
The LTC2656 lsb - index 8 for "all DACs".
Definition: DC1397A.ino:163
#define LTC2656_CMD_POWER_DOWN
Power down n.
Definition: LTC2656.h:116
static void calibrate_dac(uint8_t index)
Calibrate the selected DAC using a voltmeter.
Definition: DC1397A.ino:637
#define INT_CAL_PARAMS_BASE
Base address of the internal ref calibration parameters.
Definition: DC1397A.ino:131
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.
static void print_title()
Prints the title block when program first starts.
Definition: DC1397A.ino:588
#define LTC2656_DAC_F
Definition: LTC2656.h:131
unsigned char user_command
static void menu_3_write_and_update_dac(int16_t selected_dac)
Write data to DAC register (which updates output immediately)
Definition: DC1397A.ino:278
#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 void menu_2_write_to_input_register(int16_t selected_dac)
Write data to input register, but do not update DAC output.
Definition: DC1397A.ino:265
#define EXT_CAL_PARAMS_BASE
Base address of the external ref calibration parameters.
Definition: DC1397A.ino:133
#define LTC2656_DAC_E
Definition: LTC2656.h:130
static void 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: DC1397A.ino:291
static void menu_7_calibrate_dacs()
Calibrate all DACs by measuring two known outputs.
Definition: DC1397A.ino:329
#define LTC2656_DAC_A
Definition: LTC2656.h:126
Header File for Linduino Libraries and Demo Code.
static void menu_5_power_down_dac(int16_t selected_dac)
Power down DAC.
Definition: DC1397A.ino:298
static uint8_t shift_count
The data align shift count.
Definition: DC1397A.ino:157
#define REF_EXTERNAL
Stored reference state is External.
Definition: DC1397A.ino:126
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 void setup()
Initialize Linduino.
Definition: DC1397A.ino:181
#define INT_CAL_VALID_BASE
Base address of the "internal ref calibration valid" flag.
Definition: DC1397A.ino:130
const uint8_t address_map[9]
Lookup table for DAC address.
Definition: DC1397A.ino:169
#define LTC2656_CMD_WRITE
Write to input register n.
Definition: LTC2656.h:112
#define LTC2656_DAC_B
Definition: LTC2656.h:127
#define STORED_REF_STATE_BASE
Base address of the stored reference state.
Definition: DC1397A.ino:129
void LTC2656_calibrate(uint16_t dac_code1, uint16_t dac_code2, float voltage1, float voltage2, float *LTC2656_lsb, int16_t *LTC2656_offset)
Calculate the LTC2656 offset and LSB voltage given two measured voltages and their corresponding code...
Definition: LTC2656.cpp:115
static uint8_t reference_mode
Tells whether to set internal or external reference.
Definition: DC1397A.ino:158
static int16_t prompt_voltage_or_code()
Prompt user to enter a voltage or digital code to send to DAC.
Definition: DC1397A.ino:547
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 void menu_8_enable_calibration()
Enable / Disable calibration.
Definition: DC1397A.ino:342
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.
void LTC2656_write(uint8_t cs, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code)
Write the 16-bit dac_code to the LTC2656.
Definition: LTC2656.cpp:79
static int16_t LTC2656_offset[9]
DAC offset - index 8 for "all DACs".
Definition: DC1397A.ino:162
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1397A.ino:156
#define REF_INTERNAL
Stored reference state is Internal.
Definition: DC1397A.ino:125
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.
QuikEval EEPROM Library.
static float reference_voltage
Reference voltage, either internal or external.
Definition: DC1397A.ino:161
#define LTC2656_DAC_D
Definition: LTC2656.h:129
static void store_calibration()
Store measured calibration parameters to nonvolatile EEPROM on demo board.
Definition: DC1397A.ino:512
static void menu_6_set_reference_mode()
Set reference mode and store to EEPROM.
Definition: DC1397A.ino:305
static void menu_1_select_dac(int16_t *selected_dac)
Select which DAC to operate on.
Definition: DC1397A.ino:253
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
static void loop()
Repeats Linduino loop.
Definition: DC1397A.ino:199
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
#define EXT_REF_V_BASE
Base address of the stored external reference voltage.
Definition: DC1397A.ino:134
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
int32_t read_int()
static int index
#define LTC2656_DAC_G
Definition: LTC2656.h:132
float read_float()
#define LTC2656_DAC_C
Definition: LTC2656.h:128
char product_name[15]
LTC Product (LTC2654-L16)
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
static uint16_t get_code()
Get code to send to DAC directly, in decimal, hex, or binary.
Definition: DC1397A.ino:575
static int i
Definition: DC2430A.ino:184
#define LTC2656_CMD_WRITE_UPDATE
Write to input register n, update (power up) all.
Definition: LTC2656.h:115
static int8_t restore_calibration()
Read stored calibration parameters from nonvolatile EEPROM on demo board.
Definition: DC1397A.ino:370
uint16_t LTC2656_voltage_to_code(float dac_voltage, float LTC2656_lsb, int16_t LTC2656_offset)
Calculate a LTC2656 DAC code given the desired output voltage and DAC address (0-7) ...
Definition: LTC2656.cpp:94
LTC2656: Octal SPI 16-/12-Bit Rail-to-Rail DACs with 10ppm/C Max Reference.
#define LTC2656_CMD_UPDATE
Update (power up) DAC register n.
Definition: LTC2656.h:113
#define LTC2656_DAC_H
Definition: LTC2656.h:133
#define EEPROM_CAL_KEY
static uint16_t get_voltage(float LTC2656_lsb, int16_t LTC2656_offset)
Get voltage from user input, calculate DAC code based on lsb, offset.
Definition: DC1397A.ino:562
#define LTC2656_DAC_ALL
Definition: LTC2656.h:134
static void print_prompt(int16_t selected_dac)
Prints main menu.
Definition: DC1397A.ino:603
#define LTC2656_CS
Define the SPI CS pin.
Definition: LTC2656.h:106