Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fsk: add Y option for selecting different fsk low pass coefficients #1191

Merged
merged 5 commits into from
Nov 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/baseband.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ void baseband_low_pass_filter(uint16_t const *x_buf, int16_t *y_buf, uint32_t le
@param len: number of samples to process
@param[in,out] state: State to store between chunk processing
*/
void baseband_demod_FM(uint8_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state);
void baseband_demod_FM(uint8_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state, unsigned fpdm);

/// For evaluation.
void baseband_demod_FM_cs16(int16_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state);
void baseband_demod_FM_cs16(int16_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state, unsigned fpdm);

/** Initialize tables and constants.
Should be called once at startup.
Expand Down
8 changes: 7 additions & 1 deletion include/pulse_detect.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ typedef struct {
int fm_f1_est; ///< Estimate for the F1 frequency for FSK
int fm_f2_est; ///< Estimate for the F2 frequency for FSK

int16_t var_test_max;
int16_t var_test_min;
int16_t maxx;
int16_t minn;
int16_t midd;
int skip_samples;
} pulse_FSK_state_t;

typedef struct pulse_detect pulse_detect_t;
Expand Down Expand Up @@ -107,7 +113,7 @@ void pulse_detect_free(pulse_detect_t *pulse_detect);
/// @return 0 if all input sample data is processed
/// @return 1 if OOK package is detected (but all sample data is still not completely processed)
/// @return 2 if FSK package is detected (but all sample data is still not completely processed)
int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_data, int16_t const *fm_data, int len, int16_t level_limit, uint32_t samp_rate, uint64_t sample_offset, pulse_data_t *pulses, pulse_data_t *fsk_pulses);
int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_data, int16_t const *fm_data, int len, int16_t level_limit, uint32_t samp_rate, uint64_t sample_offset, pulse_data_t *pulses, pulse_data_t *fsk_pulses, unsigned fpdm);

/// Analyze and print result.
void pulse_analyzer(pulse_data_t *data, int package_type);
Expand Down
8 changes: 8 additions & 0 deletions include/pulse_detect_fsk.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,13 @@

void pulse_FSK_detect(int16_t fm_n, pulse_data_t *fsk_pulses, pulse_FSK_state_t *s);
void pulse_FSK_wrap_up(pulse_data_t *fsk_pulses, pulse_FSK_state_t *s);
void pulse_FSK_detect_mm(int16_t fm_n, pulse_data_t *fsk_pulses, pulse_FSK_state_t *s);

#define FSK_PULSE_DETECT_START 0
enum {
FSK_PULSE_DETECT_OLD,
FSK_PULSE_DETECT_NEW,
FSK_PULSE_DETECT_AUTO,
FSK_PULSE_DETECT_END,
};
#endif /* INCLUDE_PULSE_DETECT_FSK_H_ */
2 changes: 2 additions & 0 deletions include/r_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ struct dm_state {
filter_state_t lowpass_filter_state;
demodfm_state_t demod_FM_state;
int enable_FM_demod;
unsigned fsk_pulse_detect_mode;
unsigned frequency;
samp_grab_t *samp_grab;
am_analyze_t *am_analyze;
int analyze_pulses;
Expand Down
3 changes: 2 additions & 1 deletion include/rtl_433.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define DEFAULT_HOP_TIME (60*10)
#define DEFAULT_ASYNC_BUF_NUMBER 0 // Force use of default value (librtlsdr default: 15)
#define DEFAULT_BUF_LENGTH (16 * 32 * 512) // librtlsdr default

#define FSK_PULSE_DETECTOR_LIMIT 800000000
/*
* Theoretical high level at I/Q saturation is 128x128 = 16384 (above is ripple)
* 0 = automatic adaptive level limit, else fixed level limit
Expand Down Expand Up @@ -62,6 +62,7 @@ typedef struct r_cfg {
int frequency_index;
uint32_t frequency[MAX_FREQS];
uint32_t center_frequency;
int fsk_pulse_detect_mode;
int hop_times;
int hop_time[MAX_FREQS];
time_t hop_start_time;
Expand Down
28 changes: 20 additions & 8 deletions src/baseband.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,32 @@ int16_t atan2_int16(int16_t y, int16_t x)
return angle;
}

void baseband_demod_FM(uint8_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state)

/// [b,a] = butter(1, 0.1) -> 3x tau (95%) ~10 samples
//static int const alp[2] = {FIX(1.00000), FIX(0.72654)};
//static int const blp[2] = {FIX(0.13673), FIX(0.13673)};
/// [b,a] = butter(1, 0.2) -> 3x tau (95%) ~5 samples
//static int const alp[2] = {FIX(1.00000), FIX(0.50953)};
//static int const blp[2] = {FIX(0.24524), FIX(0.24524)};


static int32_t const alps_16[][2] = {{FIX(1.00000), FIX(0.72654)},
{FIX(1.00000), FIX(0.50953)}};
static int32_t const blps_16[][2] = {{FIX(0.13673), FIX(0.13673)},
{FIX(0.24524), FIX(0.24524)}};

void baseband_demod_FM(uint8_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state, unsigned fpdm)
{
/// [b,a] = butter(1, 0.1) -> 3x tau (95%) ~10 samples
//static int const alp[2] = {FIX(1.00000), FIX(0.72654)};
//static int const blp[2] = {FIX(0.13673), FIX(0.13673)};
/// [b,a] = butter(1, 0.2) -> 3x tau (95%) ~5 samples
static int const alp[2] = {FIX(1.00000), FIX(0.50953)};
static int const blp[2] = {FIX(0.24524), FIX(0.24524)};

int16_t ar, ai; // New IQ sample: x[n]
int16_t br, bi; // Old IQ sample: x[n-1]
int32_t pr, pi; // Phase difference vector
int16_t xlp, ylp, xlp_old, ylp_old; // Low Pass filter variables

/* Select filter coeffs */
const int32_t *alp = alps_16[fpdm];
const int32_t *blp = blps_16[fpdm];

// Pre-feed old sample
ar = state->br; ai = state->bi;
xlp_old = state->xlp; ylp_old = state->ylp;
Expand Down Expand Up @@ -246,7 +258,7 @@ int32_t atan2_int32(int32_t y, int32_t x)
}

/// for evaluation.
void baseband_demod_FM_cs16(int16_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state)
void baseband_demod_FM_cs16(int16_t const *x_buf, int16_t *y_buf, unsigned long num_samples, demodfm_state_t *state, unsigned fpdm)
{
/// [b,a] = butter(1, 0.1) -> 3x tau (95%) ~10 samples
//static int const alp[2] = {FIX32(1.00000), FIX32(0.72654)};
Expand Down
18 changes: 14 additions & 4 deletions src/pulse_detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void pulse_detect_free(pulse_detect_t *pulse_detect)
}

/// Demodulate On/Off Keying (OOK) and Frequency Shift Keying (FSK) from an envelope signal
int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_data, int16_t const *fm_data, int len, int16_t level_limit, uint32_t samp_rate, uint64_t sample_offset, pulse_data_t *pulses, pulse_data_t *fsk_pulses)
int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_data, int16_t const *fm_data, int len, int16_t level_limit, uint32_t samp_rate, uint64_t sample_offset, pulse_data_t *pulses, pulse_data_t *fsk_pulses, unsigned fpdm)
{
int const samples_per_ms = samp_rate / 1000;
pulse_detect_t *s = pulse_detect;
Expand Down Expand Up @@ -257,6 +257,9 @@ int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_d
s->pulse_length = 0;
s->max_pulse = 0;
s->FSK_state = (pulse_FSK_state_t){0};
s->FSK_state.var_test_max = INT16_MIN;
s->FSK_state.var_test_min = INT16_MAX;
s->FSK_state.skip_samples = 40;
s->ook_state = PD_OOK_STATE_PULSE;
}
else { // We are still idle..
Expand Down Expand Up @@ -298,7 +301,10 @@ int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_d
}
// FSK Demodulation
if (pulses->num_pulses == 0) { // Only during first pulse
pulse_FSK_detect(fm_data[s->data_counter], fsk_pulses, &s->FSK_state);
if (fpdm == FSK_PULSE_DETECT_OLD)
pulse_FSK_detect(fm_data[s->data_counter], fsk_pulses, &s->FSK_state);
else
pulse_FSK_detect_mm(fm_data[s->data_counter], fsk_pulses, &s->FSK_state);
}
break;
case PD_OOK_STATE_GAP_START: // Beginning of gap - it might be a spurious gap
Expand All @@ -314,7 +320,8 @@ int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_d
// Determine if FSK modulation is detected
if (fsk_pulses->num_pulses > PD_MIN_PULSES) {
// Store last pulse/gap
pulse_FSK_wrap_up(fsk_pulses, &s->FSK_state);
if (fpdm == FSK_PULSE_DETECT_OLD)
pulse_FSK_wrap_up(fsk_pulses, &s->FSK_state);
// Store estimates
fsk_pulses->fsk_f1_est = s->FSK_state.fm_f1_est;
fsk_pulses->fsk_f2_est = s->FSK_state.fm_f2_est;
Expand All @@ -328,7 +335,10 @@ int pulse_detect_package(pulse_detect_t *pulse_detect, int16_t const *envelope_d
} // if
// FSK Demodulation (continue during short gap - we might return...)
if (pulses->num_pulses == 0) { // Only during first pulse
pulse_FSK_detect(fm_data[s->data_counter], fsk_pulses, &s->FSK_state);
if (fpdm == FSK_PULSE_DETECT_OLD)
pulse_FSK_detect(fm_data[s->data_counter], fsk_pulses, &s->FSK_state);
else
pulse_FSK_detect_mm(fm_data[s->data_counter], fsk_pulses, &s->FSK_state);
}
break;
case PD_OOK_STATE_GAP:
Expand Down
62 changes: 62 additions & 0 deletions src/pulse_detect_fsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,65 @@ void pulse_FSK_wrap_up(pulse_data_t *fsk_pulses, pulse_FSK_state_t *s)
fsk_pulses->num_pulses++;
}
}


