| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC1684AA.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1684AA Demonstration Board.
3 LTC2758: Dual Serial 18-Bit SoftSpan IOUT DAC
4
5 @verbatim
6 NOTES
7 Setup:
8 Set the terminal baud rate to 115200 and select the newline terminator.
9
10 An external +/- 15V power supply is required to power the circuit.
11
12 Explanation of Commands:
13 1- Select DAC
14 Select between DAC A, DAC B, or both.
15
16 2- Change Span of Selected DAC
17 | Command | Range Selected |
18 | C3 C2 C1 C0 | |
19 |-------------|----------------|
20 | 1 0 0 0 | 0V - 5V |
21 | 1 0 0 1 | 0V - 10V |
22 | 1 0 1 0 | -5V - +5V |
23 | 1 0 1 1 | -10V - +10V |
24 | 1 1 0 0 | -2.5V - +2.5V |
25 | 1 1 0 1 | -2.5V - +7V |
26
27 3- Voltage Output
28 Displays the calculated voltage depending on the code input from user and
29 voltage range selected.
30
31 4- Square wave output
32 Generates a square wave on the output pin. This function helps to measure
33 settling time and glitch impulse.
34
35 USER INPUT DATA FORMAT:
36 decimal : 1024
37 hex : 0x400
38 octal : 02000 (leading 0 "zero")
39 binary : B10000000000
40 float : 1024.0
41
42 @endverbatim
43
44 http://www.linear.com/product/LTC2758
45
46 http://www.linear.com/product/LTC2758#demoboards
47
48
49 Copyright 2018(c) Analog Devices, Inc.
50
51 All rights reserved.
52
53 Redistribution and use in source and binary forms, with or without
54 modification, are permitted provided that the following conditions are met:
55 - Redistributions of source code must retain the above copyright
56 notice, this list of conditions and the following disclaimer.
57 - Redistributions in binary form must reproduce the above copyright
58 notice, this list of conditions and the following disclaimer in
59 the documentation and/or other materials provided with the
60 distribution.
61 - Neither the name of Analog Devices, Inc. nor the names of its
62 contributors may be used to endorse or promote products derived
63 from this software without specific prior written permission.
64 - The use of this software may or may not infringe the patent rights
65 of one or more patent holders. This license does not release you
66 from the requirement that you obtain separate licenses from these
67 patent holders to use this software.
68 - Use of the software either in source or binary form, must be run
69 on or directly connected to an Analog Devices Inc. component.
70
71 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
72 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
73 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
74 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
75 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
76 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
77 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
78 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
79 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
81 */
82
83 /*! @file
84 @ingroup LTC2758
85 */
86
87 // Headerfiles
88 #include "LT_SPI.h"
89 #include "UserInterface.h"
90 #include "LT_I2C.h"
91 #include "QuikEval_EEPROM.h"
92 #include "Linduino.h"
93 #include <SPI.h>
94 #include <Stream.h>
95 #include "LTC2758.h"
96
97 // Global variables
98 static uint8_t demo_board_connected; //!< Set to 1 if the board is connected
99
100 float DACA_RANGE_LOW = 0;
101 float DACA_RANGE_HIGH = 5;
102
103 float DACB_RANGE_LOW = 0;
104 float DACB_RANGE_HIGH = 5;
105
106 uint8_t DAC_SELECTED = ADDRESS_DACA;
107
108 // Function Declarations
109 void print_title();
110 void print_prompt();
111 uint8_t menu1_select_dac();
112 void menu2_change_range();
113 uint8_t menu3_voltage_output();
114 uint8_t menu4_square_wave_output();
115
116 //! Initialize Linduino
117 void setup()
118 {
119 char product_name[] = "LTC2758"; // Product Name stored in QuikEval EEPROM
120 char board_name[] = "DC1684"; // Demo Board Name stored in QuikEval EEPROM
121
122 quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
123 quikeval_SPI_connect(); // Connect SPI to main data port
124 quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz
125
126 Serial.begin(115200); // Initialize the serial port to the PC
127 print_title();
128
129 demo_board_connected = discover_DC1684AB(product_name, board_name);
130 if (demo_board_connected)
131 {
132 print_prompt();
133 }
134 LTC2758_write(LTC2758_CS, LTC2758_WRITE_SPAN_DAC, ADDRESS_DAC_ALL, 0); // initialising all channels to 0V - 5V range
135 LTC2758_write(LTC2758_CS, LTC2758_WRITE_CODE_UPDATE_DAC, ADDRESS_DAC_ALL, 0); // initialising all channels to 0V
136 }
137
138 //! Read the ID string from the EEPROM and determine if the correct board is connected.
139 //! Returns 1 if successful, 0 if not successful
140 uint8_t discover_DC1684AB(char *product_name, char *board_name)
141 {
142 Serial.print(F("\nChecking EEPROM contents..."));
143 read_quikeval_id_string(&ui_buffer[0]);
144 ui_buffer[48] = 0;
145 // Serial.println(ui_buffer);
146
147 if (!strcmp(demo_board.product_name, product_name) && !strcmp(demo_board.name, board_name))
148 {
149 Serial.print("\nDemo Board Name: ");
150 Serial.println(demo_board.name);
151 Serial.print("Product Name: ");
152 Serial.println(demo_board.product_name);
153 if (demo_board.option)
154 {
155 Serial.print("Demo Board Option: ");
156 Serial.println(demo_board.option);
157 }
158 Serial.println(F("Demo board connected..."));
159 Serial.println(F("\n\n\t\t\t\tPress Enter to Continue..."));
160 read_int();
161 return 1;
162 }
163 else
164 {
165 Serial.print("Demo board ");
166 Serial.print(board_name);
167 Serial.print(" not found, \nfound ");
168 Serial.print(demo_board.name);
169 Serial.println(" instead. \nConnect the correct demo board, then press the reset button.");
170 return 0;
171 }
172 }
173
174 //! Repeats Linduino loop
175 void loop()
176 {
177 int16_t user_command;
178 if (Serial.available()) // Check for user input
179 {
180 user_command = read_int(); // Read the user command
181 Serial.println(user_command);
182 Serial.flush();
183 switch (user_command)
184 {
185 case 1:
186 menu1_select_dac();
187 break;
188 case 2:
189 menu2_change_range();
190 break;
191 case 3:
192 menu3_voltage_output();
193 break;
194 case 4:
195 menu4_square_wave_output();
196 break;
197 default:
198 Serial.println(F("Incorrect Option"));
199 break;
200 }
201 Serial.println(F("\n************************************************************"));
202 print_prompt();
203 }
204 }
205
206 //! Prints the title block when program first starts.
207 void print_title()
208 {
209 Serial.println();
210 Serial.println(F("*****************************************************************"));
211 Serial.println(F("* DC1684A-A Demonstration Program *"));
212 Serial.println(F("* *"));
213 Serial.println(F("* This program demonstrates how to send data to the LTC2758 *"));
214 Serial.println(F("* Dual Serial 18-bit Soft Span DAC *"));
215 Serial.println(F("* *"));
216 Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
217 Serial.println(F("* *"));
218 Serial.println(F("*****************************************************************\n"));
219 }
220
221 //! Prints main menu.
222 void print_prompt()
223 {
224 Serial.println(F("\nCommand Summary:"));
225 Serial.println(F("\n 1. Select DAC"));
226 Serial.println(F(" 2. Change Span of selected DAC"));
227 Serial.println(F(" 3. Voltage Output"));
228 Serial.println(F(" 4. Square wave output"));
229
230 Serial.println(F("\nPresent Values:\n"));
231 Serial.print(F(" DAC A Range: "));
232 Serial.print(DACA_RANGE_LOW);
233 Serial.print(F(" V to "));
234 Serial.print(DACA_RANGE_HIGH);
235 Serial.println(F(" V"));
236
237 Serial.print(F(" DAC B Range: "));
238 Serial.print(DACB_RANGE_LOW);
239 Serial.print(F(" V to "));
240 Serial.print(DACB_RANGE_HIGH);
241 Serial.println(F(" V"));
242
243 Serial.print(F("\n Selected DAC: "));
244 switch (DAC_SELECTED)
245 {
246 case ADDRESS_DACA:
247 Serial.println(F("DAC A"));
248 break;
249 case ADDRESS_DACB:
250 Serial.println(F("DAC B"));
251 break;
252 case ADDRESS_DAC_ALL:
253 Serial.println(F("ALL DACs"));
254 break;
255 }
256
257 Serial.print(F("\n\nEnter a command: "));
258 Serial.flush();
259 }
260
261 //! Function to select DAC and set DAC address
262 uint8_t menu1_select_dac()
263 {
264 uint8_t choice;
265 Serial.println(F("\n1. DAC A"));
266 Serial.println(F("2. DAC B"));
267 Serial.println(F("3. All DACs"));
268 Serial.print(F("\nEnter a choice: "));
269 choice = read_int(); // Read the user command
270
271 switch (choice)
272 {
273 case 1:
274 DAC_SELECTED = ADDRESS_DACA;
275 Serial.println("DAC A");
276 break;
277 case 2:
278 DAC_SELECTED = ADDRESS_DACB;
279 Serial.println("DAC B");
280 break;
281 default:
282 DAC_SELECTED = ADDRESS_DAC_ALL;
283 Serial.println("ALL DACs");
284 break;
285 }
286 Serial.flush();
287 }
288
289 //! Function to choose the range of voltages to be used
290 void menu2_change_range()
291 {
292 uint8_t choice;
293 uint32_t span;
294 Serial.println("\n| Choice | Range |");
295 Serial.println("|--------|---------------|");
296 Serial.println("| 0 | 0 - 5 V |");
297 Serial.println("| 1 | 0 - 10 V |");
298 Serial.println("| 2 | -5 - +5 V |");
299 Serial.println("| 3 | -10 - +10 V |");
300 Serial.println("| 4 | -2.5 - +2.5 V |");
301 Serial.println("| 5 | -2.5 - +7.5 V |");
302
303 Serial.print("\nEnter your choice: ");
304 choice = read_int();
305 Serial.println(choice);
306 span = (uint32_t)(choice << 2);
307 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
308 {
309 switch (choice)
310 {
311 case 0:
312 DACA_RANGE_LOW = 0;
313 DACA_RANGE_HIGH = 5;
314 break;
315
316 case 1:
317 DACA_RANGE_LOW = 0;
318 DACA_RANGE_HIGH = 10;
319 break;
320
321 case 2:
322 DACA_RANGE_LOW = -5;
323 DACA_RANGE_HIGH = 5;
324 break;
325
326 case 3:
327 DACA_RANGE_LOW = -10;
328 DACA_RANGE_HIGH = 10;
329 break;
330
331 case 4:
332 DACA_RANGE_LOW = -2.5;
333 DACA_RANGE_HIGH = 2.5;
334 break;
335
336 case 5:
337 DACA_RANGE_LOW = -2.5;
338 DACA_RANGE_HIGH = 7.5;
339 break;
340
341 default:
342 Serial.println("\nWrong choice!");
343 }
344 Serial.print(F("Span Changed!"));
345 }
346 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
347 {
348 switch (choice)
349 {
350 case 0:
351 DACB_RANGE_LOW = 0;
352 DACB_RANGE_HIGH = 5;
353 break;
354
355 case 1:
356 DACB_RANGE_LOW = 0;
357 DACB_RANGE_HIGH = 10;
358 break;
359
360 case 2:
361 DACB_RANGE_LOW = -5;
362 DACB_RANGE_HIGH = 5;
363 break;
364
365 case 3:
366 DACB_RANGE_LOW = -10;
367 DACB_RANGE_HIGH = 10;
368 break;
369
370 case 4:
371 DACB_RANGE_LOW = -2.5;
372 DACB_RANGE_HIGH = 2.5;
373 break;
374
375 case 5:
376 DACB_RANGE_LOW = -2.5;
377 DACB_RANGE_HIGH = 7.5;
378 break;
379
380 default:
381 Serial.println("\nWrong choice!");
382 }
383 Serial.print(F("Span Changed!"));
384 }
385 LTC2758_write(LTC2758_CS, LTC2758_WRITE_SPAN_DAC, DAC_SELECTED, span);
386 }
387
388 //! Function to enter a digital value and get the analog output
389 uint8_t menu3_voltage_output()
390 {
391 uint8_t choice;
392 uint32_t data;
393 float voltage;
394
395 Serial.println(F("\n1. Enter Voltage"));
396 Serial.println(F("2. Enter Code"));
397 Serial.print(F("\nEnter a choice: "));
398 choice = read_int(); // Read the user command
399 Serial.print(choice);
400
401 if (choice == 2)
402 {
403 Serial.print("\nEnter the 18-bit data as decimal or hex: ");
404 data = read_int();
405 Serial.print("0x");
406 Serial.println(data, HEX);
407
408 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
409 {
410 voltage = LTC2758_code_to_voltage(data, DACA_RANGE_LOW, DACA_RANGE_HIGH);
411 Serial.print("\nDACA Output voltage = ");
412 Serial.print(voltage);
413 Serial.println(" V");
414 }
415
416 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
417 {
418 voltage = LTC2758_code_to_voltage(data, DACB_RANGE_LOW, DACB_RANGE_HIGH);
419 Serial.print("\nDACB Output voltage = ");
420 Serial.print(voltage);
421 Serial.println(" V");
422 }
423 LTC2758_write(LTC2758_CS, LTC2758_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, data);
424 }
425 else if (choice == 1)
426 {
427 Serial.print("\nEnter voltage: ");
428 while (!Serial.available());
429 voltage = read_float();
430 Serial.print(voltage);
431 Serial.println(" V");
432
433 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
434 {
435 data = LTC2758_voltage_to_code(voltage, DACA_RANGE_LOW, DACA_RANGE_HIGH);
436 LTC2758_write(LTC2758_CS, LTC2758_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, data);
437 Serial.print("\nDACA Output voltage = ");
438 Serial.print(voltage);
439 Serial.println(" V");
440 Serial.print("\nDAC CODE: 0x");
441 Serial.println(data, HEX);
442 }
443
444 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
445 {
446 data = LTC2758_voltage_to_code(voltage, DACB_RANGE_LOW, DACB_RANGE_HIGH);
447 LTC2758_write(LTC2758_CS, LTC2758_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, data);
448 Serial.println(DACB_RANGE_HIGH);
449 Serial.print("\nDACB Output voltage = ");
450 Serial.print(voltage);
451 Serial.println(" V");
452 Serial.print("\nDAC CODE: 0x");
453 Serial.println(data, HEX);
454 }
455 }
456 return 0;
457 }
458
459 //! Function to generate a square wave of desired frequency and voltage ranges
460 uint8_t menu4_square_wave_output()
461 {
462 uint16_t freq;
463 float time;
464 float voltage_high, voltage_low;
465 uint32_t code_high, code_low;
466 uint8_t receive_enter; // To receive enter key pressed
467
468 Serial.print("\nEnter voltage_high: ");
469 while (!Serial.available());
470 voltage_high = read_float();
471 Serial.print(voltage_high);
472 Serial.println(" V");
473
474 Serial.print("\nEnter voltage_low: ");
475 while (!Serial.available());
476 voltage_low = read_float();
477 Serial.print(voltage_low);
478 Serial.println(" V");
479
480 Serial.print("\nEnter the required frequency in Hz: ");
481 freq = read_int();
482 Serial.print(freq);
483 Serial.println(" Hz");
484
485 time = (float)1000/freq;
486 Serial.print("\nT = ");
487 Serial.print(time);
488 Serial.println(" ms");
489
490 //! Converting voltage into data
491 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
492 {
493 code_high = LTC2758_voltage_to_code(voltage_high, DACA_RANGE_LOW, DACA_RANGE_HIGH);
494 code_low = LTC2758_voltage_to_code(voltage_low, DACA_RANGE_LOW, DACA_RANGE_HIGH);
495 }
496 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
497 {
498 code_high = LTC2758_voltage_to_code(voltage_high, DACB_RANGE_LOW, DACB_RANGE_HIGH);
499 code_low = LTC2758_voltage_to_code(voltage_low, DACB_RANGE_LOW, DACB_RANGE_HIGH);
500 }
501
502 while (!Serial.available()) //! Generate square wave until a key is pressed
503 {
504 LTC2758_write(LTC2758_CS, LTC2758_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, code_high);
505 delayMicroseconds(time * 500);
506 LTC2758_write(LTC2758_CS, LTC2758_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, code_low);
507 delayMicroseconds(time * 500);
508 }
509 receive_enter = read_int();
510 return 0;
511 }
512
demo_board
struct demo_board_type demo_board
Instantiate demo board structure.
Definition: QuikEval_EEPROM.cpp:71
menu1_select_dac
static uint8_t menu1_select_dac()
Function to select DAC and set DAC address.
Definition: DC1684AA.ino:262
LTC2758_WRITE_CODE_UPDATE_DAC
#define LTC2758_WRITE_CODE_UPDATE_DAC
Write Code DAC n and Update DAC n.
Definition: LTC2758.h:106
demo_board_type::option
char option
Demo Circuit option (A)
Definition: QuikEval_EEPROM.h:72
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
demo_board_connected
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1684AA.ino:98
demo_board_type::name
char name[15]
Demo Circuit number (DC1678)
Definition: QuikEval_EEPROM.h:71
LTC2758_write
void LTC2758_write(uint8_t cs, uint8_t dac_command, uint8_t dac_address, uint32_t data)
Transmits 32 bit input stream: 4-bit command + 4-bit don&#39;t-care + 18-bit data + 6 don&#39;t care...
Definition: LTC2758.cpp:77
loop
static void loop()
Repeats Linduino loop.
Definition: DC1684AA.ino:175
Linduino.h
Header File for Linduino Libraries and Demo Code.
menu3_voltage_output
static uint8_t menu3_voltage_output()
Function to enter a digital value and get the analog output.
Definition: DC1684AA.ino:389
LTC2758_CS
#define LTC2758_CS
Define the SPI CS pin.
Definition: LTC2758.h:90
DACA_RANGE_HIGH
static float DACA_RANGE_HIGH
Definition: DC1684AA.ino:101
LTC2758_code_to_voltage
float LTC2758_code_to_voltage(uint32_t dac_code, float min_output, float max_output)
Calculate the LTC2758 DAC output voltage given the DAC code and and the minimum / maximum outputs for...
Definition: LTC2758.cpp:89
DAC_SELECTED
static uint8_t DAC_SELECTED
Definition: DC1684AA.ino:106
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
discover_DC1684AB
static uint8_t discover_DC1684AB(char *product_name, char *board_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
Definition: DC1684AA.ino:140
LTC2758_WRITE_SPAN_DAC
#define LTC2758_WRITE_SPAN_DAC
Write Span DAC n.
Definition: LTC2758.h:101
QuikEval_EEPROM.h
QuikEval EEPROM Library.
ADDRESS_DAC_ALL
#define ADDRESS_DAC_ALL
Definition: LTC2752.h:96
quikeval_SPI_init
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
menu2_change_range
static void menu2_change_range()
Function to choose the range of voltages to be used.
Definition: DC1684AA.ino:290
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC1684AA.ino:207
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
ADDRESS_DACA
#define ADDRESS_DACA
Definition: LTC2752.h:94
DACB_RANGE_HIGH
static float DACB_RANGE_HIGH
Definition: DC1684AA.ino:104
LTC2758.h
LTC2758: Dual Serial 18-Bit SoftSpan IOUT DAC.
quikeval_SPI_connect
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
UserInterface.h
read_int
int32_t read_int()
Definition: UserInterface.cpp:93
read_float
float read_float()
Definition: UserInterface.cpp:78
DACB_RANGE_LOW
static float DACB_RANGE_LOW
Definition: DC1684AA.ino:103
demo_board_type::product_name
char product_name[15]
LTC Product (LTC2654-L16)
Definition: QuikEval_EEPROM.h:70
DACA_RANGE_LOW
static float DACA_RANGE_LOW
Definition: DC1684AA.ino:100
menu4_square_wave_output
static uint8_t menu4_square_wave_output()
Function to generate a square wave of desired frequency and voltage ranges.
Definition: DC1684AA.ino:460
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
setup
static void setup()
Initialize Linduino.
Definition: DC1684AA.ino:117
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC1684AA.ino:222
voltage
static float voltage
Definition: DC2289AA.ino:71
read_quikeval_id_string
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...
Definition: QuikEval_EEPROM.cpp:77
ui_buffer
char ui_buffer[UI_BUFFER_SIZE]
Definition: UserInterface.cpp:46
LTC2758_voltage_to_code
uint32_t LTC2758_voltage_to_code(float dac_voltage, float min_output, float max_output)
Calculate a LTC2758 DAC code given the desired output voltage and the minimum / maximum outputs for a...
Definition: LTC2758.cpp:97
ADDRESS_DACB
#define ADDRESS_DACB
Definition: LTC2752.h:95