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