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
114 void menu_4_set_frf();
115 void menu_5_store_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 
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:
173  break;
174 
175  case 2:
177  break;
178 
179  case 3:
181  break;
182 
183  case 4:
184  menu_4_set_frf();
185  break;
186 
187  case 5:
189  break;
190 
191  case 6:
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
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
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
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
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
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 ---------------------------------------------------------------------------- */
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
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"));
1024  LTC6950_set_frf();
1025 }
1026 
1027 /* ------------------------------------------------------------------------- */
1028 //! Store PLL settings to nonvolatile EEPROM on demo board
1029 //! @return void
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 
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
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
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.
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.
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 
#define LTC6950_RES6950
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:139
struct demo_board_type demo_board
Instantiate demo board structure.
boolean lt64(unsigned long an[], unsigned long ann[])
64 bit, if an < ann, then true
Definition: LTC6945.cpp:848
#define LTC6950_CPWIDE
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:90
unsigned long get_LTC6950_global_frf_MHz()
returns global LTC6950_Frf_MHz
Definition: LTC6950.cpp:651
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
#define LTC6950_N
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:119
#define LTC6950_NO_REF
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:120
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.
static void menu_6_restore_settings()
Read stored PLL settings from nonvolatile EEPROM on demo board.
Definition: DC1795A.ino:1056
unsigned char user_command
#define EEPROM_I2C_ADDRESS
#define LTC6950_RESET_N
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:141
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.
char name[15]
Demo Circuit number (DC1678)
#define LTC6950_RESET_R
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:140
#define LTC6950_CS
Define the SPI CS pin.
Definition: LTC6950.h:76
#define LTC6950_LKCT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:109
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
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
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
#define LTC6950_CPCLO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:84
#define LTC6950_SYNC_EN0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:146
Header File for Linduino Libraries and Demo Code.
#define LTC6950_PDALL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:123
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
#define LTC6950_SYNCMD
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:145
#define LTC6950_CPCHI
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:83
#define LTC6950_PDREFAC
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:135
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
#define OneMHz
1MHz in long format, used in 64 bit math
Definition: LTC6945.h:121
boolean eq64(unsigned long an[], unsigned long ann[])
64 bit, if an == ann, then true
Definition: LTC6945.cpp:838
#define LTC6950_TLO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:152
#define LTC6950_FILTV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:97
#define LTC6950_PDPLL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:134
#define LTC6950_PDVCOAC
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:136
#define LTC6950_R
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:137
static void menu_5_store_settings()
Store PLL settings to nonvolatile EEPROM on demo board.
Definition: DC1795A.ino:1030
static uint8_t ref_out
Used to keep track of reference out status.
Definition: DC1795A.ino:119
unsigned long get_LTC6950_global_frf_Hz()
returns global LTC6950_Frf_Hz
Definition: LTC6950.cpp:656
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
#define LTC6950_LKEN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:110
#define LTC6950_LKWIN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:111
static int8_t demo_board_connected
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1795A.ino:120
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
#define LTC6950_UNLOCK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:153
#define LTC6950_MAXFREQ
LTC6950 upper freq limit.
Definition: LTC6950.h:167
#define LTC6950_DEL0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:91
#define LTC6950_CPUP
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:89
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
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
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.
LTC6950: 1.4GHz Low Phase Noise, Low Jitter PLL with Clock Distribution.
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
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
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.
QuikEval EEPROM Library.
#define LTC6950_M0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:114
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
static void setup()
Initialize Linduino.
Definition: DC1795A.ino:127
void quikeval_SPI_init(void)
Configure the SPI port for 4Mhz SCK.
Definition: LT_SPI.cpp:151
unsigned long get_LTC6950_global_VCO_MAX_MHz()
returns global LTC6950_VCO_Max_Freq_MHz
Definition: LTC6950.cpp:661
#define EEPROM_CAL_STATUS_ADDRESS
int8_t discover_demo_board(char *demo_name)
Read the ID string from the EEPROM and determine if the correct board is connected.
static void loop()
Repeats Linduino loop.
Definition: DC1795A.ino:154
unsigned long get_LTC6950_global_VCO_MIN_MHz()
returns global LTC6950_VCO_Min_Freq_MHz
Definition: LTC6950.cpp:666
#define LTC6950_FLDRV0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:98
#define LTC6950_REV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:142
#define LTC6950_CPMID
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:87
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: Routines to communicate with ATmega328P&#39;s hardware SPI port.
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
#define LTC6950_MAX_REF_FREQ
LTC6950 upper reference frequency limit.
Definition: LTC6950.h:170
static void print_title()
Prints the title block when program first starts.
Definition: DC1795A.ino:1093
static void LTC6950_Fout_Freq_Verification()
Definition: DC1795A.ino:938
#define LTC6950_RDIVOUT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:138
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: Routines to communicate with ATmega328P&#39;s hardware I2C port.
#define LTC6950_IBIAS0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:103
#define LTC6950_MIN_REF_FREQ
LTC6950 lower reference frequency limit.
Definition: LTC6950.h:169
unsigned long get_LTC6950_global_fref_MHz()
returns global LTC6950_Fref_MHz
Definition: LTC6950.cpp:641
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
Definition: LT_SPI.cpp:138
int32_t read_int()
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
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
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
#define LTC6950_CPRST
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:88
#define LTC6950_PART
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:122
#define LTC6950_MINFREQ
LTC6950 lower freq limit.
Definition: LTC6950.h:166
float read_float()
#define LTC6950_INV_ST1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:107
unsigned long get_LTC6950_global_VCO_MIN_Hz()
returns global LTC6950_VCO_Min_Freq_Hz
Definition: LTC6950.cpp:676
#define LTC6950_NO_VCO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:121
unsigned long get_LTC6950_global_fref_Hz()
returns global LTC6950_Fref_Hz
Definition: LTC6950.cpp:646
#define LTC6950_CPDN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:85
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
uint8_t get_LTC6950_REGSIZE()
returns # of addresses in parts register map (array size)
Definition: LTC6950.cpp:239
unsigned long get_LTC6950_global_VCO_MAX_Hz()
returns global LTC6950_VCO_Max_Freq_Hz
Definition: LTC6950.cpp:671
static uint8_t First_Run
if first time through loop = 0, otherwise=1
Definition: DC1795A.ino:121
#define LTC6950_LOCK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:112
void quikeval_I2C_init(void)
Initializes Linduino I2C port.
Definition: LT_I2C.cpp:394
#define LTC6950_SM1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:143
#define LTC6950_PD_OUT0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:129
static int i
Definition: DC2430A.ino:184
#define LTC6950_CP
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:82
static void print_prompt()
Prints main menu.
Definition: DC1795A.ino:1118
static void LTC6950_Ref_Freq_Verification()
verifies reference frequency is within datasheet specifications
Definition: DC1795A.ino:890
static void LTC6950_VCO_Freq_Verification()
verifies VCO frequency is within datasheet specifications
Definition: DC1795A.ino:823
#define LTC6950_CMSINV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:81
#define LTC6950_PD_DIV0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:124
#define LTC6950_LVCMS
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:113
#define EEPROM_CAL_KEY
#define LTC6950_THI
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:151
#define LTC6950_CPINV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:86
#define LTC6950_FILTR
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6950.h:96