From 6e70ef143310f14f7eacadc2f47d05c1654cda2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= <mordae@anilinux.org>
Date: Tue, 2 Jul 2024 01:56:08 +0200
Subject: [PATCH] Implement fixed off-tuning

---
 src/main.c | 49 +++++++++++++++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/src/main.c b/src/main.c
index 4bd3e0d..78ad6f6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,9 +38,9 @@
 static uint32_t lo_cos[LO_WORDS] __attribute__((__aligned__(1 << LO_BITS_DEPTH)));
 static uint32_t lo_sin[LO_WORDS] __attribute__((__aligned__(1 << LO_BITS_DEPTH)));
 
-#define DECIMATE 2
+#define DECIMATE 4
 #define RX_STRIDE (2 * IQ_SAMPLES * DECIMATE)
-#define RX_BITS_DEPTH 12
+#define RX_BITS_DEPTH 13
 #define RX_WORDS (1 << (RX_BITS_DEPTH - 2))
 
 static_assert(RX_STRIDE * 4 < RX_WORDS, "RX_STRIDE * 4 < RX_WORDS");
@@ -463,7 +463,6 @@ static void rf_rx(void)
 	int pos = 0;
 
 	int64_t dcI = 0, dcQ = 0;
-	int prevI = 0, prevQ = 0;
 
 	while (true) {
 		if (multicore_fifo_rvalid()) {
@@ -520,8 +519,32 @@ static void rf_rx(void)
 			cos_pos = *cos_ptr++;
 			int I2 = cos_neg - cos_pos;
 
-			int64_t I = (prevI + I1 + I1 + I2) / 2;
-			prevI = I2;
+			cos_neg = *cos_ptr++;
+			cos_pos = *cos_ptr++;
+			int I3 = cos_neg - cos_pos;
+
+			cos_neg = *cos_ptr++;
+			cos_pos = *cos_ptr++;
+			int I4 = cos_neg - cos_pos;
+
+			uint32_t sin_neg = *sin_ptr++;
+			uint32_t sin_pos = *sin_ptr++;
+			int Q1 = sin_neg - sin_pos;
+
+			sin_neg = *sin_ptr++;
+			sin_pos = *sin_ptr++;
+			int Q2 = sin_neg - sin_pos;
+
+			sin_neg = *sin_ptr++;
+			sin_pos = *sin_ptr++;
+			int Q3 = sin_neg - sin_pos;
+
+			sin_neg = *sin_ptr++;
+			sin_pos = *sin_ptr++;
+			int Q4 = sin_neg - sin_pos;
+
+			int64_t I = I1 - I3 + Q2 - Q4;
+			int64_t Q = Q1 - Q3 - I2 + I4;
 
 			int64_t I16 = I << 16;
 			dcI = ((dcI << 16) - dcI + I16) >> 16;
@@ -537,17 +560,6 @@ static void rf_rx(void)
 
 			*blockptr++ = I + 128;
 
-			uint32_t sin_neg = *sin_ptr++;
-			uint32_t sin_pos = *sin_ptr++;
-			int Q1 = sin_neg - sin_pos;
-
-			sin_neg = *sin_ptr++;
-			sin_pos = *sin_ptr++;
-			int Q2 = sin_neg - sin_pos;
-
-			int64_t Q = (prevQ + Q1 + Q1 + Q2) / 2;
-			prevQ = Q2;
-
 			int64_t Q16 = Q << 16;
 			dcQ = ((dcQ << 16) - dcQ + Q16) >> 16;
 			Q = (Q16 - dcQ) >> 16;
@@ -573,11 +585,12 @@ static void run_command(uint8_t cmd, uint32_t arg)
 {
 	if (0x01 == cmd) {
 		/* Tune to a new center frequency */
-		rx_lo_init(arg, true);
+		rx_lo_init(arg - sample_rate, true);
 	} else if (0x02 == cmd) {
 		/* Set the rate at which IQ sample pairs are sent */
 		sample_rate = arg;
 		dma_timer_set_fraction(dma_t_samp, 1, CLK_SYS_HZ / (sample_rate * DECIMATE));
+		rx_lo_init(arg - sample_rate, true);
 	} else if (0x04 == cmd) {
 		/* Set the tuner gain level */
 		gain = INIT_GAIN * powf(10.0f, 0.005f * arg);
@@ -701,7 +714,7 @@ int main()
 
 	queue_init(&iq_queue, sizeof(uint8_t *), IQ_QUEUE_LEN);
 
-	rx_lo_init(INIT_FREQ, true);
+	rx_lo_init(INIT_FREQ - INIT_SAMPLE_RATE, true);
 
 	while (true) {
 		if (check_command() > 0) {