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
Diff: si5351a.h
- Revision:
- 0:47b9bfa03730
- Child:
- 1:a2309757c450
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/si5351a.h Sun Jan 01 01:21:34 2017 +0000
@@ -0,0 +1,280 @@
+/*
+ * 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 1st, 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