Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vcocalc.py improvements #1773

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 43 additions & 14 deletions src/rp2_common/hardware_clocks/scripts/vcocalc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,32 @@

import argparse

# Fixed hardware parameters
fbdiv_range = range(16, 320 + 1)
postdiv_range = range(1, 7 + 1)
ref_min = 5
refdiv_min = 1
refdiv_max = 63

def validRefdiv(string):
if ((int(string) < refdiv_min) or (int(string) > refdiv_max)):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a minor nit, but I think personally I'd do the int(string) once, rather than three separate times?

raise ValueError("REFDIV must be in the range {} to {}".format(refdiv_min, refdiv_max))
return int(string)

parser = argparse.ArgumentParser(description="PLL parameter calculator")
parser.add_argument("--input", "-i", default=12, help="Input (reference) frequency. Default 12 MHz", type=float)
parser.add_argument("--ref-min", default=5, help="Override minimum reference frequency. Default 5 MHz", type=float)
parser.add_argument("--vco-max", default=1600, help="Override maximum VCO frequency. Default 1600 MHz", type=float)
parser.add_argument("--vco-min", default=750, help="Override minimum VCO frequency. Default 750 MHz", type=float)
parser.add_argument("--lock-refdiv", help="Lock REFDIV to specified number in the range {} to {}".format(refdiv_min, refdiv_max), type=validRefdiv)
parser.add_argument("--low-vco", "-l", action="store_true", help="Use a lower VCO frequency when possible. This reduces power consumption, at the cost of increased jitter")
parser.add_argument("output", help="Output frequency in MHz.", type=float)
args = parser.parse_args()

# Fixed hardware parameters
fbdiv_range = range(16, 320 + 1)
postdiv_range = range(1, 7 + 1)
ref_min = 5
refdiv_min = 1
refdiv_max = 63

refdiv_range = range(refdiv_min, max(refdiv_min, min(refdiv_max, int(args.input / args.ref_min))) + 1)
if args.lock_refdiv:
print("Locking REFDIV to", args.lock_refdiv)
refdiv_range = [args.lock_refdiv]

best = (0, 0, 0, 0, 0)
best_margin = args.output
Expand All @@ -33,13 +42,33 @@
for pd1 in postdiv_range:
out = vco / pd1 / pd2
margin = abs(out - args.output)
if margin < best_margin:
if ((vco * 1000) % (pd1 * pd2)):
continue
elif margin < best_margin:
best = (out, fbdiv, pd1, pd2, refdiv)
best_margin = margin

print("Requested: {} MHz".format(args.output))
print("Achieved: {} MHz".format(best[0]))
print("REFDIV: {}".format(best[4]))
print("FBDIV: {} (VCO = {} MHz)".format(best[1], args.input / best[4] * best[1]))
print("PD1: {}".format(best[2]))
print("PD2: {}".format(best[3]))
if best[0] > 0:
print("Requested: {} MHz".format(args.output))
print("Achieved: {} MHz".format(best[0]))
print("REFDIV: {}".format(best[4]))
print("FBDIV: {} (VCO = {} MHz)".format(best[1], args.input / best[4] * best[1]))
print("PD1: {}".format(best[2]))
print("PD2: {}".format(best[3]))
if best[4] != 1:
print(
"""
As the requires a non-standard refdiv, this will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"As the requires" -> "As this requires" ?

need to be set as a compile definition
Add the following to your CMakeLists.txt file to
configure the clocks as calculated above

target_compile_definitions(executable_name PRIVATE
PLL_SYS_REFDIV={}
PLL_SYS_VCO_FREQ_HZ={}
PLL_SYS_POSTDIV1={}
PLL_SYS_POSTDIV2={}
)\
""".format(best[4], int((args.input * 1_000_000) / best[4] * best[1]), best[2], best[3]))
else:
print("UNABLE TO COME UP WITH A SOLUTION....")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

Loading