/// Demodulate Frequency Shift Keying (FSK) sample by sample
///
/// Function is stateful between calls
/// @param fm_n: One single sample of FM data
/// @param *fsk_pulses: Will return a pulse_data_t structure for FSK demodulated data
/// @param *s: Internal state
void pulse_FSK_detect_mm(int16_t fm_n, pulse_data_t *fsk_pulses, pulse_FSK_state_t *s){

int16_t mid = 0;

/* Skip a few samples in the beginning, need for framing
* otherwise the min/max trackers wont converge properly
*/
if (!s->skip_samples) {
s->var_test_max = MAX(fm_n, s->var_test_max);
s->var_test_min = MIN(fm_n, s->var_test_min);
mid = (s->var_test_max + s->var_test_min) / 2;
if (fm_n > mid)
s->var_test_max -= 10;
if (fm_n < mid)
s->var_test_min += 10;

s->fsk_pulse_length++;
switch(s->fsk_state) {
case PD_FSK_STATE_INIT:
if (fm_n > mid)
s->fsk_state = PD_FSK_STATE_FH;
if (fm_n <= mid)
s->fsk_state = PD_FSK_STATE_FL;
break;
case PD_FSK_STATE_FH:
if (fm_n < mid) {
s->fsk_state = PD_FSK_STATE_FL;
fsk_pulses->pulse[fsk_pulses->num_pulses] = s->fsk_pulse_length;
s->fsk_pulse_length = 0;
}
break;
case PD_FSK_STATE_FL:
if (fm_n > mid) {
s->fsk_state = PD_FSK_STATE_FH;
fsk_pulses->gap[fsk_pulses->num_pulses] = s->fsk_pulse_length;
fsk_pulses->num_pulses++;
s->fsk_pulse_length = 0;
// When pulse buffer is full go to error state
if (fsk_pulses->num_pulses >= PD_MAX_PULSES) {
fprintf(stderr, "pulse_FSK_detect(): Maximum number of pulses reached!\n");
s->fsk_state = PD_FSK_STATE_ERROR;
}
}
break;
case PD_FSK_STATE_ERROR: // Stay here until cleared
break;
default:
fprintf(stderr, "pulse_FSK_detect(): Unknown FSK state!!\n");
s->fsk_state = PD_FSK_STATE_ERROR;
break;
}
}
if (s->skip_samples > 0) s->skip_samples--;
}
2 changes: 2 additions & 0 deletions src/r_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "r_private.h"
#include "r_device.h"
#include "pulse_demod.h"
#include "pulse_detect_fsk.h"
#include "sdr.h"
#include "data.h"
#include "list.h"
Expand Down Expand Up @@ -77,6 +78,7 @@ void r_init_cfg(r_cfg_t *cfg)
cfg->out_block_size = DEFAULT_BUF_LENGTH;
cfg->samp_rate = DEFAULT_SAMPLE_RATE;
cfg->conversion_mode = CONVERT_NATIVE;
cfg->fsk_pulse_detect_mode = FSK_PULSE_DETECT_AUTO;

