Silicon Laboratories Inc. Si5351A-B-GT I2C-PROGRAMMABLE ANY-FREQUENCY CMOS CLOCK GENERATOR
Dependents: clockGenerator Check_Si5351A_Clock_generator t2d Thing2Do ... more
Test program:
/users/kenjiArai/code/Check_Si5351A_Clock_generator/
si5351a.h
- Committer:
- kenjiArai
- Date:
- 2017-01-05
- Revision:
- 1:a2309757c450
- Parent:
- 0:47b9bfa03730
- Child:
- 2:8fe745836ea6
File content as of revision 1:a2309757c450:
/* * mbed Library / Silicon Laboratories Inc. Si5351A-B-GT * I2C-PROGRAMMABLE ANY-FREQUENCY CMOS CLOCK GENERATOR * https://www.silabs.com/products/ * timing/clock-generator/si535x/pages/Si5351A-B-GM.aspx * * Checked on Nucleo-F411RE & F401RE mbed board * * Original & Reference program: * 1) * https://github.com/adafruit/Adafruit_Si5351_Library * see original source (bottom part of si5351a.cpp file) * Software License Agreement (BSD License) * Copyright (c) 2014, Adafruit Industries All rights reserved. * 2) * https://gist.github.com/edy555/f1ee7ef44fe4f5c6f7618ac4cbbe66fb * made by TT@Hokkaido-san (edy555) * http://ttrftech.tumblr.com/ * http://ttrftech.tumblr.com/post/150247113216/ * si5351a-configuration-how-to-and-signal-quality * * Modified by Kenji Arai / JH1PJL * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * * Started: December 24th, 2016 * Revised: January 5th, 2017 * */ #ifndef MBED_SI5351A #define MBED_SI5351A ////////////// ADDRESS ///////////////////////////////////////////////////////// // 7bit address = 0b1100000(0x60) -> 8bit = 0b11000000(0xc0) // -> Fixed adddress (No other choises) #define SI5351_I2C_ADDR (0x60<<1) ////////////// REGISTER DEFINITION ///////////////////////////////////////////// #define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3 #define SI5351_REG_16_CLK0_CONTROL 16 #define SI5351_REG_17_CLK1_CONTROL 17 #define SI5351_REG_18_CLK2_CONTROL 18 #define SI5351_REG_26_PLL_A 26 #define SI5351_REG_34_PLL_B 34 #define SI5351_REG_42_MULTISYNTH0 42 #define SI5351_REG_44_MULTISYNTH0_P3 44 #define SI5351_REG_50_MULTISYNTH1 50 #define SI5351_REG_52_MULTISYNTH1_P3 52 #define SI5351_REG_58_MULTISYNTH2 58 #define SI5351_REG_60_MULTISYNTH2_P3 60 #define SI5351_REG_177_PLL_RESET 177 #define SI5351_REG_183_CRYSTAL_LOAD 183 ////////////// Configration //////////////////////////////////////////////////// // PLLn #define SI5351_PLL_A 0 #define SI5351_PLL_B 1 // CLKn #define SI5351_CLK0 0 #define SI5351_CLK1 1 #define SI5351_CLK2 2 // REG_44_MULTISYNTH0, REG_52_MULTISYNTH1, REG_60_MULTISYNTH2 #define SI5351_R_DIV_1 (0<<4) #define SI5351_R_DIV_2 (1<<4) #define SI5351_R_DIV_4 (2<<4) #define SI5351_R_DIV_8 (3<<4) #define SI5351_R_DIV_16 (4<<4) #define SI5351_R_DIV_32 (5<<4) #define SI5351_R_DIV_64 (6<<4) #define SI5351_R_DIV_128 (7<<4) #define SI5351_DIVBY4 (3<<2) // REG_16_CLK0_CONTROL, REG_17_CLK1_CONTROL, REG_18_CLK2_CONTROL #define SI5351_CLK_POWERDOWN (1<<7) #define SI5351_CLK_INTEGER_MODE (1<<6) #define SI5351_CLK_PLL_SELECT_B (1<<5) #define SI5351_CLK_INVERT (1<<4) #define SI5351_CLK_INPUT_MASK (3<<2) #define SI5351_CLK_INPUT_XTAL (0<<2) #define SI5351_CLK_INPUT_CLKIN (1<<2) #define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) #define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) #define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) #define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) #define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) #define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) #define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) // REG_177_PLL_RESET #define SI5351_PLL_RESET_B (1<<7) #define SI5351_PLL_RESET_A (1<<5) // REG_183_CRYSTAL_LOAD #define SI5351_CRYSTAL_LOAD_6PF (1<<6) #define SI5351_CRYSTAL_LOAD_8PF (2<<6) #define SI5351_CRYSTAL_LOAD_10PF (3<<6) // Frequency #define FREQ_150MHZ (150000000UL) #define FREQ_100MHZ (100000000UL) #define FREQ_1MHZ (1000000UL) #define FREQ_450KHZ (450000UL) #define FREQ_75KHZ (75000UL) #define FREQ_20KHZ (20000UL) typedef enum { // Operating mode CLK_OUT_NOT_USED = 0, CLK_OUT_FIXEDPLL, CLK_OUT_FIXEDDIV } OperatingMode; /** Silicon Laboratories Inc. Si5351A * * @code * #include "mbed.h" * #include "si5351a.h" * * I2C i2c(I2C_SDA, I2C_SCL); // communication with Si5351A * SI5351 clk(i2c, 25000000UL); // Base clock = 25MHz * * int main() { * clk.set_frequency(SI5351_CLK0, 10000000); // CLK0=10MHz * while(true) { * wait(1000); * } * } * * // --------- CAUTION & RESTRICTION ----------------------------------------- * // 1) SETTING METHOD * // 1~100MHz : fixed PLL (XTAL * PLL_N)MHz, fractional divider * // 100~150MHz : fractional PLL 600-900MHz, fixed divider 6 * // 150~200MHz : fractional PLL 600-900MHz, fixed divider 4 * // * // 2) RESOURCE USAGE * // PLLA -> only for CLK0 (You can change freqency any time to any value.) * // PLLB -> use for bothe CLK1 & CLK2 * // If you set a freq. less than 100MHz, * // You can change both CLK1 & CLK2 independently. * // Over 100MHz, you may have a trouble becase need to change PLLB freq. * // * // 3) DISCONTINUITY * // If you use multiple output, you will lose output signal when you change * // the output frequency even not specific CLKn during I2C acccess. * // -------------------------------------------------------------------------- * * @endcode */ class SI5351A { public: /** Configure data pin * @param data SDA and SCL pins * @param External base clock frequency * @param Internal capacitor value (10pF, 8pF & 6pF/ Default 8pF) * @param Output current drive strength(Default 2mA) same value CLK0,1,2 */ SI5351A(PinName p_sda, PinName p_scl, uint32_t base_clk_freq, uint8_t xtal_cap = SI5351_CRYSTAL_LOAD_8PF, uint8_t drive_current = SI5351_CLK_DRIVE_STRENGTH_2MA ); /** Configure data pin (with other devices on I2C line) * @param I2C previous definition * @param External base clock frequency * @param Internal capacitor value (10pF, 8pF & 6pF/ Default 8pF) * @param Output current drive strength(Default 2mA) same value CLK0,1,2 */ SI5351A(I2C& p_i2c, uint32_t base_clk_freq, uint8_t xtal_cap = SI5351_CRYSTAL_LOAD_8PF, uint8_t drive_current = SI5351_CLK_DRIVE_STRENGTH_2MA ); /** Set frequency * @param output channel CLK0=0, CLK1=1, CLK2=2 * @param target frequency (unit = Hz) * @return output frequency */ uint32_t set_frequency(uint8_t channel, uint32_t freq); /** shift frequency after setting frequency (Range: 750KHz to 100MHz ) * @param desired channel CLK0=0, CLK1=1, CLK2=2 * @param sift(+/-) frequency (unit = Hz) * @return output frequency */ uint32_t shift_freq(uint8_t channel, int32_t diff); /** read frequency * @param select channel CLK0=0, CLK1=1, CLK2=2 * @return output frequency */ uint32_t read_freq(uint8_t channel); /** reset Si5351A all registers * @param none * @return none */ void all_reset(void); //--------------- Debug interface ------------------------------------------ /** debug / print registers * @param none * @return none (but print on console) */ void debug_reg_print(void); /** debug / check registers and shows current configlation * @param none * @return none (but print on console) */ void debug_current_config(void); /** debug / set CLK0: 120.00MHz, CLK1: 12.00MHz, CLK2: 13.56MHz * as demonstration purpose for hardware check (@25MHz Xtal) * @param none * @return none */ void debug_example_clock(void); protected: I2C _i2c; uint32_t gcd(uint32_t x, uint32_t y); void si5351_read(const uint8_t *buf); void si5351_write(uint8_t reg, uint8_t dat); void si5351_bulk_write(const uint8_t *buf, uint8_t len); double si5351_set_frequency_fixeddiv( uint8_t channel, uint32_t pll, uint32_t freq, uint32_t div); double si5351_set_frequency_fixedpll( uint8_t channel, uint32_t pll, uint32_t pllfreq, uint32_t freq, uint8_t factor); double si5351_setupMultisynth( uint8_t output, uint8_t pllSource, uint32_t div, uint32_t num, uint32_t denom, uint8_t factor); void si5351_setupPLL( uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom); void si5351_reset_pll(void); void si5351_enable_output(void); void si5351_disable_output(void); void si5351_disable_all_output(void); void si5351_init(void); void put_dump(const uint8_t *buff, uint8_t ofs, uint8_t cnt); void prnt_reg(uint8_t offset, uint8_t n); void reg_16_17_18(uint8_t dt); void reg_pll_8bytes(uint8_t *buf); void reg_mltisyc_8bytes(uint8_t *buf); private: uint8_t addr; // Chip I2C address uint32_t base_freq; // Xtal oscilation freq. uint8_t x_cap; // Internal capacitor value uint8_t drv_current; // Output current drive strength uint32_t pll_freq; // XTAL * PLL_N uint32_t plla_freq; // Calculated freq of PLLA uint32_t pllb_freq; // Calculated freq of PLLB // Setting frequency double clk0_freq; double clk1_freq; double clk2_freq; // operating mode uint8_t clk0_state; uint8_t clk1_state; uint8_t clk2_state; }; // class SI5351A #endif // MBED_SI5351A