Implemented wspr test
This commit is contained in:
parent
a83f1346de
commit
2bc9b77ac4
|
@ -4,8 +4,8 @@ ISPPORT ?= /dev/kaboard
|
|||
|
||||
VERSION = 0.1
|
||||
|
||||
HEADERS = include/twi.h include/si5351.h
|
||||
SRC = main.c twi.c si5351.c
|
||||
HEADERS = include/twi.h include/si5351.h include/wspr.h
|
||||
SRC = main.c twi.c si5351.c wspr.c
|
||||
TARGET = cube-kl
|
||||
OBJDIR = bin
|
||||
|
||||
|
|
|
@ -31,6 +31,11 @@ enum si5351_reg {
|
|||
};
|
||||
|
||||
|
||||
struct si5351_params {
|
||||
uint32_t p1;
|
||||
uint32_t p2;
|
||||
uint32_t p3;
|
||||
};
|
||||
|
||||
static inline uint8_t si5351_write8(uint8_t reg, uint8_t value) {
|
||||
uint8_t data[3] = {reg, value};
|
||||
|
@ -42,8 +47,12 @@ void si5351_ms_enable_output(enum si5351_multisynth synth);
|
|||
void si5351_ms_disable_output(enum si5351_multisynth synth);
|
||||
void si5351_ms_set_source(enum si5351_multisynth synth, enum si5351_pll pll);
|
||||
void si5351_ms_set_freq(enum si5351_multisynth synth, uint32_t freq);
|
||||
uint8_t si5351_write_params(uint8_t base, uint32_t p1, uint32_t p2, uint32_t p3);
|
||||
|
||||
uint8_t si5351_write_params(uint8_t base, struct si5351_params params);
|
||||
|
||||
static inline void si5351_ms_write_params(enum si5351_multisynth synth, struct si5351_params params) {
|
||||
si5351_write_params(SI5351_MULTISYNTH_BASE[synth], params);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef __WSPR_H__
|
||||
#define __WSPR_H__ __WSPR_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "si5351.h"
|
||||
|
||||
|
||||
// For PLL with 800MHz
|
||||
static const struct si5351_params WSPR_SYMBOLS[4] = {
|
||||
// 7040100.000000: 113 + 44687 / 70401
|
||||
// actual: 7040100.000000
|
||||
{14033, 17455, 70401},
|
||||
// 7040101.464844: 113 + 447801 / 705503
|
||||
// actual: 7040101.464844
|
||||
{14033, 172785, 705503},
|
||||
// 7040102.929688: 113 + 38515 / 60682
|
||||
// actual: 7040102.929688
|
||||
{14033, 14678, 60682},
|
||||
// 7040104.394531: 113 + 123233 / 194166
|
||||
// actual: 7040104.394531
|
||||
{14033, 46378, 194166},
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t WSPR_LENGTH = 162;
|
||||
static const uint16_t WSPR_PERIOD = 683;
|
||||
|
||||
// DL1SSK at JN39we
|
||||
static uint8_t default_wspr_msg[162] = {
|
||||
1, 1, 0, 0, 2, 0, 0, 2, 1, 0, 0, 0, 1, 3, 3, 2, 2, 2, 3, 2, 0, 1, 0, 3, 1, 1, 1, 0, 2,
|
||||
2, 0, 2, 2, 0, 3, 0, 0, 1, 0, 3, 2, 0, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 3, 1, 2, 1, 0, 2,
|
||||
2, 3, 1, 2, 1, 2, 2, 2, 2, 3, 3, 2, 1, 2, 1, 2, 1, 2, 3, 2, 0, 3, 2, 0, 1, 0, 3, 3, 0,
|
||||
2, 2, 1, 1, 2, 1, 0, 1, 0, 2, 0, 1, 2, 2, 2, 0, 0, 3, 2, 2, 3, 0, 0, 1, 3, 3, 2, 3, 3,
|
||||
0, 2, 3, 1, 2, 1, 0, 2, 2, 3, 3, 3, 0, 2, 2, 0, 2, 1, 2, 1, 2, 0, 1, 3, 0, 0, 0, 0, 0,
|
||||
2, 0, 3, 1, 0, 1, 2, 3, 1, 2, 2, 2, 1, 1, 0, 0, 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
void wspr_transmit(enum si5351_multisynth synth, uint8_t *msg);
|
||||
|
||||
|
||||
#endif
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "twi.h"
|
||||
#include "si5351.h"
|
||||
#include "wspr.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
|
@ -10,16 +11,16 @@ int main(void) {
|
|||
|
||||
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);
|
||||
|
||||
|
||||
|
||||
//si5351_ms_set_freq(SI5351_MS0, 7040100);
|
||||
//si5351_ms_enable_output(SI5351_MS0);
|
||||
//si5351_ms_write_params(SI5351_MS0, WSPR_SYMBOLS[3]);
|
||||
|
||||
|
||||
wspr_transmit(SI5351_MS0, default_wspr_msg);
|
||||
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ from fractions import Fraction
|
|||
from math import floor
|
||||
|
||||
|
||||
PLL_FREQ = 900.0 * 10**6
|
||||
PLL_FREQ = 800.0 * 10**6
|
||||
|
||||
SYMBOL_COUNT = 4
|
||||
# http://www.g4jnt.com/wspr_coding_process.pdf
|
||||
|
@ -17,7 +17,7 @@ MAX_DENOM = 0x0FFFFF
|
|||
|
||||
|
||||
def main():
|
||||
print("struct si5351_params wspr_symbols[%d] = {" % SYMBOL_COUNT)
|
||||
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
|
||||
|
@ -30,15 +30,17 @@ def main():
|
|||
c = divider.denominator
|
||||
|
||||
print("\t// %f: %d + %d / %d" % (symbol_freq, a, b, c))
|
||||
actual = PLL_FREQ / (a + b/c)
|
||||
print("\t// actual: %f" % actual)
|
||||
|
||||
# See https://www.silabs.com/documents/public/application-notes/AN619.pdf
|
||||
p1 = 128 * a + floor(128 * b/c) + 512
|
||||
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("}")
|
||||
print("};")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -27,10 +27,13 @@ void si5351_init(uint32_t freq_xtal, uint32_t freq_a, uint32_t freq_b) {
|
|||
uint32_t c = 0x0FFFFF;
|
||||
uint32_t a = (uint32_t) fdiv;
|
||||
uint32_t b = (uint32_t) ((uint64_t) rm * (uint64_t) c / (uint64_t) freq_xtal);
|
||||
uint32_t p1 = 128 * a + (128 * b / c) - 512;
|
||||
uint32_t p2 = 128 * b - c * (128 * b / c);
|
||||
uint32_t p3 = c;
|
||||
si5351_write_params(SI5351_PLL_BASE_ADDR[i], p1, p2, p3);
|
||||
|
||||
struct si5351_params params = {
|
||||
128 * a + (128 * b / c) - 512,
|
||||
128 * b - c * (128 * b / c),
|
||||
c
|
||||
};
|
||||
si5351_write_params(SI5351_PLL_BASE_ADDR[i], params);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,25 +67,27 @@ void si5351_ms_set_freq(enum si5351_multisynth synth, uint32_t freq) {
|
|||
uint32_t a = fdiv;
|
||||
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;
|
||||
si5351_write_params(SI5351_MULTISYNTH_BASE[synth], p1, p2, p3);
|
||||
struct si5351_params params = {
|
||||
128 * a + (128 * b / c) - 512,
|
||||
128 * b - c * (128 * b / c),
|
||||
c
|
||||
};
|
||||
si5351_write_params(SI5351_MULTISYNTH_BASE[synth], params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t si5351_write_params(uint8_t base, uint32_t p1, uint32_t p2, uint32_t p3) {
|
||||
uint8_t si5351_write_params(uint8_t base, struct si5351_params params) {
|
||||
uint8_t data[9] = {
|
||||
base,
|
||||
(p3 & 0x00FF00) >> 8,
|
||||
p3 & 0x0000FF,
|
||||
(p1 & 0x030000) >> 16,
|
||||
(p1 & 0x00FF00) >> 8,
|
||||
p1 & 0x0000FF,
|
||||
((p3 & 0x0F0000) >> 12) | ((p2 & 0x0F0000) >> 16),
|
||||
(p2 & 0x00FF00) >> 8,
|
||||
p2 & 0x0000FF
|
||||
(params.p3 & 0x00FF00) >> 8,
|
||||
params.p3 & 0x0000FF,
|
||||
(params.p1 & 0x030000) >> 16,
|
||||
(params.p1 & 0x00FF00) >> 8,
|
||||
params.p1 & 0x0000FF,
|
||||
((params.p3 & 0x0F0000) >> 12) | ((params.p2 & 0x0F0000) >> 16),
|
||||
(params.p2 & 0x00FF00) >> 8,
|
||||
params.p2 & 0x0000FF
|
||||
};
|
||||
return twi_write(SI5351_ADDRESS, data, 9);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#include "wspr.h"
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
|
||||
void wspr_transmit(enum si5351_multisynth synth, uint8_t *msg) {
|
||||
si5351_ms_enable_output(synth);
|
||||
for(uint8_t i = 0; i < WSPR_LENGTH; i++) {
|
||||
uint8_t sym = msg[i];
|
||||
si5351_ms_write_params(synth, WSPR_SYMBOLS[sym]);
|
||||
_delay_ms(WSPR_PERIOD);
|
||||
}
|
||||
si5351_ms_disable_output(synth);
|
||||
}
|
Loading…
Reference in New Issue