| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC579A.ino
Go to the documentation of this file.
1 /*!
2 LTC2600: Octal 16-Bit Rail-to-Rail DACs in 16-Lead SSOP
3
4 @verbatim
5
6 The LTC2600/LTC2610/LTC2620 are octal 16-, 14- and 12-bit, 2.5V-to-5.5V
7 rail-to-rail voltage-output DACs in 16-lead narrow SSOP and 20-lead 4mm × 5mm
8 QFN packages. They have built-in high performance output buffers and are
9 guaranteed monotonic.
10
11 These parts establish advanced performance standards for output drive,
12 crosstalk and load regulation in single-supply, voltage output multiples.
13
14 @endverbatim
15
16
17 http://www.linear.com/product/LTC2600
18
19 http://www.linear.com/product/LTC2600#demoboards
20
21
22 Copyright 2018(c) Analog Devices, Inc.
23
24 All rights reserved.
25
26 Redistribution and use in source and binary forms, with or without
27 modification, are permitted provided that the following conditions are met:
28 - Redistributions of source code must retain the above copyright
29 notice, this list of conditions and the following disclaimer.
30 - Redistributions in binary form must reproduce the above copyright
31 notice, this list of conditions and the following disclaimer in
32 the documentation and/or other materials provided with the
33 distribution.
34 - Neither the name of Analog Devices, Inc. nor the names of its
35 contributors may be used to endorse or promote products derived
36 from this software without specific prior written permission.
37 - The use of this software may or may not infringe the patent rights
38 of one or more patent holders. This license does not release you
39 from the requirement that you obtain separate licenses from these
40 patent holders to use this software.
41 - Use of the software either in source or binary form, must be run
42 on or directly connected to an Analog Devices Inc. component.
43
44 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
45 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
46 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
48 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
50 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56
57 /*! @file
58 @ingroup LTC2600
59 */
60
61 #include <Arduino.h>
62 #include <stdint.h>
63 #include "Linduino.h"
64 #include "LT_SPI.h"
65 #include "UserInterface.h"
66 #include "LT_I2C.h"
67 #include "QuikEval_EEPROM.h"
68 #include "LTC2600.h"
69 #include <SPI.h>
70 #include <Wire.h>
71
72 //Function Declaration
73
74 void print_title(); // Print the title block
75 void print_prompt(int16_t selected_dac); // Prompt the user for an input command
76 int16_t prompt_voltage_or_code();
77 uint16_t get_voltage(float LTC2600_lsb, int16_t LTC2600_offset);
78 uint16_t get_code();
79
80 void menu_1_select_dac(int16_t *selected_dac);
81 void menu_2_write_to_input_register(int16_t selected_dac);
82 void menu_3_write_and_update_dac(int16_t selected_dac);
83 void menu_4_update_power_up_dac(int16_t selected_dac);
84 void menu_5_power_down_dac(int16_t selected_dac);
85
86 //Global variables
87 static uint8_t demo_board_connected; //!< set to 1 if the board is connected
88 static uint8_t shift_count =0; //!< The data align shift count for 16-bit =0 14-bit =2 12-bit =4
89 static float reference_voltage = 4.096; //!< set based on jumper positions
90 static int16_t LTC2600_offset =0;
91 static float LTC2600_lsb = reference_voltage/ (pow(2,16) - 1);
92
93 // constants
94
95 //! Lookup table for DAC address. Allows the "All DACs" address to be indexed right after DAC D in loops.
96 //! This technique is very useful for devices with non-monotonic channel addresses.
97 const uint8_t address_map[5] = {LTC2600_DAC_A, LTC2600_DAC_B, LTC2600_DAC_C, LTC2600_DAC_D, LTC2600_DAC_ALL}; //!< Map entered option 0..2 to DAC address
98
99 //! Used to keep track to print voltage or print code
100 enum
101 {
102 PROMPT_VOLTAGE = 0, /**< 0 */
103 PROMPT_CODE = 1 /**< 1 */
104 };
105
106 //! Initialize Linduino
107 void setup()
108 // Setup the program
109 {
110 char demo_name[] = "DC579A"; // Demo Board Name stored in QuikEval EEPROM
111 quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
112 quikeval_SPI_connect(); // Connect SPI to main data port
113 Serial.begin(115200); // Initialize the serial port to the PC
114 print_title();
115 char buffer[50];
116 read_quikeval_id_string(buffer);
117 Serial.println(buffer);
118 demo_board_connected = true; // discover_demo_board(demo_name);
119 if (demo_board_connected)
120 {
121 print_prompt(0);
122 }
123 }
124
125 //! Repeats Linduino loops
126 void loop()
127 {
128 int16_t user_command;
129 static int16_t selected_dac =0; // The selected DAC to be updated (0=A, 1=B ... 5=All). Initialized to "A".
130 // The main control loop
131 if (demo_board_connected) // Do nothing if the demo board is not connected
132 {
133 if (Serial.available()) // Check for user input
134 {
135 user_command = read_int(); // Read the user command
136 Serial.println(user_command);
137 Serial.flush();
138 switch (user_command)
139 {
140 case 1:
141 menu_1_select_dac(&selected_dac);
142 break;
143 case 2:
144 menu_2_write_to_input_register(selected_dac);
145 break;
146 case 3:
147 menu_3_write_and_update_dac(selected_dac);
148 break;
149 case 4:
150 menu_4_update_power_up_dac(selected_dac);
151 break;
152 case 5:
153 menu_5_power_down_dac(selected_dac);
154 break;
155 }
156 Serial.println("\n*****************************************************************");
157 print_prompt(selected_dac);
158 }
159 }
160 }
161
162 // Function Definitions
163
164 //! Select which DAC to operate on
165 void menu_1_select_dac(int16_t *selected_dac ) //!< what DAC to operate on
166 {
167 // Select a DAC to operate on
168 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)");
169 *selected_dac = read_int();
170 if (*selected_dac == 8)
171 {
172 Serial.println("All");
173 *selected_dac = 15;
174 }
175 else
176 {
177 Serial.println(*selected_dac);
178 }
179 }
180
181 //! Write data to input register, but do not update DAC output
182 void menu_2_write_to_input_register(int16_t selected_dac) //!< what DAC to operate on
183 {
184 uint16_t dac_code;
185
186 if (prompt_voltage_or_code() == PROMPT_VOLTAGE)
187 dac_code = get_voltage(LTC2600_lsb, LTC2600_offset);
188 else
189 dac_code = get_code();
190
191 LTC2600_write(LTC2600_CS, LTC2600_CMD_WRITE, address_map[selected_dac], dac_code << shift_count);
192 }
193
194 //!Write data to DAC register (which updates output immediately)
195 void menu_3_write_and_update_dac(int16_t selected_dac) //!< what DAC to operate on
196 {
197 uint16_t dac_code;
198
199 if (prompt_voltage_or_code() == PROMPT_VOLTAGE)
200 dac_code = get_voltage(LTC2600_lsb, LTC2600_offset);
201 else
202 dac_code = get_code();
203
204 LTC2600_write(LTC2600_CS,LTC2600_CMD_WRITE_UPDATE, address_map[selected_dac], dac_code << shift_count);
205 }
206
207 //! Update DAC with data that is stored in input register, power up if sleeping
208 void menu_4_update_power_up_dac(int16_t selected_dac) //!< what DAC to operate on
209 {
210 // Update DAC
211 LTC2600_write(LTC2600_CS,LTC2600_CMD_UPDATE, address_map[selected_dac], 0x0000);
212 }
213
214 //! Power down DAC
215 void menu_5_power_down_dac(int16_t selected_dac) //!< what DAC to operate on
216 {
217 // Power down DAC
218 LTC2600_write(LTC2600_CS,LTC2600_CMD_POWER_DOWN, address_map[selected_dac], 0x0000);
219 }
220
221
222 //! Prompt user to enter a voltage or digital code to send to DAC
223 //! @returns user input
224 int16_t prompt_voltage_or_code()
225 {
226 int16_t user_input;
227 Serial.print(F("Type 1 to enter voltage, 2 to enter code:"));
228 Serial.flush();
229 user_input = read_int();
230 Serial.println(user_input);
231
232 if (user_input != 2)
233 return(PROMPT_VOLTAGE);
234 else
235 return(PROMPT_CODE);
236 }
237
238 //! Get voltage from user input, calculate DAC code based on lsb, offset
239 //! @returns the DAC code
240 uint16_t get_voltage(float LTC2600_lsb, //!< the voltage LSB of the DAC
241 int16_t LTC2600_offset) //!< the Offset of the DAC
242 {
243 float dac_voltage;
244
245 Serial.print(F("Enter Desired DAC output voltage: "));
246 dac_voltage = read_float();
247 Serial.print(dac_voltage);
248 Serial.println(" V");
249 Serial.flush();
250 return(LTC2600_voltage_to_code(dac_voltage, LTC2600_lsb, LTC2600_offset));
251 }
252
253 //! Get code to send to DAC directly, in decimal, hex, or binary
254 //! @return code from user
255 uint16_t get_code()
256 {
257 uint16_t returncode;
258 Serial.println("Enter Desired DAC Code");
259 Serial.print("(Format 32768, 0x8000, 0100000, or B1000000000000000): ");
260 returncode = (uint16_t) read_int();
261 Serial.print("0x");
262 Serial.println(returncode, HEX);
263 Serial.flush();
264 return(returncode);
265 }
266
267 //! Prints the title block when program first starts.
268 void print_title()
269 {
270 Serial.println("");
271 Serial.println(F("*****************************************************************"));
272 Serial.println(F("* DC579A Demonstration Program *"));
273 Serial.println(F("* *"));
274 Serial.println(F("* This program demonstrates how to send data to the LTC2600 *"));
275 Serial.println(F("* octal 16/14/12-bit DAC found on the DC579A demo board. *"));
276 Serial.println(F("* *"));
277 Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
278 Serial.println(F("* *"));
279 Serial.println(F("*****************************************************************"));
280 }
281
282 //! Prints main menu.
283 void print_prompt(int16_t selected_dac) //!< what DAC to operate on
284 {
285 Serial.println(F("\nCommand Summary:"));
286 Serial.println(F(" 1-Select DAC"));
287 Serial.println(F(" 2-Write to input register (no update)"));
288 Serial.println(F(" 3-Write and update DAC"));
289 Serial.println(F(" 4-Update / power up DAC"));
290 Serial.println(F(" 5-Power down DAC"));
291
292 Serial.println("\nPresent Values:");
293 Serial.print(" Selected DAC: ");
294 if (selected_dac != 4)
295 Serial.println((char) (selected_dac + 0x41));
296 else
297 Serial.println("All");
298 Serial.print(" DAC Reference: ");
299 Serial.println("Internal");
300 Serial.print(F("Enter a command:"));
301
302 Serial.flush();
303 }
LTC2600_CMD_POWER_DOWN
#define LTC2600_CMD_POWER_DOWN
Power down n.
Definition: LTC2600.h:115
LTC2600_DAC_A
#define LTC2600_DAC_A
Definition: LTC2600.h:136
LTC2600_CMD_UPDATE
#define LTC2600_CMD_UPDATE
Update (power up) DAC register n.
Definition: LTC2600.h:112
LTC2600_CMD_WRITE
#define LTC2600_CMD_WRITE
Write to input register n.
Definition: LTC2600.h:111
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
menu_2_write_to_input_register
static void menu_2_write_to_input_register(int16_t selected_dac)
Write data to input register, but do not update DAC output.
Definition: DC579A.ino:182
LTC2600_CMD_WRITE_UPDATE
#define LTC2600_CMD_WRITE_UPDATE
Write to input register n, update (power up) all.
Definition: LTC2600.h:114
print_prompt
static void print_prompt(int16_t selected_dac)
Prints main menu.
Definition: DC579A.ino:283
LTC2600.h
LTC2600: Octal 16-Bit Rail-to-Rail DACs in 16-Lead SSOP.
LTC2600_offset
static int16_t LTC2600_offset
Definition: DC579A.ino:90
Linduino.h
Header File for Linduino Libraries and Demo Code.
LTC2600_lsb
static float LTC2600_lsb
Definition: DC579A.ino:91
setup
static void setup()
Initialize Linduino.
Definition: DC579A.ino:107
menu_5_power_down_dac
static void menu_5_power_down_dac(int16_t selected_dac)
Power down DAC.
Definition: DC579A.ino:215
LTC2600_voltage_to_code
uint16_t LTC2600_voltage_to_code(float dac_voltage, float LTC2600_lsb, int16_t LTC2600_offset)
Calculate a LTC2600 DAC code given the desired output voltage and DAC address (0-3) ...
Definition: LTC2600.cpp:90
QuikEval_EEPROM.h
QuikEval EEPROM Library.
menu_3_write_and_update_dac
static void menu_3_write_and_update_dac(int16_t selected_dac)
Write data to DAC register (which updates output immediately)
Definition: DC579A.ino:195
quikeval_SPI_init
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
shift_count
static uint8_t shift_count
The data align shift count for 16-bit =0 14-bit =2 12-bit =4.
Definition: DC579A.ino:88
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
menu_4_update_power_up_dac
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: DC579A.ino:208
LTC2600_DAC_ALL
#define LTC2600_DAC_ALL
Definition: LTC2600.h:144
PROMPT_VOLTAGE
0
Definition: DC579A.ino:102
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
menu_1_select_dac
static void menu_1_select_dac(int16_t *selected_dac)
Select which DAC to operate on.
Definition: DC579A.ino:165
get_voltage
static uint16_t get_voltage(float LTC2600_lsb, int16_t LTC2600_offset)
Get voltage from user input, calculate DAC code based on lsb, offset.
Definition: DC579A.ino:240
demo_name
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
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
PROMPT_CODE
1
Definition: DC579A.ino:103
LTC2600_CS
#define LTC2600_CS
Define the SPI CS pin.
Definition: LTC2600.h:104
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC579A.ino:268
LTC2600_write
void LTC2600_write(uint8_t cs, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code)
Write the 16-bit dac_code to the LTC2600.
Definition: LTC2600.cpp:75
LTC2600_DAC_C
#define LTC2600_DAC_C
Definition: LTC2600.h:138
LTC2600_DAC_B
#define LTC2600_DAC_B
Definition: LTC2600.h:137
prompt_voltage_or_code
static int16_t prompt_voltage_or_code()
Prompt user to enter a voltage or digital code to send to DAC.
Definition: DC579A.ino:224
reference_voltage
static float reference_voltage
set based on jumper positions
Definition: DC579A.ino:89
get_code
static uint16_t get_code()
Get code to send to DAC directly, in decimal, hex, or binary.
Definition: DC579A.ino:255
demo_board_connected
static uint8_t demo_board_connected
set to 1 if the board is connected
Definition: DC579A.ino:87
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
address_map
const uint8_t address_map[5]
Lookup table for DAC address.
Definition: DC579A.ino:97
LTC2600_DAC_D
#define LTC2600_DAC_D
Definition: LTC2600.h:139
loop
static void loop()
Repeats Linduino loops.
Definition: DC579A.ino:126