Library to control Silicon Labs SI570 10 MHZ TO 1.4 GHZ I2C PROGRAMMABLE XO/VCXO.

Dependents:   t2d Thing2Do

This is the page for the Silicon Laboratories Si570 frequency synthesizer, with I2C interface.

The Si570 XO/Si571 VCXO utilizes Silicon Laboratories’ advanced DSPLL® circuitry to provide a low-jitter clock at any frequency. The Si570/Si571 are user-programmable to any output frequency from 10 to 945 MHz and select frequencies to 1400 MHz with <1 ppb resolution. The device is programmed via an I2C serial interface. Unlike traditional XO/VCXOs where a different crystal is required for each output frequency, the Si57x uses one fixed- frequency crystal and a DSPLL clock synthesis IC to provide any-frequency operation. This IC-based approach allows the crystal resonator to provide exceptional frequency stability and reliability. In addition, DSPLL clock synthesis provides superior supply noise rejection, simplifying the task of generating low-jitter clocks in noisy environments typically found in communication systems.

The Si570 is very popular for amateur radio use. It can be used as the local oscillator in a superheterodyne receiver, or it can be the local oscillator in a direct conversion quadrature receiver for software defined radio (SDR) such as the Softrock. In addition to its use inside a receiver, the Si570 kit can be used as a stand-alone signal source for test and measurement and for other purposes, such as a VFO for your old Heathkit DX40 for that matter. Just keep in mind that the Si570's output is a square wave and may require additional filtering for some purposes.

Image of the SI570 in action

/media/uploads/soldeerridder/si570_sr.jpg

Hello World!

 #include "mbed.h"
 #include "TextLCD.h"
 #include "SI570.h"
 #include "QEI.h"
 
 TextLCD lcd(p11, p12, p15, p16, p29, p30); // rs, e, d0-d3
 SI570 si570(p9, p10, 0xAA);
 QEI wheel (p5, p6, NC, 360);
 
 int main() {
     int wp,swp=0;
     float startfreq=7.0;
     float freq;
 
     while (1) {
         wp =  wheel.getPulses();
         freq=startfreq+wp*0.00001;
         if (swp != wp) {
             si570.set_frequency(freq);
             swp = wp;
         }                
         lcd.locate(0,0);
         lcd.printf("%f MHz", si570.get_frequency());
     }
 }

Links

Reference