list_ensure_size(&cfg->in_files, 100);
list_ensure_size(&cfg->output_handler, 16);
Expand Down
25 changes: 20 additions & 5 deletions src/rtl_433.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "sdr.h"
#include "baseband.h"
#include "pulse_detect.h"
#include "pulse_detect_fsk.h"
#include "pulse_demod.h"
#include "data.h"
#include "r_util.h"
Expand Down Expand Up @@ -101,6 +102,7 @@ static void usage(int exit_code)
" [-z <value>] Override short value in data decoder\n"
" [-x <value>] Override long value in data decoder\n"
" [-n <value>] Specify number of samples to take (each sample is 2 bytes: 1 each of I & Q)\n"
" [-Y <mode>] FSK pulse detector mode, old(0)|minmax(1)|auto(2).\n"
"\t\t= Analyze/Debug options =\n"
" [-a] Analyze mode. Print a textual description of the signal.\n"
" [-A] Pulse Analyzer. Enable pulse analysis and decode attempt.\n"
Expand Down Expand Up @@ -319,11 +321,20 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
baseband_low_pass_filter(demod->buf.temp, demod->am_buf, n_samples, &demod->lowpass_filter_state);

// FM demodulation
/* Select the correct fsk pulse detector */
unsigned fpdm = cfg->fsk_pulse_detect_mode;
if (cfg->fsk_pulse_detect_mode == FSK_PULSE_DETECT_AUTO) {
if (cfg->frequency[cfg->frequency_index] > FSK_PULSE_DETECTOR_LIMIT)
fpdm = FSK_PULSE_DETECT_NEW;
else
fpdm = FSK_PULSE_DETECT_OLD;
}

