Si5351 adventures
A complicated little beast. 2 PLLs which can be integer (preferable, less jitter) or fractional multiples of the reference crystal oscillator. Max freq for a PLL is 900MHz with max crystal multipliers being in the range 15-90
After setting the PLL the output clocks are either integer or fractional divisors of the selected PLL. I believe the range is 4 to 900. If fractional then parameters need to be supplied in the format multiplier, numerator, denominator where numerator and denominator are limited to 20 bits (i.e. 1048575). Fortunately Python makes this pretty straightforward,
Here's some simple but crude code to calculate a spot frequency from a given PLL frequency:
from fractions import Fraction
def calc_freq(pll_freq, freq):
mult,rem = divmod(pll_freq, freq)
if mult < 4 or mult >900:
raise Exception("Target frequency produced invalid divider for the given PLL frequency")
frac=Fraction(rem/freq).limit_denominator(1048575)
return int(mult), frac.numerator, frac.denominator
def set_freq(clock,pll,freq):
m,n,d = calc_freq(pll.frequency,freq)
if d == 1:
clock.configure_integer(pll, m)
else:
clock.configure_fractional(pll,m,n,d )
set_freq(si5351.clock_1,si5351.pll_a,9.0e6) #sets clock1 to 9.0MHz
To divide down further there is an additional R-divide which can be applied to a specific clock, values are multiples of 2 from 1 to 128.