| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

DC1795A.ino
Go to the documentation of this file.
1 /*!
2 DC1795A
3 LTC6950: 1.4GHz Low Phase Noise, Low Jitter PLL with Clock Distribution
4
5 @verbatim
6
7 Setup:
8 Set the terminal baud rate to 115200 and select the newline terminator.
9 Refer to Demo Manual DC1795A.
10 Ensure all jumpers are installed in the factory default positions.
11 Two power supplies are needed for this demo board: a 5v and a 3.3v supply.
12 The 5V powers the 5V supply and V+VCO turret.
13
14
15 Command Description:
16
17 *****Main Menu*****
18 1- Load Default Settings- Loads the SPI map that is identical to file
19 LTC6950_ALL_CHAN_250MHz.clkset that is supplied with the ClockWizard and mentioned
20 in the DC1795A user's manual. It assumes a 100MHz reference input, a 1GHz VCO input
21 and the default DC1795A BOM. It should output a 250MHz signal on all outputs.
22
23 ** If you want to use a different loop filter, reference frequency or different
24 register settings. Please use ClockWizard for the loop filter design and initial
25 device setup. The register settings from ClockWizard can be entered into menu option 2.
26
27 2- READ/WRITE to Registers Addresses- Selecting this option will cause all the registers to
28 be read, stored to variables, and displayed. The user will then have the option
29 to write to one register address at a time.
30
31 3- READ/WRITE to Registers Fields- Selecting this option will allow the user
32 to read or write to one register field name at a time.
33
34 4- This function calculates and programs OD, ND, NUM based on the desired Frf,
35 the reference frequency, and the current RD value. Linduino One (Arduino Uno) are
36 limited to 32 bit floats, int and doubles. Significant rounding errors are created
37 with this 32 bit limitation. Therefore, this function uses 64bit math functions
38 specifically created to overcome this limitation. After OD, ND, and NUM are programmed,
39 the program calibrates the LTC6950. If other register need change see menu 2 or menu 3.
40
41 5- This function stores the current SPI settings in the demo boards EEPROM
42
43 6- This function loads SPI settings from the demo boards EEPROM to the device
44
45 USER INPUT DATA FORMAT:
46 decimal : 1024
47 hex : 0x400
48 octal : 02000 (leading 0 "zero")
49 binary : B10000000000
50 float : 1024.0
51
52 @endverbatim
53
54 http://www.linear.com/product/LTC6950
55
56 http://www.linear.com/product/LTC6950#demoboards
57
58
59 Copyright 2018(c) Analog Devices, Inc.
60
61 All rights reserved.
62
63 Redistribution and use in source and binary forms, with or without
64 modification, are permitted provided that the following conditions are met:
65 - Redistributions of source code must retain the above copyright
66 notice, this list of conditions and the following disclaimer.
67 - Redistributions in binary form must reproduce the above copyright
68 notice, this list of conditions and the following disclaimer in
69 the documentation and/or other materials provided with the
70 distribution.
71 - Neither the name of Analog Devices, Inc. nor the names of its
72 contributors may be used to endorse or promote products derived
73 from this software without specific prior written permission.
74 - The use of this software may or may not infringe the patent rights
75 of one or more patent holders. This license does not release you
76 from the requirement that you obtain separate licenses from these
77 patent holders to use this software.
78 - Use of the software either in source or binary form, must be run
79 on or directly connected to an Analog Devices Inc. component.
80
81 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
82 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
83 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
84 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
85 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
86 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
87 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
88 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
89 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
90 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91 */
92
93 /*! @file
94 @ingroup LTC6950
95 */
96
97 #include <Arduino.h>
98 #include <stdint.h>
99 #include "Linduino.h"
100 #include "LT_SPI.h"
101 #include "UserInterface.h"
102 #include "LT_I2C.h"
103 #include "QuikEval_EEPROM.h"
104 #include "LTC6950.h"
105 #include <SPI.h>
106 #include <Wire.h>
107
108 // Function Declaration
109 void print_title(); // Print the title block
110 void print_prompt(); // Print the main menu
111 void menu_1_load_default_settings(); // Sub-menus
112 void menu_2_RW_to_reg_addresss();
113 void menu_3_RW_to_reg_field();
114 void menu_4_set_frf();
115 void menu_5_store_settings();
116 void menu_6_restore_settings();
117
118 // Global Variables
119 static uint8_t ref_out = 0; //!< Used to keep track of reference out status
120 static int8_t demo_board_connected; //!< Demo Board Name stored in QuikEval EEPROM
121 uint8_t First_Run=0; //!< if first time through loop = 0, otherwise=1
122
123
124 /* ------------------------------------------------------------------------- */
125 //! Initialize Linduino
126 //! @return void
127 void setup()
128 {
129 char demo_name[] = "DC1795"; // Demo Board Name stored in QuikEval EEPROM
130 uint8_t data;
131
132 quikeval_SPI_init(); //! Configure the spi port for 4MHz SCK
133 quikeval_SPI_connect(); //! Connect SPI to main data port
134 quikeval_I2C_init(); //! Configure the EEPROM I2C port for 100kHz
135 Serial.begin(115200); //! Initialize the serial port to the PC
136 LTC6950_init();
137 print_title();
138
139 demo_board_connected = discover_demo_board(demo_name); //! Checks if correct demo board is connected.
140
141 if (!demo_board_connected)
142 while (1); //! Does nothing if the demo board is not connected
143
144 Serial.print(demo_board.name);
145 Serial.println(F(" was found"));
146
147 print_prompt();
148 } // end of setup()
149
150
151 /* ------------------------------------------------------------------------- */
152 //! Repeats Linduino loop
153 //! @return void
154 void loop()
155 {
156 uint16_t user_command; // User input command
157
158 if (Serial.available()) // Check for user input
159 {
160 if (First_Run==0)
161 {
162 First_Run=1;
163 }
164
165 user_command = read_int(); //! Reads the user command
166 if (user_command != 'm')
167 Serial.println(user_command);
168
169 switch (user_command) //! Prints the appropriate submenu
170 {
171 case 1:
172 menu_1_load_default_settings();
173 break;
174
175 case 2:
176 menu_2_RW_to_reg_addresss();
177 break;
178
179 case 3:
180 menu_3_RW_to_reg_field();
181 break;
182
183 case 4:
184 menu_4_set_frf();
185 break;
186
187 case 5:
188 menu_5_store_settings();
189 break;
190
191 case 6:
192 menu_6_restore_settings();
193 break;
194
195 default:
196 Serial.println(F("Incorrect Option"));
197 break;
198 } // end of switch statement
199 Serial.println(F("\n*****************************************************************"));
200 print_prompt();
201 } // end of if statement
202 } // end of loop()
203
204 // Function Definitions
205 /* ------------------------------------------------------------------------- */
206 //! Menu 1: Load Default SPI Register Settings
207 //! This function loads the register settings referenced
208 //! in the DC1795A demo manual's quick start section.
209 //! The register settings loaded are the same as CLOCK WIZARDS
210 //! clkset files LTC6950_PECL0_250MHz.clkset
211 //! The setting loaded with this function assume the LTC6950's
212 //! reference is set to 100MHz, the VCO input is set to 1GHz and
213 //! the DC1795A's BOM has not been modified.
214 //! @return void
215 void menu_1_load_default_settings()
216 {
217
218 set_LTC6950_ALLREGS(LTC6950_CS, 0x04,0x3b,0x08,0x00,0x3b,0x00,0x00,0x01,0x00,0x0a,0x44,0x80,0x84,0x80,0x84,0x80,0x84,0x80,0x84,0x80,0x04);
219 Serial.println(F("Registers Have Been Written"));
220 } // end menu_1_load_default_settings function
221
222
223 /* ------------------------------------------------------------------------- */
224 //! Menu 2: Reads and/or Writes the SPI register address
225 //! This function reads and displays all SPI register address settings in HEX format.
226 //! It then provides an option to modify(write to) individual registers one at time
227 //!
228 //! EXAMPLE:
229 //! - 0- ADDR00 = 0x04 (read only)
230 //! - 1- ADDR01 = 0x04
231 //! - ....
232 //! - 21- ADDR15 = 0x04
233 //! - 22- ADDR16 = 0x65 (read only)
234 //! - 0 - Return to Main Menu
235 //! - Enter a command (1-21 to modify register, or '0' to return to Main Menu):
236 //! @return void
237 void menu_2_RW_to_reg_addresss()
238 {
239 uint8_t i, regval, user_regval, num_reg;
240 uint16_t user_address; // User input command
241
242 num_reg = get_LTC6950_REGSIZE();
243 user_address=1;
244 // Read/Write loop, can exit loop by choosing '0'
245 while (user_address != 0)
246 {
247 Serial.println(F("\n*****************************************************************"));
248 // Read All Registers and display results
249 for (i=0; i<num_reg; i++)
250 {
251 regval = LTC6950_read(LTC6950_CS,i);
252 Serial.print(i);
253 if (i<16)
254 Serial.print(F("- ADDR0"));
255 else
256 Serial.print(F("- ADDR"));
257 Serial.print(i, HEX);
258 Serial.print(F(" = 0x"));
259 if (regval<16) Serial.print(F("0"));
260 Serial.print(regval, HEX);
261 if (i==3) Serial.print(F(" (warning: if D2=1 it resets all registers. RES6950 Bit)"));
262 if ((i==0)||(i==(num_reg-1))) Serial.print(F(" (read only) "));
263 Serial.println("");
264 } // end for loop
265 Serial.print("0 - Return to Main Menu\n\n");
266 // User input: Select which register to modify, or return to main menu
267 Serial.print("Enter a command (1-21 to modify register, or '0' to return to Main Menu): ");
268 user_address = read_int(); //! Reads the user command
269 Serial.println(user_address);
270
271 // User input: enter new setting for selected register
272 if (user_address >0 && user_address<(num_reg-1))
273 {
274 Serial.print("What value should ADDR");
275 Serial.print(user_address);
276 Serial.print(" be set to (ex: HEX format 0xff): ");
277 user_regval = read_int(); //! Reads the user command
278 Serial.println(user_regval);
279
280 // writes new setting to part
281 LTC6950_write(LTC6950_CS, (uint8_t)user_address, user_regval);
282 } // end if statement
283 } // end while loop
284 } // end menu_2_RW_to_reg_addresss
285
286
287 /* ------------------------------------------------------------------------- */
288 //! Support function for function menu_3_RW_to_reg_field
289 //! displays current state of select field
290 //! provides user the option to write to that field or return to menu
291 //! @return field value (user input) that will be written to part
292 long field_menu_RW(long field_val, //!< current state of the selected field
293 char field_name[], //!< SPI Field name selected
294 uint8_t f //!< SPI field identifier identifies selected fields information in SPI MAP arrays
295 )
296 {
297 long usr_field_val;
298 uint8_t field_size, i;
299 long max_num=1, pow2=1;
300
301 Serial.print("CURRENT STATE (HEX): ");
302 Serial.print(field_name);
303 Serial.print("= 0x");
304 Serial.println(field_val, HEX);
305
306 if (get_LTC6950_SPI_FIELD_RW(f)==0)
307 {
308 field_size=get_LTC6950_SPI_FIELD_NUMBITS(f);
309 for (i=1; i<field_size; i++)
310 {
311 pow2=pow2*2;
312 max_num=max_num + pow2;
313 }
314
315 Serial.print("What value should ");
316 Serial.print(field_name);
317 Serial.print(" be set to or type '-1' to exit: (ex: HEX format 0x00 to 0x");
318 Serial.print(max_num, HEX);
319 Serial.print(")");
320 usr_field_val = read_int(); //! Reads the user command
321
322 if (usr_field_val>=0 && usr_field_val<=max_num)
323 {
324 Serial.println(usr_field_val);
325 return usr_field_val;
326 }
327 else
328 {
329 return field_val;
330 } // end of if statement
331 } // end of if statement
332 } // end of field_menu_RW
333
334
335 /* ------------------------------------------------------------------------- */
336 //! Menu 3: Reads and/or Writes individual SPI fields
337 //! This function provides the user with a list of all SPI fields.
338 //! The user can select a SPI field to read its current value.
339 //! Then the user will be provided with an option to write to that field
340 //! or return to the selection menu.
341 //!
342 //! EXAMPLE:
343 //! - 1-CMSINV 26-IBIAS3 51-PD_OUT2
344 //! - 2-CP 27-INV_ST1 52-PD_OUT3
345 //! - ....
346 //! - 23-IBIAS0 48-PD_DIV4 73-UNLOCK *
347 //! - 24-IBIAS1 49-PD_OUT0
348 //! - 25-IBIAS2 50-PD_OUT1
349 //! - 0 - Return to Main Menu
350 //! - * = READ ONLY FIELD
351 //! - Enter a command (1-73 to modify register, or '0' to return to Main Menu):
352 //! @return void
353 void menu_3_RW_to_reg_field()
354 {
355 uint8_t field_num;
356 long field_val;
357
358 field_val=999L;
359 field_num=1;
360 // Read/Write loop, can exit loop by choosing 'm'
361 while (field_num != 0)
362 {
363 Serial.println(F("\n*****************************************************************"));
364 // Select Fields to read and write to
365 Serial.print(F("1-CMSINV 26-IBIAS3 51-PD_OUT2\n"));
366 Serial.print(F("2-CP 27-INV_ST1 52-PD_OUT3\n"));
367 Serial.print(F("3-CPCHI 28-INV_ST2 53-PD_OUT4\n"));
368 Serial.print(F("4-CPCLO 29-LKCT 54-PDPLL\n"));
369 Serial.print(F("5-CPDN 30-LKEN 55-PDREFAC\n"));
370 Serial.print(F("6-CPINV 31-LKWIN 56-PDVCOAC\n"));
371 Serial.print(F("7-CPMID 32-LOCK * 57-R\n"));
372 Serial.print(F("8-CPRST 33-LVCMS 58-RDIVOUT\n"));
373 Serial.print(F("9-CPUP 34-M0 59-RES6950\n"));
374 Serial.print(F("10-CPWIDE 35-M1 60-RESET_R\n"));
375 Serial.print(F("11-DEL0 36-M2 61-RESET_N\n"));
376 Serial.print(F("12-DEL1 37-M3 62-REV *\n"));
377 Serial.print(F("13-DEL2 38-M4 63-SM1\n"));
378 Serial.print(F("14-DEL3 39-N 64-SM2\n"));
379 Serial.print(F("15-DEL4 40-NO_REF * 65-SYNCMD\n"));
380 Serial.print(F("16-FILTR 41-NO_VCO * 66-SYNC_EN0\n"));
381 Serial.print(F("17-FILTV 42-PART * 67-SYNC_EN1\n"));
382 Serial.print(F("18-FLDRV0 43-PDALL 68-SYNC_EN2\n"));
383 Serial.print(F("19-FLDRV1 44-PD_DIV0 69-SYNC_EN3\n"));
384 Serial.print(F("20-FLDRV2 45-PD_DIV1 70-SYNC_EN4\n"));
385 Serial.print(F("21-FLDRV3 46-PD_DIV2 71-THI *\n"));
386 Serial.print(F("22-FLDRV4 47-PD_DIV3 72-TLO *\n"));
387 Serial.print(F("23-IBIAS0 48-PD_DIV4 73-UNLOCK *\n"));
388 Serial.print(F("24-IBIAS1 49-PD_OUT0 \n"));
389 Serial.print(F("25-IBIAS2 50-PD_OUT1 \n"));
390 Serial.print("0 - Return to Main Menu\n");
391 Serial.print("* = READ ONLY FIELD\n\n");
392
393 Serial.print("Enter a command (1-73 to modify register, or '0' to return to Main Menu): ");
394 field_num = read_int(); //! Reads the user command
395 Serial.println(field_num);
396
397 // User input: enter new setting for selected register
398 if (field_num != 0)
399 {
400 switch (field_num) //! Prints the appropriate submenu
401 {
402 case LTC6950_CMSINV:
403 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CMSINV); // reads selected field
404 field_val=field_menu_RW(field_val,"CMSINV",LTC6950_CMSINV); // user interface control and printout
405 if (field_val>-1)
406 {
407 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CMSINV, field_val); // updates selected field
408 }
409 break;
410
411 case LTC6950_CP:
412 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CP); // reads selected field
413 field_val=field_menu_RW(field_val,"CP",LTC6950_CP); // user interface control and printout
414 if (field_val>-1)
415 {
416 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CP, field_val); // updates selected field
417 }
418 break;
419
420 case LTC6950_CPCHI:
421 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPCHI); // reads selected field
422 field_val=field_menu_RW(field_val,"CPCHI",LTC6950_CPCHI); // user interface control and printout
423 if (field_val>-1)
424 {
425 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPCHI, field_val); // updates selected field
426 }
427 break;
428
429 case LTC6950_CPCLO:
430 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPCLO); // reads selected field
431 field_val=field_menu_RW(field_val,"CPCLO",LTC6950_CPCLO); // user interface control and printout
432 if (field_val>-1)
433 {
434 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPCLO, field_val); // updates selected field
435 }
436 break;
437
438 case LTC6950_CPDN:
439 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPDN); // reads selected field
440 field_val=field_menu_RW(field_val,"CPDN",LTC6950_CPDN); // user interface control and printout
441 if (field_val>-1)
442 {
443 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPDN, field_val); // updates selected field
444 }
445 break;
446
447 case LTC6950_CPINV:
448 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPINV); // reads selected field
449 field_val=field_menu_RW(field_val,"CPINV",LTC6950_CPINV); // user interface control and printout
450 if (field_val>-1)
451 {
452 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPINV, field_val); // updates selected field
453 }
454 break;
455
456 case LTC6950_CPMID:
457 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPMID); // reads selected field
458 field_val=field_menu_RW(field_val,"CPMID",LTC6950_CPMID); // user interface control and printout
459 if (field_val>-1)
460 {
461 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPMID, field_val); // updates selected field
462 }
463 break;
464
465 case LTC6950_CPRST:
466 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPRST); // reads selected field
467 field_val=field_menu_RW(field_val,"CPRST",LTC6950_CPRST); // user interface control and printout
468 if (field_val>-1)
469 {
470 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPRST, field_val); // updates selected field
471 }
472 break;
473
474 case LTC6950_CPUP:
475 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPUP); // reads selected field
476 field_val=field_menu_RW(field_val,"CPUP",LTC6950_CPUP); // user interface control and printout
477 if (field_val>-1)
478 {
479 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPUP, field_val); // updates selected field
480 }
481 break;
482
483 case LTC6950_CPWIDE:
484 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_CPWIDE); // reads selected field
485 field_val=field_menu_RW(field_val,"CPWIDE",LTC6950_CPWIDE); // user interface control and printout
486 if (field_val>-1)
487 {
488 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_CPWIDE, field_val); // updates selected field
489 }
490 break;
491
492 case LTC6950_DEL0:
493 // DEL1-4 programmed same as DEL0 above, just change DEL0 to DELx
494 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_DEL0); // reads selected field
495 field_val=field_menu_RW(field_val,"DEL0",LTC6950_DEL0); // user interface control and printout
496 if (field_val>-1)
497 {
498 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_DEL0, field_val); // updates selected field
499 }
500 break;
501
502 case LTC6950_FILTR:
503 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_FILTR); // reads selected field
504 field_val=field_menu_RW(field_val,"FILTR",LTC6950_FILTR); // user interface control and printout
505 if (field_val>-1)
506 {
507 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_FILTR, field_val); // updates selected field
508 }
509 break;
510
511 case LTC6950_FILTV:
512 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_FILTV); // reads selected field
513 field_val=field_menu_RW(field_val,"FILTV",LTC6950_FILTV); // user interface control and printout
514 if (field_val>-1)
515 {
516 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_FILTV, field_val); // updates selected field
517 }
518 break;
519
520 case LTC6950_FLDRV0:
521 // FLDRV1-4 programmed same as FLDRV0 above, just change FLDRV0 to FLDRVx
522 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_FLDRV0); // reads selected field
523 field_val=field_menu_RW(field_val,"FLDRV0",LTC6950_FLDRV0); // user interface control and printout
524 if (field_val>-1)
525 {
526 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_FLDRV0, field_val); // updates selected field
527 }
528 break;
529
530 case LTC6950_IBIAS0:
531 // IBIAS1-3 programmed same as IBIAS0 above, just change IBIAS0 to IBIASx
532 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_IBIAS0); // reads selected field
533 field_val=field_menu_RW(field_val,"IBIAS0",LTC6950_IBIAS0); // user interface control and printout
534 if (field_val>-1)
535 {
536 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_IBIAS0, field_val); // updates selected field
537 }
538 break;
539
540 case LTC6950_INV_ST1:
541 // INV_ST2 programmed same as INV_ST1 above, just change INV_ST1 to INV_STx
542 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_INV_ST1); // reads selected field
543 field_val=field_menu_RW(field_val,"INV_ST1",LTC6950_INV_ST1); // user interface control and printout
544 if (field_val>-1)
545 {
546 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_INV_ST1, field_val); // updates selected field
547 }
548 break;
549
550 case LTC6950_LKCT:
551 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_LKCT); // reads selected field
552 field_val=field_menu_RW(field_val,"LKCT",LTC6950_LKCT); // user interface control and printout
553 if (field_val>-1)
554 {
555 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_LKCT, field_val); // updates selected field
556 }
557 break;
558
559 case LTC6950_LKEN:
560 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_LKEN); // reads selected field
561 field_val=field_menu_RW(field_val,"LKEN",LTC6950_LKEN); // user interface control and printout
562 if (field_val>-1)
563 {
564 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_LKEN, field_val); // updates selected field
565 }
566 break;
567
568 case LTC6950_LKWIN:
569 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_LKWIN); // reads selected field
570 field_val=field_menu_RW(field_val,"LKWIN",LTC6950_LKWIN); // user interface control and printout
571 if (field_val>-1)
572 {
573 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_LKWIN, field_val); // updates selected field
574 }
575 break;
576
577 case LTC6950_LOCK:
578 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_LOCK); // reads selected field
579 field_val=field_menu_RW(field_val,"LOCK",LTC6950_LOCK); // user interface control and printout
580 if (field_val>-1)
581 {
582 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_LOCK, field_val); // updates selected field
583 }
584 break;
585
586 case LTC6950_LVCMS:
587 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_LVCMS); // reads selected field
588 field_val=field_menu_RW(field_val,"LVCMS",LTC6950_LVCMS); // user interface control and printout
589 if (field_val>-1)
590 {
591 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_LVCMS, field_val); // updates selected field
592 }
593 break;
594
595 case LTC6950_M0:
596 // M1-4 programmed same as M0 above, just change M0 to Mx
597 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_M0); // reads selected field
598 field_val=field_menu_RW(field_val,"M0",LTC6950_M0); // user interface control and printout
599 if (field_val>-1)
600 {
601 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_M0, field_val); // updates selected field
602 }
603 break;
604
605 case LTC6950_N:
606 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_N); // reads selected field
607 field_val=field_menu_RW(field_val,"N",LTC6950_N); // user interface control and printout
608 if (field_val>-1)
609 {
610 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_N, field_val); // updates selected field
611 }
612 break;
613
614 case LTC6950_NO_REF:
615 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_NO_REF); // reads selected field
616 field_val=field_menu_RW(field_val,"NO_REF",LTC6950_NO_REF); // user interface control and printout
617 if (field_val>-1)
618 {
619 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_NO_REF, field_val); // updates selected field
620 }
621 break;
622
623 case LTC6950_NO_VCO:
624 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_NO_VCO); // reads selected field
625 field_val=field_menu_RW(field_val,"NO_VCO",LTC6950_NO_VCO); // user interface control and printout
626 if (field_val>-1)
627 {
628 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_NO_VCO, field_val); // updates selected field
629 }
630 break;
631
632 case LTC6950_PART:
633 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_PART); // reads selected field
634 field_val=field_menu_RW(field_val,"PART",LTC6950_PART); // user interface control and printout
635 if (field_val>-1)
636 {
637 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_PART, field_val); // updates selected field
638 }
639 break;
640
641 case LTC6950_PDALL:
642 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_PDALL); // reads selected field
643 field_val=field_menu_RW(field_val,"PDALL",LTC6950_PDALL); // user interface control and printout
644 if (field_val>-1)
645 {
646 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_PDALL, field_val); // updates selected field
647 }
648 break;
649
650 case LTC6950_PD_DIV0:
651 // PD_DIV1-4 programmed same as PD_DIV0 above, just change PD_DIV0 to PD_DIVx
652 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_PD_DIV0); // reads selected field
653 field_val=field_menu_RW(field_val,"PD_DIV0",LTC6950_PD_DIV0); // user interface control and printout
654 if (field_val>-1)
655 {
656 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_PD_DIV0, field_val); // updates selected field
657 }
658 break;
659
660 case LTC6950_PD_OUT0:
661 // PD_OUT1-4 programmed same as PD_OUT0 above, just change PD_OUT0 to PD_OUTx
662 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_PD_OUT0); // reads selected field
663 field_val=field_menu_RW(field_val,"PD_OUT0",LTC6950_PD_OUT0); // user interface control and printout
664 if (field_val>-1)
665 {
666 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_PD_OUT0, field_val); // updates selected field
667 }
668 break;
669
670 case LTC6950_PDPLL:
671 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_PDPLL); // reads selected field
672 field_val=field_menu_RW(field_val,"PDPLL",LTC6950_PDPLL); // user interface control and printout
673 if (field_val>-1)
674 {
675 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_PDPLL, field_val); // updates selected field
676 }
677 break;
678
679 case LTC6950_PDREFAC:
680 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_PDREFAC); // reads selected field
681 field_val=field_menu_RW(field_val,"PDREFAC",LTC6950_PDREFAC); // user interface control and printout
682 if (field_val>-1)
683 {
684 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_PDREFAC, field_val); // updates selected field
685 }
686 break;
687
688 case LTC6950_PDVCOAC:
689 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_PDVCOAC); // reads selected field
690 field_val=field_menu_RW(field_val,"PDVCOAC",LTC6950_PDVCOAC); // user interface control and printout
691 if (field_val>-1)
692 {
693 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_PDVCOAC, field_val); // updates selected field
694 }
695 break;
696
697 case LTC6950_R:
698 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_R); // reads selected field
699 field_val=field_menu_RW(field_val,"R",LTC6950_R); // user interface control and printout
700 if (field_val>-1)
701 {
702 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_R, field_val); // updates selected field
703 }
704 break;
705
706 case LTC6950_RDIVOUT:
707 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_RDIVOUT); // reads selected field
708 field_val=field_menu_RW(field_val,"RDIVOUT",LTC6950_RDIVOUT); // user interface control and printout
709 if (field_val>-1)
710 {
711 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_RDIVOUT, field_val); // updates selected field
712 }
713 break;
714
715 case LTC6950_RES6950:
716 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_RES6950); // reads selected field
717 field_val=field_menu_RW(field_val,"RES6950",LTC6950_RES6950); // user interface control and printout
718 if (field_val>-1)
719 {
720 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_RES6950, field_val); // updates selected field
721 }
722 break;
723
724 case LTC6950_RESET_R:
725 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_RESET_R); // reads selected field
726 field_val=field_menu_RW(field_val,"RESET_R",LTC6950_RESET_R); // user interface control and printout
727 if (field_val>-1)
728 {
729 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_RESET_R, field_val); // updates selected field
730 }
731 break;
732
733 case LTC6950_RESET_N:
734 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_RESET_N); // reads selected field
735 field_val=field_menu_RW(field_val,"RESET_N",LTC6950_RESET_N); // user interface control and printout
736 if (field_val>-1)
737 {
738 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_RESET_N, field_val); // updates selected field
739 }
740 break;
741
742 case LTC6950_REV:
743 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_REV); // reads selected field
744 field_val=field_menu_RW(field_val,"REV",LTC6950_REV); // user interface control and printout
745 if (field_val>-1)
746 {
747 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_REV, field_val); // updates selected field
748 }
749 break;
750
751 case LTC6950_SM1:
752 // SM2 programmed same as SM1 above, just change SM1 to SM2
753 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_SM1); // reads selected field
754 field_val=field_menu_RW(field_val,"SM1",LTC6950_SM1); // user interface control and printout
755 if (field_val>-1)
756 {
757 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_SM1, field_val); // updates selected field
758 }
759 break;
760
761 case LTC6950_SYNCMD:
762 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_SYNCMD); // reads selected field
763 field_val=field_menu_RW(field_val,"SYNCMD",LTC6950_SYNCMD); // user interface control and printout
764 if (field_val>-1)
765 {
766 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_SYNCMD, field_val); // updates selected field
767 }
768 break;
769
770 case LTC6950_SYNC_EN0:
771 // SYNC_EN1-4 programmed same as SYNC_EN0 above, just change SYNC_EN0 to SYNC_ENx
772 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_SYNC_EN0); // reads selected field
773 field_val=field_menu_RW(field_val,"SYNC_EN0",LTC6950_SYNC_EN0); // user interface control and printout
774 if (field_val>-1)
775 {
776 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_SYNC_EN0, field_val); // updates selected field
777 }
778 break;
779
780 case LTC6950_THI:
781 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_THI); // reads selected field
782 field_val=field_menu_RW(field_val,"THI",LTC6950_THI); // user interface control and printout
783 if (field_val>-1)
784 {
785 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_THI, field_val); // updates selected field
786 }
787 break;
788
789 case LTC6950_TLO:
790 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_TLO); // reads selected field
791 field_val=field_menu_RW(field_val,"TLO",LTC6950_TLO); // user interface control and printout
792 if (field_val>-1)
793 {
794 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_TLO, field_val); // updates selected field
795 }
796 break;
797
798 case LTC6950_UNLOCK:
799 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,LTC6950_UNLOCK); // reads selected field
800 field_val=field_menu_RW(field_val,"UNLOCK",LTC6950_UNLOCK); // user interface control and printout
801 if (field_val>-1)
802 {
803 set_LTC6950_SPI_FIELD(LTC6950_CS, LTC6950_UNLOCK, field_val); // updates selected field
804 }
805 break;
806
807 default:
808 field_val=get_LTC6950_SPI_FIELD(LTC6950_CS,field_num); // reads selected field
809 field_val=field_menu_RW(field_val," ",field_num); // user interface control and printout
810 if (field_val>-1)
811 {
812 set_LTC6950_SPI_FIELD(LTC6950_CS, field_num, field_val); // updates selected field
813 }
814 break;
815 } // end of switch statement
816 } // end if user_command != 0 statement
817 } // end while loop
818 } // end menu_3_RW_to_reg_field function
819
820
821 /* ------------------------------------------------------------------------- */
822 //! verifies VCO frequency is within datasheet specifications
823 void LTC6950_VCO_Freq_Verification()
824 {
825 unsigned long temp_val, temp_max_VCO_MHz, temp_min_VCO_MHz, temp_max_VCO_Hz, temp_min_VCO_Hz;
826 unsigned long fvco_max[2], fvco_min[2], fvco_max_lim[2], fvco_min_lim[2];
827 boolean valid_input=false;
828
829 // USER INPUT
830 valid_input=false;
831
832
833 while (valid_input==false)
834 {
835 temp_max_VCO_MHz=get_LTC6950_global_VCO_MAX_MHz();
836 temp_min_VCO_MHz=get_LTC6950_global_VCO_MIN_MHz();
837 temp_max_VCO_Hz=get_LTC6950_global_VCO_MAX_Hz();
838 temp_min_VCO_Hz=get_LTC6950_global_VCO_MIN_Hz();
839
840 Serial.print(F("What is the upper frequency limit of the VCO (MHZ portion)? ["));
841 Serial.print(temp_max_VCO_MHz);
842 Serial.print(F("]: "));
843 temp_val = read_float(); //! Reads the user command
844 // if user selects enter, keep same Fref. Otherwise set Fref and verify
845 if (temp_val!=0) temp_max_VCO_MHz = abs(temp_val);
846 Serial.println(temp_max_VCO_MHz);
847
848 Serial.print(F("What is the upper VCO frequency limit (HZ portion)? "));
849 temp_max_VCO_Hz = read_float(); //! Reads the user command
850 // if user selects enter, keep same Fref. Otherwise set Fref and verify
851 Serial.println(temp_max_VCO_Hz);
852
853 Serial.print(F("\nWhat is the lower frequency limit of the VCO (MHZ portion)? ["));
854 Serial.print(temp_min_VCO_MHz);
855 Serial.print(F("]: "));
856 temp_val = read_float(); //! Reads the user command
857 // if user selects enter, keep same Fref. Otherwise set Fref and verify
858 if (temp_val!=0) temp_min_VCO_MHz = abs(temp_val);
859 Serial.println(temp_min_VCO_MHz);
860
861 Serial.print(F("What is the lower frequency limit of the VCO (HZ portion)? "));
862 temp_min_VCO_Hz = read_float(); //! Reads the user command
863 Serial.println(temp_min_VCO_Hz);
864
865 HZto64(fvco_max,temp_max_VCO_MHz,temp_max_VCO_Hz); // convert to 64 bit integer
866 HZto64(fvco_min,temp_min_VCO_MHz,temp_min_VCO_Hz); // convert to 64 bit integer
867 HZto64(fvco_max_lim,LTC6950_MAXFREQ,0); // convert to 64 bit integer
868 HZto64(fvco_min_lim,LTC6950_MINFREQ,0); // convert to 64 bit integer
869
870
871 // if valid input print the following to the screen
872 if (lt64(fvco_min_lim,fvco_min) && lt64(fvco_max,fvco_max_lim) &&
873 lt64(fvco_min_lim,fvco_max) && lt64(fvco_min,fvco_max_lim) &&
874 (eq64(fvco_min, fvco_max) || lt64(fvco_min, fvco_max)) )
875 {
876 set_LTC6950_global_vcolim(temp_max_VCO_MHz, temp_max_VCO_Hz, temp_min_VCO_MHz, temp_min_VCO_Hz);
877 Serial.print(F("VCO Frequencies entered are valid\n"));
878 valid_input=true;
879 }
880 else
881 {
882 Serial.print(F("VCO Frequencies must be less than 1400MHz\n"));
883 } // end of if-else
884 } // end of while
885 } // end of LTC6950_VCO_Freq_Verification
886
887
888 /* ------------------------------------------------------------------------- */
889 //! verifies reference frequency is within datasheet specifications
890 void LTC6950_Ref_Freq_Verification()
891 {
892 unsigned long temp_val, temp_fref_MHz, temp_fref_Hz;
893 boolean valid_input=false;
894
895 // USER INPUT
896 valid_input=false;
897
898
899 while (valid_input==false)
900 {
901 temp_fref_MHz=get_LTC6950_global_fref_MHz();
902 temp_fref_Hz=get_LTC6950_global_fref_Hz();
903 Serial.print(F("\nWhat is the MHz portion of the Reference Input Frequency(MHZ)? ["));
904 Serial.print(temp_fref_MHz);
905 Serial.print(F("]: "));
906 temp_val = read_float(); //! Reads the user command
907 // if user selects enter, keep same Fref. Otherwise set Fref and verify
908 if (temp_val!=0) temp_fref_MHz = abs(temp_val);
909 Serial.println(temp_fref_MHz);
910
911 Serial.print(F("What is the sub-MHz portion of the Reference Input Frequency(HZ)? "));
912 temp_val = read_float(); //! Reads the user command
913 temp_fref_Hz = abs(temp_val);
914 Serial.println(temp_fref_Hz);
915
916 // if valid input print the following to the screen
917 if (temp_fref_MHz >=LTC6950_MIN_REF_FREQ & temp_fref_MHz <= LTC6950_MAX_REF_FREQ)
918 {
919 set_LTC6950_global_fref(temp_fref_MHz,temp_fref_Hz);
920 temp_val= temp_fref_MHz*OneMHz + temp_fref_Hz;
921 Serial.print(F("Reference Frequency set to "));
922 Serial.print(temp_val);
923 Serial.println(F("Hz"));
924 valid_input=true;
925 }
926 else
927 {
928 Serial.print(F("Reference Frequency must be between 2MHz and 250MHz\n"));
929 } // end of if-else
930 } // end of while
931 } // end of LTC6950_Ref_Freq_Verification
932
933
934 /* -------------------------------------------------------------------------
935 FUNCTION: LTC6950_Fout_Freq_Verification
936 //! verifies frf frequency is within datasheet specifications
937 ---------------------------------------------------------------------------- */
938 void LTC6950_Fout_Freq_Verification()
939 {
940 unsigned long odiv, temp_fout_MHz, temp_fout_Hz, temp_val;
941 unsigned long frf[2];
942 boolean valid_input=false;
943
944 // USER INPUT
945 temp_fout_MHz=get_LTC6950_global_frf_MHz();
946 temp_fout_Hz=get_LTC6950_global_frf_Hz();
947
948 while (valid_input==false)
949 {
950 Serial.print(F("\nWhat is the MHz portion of the Output Frequency(MHZ)? ["));
951 Serial.print(temp_fout_MHz);
952 Serial.print(F("]: "));
953 temp_val = read_int(); //! Reads the user command
954 // if user selects enter, keep same Fout. Otherwise set Fout and verify
955 if (temp_val!=0) temp_fout_MHz = abs(temp_val);
956 Serial.println(temp_fout_MHz);
957
958 Serial.print(F("What is the Hz portion of the Output Frequency(HZ)? "));
959 temp_val = read_int(); //! Reads the user command
960 temp_fout_Hz = abs(temp_val);
961 Serial.println(temp_fout_Hz);
962
963 HZto64(frf,temp_fout_MHz,temp_fout_Hz); // convert to 64 bit integer
964
965 // verify desired frequency falls within a divider range (1-6)
966 odiv = LTC6950_calc_odiv(frf);
967 valid_input=false;
968 if ((odiv>=1) && (odiv<=63)) valid_input=true;
969
970 // if valid input print the following to the screen
971 if (valid_input==true)
972 {
973 set_LTC6950_global_frf(temp_fout_MHz,temp_fout_Hz);
974 if (temp_fout_MHz < 4294)
975 {
976 temp_val= temp_fout_MHz*OneMHz + temp_fout_Hz;
977 Serial.print(F("Desired Output Frequency is "));
978 Serial.print(temp_val);
979 Serial.println(F("Hz"));
980 }
981 else // over flow condition
982 {
983 Serial.print(F("Desired Output Frequency is "));
984 Serial.print(temp_fout_MHz);
985 Serial.print(F("MHz + "));
986 Serial.print(temp_fout_Hz);
987 Serial.println(F("Hz"));
988 }
989 }
990 // if invalid input print the following to the screen
991 else
992 {
993 Serial.println(F("Invalid Fout frequency chosen"));
994 } // end of if/else (valid_input==true)
995 } // end of while(valid_input=false)
996 } // end of Fout_Freq_Verification
997
998
999 /* ------------------------------------------------------------------------- */
1000 //! Menu 4: Calculates and programs OD, ND, NUM based on desired Frf
1001 //! This function calculates and programs OD, ND, NUM based on desired Frf,
1002 //! the reference frequency, and current RD value.
1003 //! Linduino One (Arduino Uno) are limited to 32 bit floats, int and doubles.
1004 //! Significant rounding errors are created with this 32 bit limitation. Therefore,
1005 //! This function uses 64bit math functions specifically created to overcome this limitation.
1006 //! If RD needs to change see menu 2 or menu 3
1007 //! @return void
1008 void menu_4_set_frf()
1009 {
1010 Serial.print(F("\nThis function calculates and programs OD and ND\n"));
1011 Serial.print(F("based on the value input for Fvco, Frf and Fref.\n"));
1012 Serial.print(F("It assumes all other register settings are correct\n"));
1013 Serial.print(F("The ClockWizard tool can verify the correctness of the other register settings.\n"));
1014
1015
1016 Serial.print(F("\nThe following frequencies will be entered with 2 integers\n"));
1017 Serial.print(F("1st number is the MHZ portion, the 2nd number is Hz portion\n"));
1018 Serial.print(F(" - Example: A. 100\n"));
1019 Serial.print(F(" B. 25\n"));
1020 Serial.print(F(" equates to 100.000025MHZ\n\n"));
1021 LTC6950_VCO_Freq_Verification();
1022 LTC6950_Ref_Freq_Verification();
1023 LTC6950_Fout_Freq_Verification();
1024 LTC6950_set_frf();
1025 }
1026
1027 /* ------------------------------------------------------------------------- */
1028 //! Store PLL settings to nonvolatile EEPROM on demo board
1029 //! @return void
1030 void menu_5_store_settings()
1031 {
1032 // Store the PLL Settings to the EEPROM
1033 uint8_t regval;
1034
1035 uint8_t addr_offset;
1036 uint8_t num_reg;
1037
1038 addr_offset=2;
1039 num_reg = get_LTC6950_REGSIZE();
1040
1041 eeprom_write_int16(EEPROM_I2C_ADDRESS, EEPROM_CAL_KEY, EEPROM_CAL_STATUS_ADDRESS); // Cal key
1042
1043 for (uint8_t i = 0; i <= num_reg ; i++)
1044 {
1045 regval = LTC6950_read(LTC6950_CS,i);
1046 eeprom_write_byte(EEPROM_I2C_ADDRESS,(char) regval, EEPROM_CAL_STATUS_ADDRESS+ i+addr_offset);
1047 }
1048 Serial.println(F("PLL Settings Stored to EEPROM"));
1049
1050 }
1051
1052
1053 /* ------------------------------------------------------------------------- */
1054 //! Read stored PLL settings from nonvolatile EEPROM on demo board
1055 //! @return void
1056 void menu_6_restore_settings()
1057 {
1058 // Read the PLL settings from EEPROM
1059 int16_t cal_key;
1060 uint8_t regval;
1061 uint8_t user_address;
1062
1063 uint8_t addr_offset;
1064 uint8_t num_reg;
1065
1066 addr_offset=2;
1067 num_reg = get_LTC6950_REGSIZE();
1068
1069 // read the cal key from the EEPROM
1070 eeprom_read_int16(EEPROM_I2C_ADDRESS, &cal_key, EEPROM_CAL_STATUS_ADDRESS);
1071 if (cal_key == EEPROM_CAL_KEY)
1072 {
1073 // PLL Settings has been stored, read PLL Settings
1074 user_address=2;
1075 for (uint8_t i = 0; i <= num_reg ; i++)
1076 {
1077 eeprom_read_byte(EEPROM_I2C_ADDRESS,(char *) &regval, EEPROM_CAL_STATUS_ADDRESS + i+addr_offset);
1078 LTC6950_write(LTC6950_CS, (uint8_t)i, regval);
1079 user_address++;
1080 }
1081 Serial.println(F("PLL Settings Restored"));
1082 }
1083 else
1084 {
1085 Serial.println(F("PLL Settings not found"));
1086 }
1087
1088 }
1089
1090
1091 /* ------------------------------------------------------------------------- */
1092 //! Prints the title block when program first starts.
1093 void print_title()
1094 {
1095
1096 Serial.println(F("*****************************************************************"));
1097 Serial.println(F("* DC1795 Demonstration Program *"));
1098 Serial.println(F("* *"));
1099 Serial.println(F("* This program demonstrates how to send data to the LTC6950 *"));
1100 Serial.println(F("* 1.4GHz Low Phase Noise, Low Jitter PLL with Clock *"));
1101 Serial.println(F("* Distribution. *"));
1102 Serial.println(F("* *"));
1103 Serial.println(F("* Set the baud rate to 115200 and select the newline terminator.*"));
1104 Serial.println(F("* *"));
1105 Serial.println(F("* For loop filter design please use the Clock Wizard software. *"));
1106 Serial.println(F("* - It is recommended to use ClockWizard to determine the *"));
1107 Serial.println(F("* correct SPI register values for the initial setup. These *"));
1108 Serial.println(F("* values can be entered into this program via menu option 2 *"));
1109 Serial.println(F("* below. These values can then be stored and recalled from the *"));
1110 Serial.println(F("* DC1795 EEPROM using options 5 and 6 below. *"));
1111 Serial.println(F("*****************************************************************"));
1112 Serial.println();
1113 } // end of print_title
1114
1115
1116 /* ------------------------------------------------------------------------- */
1117 //! Prints main menu.
1118 void print_prompt()
1119 {
1120
1121 Serial.println(F("\nCommand Summary:"));
1122 Serial.println(F(" 1-Load Default Settings (same as the Clock Wizard's LTC6950_ALL_CHAN_250MHz.clkset settings)"));
1123 Serial.println(F(" 2-READ/WRITE to Registers Addresses"));
1124 Serial.println(F(" 3-READ/WRITE to Registers Fields"));
1125 Serial.println(F(" 4-Set Output Frequency - OUT0"));
1126 Serial.println(F(" 5-Store LTC6950 SPI settings to the DC1795's EEPROM"));
1127 Serial.println(F(" 6-Restore LTC6950 SPI settings from the DC1795's EEPROM"));
1128 Serial.println("");
1129 Serial.print(F("Enter a command: "));
1130 } // end of print_prompt
1131
1132
LTC6950_RES6950
#define LTC6950_RES6950
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:139
demo_board
struct demo_board_type demo_board
Instantiate demo board structure.
Definition: QuikEval_EEPROM.cpp:71
lt64
boolean lt64(unsigned long an[], unsigned long ann[])
64 bit, if an < ann, then true
Definition: LTC6945.cpp:848
LTC6950_CPWIDE
#define LTC6950_CPWIDE
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:90
get_LTC6950_global_frf_MHz
unsigned long get_LTC6950_global_frf_MHz()
returns global LTC6950_Frf_MHz
Definition: LTC6950.cpp:651
get_LTC6950_SPI_FIELD_NUMBITS
uint8_t get_LTC6950_SPI_FIELD_NUMBITS(uint8_t f)
returns the number of bits for a given field name in the SPI map
Definition: LTC6950.cpp:249
LTC6950_N
#define LTC6950_N
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:119
LTC6950_NO_REF
#define LTC6950_NO_REF
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:120
eeprom_read_int16
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.
Definition: QuikEval_EEPROM.cpp:395
menu_6_restore_settings
static void menu_6_restore_settings()
Read stored PLL settings from nonvolatile EEPROM on demo board.
Definition: DC1795A.ino:1056
user_command
unsigned char user_command
Definition: Serial_EEPROM_Test.ino:75
EEPROM_I2C_ADDRESS
#define EEPROM_I2C_ADDRESS
Definition: QuikEval_EEPROM.h:60
LTC6950_RESET_N
#define LTC6950_RESET_N
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:141
eeprom_write_byte
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.
Definition: QuikEval_EEPROM.cpp:214
demo_board_type::name
char name[15]
Demo Circuit number (DC1678)
Definition: QuikEval_EEPROM.h:71
LTC6950_RESET_R
#define LTC6950_RESET_R
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:140
LTC6950_CS
#define LTC6950_CS
Define the SPI CS pin.
Definition: LTC6950.h:76
LTC6950_LKCT
#define LTC6950_LKCT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:109
field_menu_RW
long field_menu_RW(long field_val, char field_name[], uint8_t f)
Support function for function menu_3_RW_to_reg_field displays current state of select field provides ...
Definition: DC1795A.ino:292
LTC6950_calc_odiv
unsigned long LTC6950_calc_odiv(unsigned long frf[2])
calculates the output divider setting based on the frf and on board VCO frequencies of LTC6950 ...
Definition: LTC6950.cpp:687
menu_1_load_default_settings
static void menu_1_load_default_settings()
Menu 1: Load Default SPI Register Settings This function loads the register settings referenced in th...
Definition: DC1795A.ino:215
LTC6950_CPCLO
#define LTC6950_CPCLO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:84
LTC6950_SYNC_EN0
#define LTC6950_SYNC_EN0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:146
Linduino.h
Header File for Linduino Libraries and Demo Code.
LTC6950_PDALL
#define LTC6950_PDALL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:123
LTC6950_set_frf
void LTC6950_set_frf()
FUNCTION: LTC6950_set_frf Calculates the integer (N) and output divider (OD) SPI values using self cr...
Definition: LTC6950.cpp:766
LTC6950_SYNCMD
#define LTC6950_SYNCMD
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:145
LTC6950_CPCHI
#define LTC6950_CPCHI
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:83
LTC6950_PDREFAC
#define LTC6950_PDREFAC
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:135
set_LTC6950_global_frf
void set_LTC6950_global_frf(unsigned long frf_MHz, unsigned long frf_Hz)
sets globals LTC6950_Frf_MHz and LTC6950_Frf_Hz
Definition: LTC6950.cpp:625
OneMHz
#define OneMHz
1MHz in long format, used in 64 bit math
Definition: LTC6945.h:121
eq64
boolean eq64(unsigned long an[], unsigned long ann[])
64 bit, if an == ann, then true
Definition: LTC6945.cpp:838
LTC6950_TLO
#define LTC6950_TLO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:152
LTC6950_FILTV
#define LTC6950_FILTV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:97
LTC6950_PDPLL
#define LTC6950_PDPLL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:134
LTC6950_PDVCOAC
#define LTC6950_PDVCOAC
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:136
LTC6950_R
#define LTC6950_R
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:137
menu_5_store_settings
static void menu_5_store_settings()
Store PLL settings to nonvolatile EEPROM on demo board.
Definition: DC1795A.ino:1030
ref_out
static uint8_t ref_out
Used to keep track of reference out status.
Definition: DC1795A.ino:119
get_LTC6950_global_frf_Hz
unsigned long get_LTC6950_global_frf_Hz()
returns global LTC6950_Frf_Hz
Definition: LTC6950.cpp:656
HZto64
void HZto64(unsigned long an[], unsigned long MHzPart, unsigned long HzPart)
create a 64 bit Hz number from 32 bit xxxx MHz number and 32 bit yyy yyy Hz number.
Definition: LTC6945.cpp:729
LTC6950_LKEN
#define LTC6950_LKEN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:110
LTC6950_LKWIN
#define LTC6950_LKWIN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:111
demo_board_connected
static int8_t demo_board_connected
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1795A.ino:120
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
LTC6950_UNLOCK
#define LTC6950_UNLOCK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:153
LTC6950_MAXFREQ
#define LTC6950_MAXFREQ
LTC6950 upper freq limit.
Definition: LTC6950.h:167
LTC6950_DEL0
#define LTC6950_DEL0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:91
LTC6950_CPUP
#define LTC6950_CPUP
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:89
menu_4_set_frf
static void menu_4_set_frf()
Menu 4: Calculates and programs OD, ND, NUM based on desired Frf This function calculates and program...
Definition: DC1795A.ino:1008
get_LTC6950_SPI_FIELD
long get_LTC6950_SPI_FIELD(uint8_t cs, uint8_t f)
Gets the LTC6950 SPI field value calls function LTC6950_read_field, which reads specific address loca...
Definition: LTC6950.cpp:161
eeprom_write_int16
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.
Definition: QuikEval_EEPROM.cpp:377
LTC6950.h
LTC6950: 1.4GHz Low Phase Noise, Low Jitter PLL with Clock Distribution.
set_LTC6950_ALLREGS
void set_LTC6950_ALLREGS(uint8_t cs, uint8_t reg01, uint8_t reg02, uint8_t reg03, uint8_t reg04, uint8_t reg05, uint8_t reg06, uint8_t reg07, uint8_t reg08, uint8_t reg09, uint8_t reg0A, uint8_t reg0B, uint8_t reg0C, uint8_t reg0D, uint8_t reg0E, uint8_t reg0F, uint8_t reg10, uint8_t reg11, uint8_t reg12, uint8_t reg13, uint8_t reg14, uint8_t reg15)
Writes values to ALL LTC6950 RW addresses.
Definition: LTC6950.cpp:282
set_LTC6950_global_fref
void set_LTC6950_global_fref(unsigned long fref_MHz, unsigned long fref_Hz)
sets globals LTC6950_Fref_MHz and LTC6950_Fref_Hz
Definition: LTC6950.cpp:619
eeprom_read_byte
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.
Definition: QuikEval_EEPROM.cpp:282
QuikEval_EEPROM.h
QuikEval EEPROM Library.
LTC6950_M0
#define LTC6950_M0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:114
menu_3_RW_to_reg_field
static void menu_3_RW_to_reg_field()
Menu 3: Reads and/or Writes individual SPI fields This function provides the user with a list of all ...
Definition: DC1795A.ino:353
setup
static void setup()
Initialize Linduino.
Definition: DC1795A.ino:127
quikeval_SPI_init
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
get_LTC6950_global_VCO_MAX_MHz
unsigned long get_LTC6950_global_VCO_MAX_MHz()
returns global LTC6950_VCO_Max_Freq_MHz
Definition: LTC6950.cpp:661
EEPROM_CAL_STATUS_ADDRESS
#define EEPROM_CAL_STATUS_ADDRESS
Definition: QuikEval_EEPROM.h:58
discover_demo_board
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
Definition: QuikEval_EEPROM.cpp:141
loop
static void loop()
Repeats Linduino loop.
Definition: DC1795A.ino:154
get_LTC6950_global_VCO_MIN_MHz
unsigned long get_LTC6950_global_VCO_MIN_MHz()
returns global LTC6950_VCO_Min_Freq_MHz
Definition: LTC6950.cpp:666
LTC6950_FLDRV0
#define LTC6950_FLDRV0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:98
LTC6950_REV
#define LTC6950_REV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:142
LTC6950_CPMID
#define LTC6950_CPMID
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:87
LTC6950_write
void LTC6950_write(uint8_t cs, uint8_t address, uint8_t Data)
LTC6950 Write Single Address writes 8 bit Data field to LTC6950.
Definition: LTC6950.cpp:172
LT_SPI.h
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
get_LTC6950_SPI_FIELD_RW
uint8_t get_LTC6950_SPI_FIELD_RW(uint8_t f)
returns if the given field name is (0)read/write or (1)read_only field
Definition: LTC6950.cpp:259
LTC6950_MAX_REF_FREQ
#define LTC6950_MAX_REF_FREQ
LTC6950 upper reference frequency limit.
Definition: LTC6950.h:170
print_title
static void print_title()
Prints the title block when program first starts.
Definition: DC1795A.ino:1093
LTC6950_Fout_Freq_Verification
static void LTC6950_Fout_Freq_Verification()
Definition: DC1795A.ino:938
LTC6950_RDIVOUT
#define LTC6950_RDIVOUT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:138
LTC6950_read
uint8_t LTC6950_read(uint8_t cs, int8_t address)
LTC6950 Read Single Address reads 8 bit Data field to LTC6950.
Definition: LTC6950.cpp:105
LT_I2C.h
LT_I2C: Routines to communicate with ATmega328P&#39;s hardware I2C port.
LTC6950_IBIAS0
#define LTC6950_IBIAS0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:103
LTC6950_MIN_REF_FREQ
#define LTC6950_MIN_REF_FREQ
LTC6950 lower reference frequency limit.
Definition: LTC6950.h:169
get_LTC6950_global_fref_MHz
unsigned long get_LTC6950_global_fref_MHz()
returns global LTC6950_Fref_MHz
Definition: LTC6950.cpp:641
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
set_LTC6950_global_vcolim
void set_LTC6950_global_vcolim(unsigned long fvco_max_MHz, unsigned long fvco_max_Hz, unsigned long fvco_min_MHz, unsigned long fvco_min_Hz)
sets globals LTC6950_VCO_Max_Freq_MHz, LTC6950_VCO_Max_Freq_Hz, LTC6950_VCO_Min_Freq_MHz and LTC6950_...
Definition: LTC6950.cpp:631
set_LTC6950_SPI_FIELD
void set_LTC6950_SPI_FIELD(uint8_t cs, uint8_t f, long field_data)
Sets the LTC6950 SPI field value calls function LTC6950_read_field, which reads specific address/fiel...
Definition: LTC6950.cpp:272
LTC6950_init
void LTC6950_init()
Initializes the SPI MAP arrays The values set in initialization are used for all the LTC6950 SPI/WRIT...
Definition: LTC6950.cpp:319
LTC6950_CPRST
#define LTC6950_CPRST
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:88
LTC6950_PART
#define LTC6950_PART
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:122
LTC6950_MINFREQ
#define LTC6950_MINFREQ
LTC6950 lower freq limit.
Definition: LTC6950.h:166
read_float
float read_float()
Definition: UserInterface.cpp:78
LTC6950_INV_ST1
#define LTC6950_INV_ST1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:107
get_LTC6950_global_VCO_MIN_Hz
unsigned long get_LTC6950_global_VCO_MIN_Hz()
returns global LTC6950_VCO_Min_Freq_Hz
Definition: LTC6950.cpp:676
LTC6950_NO_VCO
#define LTC6950_NO_VCO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:121
get_LTC6950_global_fref_Hz
unsigned long get_LTC6950_global_fref_Hz()
returns global LTC6950_Fref_Hz
Definition: LTC6950.cpp:646
LTC6950_CPDN
#define LTC6950_CPDN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:85
menu_2_RW_to_reg_addresss
static void menu_2_RW_to_reg_addresss()
Menu 2: Reads and/or Writes the SPI register address This function reads and displays all SPI registe...
Definition: DC1795A.ino:237
get_LTC6950_REGSIZE
uint8_t get_LTC6950_REGSIZE()
returns # of addresses in parts register map (array size)
Definition: LTC6950.cpp:239
get_LTC6950_global_VCO_MAX_Hz
unsigned long get_LTC6950_global_VCO_MAX_Hz()
returns global LTC6950_VCO_Max_Freq_Hz
Definition: LTC6950.cpp:671
First_Run
static uint8_t First_Run
if first time through loop = 0, otherwise=1
Definition: DC1795A.ino:121
LTC6950_LOCK
#define LTC6950_LOCK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:112
quikeval_I2C_init
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
LTC6950_SM1
#define LTC6950_SM1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:143
LTC6950_PD_OUT0
#define LTC6950_PD_OUT0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:129
i
static int i
Definition: DC2430A.ino:184
LTC6950_CP
#define LTC6950_CP
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:82
print_prompt
static void print_prompt()
Prints main menu.
Definition: DC1795A.ino:1118
LTC6950_Ref_Freq_Verification
static void LTC6950_Ref_Freq_Verification()
verifies reference frequency is within datasheet specifications
Definition: DC1795A.ino:890
LTC6950_VCO_Freq_Verification
static void LTC6950_VCO_Freq_Verification()
verifies VCO frequency is within datasheet specifications
Definition: DC1795A.ino:823
LTC6950_CMSINV
#define LTC6950_CMSINV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:81
LTC6950_PD_DIV0
#define LTC6950_PD_DIV0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:124
LTC6950_LVCMS
#define LTC6950_LVCMS
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:113
EEPROM_CAL_KEY
#define EEPROM_CAL_KEY
Definition: QuikEval_EEPROM.h:59
LTC6950_THI
#define LTC6950_THI
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:151
LTC6950_CPINV
#define LTC6950_CPINV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:86
LTC6950_FILTR
#define LTC6950_FILTR
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:96