Author | Rob Jansen, Copyright © 2020..2020, all rights reserved. |
Adapted-by | |
Compiler | 2.5r4 |
Libray for use of the Si5351a clock generator.
Inspired by the following sources: -) https://github.com/etherkit/Si5351Arduino -) https://radiotransmitter.wordpress.com/2017/02/23/a-simple-software-to-control-the-si5351a-generator-chip/ -) https://www.rfzero.net/tutorials/si5351a/ Application note AN619 from Silicon Labs.
The following IIC pins must be defined by the main program before including this library: -) alias si5351a_scl -- To SCL of SI5351 -) alias si5351a_scl_direction -) alias si5351a_sda -- To SDA of SI5351 -) alias si5351a_sda_direction
No dependency found
const byte _SI5351A_MASK_MSX_SRC = 0b0010_0000
const byte _SI5351A_CLOCK0_CONTROL = 16
const byte _SI5351A_MASK_CLKX_INV = 0b0001_0000
const byte _SI5351A_OUTPUT_ENABLE_PIN = 9
var dword _si5351a_pll_a_frequency
const byte SI5351A_CLOCK_SOURCE_XTAL = 0b0000_0000
const byte _SI5351A_MULTISYNTH_6_PARAMETERS = 90
const byte _SI5351A_MASK_PLL_B_RESET = 0b1000_0000
var byte _si5351a_ms_register_data[8]
const byte _SI5351A_MASK_CLKX_PDN = 0b1000_0000
const byte _SI5351A_FANOUT_ENABLE = 187
const byte _SI5351A_NO_PLL = 0xFF
const byte _SI5351A_MASK_PLL_XTAL_SOURCE = 0b0000_1100
const byte SI5351A_PLL_A = 0
const byte _SI5351A_CLOCK7_4_DISABLE_STATE = 25
const byte SI5351A_CLOCK_7 = 7
const byte _SI5351A_MASK_LOL_A = 0b0010_0000
const byte SI5351A_CLOCK_DRIVE_8_MA = 0x03
const byte _SI5351A_MASK_CLKX_IDRV = 0b1111_1100
const byte _SI5351A_MASK_XO_FANOUT_ENABLE = 0b0100_0000
const byte _SI5351A_CLOCK3_0_DISABLE_STATE = 24
const byte SI5351A_CLOCK_4 = 4
const byte SI5351A_CRYSTAL_LOAD_10_PF = 0b1101_0010
const byte _SI5351A_PLL_INPUT_SOURCE = 15
const byte _SI5351A_MASK_CLKX_PHASE_OFFSET = 0b0111_1111
const byte _SI5351A_MASK_CLKX_SOURCE = 0b1111_0011
const byte _SI5351A_MULTISYNTH_7_PARAMETERS = 91
const byte _SI5351A_CRYSTAL_LOAD_CAPACITANCE = 183
const byte _SI5351A_DEVICE_STATUS = 0
const byte _SI5351A_MASK_MSX_INT = 0b0100_0000
const byte _SI5351A_CLOCK0_INITIAL_PHASE_OFFSET = 165
var dword _si5351a_pll_b_frequency
const byte _SI5351A_MASK_MS_FANOUT_ENABLE = 0b0001_0000
const byte SI5351A_PLL_B = 1
const byte _SI5351A_PLL_RESET = 177
const word _i2c_bus_speed = 1
const byte _SI5351A_MASK_FBA_INT = 0b0100_0000
const byte SI5351A_CLOCK_DRIVE_4_MA = 0x01
const byte _SI5351A_MASK_REVID = 0b0000_0011
const byte SI5351A_MIN_CLOCK = 1
const dword SI5351A_MAX_OUT_FREQUENCY = 225_000_000
const byte _SI5351A_MASK_CLKX_DIS_STATE = 0b0000_0011
const byte SI5351A_CLOCK_DISABLE_STATE_NEVER = 0x03
const byte _SI5351A_MASK_LOS_XTAL = 0b0000_1000
const dword SI5351A_MIN_OUT_FREQUENCY = 2_500
const byte SI5351A_CLOCK_0 = 0
const byte SI5351A_CRYSTAL_LOAD_6_PF = 0b0101_0010
const byte _SI5351A_OUTPUT_ENABLE_CONTROL = 3
const dword SI5351A_MAX_PLL_FREQUENCY = 900_000_000
const dword _SI5351A_FRACTIONAL_FREQUENCY = 150_000_000
var _si5351a_clock_setting _si5351a_clock_output[SI5351A_MAX_CLOCK]
const byte SI5351A_CLOCK_SOURCE_MULTISYNTH_X = 0b0000_1100
const byte SI5351A_CLOCK_3 = 3
const byte _SI5351A_MASK_SYS_INIT = 0b1000_0000
const byte SI5351A_MAX_CLOCK = 8
const byte _SI5351A_MULTISYNTH_NA_PARAMETERS = 26
const byte SI5351A_CLOCK_DRIVE_2_MA = 0x00
const byte _SI5351A_CLOCK_6_7_OUTPUT_DIVIDER = 92
const byte SI5351A_CLOCK_1 = 1
const byte SI5351A_CLOCK_DISABLE_STATE_LOW = 0x00
const byte SI5351A_CLOCK_5 = 5
const byte SI5351A_CLOCK_6 = 6
const byte _SI5351A_MASK_LOL_B = 0b0100_0000
const byte SI5351A_CLOCK_SOURCE_MULTISYNTH_0_4 = 0b0000_1000
const byte SI5351A_CLOCK_DISABLE_STATE_FLOAT = 0x02
const byte _SI5351A_MULTISYNTH_0_PARAMETERS = 42
const byte SI5351A_CLOCK_2 = 2
const byte SI5351A_CRYSTAL_LOAD_8_PF = 0b1001_0010
const byte _SI5351A_MASK_FBB_INT = 0b0100_0000
const byte _SI5351A_MULTISYNTH_NB_PARAMETERS = 34
const byte _SI5351A_MASK_PLL_A_RESET = 0b0010_0000
const byte SI5351A_CLOCK_DRIVE_6_MA = 0x02
const dword SI5351A_MIN_PLL_FREQUENCY = 600_000_000
const byte SI5351A_CLOCK_DISABLE_STATE_HIGH = 0x01
si5351a_enable_clock_output(byte in clock)
si5351a_power_up_clock_output(byte in clock)
si5351a_set_multisynth_integer_mode(byte in clock)
si5351a_set_force_feedback_a_multisynth_fractional_mode()
si5351a_set_clock_drive_strength(byte in clock, byte in strength)
si5351a_set_multisynth_source_pll_b(byte in clock)
si5351a_set_force_feedback_b_multisynth_fractional_mode()
si5351a_set_clock_output_not_inverted(byte in clock)
si5351a_power_down_clock_output(byte in clock)
si5351a_disable_clock_output(byte in clock)
si5351a_enable_xo_fanout()
si5351a_set_multisynth_fractional_mode(byte in clock)
si5351a_set_clock_disable_state(byte in clock, byte in disable_state)
si5351a_set_initial_phase_offset(byte in clock, byte in phase_offset)
si5351a_disable_xo_fanout()
si5351a_set_force_feedback_b_multisynth_integer_mode()
si5351a_reset_pll_a()
si5351a_set_force_feedback_a_multisynth_integer_mode()
si5351a_reset_pll_b()
si5351a_enable_multisynth_fanout()
si5351a_disable_multisynth_fanout()
si5351a_set_multisynth_source_pll_a(byte in clock)
si5351a_init()
si5351a_set_clock_output_inverted(byte in clock)
si5351a_set_clock_input_source(byte in clock, byte in source)
si5351a_set_crystal_load_capacitance(byte in load_capacitance)
_store_multisynth_data(byte in start_register)
_si5351a_update_all_clocks()
_si5351a_write_register(byte in register, byte in data)
_si5351a_calculate_pll_setting(dword in pll_frequency)
si5351a_pll_b_is_locked() return bit
si5351a_set_frequency(dword in frequency, byte in clock) return bit
si5351a_crystal_signal_is_valid() return bit
si5351a_pll_a_is_locked() return bit
si5351a_get_revision_id() return byte
_si5351a_recalculate_outputs(byte in which_pll) return bit
_si5351a_pll_on_clock(byte in which_pll) return byte
_si5351a_read_register(byte in register) return byte
_si5351a_determine_maximum_pll_frequency() return dword
const byte _SI5351A_MASK_MSX_SRC = 0b0010_0000
X = 0..7
const byte _SI5351A_CLOCK0_CONTROL = 16
Used as base for clock 0..7.
const byte _SI5351A_MASK_CLKX_INV = 0b0001_0000
X = 0..7
const byte _SI5351A_OUTPUT_ENABLE_PIN = 9
No documentation found
var dword _si5351a_pll_a_frequency
Variable that holds the currently set PLL A frequency.
const byte SI5351A_CLOCK_SOURCE_XTAL = 0b0000_0000
Clock sources. Values valid for the SI5351A version only.
const byte _SI5351A_MULTISYNTH_6_PARAMETERS = 90
No documentation found
const byte _SI5351A_MASK_PLL_B_RESET = 0b1000_0000
No documentation found
var byte _si5351a_ms_register_data[8]
Array that holds data for the 8 multisynth registers.
const byte _SI5351A_MASK_CLKX_PDN = 0b1000_0000
X = 0..7
const byte _SI5351A_FANOUT_ENABLE = 187
No documentation found
const byte _SI5351A_NO_PLL = 0xFF
Internal PLL constant, must not be equal to SI5351A_PLL_A or SI5351A_PLL_B
const byte _SI5351A_MASK_PLL_XTAL_SOURCE = 0b0000_1100
No documentation found
const byte SI5351A_PLL_A = 0
PLL constants.
const byte _SI5351A_CLOCK7_4_DISABLE_STATE = 25
No documentation found
const byte SI5351A_CLOCK_7 = 7
No documentation found
const byte _SI5351A_MASK_LOL_A = 0b0010_0000
No documentation found
const byte SI5351A_CLOCK_DRIVE_8_MA = 0x03
No documentation found
const byte _SI5351A_MASK_CLKX_IDRV = 0b1111_1100
X = 0..7
const byte _SI5351A_MASK_XO_FANOUT_ENABLE = 0b0100_0000
No documentation found
const byte _SI5351A_CLOCK3_0_DISABLE_STATE = 24
No documentation found
const byte SI5351A_CLOCK_4 = 4
No documentation found
const byte SI5351A_CRYSTAL_LOAD_10_PF = 0b1101_0010
No documentation found
const byte _SI5351A_PLL_INPUT_SOURCE = 15
No documentation found
const byte _SI5351A_MASK_CLKX_PHASE_OFFSET = 0b0111_1111
X = 0..7
const byte _SI5351A_MASK_CLKX_SOURCE = 0b1111_0011
X = 0..7
const byte _SI5351A_MULTISYNTH_7_PARAMETERS = 91
No documentation found
const byte _SI5351A_CRYSTAL_LOAD_CAPACITANCE = 183
No documentation found
const byte _SI5351A_DEVICE_STATUS = 0
Registers.
const byte _SI5351A_MASK_MSX_INT = 0b0100_0000
X = 0..7
const byte _SI5351A_CLOCK0_INITIAL_PHASE_OFFSET = 165
Used as base for clock 0..7.
var dword _si5351a_pll_b_frequency
Variable that holds the currently set PLL B frequency.
const byte _SI5351A_MASK_MS_FANOUT_ENABLE = 0b0001_0000
No documentation found
const byte SI5351A_PLL_B = 1
No documentation found
const byte _SI5351A_PLL_RESET = 177
No documentation found
const word _i2c_bus_speed = 1
100kHz
const byte _SI5351A_MASK_FBA_INT = 0b0100_0000
No documentation found
const byte SI5351A_CLOCK_DRIVE_4_MA = 0x01
No documentation found
const byte _SI5351A_MASK_REVID = 0b0000_0011
No documentation found
const byte SI5351A_MIN_CLOCK = 1
Output clocks. Note that the 10-pin version only has clock outputs 0..2.
const dword SI5351A_MAX_OUT_FREQUENCY = 225_000_000
No documentation found
const byte _SI5351A_MASK_CLKX_DIS_STATE = 0b0000_0011
X = 0..7
const byte SI5351A_CLOCK_DISABLE_STATE_NEVER = 0x03
No documentation found
const byte _SI5351A_MASK_LOS_XTAL = 0b0000_1000
No documentation found
const dword SI5351A_MIN_OUT_FREQUENCY = 2_500
Clock frequency ranges in Hz. Range is from 2.5 kHz to 225 MHz. The chip mentioned 200 MHz but the maximum clock it can produce is the maximum PLL frequency of 900 MHz divided by 4 which is 225 MHz
const byte SI5351A_CLOCK_0 = 0
No documentation found
const byte SI5351A_CRYSTAL_LOAD_6_PF = 0b0101_0010
Crystal load capacitance constants.
const byte _SI5351A_OUTPUT_ENABLE_CONTROL = 3
No documentation found
const dword SI5351A_MAX_PLL_FREQUENCY = 900_000_000
No documentation found
const dword _SI5351A_FRACTIONAL_FREQUENCY = 150_000_000
For clock frequencies above the 150 MHz we need to switch from fractional mode to integer mode. In this mode the output is just 4 times the PLL frequency.
var _si5351a_clock_setting _si5351a_clock_output[SI5351A_MAX_CLOCK]
Array that stores the current setting of the clock outputs.
const byte SI5351A_CLOCK_SOURCE_MULTISYNTH_X = 0b0000_1100
X = 0..7.
const byte SI5351A_CLOCK_3 = 3
No documentation found
const byte _SI5351A_MASK_SYS_INIT = 0b1000_0000
Register Masks.
const byte SI5351A_MAX_CLOCK = 8
No documentation found
const byte _SI5351A_MULTISYNTH_NA_PARAMETERS = 26
No documentation found
const byte SI5351A_CLOCK_DRIVE_2_MA = 0x00
Clock drive strength.
const byte _SI5351A_CLOCK_6_7_OUTPUT_DIVIDER = 92
No documentation found
const byte SI5351A_CLOCK_1 = 1
No documentation found
const byte SI5351A_CLOCK_DISABLE_STATE_LOW = 0x00
Clock disable states.
const byte SI5351A_CLOCK_5 = 5
No documentation found
const byte SI5351A_CLOCK_6 = 6
No documentation found
const byte _SI5351A_MASK_LOL_B = 0b0100_0000
No documentation found
const byte SI5351A_CLOCK_SOURCE_MULTISYNTH_0_4 = 0b0000_1000
No documentation found
const byte SI5351A_CLOCK_DISABLE_STATE_FLOAT = 0x02
High impedance state.
const byte _SI5351A_MULTISYNTH_0_PARAMETERS = 42
Used as base for clock 0..7
const byte SI5351A_CLOCK_2 = 2
No documentation found
const byte SI5351A_CRYSTAL_LOAD_8_PF = 0b1001_0010
No documentation found
const byte _SI5351A_MASK_FBB_INT = 0b0100_0000
No documentation found
const byte _SI5351A_MULTISYNTH_NB_PARAMETERS = 34
No documentation found
const byte _SI5351A_MASK_PLL_A_RESET = 0b0010_0000
No documentation found
const byte SI5351A_CLOCK_DRIVE_6_MA = 0x02
No documentation found
const dword SI5351A_MIN_PLL_FREQUENCY = 600_000_000
PLL frequencies in Hz.
const byte SI5351A_CLOCK_DISABLE_STATE_HIGH = 0x01
No documentation found
si5351a_enable_clock_output(byte in clock)
Enable the given clock output. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.
si5351a_power_up_clock_output(byte in clock)
Power up given clock output. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.
si5351a_set_multisynth_integer_mode(byte in clock)
Set multisynth in integer devision mode. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_5.
si5351a_set_force_feedback_a_multisynth_fractional_mode()
Set force feedback A multisynth in factional division mode.
si5351a_set_clock_drive_strength(byte in clock, byte in strength)
Set the multisynth as clock input source. Parameter clock must be between SI5351A_CLOCK_0 .. SI5351A_CLOCK_7. Drive strength must be one of the four values of SI5351A_CLOCK_DRIVE_X_MA (X = 2,4,6 or 8)
si5351a_set_multisynth_source_pll_b(byte in clock)
Set multisynth source to PLL B. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.
si5351a_set_force_feedback_b_multisynth_fractional_mode()
Set force feedback B multisynth in factional division mode.
si5351a_set_clock_output_not_inverted(byte in clock)
Set the clock output to not inverted. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.
si5351a_power_down_clock_output(byte in clock)
Power down given clock output. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.
si5351a_disable_clock_output(byte in clock)
Disable the given clock output. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7. The level of the output signal depends on the set clock disable state as defined by si5351a_set_clock_disable_state().
si5351a_enable_xo_fanout()
Enable fanout of XO to clock output multiplexers.
si5351a_set_multisynth_fractional_mode(byte in clock)
Set multisynth in factional division mode. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_5.
si5351a_set_clock_disable_state(byte in clock, byte in disable_state)
Set the clock disable state Parameter clock must be between SI5351A_CLOCK_0 .. SI5351A_CLOCK_7. Disable state must be one of the four values of SI5351A_CLOCK_DISABLE_STATE
si5351a_set_initial_phase_offset(byte in clock, byte in phase_offset)
Set initial clodk phase offset Parameter clock must be between SI5351A_CLOCK_0 .. SI5351A_CLOCK_5. The phase_offset is a 7 bit number in units of the VCO/4 period.
si5351a_disable_xo_fanout()
Disable fanout of XO to clock output multiplexers.
si5351a_set_force_feedback_b_multisynth_integer_mode()
Set force feedback B multisynth in integer division mode.
si5351a_reset_pll_a()
Reset PPL A.
si5351a_set_force_feedback_a_multisynth_integer_mode()
Set force feedback A multisynth in integer division mode.
si5351a_reset_pll_b()
Reset PPL B.
si5351a_enable_multisynth_fanout()
Enable fanout of Multisynth0 and Multisynth4 to all output multiplexers.
si5351a_disable_multisynth_fanout()
Disable fanout of Multisynth0 and Multisynth4 to all output multiplexers.
si5351a_set_multisynth_source_pll_a(byte in clock)
Set multisynth source to PLL A. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.
si5351a_init()
Initialize the IIC interface and the Si5351a device.
si5351a_set_clock_output_inverted(byte in clock)
Set the clock output to inverted. Parameter clock must be in range SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.
si5351a_set_clock_input_source(byte in clock, byte in source)
Set clock input source. Parameter clock must be between SI5351A_CLOCK_0 .. SI5351A_CLOCK_7. Source must be one of the values of SI5351A_CLOCK_SOURCE_XTAL, SI5351A_CLOCK_SOURCE_MULTISYNTH_0_4 or SI5351A_CLOCK_SOURCE_MUTLISYNTH_X. Note that SI5351A_CLOCK_SOURCE_MULTISYNTH_0_4 cannot be used for clock 0 and clock 4.
si5351a_set_crystal_load_capacitance(byte in load_capacitance)
Set the crystal load capacitance. Load capacitance must be one of the three values SI5351A_CRYSTAL_LOAD_X_PF (X = 6, 8 or 10)
_store_multisynth_data(byte in start_register)
Store the multisynth data available in the global array '_si5351a_ms_register_data' to the multisynth registers, starting at register 'start_register'.
_si5351a_update_all_clocks()
Update all clocks with the current settings. This means re-calculating all pll multisynth and output multisynth values and updating all registers. This function also assigns the clock source to the correct PLL.
_si5351a_write_register(byte in register, byte in data)
Write a byte to the given Si5351a register via IIC.
_si5351a_calculate_pll_setting(dword in pll_frequency)
Calculate the FMD divider. Note that we only use integer values so the PLL freqency has to be set in steps of SI5351A_CRYSTAL_FREQUENCY. The Feedback Multisynth Divider (FMD) = a + (b/c) and since we use only integers (b=0) this makes calculation straight forward. The FMD ratio can be from 15 + 0/1048575 and to 90 + 0/1048575 which is always the case for a PLL frequency between 600 MHz and 900 MHz and with a crystal frequency of 25 MHz or 27 MHz. The calculated values are stord in the global array _si5351a_ms_register_data
si5351a_pll_b_is_locked() return bit
Returns TRUE when PLL B is locked.
si5351a_set_frequency(dword in frequency, byte in clock) return bit
Set the given frequency on the given clock output. The frequency is given in Hz. Clock must be in range I5351A_CLOCK_0 .. SI5351A_CLOCK_7. This function selects the PLL automatically and tries to map the clocks as much as possible on the same PLL as to enable multiple frequencies on different clock outputs. The function returns TRUE when the frequency was set succesfully on the given clock output. Note that this function requires much more ROM code for mapping more clocks on the same PLL so if you do not need the feature use the function 'si5351a_set_frequency_manual' to limit ROM space.
si5351a_crystal_signal_is_valid() return bit
Returns TRUE when a valid crystal signal is detected.
si5351a_pll_a_is_locked() return bit
Returns TRUE when PLL A is locked.
si5351a_get_revision_id() return byte
Returns the revision id of the device.
_si5351a_recalculate_outputs(byte in which_pll) return bit
Recalculate all outputs on the given PLL by lowering the currently set PLL value. If a new PLL frequency is found it will be stored for all clocks that use that PLL.
_si5351a_pll_on_clock(byte in which_pll) return byte
Check if the given PLL is in use by any of the outputs, if so return the number of the output.
_si5351a_read_register(byte in register) return byte
Read a byte from the given Si5351a register via IIC.
_si5351a_determine_maximum_pll_frequency() return dword
Determine the maximum PLL frequency in steps of the crystal frequency. This will guarantee an integer value when setting the PLL frequency.
16f1825 | 16f1825_si5351a.jal |
16f18857 | 16f18857_si5351a.jal |