2018-07-07 01:51:20 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
from fractions import Fraction
|
|
|
|
from math import floor
|
|
|
|
|
|
|
|
|
2018-07-08 02:06:25 +02:00
|
|
|
PLL_FREQ = 800.0 * 10**6
|
2018-07-07 01:51:20 +02:00
|
|
|
|
|
|
|
SYMBOL_COUNT = 4
|
|
|
|
# http://www.g4jnt.com/wspr_coding_process.pdf
|
|
|
|
FREQ_SHIFT = Fraction(12000,8192) # What the fractional fuck?
|
|
|
|
|
|
|
|
# 7.040000 - 7.040200
|
|
|
|
BASE_FREQ = 7.040100 * 10**6
|
|
|
|
|
|
|
|
# Maximum c
|
|
|
|
MAX_DENOM = 0x0FFFFF
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
2018-07-08 02:06:25 +02:00
|
|
|
print("struct si5351_params WSPR_SYMBOLS[%d] = {" % SYMBOL_COUNT)
|
2018-07-07 01:51:20 +02:00
|
|
|
|
|
|
|
for i in range(0, SYMBOL_COUNT):
|
|
|
|
symbol_freq = Fraction(BASE_FREQ) + Fraction(i) * FREQ_SHIFT
|
|
|
|
|
|
|
|
divider = Fraction(PLL_FREQ) / symbol_freq
|
|
|
|
divider = divider.limit_denominator(MAX_DENOM)
|
|
|
|
|
|
|
|
a = floor(divider.numerator / divider.denominator)
|
|
|
|
b = divider.numerator % divider.denominator
|
|
|
|
c = divider.denominator
|
|
|
|
|
|
|
|
print("\t// %f: %d + %d / %d" % (symbol_freq, a, b, c))
|
2018-07-08 02:06:25 +02:00
|
|
|
actual = PLL_FREQ / (a + b/c)
|
|
|
|
print("\t// actual: %f" % actual)
|
2018-07-07 01:51:20 +02:00
|
|
|
|
|
|
|
# See https://www.silabs.com/documents/public/application-notes/AN619.pdf
|
2018-07-08 02:06:25 +02:00
|
|
|
p1 = 128 * a + floor(128 * b/c) - 512
|
2018-07-07 01:51:20 +02:00
|
|
|
p2 = 128 * b - c * floor(128 * b/c)
|
|
|
|
p3 = c
|
|
|
|
|
|
|
|
print("\t{%d, %d, %d}," % (p1, p2, p3))
|
|
|
|
|
2018-07-08 02:06:25 +02:00
|
|
|
print("};")
|
2018-07-07 01:51:20 +02:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|