| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC1684AB.ino
Go to the documentation of this file.
1 /*!
2 Linear Technology DC1684AB Demonstration Board.
3 LTC2752: Dual Serial 16-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/LTC2752
45
46 http://www.linear.com/product/LTC2752#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 LTC2752
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 "LTC2752.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[] = "LTC2752"; // 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 }
135
136 //! Read the ID string from the EEPROM and determine if the correct board is connected.
137 //! Returns 1 if successful, 0 if not successful
138 uint8_t discover_DC1684AB(char *product_name, char *board_name)
139 {
140 Serial.print(F("\nChecking EEPROM contents..."));
141 read_quikeval_id_string(&ui_buffer[0]);
142 ui_buffer[48] = 0;
143 // Serial.println(ui_buffer);
144
145 if (!strcmp(demo_board.product_name, product_name) && !strcmp(demo_board.name, board_name))
146 {
147 Serial.print("\nDemo Board Name: ");
148 Serial.println(demo_board.name);
149 Serial.print("Product Name: ");
150 Serial.println(demo_board.product_name);
151 if (demo_board.option)
152 {
153 Serial.print("Demo Board Option: ");
154 Serial.println(demo_board.option);
155 }
156 Serial.println(F("Demo board connected..."));
157 Serial.println(F("\n\n\t\t\t\tPress Enter to Continue..."));
158 read_int();
159 return 1;
160 }
161 else
162 {
163 Serial.print("Demo board ");
164 Serial.print(board_name);
165 Serial.print(" not found, \nfound ");
166 Serial.print(demo_board.name);
167 Serial.println(" instead. \nConnect the correct demo board, then press the reset button.");
168 return 0;
169 }
170 }
171
172 //! Repeats Linduino loop
173 void loop()
174 {
175 int16_t user_command;
176 if (Serial.available()) // Check for user input
177 {
178 user_command = read_int(); // Read the user command
179 Serial.println(user_command);
180 Serial.flush();
181 switch (user_command)
182 {
183 case 1:
184 menu1_select_dac();
185 break;
186 case 2:
187 menu2_change_range();
188 break;
189 case 3:
190 menu3_voltage_output();
191 break;
192 case 4:
193 menu4_square_wave_output();
194 break;
195 default:
196 Serial.println(F("Incorrect Option"));
197 break;
198 }
199 Serial.println(F("\n************************************************************"));
200 print_prompt();
201 }
202 }
203
204 //! Prints the title block when program first starts.
205 void print_title()
206 {
207 Serial.println();
208 Serial.println(F("*****************************************************************"));
209 Serial.println(F("* DC1684A-B Demonstration Program *"));
210 Serial.println(F("* *"));
211 Serial.println(F("* This program demonstrates how to send data to the LTC2752 *"));
212 Serial.println(F("* Dual Serial 16-bit Soft Span DAC *"));
213 Serial.println(F("* *"));
214 Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
215 Serial.println(F("* *"));
216 Serial.println(F("*****************************************************************\n"));
217 }
218
219 //! Prints main menu.
220 void print_prompt()
221 {
222 Serial.println(F("\nCommand Summary:"));
223 Serial.println(F("\n 1. Select DAC"));
224 Serial.println(F(" 2. Change Span of selected DAC"));
225 Serial.println(F(" 3. Voltage Output"));
226 Serial.println(F(" 4. Square wave output"));
227
228 Serial.println(F("\nPresent Values:\n"));
229 Serial.print(F(" DAC A Range: "));
230 Serial.print(DACA_RANGE_LOW);
231 Serial.print(F(" V to "));
232 Serial.print(DACA_RANGE_HIGH);
233 Serial.println(F(" V"));
234
235 Serial.print(F(" DAC B Range: "));
236 Serial.print(DACB_RANGE_LOW);
237 Serial.print(F(" V to "));
238 Serial.print(DACB_RANGE_HIGH);
239 Serial.println(F(" V"));
240
241 Serial.print(F("\n Selected DAC: "));
242 switch (DAC_SELECTED)
243 {
244 case ADDRESS_DACA:
245 Serial.println(F("DAC A"));
246 break;
247 case ADDRESS_DACB:
248 Serial.println(F("DAC B"));
249 break;
250 case ADDRESS_DAC_ALL:
251 Serial.println(F("ALL DACs"));
252 break;
253 }
254
255 Serial.print(F("\n\nEnter a command: "));
256 Serial.flush();
257 }
258
259 //! Function to select DAC and set DAC address
260 uint8_t menu1_select_dac()
261 {
262 uint8_t choice;
263 Serial.println(F("\n1. DAC A"));
264 Serial.println(F("2. DAC B"));
265 Serial.println(F("3. All DACs"));
266 Serial.print(F("\nEnter a choice: "));
267 choice = read_int(); // Read the user command
268
269 switch (choice)
270 {
271 case 1:
272 DAC_SELECTED = ADDRESS_DACA;
273 Serial.println("DAC A");
274 break;
275 case 2:
276 DAC_SELECTED = ADDRESS_DACB;
277 Serial.println("DAC B");
278 break;
279 default:
280 DAC_SELECTED = ADDRESS_DAC_ALL;
281 Serial.println("ALL DACs");
282 break;
283 }
284 Serial.flush();
285 }
286
287 //! Function to choose the range of voltages to be used
288 void menu2_change_range()
289 {
290 uint16_t span;
291 Serial.println("\n| Choice | Range |");
292 Serial.println("|--------|---------------|");
293 Serial.println("| 0 | 0 - 5 V |");
294 Serial.println("| 1 | 0 - 10 V |");
295 Serial.println("| 2 | -5 - +5 V |");
296 Serial.println("| 3 | -10 - +10 V |");
297 Serial.println("| 4 | -2.5 - +2.5 V |");
298 Serial.println("| 5 | -2.5 - +7.5 V |");
299
300 Serial.print("\nEnter your choice: ");
301 span = read_int();
302
303 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
304 {
305 switch (span)
306 {
307 case 0:
308 DACA_RANGE_LOW = 0;
309 DACA_RANGE_HIGH = 5;
310 break;
311
312 case 1:
313 DACA_RANGE_LOW = 0;
314 DACA_RANGE_HIGH = 10;
315 break;
316
317 case 2:
318 DACA_RANGE_LOW = -5;
319 DACA_RANGE_HIGH = 5;
320 break;
321
322 case 3:
323 DACA_RANGE_LOW = -10;
324 DACA_RANGE_HIGH = 10;
325 break;
326
327 case 4:
328 DACA_RANGE_LOW = -2.5;
329 DACA_RANGE_HIGH = 2.5;
330 break;
331
332 case 5:
333 DACA_RANGE_LOW = -2.5;
334 DACA_RANGE_HIGH = 7.5;
335 break;
336
337 default:
338 Serial.println("\nWrong choice!");
339 }
340 Serial.print(F("Span Changed!"));
341 }
342 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
343 {
344 switch (span)
345 {
346 case 0:
347 DACB_RANGE_LOW = 0;
348 DACB_RANGE_HIGH = 5;
349 break;
350
351 case 1:
352 DACB_RANGE_LOW = 0;
353 DACB_RANGE_HIGH = 10;
354 break;
355
356 case 2:
357 DACB_RANGE_LOW = -5;
358 DACB_RANGE_HIGH = 5;
359 break;
360
361 case 3:
362 DACB_RANGE_LOW = -10;
363 DACB_RANGE_HIGH = 10;
364 break;
365
366 case 4:
367 DACB_RANGE_LOW = -2.5;
368 DACB_RANGE_HIGH = 2.5;
369 break;
370
371 case 5:
372 DACB_RANGE_LOW = -2.5;
373 DACB_RANGE_HIGH = 7.5;
374 break;
375
376 default:
377 Serial.println("\nWrong choice!");
378 }
379 Serial.print(F("Span Changed!"));
380 }
381 LTC2752_write(LTC2752_CS, LTC2752_WRITE_SPAN_DAC, DAC_SELECTED, span);
382 }
383
384 //! Function to enter a digital value and get the analog output
385 uint8_t menu3_voltage_output()
386 {
387 uint8_t choice;
388 uint16_t data;
389 float voltage;
390
391 Serial.println(F("\n1. Enter Voltage"));
392 Serial.println(F("2. Enter Code"));
393 Serial.print(F("\nEnter a choice: "));
394 choice = read_int(); // Read the user command
395 Serial.print(choice);
396
397 if (choice == 2)
398 {
399 Serial.print("\nEnter the 16-bit data as decimal or hex: ");
400 data = read_int();
401 Serial.print("0x");
402 Serial.println(data, HEX);
403
404 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
405 {
406 voltage = LTC2752_code_to_voltage(data, DACA_RANGE_LOW, DACA_RANGE_HIGH);
407 Serial.print("\nDACA Output voltage = ");
408 Serial.print(voltage);
409 Serial.println(" V");
410 }
411
412 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
413 {
414 voltage = LTC2752_code_to_voltage(data, DACB_RANGE_LOW, DACB_RANGE_HIGH);
415 Serial.print("\nDACB Output voltage = ");
416 Serial.print(voltage);
417 Serial.println(" V");
418 }
419 LTC2752_write(LTC2752_CS, LTC2752_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, data);
420 }
421 else if (choice == 1)
422 {
423 Serial.print("\nEnter voltage: ");
424 while (!Serial.available());
425 voltage = read_float();
426 Serial.print(voltage);
427 Serial.println(" V");
428
429 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
430 {
431 data = LTC2752_voltage_to_code(voltage, DACA_RANGE_LOW, DACA_RANGE_HIGH);
432 LTC2752_write(LTC2752_CS, LTC2752_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, data);
433 Serial.print("\nDACA Output voltage = ");
434 Serial.print(voltage);
435 Serial.println(" V");
436 Serial.print("\nDAC CODE: 0x");
437 Serial.println(data, HEX);
438 }
439
440 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
441 {
442 data = LTC2752_voltage_to_code(voltage, DACB_RANGE_LOW, DACB_RANGE_HIGH);
443 LTC2752_write(LTC2752_CS, LTC2752_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, data);
444 Serial.print("\nDACB Output voltage = ");
445 Serial.print(voltage);
446 Serial.println(" V");
447 Serial.print("\nDAC CODE: 0x");
448 Serial.println(data, HEX);
449 }
450 }
451 return 0;
452 }
453
454 //! Function to generate a square wave of desired frequency and voltage ranges
455 uint8_t menu4_square_wave_output()
456 {
457 uint16_t freq;
458 float time;
459 float voltage_high, voltage_low;
460 uint16_t code_high, code_low;
461 uint8_t receive_enter; // To receive enter key pressed
462
463 Serial.print("\nEnter voltage_high: ");
464 while (!Serial.available());
465 voltage_high = read_float();
466 Serial.print(voltage_high);
467 Serial.println(" V");
468
469 Serial.print("\nEnter voltage_low: ");
470 while (!Serial.available());
471 voltage_low = read_float();
472 Serial.print(voltage_low);
473 Serial.println(" V");
474
475 Serial.print("\nEnter the required frequency in Hz: ");
476 freq = read_int();
477 Serial.print(freq);
478 Serial.println(" Hz");
479
480 time = (float)1000/freq;
481 Serial.print("\nT = ");
482 Serial.print(time);
483 Serial.println(" ms");
484
485 //! Converting voltage into data
486 if (DAC_SELECTED == ADDRESS_DACA || DAC_SELECTED == ADDRESS_DAC_ALL)
487 {
488 code_high = LTC2752_voltage_to_code(voltage_high, DACA_RANGE_LOW, DACA_RANGE_HIGH);
489 code_low = LTC2752_voltage_to_code(voltage_low, DACA_RANGE_LOW, DACA_RANGE_HIGH);
490 }
491 if (DAC_SELECTED == ADDRESS_DACB || DAC_SELECTED == ADDRESS_DAC_ALL)
492 {
493 code_high = LTC2752_voltage_to_code(voltage_high, DACB_RANGE_LOW, DACB_RANGE_HIGH);
494 code_low = LTC2752_voltage_to_code(voltage_low, DACB_RANGE_LOW, DACB_RANGE_HIGH);
495 }
496
497 while (!Serial.available()) //! Generate square wave until a key is pressed
498 {
499 LTC2752_write(LTC2752_CS, LTC2752_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, code_high);
500 delayMicroseconds(time * 500);
501 LTC2752_write(LTC2752_CS, LTC2752_WRITE_CODE_UPDATE_DAC, DAC_SELECTED, code_low);
502 delayMicroseconds(time * 500);
503 }
504 receive_enter = read_int();
505 return 0;
506 }
507
demo_board
struct demo_board_type demo_board
Instantiate demo board structure.
Definition: QuikEval_EEPROM.cpp:71
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
menu1_select_dac
static uint8_t menu1_select_dac()
Function to select DAC and set DAC address.
Definition: DC1684AB.ino:260
demo_board_connected
static uint8_t demo_board_connected
Set to 1 if the board is connected.
Definition: DC1684AB.ino:98
demo_board_type::name
char name[15]
Demo Circuit number (DC1678)
Definition: QuikEval_EEPROM.h:71
LTC2752_CS
#define LTC2752_CS
Define the SPI CS pin.
Definition: LTC2752.h:90
menu3_voltage_output
static uint8_t menu3_voltage_output()
Function to enter a digital value and get the analog output.
Definition: DC1684AB.ino:385
Linduino.h
Header File for Linduino Libraries and Demo Code.
loop
static void loop()
Repeats Linduino loop.
Definition: DC1684AB.ino:173
DAC_SELECTED
static uint8_t DAC_SELECTED
Definition: DC1684AB.ino:106
DACA_RANGE_HIGH
static float DACA_RANGE_HIGH
Definition: DC1684AB.ino:101
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: DC1684AB.ino:138
LTC2752_WRITE_CODE_UPDATE_DAC
#define LTC2752_WRITE_CODE_UPDATE_DAC
Write Code DAC n and Update DAC n.
Definition: LTC2752.h:106
LTC2752_write
void LTC2752_write(uint8_t cs, uint8_t dac_command, uint8_t dac_address, uint16_t data)
Transmits 24 bit input stream: 4-bit command + 4-bit don&#39;t-care + 16-bit data.
Definition: LTC2752.cpp:77
LTC2752_voltage_to_code
uint16_t LTC2752_voltage_to_code(float dac_voltage, float min_output, float max_output)
Calculate a LTC2752 DAC code given the desired output voltage and the minimum / maximum outputs for a...
Definition: LTC2752.cpp:96
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: DC1684AB.ino:288
DACB_RANGE_HIGH
static float DACB_RANGE_HIGH
Definition: DC1684AB.ino:104
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: DC1684AB.ino:205
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
ADDRESS_DACA
#define ADDRESS_DACA
Definition: LTC2752.h:94
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
demo_board_type::product_name
char product_name[15]
LTC Product (LTC2654-L16)
Definition: QuikEval_EEPROM.h:70
menu4_square_wave_output
static uint8_t menu4_square_wave_output()
Function to generate a square wave of desired frequency and voltage ranges.
Definition: DC1684AB.ino:455
DACB_RANGE_LOW
static float DACB_RANGE_LOW
Definition: DC1684AB.ino:103
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
voltage
static float voltage
Definition: DC2289AA.ino:71
LTC2752.h
LTC2752: Dual Serial 16-Bit SoftSpan IOUT DAC.
DACA_RANGE_LOW
static float DACA_RANGE_LOW
Definition: DC1684AB.ino:100
LTC2752_code_to_voltage
float LTC2752_code_to_voltage(uint16_t dac_code, float min_output, float max_output)
Calculate the LTC2752 DAC output voltage given the DAC code and and the minimum / maximum outputs for...
Definition: LTC2752.cpp:87
setup
static void setup()
Initialize Linduino.
Definition: DC1684AB.ino:117
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC1684AB.ino:220
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
LTC2752_WRITE_SPAN_DAC
#define LTC2752_WRITE_SPAN_DAC
Write Span DAC n.
Definition: LTC2752.h:101
ADDRESS_DACB
#define ADDRESS_DACB
Definition: LTC2752.h:95