Linduino  1.3.0
Linear Technology Arduino-Compatible Demonstration Board
LTC6954.cpp
Go to the documentation of this file.
1 /*!
2  LTC6954: Low Phase Noise, Triple Output Clock Distribution Divider/Driver
3 
4 @verbatim
5 
6 The LTC®6954 is a family of very low phase noise clock
7 distribution parts. Each part has three outputs and each
8 output has an individually programmable frequency
9 divider and delay.
10 
11 There are four members of the family, differing in their output logic signal type:
12 LTC6954-1: Three LVPECL outputs
13 LTC6954-2: Two LVPECL and one LVDS/CMOS outputs
14 LTC6954-3: One LVPECL and two LVDS/CMOS outputs
15 LTC6954-4: Three LVDS/CMOS outputs
16 
17 Each output is individually programmable to divide the
18 input frequency by any integer from 1 to 63, and to delay
19 each output by 0 to 63 input clock cycles. The output duty
20 cycle is always 50%, regardless of the divide number.
21 
22 The LVDS/CMOS outputs are jumper selectable via the
23 OUTSEL pins to provide either an LVDS logic output or a
24 CMOS logic output.
25 
26 The LTC6954 also features Linear Technology’s EZSync
27 system for perfect clock synchronization and alignment
28 every time.
29 
30 The LTC6954 is available in a 36-lead, 4mm × 7mm QFN
31 package.
32 
33 All device settings are controlled through an SPI-compatible
34 serial port.
35 
36 @endverbatim
37 
38 
39 http://www.linear.com/product/LTC6954
40 
41 http://www.linear.com/product/LTC6954#demoboards
42 
43 
44 Copyright 2018(c) Analog Devices, Inc.
45 
46 All rights reserved.
47 
48 Redistribution and use in source and binary forms, with or without
49 modification, are permitted provided that the following conditions are met:
50  - Redistributions of source code must retain the above copyright
51  notice, this list of conditions and the following disclaimer.
52  - Redistributions in binary form must reproduce the above copyright
53  notice, this list of conditions and the following disclaimer in
54  the documentation and/or other materials provided with the
55  distribution.
56  - Neither the name of Analog Devices, Inc. nor the names of its
57  contributors may be used to endorse or promote products derived
58  from this software without specific prior written permission.
59  - The use of this software may or may not infringe the patent rights
60  of one or more patent holders. This license does not release you
61  from the requirement that you obtain separate licenses from these
62  patent holders to use this software.
63  - Use of the software either in source or binary form, must be run
64  on or directly connected to an Analog Devices Inc. component.
65 
66 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
67 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
68 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
69 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
70 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
71 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
72 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
73 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
74 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
75 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76 */
77 
78 //! @ingroup RF_Timing
79 //! @{
80 //! @defgroup LTC6954 LTC6954: Low Phase Noise, Triple Output Clock Distribution Divider/Driver
81 //! @}
82 
83 /*! @file
84  @ingroup LTC6954
85  Library for LTC6954: Low Phase Noise, Triple Output Clock Distribution Divider/Driver
86 */
87 
88 #include <stdint.h>
89 #include <Arduino.h>
90 #include "Linduino.h"
91 #include "UserInterface.h"
92 #include "LT_SPI.h"
93 #include "LTC6954.h"
94 #include <SPI.h>
95 
96 uint8_t LTC6954_reg[LTC6954_NUM_REGADDR]; //!< number of LTC6954 spi addresses
97 uint8_t LTC6954_spi_map[(LTC6954_NUM_REGFIELD+1)][4]; //!< LTC6954 spi map, stores MSB address location, MSB bit location, field length in bits, and R or RW capability
98 
99 
100 /* -------------------------------------------------------------------------
101  FUNCTION: LTC6954_read
102  - reads 8 bit Data field to LTC6954.
103  - has to shift data by one bit to account for RW bit
104  -------------------------------------------------------------------------- */
105 uint8_t LTC6954_read(uint8_t cs, int8_t address)
106 {
107  int8_t address_shift;
109 
110  address_shift =(address << 1) | 0x01; // shift to left to account for R/W bit, set bit high for read
111  spi_transfer_word(cs, address_shift<<8 , &rx.LT_uint16);
112 
113  LTC6954_reg[address]=rx.LT_byte[0];
114  return(rx.LT_byte[0]);
115 }
116 
117 
118 /* -------------------------------------------------------------------------
119  FUNCTION: LTC6954_read_field
120  For SPI FIELDS located in 1 or multiple address location
121  - reads specific address locations
122  - identifies and returns specific field in question
123  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
124 --------------------------------------------------------------------------- */
125 long LTC6954_read_field(uint8_t cs, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
126 {
127  int bit_shift, i, num_reg;
128  long field_val, maskbits, pow2;
129 
130  num_reg=0;
131  field_val=0;
132 // determines how many register are used
133  do
134  {
135  bit_shift = (MSB_loc+1)- (numbits-num_reg*8); // determines bit_shift for last register location
136  field_val=LTC6954_read(cs, (address+num_reg))+(field_val<<8); // reads current address locations, shifts previous address location 8 bits
137  num_reg++;
138  }
139  while ((bit_shift<0) && (num_reg<4));
140 
141 // creates a bit mask for complete word,
142  maskbits = 1;
143  pow2=1;
144  for (i=1, maskbits=1; i<numbits; i++)
145  {
146  pow2=pow2*2;
147  maskbits = maskbits+pow2;
148  }
149 
150  field_val=(field_val >>bit_shift) &maskbits;
151  return field_val;
152 }
153 
154 /* -------------------------------------------------------------------------
155  FUNCTION: get_LTC6954_SPI_FIELD
156  For SPI FIELDS
157  - reads specific address locations
158  - identifies and returns specific field in question
159  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
160 --------------------------------------------------------------------------- */
161 long get_LTC6954_SPI_FIELD(uint8_t cs, uint8_t f)
162 {
163 
165 }
166 
167 /* -------------------------------------------------------------------------
168  FUNCTION: LTC6954_write
169  - writes 8 bit Data field to LTC6954.
170  - has to shift data by one bit to account for RW bit
171 --------------------------------------------------------------------------- */
172 void LTC6954_write(uint8_t cs, uint8_t address, uint8_t Data)
173 {
175 
176  address=address << 1; // shift to left to account for R/W bit
177  spi_transfer_word(cs, (address<<8) | Data, &rx.LT_uint16);
178 }
179 
180 
181 /* -------------------------------------------------------------------------
182  FUNCTION: LTC6954_write_field
183  For SPI FIELDS
184  - reads specific address location
185  - identifies and returns specific field in question
186  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
187 ---------------------------------------------------------------------------- */
188 uint8_t LTC6954_write_field(uint8_t cs, long field_data, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
189 {
190  long current_content, desired_content, reg_val;
191  int LSB_loc, i, j, num_reg, bit_shift;
192  long temp_arr[32];
193 
194  for (i=0; i<32 ; i++) temp_arr[i]=0; // init temp_arr
195 
196 // read data in current address location and put in a bit array
197  num_reg=0;
198  current_content=0;
199  do
200  {
201  bit_shift=(MSB_loc+1)-(numbits-num_reg*8);
202  current_content=LTC6954_read(cs, (address+num_reg)) + (current_content<<8);
203 
204  num_reg++;
205  }
206  while ((bit_shift<0) && (num_reg<4));
207  for (i=0; i<(8*num_reg); i++)
208  {
209  temp_arr[i]=(current_content>>i) & 1;
210  }
211 
212 // exchange current bits with desired bits
213  LSB_loc = 8*(num_reg-1)+MSB_loc-numbits+1;
214  for (i=LSB_loc, j=0; i<=(MSB_loc+(num_reg-1)*8); i++, j++)
215  {
216  temp_arr[i] = (field_data>>j) &1;
217  } // end of for loop
218 
219 // reconstruct bits into an integer
220  desired_content = 0;
221  for (i=0; i<(8*num_reg); i++)
222  {
223  desired_content = desired_content | (temp_arr[i]<<i);
224  } // end of for loop
225 
226 // write new field value to part
227  for (i=0; i<num_reg; i++)
228  {
229  reg_val = (desired_content >> 8*(num_reg-1-i)) & 0xff;
230  LTC6954_write(cs, (address+i), reg_val);
231  } // end of for loop
232 } // end of LTC6954_write_field
233 
234 
235 /* -------------------------------------------------------------------------
236  FUNCTION: get_LTC6954_REGSIZE
237  - returns # of addresses in parts register map (array size)
238 ---------------------------------------------------------------------------- */
240 {
241  return sizeof(LTC6954_reg);
242 }
243 
244 
245 /* -------------------------------------------------------------------------
246  FUNCTION: get_LTC6954_SPI_FIELD_NUMBITS
247  - returns the number of bits for a given field name in the SPI map
248 ---------------------------------------------------------------------------- */
250 {
251  return LTC6954_spi_map[f][NUMBITS];
252 }
253 
254 
255 /* -------------------------------------------------------------------------
256  FUNCTION: get_LTC6954_SPI_FIELD_RW
257  - returns if the given field name is (0)read/write or (1)read_only field
258 ---------------------------------------------------------------------------- */
259 uint8_t get_LTC6954_SPI_FIELD_RW(uint8_t f)
260 {
261  return LTC6954_spi_map[f][R_ONLY];
262 }
263 
264 
265 /* -------------------------------------------------------------------------
266  FUNCTION: set_LTC6954_SPI_FIELD
267  For SPI FIELDS
268  - reads specific address location
269  - identifies and returns specific field in question
270  - can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
271 ---------------------------------------------------------------------------- */
272 void set_LTC6954_SPI_FIELD(uint8_t cs, uint8_t f, long field_data)
273 {
275 }
276 
277 
278 /* -------------------------------------------------------------------------
279  FUNCTION: set_LTC6954_ALLREGS
280  - writes data to all registers at once
281 --------------------------------------------------------------------------- */
282 void set_LTC6954_ALLREGS(uint8_t cs, uint8_t reg00, uint8_t reg01, uint8_t reg02, uint8_t reg03, uint8_t reg04, uint8_t reg05, uint8_t reg06)
283 {
284  uint8_t i;
285 
286  LTC6954_reg[0] = reg00;
287  LTC6954_reg[1] = reg01;
288  LTC6954_reg[2] = reg02;
289  LTC6954_reg[3] = reg03;
290  LTC6954_reg[4] = reg04;
291  LTC6954_reg[5] = reg05;
292  LTC6954_reg[6] = reg06;
293 
294 
295  for (i=0; i<get_LTC6954_REGSIZE(); i++) LTC6954_write(cs, i, LTC6954_reg[i]);
296 } // end of set_LTC6954_ALLREGS
297 
298 
299 /* -------------------------------------------------------------------------
300  FUNCTION: LTC6954_init
301  - initializes the SPI MAP
302  - for ease of programming there is spreadsheet that automates this some.
303 ----------------------------------------------------------------------------*/
305 {
306 
307 // spi map
380 
381 
406 
407 
408 } // end of LTC6954_init
uint8_t LTC6954_reg[LTC6954_NUM_REGADDR]
number of LTC6954 spi addresses
Definition: LTC6954.cpp:96
uint8_t LTC6954_read(uint8_t cs, int8_t address)
LTC6954 Read Single Address reads 8 bit Data field to LTC6954.
Definition: LTC6954.cpp:105
#define LTC6954_PD_DIV1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:96
#define LTC6954_PDALL
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:94
#define LTC6954_SYNC_EN0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:102
#define LTC6954_M2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:92
LTC6954: Low Phase Noise, Triple Output Clock Distribution Divider/Driver.
long LTC6954_read_field(uint8_t cs, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
LTC6954 Read Single Field For SPI FIELDS located in 1 or multiple address locations reads specific ad...
Definition: LTC6954.cpp:125
Header File for Linduino Libraries and Demo Code.
#define LTC6954_PD_OUT0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:98
#define LTC6954_LVCS1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:88
#define LTC6954_NUM_REGADDR
Defines number of LTC6954 SPI registers, used in spi_map array.
Definition: LTC6954.h:106
#define LTC6954_NUM_REGFIELD
Defines number of LTC6954 SPI fields, used in spi_map array.
Definition: LTC6954.h:107
#define LTC6954_SYNC_EN1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:103
#define LTC6954_LVCS2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:89
uint8_t LTC6954_spi_map[(LTC6954_NUM_REGFIELD+1)][4]
LTC6954 spi map, stores MSB address location, MSB bit location, field length in bits, and R or RW capability.
Definition: LTC6954.cpp:97
uint8_t LTC6954_write_field(uint8_t cs, long field_data, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
LTC6954 Write Single Field For SPI FIELDS in 1 or multiple address locations reads specific address/f...
Definition: LTC6954.cpp:188
#define LTC6954_PART
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:93
void LTC6954_init()
Initializes the SPI MAP arrays The values set in initialization are used all the LTC6954 SPI/WRITE an...
Definition: LTC6954.cpp:304
#define LTC6954_CMSINV0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:81
#define NUMBITS
Definition: LTC6115.h:69
static uint8_t address
Definition: DC2091A.ino:83
uint8_t get_LTC6954_REGSIZE()
returns # of addresses in parts register map (array size)
Definition: LTC6954.cpp:239
#define LTC6954_PD_OUT2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:100
#define LTC6954_DEL1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:85
uint8_t get_LTC6954_SPI_FIELD_RW(uint8_t f)
returns if the given field name is (0)read/write or (1)read_only field
Definition: LTC6954.cpp:259
uint16_t LT_uint16
16-bit unsigned integer to be converted to two bytes
Definition: Linduino.h:102
#define R_ONLY
used for 2nd dim of 2d spi_map array
Definition: LTC6945.h:119
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 LTC6954_PD_DIV2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:97
long get_LTC6954_SPI_FIELD(uint8_t cs, uint8_t f)
Gets the LTC6954 SPI field value calls function LTC6954_read_field, which reads specific address loca...
Definition: LTC6954.cpp:161
#define LTC6954_M1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:91
#define LTC6954_PD_OUT1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:99
#define LTC6954_SYNC_EN2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:104
LT_SPI: Routines to communicate with ATmega328P&#39;s hardware SPI port.
#define ADDRx
used for 2nd dim of 2d spi_map array
Definition: LTC6945.h:116
void set_LTC6954_SPI_FIELD(uint8_t cs, uint8_t f, long field_data)
Sets the LTC6954 SPI field value calls function LTC6954_read_field, which reads specific address/fiel...
Definition: LTC6954.cpp:272
void LTC6954_write(uint8_t cs, uint8_t address, uint8_t Data)
LTC6954 Write Single Address writes 8 bit Data field to LTC6954.
Definition: LTC6954.cpp:172
#define LTC6954_PD_DIV0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:95
This union splits one int16_t (16-bit signed integer) or uint16_t (16-bit unsigned integer) into two ...
Definition: Linduino.h:99
#define LTC6954_DEL0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:84
#define LTC6954_REV
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:101
static int i
Definition: DC2430A.ino:184
void set_LTC6954_ALLREGS(uint8_t cs, uint8_t reg00, uint8_t reg01, uint8_t reg02, uint8_t reg03, uint8_t reg04, uint8_t reg05, uint8_t reg06)
Writes values to ALL LTC6954 RW address.
Definition: LTC6954.cpp:282
#define LTC6954_CMSINV1
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:82
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
#define LTC6954_LVCS0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:87
#define LTC6954_DEL2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:86
uint8_t get_LTC6954_SPI_FIELD_NUMBITS(uint8_t f)
returns the number of bits for a given field name in the SPI map
Definition: LTC6954.cpp:249
#define LTC6954_M0
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:90
#define LTC6954_CMSINV2
for spi_map array, defines location for field specific information used to create the spi map ...
Definition: LTC6954.h:83
#define DxMSB
used for 2nd dim of 2d spi_map array
Definition: LTC6945.h:117