LTC6951 - Ultralow Jitter Multi-Output Clock Synthesizer with Integrated VCO
Features
- Low Noise Integer-N PLL with Integrated VCO
- Output Jitter:
- 90fs RMS (12kHz to 20MHz)
- 115fs RMS (ADC SNR Method)
- Noise Floor = –165dBc/Hz at 250MHz
- EZSync™, ParallelSync™ Multichip Synchronization
- SYSREF Generation for JESD204B, Subclass 1
- Output Frequency Range:
- 1.95MHz to 2.5GHz (LTC6951)
- 2.1MHz to 2.7GHz (LTC6951-1)
- –229dBc/Hz Normalized In-Band Phase Noise Floor
- –277dBc/Hz Normalized In-Band 1/f Noise
- Five Independent, Low Noise Outputs
- Reference Input Frequency up to 425MHz
- LTC6951Wizard™ Software Design Tool Support
- –40°C to 105°C Operating Junction Temperature Range
- LTC6951Wizard Design Tool
Typical Application
Description
The LTC®6951 is a high performance, low noise, Phase Locked Loop (PLL) with a fully integrated VCO. The low noise VCO uses no external components and is internally calibrated to the correct output frequency with no external system support.
The clock generation section provides five outputs based on the VCO prescaler signal with individual dividers for each output. Four outputs feature very low noise, low skew CML logic. The fifth output is low noise LVDS. All outputs can be synchronized and set to precise phase alignment using the programmable delays.
Choose the LTC6951-1 if any desired output frequency falls in the ranges 2.5GHz to 2.7GHz, 1.66GHz to 1.8GHz, or 1.25GHz to 1.35GHz. Choose the LTC6951 for all other frequencies.
Packaging
CAD Symbols and Footprints: The downloadable Zip file below contains the schematic symbol and PCB footprints.
For complete and up to date package information and drawings, please refer to our packaging page
| Part Number | Package | Code | Temp | Package Drawing |
RoHS |
|---|---|---|---|---|---|
| LTC6951IUHF-1#PBF | 5x7 QFN-40 | UHF | I | 05-08-1951 | Yes |
| LTC6951IUHF-1#TRPBF | 5x7 QFN-40 | UHF | I | 05-08-1951 | Yes |
| LTC6951IUHF#PBF | 5x7 QFN-40 | UHF | I | 05-08-1951 | Yes |
| LTC6951IUHF#TRPBF | 5x7 QFN-40 | UHF | I | 05-08-1951 | Yes |
Order Info
- Part numbers ending in PBF are lead free. Solder plated terminal finish (SnPb) versions are non-standard and special terms and conditions and pricing applies if available. Please contact LTC marketing for information.
- Part numbers containing TR or TRM are shipped in tape and reel or 500 unit mini tape and reel, respectively
- Please refer to our general ordering information or the product datasheet for more details
Package Variations and Pricing
| Part Number | Package | Temp | Price (1-99) |
Price (1k)* |
RoHS | |
|---|---|---|---|---|---|---|
| LTC6951IUHF-1#PBF | 5x7 QFN-40 | I | $12.50 | $8.75 | Yes | |
| LTC6951IUHF-1#TRPBF | 5x7 QFN-40 | I | $12.56 | $8.81 | Yes | |
| LTC6951IUHF#PBF | 5x7 QFN-40 | I | $12.50 | $8.75 | Yes | |
| LTC6951IUHF#TRPBF | 5x7 QFN-40 | I | $12.56 | $8.81 | Yes | |
| Buy Now • Request Samples | ||||||
Demo Boards
Linear Technology offers many demo boards free of charge to qualified customers. Contact your local sales office or distributor to inquire about a demo board. Certain demo boards are also available for sale via credit card on this website. Demo boards are for evaluation purposes only. It remains the customer’s responsibility to verify proper and reliable operation in the actual end application.| Part Number | Description | Price | Documentation |
|---|---|---|---|
| DC2226A-A | 4-Channel 14-bit 250Msps JESD204B ADC with Clocking [Featuring LTC2123, LTC6951] | $300.00 | |
| DC2248A-A | LTC6951 Demo | 5-Output Integer-N PLL with Integrated VCO, Output Range: 1.95MHz to 2.5GHz (requires DC590 or DC2026) | $300.00 | |
| DC2248A-B | LTC6951-1 Demo | 5-Output Integer-N PLL with Integrated VCO, Output Range: 2.1MHz to 2.7GHz (requires DC590 or DC2026) | $300.00 | |
| Buy Now | |||
Companion Boards
| Part Number | Description | Price | Documentation |
|---|---|---|---|
| DC2159A | FMC to USB Adapter to Interface with PScope | $50.00 | |
| DC2430A | DC2430A Linduino SPI 1:8 Expander Demonstration Board (DC2026 Included) | Contact Factory | |
| DC2026C | Linduino One Isolated USB Demo Board: An Arduino- and QuikEval-Compatible Code Development Platform | $75.00 | |
| DC590B | Isolated USB Serial Controller for Linear Technology QuikEval-Compatible Demo Boards | $50.00 | |
| Buy Now | |||
Applications
- High Performance Data Converter Clocking
- Wireless Infrastructure
- Test and Measurement
People Who Viewed This Product Also Viewed
- LTC6957 - Low Phase Noise, Dual Output Buffer/Driver/Logic Converter
- LTC6950 - 1.4GHz Low Phase Noise, Low Jitter PLL with Clock Distribution
- LT3042 - 20V, 200mA, Ultralow Noise, Ultrahigh PSRR RF Linear Regulator
- LTC6946 - Ultralow Noise and Spurious 0.37GHz to 6.39GHz Integer-N Synthesizer with Integrated VCO
- LTC6655 - 0.25ppm Noise, Low Drift Precision References
- LTC2380-24 - 24-Bit, 1.5Msps/2Msps, Low Power SAR ADC with Integrated Digital Filter
- LT5400 - Quad Matched Resistor Network
- LTC6409 - 10GHz GBW, 1.1nV/√Hz Differential Amplifier/ADC Driver
- LTC6948 - Ultralow Noise 0.37GHz to 6.39GHz Fractional-N Synthesizer with Integrated VCO
- LT3080 - Adjustable 1.1A Single Resistor Low Dropout Regulator
Product Notifications
Please login to your MyLinear account for notifications of datasheet updates, new document releases and LTspice model announcements for your favorite products. If you do not have a MyLinear account you may Sign Up Now.
Forgot your password? Click here.
Need help? Email mylinear@linear.com with questions and comments.
Design Tools
LTC6951Wizard
The LTC6951Wizard software provides appropriate LTC6951 PLL settings and loop filter component values with a click of a button, and accurately predicts the individual output’s phase noise and jitter. Besides performance simulation, the LTC6951Wizard GUI features a scope plot that simulates time domain results of the LTC6951 outputs based on the clock divider, delay and synchronization settings, simplifying the design process and assisting in the circuit debugging phase.
The LTC6951Wizard GUI is also used to communicate with the LTC6951 situated on the DC2248, the demo board of the LTC6951. It uses the DC590 (or the DC2026 emulating the DC590) to communicate with the PC.
The following list summarizes its uses:
- Read and write all device registers
- Determine each register’s contents
- Recommend part parameters based on the given frequency plan
- Design noise-optimized loop filters
- Simulate loop frequency response and stability
- Simulate VCO and Reference source noise
- Simulate output noise characteristics and statistics
- Simulate output timing and delays
Linduino
Linduino is an Arduino compatible platform for developing and distributing firmware libraries and code for SPI and I²C-compatible integrated circuits. The Linduino One board interfaces to more than 300 QuikEval demonstration cards, supporting a variety of product types including analog-to-digital converters (ADCs), digital-to-analog converters (DACs), power monitors, and more. Firmware libraries for individual devices are written in C and designed to be portable to a wide variety of processors and microcontrollers. Each library has a demonstration program that can be uploaded to the Linduino One platform to allow the circuit and software to be quickly and easily verified.
Code
Linduino is Linear Technology's Arduino compatible system for developing and distributing firmware libraries and example code for Linear Technology’s integrated circuits. The code below can be downloaded or copied and pasted into your project. Please visit the Linduino Home Page for demo board, manual and setup information.
This part is Code Supported: There is example code available for this part. The code below may rely on other drivers available in the full library.
Download LTC6951 - DC2248A.ino
/*!
DC2248A
LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
@verbatim
Setup:
Set the terminal baud rate to 115200 and select the newline terminator.
Refer to Demo Manual DC2248A.
Ensure all jumpers are installed in the factory default positions.
One Power Supply is needed for this demo board: 6V supply.
Command Description:
1- Load Default Settings from a Look-up Table- Loads the SPI map from one of 10 options in a look-up table.
The look-up table allows the user to select different frequencies and synchronization option. All options
assume a 100MHz reference input and a default DC2248A BOM.
** If you want to use a different loop filter, reference frequency or different
register settings. Please use LTC6951Wizard for the loop filter design and initial
device setup. The register settings from LTC6951Wizard can be entered into menu option 2
or you can change the default registers in the LTC6951_lkup_tbl array. After the
LTC6951Wizard settings are created, export the register settings by selecting
File --> Export Register Settings from the TLC6951Wizard Menu.
2- READ/WRITE to Registers Addresses- Selecting this option will cause all the registers to
be read, stored to variables, and displayed. The user will then have the option
to write to one register address at a time.
3- READ/WRITE to Registers Fields- Selecting this option will allow the user
to read or write to one register field name at a time.
4- This function stores the current SPI settings in the demo boards EEPROM
5- This function loads SPI settings from the demo boards EEPROM to the device
6- Frequency chnage Timing test (SPI write + Calibration + Settling Time):
Provides two frequency settings and allows user to toggle between the two frequencies by
changing the N-divider(ND) value. The user can monitor the STATUS pin. The user
can trigger off the STATUS or CS pins. In most cases the user will want to set the SPI
frequency to 8MHz (see menu option 7)
7- SPI Frequency: Allows user to control Linduino's SPI frequency. By default this is set to 8MHz
when connecting Linduino directly to the DC2248. If Linduino is connected to the DC2430 the default
SPI rate is 4MHz
8- If using a DC2430 (Linduino Expander), this allows the user to select 1 of 8 sites to talk to.
USER INPUT DATA FORMAT:
decimal : 1024
hex : 0x400
octal : 02000 (leading 0 "zero")
binary : B10000000000
float : 1024.0
@endverbatim
http://www.linear.com/product/LTC6951
http://www.linear.com/product/LTC6951#demoboards
REVISION HISTORY
$Revision: 4818 $
$Date: 2016-03-24 11:37:16 -0700 (Thu, 24 Mar 2016) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC6951
*/
#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "LTC6951.h"
#include <SPI.h>
#include <Wire.h>
// Function Declaration
void print_title(); // Print the title block
void print_prompt(); // Print the main menu
void menu_1_load_default_settings(); // Sub-menus
void menu_2_RW_to_reg_addresss();
void menu_3_RW_to_reg_field();
void menu_4_store_settings();
void menu_5_restore_settings();
void menu_6_multibytewrite();
void menu_7_SPI_speed();
void menu_8_DC2430_site_select();
//void DUTsync();
// Global Variables
static int8_t demo_board_connected = 0; //!< Demo Board Name stored in QuikEval EEPROM
static int8_t dc2248_board_connected = 0; //!< Demo Board Name stored in QuikEval EEPROM
uint8_t First_Run=0; //!< if first time through loop = 0, otherwise=1
boolean Using_DC2430= false; //!< Indicator if DC2430 (Linduino Expander) is connected
// Analog Pins used on DC2430 (Linduino Expander)
int dc2430_site_A0_APin =0; //!< DC2430 resistor tree, if it reads 3.3V then DC2430 connected
int dc2430_site_A1_APin =1; //!< DC2430 resistor tree, if it reads 1.66V then DC2430 connected
int dc2430_site_A2_APin =2; //!< DC2430 INFO ONLY, measures DC2226 (Linduino) VCCIO voltage
// Digital Pins used on DC2430 (Linduino Expander)
int dc2430_site_DA0_Pin =2; //!< DC2430 digital pin allows Linduino to control which DC2430 site is selected
int dc2430_site_DA1_Pin =3; //!< DC2430 digital pin allows Linduino to control which DC2430 site is selected
int dc2430_site_DA2_Pin =4; //!< DC2430 digital pin allows Linduino to control which DC2430 site is selected
int dc2430_en_Pin =5; //!< DC2430 digital pin enables Linduino to control which DC2430 site is selected & turns on DC2430 LED
/* ------------------------------------------------------------------------- */
//! Initialize Linduino
//! @return void
void setup()
{
char demo_name[] = "DC2248"; // Demo Board Name stored in QuikEval EEPROM
uint8_t data;
int site_select=0;
int dc2430_A0_val=0;
int dc2430_A1_val=0;
int dc2430_A2_val=0;
float dc2430_A0_fval=0;
float dc2430_A1_fval=0;
float dc2430_A2_fval=0;
Using_DC2430= false;
quikeval_SPI_init(); //! Configure the spi port for 500kHz SCK
quikeval_SPI_connect(); //! Connect SPI to main data port
quikeval_I2C_init(); //! Configure the EEPROM I2C port for 100kHz
Serial.begin(115200); //! Initialize the serial port to the PC
LTC6951_init();
print_title();
//! **************** DETECT IF USING DC2430 SECTION ******************
//! this checks to see if a DC2026 (linduino) to DC2430 (linduino expander)
//! by measuring 3 analog voltages
//! if a DC2430 is connect then read A0, A1 , A2
dc2430_A0_val = analogRead(dc2430_site_A0_APin);
dc2430_A0_fval = (5.0*dc2430_A0_val)/1023;
dc2430_A1_val = analogRead(dc2430_site_A1_APin);
dc2430_A1_fval = (5.0*dc2430_A1_val)/1023;
//! If DC2430 located, auto search site 0 to 7 until a DC2248 is found
if ((dc2430_A0_fval>3.0) && (dc2430_A0_fval<3.6) && (dc2430_A1_fval>1.5) && (dc2430_A1_fval<1.8))
{
Serial.println(F("--- DC2430 Connected ---"));
Using_DC2430= true;
pinMode(dc2430_site_DA0_Pin, OUTPUT);
pinMode(dc2430_site_DA1_Pin, OUTPUT);
pinMode(dc2430_site_DA2_Pin, OUTPUT);
pinMode(dc2430_en_Pin, OUTPUT); // sets the digital pin as output
dc2248_board_connected =0;
demo_board_connected = 0;
digitalWrite(dc2430_en_Pin, HIGH); // sets the LED on
site_select=0;
do
{
dc2430_site_select(site_select);
delay(150); //! probably could be shorter, but this allows the eyes to track which site is being tested
demo_board_connected = discover_demo_board_local(demo_name); //! Checks if any demo board is connected.
if (demo_board_connected)
{
Serial.println(F("\n********************************************************"));
dc2248_board_connected = discover_demo_board(demo_name); //! Checks if correct demo board is connected.
if (dc2248_board_connected)
{
dc2430_A2_val = analogRead(dc2430_site_A2_APin);
dc2430_A2_fval = (5.0*dc2430_A2_val)/1023;
Serial.print(F("Linduino's JP3 VCCIO voltage = "));
Serial.println(dc2430_A2_fval); //! if DC2430 connect, VCCIO voltage set by JP3 on DC2026
spi_enable(SPI_CLOCK_DIV4); //! 1) Configure the spi port for 4MHz SCK
Serial.println(F("Linduino's SPI Frequency = 4MHz, max DC2430 SPI speed"));
Serial.print(F("\nDC2248 FOUND ON DC2430 SITE "));
Serial.println(site_select);
site_select=15;
}
}
if (!dc2248_board_connected)
{
Serial.print(F("\nDC2248 NOT FOUND ON DC2430 SITE "));
Serial.print(site_select);
site_select++;
}
}
while (site_select<8);
//! if no DC2248A was found. Return dc2430_en_Pin to default state (LOW)
if (!dc2248_board_connected)
{
digitalWrite(dc2430_en_Pin, LOW); // sets the LED on
Serial.println(F("\n\nConnect DC2248 demo board to DC2430, then press the reset button."));
}
}
else
{
//! If DC2430 is not located, check to see if Linduino is connected directly to the DC2248
//! most common use case
Serial.println(F("DC2248A CONNECTED TO LINDUINO"));
dc2248_board_connected = discover_demo_board(demo_name); //! Checks if correct demo board is connected.
if (dc2248_board_connected)
{
Serial.println(F("Linduino's SPI Frequency = 8MHz, max speed"));
spi_enable(SPI_CLOCK_DIV2); //! 1) Configure the spi port for 8MHz SCK
}
}
if (dc2248_board_connected)
{
print_prompt();
}
} // end of setup()
/* ------------------------------------------------------------------------- */
//! Repeats Linduino loop
//! @return void
void loop()
{
uint16_t user_command; // User input command
if (Serial.available()) // Check for user input
{
if (First_Run==0)
{
First_Run=1;
}
user_command = read_int(); //! Reads the user command
if (user_command != 'm')
Serial.println(user_command);
switch (user_command) //! Prints the appropriate submenu
{
case 1:
menu_1_load_default_settings();
break;
case 2:
menu_2_RW_to_reg_addresss();
break;
case 3:
menu_3_RW_to_reg_field();
break;
case 4:
menu_4_store_settings();
break;
case 5:
menu_5_restore_settings();
break;
case 6:
menu_6_multibytewrite();
break;
case 7:
menu_7_SPI_speed();
break;
case 8:
menu_8_DC2430_site_select();
break;
default:
Serial.println(F("Incorrect Option"));
break;
} // end of switch statement
Serial.println(F("\n*****************************************************************"));
print_prompt();
} // end of if statement
} // end of loop()
// Function Definitions
/* ------------------------------------------------------------------------- */
//! Menu 1: Load Default SPI Register Settings
//! This function loads the register settings from a look up table.
//! The setting loaded with this function assume the LTC6951's
//! reference is set to 100MHz and the DC2248A's BOM has not been modified.
//! The settings in the look up table were created using the LTC6951Wizard.
//! It is recommended to use the LTC6951Wizard to create the register settings for
//! all desired frequency plans and enter these frequency plans into a look-up table.
//! The LTC6951Wizard generates register values for optimal LTC6951 performance.
//! @return void
void menu_1_load_default_settings()
{
uint8_t field_num;
long field_val;
field_val=999L;
field_num=1;
// Read/Write loop, can exit loop by choosing 'm'
while (field_num != 0)
{
Serial.print(F("\n*****************************************************************"));
Serial.print(F("\n************* Select LTC6951 Configuration *****************"));
Serial.println(F("\n*****************************************************************"));
// Select Fields to read and write to
Serial.print(F("1- OUT[4:0] = 600MHZ, EZSync\n"));
Serial.print(F("2- OUT[4:0] = 600MHZ, EZSync Ref Aligned\n"));
Serial.print(F("3- OUT[4:0] = 600MHZ, EZParallelSync\n"));
Serial.print(F("4- OUT[4:0] = 600MHZ, ParallelSync\n"));
Serial.print(F("5- OUT[3:0] = 2500MHZ, OUT4:625MHz, EZSync\n"));
Serial.print(F("6- OUT[3:0] = 2500MHZ, OUT4:625MHz, EZSync Ref Aligned\n"));
Serial.print(F("7- OUT[3:1] = 2400MHZ, OUT0&OUT4 = 600MHz, EZParallelSync\n"));
Serial.print(F("8- OUT[3:0] = 2500MHZ, OUT4 = 625MHz, ParallelSync\n"));
Serial.print(F("9- OUT[4:0] = Same frequencies as DC2226 U10, JESD204B SC1, ParallelSync\n"));
Serial.print(F("10- OUT[4:0] = Same frequencies as DC2226 U13, JESD204B SC1, ParallelSync\n"));
Serial.println(F("0 - Return to Main Menu\n"));
Serial.println(F("Load LTC6951 register settings from a look up table (Settings created from LTC6951Wizard)"));
Serial.println(F("Enter a command (1-10), or '0' to return to Main Menu): "));
field_num = read_int(); //! Reads the user command
Serial.println(field_num);
// User input: enter new setting for selected register
if (field_num != 0)
{
field_num=field_num-1;
set_LTC6951_REGS_lkup_tbl(field_num);
field_num=field_num+1;
} // end if user_command != 0 statement
} // end while loop
} // end menu_1_load_default_settings function
/* ------------------------------------------------------------------------- */
//! Menu 2: Reads and/or Writes the SPI register address
//! This function reads and displays all SPI register address settings in HEX format.
//! It then provides an option to modify(write to) individual registers one at time
//!
//! EXAMPLE:
//! - 0- ADDR00 = 0x04 (read only)
//! - 1- ADDR01 = 0x04
//! - ....
//! - 21- ADDR15 = 0x04
//! - 22- ADDR16 = 0x65 (read only)
//! - 0 - Return to Main Menu
//! - Enter a command (1-21 to modify register, or '0' to return to Main Menu):
//! @return void
void menu_2_RW_to_reg_addresss()
{
uint8_t i, regval, user_regval, num_reg;
uint16_t user_address; // User input command
num_reg = get_LTC6951_REGSIZE();
user_address=1;
// Read/Write loop, can exit loop by choosing '0'
while (user_address != 0)
{
Serial.println(F("\n*****************************************************************"));
// Read All Registers and display results
for (i=0; i<num_reg; i++)
{
regval = LTC6951_read(LTC6951_CS,i);
Serial.print(i);
if (i<16)
Serial.print(F("- ADDR0"));
else
Serial.print(F("- ADDR"));
Serial.print(i, HEX);
Serial.print(F(" = 0x"));
if (regval<16) Serial.print(F("0"));
Serial.print(regval, HEX);
if (i==3) Serial.print(F(" (warning: if D2=1 it resets all registers. RES6951 Bit)"));
if ((i==0)||(i==(num_reg-1))) Serial.print(F(" (read only) "));
Serial.println("");
} // end for loop
Serial.print(F("0 - Return to Main Menu\n\n"));
// User input: Select which register to modify, or return to main menu
Serial.print(F("Enter a command (1-19 to modify register, or '0' to return to Main Menu): "));
user_address = read_int(); //! Reads the user command
Serial.println(user_address);
// User input: enter new setting for selected register
if (user_address >0 && user_address<(num_reg-1))
{
Serial.print(F("What value should ADDR"));
Serial.print(user_address);
Serial.print(F(" be set to (ex: HEX format 0xff): "));
user_regval = read_int(); //! Reads the user command
Serial.println(user_regval);
// writes new setting to part
LTC6951_write(LTC6951_CS, (uint8_t)user_address, user_regval);
} // end if statement
} // end while loop
} // end menu_2_RW_to_reg_addresss
/* ------------------------------------------------------------------------- */
//! Support function for function menu_3_RW_to_reg_field
//! displays current state of select field
//! provides user the option to write to that field or return to menu
//! @return field value (user input) that will be written to part
long field_menu_RW(long field_val, //!< current state of the selected field
char field_name[], //!< SPI Field name selected
uint8_t f //!< SPI field identifier identifies selected fields information in SPI MAP arrays
)
{
long usr_field_val;
uint8_t field_size, i;
long max_num=1, pow2=1;
Serial.print("CURRENT STATE (HEX): ");
Serial.print(field_name);
Serial.print("= 0x");
Serial.println(field_val, HEX);
if (get_LTC6951_SPI_FIELD_RW(f)==0)
{
field_size=get_LTC6951_SPI_FIELD_NUMBITS(f);
for (i=1; i<field_size; i++)
{
pow2=pow2*2;
max_num=max_num + pow2;
}
Serial.print("What value should ");
Serial.print(field_name);
Serial.print(" be set to or type '-1' to exit: (ex: HEX format 0x00 to 0x");
Serial.print(max_num, HEX);
Serial.print(")");
usr_field_val = read_int(); //! Reads the user command
if (usr_field_val>=0 && usr_field_val<=max_num)
{
Serial.println(usr_field_val);
return usr_field_val;
}
else
{
return field_val;
} // end of if statement
} // end of if statement
} // end of field_menu_RW
/* ------------------------------------------------------------------------- */
//! Menu 3: Reads and/or Writes individual SPI fields
//! This function provides the user with a list of all SPI fields.
//! The user can select a SPI field to read its current value.
//! Then the user will be provided with an option to write to that field
//! or return to the selection menu.
//!
//! EXAMPLE:
//! - 1-ALCCAL 25-LKWIN 49-PART *
//! - 2-ALCEN 26-LOCK * 50-PD
//! - ....
//! - 21-DLY4 45-OINV1 69-SYNCEN4
//! - 23-INVSTAT 47-OINV3 71-x
//! - 24-LKCT 48-OINV4
//! - 0 - Return to Main Menu
//! - * = READ ONLY FIELD
//! - Enter a command (1-71 to modify register, or '0' to return to Main Menu):
//! @return void
void menu_3_RW_to_reg_field()
{
uint8_t field_num;
long field_val;
field_val=999L;
field_num=1;
// Read/Write loop, can exit loop by choosing 'm'
while (field_num != 0)
{
Serial.println(F("\n*****************************************************************"));
// Select Fields to read and write to
Serial.print(F("1-ALCCAL 25-LKWIN 49-PART *\n"));
Serial.print(F("2-ALCEN 26-LOCK * 50-PD\n"));
Serial.print(F("3-ALCHI * 27-!LOCK * 51-PDALL\n"));
Serial.print(F("4-ALCLO * 28-MCO 52-PDOUT\n"));
Serial.print(F("5-ALCMON 29-MC1 53-PDPLL\n"));
Serial.print(F("6-ALCULOK 30-MC2 54-PDREFPK\n"));
Serial.print(F("7-AUTOCAL 31-MC3 55-PDVCO\n"));
Serial.print(F("8-BD 32-MC4 56-POR\n"));
Serial.print(F("9-BST 33-MD0 57-RAO\n"));
Serial.print(F("10-CAL 34-MD1 58-RD\n"));
Serial.print(F("11-CP 35-MD2 59-REFOK *\n"));
Serial.print(F("12-CPDN 36-MD3 60-!REFOK *\n"));
Serial.print(F("13-CPMID 37-MD4 61-REV *\n"));
Serial.print(F("14-CPRST 38-MUTE0 62-SN\n"));
Serial.print(F("15-CPUP 39-MUTE1 63-SR\n"));
Serial.print(F("16-CPWIDE 40-MUTE2 64-SSYNC\n"));
Serial.print(F("17-DLY0 41-MUTE3 65-SYNCEN0\n"));
Serial.print(F("18-DLY1 42-MUTE4 66-SYNCEN1\n"));
Serial.print(F("19-DLY2 43-ND 67-SYNCEN2\n"));
Serial.print(F("20-DLY3 44-OINV0 68-SYNCEN3\n"));
Serial.print(F("21-DLY4 45-OINV1 69-SYNCEN4\n"));
Serial.print(F("22-FILT 46-OINV2 70-UNLOCK *\n"));
Serial.print(F("23-INVSTAT 47-OINV3 71-x\n"));
Serial.print(F("24-LKCT 48-OINV4 \n"));
Serial.print(F("0 - Return to Main Menu\n"));
Serial.print(F("* = READ ONLY FIELD\n\n"));
Serial.print(F("Enter a command (1-71 to modify register, or '0' to return to Main Menu): "));
field_num = read_int(); //! Reads the user command
Serial.println(field_num);
// User input: enter new setting for selected register
if (field_num != 0)
{
switch (field_num) //! Prints the appropriate submenu
{
default:
field_val=get_LTC6951_SPI_FIELD(LTC6951_CS,field_num); // reads selected field
field_val=field_menu_RW(field_val," ",field_num); // user interface control and printout
if (field_val>-1)
{
set_LTC6951_SPI_FIELD(LTC6951_CS, field_num, field_val); // updates selected field
}
break;
} // end of switch statement
} // end if user_command != 0 statement
} // end while loop
} // end menu_3_RW_to_reg_field function
/* ------------------------------------------------------------------------- */
//! Store PLL settings to nonvolatile EEPROM on demo board
//! @return void
void menu_4_store_settings()
{
// Store the PLL Settings to the EEPROM
uint8_t regval;
uint8_t addr_offset;
uint8_t num_reg;
addr_offset=2;
num_reg = get_LTC6951_REGSIZE();
eeprom_write_int16(EEPROM_I2C_ADDRESS, EEPROM_CAL_KEY, EEPROM_CAL_STATUS_ADDRESS); // Cal key
for (uint8_t i = 0; i <= num_reg ; i++)
{
regval = LTC6951_read(LTC6951_CS,i);
eeprom_write_byte(EEPROM_I2C_ADDRESS,(char) regval, EEPROM_CAL_STATUS_ADDRESS+ i+addr_offset);
}
Serial.println(F("PLL Settings Stored to EEPROM"));
}
/* ------------------------------------------------------------------------- */
//! Read stored PLL settings from nonvolatile EEPROM on demo board
//! @return void
void menu_5_restore_settings()
{
// Read the PLL settings from EEPROM
int16_t cal_key;
uint8_t regval;
uint8_t user_address;
uint8_t addr_offset;
uint8_t num_reg;
long field_val;
uint8_t field_num;
addr_offset=2;
num_reg = get_LTC6951_REGSIZE();
// read the cal key from the EEPROM
eeprom_read_int16(EEPROM_I2C_ADDRESS, &cal_key, EEPROM_CAL_STATUS_ADDRESS);
if (cal_key == EEPROM_CAL_KEY)
{
// PLL Settings has been stored, read PLL Settings
user_address=2;
for (uint8_t i = 0; i <= num_reg ; i++)
{
eeprom_read_byte(EEPROM_I2C_ADDRESS,(char *) ®val, EEPROM_CAL_STATUS_ADDRESS + i+addr_offset);
LTC6951_write(LTC6951_CS, (uint8_t)i, regval);
user_address++;
}
Serial.println(F("LTC6951 Settings Restored"));
Serial.println(F("Calibrate LTC6951 VCO"));
set_LTC6951_SPI_FIELD(LTC6951_CS, LTC6951_CAL, 1L);
delay(1); // Calibrations typically ~50us long, CAL bit clears automatically
Serial.println(F("Syncs LTC6951 OUTPUTS"));
DUTsync(1);
}
else
{
Serial.println(F("PLL Settings not found"));
}
}
/* ------------------------------------------------------------------------- */
//! Syncs LTC6951 Outputs using SSYNC bit
//! @return void
void DUTsync(uint16_t delay_num)
{
set_LTC6951_SPI_FIELD(LTC6951_CS, LTC6951_SSYNC, 1L);
delay(1);
set_LTC6951_SPI_FIELD(LTC6951_CS, LTC6951_SSYNC, 0L);
delay(delay_num);
}
/* ------------------------------------------------------------------------- */
//! Frequency change Timing test (SPI write + Calibration + Settling Time):
//! Provides two frequency settings and allows user to toggle between the two frequencies by
//! changing the N-divider(ND) value. The user can monitor the STATUS pin. The user
//! can trigger off the STATUS or CS pins. In most cases the user will want to set the SPI
//! frequency to 8MHz (see menu option 7)
//! @return void
void menu_6_multibytewrite()
{
uint8_t init_setup;
uint8_t lkup_tbl_row; // User input command
lkup_tbl_row=1;
init_setup=1;
// Read/Write loop, can exit loop by choosing '0'
while (lkup_tbl_row != 0)
{
Serial.println(F("\n*****************************************************************"));
Serial.println(F("This option is good for measuring calibration and settling time"));
Serial.println(F("It allows one to hop back and forth between 2 frequencies"));
Serial.println(F("For different frequencies - modify the lookup table in function"));
Serial.println(F("Fset_LTC6951_REGS_freq_jump. LTC6951Wizard exports register settings"));
Serial.println(F("in the correct format for an easy modification"));
Serial.println(F("For best timing results, set the SPI clock frequency to 8MHz (main menu: option 7)"));
// Read All Registers and display results
Serial.println(F("1 - Frequency 1: 600MHz"));
Serial.println(F("2 - Frequency 2: 550MHz\n"));
Serial.print(F("0 - Return to Main Menu\n\n"));
Serial.print(F("Select an Option (0,1, or 2) : "));
lkup_tbl_row = read_int(); //! Reads the user command
Serial.println(lkup_tbl_row);
if ((lkup_tbl_row >2)|| (lkup_tbl_row <0))
{
Serial.println(F("Not an option - try again"));
}
else if (lkup_tbl_row == 0)
{
// do nothing
}
else
{
set_LTC6951_REGS_freq_jump((lkup_tbl_row-1), init_setup);
init_setup=0;
}
} // end while loop
}
/* ------------------------------------------------------------------------- */
//! Read stored PLL settings from nonvolatile EEPROM on demo board
//! @return void
void menu_7_SPI_speed()
{
int temp_val;
Serial.println(F("\nCommand Summary:"));
if (Using_DC2430)
{
Serial.println(F(" 1-8MHz NOT Available with DC2430"));
}
else
{
Serial.println(F(" 1-SPI Clock = 8MHz"));
}
Serial.println(F(" 2-SPI Clock = 4MHz"));
Serial.println(F(" 3-SPI Clock = 2MHz"));
Serial.println(F(" 4-SPI Clock = 1MHz"));
Serial.println(F(" 5-SPI Clock = 500kHz"));
Serial.println("");
Serial.print(F("Enter a command: "));
temp_val = read_int(); //! Reads the user command
switch (temp_val) //! Prints the appropriate submenu
{
case 1:
if (Using_DC2430)
{
Serial.println(F("incorrect option"));
}
else
{
spi_enable(SPI_CLOCK_DIV2); //! 1) Configure the spi port for 8MHz SCK
}
break;
case 2:
spi_enable(SPI_CLOCK_DIV4); //! 1) Configure the spi port for 4MHz SCK
break;
case 3:
spi_enable(SPI_CLOCK_DIV8); //! 1) Configure the spi port for 2MHz SCK
break;
case 4:
spi_enable(SPI_CLOCK_DIV16); //! 1) Configure the spi port for 1MHz SCK
break;
case 5:
spi_enable(SPI_CLOCK_DIV32); //! 1) Configure the spi port for 500kHz SCK
break;
default:
Serial.println(F("Incorrect Option"));
break;
}
}
/* ------------------------------------------------------------------------- */
//! Read stored PLL settings from nonvolatile EEPROM on demo board
//! @return void
void menu_8_DC2430_site_select()
{
int temp_val;
char demo_name[] = "DC2248"; // Demo Board Name stored in QuikEval EEPROM
Serial.println(F("\nCommand Summary:"));
Serial.println(F(" 0-Site 0"));
Serial.println(F(" 1-Site 1"));
Serial.println(F(" 2-Site 2"));
Serial.println(F(" 3-Site 3"));
Serial.println(F(" 4-Site 4"));
Serial.println(F(" 5-Site 5"));
Serial.println(F(" 6-Site 6"));
Serial.println(F(" 7-Site 7"));
Serial.println("");
Serial.print(F("Enter a command: "));
temp_val = read_int(); //! Reads the user command
dc2430_site_select(temp_val);
demo_board_connected=0;
dc2248_board_connected=0;
demo_board_connected = discover_demo_board_local(demo_name); //! Checks if any demo board is connected.
if (demo_board_connected)
{
Serial.println(F("\n********************************************************"));
dc2248_board_connected = discover_demo_board(demo_name); //! Checks if correct demo board is connected.
}
if (!dc2248_board_connected)
{
Serial.print(F("\nDC2248 NOT FOUND ON DC2430 SITE "));
Serial.print(temp_val);
}
}
/* ------------------------------------------------------------------------- */
//! Called from function menu_8_DC2430_site_select(), programs DC2430 to site selected
//! @return void
void dc2430_site_select(int site_select)
{
switch (site_select) //! Prints the appropriate submenu
{
case 0:
digitalWrite(dc2430_site_DA0_Pin, LOW);
digitalWrite(dc2430_site_DA1_Pin, LOW);
digitalWrite(dc2430_site_DA2_Pin, LOW);
break;
case 1:
digitalWrite(dc2430_site_DA0_Pin, HIGH);
digitalWrite(dc2430_site_DA1_Pin, LOW);
digitalWrite(dc2430_site_DA2_Pin, LOW);
break;
case 2:
digitalWrite(dc2430_site_DA0_Pin, LOW);
digitalWrite(dc2430_site_DA1_Pin, HIGH);
digitalWrite(dc2430_site_DA2_Pin, LOW);
break;
case 3:
digitalWrite(dc2430_site_DA0_Pin, HIGH);
digitalWrite(dc2430_site_DA1_Pin, HIGH);
digitalWrite(dc2430_site_DA2_Pin, LOW);
break;
case 4:
digitalWrite(dc2430_site_DA0_Pin, LOW);
digitalWrite(dc2430_site_DA1_Pin, LOW);
digitalWrite(dc2430_site_DA2_Pin, HIGH);
break;
case 5:
digitalWrite(dc2430_site_DA0_Pin, HIGH);
digitalWrite(dc2430_site_DA1_Pin, LOW);
digitalWrite(dc2430_site_DA2_Pin, HIGH);
break;
case 6:
digitalWrite(dc2430_site_DA0_Pin, LOW);
digitalWrite(dc2430_site_DA1_Pin, HIGH);
digitalWrite(dc2430_site_DA2_Pin, HIGH);
break;
case 7:
digitalWrite(dc2430_site_DA0_Pin, HIGH);
digitalWrite(dc2430_site_DA1_Pin, HIGH);
digitalWrite(dc2430_site_DA2_Pin, HIGH);
break;
default:
Serial.println(F("Incorrect Option"));
break;
}
}
/* ------------------------------------------------------------------------- */
//! Prints the title block when program first starts.
void print_title()
{
Serial.println(F("\n****************************************************************************************************"));
Serial.println(F("* DC2248 Demonstration Program *"));
Serial.println(F("* - Input Voltage 6V-20V (J15/J16) *"));
Serial.println(F("* *"));
Serial.println(F("* This program demonstrates how to send data to the LTC6951 Ultralow Jitter *"));
Serial.println(F("* Multi-Output Clock Synthesizer with Integrated VCO. *"));
Serial.println(F("* *"));
Serial.println(F("* Set the baud rate to 115200 and select the newline terminator. *"));
Serial.println(F("* *"));
Serial.println(F("* Recommendations on how to best use LTC6951Wizard and DC2248 Linduino code together *"));
Serial.println(F("* Use LTC6951Wizard to *"));
Serial.println(F("* - determine best SPI register values for specific frequenices and Sync Methods for all settings *"));
Serial.println(F("* - determine loop filter value *"));
Serial.println(F("* - Simulate LTC6951 Phase noise and Time Domain response *"));
Serial.println(F("* - initial engineering evaluation *"));
Serial.println(F("* Use DC2248 Linduino code *"));
Serial.println(F("* - Create a look up table of the SPI register values created from LTC6951Wizard (option 1) *"));
Serial.println(F("* - Software development for reading and writing to specific register/address (option 2 & 3) *"));
Serial.println(F("* - Storing demo board settings on the demo board EEPROM *"));
Serial.println(F("* - test that require a fast SPI clocks up to 8MHz, (i.e. settling time) *"));
Serial.println(F("* - starting place to use the DC2248 with the DC2430 *"));
Serial.println(F("****************************************************************************************************"));
Serial.println();
} // end of print_title
/* ------------------------------------------------------------------------- */
//! Prints main menu.
void print_prompt()
{
Serial.println(F("\nCommand Summary:"));
Serial.println(F(" 1-Load Default Settings from a Look-up Table"));
Serial.println(F(" 2-READ/WRITE to Registers Addresses"));
Serial.println(F(" 3-READ/WRITE to Registers Fields"));
Serial.println(F(" 4-Store LTC6951 SPI settings to the DC2248's EEPROM"));
Serial.println(F(" 5-Restore LTC6951 SPI settings from the DC2248's EEPROM"));
Serial.println(F(" 6-Timing Measurement Aid: SPI WRITE + CALIBRAION + SETTLING TIME"));
Serial.println(F(" 7-Adjust SPI frequency"));
if (Using_DC2430)
{
Serial.println(F(" 8-DC2430 Site Selector"));
}
Serial.println("");
Serial.print(F("Enter a command: "));
} // end of print_prompt
Download LTC6951 - Linduino Header File
/*!
LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
@verbatim
SPI DATA FORMAT (MSB First):
Write Sequence:
Byte #1 Byte #2
MOSI: A6 A5 A4 A3 A2 A1 A0 W D7 D6 D5 D4 D3 D2 D1 D0
MISO: X X X X X X X X X X X X X X X X
Read Sequence:
Byte #1 Byte #2
MOSI: A6 A5 A4 A3 A2 A1 A0 R X X X X X X X X
MISO: X X X X X X X X D7 D6 D5 D4 D3 D2 D1 D0
W : SPI Write (0)
R : SPI Read (1)
Ax : Address
Dx : Data Bits
X : Don't care
@endverbatim
http://www.linear.com/product/LTC6951
http://www.linear.com/product/LTC6951#demoboards
REVISION HISTORY
$Revision: 4818 $
$Date: 2016-03-24 11:37:16 -0700 (Thu, 24 Mar 2016) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC6951
Header for LTC6951: Ultra-Low Jitter 2MHz to 2.5GHz Multi-Output Clock Synthesizer with Integrated VCO
*/
#ifndef LTC6951_H
#define LTC6951_H
//! Define the SPI CS pin
#ifndef LTC6951_CS
#define LTC6951_CS QUIKEVAL_CS //! SPI Chip Select Pin
#endif
/*! @name LTC6951 Registers Fields in Alphabetical Order */
#define LTC6951_ALCCAL 1 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_ALCEN 2 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_ALCHI 3 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_ALCLO 4 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_ALCMON 5 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_ALCULOK 6 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_AUTOCAL 7 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_BD 8 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_BST 9 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_CAL 10 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_CP 11 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_CPDN 12 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_CPMID 13 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_CPRST 14 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_CPUP 15 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_CPWIDE 16 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_DLY0 17 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_DLY1 18 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_DLY2 19 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_DLY3 20 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_DLY4 21 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_FILT 22 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_INVSTAT 23 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_LKCT 24 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_LKWIN 25 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_LOCK 26 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_NLOCK 27 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MCO 28 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MC1 29 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MC2 30 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MC3 31 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MC4 32 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MD0 33 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MD1 34 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MD2 35 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MD3 36 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MD4 37 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MUTE0 38 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MUTE1 39 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MUTE2 40 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MUTE3 41 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_MUTE4 42 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_ND 43 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_OINV0 44 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_OINV1 45 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_OINV2 46 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_OINV3 47 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_OINV4 48 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_PART 49 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_PD 50 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_PDALL 51 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_PDOUT 52 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_PDPLL 53 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_PDREFPK 54 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_PDVCO 55 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_POR 56 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_RAO 57 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_RD 58 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_REFOK 59 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_NREFOK 60 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_REV 61 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SN 62 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SR 63 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SSYNC 64 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SYNCEN0 65 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SYNCEN1 66 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SYNCEN2 67 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SYNCEN3 68 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_SYNCEN4 69 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_UNLOCK 70 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_x 71 //!< for spi_map array, defines location for field specific information used to create the spi map
#define LTC6951_NUM_REGADDR 20 //!< Defines number of LTC6951 SPI registers, used in spi_map array
#define LTC6951_NUM_REGFIELD 71 //!< Defines number of LTC6951 SPI fields, used in spi_map array
#define ADDRx 0 //!< used for 2nd dim of 2d spi_map array
#define DxMSB 1 //!< used for 2nd dim of 2d spi_map array
#define NUMBITS 2 //!< used for 2nd dim of 2d spi_map array
#define R_ONLY 3 //!< used for 2nd dim of 2d spi_map array
//! @} */
/* ------------------------------------------------------------------------- */
//! LTC6951 Read Single Address
//! reads 8 bit Data field to LTC6951.
//! has to shift data by one bit to account for RW bit
//! @return data that was read from address
uint8_t LTC6951_read(uint8_t cs, //!< Chip Select Pin
int8_t address //!< Register address for the LTC6951.
);
/* ------------------------------------------------------------------------- */
//! LTC6951 Read Single Field
//! For SPI FIELDS located in 1 or multiple address location
//! reads specific address locations
//! identifies and returns specific field in question
//! can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
//! @return data that was read from field
long LTC6951_read_field(uint8_t cs, //!< Chip Select Pin
uint8_t address, //!< Register address for the LTC6951.
uint8_t MSB_loc, //!< MSB bit location of field
uint8_t numbits //!< length of field (i.e. number of bits in field)
);
/* ------------------------------------------------------------------------- */
//! Gets the LTC6951 SPI field value
//! calls function LTC6951_read_field, which
//! reads specific address locations
//! identifies and returns specific field in question
//! can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
//! @return data that was read from field
long get_LTC6951_SPI_FIELD(uint8_t cs, //!< Chip Select Pin
uint8_t f //!< SPI field number
);
/* ------------------------------------------------------------------------- */
//! LTC6951 Write Single Address
//! writes 8 bit Data field to LTC6951.
//! has to shift data by one bit to account for RW bit
//! @return void
void LTC6951_write(uint8_t cs, //!< Chip Select Pin
uint8_t address, //!< Register address for the LTC6951.
uint8_t Data //!< 8-bit data to be written to register
);
/* ------------------------------------------------------------------------- */
//! LTC6951 Write Single Field
//! For SPI FIELDS in 1 or multiple address locations
//! reads specific address/field location then writes to specific field
//! can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
//! @return void
uint8_t LTC6951_write_field(uint8_t cs, //!< Chip Select Pin
long field_data, //!< Value field value to be set to
uint8_t address, //!< Register address for the LTC6951.
uint8_t MSB_loc, //!< MSB bit location of field
uint8_t numbits //!< length of field (i.e. number of bits in field)
);
/* ------------------------------------------------------------------------- */
//! Sets the LTC6951 SPI field value
//! calls function LTC6951_read_field, which
//! reads specific address/field location then writes to specific field
//! can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
//! @return void
void set_LTC6951_SPI_FIELD(uint8_t cs, //!< Chip Select Pin
uint8_t f, //!< SPI field number
long field_data //!< Value field value to be set to
);
/* ------------------------------------------------------------------------- */
//! Writes values to ALL LTC6951 RW addresses
//! @return void
void set_LTC6951_ALLREGS(uint8_t cs, //!< Chip Select Pin
uint8_t reg01, //!< LTC6951 register 1
uint8_t reg02, //!< LTC6951 register 2
uint8_t reg03, //!< LTC6951 register 3
uint8_t reg04, //!< LTC6951 register 4
uint8_t reg05, //!< LTC6951 register 5
uint8_t reg06, //!< LTC6951 register 6
uint8_t reg07, //!< LTC6951 register 7
uint8_t reg08, //!< LTC6951 register 8
uint8_t reg09, //!< LTC6951 register 9
uint8_t reg0A, //!< LTC6951 register 10
uint8_t reg0B, //!< LTC6951 register 11
uint8_t reg0C, //!< LTC6951 register 12
uint8_t reg0D, //!< LTC6951 register 13
uint8_t reg0E, //!< LTC6951 register 14
uint8_t reg0F, //!< LTC6951 register 15
uint8_t reg10, //!< LTC6951 register 16
uint8_t reg11, //!< LTC6951 register 17
uint8_t reg12 //!< LTC6951 register 18
);
/* ------------------------------------------------------------------------- */
//! Writes values to ALL LTC6951 RW addresses from a look-up table
//! - uses the Multi-byte write option for more efficient data transfer
//! - Calibrates VCO based on RAO and Autocal bit vales
//! - Either SPI Syncs or recommends the use to SYNC pin based on RAO, SN and SR values
//! @return void
void set_LTC6951_REGS_lkup_tbl(uint8_t lkup_tbl_row //!< Any number 0-9, lookup table has 10 options
);
/* ------------------------------------------------------------------------- */
//! This function toggles between two frequencies
//! - if measuring calibration or settling times set SPI clock to max SPI rate (8MHz)
//! - writes LTC6951 registers from a local look up table
//! - uses the Multi-byte write option for more efficient data transfer
//! - Calibrates VCO based on RAO and Autocal bit vales
//! - DOES NOT SYNC OUTPUTS
//! - RECOMMENDATION: If measuring settling times with E5052, NOT MUTING OUTPUT DURING CAL can provide more meaningful results
//! @return void
void set_LTC6951_REGS_freq_jump(uint8_t lkup_tbl_row, //!< Can be 0 or 1
uint8_t init_setup //!< 0 = not first setup, 1= first setup
);
/* ------------------------------------------------------------------------- */
//! Initializes the SPI MAP arrays
//! The values set in initialization are used for all the LTC6951 SPI/WRITE and
//! read functions (set_LTC6951_SPI_FIELD, get_LTC6951_SPI_FIELD,
//! LTC6951_read, LTC6951_write, etc, etc)
//! @return void
void LTC6951_init();
/* ------------------------------------------------------------------------- */
//! returns # of addresses in parts register map (array size)
//! @return # of addresses in parts register map
uint8_t get_LTC6951_REGSIZE();
/* ------------------------------------------------------------------------- */
//! returns the number of bits for a given field name in the SPI map
//! @return the number of bits for a given field name in the SPI map
uint8_t get_LTC6951_SPI_FIELD_NUMBITS(uint8_t f //!< SPI field number
);
/* ------------------------------------------------------------------------- */
//! returns if the given field name is (0)read/write or (1)read_only field
//! @return if the given field is a (0)read/write or (1)read_only field
uint8_t get_LTC6951_SPI_FIELD_RW(uint8_t f //!< SPI field number
) ;
/* ------------------------------------------------------------------------- */
//! Read the ID string from the EEPROM and determine if any demo board is connected.
//! Returns 1 if successful, 0 if not successful
int8_t discover_demo_board_local(char *demo_name
);
#endif // LTC6951_H
Download LTC6951 - Linduino.CPP File
/*!
LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
@verbatim
The LTC®6951 is a high performance, low noise, Phase
Locked Loop (PLL) with a fully integrated VCO. The low
noise VCO uses no external components and is internally
calibrated to the correct output frequency with no external
system support.
The clock generation section provides five outputs based
on the VCO prescaler signal with individual dividers for
each output. Four outputs feature very low noise, low skew
CML logic. The fifth output is low noise LVDS. All outputs
can be synchronized and set to precise phase alignment
using the programmable delays.
Choose the LTC6951-1 if any desired output frequency
falls in the ranges 2.5GHz to 2.7GHz, 1.66GHz to 1.8GHz,
or 1.25GHz to 1.35GHz. Choose the LTC6951 for all other
frequencies.
@endverbatim
http://www.linear.com/product/LTC6951
http://www.linear.com/product/LTC6951#demoboards
REVISION HISTORY
$Revision: 4818 $
$Date: 2016-03-24 11:37:16 -0700 (Thu, 24 Mar 2016) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
//! @defgroup LTC6951 LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
/*! @file
@ingroup LTC6951
Library for LTC6951: Ultra-Low Jitter 2MHz to 2.7GHz Multi-Output Clock Synthesizer with Integrated VCO
*/
#include <stdint.h>
#include <Arduino.h>
#include "Linduino.h"
#include "UserInterface.h"
#include "LT_SPI.h"
#include "LTC6951.h"
#include "QuikEval_EEPROM.h"
#include <SPI.h>
uint8_t LTC6951_reg[LTC6951_NUM_REGADDR]; //!< number of LTC6951 spi addresses
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
uint8_t LTC6951_lkup_tbl[10][LTC6951_NUM_REGADDR] = //!< the following settings assume a 100MHz reference input
{
{0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x30, 0x07, 0x00, 0x92, 0x00, 0x92, 0x00, 0x92, 0x00, 0x92, 0x00, 0x92, 0x00, 0x11}, //!< ALL CHAN 600MHZ, EZSync
{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
{0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x12, 0x00, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x11}, //!< ALL CHAN 600MHZ, EZParallelSync
{0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x12, 0xc0, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x92, 0x06, 0x11}, //!< ALL CHAN 600MHZ, ParallelSync
{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
{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
{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
{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
{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
{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
}; //!< LTC6951 Configuration look-up table
/* -------------------------------------------------------------------------
FUNCTION: LTC6951_read
- reads 8 bit Data field to LTC6951.
- has to shift data by one bit to account for RW bit
-------------------------------------------------------------------------- */
uint8_t LTC6951_read(uint8_t cs, int8_t address)
{
int8_t address_shift;
LT_union_int16_2bytes rx;
address_shift =(address << 1) | 0x01; // shift to left to account for R/W bit, set bit high for read
spi_transfer_word(cs, address_shift<<8 , &rx.LT_uint16);
LTC6951_reg[address]=rx.LT_byte[0];
return(rx.LT_byte[0]);
}
/* -------------------------------------------------------------------------
FUNCTION: LTC6951_read_field
For SPI FIELDS located in 1 or multiple address location
- reads specific address locations
- identifies and returns specific field in question
- can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
--------------------------------------------------------------------------- */
long LTC6951_read_field(uint8_t cs, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
{
int bit_shift, i, num_reg;
long field_val, maskbits, pow2;
num_reg=0;
field_val=0;
// determines how many register are used
do
{
bit_shift = (MSB_loc+1)- (numbits-num_reg*8); // determines bit_shift for last register location
field_val=LTC6951_read(cs, (address+num_reg))+(field_val<<8); // reads current address locations, shifts previous address location 8 bits
num_reg++;
}
while ((bit_shift<0) && (num_reg<4));
// creates a bit mask for complete word,
maskbits = 1;
pow2=1;
for (i=1, maskbits=1; i<numbits; i++)
{
pow2=pow2*2;
maskbits = maskbits+pow2;
}
field_val=(field_val >>bit_shift) &maskbits;
return field_val;
}
/* -------------------------------------------------------------------------
FUNCTION: get_LTC6951_SPI_FIELD
For SPI FIELDS
- reads specific address locations
- identifies and returns specific field in question
- can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
--------------------------------------------------------------------------- */
long get_LTC6951_SPI_FIELD(uint8_t cs, uint8_t f)
{
return LTC6951_read_field(cs, LTC6951_spi_map[f][ADDRx], LTC6951_spi_map[f][DxMSB], LTC6951_spi_map[f][NUMBITS]);
}
/* -------------------------------------------------------------------------
FUNCTION: LTC6951_write
- writes 8 bit Data field to LTC6951.
- has to shift data by one bit to account for RW bit
--------------------------------------------------------------------------- */
void LTC6951_write(uint8_t cs, uint8_t address, uint8_t Data)
{
LT_union_int16_2bytes rx;
address=address << 1; // shift to left to account for R/W bit
spi_transfer_word(cs, (address<<8) | Data, &rx.LT_uint16);
}
/* -------------------------------------------------------------------------
FUNCTION: LTC6951_write_field
For SPI FIELDS
- reads specific address location
- identifies and returns specific field in question
- can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
---------------------------------------------------------------------------- */
uint8_t LTC6951_write_field(uint8_t cs, long field_data, uint8_t address, uint8_t MSB_loc, uint8_t numbits)
{
long current_content, desired_content, reg_val;
int LSB_loc, i, j, num_reg, bit_shift;
long temp_arr[32];
for (i=0; i<32 ; i++) temp_arr[i]=0; // init temp_arr
// read data in current address location and put in a bit array
num_reg=0;
current_content=0;
do
{
bit_shift=(MSB_loc+1)-(numbits-num_reg*8);
current_content=LTC6951_read(cs, (address+num_reg)) + (current_content<<8);
num_reg++;
}
while ((bit_shift<0) && (num_reg<4));
for (i=0; i<(8*num_reg); i++)
{
temp_arr[i]=(current_content>>i) & 1;
}
// exchange current bits with desired bits
LSB_loc = 8*(num_reg-1)+MSB_loc-numbits+1;
for (i=LSB_loc, j=0; i<=(MSB_loc+(num_reg-1)*8); i++, j++)
{
temp_arr[i] = (field_data>>j) &1;
} // end of for loop
// reconstruct bits into an integer
desired_content = 0;
for (i=0; i<(8*num_reg); i++)
{
desired_content = desired_content | (temp_arr[i]<<i);
} // end of for loop
// write new field value to part
for (i=0; i<num_reg; i++)
{
reg_val = (desired_content >> 8*(num_reg-1-i)) & 0xff;
LTC6951_write(cs, (address+i), reg_val);
} // end of for loop
} // end of LTC6951_write_field
/* -------------------------------------------------------------------------
FUNCTION: get_LTC6951_REGSIZE
- returns # of addresses in parts register map (array size)
---------------------------------------------------------------------------- */
uint8_t get_LTC6951_REGSIZE()
{
return sizeof(LTC6951_reg);
}
/* -------------------------------------------------------------------------
FUNCTION: get_LTC6951_SPI_FIELD_NUMBITS
- returns the number of bits for a given field name in the SPI map
---------------------------------------------------------------------------- */
uint8_t get_LTC6951_SPI_FIELD_NUMBITS(uint8_t f)
{
return LTC6951_spi_map[f][NUMBITS];
}
/* -------------------------------------------------------------------------
FUNCTION: get_LTC6951_SPI_FIELD_RW
- returns if the given field name is (0)read/write or (1)read_only field
---------------------------------------------------------------------------- */
uint8_t get_LTC6951_SPI_FIELD_RW(uint8_t f)
{
return LTC6951_spi_map[f][R_ONLY];
}
/* -------------------------------------------------------------------------
FUNCTION: set_LTC6951_SPI_FIELD
For SPI FIELDS
- reads specific address location
- identifies and returns specific field in question
- can handle SPI fields in multiple addresses, if MSB bit is in the lower number address
---------------------------------------------------------------------------- */
void set_LTC6951_SPI_FIELD(uint8_t cs, uint8_t f, long field_data)
{
LTC6951_write_field(cs, field_data, LTC6951_spi_map[f][ADDRx], LTC6951_spi_map[f][DxMSB], LTC6951_spi_map[f][NUMBITS]);
}
/* -------------------------------------------------------------------------
FUNCTION: set_LTC6951_ALLREGS
- writes data to all registers at once
--------------------------------------------------------------------------- */
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)
{
uint8_t i;
LTC6951_reg[1] = reg01;
LTC6951_reg[2] = reg02;
LTC6951_reg[3] = reg03;
LTC6951_reg[4] = reg04;
LTC6951_reg[5] = reg05;
LTC6951_reg[6] = reg06;
LTC6951_reg[7] = reg07;
LTC6951_reg[8] = reg08;
LTC6951_reg[9] = reg09;
LTC6951_reg[10] = reg0A;
LTC6951_reg[11] = reg0B;
LTC6951_reg[12] = reg0C;
LTC6951_reg[13] = reg0D;
LTC6951_reg[14] = reg0E;
LTC6951_reg[15] = reg0F;
LTC6951_reg[16] = reg10;
LTC6951_reg[17] = reg11;
LTC6951_reg[18] = reg12;
for (i=1; i<19; i++) LTC6951_write(cs, i, LTC6951_reg[i]);
} // end of set_LTC6951_ALLREGS
/* -------------------------------------------------------------------------
FUNCTION: set_LTC6951_REGS_lkup_tbl
- writes LTC6951 registers from a look up table
- uses the Multi-byte write option for more efficient data transfer
- Calibrates VCO based on RAO and Autocal bit vales
- Either SPI Syncs or recommends the use to SYNC pin based on RAO, SN and SR values
--------------------------------------------------------------------------- */
void set_LTC6951_REGS_lkup_tbl(uint8_t lkup_tbl_row)
{
uint8_t val_temp, i, RAO_bit, AUTOCAL_bit, SN_bit, SR_bit;
uint8_t val_reg2, val_reg3, val_regA;
uint8_t *rx;
//! ************** SPI REGISTER WRITE SECTION ************
output_low(QUIKEVAL_CS); //! 1) CS low, enable SPI
val_temp = 1<<1; //! 2) addr 1, shift 1 bit to account for RW bit (W=0)
*rx = SPI.transfer(val_temp); //! 3) send ADDR1 byte
for (i=1; i<19; i++)
{
val_temp=LTC6951_lkup_tbl[lkup_tbl_row][i];
*rx = SPI.transfer(val_temp); //! 4) send REG byte
}
output_high(QUIKEVAL_CS); //! 5) CS high, disable SPI
//! **************** CALIBRATION SECTION ******************
//! Calibration required after Register writes if RAO=1 or if RAO=AUTOCAL=0.
val_reg2 = LTC6951_lkup_tbl[lkup_tbl_row][2]; //! CAL bit is located @ reg 2, bit 0, AUTOCAL bit reg 2, bit 3
val_reg3 = LTC6951_lkup_tbl[lkup_tbl_row][3]; //! RAO bit is located @ reg 3, bit 2; SSYNC bit @ reg 3, bit 4
RAO_bit = (val_reg3 & 0x04)>>2;
AUTOCAL_bit = (val_reg3 & 0x08)>>3;
val_regA = LTC6951_lkup_tbl[lkup_tbl_row][10]; //! SN, SR bit are located @ reg A, bits 7.6
SN_bit = (val_regA & 0x80)>>7;
SR_bit = (val_regA & 0x40)>>6;
if ((RAO_bit ==1) || (AUTOCAL_bit ==0)) //! checks if RAO=1 or AUTOCAL bit = 0
{
val_reg2 = val_reg2 | 0x01; //! sets CAL bit = 1
output_low(QUIKEVAL_CS); //! CS low, enable SPI
val_temp = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
*rx = SPI.transfer(val_temp); //! send ADDR2 byte + RW byte
*rx = SPI.transfer(val_reg2); //! send REG2 byte w/ CAL=1
output_high(QUIKEVAL_CS); //! CS high, disable SPI
val_reg2 = LTC6951_lkup_tbl[lkup_tbl_row][2]; //! CAL bit auto-clears after Calibration, set val_reg2 back to look-up table value
}
delay(1); //! wait 1ms for Calibration to complete, calibration usually takes <100us
//! **************** OUTPUT SYNC SECTION ******************
//! SSYNC can be used for EZSYNC StandAlone, EZSync Ref aligned standalone, EZParallelSYnc, EZ204Sync
//! - EZSync Standalone, RAO=0
//! - EZParallelSync, EZ204Sync, EZSync ref aligned: RA0=1, SN=SR=0
//! For ParallelSync or EZSync Controller to work the the SYNC pin should be used
//! - EZSync Controller, RAO=0 (User will have to remember if its a Controller as there is not a bit to distinguish this)
//! - ParallelSync: RA0=1, SN or SR= 1
//! See datasheet for timing requirements
if ((RAO_bit==0) || ((RAO_bit == 1) && ((SN_bit+SR_bit)==0)))
{
val_reg2 = val_reg2 | 0x04; //! Sets SSYNC bit =1
output_low(QUIKEVAL_CS); //! CS low, enable SPI
val_temp = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
*rx = SPI.transfer(val_temp); //! send ADDR2 byte + RW byte
*rx = SPI.transfer(val_reg2); //! send REG2 byte w/ CAL=1
output_high(QUIKEVAL_CS); //! CS high, disable SPI
delay(1); //! SSYNC bit remains high for a minimum of 1ms
val_reg2 = val_reg2 - 0x04; //! Sets SSYNC bit back to 0
output_low(QUIKEVAL_CS); //! CS low, enable SPI
val_temp = 2<<1; //! addr 2, shift 1 bit to account for RW bit (W=0)
*rx = SPI.transfer(val_temp); //! send ADDR2 byte + RW byte
*rx = SPI.transfer(val_reg2); //! send REG2 byte w/ CAL=1
output_high(QUIKEVAL_CS); //! CS high, disable SPI
}
//! **************** INFO SECTION ******************
//! INFO ONLY: Print Register Map written to part
for (i=1; i<19; i++)
{
val_temp=LTC6951_lkup_tbl[lkup_tbl_row][i];
Serial.print(F("ADDR"));
if (i<16) Serial.print("0");
Serial.print(i, HEX);
Serial.print(F(" = 0x"));
Serial.println(val_temp, HEX);
}
if (RAO_bit == 0)
{
Serial.println(F(" ***************************************************************************** "));
Serial.println(F("If this is a EZSync Standalone Device ignore this message - LTC6951 has been SYNC'd via SPI "));
Serial.println(F("If this is a EZSync Controller Device toggle all EZSync Device's Sync pins "));
Serial.println(F("EZSync TIMING: Sync Pins must remain high for 1ms, and with <10us skew between all EZSync Sync pins "));
Serial.println(F(" ***************************************************************************** "));
}
if ( (RAO_bit == 1) && ( (SN_bit+SR_bit)>0 ) )
{
Serial.println(F(" ***************************************************************************** "));
Serial.println(F("ParallelSync Timing: See Datasheet for setup and hold times "));
Serial.println(F("USER MUST TOGGLE SYNC PINS ACROSS ALL PARALLLESYNC DEVICES "));
Serial.println(F("If a DC2430 is available:"));
Serial.println(F(" - DC2430's J20-J22 circuitry can be used to create correct SYNC to REF setup and hold times"));
Serial.println(F(" ***************************************************************************** "));
}
} // end of set_LTC6951_REGS_lkup_tbl
/* -------------------------------------------------------------------------
FUNCTION: set_LTC6951_REGS_freq_jump
- used to toggle between two frequencies
- if measuring calibration or settling times set SPI clock to max SPI rate (8MHz)
= writes LTC6951 registers from a local look up table
- uses the Multi-byte write option for more efficient data transfer
- Calibrates VCO based on RAO and Autocal bit vales
- DOES NOTE SYNC OUTPUTS
- RECOMMENDATION: If measuring settling times with E5052, NOT MUTING OUTPUT DURING CAL can provide more meaningful results
--------------------------------------------------------------------------- */
void set_LTC6951_REGS_freq_jump(uint8_t lkup_tbl_row, uint8_t init_setup)
{
boolean REGx3toREGx5_change=false;
boolean REGx9toREGx12_change=false;
boolean REGx7toREGx8_change=false;
uint8_t start_addr, end_addr, val_temp, i, RAO_bit, AUTOCAL_bit, SN_bit, SR_bit;
uint8_t val_reg2, val_reg3, val_regA;
uint8_t *rx;
// Modifiy the 2 registers to try different settings. LTC6951Wizard has an export register option that supplies the below format.
uint8_t local6951_lkup_tbl[2][LTC6951_NUM_REGADDR] = //!< the following settings assume a 100MHz reference input
{
//{0x05, 0xba, 0x00, 0x74, 0xa3, 0x04, 0x06, 0x07, 0x00, 0x02, 0xc0, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x11}, //! ALL CHAN 600MHz, ParallelSync
//{0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x31, 0x07, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x11}, //! ALL CHAN 1225MHz, EZSync
{0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x30, 0x07, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x11}, //!< ALL CHAN 600MHZ, EZSync
{0x05, 0xba, 0x00, 0x78, 0xb3, 0x04, 0x2c, 0x07, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x11} //!< ALL CHAN 550MHZ, EZSync
};//
// inital setup program all registers
if (init_setup)
{
//! ************** INIT: SPI REGISTERS (ALL) WRITE SECTION ************
output_low(QUIKEVAL_CS); //! 1) CS low, enable SPI
start_addr = 1;
val_temp = start_addr<<1; //! 2) addr 1, shift 1 bit to account for RW bit (W=0)
*rx = SPI.transfer(val_temp); //! 3) send ADDR1 byte
for (i=start_addr; i<19; i++)
{
val_temp=local6951_lkup_tbl[lkup_tbl_row][i];
*rx = SPI.transfer(val_temp); //! 4) send REG byte
}
output_high(QUIKEVAL_CS); //! 5) CS high, disable SPI
} // end if(init_setup)
// checks if b or r-divider change?
REGx3toREGx5_change=false;
for (i=3; i<=5; i++)
{
if (local6951_lkup_tbl[0][i] != local6951_lkup_tbl[1][i]) REGx3toREGx5_change=true;
}
// checks if p-divider change?
REGx7toREGx8_change=false;
for (i=7; i<=8; i++)
{
if (local6951_lkup_tbl[0][i] != local6951_lkup_tbl[1][i]) REGx7toREGx8_change=true;
}
// checks if output divider change?
REGx9toREGx12_change=false;
for (i=9; i<=0x12; i++)
{
if (local6951_lkup_tbl[0][i] != local6951_lkup_tbl[1][i]) REGx9toREGx12_change=true;
}
//! **************** SELECTION SECTION ******************
//! Calibration required after Register writes if RAO=1 or if RAO=AUTOCAL=0.
val_reg2 = local6951_lkup_tbl[lkup_tbl_row][2]; //! CAL bit is located @ reg 2, bit 0, AUTOCAL bit reg 2, bit 3
val_reg3 = local6951_lkup_tbl[lkup_tbl_row][3]; //! RAO bit is located @ reg 3, bit 2; SSYNC bit @ reg 3, bit 4
RAO_bit = (val_reg3 & 0x04)>>2;
AUTOCAL_bit = (val_reg3 & 0x08)>>3;
//! All Settings of RAO and AUTOCAL Run this section
//! ************** SPI REGISTERS 4-19 WRITE SECTION ************
//! it possible the that register 6 is the only register that needs to change (N-divider),
//! but this codes was written for any and all frequency changes.
start_addr = 6; //! ADDR6 includes include ND
if (REGx3toREGx5_change==true) start_addr=3; //! ADDR4 includes include BD (cal-divider), ADDR 5 includes RD
end_addr=6; //! ADDR6 includes include ND
if (REGx7toREGx8_change==true) end_addr=8; //! ADDR8 includes include PD
if (REGx9toREGx12_change==true) end_addr=12; //! ADDR9-12 include output dividers
output_low(QUIKEVAL_CS); //! CS low, enable SPI
val_temp = start_addr<<1; //! addr 4, shift 1 bit to account for RW bit (W=0)
*rx = SPI.transfer(val_temp); //! send ADDR byte
for (i=start_addr; i<=end_addr; i++)
{
val_temp=local6951_lkup_tbl[lkup_tbl_row][i];
*rx = SPI.transfer(val_temp); //! send REG bytes
}
output_high(QUIKEVAL_CS); //! CS high, disable SPI
//! If Autocal=0 or RAO_bit=1 (ParallelSync, EZParallelSync, EZ204Sync, EZSync Ref Aligned
//! Then the cal bit needs to be toggle, with Linduino it maybe fastest to continue
//! The multi-byte write operation. (reason: The CS L-H transistion has a delay)
if (RAO_bit || !AUTOCAL_bit)
{
start_addr = 2;
val_temp = start_addr<<1; //! ADDR, shift 1 bit to account for RW bit (W=0)
val_reg2 = val_reg2 | 0x01; //! sets CAL bit loc = 1
output_low(QUIKEVAL_CS); //! CS low, enable SPI
*rx = SPI.transfer(val_temp); //! send ADDR2 byte
*rx = SPI.transfer(val_reg2); //! send REG2 byte
output_high(QUIKEVAL_CS); //! CS high, disable SPI
}
} // end of set_LTC6951_REGS_freq_jump
/* -------------------------------------------------------------------------
FUNCTION: LTC6951_init
- initializes the SPI MAP
- for ease of programming there is spreadsheet that automates this some.
----------------------------------------------------------------------------*/
void LTC6951_init()
{
// look up table
// spi map
LTC6951_spi_map[LTC6951_ALCCAL][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_ALCCAL][DxMSB]= 5;
LTC6951_spi_map[LTC6951_ALCCAL][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_ALCEN][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_ALCEN][DxMSB]= 7;
LTC6951_spi_map[LTC6951_ALCEN][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_ALCHI][ADDRx]=0x00;
LTC6951_spi_map[LTC6951_ALCHI][DxMSB]= 5;
LTC6951_spi_map[LTC6951_ALCHI][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_ALCLO][ADDRx]=0x00;
LTC6951_spi_map[LTC6951_ALCLO][DxMSB]= 4;
LTC6951_spi_map[LTC6951_ALCLO][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_ALCMON][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_ALCMON][DxMSB]= 6;
LTC6951_spi_map[LTC6951_ALCMON][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_ALCULOK][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_ALCULOK][DxMSB]= 4;
LTC6951_spi_map[LTC6951_ALCULOK][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_AUTOCAL][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_AUTOCAL][DxMSB]= 3;
LTC6951_spi_map[LTC6951_AUTOCAL][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_BD][ADDRx]=0x04;
LTC6951_spi_map[LTC6951_BD][DxMSB]= 7;
LTC6951_spi_map[LTC6951_BD][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_BST][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_BST][DxMSB]= 1;
LTC6951_spi_map[LTC6951_BST][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_CAL][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_CAL][DxMSB]= 0;
LTC6951_spi_map[LTC6951_CAL][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_CP][ADDRx]=0x07;
LTC6951_spi_map[LTC6951_CP][DxMSB]= 2;
LTC6951_spi_map[LTC6951_CP][NUMBITS]= 3;
LTC6951_spi_map[LTC6951_CPDN][ADDRx]=0x07;
LTC6951_spi_map[LTC6951_CPDN][DxMSB]= 3;
LTC6951_spi_map[LTC6951_CPDN][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_CPMID][ADDRx]=0x07;
LTC6951_spi_map[LTC6951_CPMID][DxMSB]= 7;
LTC6951_spi_map[LTC6951_CPMID][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_CPRST][ADDRx]=0x07;
LTC6951_spi_map[LTC6951_CPRST][DxMSB]= 5;
LTC6951_spi_map[LTC6951_CPRST][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_CPUP][ADDRx]=0x07;
LTC6951_spi_map[LTC6951_CPUP][DxMSB]= 4;
LTC6951_spi_map[LTC6951_CPUP][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_CPWIDE][ADDRx]=0x07;
LTC6951_spi_map[LTC6951_CPWIDE][DxMSB]= 6;
LTC6951_spi_map[LTC6951_CPWIDE][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_DLY0][ADDRx]=0x0a;
LTC6951_spi_map[LTC6951_DLY0][DxMSB]= 7;
LTC6951_spi_map[LTC6951_DLY0][NUMBITS]= 8;
LTC6951_spi_map[LTC6951_DLY1][ADDRx]=0x0c;
LTC6951_spi_map[LTC6951_DLY1][DxMSB]= 7;
LTC6951_spi_map[LTC6951_DLY1][NUMBITS]= 8;
LTC6951_spi_map[LTC6951_DLY2][ADDRx]=0x0e;
LTC6951_spi_map[LTC6951_DLY2][DxMSB]= 7;
LTC6951_spi_map[LTC6951_DLY2][NUMBITS]= 8;
LTC6951_spi_map[LTC6951_DLY3][ADDRx]=0x10;
LTC6951_spi_map[LTC6951_DLY3][DxMSB]= 7;
LTC6951_spi_map[LTC6951_DLY3][NUMBITS]= 8;
LTC6951_spi_map[LTC6951_DLY4][ADDRx]=0x12;
LTC6951_spi_map[LTC6951_DLY4][DxMSB]= 7;
LTC6951_spi_map[LTC6951_DLY4][NUMBITS]= 8;
LTC6951_spi_map[LTC6951_FILT][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_FILT][DxMSB]= 0;
LTC6951_spi_map[LTC6951_FILT][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_INVSTAT][ADDRx]=0x01;
LTC6951_spi_map[LTC6951_INVSTAT][DxMSB]= 7;
LTC6951_spi_map[LTC6951_INVSTAT][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_LKCT][ADDRx]=0x04;
LTC6951_spi_map[LTC6951_LKCT][DxMSB]= 1;
LTC6951_spi_map[LTC6951_LKCT][NUMBITS]= 2;
LTC6951_spi_map[LTC6951_LKWIN][ADDRx]=0x04;
LTC6951_spi_map[LTC6951_LKWIN][DxMSB]= 2;
LTC6951_spi_map[LTC6951_LKWIN][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_LOCK][ADDRx]=0x00;
LTC6951_spi_map[LTC6951_LOCK][DxMSB]= 2;
LTC6951_spi_map[LTC6951_LOCK][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_NLOCK][ADDRx]=0x00;
LTC6951_spi_map[LTC6951_NLOCK][DxMSB]= 3;
LTC6951_spi_map[LTC6951_NLOCK][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_MCO][ADDRx]=0x09;
LTC6951_spi_map[LTC6951_MCO][DxMSB]= 5;
LTC6951_spi_map[LTC6951_MCO][NUMBITS]= 2;
LTC6951_spi_map[LTC6951_MC1][ADDRx]=0x0b;
LTC6951_spi_map[LTC6951_MC1][DxMSB]= 5;
LTC6951_spi_map[LTC6951_MC1][NUMBITS]= 2;
LTC6951_spi_map[LTC6951_MC2][ADDRx]=0x0d;
LTC6951_spi_map[LTC6951_MC2][DxMSB]= 5;
LTC6951_spi_map[LTC6951_MC2][NUMBITS]= 2;
LTC6951_spi_map[LTC6951_MC3][ADDRx]=0x0f;
LTC6951_spi_map[LTC6951_MC3][DxMSB]= 5;
LTC6951_spi_map[LTC6951_MC3][NUMBITS]= 2;
LTC6951_spi_map[LTC6951_MC4][ADDRx]=0x11;
LTC6951_spi_map[LTC6951_MC4][DxMSB]= 5;
LTC6951_spi_map[LTC6951_MC4][NUMBITS]= 2;
LTC6951_spi_map[LTC6951_MD0][ADDRx]=0x09;
LTC6951_spi_map[LTC6951_MD0][DxMSB]= 3;
LTC6951_spi_map[LTC6951_MD0][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_MD1][ADDRx]=0x0b;
LTC6951_spi_map[LTC6951_MD1][DxMSB]= 3;
LTC6951_spi_map[LTC6951_MD1][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_MD2][ADDRx]=0x0d;
LTC6951_spi_map[LTC6951_MD2][DxMSB]= 3;
LTC6951_spi_map[LTC6951_MD2][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_MD3][ADDRx]=0x0f;
LTC6951_spi_map[LTC6951_MD3][DxMSB]= 3;
LTC6951_spi_map[LTC6951_MD3][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_MD4][ADDRx]=0x11;
LTC6951_spi_map[LTC6951_MD4][DxMSB]= 3;
LTC6951_spi_map[LTC6951_MD4][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_MUTE0][ADDRx]=0x08;
LTC6951_spi_map[LTC6951_MUTE0][DxMSB]= 0;
LTC6951_spi_map[LTC6951_MUTE0][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_MUTE1][ADDRx]=0x08;
LTC6951_spi_map[LTC6951_MUTE1][DxMSB]= 1;
LTC6951_spi_map[LTC6951_MUTE1][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_MUTE2][ADDRx]=0x08;
LTC6951_spi_map[LTC6951_MUTE2][DxMSB]= 2;
LTC6951_spi_map[LTC6951_MUTE2][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_MUTE3][ADDRx]=0x08;
LTC6951_spi_map[LTC6951_MUTE3][DxMSB]= 3;
LTC6951_spi_map[LTC6951_MUTE3][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_MUTE4][ADDRx]=0x08;
LTC6951_spi_map[LTC6951_MUTE4][DxMSB]= 4;
LTC6951_spi_map[LTC6951_MUTE4][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_ND][ADDRx]=0x05;
LTC6951_spi_map[LTC6951_ND][DxMSB]= 1;
LTC6951_spi_map[LTC6951_ND][NUMBITS]= 10;
LTC6951_spi_map[LTC6951_OINV0][ADDRx]=0x09;
LTC6951_spi_map[LTC6951_OINV0][DxMSB]= 6;
LTC6951_spi_map[LTC6951_OINV0][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_OINV1][ADDRx]=0x0b;
LTC6951_spi_map[LTC6951_OINV1][DxMSB]= 6;
LTC6951_spi_map[LTC6951_OINV1][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_OINV2][ADDRx]=0x0d;
LTC6951_spi_map[LTC6951_OINV2][DxMSB]= 6;
LTC6951_spi_map[LTC6951_OINV2][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_OINV3][ADDRx]=0x0f;
LTC6951_spi_map[LTC6951_OINV3][DxMSB]= 6;
LTC6951_spi_map[LTC6951_OINV3][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_OINV4][ADDRx]=0x11;
LTC6951_spi_map[LTC6951_OINV4][DxMSB]= 6;
LTC6951_spi_map[LTC6951_OINV4][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_PART][ADDRx]=0x13;
LTC6951_spi_map[LTC6951_PART][DxMSB]= 3;
LTC6951_spi_map[LTC6951_PART][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_PD][ADDRx]=0x08;
LTC6951_spi_map[LTC6951_PD][DxMSB]= 7;
LTC6951_spi_map[LTC6951_PD][NUMBITS]= 3;
LTC6951_spi_map[LTC6951_PDALL][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_PDALL][DxMSB]= 7;
LTC6951_spi_map[LTC6951_PDALL][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_PDOUT][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_PDOUT][DxMSB]= 4;
LTC6951_spi_map[LTC6951_PDOUT][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_PDPLL][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_PDPLL][DxMSB]= 6;
LTC6951_spi_map[LTC6951_PDPLL][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_PDREFPK][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_PDREFPK][DxMSB]= 3;
LTC6951_spi_map[LTC6951_PDREFPK][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_PDVCO][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_PDVCO][DxMSB]= 5;
LTC6951_spi_map[LTC6951_PDVCO][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_POR][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_POR][DxMSB]= 1;
LTC6951_spi_map[LTC6951_POR][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_RAO][ADDRx]=0x03;
LTC6951_spi_map[LTC6951_RAO][DxMSB]= 2;
LTC6951_spi_map[LTC6951_RAO][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_RD][ADDRx]=0x05;
LTC6951_spi_map[LTC6951_RD][DxMSB]= 7;
LTC6951_spi_map[LTC6951_RD][NUMBITS]= 6;
LTC6951_spi_map[LTC6951_REFOK][ADDRx]=0x00;
LTC6951_spi_map[LTC6951_REFOK][DxMSB]= 0;
LTC6951_spi_map[LTC6951_REFOK][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_NREFOK][ADDRx]=0x00;
LTC6951_spi_map[LTC6951_NREFOK][DxMSB]= 1;
LTC6951_spi_map[LTC6951_NREFOK][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_REV][ADDRx]=0x13;
LTC6951_spi_map[LTC6951_REV][DxMSB]= 7;
LTC6951_spi_map[LTC6951_REV][NUMBITS]= 4;
LTC6951_spi_map[LTC6951_SN][ADDRx]=0x0a;
LTC6951_spi_map[LTC6951_SN][DxMSB]= 7;
LTC6951_spi_map[LTC6951_SN][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_SR][ADDRx]=0x0a;
LTC6951_spi_map[LTC6951_SR][DxMSB]= 6;
LTC6951_spi_map[LTC6951_SR][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_SSYNC][ADDRx]=0x02;
LTC6951_spi_map[LTC6951_SSYNC][DxMSB]= 2;
LTC6951_spi_map[LTC6951_SSYNC][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_SYNCEN0][ADDRx]=0x09;
LTC6951_spi_map[LTC6951_SYNCEN0][DxMSB]= 7;
LTC6951_spi_map[LTC6951_SYNCEN0][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_SYNCEN1][ADDRx]=0x0b;
LTC6951_spi_map[LTC6951_SYNCEN1][DxMSB]= 7;
LTC6951_spi_map[LTC6951_SYNCEN1][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_SYNCEN2][ADDRx]=0x0d;
LTC6951_spi_map[LTC6951_SYNCEN2][DxMSB]= 7;
LTC6951_spi_map[LTC6951_SYNCEN2][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_SYNCEN3][ADDRx]=0x0f;
LTC6951_spi_map[LTC6951_SYNCEN3][DxMSB]= 7;
LTC6951_spi_map[LTC6951_SYNCEN3][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_SYNCEN4][ADDRx]=0x11;
LTC6951_spi_map[LTC6951_SYNCEN4][DxMSB]= 7;
LTC6951_spi_map[LTC6951_SYNCEN4][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_UNLOCK][ADDRx]=0x00;
LTC6951_spi_map[LTC6951_UNLOCK][DxMSB]= 6;
LTC6951_spi_map[LTC6951_UNLOCK][NUMBITS]= 1;
LTC6951_spi_map[LTC6951_x][ADDRx]=0x01;
LTC6951_spi_map[LTC6951_x][DxMSB]= 6;
LTC6951_spi_map[LTC6951_x][NUMBITS]= 7;
LTC6951_spi_map[LTC6951_ALCCAL][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_ALCEN][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_ALCHI][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_ALCLO][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_ALCMON][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_ALCULOK][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_AUTOCAL][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_BD][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_BST][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_CAL][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_CP][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_CPDN][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_CPMID][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_CPRST][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_CPUP][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_CPWIDE][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_DLY0][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_DLY1][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_DLY2][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_DLY3][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_DLY4][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_FILT][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_INVSTAT][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_LKCT][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_LKWIN][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_LOCK][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_NLOCK][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_MCO][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MC1][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MC2][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MC3][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MC4][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MD0][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MD1][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MD2][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MD3][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MD4][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MUTE0][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MUTE1][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MUTE2][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MUTE3][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_MUTE4][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_ND][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_OINV0][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_OINV1][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_OINV2][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_OINV3][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_OINV4][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_PART][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_PD][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_PDALL][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_PDOUT][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_PDPLL][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_PDREFPK][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_PDVCO][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_POR][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_RAO][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_RD][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_REFOK][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_NREFOK][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_REV][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_SN][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_SR][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_SSYNC][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_SYNCEN0][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_SYNCEN1][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_SYNCEN2][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_SYNCEN3][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_SYNCEN4][R_ONLY]= 0;
LTC6951_spi_map[LTC6951_UNLOCK][R_ONLY]= 1;
LTC6951_spi_map[LTC6951_x][R_ONLY]= 0;
} // end of LTC6951_init
// Read the ID string from the EEPROM and determine if the correct board is connected.
// Returns 1 if successful, 0 if not successful
int8_t discover_demo_board_local(char *demo_name)
{
int8_t connected;
connected = 1;
// read the ID from the serial EEPROM on the board
// reuse the buffer declared in UserInterface
if (read_quikeval_id_string(&ui_buffer[0]) == 0) connected = 0;
return(connected);
}
Technical Support
- For immediate technical assistance, contact your local sales office or distributor or call 1-800-4-LINEAR (US customers only) or 408-432-1900.
- For less urgent requests, please complete our Technical Support Request Form. Please allow 2-3 business days for reply.
