Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: clockGenerator Check_Si5351A_Clock_generator t2d Thing2Do ... more
si5351a.h
00001 /* 00002 * mbed Library / Silicon Laboratories Inc. Si5351A-B-GT 00003 * I2C-PROGRAMMABLE ANY-FREQUENCY CMOS CLOCK GENERATOR 00004 * https://www.silabs.com/products/ 00005 * timing/clock-generator/si535x/pages/Si5351A-B-GM.aspx 00006 * 00007 * Checked on Nucleo-F411RE & F401RE mbed board 00008 * 00009 * Original & Reference program: 00010 * 1) 00011 * https://github.com/adafruit/Adafruit_Si5351_Library 00012 * see original source (bottom part of si5351a.cpp file) 00013 * Software License Agreement (BSD License) 00014 * Copyright (c) 2014, Adafruit Industries All rights reserved. 00015 * 2) 00016 * https://gist.github.com/edy555/f1ee7ef44fe4f5c6f7618ac4cbbe66fb 00017 * made by TT@Hokkaido-san (edy555) 00018 * http://ttrftech.tumblr.com/ 00019 * http://ttrftech.tumblr.com/post/150247113216/ 00020 * si5351a-configuration-how-to-and-signal-quality 00021 * 00022 * Modified by Kenji Arai / JH1PJL 00023 * http://www.page.sannet.ne.jp/kenjia/index.html 00024 * http://mbed.org/users/kenjiArai/ 00025 * 00026 * Started: December 24th, 2016 00027 * Revised: August 23rd, 2017 00028 * 00029 */ 00030 00031 #ifndef MBED_SI5351A 00032 #define MBED_SI5351A 00033 00034 #if 0 // Range extend mode -> set 1 00035 #define RANGE_EXTENDED 00036 #endif 00037 #if defined(RANGE_EXTENDED) 00038 #warning "Si5351A PLL range is only 600MHz to 900MHz." 00039 #warning "If you use RANGE_EXTENDED mode, PLL sets 250MHz to 1.3GHz." 00040 #warning "This causes high possibility to make a \ 00041 PARMANENT DAMAGE for the chip!!!!!" 00042 #warning "Don't use this mode!!!" 00043 #endif 00044 00045 ////////////// ADDRESS ///////////////////////////////////////////////////////// 00046 // 7bit address = 0b1100000(0x60) -> 8bit = 0b11000000(0xc0) 00047 // -> Fixed adddress (No other choises) 00048 #define SI5351_I2C_ADDR (0x60<<1) 00049 00050 ////////////// REGISTER DEFINITION ///////////////////////////////////////////// 00051 #define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3 00052 #define SI5351_REG_16_CLK0_CONTROL 16 00053 #define SI5351_REG_17_CLK1_CONTROL 17 00054 #define SI5351_REG_18_CLK2_CONTROL 18 00055 #define SI5351_REG_26_PLL_A 26 00056 #define SI5351_REG_34_PLL_B 34 00057 #define SI5351_REG_42_MULTISYNTH0 42 00058 #define SI5351_REG_44_MULTISYNTH0_P3 44 00059 #define SI5351_REG_50_MULTISYNTH1 50 00060 #define SI5351_REG_52_MULTISYNTH1_P3 52 00061 #define SI5351_REG_58_MULTISYNTH2 58 00062 #define SI5351_REG_60_MULTISYNTH2_P3 60 00063 #define SI5351_REG_177_PLL_RESET 177 00064 #define SI5351_REG_183_CRYSTAL_LOAD 183 00065 00066 ////////////// Configration //////////////////////////////////////////////////// 00067 // PLLn 00068 #define SI5351_PLL_A 0 00069 #define SI5351_PLL_B 1 00070 // CLKn 00071 #define SI5351_CLK0 0 00072 #define SI5351_CLK1 1 00073 #define SI5351_CLK2 2 00074 // REG_44_MULTISYNTH0, REG_52_MULTISYNTH1, REG_60_MULTISYNTH2 00075 #define SI5351_R_DIV_1 (0<<4) 00076 #define SI5351_R_DIV_2 (1<<4) 00077 #define SI5351_R_DIV_4 (2<<4) 00078 #define SI5351_R_DIV_8 (3<<4) 00079 #define SI5351_R_DIV_16 (4<<4) 00080 #define SI5351_R_DIV_32 (5<<4) 00081 #define SI5351_R_DIV_64 (6<<4) 00082 #define SI5351_R_DIV_128 (7<<4) 00083 #define SI5351_DIVBY4 (3<<2) 00084 // REG_16_CLK0_CONTROL, REG_17_CLK1_CONTROL, REG_18_CLK2_CONTROL 00085 #define SI5351_CLK_POWERDOWN (1<<7) 00086 #define SI5351_CLK_INTEGER_MODE (1<<6) 00087 #define SI5351_CLK_PLL_SELECT_B (1<<5) 00088 #define SI5351_CLK_INVERT (1<<4) 00089 #define SI5351_CLK_INPUT_MASK (3<<2) 00090 #define SI5351_CLK_INPUT_XTAL (0<<2) 00091 #define SI5351_CLK_INPUT_CLKIN (1<<2) 00092 #define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) 00093 #define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) 00094 #define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) 00095 #define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) 00096 #define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) 00097 #define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) 00098 #define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) 00099 // REG_177_PLL_RESET 00100 #define SI5351_PLL_RESET_B (1<<7) 00101 #define SI5351_PLL_RESET_A (1<<5) 00102 // REG_183_CRYSTAL_LOAD 00103 #define SI5351_CRYSTAL_LOAD_6PF (1<<6) 00104 #define SI5351_CRYSTAL_LOAD_8PF (2<<6) 00105 #define SI5351_CRYSTAL_LOAD_10PF (3<<6) 00106 00107 // Frequency 00108 #define FREQ_900MHZ (900000000UL) 00109 #define FREQ_600MHZ (600000000UL) 00110 #define FREQ_200MHZ (200000000UL) 00111 #define FREQ_150MHZ (150000000UL) 00112 #define FREQ_110MHZ (110000000UL) 00113 #define FREQ_1MHZ (1000000UL) 00114 #define FREQ_450KHZ (450000UL) 00115 #define FREQ_75KHZ (75000UL) 00116 #define FREQ_20KHZ (20000UL) 00117 00118 typedef enum { // Operating mode 00119 CLK_OUT_NOT_USED = 0, CLK_OUT_FIXEDPLL, CLK_OUT_FIXEDDIV 00120 } OperatingMode; 00121 00122 /** Silicon Laboratories Inc. Si5351A 00123 * 00124 * @code 00125 * #include "mbed.h" 00126 * #include "si5351a.h" 00127 * 00128 * I2C i2c(I2C_SDA, I2C_SCL); // communication with Si5351A 00129 * SI5351 clk(i2c, 25000000UL); // Base clock = 25MHz 00130 * 00131 * int main() { 00132 * clk.set_frequency(SI5351_CLK0, 10000000); // CLK0=10MHz 00133 * while(true) { 00134 * wait(1000); 00135 * } 00136 * } 00137 * 00138 * // --------- CAUTION & RESTRICTION ----------------------------------------- 00139 * // 1) SETTING METHOD 00140 * // 2.6KHz~100MHz: fixed PLL(around 900 or around 600MHz), fractional divider 00141 * // 100~150MHz: fractional PLL 600-900MHz, fixed divider 6 00142 * // 150~200MHz: fractional PLL 600-900MHz, fixed divider 4 00143 * // 00144 * // 2) RESOURCE USAGE 00145 * // PLLA -> only for CLK0 (You can change freqency any time to any value.) 00146 * // PLLB -> use for bothe CLK1 & CLK2 00147 * // If you set a freq. less than 100MHz, 00148 * // You can change both CLK1 & CLK2 independently. 00149 * // Over 100MHz, you may have a trouble becase need to change PLLB freq. 00150 * // 00151 * // 3) DISCONTINUITY 00152 * // If you use multiple output, you will lose output signal when you change 00153 * // the output frequency even not specific CLKn during I2C acccess. 00154 * // -------------------------------------------------------------------------- 00155 * 00156 * @endcode 00157 */ 00158 00159 class SI5351A 00160 { 00161 public: 00162 /** Configure data pin 00163 * @param data SDA and SCL pins 00164 * @param External base clock frequency 00165 * @param Internal capacitor value (10pF, 8pF & 6pF/ Default 8pF) 00166 * @param Output current drive strength(Default 2mA) same value CLK0,1,2 00167 */ 00168 SI5351A(PinName p_sda, PinName p_scl, 00169 uint32_t base_clk_freq, 00170 uint8_t xtal_cap = SI5351_CRYSTAL_LOAD_8PF, 00171 uint8_t drive_current = SI5351_CLK_DRIVE_STRENGTH_2MA 00172 ); 00173 00174 /** Configure data pin (with other devices on I2C line) 00175 * @param I2C previous definition 00176 * @param External base clock frequency 00177 * @param Internal capacitor value (10pF, 8pF & 6pF/ Default 8pF) 00178 * @param Output current drive strength(Default 2mA) same value CLK0,1,2 00179 */ 00180 SI5351A(I2C& p_i2c, 00181 uint32_t base_clk_freq, 00182 uint8_t xtal_cap = SI5351_CRYSTAL_LOAD_8PF, 00183 uint8_t drive_current = SI5351_CLK_DRIVE_STRENGTH_2MA 00184 ); 00185 00186 /** Set frequency 00187 * @param output channel CLK0=0, CLK1=1, CLK2=2 00188 * @param target frequency (unit = Hz) 00189 * @return output frequency 00190 */ 00191 uint32_t set_frequency(uint8_t channel, uint32_t freq); 00192 00193 /** shift frequency after setting frequency (Range: 750KHz to 100MHz ) 00194 * @param desired channel CLK0=0, CLK1=1, CLK2=2 00195 * @param sift(+/-) frequency (unit = Hz) 00196 * @return output frequency 00197 */ 00198 uint32_t shift_freq(uint8_t channel, int32_t diff); 00199 00200 /** read frequency 00201 * @param select channel CLK0=0, CLK1=1, CLK2=2 00202 * @return output frequency 00203 */ 00204 uint32_t read_freq(uint8_t channel); 00205 00206 /** compensation frequency 00207 * @param Target freuency (setting value) 00208 * @param Measured freuency (actual value) 00209 * @return none 00210 */ 00211 void f_compensation(uint32_t target_f, uint32_t measured_f); 00212 00213 /** reset Si5351A all registers 00214 * @param none 00215 * @return none 00216 */ 00217 void all_reset(void); 00218 00219 //--------------- Debug interface ------------------------------------------ 00220 00221 /** debug / print registers 00222 * @param none 00223 * @return none (but print on console) 00224 */ 00225 void debug_reg_print(void); 00226 00227 /** debug / check registers and shows current configlation 00228 * @param none 00229 * @return none (but print on console) 00230 */ 00231 void debug_current_config(void); 00232 00233 /** debug / set CLK0: 120.00MHz, CLK1: 12.00MHz, CLK2: 13.56MHz 00234 * as demonstration purpose for hardware check (@25MHz Xtal) 00235 * @param none 00236 * @return none 00237 */ 00238 void debug_example_clock(void); 00239 00240 protected: 00241 I2C *_i2c_p; 00242 I2C &_i2c; 00243 00244 uint32_t gcd(uint32_t x, uint32_t y); 00245 void si5351_read(const uint8_t *buf); 00246 void si5351_write(uint8_t reg, uint8_t dat); 00247 void si5351_bulk_write(const uint8_t *buf, uint8_t len); 00248 double si5351_set_frequency_fixeddiv( 00249 uint8_t channel, 00250 uint32_t pll, 00251 uint32_t freq, 00252 uint32_t div); 00253 double si5351_set_frequency_fixedpll( 00254 uint8_t channel, 00255 uint32_t pll, 00256 uint32_t pllfreq, 00257 uint32_t freq, 00258 uint8_t factor); 00259 double si5351_setupMultisynth( 00260 uint8_t output, 00261 uint8_t pllSource, 00262 uint32_t div, 00263 uint32_t num, 00264 uint32_t denom, 00265 uint8_t factor); 00266 void si5351_setupPLL( 00267 uint8_t pll, 00268 uint8_t mult, 00269 uint32_t num, 00270 uint32_t denom); 00271 void si5351_set_PLL_input_condition(uint32_t freq); 00272 void si5351_reset_pll(void); 00273 void si5351_enable_output(void); 00274 void si5351_disable_output(void); 00275 void si5351_disable_all_output(void); 00276 void si5351_init(void); 00277 void put_dump(const uint8_t *buff, uint8_t ofs, uint8_t cnt); 00278 void prnt_reg(uint8_t offset, uint8_t n); 00279 void reg_16_17_18(uint8_t dt); 00280 void reg_pll_8bytes(uint8_t *buf); 00281 void reg_mltisyc_8bytes(uint8_t *buf); 00282 00283 private: 00284 uint8_t addr; // Chip I2C address 00285 uint32_t base_freq; // Xtal oscilation freq. 00286 uint8_t x_cap; // Internal capacitor value 00287 uint8_t drv_current; // Output current drive strength 00288 uint8_t pll_n; // PLL div number (PLL_N) 00289 uint32_t pll_freq; // XTAL * pll_n 00290 uint32_t plla_freq; // Calculated freq of PLLA 00291 uint32_t pllb_freq; // Calculated freq of PLLB 00292 double compensation; // Compensation data 00293 // Setting frequency 00294 double clk0_freq; 00295 double clk1_freq; 00296 double clk2_freq; 00297 // operating mode 00298 uint8_t clk0_state; 00299 uint8_t clk1_state; 00300 uint8_t clk2_state; 00301 00302 }; // class SI5351A 00303 00304 #endif // MBED_SI5351A
Generated on Fri Jul 15 2022 10:58:14 by
