forked from M-Labs/artiq
1
0
Fork 0

coredevice: adf5355: more general PLL parameters calculation

Signed-off-by: Etienne Wodey <wodey@iqo.uni-hannover.de>
This commit is contained in:
Etienne Wodey 2020-11-09 18:09:50 +01:00 committed by Sébastien Bourdeauducq
parent b856df7c35
commit d433f6e86d
1 changed files with 24 additions and 11 deletions

View File

@ -474,6 +474,18 @@ class ADF5355:
return int32(r) return int32(r)
@portable
def gcd(a, b):
while b:
a, b = b, a % b
return a
@portable
def split_msb_lsb_28b(v):
return int32((v >> 14) & 0x3FFF), int32(v & 0x3FFF)
@portable @portable
def calculate_pll(f_vco: TInt64, f_pfd: TInt64): def calculate_pll(f_vco: TInt64, f_pfd: TInt64):
""" """
@ -489,20 +501,21 @@ def calculate_pll(f_vco: TInt64, f_pfd: TInt64):
f_vco = int64(f_vco) f_vco = int64(f_vco)
# integral part # integral part
n = int32(f_vco / f_pfd) n, r = int32(f_vco // f_pfd), f_vco % f_pfd
r = f_vco / f_pfd - n
# main fractional part # main fractional part
frac1 = int32(ADF5355_MODULUS1 * r) r *= ADF5355_MODULUS1
r = r * ADF5355_MODULUS1 - frac1 frac1, frac2 = int32(r // f_pfd), r % f_pfd
# auxiliary fractional part # auxiliary fractional part
# FIXME: calculate optimal MOD2 mod2 = f_pfd
mod2 = ADF5355_MAX_MODULUS2
frac2 = int32(r * mod2)
# split frac2, mod2 while mod2 > ADF5355_MAX_MODULUS2:
frac2_msb, frac2_lsb = (frac2 >> 14) & 0x3FFF, frac2 & 0x3FFF mod2 >>= 1
mod2_msb, mod2_lsb = (mod2 >> 14) & 0x3FFF, mod2 & 0x3FFF frac2 >>= 1
return n, frac1, (frac2_msb, frac2_lsb), (mod2_msb, mod2_lsb) gcd_div = gcd(frac2, mod2)
mod2 //= gcd_div
frac2 //= gcd_div
return n, frac1, split_msb_lsb_28b(frac2), split_msb_lsb_28b(mod2)