From 4b419bd1ad9f22266e068341176f5ab665a26222 Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 5 Mar 2020 19:15:28 +0100 Subject: Working on DSSS demodulator sim --- controller/fw/src/dsss_demod.c | 180 +++++++++++++++++++++++++++++++++++++++++ controller/fw/src/dsss_demod.h | 44 ++++++++++ controller/fw/src/sr_global.h | 1 + 3 files changed, 225 insertions(+) create mode 100644 controller/fw/src/dsss_demod.c create mode 100644 controller/fw/src/dsss_demod.h (limited to 'controller/fw/src') diff --git a/controller/fw/src/dsss_demod.c b/controller/fw/src/dsss_demod.c new file mode 100644 index 0000000..ec54d41 --- /dev/null +++ b/controller/fw/src/dsss_demod.c @@ -0,0 +1,180 @@ + +#include +#include +#include + +#include + +#include "freq_meas.h" +#include "sr_global.h" +#include "dsss_demod.h" +#include "simulation.h" + +#include "generated/dsss_gold_code.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}}, +}; + +float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx); +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); + +#ifdef SIMULATION +void dsss_demod_step(struct dsss_demod_state *st, float new_value, size_t sim_pos) { +#else /* SIMULATION */ +void dsss_demod_step(struct dsss_demod_state *st, float new_value) { +#endif /* SIMULATION */ + +//#define DEBUG_PRINT(...) ((void)0) +//#define DEBUG_PRINTN(...) ((void)0) + bool debug = sim_pos % DSSS_CORRELATION_LENGTH == 0; + 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; + + st->signal[st->signal_wpos] = new_value; + st->signal_wpos = (st->signal_wpos + 1) % ARRAY_LENGTH(st->signal); + if (debug) DEBUG_PRINT(" signal: %f", 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); + /* 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]); + + float cwt[DSSS_GOLD_CODE_COUNT]; + for (size_t i=0; icorrelation[i], st->correlation_wpos); + /* debug */ + if (debug) DEBUG_PRINTN(" cwt: ["); + for (size_t i=0; icwt_filter[i].st); + /* debug */ + /* + DEBUG_PRINTN(" avg: ["); + for (size_t i=0; igroup.max; + int max_ch = st->group.max_ch; + int max_idx = st->group.max_idx + 1; + bool found = false; + if (debug) DEBUG_PRINTN(" rel: ["); + for (size_t i=0; i DSSS_THESHOLD_FACTOR) + found = true; + + if (fabs(val) > fabs(max_val)) { + max_val = val; + max_ch = i; + max_idx = st->group.len; + } + } + if (debug) DEBUG_PRINTN("]\n"); + + /* debug */ + if (debug) DEBUG_PRINT(" found=%d len=%d idx=%d ch=%d max=%f", + found, st->group.len, st->group.max_idx, st->group.max_ch, st->group.max); + /* end */ + + if (found) { + /* Continue ongoing group */ + st->group.len++; + st->group.max = max_val; + st->group.max_ch = max_ch; + st->group.max_idx = max_idx; + return; + } + + if (st->group.len == 0) + /* We're between groups */ + return; + + /* A group ended. Process result. */ + DEBUG_PRINT("GROUP FOUND: %8d len=%3d max=%f ch=%d offx=%d", + sim_pos, st->group.len, st->group.max, st->group.max_ch, st->group.max_idx); + + /* reset grouping state */ + st->group.len = 0; + st->group.max_idx = 0; + st->group.max_ch = 0; + st->group.max = 0.0f; +} + +float run_iir(const float x, const int order, const struct iir_biquad q[order], struct iir_biquad_state st[order]) { + float intermediate = x; + for (int i=0; i<(order+1)/2; i++) + intermediate = run_biquad(intermediate, &q[i], &st[i]); + return intermediate; +} + +float run_biquad(float x, const struct iir_biquad *const q, struct iir_biquad_state *const restrict st) { + /* direct form 2, see https://en.wikipedia.org/wiki/Digital_biquad_filter */ + float intermediate = x + st->reg[0] * -q->a[0] + st->reg[1] * -q->a[1]; + float out = intermediate * q->b[0] + st->reg[0] * q->b[1] + st->reg[1] * q->b[2]; + st->reg[1] = st->reg[0]; + st->reg[0] = intermediate; + return out; +} + +float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx) { + float sum = 0.0f; + for (ssize_t j=0; j>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 */ + } + acc_outer += acc_inner; + } + return acc_outer / DSSS_CORRELATION_LENGTH; +} diff --git a/controller/fw/src/dsss_demod.h b/controller/fw/src/dsss_demod.h new file mode 100644 index 0000000..8ab5cac --- /dev/null +++ b/controller/fw/src/dsss_demod.h @@ -0,0 +1,44 @@ +#ifndef __DSSS_DEMOD_H__ +#define __DSSS_DEMOD_H__ + +#define DSSS_GOLD_CODE_LENGTH ((1<