Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
LTC6951.cpp
Go to the documentation of this file.
1 /*!
2  LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
3 
4 @verbatim
5 
6 The LTC®6951 is a high performance, low noise, Phase
7 Locked Loop (PLL) with a fully integrated VCO. The low
8 noise VCO uses no external components and is internally
9 calibrated to the correct output frequency with no external
10 system support.
11 
12 The clock generation section provides five outputs based
13 on the VCO prescaler signal with individual dividers for
14 each output. Four outputs feature very low noise, low skew
15 CML logic. The fifth output is low noise LVDS. All outputs
16 can be synchronized and set to precise phase alignment
17 using the programmable delays.
18 
19 Choose the LTC6951-1 if any desired output frequency
20 falls in the ranges 2.5GHz to 2.7GHz, 1.66GHz to 1.8GHz,
21 or 1.25GHz to 1.35GHz. Choose the LTC6951 for all other
22 frequencies.
23 
24 @endverbatim
25 
26 
27 http://www.linear.com/product/LTC6951
28 
29 http://www.linear.com/product/LTC6951#demoboards
30 
31 
32 Copyright 2018(c) Analog Devices, Inc.
33 
34 All rights reserved.
35 
36 Redistribution and use in source and binary forms, with or without
37 modification, are permitted provided that the following conditions are met:
38  - Redistributions of source code must retain the above copyright
39  notice, this list of conditions and the following disclaimer.
40  - Redistributions in binary form must reproduce the above copyright
41  notice, this list of conditions and the following disclaimer in
42  the documentation and/or other materials provided with the
43  distribution.
44  - Neither the name of Analog Devices, Inc. nor the names of its
45  contributors may be used to endorse or promote products derived
46  from this software without specific prior written permission.
47  - The use of this software may or may not infringe the patent rights
48  of one or more patent holders. This license does not release you
49  from the requirement that you obtain separate licenses from these
50  patent holders to use this software.
51  - Use of the software either in source or binary form, must be run
52  on or directly connected to an Analog Devices Inc. component.
53 
54 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
55 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
56 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
58 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
59 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
60 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
61 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
62 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
63 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 */
65 
66 //! @ingroup RF_Timing
67 //! @{
68 //! @defgroup LTC6951 LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
69 //! @}
70 
71 /*! @file
72  @ingroup LTC6951
73  Library for LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
74 */
75 
76 #include <stdint.h>
77 #include <Arduino.h>
78 #include "Linduino.h"
79 #include "UserInterface.h"
80 #include "LT_SPI.h"
81 #include "LTC6951.h"
82 #include "QuikEval_EEPROM.h"
83 #include <SPI.h>
84 
85 uint8_t LTC6951_reg[LTC6951_NUM_REGADDR]; //!< number of LTC6951 spi addresses
86 uint8_t LTC6951_spi_map[(LTC6951_NUM_REGFIELD+1)][4]; //!< LTC6951 spi map, stores MSB address location, MSB bit location, field length in bits, and R or RW capability
87 
88 uint8_t LTC6951_lkup_tbl[10][LTC6951_NUM_REGADDR] = //!< the following settings assume a 100MHz reference input
89 {
90  {0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x30, 0x07, 0x00, 0x92, 0x00, 0x92, 0x00, 0x92, 0x00, 0x92, 0x00, 0x92, 0x00, 0x11}, //!< ALL CHAN 600MHZ, EZSync
91  {0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x12, 0x00, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x11}, //!< ALL CHAN 600MHZ, EZSync Ref Aligned
92  {0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x12, 0x00, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x11}, //!< ALL CHAN 600MHZ, EZParallelSync
93  {0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x12, 0xc0, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x11}, //!< ALL CHAN 600MHZ, ParallelSync
94  {0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x32, 0x07, 0x00, 0x90, 0x00, 0x90, 0x00, 0x90, 0x00, 0x90, 0x00, 0x92, 0x00, 0x11}, //!< OUT[0:3] 2500MHZ, OUT4:625MHz, EZSync
95  {0x05, 0xba, 0x00, 0x74, 0x83, 0x04, 0x19, 0x07, 0x00, 0x10, 0x00, 0x90, 0x07, 0x90, 0x07, 0x90, 0x07, 0x92, 0x07, 0x11}, //!< OUT[0:3] 2500MHZ, OUT4:625MHz, EZSync Ref Aligned
96  {0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x12, 0x00, 0x90, 0x06, 0x90, 0x06, 0x90, 0x06, 0x92, 0x06, 0x11}, //!< OUT[1:3] 2400MHZ, OUT0 & OUT4:600MHz, EZParallelSync
97  {0x05, 0xba, 0x00, 0x74, 0x83, 0x04, 0x19, 0x07, 0x00, 0x10, 0xc0, 0x90, 0x07, 0x90, 0x07, 0x90, 0x07, 0x92, 0x07, 0x11}, //!< OUT[0:3] 2500MHZ, OUT4:625MHz, ParallelSync
98  {0x00, 0xba, 0x00, 0x74, 0x93, 0x04, 0x14, 0x07, 0x00, 0x20, 0xc0, 0xd3, 0x05, 0x30, 0x00, 0xdb, 0x09, 0x95, 0x05, 0x00}, //!< Same frequency as DC2226 U10 device
99  {0x00, 0xba, 0x00, 0x74, 0x93, 0x04, 0x14, 0x07, 0x00, 0x20, 0xc0, 0xd3, 0x05, 0x30, 0x00, 0xdb, 0x09, 0x9b, 0x09, 0x00} //!< Same frequency as DC2226 U13 device
100 }; //!< LTC6951 Configuration look-up table
101 
102 
103 /* -------------------------------------------------------------------------
104  FUNCTION: LTC6951_read
105  - reads 8 bit Data field to LTC6951.
106  - has to shift data by one bit to account for RW bit
107  -------------------------------------------------------------------------- */
108 uint8_t LTC6951_read(uint8_t cs, int8_t address)
109 {
110  int8_t address_shift;
112 
113  address_shift =(address << 1) | 0x01; // shift to left to account for R/W bit, set bit high for read
114  spi_transfer_word(cs, address_shift<<8 , &rx.LT_uint16);
115 
116  LTC6951_reg[address]=rx.LT_byte[0];
117  return(rx.LT_byte[0]);
118 }
119 
120 
121 /* -------------------------------------------------------------------------
122  FUNCTION: LTC6951_read_field
123  For SPI FIELDS located in 1 or multiple address location
124  - reads specific address locations
125  - identifies and returns specific field in question
126  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
127 --------------------------------------------------------------------------- */
128 long LTC6951_read_field(uint8_t cs, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
129 {
130  int bit_shift, i, num_reg;
131  long field_val, maskbits, pow2;
132 
133  num_reg=0;
134  field_val=0;
135 // determines how many register are used
136  do
137  {
138  bit_shift = (MSB_loc+1)- (numbits-num_reg*8); // determines bit_shift for last register location
139  field_val=LTC6951_read(cs, (address+num_reg))+(field_val<<8); // reads current address locations, shifts previous address location 8 bits
140  num_reg++;
141  }
142  while ((bit_shift<0) && (num_reg<4));
143 
144 // creates a bit mask for complete word,
145  maskbits = 1;
146  pow2=1;
147  for (i=1, maskbits=1; i<numbits; i++)
148  {
149  pow2=pow2*2;
150  maskbits = maskbits+pow2;
151  }
152 
153  field_val=(field_val >>bit_shift) &maskbits;
154  return field_val;
155 }
156 
157 /* -------------------------------------------------------------------------
158  FUNCTION: get_LTC6951_SPI_FIELD
159  For SPI FIELDS
160  - reads specific address locations
161  - identifies and returns specific field in question
162  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
163 --------------------------------------------------------------------------- */
164 long get_LTC6951_SPI_FIELD(uint8_t cs, uint8_t f)
165 {
166 
168 }
169 
170 /* -------------------------------------------------------------------------
171  FUNCTION: LTC6951_write
172  - writes 8 bit Data field to LTC6951.
173  - has to shift data by one bit to account for RW bit
174 --------------------------------------------------------------------------- */
175 void LTC6951_write(uint8_t cs, uint8_t address, uint8_t Data)
176 {
178 
179  address=address << 1; // shift to left to account for R/W bit
180  spi_transfer_word(cs, (address<<8) | Data, &rx.LT_uint16);
181 }
182 
183 
184 /* -------------------------------------------------------------------------
185  FUNCTION: LTC6951_write_field
186  For SPI FIELDS
187  - reads specific address location
188  - identifies and returns specific field in question
189  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
190 ---------------------------------------------------------------------------- */
191 uint8_t LTC6951_write_field(uint8_t cs, long field_data, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
192 {
193  long current_content, desired_content, reg_val;
194  int LSB_loc, i, j, num_reg, bit_shift;
195  long temp_arr[32];
196 
197  for (i=0; i<32 ; i++) temp_arr[i]=0; // init temp_arr
198 
199 // read data in current address location and put in a bit array
200  num_reg=0;
201  current_content=0;
202  do
203  {
204  bit_shift=(MSB_loc+1)-(numbits-num_reg*8);
205  current_content=LTC6951_read(cs, (address+num_reg)) + (current_content<<8);
206 
207  num_reg++;
208  }
209  while ((bit_shift<0) && (num_reg<4));
210  for (i=0; i<(8*num_reg); i++)
211  {
212  temp_arr[i]=(current_content>>i) & 1;
213  }
214 
215 // exchange current bits with desired bits
216  LSB_loc = 8*(num_reg-1)+MSB_loc-numbits+1;
217  for (i=LSB_loc, j=0; i<=(MSB_loc+(num_reg-1)*8); i++, j++)
218  {
219  temp_arr[i] = (field_data>>j) &1;
220  } // end of for loop
221 
222 // reconstruct bits into an integer
223  desired_content = 0;
224  for (i=0; i<(8*num_reg); i++)
225  {
226  desired_content = desired_content | (temp_arr[i]<<i);
227  } // end of for loop
228 
229 // write new field value to part
230  for (i=0; i<num_reg; i++)
231  {
232  reg_val = (desired_content >> 8*(num_reg-1-i)) & 0xff;
233  LTC6951_write(cs, (address+i), reg_val);
234  } // end of for loop
235 } // end of LTC6951_write_field
236 
237 
238 /* -------------------------------------------------------------------------
239  FUNCTION: get_LTC6951_REGSIZE
240  - returns # of addresses in parts register map (array size)
241 ---------------------------------------------------------------------------- */
243 {
244  return sizeof(LTC6951_reg);
245 }
246 
247 
248 /* -------------------------------------------------------------------------
249  FUNCTION: get_LTC6951_SPI_FIELD_NUMBITS
250  - returns the number of bits for a given field name in the SPI map
251 ---------------------------------------------------------------------------- */
253 {
254  return LTC6951_spi_map[f][NUMBITS];
255 }
256 
257 
258 /* -------------------------------------------------------------------------
259  FUNCTION: get_LTC6951_SPI_FIELD_RW
260  - returns if the given field name is (0)read/write or (1)read_only field
261 ---------------------------------------------------------------------------- */
262 uint8_t get_LTC6951_SPI_FIELD_RW(uint8_t f)
263 {
264  return LTC6951_spi_map[f][R_ONLY];
265 }
266 
267 
268 /* -------------------------------------------------------------------------
269  FUNCTION: set_LTC6951_SPI_FIELD
270  For SPI FIELDS
271  - reads specific address location
272  - identifies and returns specific field in question
273  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
274 ---------------------------------------------------------------------------- */
275 void set_LTC6951_SPI_FIELD(uint8_t cs, uint8_t f, long field_data)
276 {
278 }
279 
280 
281 /* -------------------------------------------------------------------------
282  FUNCTION: set_LTC6951_ALLREGS
283  - writes data to all registers at once
284 --------------------------------------------------------------------------- */
285 void set_LTC6951_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,
286  uint8_t reg08, uint8_t reg09, uint8_t reg0A, uint8_t reg0B, uint8_t reg0C, uint8_t reg0D, uint8_t reg0E, uint8_t reg0F,
287  uint8_t reg10, uint8_t reg11, uint8_t reg12)
288 {
289  uint8_t i;
290 
291  LTC6951_reg[1] = reg01;
292  LTC6951_reg[2] = reg02;
293  LTC6951_reg[3] = reg03;
294  LTC6951_reg[4] = reg04;
295  LTC6951_reg[5] = reg05;
296  LTC6951_reg[6] = reg06;
297  LTC6951_reg[7] = reg07;
298  LTC6951_reg[8] = reg08;
299  LTC6951_reg[9] = reg09;
300  LTC6951_reg[10] = reg0A;
301  LTC6951_reg[11] = reg0B;
302  LTC6951_reg[12] = reg0C;
303  LTC6951_reg[13] = reg0D;
304  LTC6951_reg[14] = reg0E;
305  LTC6951_reg[15] = reg0F;
306  LTC6951_reg[16] = reg10;
307  LTC6951_reg[17] = reg11;
308  LTC6951_reg[18] = reg12;
309 
310 
311  for (i=1; i<19; i++) LTC6951_write(cs, i, LTC6951_reg[i]);
312 } // end of set_LTC6951_ALLREGS
313 
314 
315 /* -------------------------------------------------------------------------
316  FUNCTION: set_LTC6951_REGS_lkup_tbl
317  - writes LTC6951 registers from a look up table
318  - uses the Multi-byte write option for more efficient data transfer
319  - Calibrates VCO based on RAO and Autocal bit vales
320  - Either SPI Syncs or recommends the use to SYNC pin based on RAO, SN and SR values
321 --------------------------------------------------------------------------- */
322 void set_LTC6951_REGS_lkup_tbl(uint8_t lkup_tbl_row)
323 {
324  uint8_t val_temp, i, RAO_bit, AUTOCAL_bit, SN_bit, SR_bit;
325  uint8_t val_reg2, val_reg3, val_regA;
326  uint8_t *rx;
327 
328 //! ************** SPI REGISTER WRITE SECTION ************
329  output_low(QUIKEVAL_CS); //! 1) CS low, enable SPI
330  val_temp = 1<<1; //! 2) addr 1, shift 1 bit to account for RW bit (W=0)
331  *rx = SPI.transfer(val_temp); //! 3) send ADDR1 byte
332  for (i=1; i<19; i++)
333  {
334  val_temp=LTC6951_lkup_tbl[lkup_tbl_row][i];
335  *rx = SPI.transfer(val_temp); //! 4) send REG byte
336  }
337  output_high(QUIKEVAL_CS); //! 5) CS high, disable SPI
338 
339 //! **************** CALIBRATION SECTION ******************
340 //! Calibration required after Register writes if RAO=1 or if RAO=AUTOCAL=0.
341  val_reg2 = LTC6951_lkup_tbl[lkup_tbl_row][2]; //! CAL bit is located @ reg 2, bit 0, AUTOCAL bit reg 2, bit 3
342  val_reg3 = LTC6951_lkup_tbl[lkup_tbl_row][3]; //! RAO bit is located @ reg 3, bit 2; SSYNC bit @ reg 3, bit 4
343  RAO_bit = (val_reg3 & 0x04)>>2;
344  AUTOCAL_bit = (val_reg3 & 0x08)>>3;
345 
346  val_regA = LTC6951_lkup_tbl[lkup_tbl_row][10]; //! SN, SR bit are located @ reg A, bits 7.6
347  SN_bit = (val_regA & 0x80)>>7;
348  SR_bit = (val_regA & 0x40)>>6;
349 
350  if ((RAO_bit ==1) || (AUTOCAL_bit ==0)) //! checks if RAO=1 or AUTOCAL bit = 0
351  {
352  val_reg2 = val_reg2 | 0x01; //! sets CAL bit = 1
353  output_low(QUIKEVAL_CS); //! CS low, enable SPI
354  val_temp = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
355  *rx = SPI.transfer(val_temp); //! send ADDR2 byte + RW byte
356  *rx = SPI.transfer(val_reg2); //! send REG2 byte w/ CAL=1
357  output_high(QUIKEVAL_CS); //! CS high, disable SPI
358  val_reg2 = LTC6951_lkup_tbl[lkup_tbl_row][2]; //! CAL bit auto-clears after Calibration, set val_reg2 back to look-up table value
359  }
360  delay(1); //! wait 1ms for Calibration to complete, calibration usually takes <100us
361 
362 //! **************** OUTPUT SYNC SECTION ******************
363 //! SSYNC can be used for EZSYNC StandAlone, EZSync Ref aligned standalone, EZParallelSYnc, EZ204Sync
364 //! - EZSync Standalone, RAO=0
365 //! - EZParallelSync, EZ204Sync, EZSync ref aligned: RA0=1, SN=SR=0
366 //! For ParallelSync or EZSync Controller to work the the SYNC pin should be used
367 //! - EZSync Controller, RAO=0 (User will have to remember if its a Controller as there is not a bit to distinguish this)
368 //! - ParallelSync: RA0=1, SN or SR= 1
369 //! See datasheet for timing requirements
370  if ((RAO_bit==0) || ((RAO_bit == 1) && ((SN_bit+SR_bit)==0)))
371  {
372  val_reg2 = val_reg2 | 0x04; //! Sets SSYNC bit =1
373  output_low(QUIKEVAL_CS); //! CS low, enable SPI
374  val_temp = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
375  *rx = SPI.transfer(val_temp); //! send ADDR2 byte + RW byte
376  *rx = SPI.transfer(val_reg2); //! send REG2 byte w/ CAL=1
377  output_high(QUIKEVAL_CS); //! CS high, disable SPI
378  delay(1); //! SSYNC bit remains high for a minimum of 1ms
379 
380  val_reg2 = val_reg2 - 0x04; //! Sets SSYNC bit back to 0
381  output_low(QUIKEVAL_CS); //! CS low, enable SPI
382  val_temp = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
383  *rx = SPI.transfer(val_temp); //! send ADDR2 byte + RW byte
384  *rx = SPI.transfer(val_reg2); //! send REG2 byte w/ CAL=1
385  output_high(QUIKEVAL_CS); //! CS high, disable SPI
386  }
387 
388 //! **************** INFO SECTION ******************
389 //! INFO ONLY: Print Register Map written to part
390  for (i=1; i<19; i++)
391  {
392  val_temp=LTC6951_lkup_tbl[lkup_tbl_row][i];
393  Serial.print(F("ADDR"));
394  if (i<16) Serial.print("0");
395  Serial.print(i, HEX);
396  Serial.print(F(" = 0x"));
397  Serial.println(val_temp, HEX);
398  }
399 
400  if (RAO_bit == 0)
401  {
402  Serial.println(F(" ***************************************************************************** "));
403  Serial.println(F("If this is a EZSync Standalone Device ignore this message - LTC6951 has been SYNC'd via SPI "));
404  Serial.println(F("If this is a EZSync Controller Device toggle all EZSync Device's Sync pins "));
405  Serial.println(F("EZSync TIMING: Sync Pins must remain high for 1ms, and with <10us skew between all EZSync Sync pins "));
406  Serial.println(F(" ***************************************************************************** "));
407  }
408  if ( (RAO_bit == 1) && ( (SN_bit+SR_bit)>0 ) )
409  {
410  Serial.println(F(" ***************************************************************************** "));
411  Serial.println(F("ParallelSync Timing: See Datasheet for setup and hold times "));
412  Serial.println(F("USER MUST TOGGLE SYNC PINS ACROSS ALL PARALLLESYNC DEVICES "));
413  Serial.println(F("If a DC2430 is available:"));
414  Serial.println(F(" - DC2430's J20-J22 circuitry can be used to create correct SYNC to REF setup and hold times"));
415  Serial.println(F(" ***************************************************************************** "));
416  }
417 
418 } // end of set_LTC6951_REGS_lkup_tbl
419 
420 /* -------------------------------------------------------------------------
421  FUNCTION: set_LTC6951_REGS_freq_jump
422  - used to toggle between two frequencies
423  - if measuring calibration or settling times set SPI clock to max SPI rate (8MHz)
424  = writes LTC6951 registers from a local look up table
425  - uses the Multi-byte write option for more efficient data transfer
426  - Calibrates VCO based on RAO and Autocal bit vales
427  - DOES NOTE SYNC OUTPUTS
428  - RECOMMENDATION: If measuring settling times with E5052, NOT MUTING OUTPUT DURING CAL can provide more meaningful results
429 --------------------------------------------------------------------------- */
430 void set_LTC6951_REGS_freq_jump(uint8_t lkup_tbl_row, uint8_t init_setup)
431 {
432  boolean REGx3toREGx5_change=false;
433  boolean REGx9toREGx12_change=false;
434  boolean REGx7toREGx8_change=false;
435  uint8_t start_addr, end_addr, val_temp, i, RAO_bit, AUTOCAL_bit, SN_bit, SR_bit;
436  uint8_t val_reg2, val_reg3, val_regA;
437  uint8_t *rx;
438 // Modifiy the 2 registers to try different settings. LTC6951Wizard has an export register option that supplies the below format.
439  uint8_t local6951_lkup_tbl[2][LTC6951_NUM_REGADDR] = //!< the following settings assume a 100MHz reference input
440  {
441 //{0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x02, 0xc0, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x11}, //! ALL CHAN 600MHz, ParallelSync
442 //{0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x31, 0x07, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x11}, //! ALL CHAN 1225MHz, EZSync
443  {0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x30, 0x07, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x11}, //!< ALL CHAN 600MHZ, EZSync
444  {0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x2c, 0x07, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x11} //!< ALL CHAN 550MHZ, EZSync
445  };//
446 
447 // inital setup program all registers
448  if (init_setup)
449  {
450  //! ************** INIT: SPI REGISTERS (ALL) WRITE SECTION ************
451  output_low(QUIKEVAL_CS); //! 1) CS low, enable SPI
452  start_addr = 1;
453  val_temp = start_addr<<1; //! 2) addr 1, shift 1 bit to account for RW bit (W=0)
454  *rx = SPI.transfer(val_temp); //! 3) send ADDR1 byte
455  for (i=start_addr; i<19; i++)
456  {
457  val_temp=local6951_lkup_tbl[lkup_tbl_row][i];
458  *rx = SPI.transfer(val_temp); //! 4) send REG byte
459  }
460  output_high(QUIKEVAL_CS); //! 5) CS high, disable SPI
461  } // end if(init_setup)
462 
463 // checks if b or r-divider change?
464  REGx3toREGx5_change=false;
465  for (i=3; i<=5; i++)
466  {
467  if (local6951_lkup_tbl[0][i] != local6951_lkup_tbl[1][i]) REGx3toREGx5_change=true;
468  }
469 
470 // checks if p-divider change?
471  REGx7toREGx8_change=false;
472  for (i=7; i<=8; i++)
473  {
474  if (local6951_lkup_tbl[0][i] != local6951_lkup_tbl[1][i]) REGx7toREGx8_change=true;
475  }
476 
477 // checks if output divider change?
478  REGx9toREGx12_change=false;
479  for (i=9; i<=0x12; i++)
480  {
481  if (local6951_lkup_tbl[0][i] != local6951_lkup_tbl[1][i]) REGx9toREGx12_change=true;
482  }
483 
484 //! **************** SELECTION SECTION ******************
485 //! Calibration required after Register writes if RAO=1 or if RAO=AUTOCAL=0.
486  val_reg2 = local6951_lkup_tbl[lkup_tbl_row][2]; //! CAL bit is located @ reg 2, bit 0, AUTOCAL bit reg 2, bit 3
487  val_reg3 = local6951_lkup_tbl[lkup_tbl_row][3]; //! RAO bit is located @ reg 3, bit 2; SSYNC bit @ reg 3, bit 4
488  RAO_bit = (val_reg3 & 0x04)>>2;
489  AUTOCAL_bit = (val_reg3 & 0x08)>>3;
490 
491 //! All Settings of RAO and AUTOCAL Run this section
492 //! ************** SPI REGISTERS 4-19 WRITE SECTION ************
493 //! it possible the that register 6 is the only register that needs to change (N-divider),
494 //! but this codes was written for any and all frequency changes.
495  start_addr = 6; //! ADDR6 includes include ND
496  if (REGx3toREGx5_change==true) start_addr=3; //! ADDR4 includes include BD (cal-divider), ADDR 5 includes RD
497  end_addr=6; //! ADDR6 includes include ND
498  if (REGx7toREGx8_change==true) end_addr=8; //! ADDR8 includes include PD
499  if (REGx9toREGx12_change==true) end_addr=12; //! ADDR9-12 include output dividers
500 
501  output_low(QUIKEVAL_CS); //! CS low, enable SPI
502  val_temp = start_addr<<1; //! addr 4, shift 1 bit to account for RW bit (W=0)
503  *rx = SPI.transfer(val_temp); //! send ADDR byte
504  for (i=start_addr; i<=end_addr; i++)
505  {
506  val_temp=local6951_lkup_tbl[lkup_tbl_row][i];
507  *rx = SPI.transfer(val_temp); //! send REG bytes
508  }
509  output_high(QUIKEVAL_CS); //! CS high, disable SPI
510 
511 
512 //! If Autocal=0 or RAO_bit=1 (ParallelSync, EZParallelSync, EZ204Sync, EZSync Ref Aligned
513 //! Then the cal bit needs to be toggle, with Linduino it maybe fastest to continue
514 //! The multi-byte write operation. (reason: The CS L-H transistion has a delay)
515  if (RAO_bit || !AUTOCAL_bit)
516  {
517  start_addr = 2;
518  val_temp = start_addr<<1; //! ADDR, shift 1 bit to account for RW bit (W=0)
519  val_reg2 = val_reg2 | 0x01; //! sets CAL bit loc = 1
520 
521  output_low(QUIKEVAL_CS); //! CS low, enable SPI
522  *rx = SPI.transfer(val_temp); //! send ADDR2 byte
523  *rx = SPI.transfer(val_reg2); //! send REG2 byte
524  output_high(QUIKEVAL_CS); //! CS high, disable SPI
525  }
526 
527 } // end of set_LTC6951_REGS_freq_jump
528 
529 
530 /* -------------------------------------------------------------------------
531  FUNCTION: LTC6951_init
532  - initializes the SPI MAP
533  - for ease of programming there is spreadsheet that automates this some.
534 ----------------------------------------------------------------------------*/
536 {
537 // look up table
538 
539 // spi map
753 
825 } // end of LTC6951_init
826 
827 
828 
829 // Read the ID string from the EEPROM and determine if the correct board is connected.
830 // Returns 1 if successful, 0 if not successful
832 {
833  int8_t connected;
834  connected = 1;
835  // read the ID from the serial EEPROM on the board
836  // reuse the buffer declared in UserInterface
837  if (read_quikeval_id_string(&ui_buffer[0]) == 0) connected = 0;
838 
839  return(connected);
840 }
841 
#define LTC6951_ALCULOK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:86
#define LTC6951_LOCK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:106
#define LTC6951_SYNCEN0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:145
#define LTC6951_UNLOCK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:150
#define LTC6951_PDPLL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:133
#define LTC6951_INVSTAT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:103
#define LTC6951_CPDN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:92
#define LTC6951_CPUP
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:95
uint8_t get_LTC6951_SPI_FIELD_RW(uint8_t f)
returns if the given field name is (0)read/write or (1)read_only field
Definition: LTC6951.cpp:262
uint8_t get_LTC6951_SPI_FIELD_NUMBITS(uint8_t f)
returns the number of bits for a given field name in the SPI map
Definition: LTC6951.cpp:252
#define LTC6951_CPMID
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:93
#define LTC6951_REFOK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:139
#define LTC6951_MUTE1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:119
#define output_high(pin)
Set "pin" high.
Definition: Linduino.h:75
LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO...
#define LTC6951_CP
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:91
#define LTC6951_MD2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:115
#define LTC6951_FILT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:102
#define LTC6951_PDVCO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:135
Header File for Linduino Libraries and Demo Code.
#define LTC6951_SYNCEN3
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:148
void set_LTC6951_REGS_freq_jump(uint8_t lkup_tbl_row, uint8_t init_setup)
This function toggles between two frequencies.
Definition: LTC6951.cpp:430
#define LTC6951_DLY3
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:100
long LTC6951_read_field(uint8_t cs, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
LTC6951 Read Single Field For SPI FIELDS located in 1 or multiple address location reads specific add...
Definition: LTC6951.cpp:128
uint8_t LTC6951_spi_map[(LTC6951_NUM_REGFIELD+1)][4]
LTC6951 spi map, stores MSB address location, MSB bit location, field length in bits, and R or RW capability.
Definition: LTC6951.cpp:86
static int32_t connected
Definition: CN-0413.ino:69
void set_LTC6951_REGS_lkup_tbl(uint8_t lkup_tbl_row)
Writes values to ALL LTC6951 RW addresses from a look-up table.
Definition: LTC6951.cpp:322
uint8_t LTC6951_write_field(uint8_t cs, long field_data, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
LTC6951 Write Single Field For SPI FIELDS in 1 or multiple address locations reads specific address/f...
Definition: LTC6951.cpp:191
#define LTC6951_OINV2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:126
#define LTC6951_ALCEN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:82
#define LTC6951_PART
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:129
#define LTC6951_POR
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:136
#define LTC6951_SSYNC
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:144
#define LTC6951_MUTE2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:120
#define NUMBITS
Definition: LTC6115.h:69
static uint8_t address
Definition: DC2091A.ino:83
#define LTC6951_DLY2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:99
#define LTC6951_MUTE3
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:121
#define LTC6951_ND
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:123
#define LTC6951_MUTE4
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:122
#define LTC6951_PDALL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:131
#define LTC6951_MD4
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:117
#define LTC6951_MC2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:110
#define LTC6951_RAO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:137
#define LTC6951_MD1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:114
#define LTC6951_MC4
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:112
uint8_t LTC6951_reg[LTC6951_NUM_REGADDR]
number of LTC6951 spi addresses
Definition: LTC6951.cpp:85
#define LTC6951_DLY1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:98
#define LTC6951_BD
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:88
#define LTC6951_SR
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:143
#define LTC6951_CPWIDE
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:96
#define LTC6951_REV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:141
#define LTC6951_ALCCAL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:81
#define LTC6951_ALCHI
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:83
#define LTC6951_SYNCEN2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:147
uint16_t LT_uint16
16-bit unsigned integer to be converted to two bytes
Definition: Linduino.h:102
#define LTC6951_MD0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:113
uint8_t LTC6951_read(uint8_t cs, int8_t address)
LTC6951 Read Single Address reads 8 bit Data field to LTC6951.
Definition: LTC6951.cpp:108
#define LTC6951_LKWIN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:105
#define output_low(pin)
Set "pin" low.
Definition: Linduino.h:72
#define R_ONLY
used for 2nd dim of 2d spi_map array
Definition: LTC6945.h:119
QuikEval EEPROM Library.
void spi_transfer_word(uint8_t cs_pin, uint16_t tx, uint16_t *rx)
Reads and sends a word.
Definition: LT_SPI.cpp:98
#define LTC6951_MUTE0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:118
uint8_t get_LTC6951_REGSIZE()
returns # of addresses in parts register map (array size)
Definition: LTC6951.cpp:242
#define LTC6951_MCO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:108
#define LTC6951_NREFOK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:140
#define LTC6951_LKCT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:104
void set_LTC6951_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)
Writes values to ALL LTC6951 RW addresses.
Definition: LTC6951.cpp:285
#define LTC6951_ALCMON
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:85
uint8_t LTC6951_lkup_tbl[10][LTC6951_NUM_REGADDR]
the following settings assume a 100MHz reference input
Definition: LTC6951.cpp:88
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
#define LTC6951_PDREFPK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:134
#define LTC6951_ALCLO
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:84
#define LTC6951_AUTOCAL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:87
#define LTC6951_OINV3
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:127
#define LTC6951_MC3
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:111
#define ADDRx
used for 2nd dim of 2d spi_map array
Definition: LTC6945.h:116
#define LTC6951_PDOUT
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:132
#define LTC6951_SYNCEN1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:146
#define LTC6951_DLY4
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:101
#define LTC6951_BST
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:89
char demo_name[]
Demo Board Name stored in QuikEval EEPROM.
Definition: DC1880A.ino:97
#define LTC6951_RD
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:138
#define LTC6951_MC1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:109
#define LTC6951_SN
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:142
#define LTC6951_NUM_REGFIELD
Defines number of LTC6951 SPI fields, used in spi_map array.
Definition: LTC6951.h:156
#define LTC6951_DLY0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:97
#define LTC6951_PD
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:130
#define LTC6951_MD3
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:116
This union splits one int16_t (16-bit signed integer) or uint16_t (16-bit unsigned integer) into two ...
Definition: Linduino.h:99
#define LTC6951_OINV4
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:128
#define LTC6951_x
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:151
#define LTC6951_CPRST
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:94
void LTC6951_init()
Initializes the SPI MAP arrays The values set in initialization are used for all the LTC6951 SPI/WRIT...
Definition: LTC6951.cpp:535
void LTC6951_write(uint8_t cs, uint8_t address, uint8_t Data)
LTC6951 Write Single Address writes 8 bit Data field to LTC6951.
Definition: LTC6951.cpp:175
void set_LTC6951_SPI_FIELD(uint8_t cs, uint8_t f, long field_data)
Sets the LTC6951 SPI field value calls function LTC6951_read_field, which reads specific address/fiel...
Definition: LTC6951.cpp:275
static int i
Definition: DC2430A.ino:184
#define LTC6951_SYNCEN4
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:149
#define LTC6951_OINV1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:125
long get_LTC6951_SPI_FIELD(uint8_t cs, uint8_t f)
Gets the LTC6951 SPI field value calls function LTC6951_read_field, which reads specific address loca...
Definition: LTC6951.cpp:164
uint8_t LT_byte[2]
2 bytes (unsigned 8-bit integers) to be converted to a 16-bit signed or unsigned integer ...
Definition: Linduino.h:103
int8_t discover_demo_board_local(char *demo_name)
Read the ID string from the EEPROM and determine if any demo board is connected.
Definition: LTC6951.cpp:831
#define QUIKEVAL_CS
QuikEval CS pin (SPI chip select on QuikEval connector pin 6) connects to Arduino SS pin...
Definition: Linduino.h:57
#define LTC6951_NLOCK
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:107
#define LTC6951_NUM_REGADDR
Defines number of LTC6951 SPI registers, used in spi_map array.
Definition: LTC6951.h:155
#define LTC6951_CAL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:90
uint8_t read_quikeval_id_string(char *buffer)
Read the id string from the EEPROM, then parse the product name, demo board name, and demo board opti...
char ui_buffer[UI_BUFFER_SIZE]
#define LTC6951_OINV0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6951.h:124
#define DxMSB
used for 2nd dim of 2d spi_map array
Definition: LTC6945.h:117