| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC809A.ino
Go to the documentation of this file.
1 /*!
2 LTC2604: Quad 16-Bit Rail-to-Rail DACs in 16-Lead SSOP
3
4 @verbatim
5
6 The LTC2604/LTC2614/LTC2624 are quad 16-,14- and 12-bit 2.5V to 5.5V
7 rail-to-rail voltage output DACs in 16-lead narrow SSOP packages. These
8 parts have separate reference inputs for each DAC. They have built-in
9 high performance output buffers and are 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/LTC2604
18
19 http://www.linear.com/product/LTC2604#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 LTC2604
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 "LTC2604.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 LTC2604_lsb, int16_t LTC2604_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] = {4.096,4.096,4.096,4.096}; //!< set based on jumper positions
90 static int16_t LTC2604_offset =0;
91 static float LTC2604_lsb[4] = {reference_voltage[0]/ (pow(2,16) - 1) , reference_voltage[1]/ (pow(2,16) - 1),
92 reference_voltage[2]/ (pow(2,16) - 1),reference_voltage[3]/ (pow(2,16) - 1)
93 };
94
95 // constants
96
97 //! Lookup table for DAC address. Allows the "All DACs" address to be indexed right after DAC D in loops.
98 //! This technique is very useful for devices with non-monotonic channel addresses.
99 const uint8_t address_map[5] = {LTC2604_DAC_A, LTC2604_DAC_B, LTC2604_DAC_C, LTC2604_DAC_D, LTC2604_DAC_ALL}; //!< Map entered option 0..2 to DAC address
100
101 //! Used to keep track to print voltage or print code
102 enum
103 {
104 PROMPT_VOLTAGE = 0, /**< 0 */
105 PROMPT_CODE = 1 /**< 1 */
106 };
107
108 //! Initialize Linduino
109 void setup()
110 // Setup the program
111 {
112 char demo_name[] = "DC809A"; // Demo Board Name stored in QuikEval EEPROM
113 quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
114 quikeval_SPI_connect(); // Connect SPI to main data port
115 Serial.begin(115200); // Initialize the serial port to the PC
116 print_title();
117 demo_board_connected = true; //discover_demo_board(demo_name);
118 if (demo_board_connected)
119 {
120 print_prompt(0);
121 }
122 }
123
124 //! Repeats Linduino loops
125 void loop()
126 {
127 int16_t user_command;
128 static int16_t selected_dac =0; // The selected DAC to be updated (0=A, 1=B ... 5=All). Initialized to "A".
129 // The main control loop
130 if (demo_board_connected) // Do nothing if the demo board is not connected
131 {
132 if (Serial.available()) // Check for user input
133 {
134 user_command = read_int(); // Read the user command
135 Serial.println(user_command);
136 Serial.flush();
137 switch (user_command)
138 {
139 case 1:
140 menu_1_select_dac(&selected_dac);
141 break;
142 case 2:
143 menu_2_write_to_input_register(selected_dac);
144 break;
145 case 3:
146 menu_3_write_and_update_dac(selected_dac);
147 break;
148 case 4:
149 menu_4_update_power_up_dac(selected_dac);
150 break;
151 case 5:
152 menu_5_power_down_dac(selected_dac);
153 break;
154 }
155 Serial.println("\n*****************************************************************");
156 print_prompt(selected_dac);
157 }
158 }
159 }
160
161 // Function Definitions
162
163 //! Select which DAC to operate on
164 void menu_1_select_dac(int16_t *selected_dac ) //!< what DAC to operate on
165 {
166 // Select a DAC to operate on
167 Serial.print("Select DAC to operate on (0=A, 1=B, 2=C, 3=D, 4=All)");
168 *selected_dac = read_int();
169 if (*selected_dac == 4)
170 Serial.println("All");
171 else
172 Serial.println(*selected_dac);
173 }
174
175 //! Write data to input register, but do not update DAC output
176 void menu_2_write_to_input_register(int16_t selected_dac) //!< what DAC to operate on
177 {
178 uint16_t dac_code;
179
180 if (prompt_voltage_or_code() == PROMPT_VOLTAGE)
181 dac_code = get_voltage(LTC2604_lsb[selected_dac], LTC2604_offset);
182 else
183 dac_code = get_code();
184
185 LTC2604_write(LTC2604_CS, LTC2604_CMD_WRITE, address_map[selected_dac], dac_code << shift_count);
186 }
187
188 //!Write data to DAC register (which updates output immediately)
189 void menu_3_write_and_update_dac(int16_t selected_dac) //!< what DAC to operate on
190 {
191 uint16_t dac_code;
192
193 if (prompt_voltage_or_code() == PROMPT_VOLTAGE)
194 dac_code = get_voltage(LTC2604_lsb[selected_dac], LTC2604_offset);
195 else
196 dac_code = get_code();
197
198 LTC2604_write(LTC2604_CS,LTC2604_CMD_WRITE_UPDATE, address_map[selected_dac], dac_code << shift_count);
199 }
200
201 //! Update DAC with data that is stored in input register, power up if sleeping
202 void menu_4_update_power_up_dac(int16_t selected_dac) //!< what DAC to operate on
203 {
204 // Update DAC
205 LTC2604_write(LTC2604_CS,LTC2604_CMD_UPDATE, address_map[selected_dac], 0x0000);
206 }
207
208 //! Power down DAC
209 void menu_5_power_down_dac(int16_t selected_dac) //!< what DAC to operate on
210 {
211 // Power down DAC
212 LTC2604_write(LTC2604_CS,LTC2604_CMD_POWER_DOWN, address_map[selected_dac], 0x0000);
213 }
214
215
216 //! Prompt user to enter a voltage or digital code to send to DAC
217 //! @returns user input
218 int16_t prompt_voltage_or_code()
219 {
220 int16_t user_input;
221 Serial.print(F("Type 1 to enter voltage, 2 to enter code:"));
222 Serial.flush();
223 user_input = read_int();
224 Serial.println(user_input);
225
226 if (user_input != 2)
227 return(PROMPT_VOLTAGE);
228 else
229 return(PROMPT_CODE);
230 }
231
232 //! Get voltage from user input, calculate DAC code based on lsb, offset
233 //! @returns the DAC code
234 uint16_t get_voltage(float LTC2604_lsb, //!< the voltage LSB of the DAC
235 int16_t LTC2604_offset) //!< the Offset of the DAC
236 {
237 float dac_voltage;
238
239 Serial.print(F("Enter Desired DAC output voltage: "));
240 dac_voltage = read_float();
241 Serial.print(dac_voltage);
242 Serial.println(" V");
243 Serial.flush();
244 return(LTC2604_voltage_to_code(dac_voltage, LTC2604_lsb, LTC2604_offset));
245 }
246
247 //! Get code to send to DAC directly, in decimal, hex, or binary
248 //! @return code from user
249 uint16_t get_code()
250 {
251 uint16_t returncode;
252 Serial.println("Enter Desired DAC Code");
253 Serial.print("(Format 32768, 0x8000, 0100000, or B1000000000000000): ");
254 returncode = (uint16_t) read_int();
255 Serial.print("0x");
256 Serial.println(returncode, HEX);
257 Serial.flush();
258 return(returncode);
259 }
260
261 //! Prints the title block when program first starts.
262 void print_title()
263 {
264 Serial.println("");
265 Serial.println(F("*****************************************************************"));
266 Serial.println(F("* DC809A Demonstration Program *"));
267 Serial.println(F("* *"));
268 Serial.println(F("* This program demonstrates how to send data to the LTC2604 *"));
269 Serial.println(F("* quad 16/14/12-bit DAC found on the DC809A demo board. *"));
270 Serial.println(F("* *"));
271 Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
272 Serial.println(F("* *"));
273 Serial.println(F("*****************************************************************"));
274 }
275
276 //! Prints main menu.
277 void print_prompt(int16_t selected_dac) //!< what DAC to operate on
278 {
279 Serial.println(F("\nCommand Summary:"));
280 Serial.println(F(" 1-Select DAC"));
281 Serial.println(F(" 2-Write to input register (no update)"));
282 Serial.println(F(" 3-Write and update DAC"));
283 Serial.println(F(" 4-Update / power up DAC"));
284 Serial.println(F(" 5-Power down DAC"));
285
286 Serial.println("\nPresent Values:");
287 Serial.print(" Selected DAC: ");
288 if (selected_dac != 4)
289 Serial.println((char) (selected_dac + 0x41));
290 else
291 Serial.println("All");
292 Serial.print(" DAC Reference: ");
293 Serial.println("Internal");
294 Serial.print(F("Enter a command:"));
295
296 Serial.flush();
297 }
demo_board_connected
static uint8_t demo_board_connected
set to 1 if the board is connected
Definition: DC809A.ino:87
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
setup
static void setup()
Initialize Linduino.
Definition: DC809A.ino:109
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: DC809A.ino:218
LTC2604_DAC_D
#define LTC2604_DAC_D
Definition: LTC2604.h:135
LTC2604_CMD_WRITE_UPDATE
#define LTC2604_CMD_WRITE_UPDATE
Write to input register n, update (power up) all.
Definition: LTC2604.h:114
Linduino.h
Header File for Linduino Libraries and Demo Code.
LTC2604_voltage_to_code
uint16_t LTC2604_voltage_to_code(float dac_voltage, float LTC2604_lsb, int16_t LTC2604_offset)
Calculate a LTC2604 DAC code given the desired output voltage and DAC address (0-3) ...
Definition: LTC2604.cpp:90
PROMPT_CODE
1
Definition: DC809A.ino:105
print_prompt
static void print_prompt(int16_t selected_dac)
Prints main menu.
Definition: DC809A.ino:277
LTC2604_DAC_A
#define LTC2604_DAC_A
Definition: LTC2604.h:132
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: DC809A.ino:189
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: DC809A.ino:202
QuikEval_EEPROM.h
QuikEval EEPROM Library.
LTC2604_DAC_B
#define LTC2604_DAC_B
Definition: LTC2604.h:133
quikeval_SPI_init
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
LTC2604_lsb
static float LTC2604_lsb[4]
Definition: DC809A.ino:91
reference_voltage
static float reference_voltage[4]
set based on jumper positions
Definition: DC809A.ino:89
LTC2604_DAC_C
#define LTC2604_DAC_C
Definition: LTC2604.h:134
LTC2604_CMD_UPDATE
#define LTC2604_CMD_UPDATE
Update (power up) DAC register n.
Definition: LTC2604.h:112
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
LTC2604_write
void LTC2604_write(uint8_t cs, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code)
Write the 16-bit dac_code to the LTC2604.
Definition: LTC2604.cpp:75
address_map
const uint8_t address_map[5]
Lookup table for DAC address.
Definition: DC809A.ino:99
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC809A.ino:262
LTC2604_offset
static int16_t LTC2604_offset
Definition: DC809A.ino:90
get_voltage
static uint16_t get_voltage(float LTC2604_lsb, int16_t LTC2604_offset)
Get voltage from user input, calculate DAC code based on lsb, offset.
Definition: DC809A.ino:234
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
LTC2604_CS
#define LTC2604_CS
Define the SPI CS pin.
Definition: LTC2604.h:104
menu_5_power_down_dac
static void menu_5_power_down_dac(int16_t selected_dac)
Power down DAC.
Definition: DC809A.ino:209
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
get_code
static uint16_t get_code()
Get code to send to DAC directly, in decimal, hex, or binary.
Definition: DC809A.ino:249
loop
static void loop()
Repeats Linduino loops.
Definition: DC809A.ino:125
LTC2604.h
LTC2604: Quad 16-Bit Rail-to-Rail DACs in 16-Lead SSOP.
menu_1_select_dac
static void menu_1_select_dac(int16_t *selected_dac)
Select which DAC to operate on.
Definition: DC809A.ino:164
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: DC809A.ino:176
LTC2604_CMD_POWER_DOWN
#define LTC2604_CMD_POWER_DOWN
Power down n.
Definition: LTC2604.h:115
shift_count
static uint8_t shift_count
The data align shift count for 16-bit =0 14-bit =2 12-bit =4.
Definition: DC809A.ino:88
LTC2604_CMD_WRITE
#define LTC2604_CMD_WRITE
Write to input register n.
Definition: LTC2604.h:111
PROMPT_VOLTAGE
0
Definition: DC809A.ino:104
LTC2604_DAC_ALL
#define LTC2604_DAC_ALL
Definition: LTC2604.h:136