if (demod->enable_FM_demod) {
if (demod->sample_size == 1) { // CU8
baseband_demod_FM(iq_buf, demod->buf.fm, n_samples, &demod->demod_FM_state);
baseband_demod_FM(iq_buf, demod->buf.fm, n_samples, &demod->demod_FM_state, fpdm);
} else { // CS16
baseband_demod_FM_cs16((int16_t *)iq_buf, demod->buf.fm, n_samples, &demod->demod_FM_state);
baseband_demod_FM_cs16((int16_t *)iq_buf, demod->buf.fm, n_samples, &demod->demod_FM_state, fpdm);
}
}

Expand All @@ -348,7 +359,7 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
}
while (package_type) {
int p_events = 0; // Sensor events successfully detected per package
package_type = pulse_detect_package(demod->pulse_detect, demod->am_buf, demod->buf.fm, n_samples, demod->level_limit, cfg->samp_rate, cfg->input_pos, &demod->pulse_data, &demod->fsk_pulse_data);
package_type = pulse_detect_package(demod->pulse_detect, demod->am_buf, demod->buf.fm, n_samples, demod->level_limit, cfg->samp_rate, cfg->input_pos, &demod->pulse_data, &demod->fsk_pulse_data, fpdm);
if (package_type) {
// new package: set a first frame start if we are not tracking one already
if (!demod->frame_start_ago)
Expand Down Expand Up @@ -591,7 +602,7 @@ static int hasopt(int test, int argc, char *argv[], char const *optstring)

static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg);

#define OPTSTRING "hVvqDc:x:z:p:aAI:S:m:M:r:w:W:l:d:t:f:H:g:s:b:n:R:X:F:K:C:T:UGy:E:"
#define OPTSTRING "hVvqDc:x:z:p:aAI:S:m:M:r:w:W:l:d:t:f:H:g:s:b:n:R:X:F:K:C:T:UGy:E:Y:"

// these should match the short options exactly
static struct conf_keywords const conf_keywords[] = {
Expand Down Expand Up @@ -622,6 +633,7 @@ static struct conf_keywords const conf_keywords[] = {
{"signal_grabber", 'S'},
{"override_short", 'z'},
{"override_long", 'x'},
{"fsk_pulse_detect_mode", 'Y'},
{"output", 'F'},
{"output_tag", 'K'},
{"convert", 'C'},
Expand Down Expand Up @@ -722,7 +734,7 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg)
if (cfg->frequencies < MAX_FREQS) {
uint32_t sr = atouint32_metric(arg, "-f: ");
/* If the frequency is above 800MHz sample at 1MS/s */
if ((sr > 800000000) && (cfg->samp_rate == DEFAULT_SAMPLE_RATE))
if ((sr > FSK_PULSE_DETECTOR_LIMIT) && (cfg->samp_rate == DEFAULT_SAMPLE_RATE))
cfg->samp_rate = 1000000;
cfg->frequency[cfg->frequencies++] = sr;
} else
Expand Down Expand Up @@ -1005,6 +1017,9 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg)
case 'y':
cfg->test_data = arg;
break;
case 'Y':
cfg->fsk_pulse_detect_mode = atoi(arg);
break;
case 'E':
if (arg && !strcmp(arg, "hop")) {
cfg->after_successful_events_flag = 2;
Expand Down
4 changes: 2 additions & 2 deletions tests/baseband-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ int main(int argc, char *argv[])
);
write_buf("bb.lp.am.s16", u16_buf, sizeof(int16_t) * n_samples);
MEASURE("baseband_demod_FM",
baseband_demod_FM(cu8_buf, s16_buf, n_samples, &fm_state);
baseband_demod_FM(cu8_buf, s16_buf, n_samples, &fm_state, 0);
);
write_buf("bb.fm.s16", s16_buf, sizeof(int16_t) * n_samples);

Expand All @@ -159,7 +159,7 @@ int main(int argc, char *argv[])
//write_buf("bb.fm.s32", s32_buf, sizeof(int32_t) * n_samples);

MEASURE("baseband_demod_FM_cs16",
baseband_demod_FM_cs16(cs16_buf, s16_buf, n_samples, &fm_state);
baseband_demod_FM_cs16(cs16_buf, s16_buf, n_samples, &fm_state, 0);
);
write_buf("bb.cs16.fm.s16", s16_buf, sizeof(int16_t) * n_samples);

Expand Down