Added some hacky ppm correction

This commit is contained in:
Sebastian 2018-07-07 01:51:20 +02:00
parent 87a2720701
commit a83f1346de
5 changed files with 98 additions and 4 deletions

View File

@ -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);
}

View File

@ -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()

View File

@ -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()

View File

@ -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;

BIN
firmware/test Executable file

Binary file not shown.