From ad9e17c35c2fc358e6660d179c844b14b92c5541 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 6 Mar 2020 11:09:35 +0100 Subject: WIP DSSS decoding --- controller/fw/Makefile | 10 ++++- controller/fw/cmsis | 2 +- controller/fw/libsodium | 2 +- controller/fw/src/dsss_demod.c | 61 ++++++++++++++++------------- controller/fw/tools/butter_filter_gen.py | 50 +++++++++++++++++++++++ controller/fw/tools/gold_code_header_gen.py | 8 +--- 6 files changed, 96 insertions(+), 37 deletions(-) create mode 100644 controller/fw/tools/butter_filter_gen.py (limited to 'controller') diff --git a/controller/fw/Makefile b/controller/fw/Makefile index cc7d156..6c5d5ea 100644 --- a/controller/fw/Makefile +++ b/controller/fw/Makefile @@ -46,12 +46,16 @@ FMEAS_ADC_MAX ?= 4096 FMEAS_FFT_LEN ?= 256 FMEAS_FFT_WINDOW ?= gaussian FMEAS_FFT_WINDOW_SIGMA ?= 16.0 +# TODO: validate +FMEAS_SAMPLING_RATE ?= 10.0 DSSS_GOLD_CODE_NBITS ?= 5 DSSS_DECIMATION ?= 10 DSSS_THESHOLD_FACTOR ?= 4.0f DSSS_WAVELET_WIDTH ?= 7.3 DSSS_WAVELET_LUT_SIZE ?= 69 +DSSS_FILTER_FC ?= 20e-3 +DSSS_FILTER_ORDER ?= 8 CC := $(PREFIX)gcc CXX := $(PREFIX)g++ @@ -122,7 +126,7 @@ LDFLAGS += -L$(OPENCM3_DIR_ABS)/lib -l$(OPENCM3_LIB) $(shell $(CC) -print-libg all: $(BUILDDIR)/$(BINARY) -src/dsss_demod.c: $(BUILDDIR)/generated/dsss_gold_code.h +src/dsss_demod.c: $(BUILDDIR)/generated/dsss_gold_code.h $(BUILDDIR)/generated/dsss_butter_filter.h $(BUILDDIR)/generated/dsss_gold_code.h: $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).h ln -srf $< $@ @@ -139,6 +143,10 @@ $(BUILDDIR)/generated/fmeas_fft_window.c: | $(BUILDDIR)/generated $(BUILDDIR)/generated/dsss_cwt_wavelet.c: | $(BUILDDIR)/generated $(PYTHON3) tools/cwt_wavelet_header_gen.py -v dsss_cwt_wavelet_table $(DSSS_WAVELET_LUT_SIZE) $(DSSS_WAVELET_WIDTH) > $@ +.PRECIOUS: $(BUILDDIR)/generated/dsss_butter_filter.h +$(BUILDDIR)/generated/dsss_butter_filter.h: | $(BUILDDIR)/generated + $(PYTHON3) tools/butter_filter_gen.py -m dsss_filter $(DSSS_FILTER_FC) $(FMEAS_SAMPLING_RATE) $(DSSS_FILTER_ORDER) > $@ + $(BUILDDIR)/generated: ; mkdir -p $@ OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)) diff --git a/controller/fw/cmsis b/controller/fw/cmsis index 6a86f4c..4a65d88 160000 --- a/controller/fw/cmsis +++ b/controller/fw/cmsis @@ -1 +1 @@ -Subproject commit 6a86f4ca00d2b96b82879e1e5bd9e89c5750dd22 +Subproject commit 4a65d88011a1595b7c8b42fa0d70b7bdfc132acc diff --git a/controller/fw/libsodium b/controller/fw/libsodium index afae623..a0a8706 160000 --- a/controller/fw/libsodium +++ b/controller/fw/libsodium @@ -1 +1 @@ -Subproject commit afae623190f025e7cf2fb0222bfe796b69a36941 +Subproject commit a0a8706c9dc9e43bc51d16334cd6c0f6ae084ce9 diff --git a/controller/fw/src/dsss_demod.c b/controller/fw/src/dsss_demod.c index ec54d41..7a2e0cc 100644 --- a/controller/fw/src/dsss_demod.c +++ b/controller/fw/src/dsss_demod.c @@ -11,17 +11,14 @@ #include "simulation.h" #include "generated/dsss_gold_code.h" +#include "generated/dsss_butter_filter.h" /* Generated CWT wavelet LUT */ extern const float * const dsss_cwt_wavelet_table; -struct iir_biquad cwt_filter_bq[3] = { - {.a = {-1.993939440f, 0.993949280f}, .b = {0.2459934300683e-5, 0.4919868601367e-5, 0.2459934300683e-5}}, - {.a = {-1.995557124f, 0.995566972f}, .b = {0.2461930046414e-5, 0.4923860092828e-5, 0.2461930046414e-5}}, - {.a = {-1.998365254f, 0.998375115f}, .b = {0.2465394452097e-5, 0.4930788904195e-5, 0.2465394452097e-5}}, -}; +struct iir_biquad cwt_filter_bq[DSSS_FILTER_CLEN] = {DSSS_FILTER_COEFF}; -float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx); +float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx, bool debug); float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx); float run_iir(const float x, const int order, const struct iir_biquad q[order], struct iir_biquad_state st[order]); float run_biquad(float x, const struct iir_biquad *const q, struct iir_biquad_state *const restrict st); @@ -34,7 +31,7 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) { //#define DEBUG_PRINT(...) ((void)0) //#define DEBUG_PRINTN(...) ((void)0) - bool debug = sim_pos % DSSS_CORRELATION_LENGTH == 0; + bool debug = sim_pos % DSSS_CORRELATION_LENGTH == DSSS_CORRELATION_LENGTH-1; if (debug) DEBUG_PRINT("Iteration %zd", sim_pos); //const float peak_group_threshold = 0.05 * DSSS_CORRELATION_LENGTH; //const float hole_patching_threshold = 0.01 * DSSS_CORRELATION_LENGTH; @@ -45,14 +42,14 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) { /* use new, incremented wpos for gold_correlate_step as first element of old data in ring buffer */ for (size_t i=0; icorrelation[i][st->correlation_wpos] = gold_correlate_step(i, st->signal, st->correlation_wpos); + st->correlation[i][st->correlation_wpos] = gold_correlate_step(i, st->signal, st->signal_wpos, debug); /* debug */ - /* - DEBUG_PRINTN(" correlation: ["); - for (size_t i=0; icorrelation[i][st->correlation_wpos]); - DEBUG_PRINTN("]\n"); - */ + if (debug) { + DEBUG_PRINTN(" correlation: ["); + for (size_t i=0; icorrelation[i][st->correlation_wpos]); + DEBUG_PRINTN("]\n"); + } /* end */ st->correlation_wpos = (st->correlation_wpos + 1) % ARRAY_LENGTH(st->correlation[0]); @@ -60,10 +57,12 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) { for (size_t i=0; icorrelation[i], st->correlation_wpos); /* debug */ + /* if (debug) DEBUG_PRINTN(" cwt: ["); for (size_t i=0; igroup.max_ch; int max_idx = st->group.max_idx + 1; bool found = false; - if (debug) DEBUG_PRINTN(" rel: ["); + //if (debug) DEBUG_PRINTN(" rel: ["); for (size_t i=0; i DSSS_THESHOLD_FACTOR) found = true; @@ -96,7 +95,7 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) { max_idx = st->group.len; } } - if (debug) DEBUG_PRINTN("]\n"); + //if (debug) DEBUG_PRINTN("]\n"); /* debug */ if (debug) DEBUG_PRINT(" found=%d len=%d idx=%d ch=%d max=%f", @@ -162,19 +161,27 @@ float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx) { * * [0] https://docs.scipy.org/doc/numpy/reference/generated/numpy.correlate.html */ -float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx) { +float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx, bool debug) { + float acc_outer = 0.0f; uint8_t table_byte = 0; - for (size_t i=0, pos=0; i>3]; /* Fetch sequence table item */ - int bv = table_byte & (1<<(pos&7)); /* Extract bit */ - bv = !!bv*2 - 1; /* Map 0, 1 -> -1, 1 */ - acc_inner += a[(offx + i + j) % DSSS_CORRELATION_LENGTH] * bv; /* Multiply item */ + if (debug) DEBUG_PRINTN("Correlate n=%d: ", ncode); + for (size_t i=0; i>3]; /* Fetch sequence table item */ + if (debug) DEBUG_PRINTN("|"); } - acc_outer += acc_inner; + int bv = table_byte & (0x80>>(i&7)); /* Extract bit */ + bv = !!bv*2 - 1; /* Map 0, 1 -> -1, 1 */ + if (debug) DEBUG_PRINTN("%s%d\033[0m", bv == 1 ? "\033[92m" : "\033[91m", (bv+1)/2); + + float acc_inner = 0.0f; + for (size_t j=0; j