From d6af05ba9e8ba0c4f6b503c9eda0b8d532973d87 Mon Sep 17 00:00:00 2001 From: batt <batt@38d2e660-2303-0410-9eaa-f027e97ec537> Date: Fri, 2 Oct 2009 21:55:51 +0000 Subject: [PATCH] Add selectable discriminator filter type. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3005 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cfg/cfg_afsk.h | 9 +++++++++ bertos/net/afsk.c | 39 +++++++++++++++++++++++++++------------ bertos/net/afsk.h | 10 ++++++++++ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/bertos/cfg/cfg_afsk.h b/bertos/cfg/cfg_afsk.h index 8ac805ee..791916d2 100644 --- a/bertos/cfg/cfg_afsk.h +++ b/bertos/cfg/cfg_afsk.h @@ -39,6 +39,15 @@ #ifndef CFG_AFSK_H #define CFG_AFSK_H + +/** + * AFSK discriminator filter type. + * + * $WIZ$ type = "enum"; value_list = "afsk_filter_list" + */ +#define CONFIG_AFSK_FILTER AFSK_CHEBYSHEV + + /** * AFSK receiver buffer length. * diff --git a/bertos/net/afsk.c b/bertos/net/afsk.c index 4ebf5454..2472861c 100644 --- a/bertos/net/afsk.c +++ b/bertos/net/afsk.c @@ -241,23 +241,38 @@ DEFINE_AFSK_ADC_ISR() /* * Frequency discrimination is achieved by simply multiplying - * the sample with a delayed sample of (bits per sample) / 2. - * Then the signal is lowpass filtered with a first order, 600 Hz - * Butterworth filter. + * the sample with a delayed sample of (samples per bit) / 2. + * Then the signal is lowpass filtered with a first order, + * 600 Hz filter. The filter implementation is selectable + * through the CONFIG_AFSK_FILTER config variable. */ iir_x[0] = iir_x[1]; - iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) >> 2; + + #if (CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH) || (CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV) + iir_x[1] = ((int8_t)fifo_pop(&delay_fifo) * curr_sample) >> 2; + #else + #error Filter type not found! + #endif + iir_y[0] = iir_y[1]; - /* - * This strange sum + shift is an optimization for iir_y[0] * 0.668. - * iir * 0.668 ~= (iir * 21) / 32 = - * = (iir * 16) / 32 + (iir * 4) / 32 + iir / 32 = - * = iir / 2 + iir / 8 + iir / 32 = - * = iir >> 1 + iir >> 3 + iir >> 5 - */ - iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1) + (iir_y[0] >> 3) + (iir_y[0] >> 5); + #if CONFIG_AFSK_FILTER == AFSK_BUTTERWORTH + /* + * This strange sum + shift is an optimization for iir_y[0] * 0.668. + * iir * 0.668 ~= (iir * 21) / 32 = + * = (iir * 16) / 32 + (iir * 4) / 32 + iir / 32 = + * = iir / 2 + iir / 8 + iir / 32 = + * = iir >> 1 + iir >> 3 + iir >> 5 + */ + iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1) + (iir_y[0] >> 3) + (iir_y[0] >> 5); + #elif CONFIG_AFSK_FILTER == AFSK_CHEBYSHEV + /* + * This should be (iir_y[0] * 0.438) but + * (iir_y[0] >> 1) is a faster approximation :-) + */ + iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1); + #endif /* Save this sampled bit in a delay line */ sampled_bits <<= 1; diff --git a/bertos/net/afsk.h b/bertos/net/afsk.h index 16eab935..37159712 100644 --- a/bertos/net/afsk.h +++ b/bertos/net/afsk.h @@ -63,4 +63,14 @@ INLINE Afsk *AFSK_CAST(KFile *fd) void afsk_init(Afsk *af); +/** + * \name afsk filter type + * $WIZ$ afsk_filter_list = "AFSK_BUTTERWORTH", "AFSK_CHEBYSHEV" + * \{ + */ +#define AFSK_BUTTERWORTH 0 +#define AFSK_CHEBYSHEV 1 +/* \} */ + + #endif -- 2.25.1