See https://github.com/etherkit/Si5351Arduino for the maintained repo
Generic Si5351A3 control functions
Dana H. Myers K6JQ
General notes:
Development of these functions is currently on a PSoC 5LP freeSoC mini, which contains an ARM Cortex-M3. However, si5351.c and si5351.h should easily integrated into other C-language environments, including avr-gcc.
These functions depend on being fed sane parameters; there is only minimal error checking if you ask the Si5351 to do something it is not capable of, or if you ask it to do something conflicting (in particular, pay attention to output frequencies above 150MHz on CLK1 and CLK2 outputs (see below)).
I strongly suggest using only a single output of the Si5351 for RF applications, since there is a relatively large amount of cross-talk between the clock outputs.
The MultiSynth mode parameter can be used to force the clock divider into integer mode, which likely improves RF phase noise performance.
I2C functional interface macros (in si5351.h):
SI5351_WRITE_XFER(reg, datap, count) SI5351_READ_XFER(reg, datap, count) SI5351_WRITE_BYTE(reg, val) SI5351_READ_BYTE(reg) where:
uint8_t reg: register address in Si5351 uint8_t * datap: pointer to data buffer for read/write uint8_t count: count of bytes to transer uint8_t val: value to write Note: If datap == NULL, writes must be 0
void si5351_init(uint32_t freq_xtal, int32_t xtal_correction, int load_cap) Arguments:
freq_xtal: reference frequency source in Hz xtal_correct: correction factor in parts-per-10MHz for reference load_cap: load capacitance: SI5351_CRYSTAL_LOAD_6PF SI5351_CRYSTAL_LOAD_8PF SI5351_CRYSTAL_LOAD_10PF Busy-waits for Si5351A to complete power-on reset, initializes Si5351A3; disables and powers-down all clock outputs. Generates corrected reference frequency using the reference frequency source and correction factor.
void si5351_calibration_mode(int enable) Argument:
enable: 0 disables calibration mode, !0 enables Configures CLK0 to pass-through the crystal oscillator according to enable argument.
void si5351_clock_enable(enum si5351_clock clk, int enable) Arguments:
clk: clock output, one of: SI5351_CLK0 SI5351_CLK1 SI5351_CLK2 enable: 0 disables, !0 enables Enables the selected clock output. This function also powers-down disabled clock outputs.
void si5351_drive_strength(enum si5351_clock clk, enum si5351_drive drive) Arguments:
clk: clock output, one of: SI5351_CLK0 SI5351_CLK1 SI5351_CLK2 drive: one of: SI5351_DRIVE_2MA SI5351_DRIVE_4MA SI5351_DRIVE_6MA SI5351_DRIVE_8MA Sets the drive level for the selected clock output.
int32_t si5351_set_frequency(int32_t freq, int32_t pll_freq, enum si5351_clock clock, int reset) Arguments:
freq: desired frequency in Hz pll_freq: PLL frequency in Hz; 0 to allow selection clock: clock output to program, one of: SI5351_CLK0 SI5351_CLK1 SI5351_CLK2 reset: Force PLL reset after frequency change; required when changing above or below 150MHz. Programs the selected clock output to the chosen frequency 'freq'. If pll_freq == 0, the PLL is programmed to the highest usable frequency; if not 0, the PLL is programmed to this frequency. The PLL is programmed with a fractional divisor. If the chosen frequency 'freq' is between 150 and 160MHz, the PLL is fixed at 4 * freq. Invalid frequency selection is indicated with a return of -1, otherwise the PLL frequency used is returned.
Outputs CLK1 and CLK2 share the same PLL; the first output programmed determines the PLL frequency and the second output programmed will use this PLL frequency regardless of pll_freq. Further, ms_mode will be forced to MODE_FRAC for the second output programmed. Since a single PLL is shared, only one of CLK1 and CLK2 can generate a frequency above 150MHz and must be the first output programmed.