Added some hacky ppm correction
This commit is contained in:
parent
87a2720701
commit
a83f1346de
|
@ -8,12 +8,18 @@ int main(void) {
|
|||
|
||||
twi_init();
|
||||
|
||||
si5351_init(25000000, 400000000, 300000000);
|
||||
si5351_ms_set_source(SI5351_MS0, SI5351_PLLB);
|
||||
si5351_ms_set_freq(SI5351_MS0, 7165000);
|
||||
si5351_init(25000000, 800000000, 500000000);
|
||||
si5351_ms_set_source(SI5351_MS0, SI5351_PLLA);
|
||||
uint32_t base = 7165000;
|
||||
uint32_t ppm_err = 9;
|
||||
uint32_t err = base * ppm_err / 1000000;
|
||||
uint32_t target = base - err;
|
||||
|
||||
si5351_ms_set_freq(SI5351_MS0, target);
|
||||
si5351_ms_enable_output(SI5351_MS0);
|
||||
|
||||
|
||||
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
PLL_FREQ = 800*10**6 # Mhz
|
||||
|
||||
def main():
|
||||
# 8kHz to 150MHz
|
||||
out_freq = np.uint32(np.arange(1*10**6, 160*10**6, 10))
|
||||
|
||||
fdiv = PLL_FREQ / out_freq
|
||||
rm = PLL_FREQ % out_freq
|
||||
|
||||
c = np.uint32(0x0FFFFF);
|
||||
a = np.uint32(fdiv)
|
||||
b = np.uint32(np.uint64(c) * np.uint64(rm) / out_freq)
|
||||
|
||||
ideal_freq = PLL_FREQ / fdiv
|
||||
real_freq = PLL_FREQ / (a + b/c)
|
||||
|
||||
err = (ideal_freq - real_freq)
|
||||
out_freq = out_freq / 10**6
|
||||
ideal_freq = ideal_freq / 10**6
|
||||
real_freq = real_freq / 10**6
|
||||
|
||||
|
||||
p1 = 128 * a + np.floor(128 * b / c) - 512;
|
||||
p2 = 128 * b - c * np.uint32(128 * b / c);
|
||||
|
||||
|
||||
#plt.plot(out_freq, ideal_freq)
|
||||
#plt.plot(out_freq, real_freq)
|
||||
|
||||
plt.plot(out_freq, err)
|
||||
|
||||
|
||||
|
||||
|
||||
plt.show()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python3
|
||||
from fractions import Fraction
|
||||
from math import floor
|
||||
|
||||
|
||||
PLL_FREQ = 900.0 * 10**6
|
||||
|
||||
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():
|
||||
print("struct si5351_params wspr_symbols[%d] = {" % SYMBOL_COUNT)
|
||||
|
||||
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))
|
||||
|
||||
# See https://www.silabs.com/documents/public/application-notes/AN619.pdf
|
||||
p1 = 128 * a + floor(128 * b/c) + 512
|
||||
p2 = 128 * b - c * floor(128 * b/c)
|
||||
p3 = c
|
||||
|
||||
print("\t{%d, %d, %d}," % (p1, p2, p3))
|
||||
|
||||
print("}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -62,7 +62,8 @@ void si5351_ms_set_freq(enum si5351_multisynth synth, uint32_t freq) {
|
|||
//TODO: Find better way to determine c and b
|
||||
uint32_t c = 0x0FFFFF;
|
||||
uint32_t a = fdiv;
|
||||
uint32_t b = (uint32_t) ((uint64_t) rm * (uint64_t) c / (uint64_t) freq);
|
||||
uint32_t b = (uint32_t) ((uint64_t) rm * (uint64_t) c / freq);
|
||||
|
||||
uint32_t p1 = 128 * a + (128 * b / c) - 512;
|
||||
uint32_t p2 = 128 * b - c * (128 * b / c);
|
||||
uint32_t p3 = c;
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue