Optimize decimation, use 3rd order filter for FM

This commit is contained in:
Jan Hamal Dvořák 2024-03-05 20:18:08 +01:00
parent f640ce9677
commit 4b6194e9c2

View file

@ -43,7 +43,7 @@
#define CLK_SYS_HZ (266 * MHZ) #define CLK_SYS_HZ (266 * MHZ)
#define BANDWIDTH 1536000 #define BANDWIDTH 1536000
#define DECIMATION_BITS 3 #define DECIMATION_BITS 3
#define LPF_ORDER 2 #define LPF_ORDER 3
#define AGC_DECAY_BITS 20 #define AGC_DECAY_BITS 20
#define BIAS_STRENGTH 0 #define BIAS_STRENGTH 0
#endif #endif
@ -664,71 +664,68 @@ static void rf_rx(void)
pos = (pos + 2 * DECIMATION) & (RX_WORDS - 1); pos = (pos + 2 * DECIMATION) & (RX_WORDS - 1);
int dI = 0; int dI = 0;
int dQ = 0;
for (int d = 0; d < DECIMATION; d++) { for (int d = 0; d < DECIMATION; d++) {
uint32_t cos_pos = *cos_ptr++; uint32_t cos_pos = *cos_ptr++;
uint32_t cos_neg = *cos_ptr++; uint32_t cos_neg = *cos_ptr++;
uint32_t sin_pos = *sin_ptr++;
uint32_t sin_neg = *sin_ptr++;
int I = cos_neg - cos_pos; int I = cos_neg - cos_pos;
int Q = sin_neg - sin_pos;
/* Scale up before filtering. */
I = I * amp_scale; I = I * amp_scale;
Q = Q * amp_scale;
#if LPF_ORDER >= 1 #if LPF_ORDER >= 1
int lpP = d & (DECIMATION - 1); lpIa1 += I - lpIh1[d];
lpIh1[d] = I;
lpIa1 += I - lpIh1[lpP];
lpQa1 += Q - lpQh1[lpP];
lpIh1[lpP] = I;
lpQh1[lpP] = Q;
I = lpIa1 / DECIMATION; I = lpIa1 / DECIMATION;
Q = lpQa1 / DECIMATION;
#endif #endif
#if LPF_ORDER >= 2 #if LPF_ORDER >= 2
lpIa2 += I - lpIh2[lpP]; lpIa2 += I - lpIh2[d];
lpQa2 += Q - lpQh2[lpP]; lpIh2[d] = I;
lpIh2[lpP] = I;
lpQh2[lpP] = Q;
I = lpIa2 / DECIMATION; I = lpIa2 / DECIMATION;
Q = lpQa2 / DECIMATION;
#endif #endif
#if LPF_ORDER >= 3 #if LPF_ORDER >= 3
lpIa3 += I - lpIh3[lpP]; lpIa3 += I - lpIh3[d];
lpQa3 += Q - lpQh3[lpP]; lpIh3[d] = I;
lpIh3[lpP] = I;
lpQh3[lpP] = Q;
I = lpIa3 / DECIMATION; I = lpIa3 / DECIMATION;
Q = lpQa3 / DECIMATION;
#endif #endif
dI += I; dI += I;
dQ += Q;
} }
int dQ = 0;
/* /*
* Original dI/dQ are scaled to 32 bits. * Original dI/dQ are scaled to 32 bits.
* These "<< 19" are part of DC removal alpha. * These "<< 19" are part of DC removal alpha.
*/ */
int64_t dI19 = (int64_t)dI << 19; int64_t dI19 = (int64_t)dI << 19;
int64_t dQ19 = (int64_t)dQ << 19;
dcI = ((dcI << 13) - dcI + dI19) >> 13; dcI = ((dcI << 13) - dcI + dI19) >> 13;
dcQ = ((dcQ << 13) - dcQ + dQ19) >> 13;
dI = (dI19 - dcI) >> 19; dI = (dI19 - dcI) >> 19;
for (int d = 0; d < DECIMATION; d++) {
uint32_t sin_pos = *sin_ptr++;
uint32_t sin_neg = *sin_ptr++;
int Q = sin_neg - sin_pos;
Q = Q * amp_scale;
#if LPF_ORDER >= 1
lpQa1 += Q - lpQh1[d];
lpQh1[d] = Q;
Q = lpQa1 / DECIMATION;
#endif
#if LPF_ORDER >= 2
lpQa2 += Q - lpQh2[d];
lpQh2[d] = Q;
Q = lpQa2 / DECIMATION;
#endif
#if LPF_ORDER >= 3
lpQa3 += Q - lpQh3[d];
lpQh3[d] = Q;
Q = lpQa3 / DECIMATION;
#endif
dQ += Q;
}
int64_t dQ19 = (int64_t)dQ << 19;
dcQ = ((dcQ << 13) - dcQ + dQ19) >> 13;
dQ = (dQ19 - dcQ) >> 19; dQ = (dQ19 - dcQ) >> 19;
/* Slowly decay AGC amplitude. */ /* Slowly decay AGC amplitude. */