Committer:
soldeerridder
Date:
Tue Nov 09 20:56:52 2010 +0000
Revision:
0:dae1bf95c49e
added documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
soldeerridder 0:dae1bf95c49e 1 /* mbed SI570 Library, for driving the SI570 programable VCXO
soldeerridder 0:dae1bf95c49e 2 * Copyright (c) 2010, Gerrit Polder, PA3BYA
soldeerridder 0:dae1bf95c49e 3 *
soldeerridder 0:dae1bf95c49e 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
soldeerridder 0:dae1bf95c49e 5 * of this software and associated documentation files (the "Software"), to deal
soldeerridder 0:dae1bf95c49e 6 * in the Software without restriction, including without limitation the rights
soldeerridder 0:dae1bf95c49e 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
soldeerridder 0:dae1bf95c49e 8 * copies of the Software, and to permit persons to whom the Software is
soldeerridder 0:dae1bf95c49e 9 * furnished to do so, subject to the following conditions:
soldeerridder 0:dae1bf95c49e 10 *
soldeerridder 0:dae1bf95c49e 11 * The above copyright notice and this permission notice shall be included in
soldeerridder 0:dae1bf95c49e 12 * all copies or substantial portions of the Software.
soldeerridder 0:dae1bf95c49e 13 *
soldeerridder 0:dae1bf95c49e 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
soldeerridder 0:dae1bf95c49e 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
soldeerridder 0:dae1bf95c49e 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
soldeerridder 0:dae1bf95c49e 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
soldeerridder 0:dae1bf95c49e 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
soldeerridder 0:dae1bf95c49e 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
soldeerridder 0:dae1bf95c49e 20 * THE SOFTWARE.
soldeerridder 0:dae1bf95c49e 21 */
soldeerridder 0:dae1bf95c49e 22
soldeerridder 0:dae1bf95c49e 23 #ifndef MBED_SI570_H
soldeerridder 0:dae1bf95c49e 24 #define MBED_SI570_H
soldeerridder 0:dae1bf95c49e 25
soldeerridder 0:dae1bf95c49e 26 #include "mbed.h"
soldeerridder 0:dae1bf95c49e 27
soldeerridder 0:dae1bf95c49e 28 //these must be floating point number especially 2^28 so that
soldeerridder 0:dae1bf95c49e 29 //there is enough memory to use them in the calculation
soldeerridder 0:dae1bf95c49e 30 #define POW_2_16 65536.0
soldeerridder 0:dae1bf95c49e 31 #define POW_2_24 16777216.0
soldeerridder 0:dae1bf95c49e 32 #define POW_2_28 268435456.0
soldeerridder 0:dae1bf95c49e 33 #define FOUT_START_UP 56.320 //MHz
soldeerridder 0:dae1bf95c49e 34 #define PPM 3500 // +/- max ppm from center frequency
soldeerridder 0:dae1bf95c49e 35 #define FDCO_MAX 5670.0 //MHz
soldeerridder 0:dae1bf95c49e 36 #define FDCO_MIN 4850.0 //MHz
soldeerridder 0:dae1bf95c49e 37
soldeerridder 0:dae1bf95c49e 38
soldeerridder 0:dae1bf95c49e 39 /** Interface to the popular SI570 VCXO */
soldeerridder 0:dae1bf95c49e 40 class SI570 {
soldeerridder 0:dae1bf95c49e 41 public:
soldeerridder 0:dae1bf95c49e 42 /** Create an instance of the SI570 connected to specified I2C pins, with the specified address.
soldeerridder 0:dae1bf95c49e 43 *
soldeerridder 0:dae1bf95c49e 44 * Example:
soldeerridder 0:dae1bf95c49e 45 * @code
soldeerridder 0:dae1bf95c49e 46 * #include "mbed.h"
soldeerridder 0:dae1bf95c49e 47 * #include "TextLCD.h"
soldeerridder 0:dae1bf95c49e 48 * #include "SI570.h"
soldeerridder 0:dae1bf95c49e 49 * #include "QEI.h"
soldeerridder 0:dae1bf95c49e 50 *
soldeerridder 0:dae1bf95c49e 51 * TextLCD lcd(p11, p12, p15, p16, p29, p30); // rs, e, d0-d3
soldeerridder 0:dae1bf95c49e 52 * SI570 si570(p9, p10, 0xAA);
soldeerridder 0:dae1bf95c49e 53 * QEI wheel (p5, p6, NC, 360);
soldeerridder 0:dae1bf95c49e 54 *
soldeerridder 0:dae1bf95c49e 55 * int main() {
soldeerridder 0:dae1bf95c49e 56 * int wp,swp=0;
soldeerridder 0:dae1bf95c49e 57 * float startfreq=7.0;
soldeerridder 0:dae1bf95c49e 58 * float freq;
soldeerridder 0:dae1bf95c49e 59 *
soldeerridder 0:dae1bf95c49e 60 * while (1) {
soldeerridder 0:dae1bf95c49e 61 * wp = wheel.getPulses();
soldeerridder 0:dae1bf95c49e 62 * freq=startfreq+wp*0.00001;
soldeerridder 0:dae1bf95c49e 63 * if (swp != wp) {
soldeerridder 0:dae1bf95c49e 64 * si570.set_frequency(freq);
soldeerridder 0:dae1bf95c49e 65 * swp = wp;
soldeerridder 0:dae1bf95c49e 66 * }
soldeerridder 0:dae1bf95c49e 67 * lcd.locate(0,0);
soldeerridder 0:dae1bf95c49e 68 * lcd.printf("%f MHz", si570.get_frequency());
soldeerridder 0:dae1bf95c49e 69 * }
soldeerridder 0:dae1bf95c49e 70 * }
soldeerridder 0:dae1bf95c49e 71 * @endcode
soldeerridder 0:dae1bf95c49e 72 *
soldeerridder 0:dae1bf95c49e 73 * @param sda The I2C data pin
soldeerridder 0:dae1bf95c49e 74 * @param scl The I2C clock pin
soldeerridder 0:dae1bf95c49e 75 * @param address The I2C address for this SI570
soldeerridder 0:dae1bf95c49e 76 */
soldeerridder 0:dae1bf95c49e 77 SI570(PinName sda, PinName scl, int address);
soldeerridder 0:dae1bf95c49e 78
soldeerridder 0:dae1bf95c49e 79 /** Resets the SI570.
soldeerridder 0:dae1bf95c49e 80 *
soldeerridder 0:dae1bf95c49e 81 * Resets and reads the startup configuration from the Si570
soldeerridder 0:dae1bf95c49e 82 */
soldeerridder 0:dae1bf95c49e 83 void si570reset(void);
soldeerridder 0:dae1bf95c49e 84
soldeerridder 0:dae1bf95c49e 85 /** Read the current frequency.
soldeerridder 0:dae1bf95c49e 86 *
soldeerridder 0:dae1bf95c49e 87 * get the SI570 registers an calculate the current frequency
soldeerridder 0:dae1bf95c49e 88 *
soldeerridder 0:dae1bf95c49e 89 * @returns the current frequency
soldeerridder 0:dae1bf95c49e 90 */
soldeerridder 0:dae1bf95c49e 91 double get_frequency(void);
soldeerridder 0:dae1bf95c49e 92
soldeerridder 0:dae1bf95c49e 93 /** Read the current rfreq value.
soldeerridder 0:dae1bf95c49e 94 *
soldeerridder 0:dae1bf95c49e 95 * get the SI570 registers an calculate the current rfreq
soldeerridder 0:dae1bf95c49e 96 *
soldeerridder 0:dae1bf95c49e 97 * @returns the current rfreq
soldeerridder 0:dae1bf95c49e 98 */
soldeerridder 0:dae1bf95c49e 99 double get_rfreq(void);
soldeerridder 0:dae1bf95c49e 100
soldeerridder 0:dae1bf95c49e 101 /** Read the current n1.
soldeerridder 0:dae1bf95c49e 102 *
soldeerridder 0:dae1bf95c49e 103 * get the SI570 registers an calculate the current n1
soldeerridder 0:dae1bf95c49e 104 *
soldeerridder 0:dae1bf95c49e 105 * @returns the current n1
soldeerridder 0:dae1bf95c49e 106 */
soldeerridder 0:dae1bf95c49e 107 int get_n1(void);
soldeerridder 0:dae1bf95c49e 108
soldeerridder 0:dae1bf95c49e 109 /** Read the current hsdiv.
soldeerridder 0:dae1bf95c49e 110 *
soldeerridder 0:dae1bf95c49e 111 * get the SI570 registers an calculate the current hsdiv
soldeerridder 0:dae1bf95c49e 112 *
soldeerridder 0:dae1bf95c49e 113 * @returns the current hsdiv
soldeerridder 0:dae1bf95c49e 114 */
soldeerridder 0:dae1bf95c49e 115 int get_hsdiv(void);
soldeerridder 0:dae1bf95c49e 116
soldeerridder 0:dae1bf95c49e 117 /** Set a new frequency.
soldeerridder 0:dae1bf95c49e 118 *
soldeerridder 0:dae1bf95c49e 119 * Set the SI570 registers to output frequency
soldeerridder 0:dae1bf95c49e 120 * When the new frequency is within the 3500 PPM range of the center frequency, hsdiv and n1 needs not to be reprogrammed, resulting in a glitch free transition.
soldeerridder 0:dae1bf95c49e 121 * For changes larger than 3500 PPM, the process of freezing and unfreezing the DCO will cause the output clock to momentarily stop and start at any arbitrary point during a clock cycle. This process can take up to 10 ms.
soldeerridder 0:dae1bf95c49e 122 *
soldeerridder 0:dae1bf95c49e 123 * @param frequency the frequency to set.
soldeerridder 0:dae1bf95c49e 124 * @returns the current frequency
soldeerridder 0:dae1bf95c49e 125 */
soldeerridder 0:dae1bf95c49e 126 int set_frequency(double frequency);
soldeerridder 0:dae1bf95c49e 127
soldeerridder 0:dae1bf95c49e 128
soldeerridder 0:dae1bf95c49e 129 private:
soldeerridder 0:dae1bf95c49e 130 I2C _i2c;
soldeerridder 0:dae1bf95c49e 131 int _address;
soldeerridder 0:dae1bf95c49e 132 char cmd[2];
soldeerridder 0:dae1bf95c49e 133 char buf[6];
soldeerridder 0:dae1bf95c49e 134 unsigned char n1;
soldeerridder 0:dae1bf95c49e 135 unsigned char hsdiv;
soldeerridder 0:dae1bf95c49e 136 unsigned long frac_bits;
soldeerridder 0:dae1bf95c49e 137 double rfreq;
soldeerridder 0:dae1bf95c49e 138 double fxtal_device;
soldeerridder 0:dae1bf95c49e 139 double currentFreq;
soldeerridder 0:dae1bf95c49e 140 double currentRfreq;
soldeerridder 0:dae1bf95c49e 141
soldeerridder 0:dae1bf95c49e 142 void get_registers(void);
soldeerridder 0:dae1bf95c49e 143 int set_frequency_small_change(double currentFrequency);
soldeerridder 0:dae1bf95c49e 144 int set_frequency_large_change(double currentFrequency);
soldeerridder 0:dae1bf95c49e 145
soldeerridder 0:dae1bf95c49e 146 unsigned char SetBits(unsigned char original, unsigned char reset_mask, unsigned char new_val);
soldeerridder 0:dae1bf95c49e 147 };
soldeerridder 0:dae1bf95c49e 148
soldeerridder 0:dae1bf95c49e 149
soldeerridder 0:dae1bf95c49e 150 #endif