From b6713909f7386cbb87e0ad28899faa6763ffbb49 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sun, 30 Jan 2022 20:23:41 +0100 Subject: [PATCH] Make initial frequency sync much faster The NCO frequency is now only adjusted every 8 symbols. That means that the frequency error over the last 8 symbols before the adjustment is (almost) constant, giving a good estimation result. Therefore, the adjustment factor can be much larger than previously, leading to faster acquisition time. --- impl/src/config.h | 2 +- impl/src/main.c | 69 ++++++++++++++++++++++++----------------------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/impl/src/config.h b/impl/src/config.h index d47e200..4e29ffd 100644 --- a/impl/src/config.h +++ b/impl/src/config.h @@ -17,7 +17,7 @@ #define RRC_DELAY 7 // delay in symbols #define RRC_BETA 0.2f -#define TRANSMISSION_RAMP_UP_LEN 128 // symbols +#define TRANSMISSION_RAMP_UP_LEN 64 // symbols #define TRANSMISSION_RAMP_DOWN_LEN 32 // symbols #endif // CONFIG_H diff --git a/impl/src/main.c b/impl/src/main.c index 65a8382..972539c 100644 --- a/impl/src/main.c +++ b/impl/src/main.c @@ -22,7 +22,7 @@ int main(void) float snr = 50.0f; channel_cccf_add_awgn(channel, -snr, snr); - channel_cccf_add_carrier_offset(channel, 0.10f, 1.00f); + channel_cccf_add_carrier_offset(channel, 0.20f, 1.00f); packet_mod_ctx_t pmod; @@ -89,7 +89,7 @@ int main(void) float complex symsync_out[burst_len]; unsigned int symsync_out_len = 0; -#define FREQ_EST_L 16 +#define FREQ_EST_L 8 float phase_history[FREQ_EST_L]; memset(phase_history, 0, sizeof(phase_history)); @@ -126,46 +126,49 @@ int main(void) } // update the frequency estimate - float unwrapped_phase_history[FREQ_EST_L]; - memcpy(unwrapped_phase_history, phase_history, sizeof(unwrapped_phase_history)); - liquid_unwrap_phase(unwrapped_phase_history, FREQ_EST_L); + if(((i/RRC_SPS) % FREQ_EST_L) == 0) { + float unwrapped_phase_history[FREQ_EST_L]; + memcpy(unwrapped_phase_history, phase_history, sizeof(unwrapped_phase_history)); + liquid_unwrap_phase(unwrapped_phase_history, FREQ_EST_L); - // calculate slope of LMS-fitted line - float mean_index = (FREQ_EST_L-1) / 2.0f; - float mean_phase = 0.0f; - for(unsigned int j = 0; j < FREQ_EST_L; j++) { - mean_phase += unwrapped_phase_history[j]; - } - mean_phase /= FREQ_EST_L; - - float numerator = 0.0f; - float denominator = 0.0f; - for(unsigned int j = 0; j < FREQ_EST_L; j++) { - float delta_index = j - mean_index; - numerator += delta_index * (unwrapped_phase_history[j] - mean_phase); - denominator += delta_index*delta_index; - } - - float lms_phase_change = numerator / denominator; - - nco_crcf_adjust_frequency(carrier_nco, lms_phase_change / RRC_SPS / 32); - - printf("Phase change: %.6f - carrier frequency: %.6f\n", lms_phase_change, nco_crcf_get_frequency(carrier_nco)); - - if(i/RRC_SPS == 2*FREQ_EST_L) { - float complex tmp[FREQ_EST_L]; + // calculate slope of LMS-fitted line + float mean_index = (FREQ_EST_L-1) / 2.0f; + float mean_phase = 0.0f; for(unsigned int j = 0; j < FREQ_EST_L; j++) { - tmp[j] = unwrapped_phase_history[j]; + mean_phase += unwrapped_phase_history[j]; + } + mean_phase /= FREQ_EST_L; + + float numerator = 0.0f; + float denominator = 0.0f; + for(unsigned int j = 0; j < FREQ_EST_L; j++) { + float delta_index = j - mean_index; + numerator += delta_index * (unwrapped_phase_history[j] - mean_phase); + denominator += delta_index*delta_index; + } + + float lms_phase_change = numerator / denominator; + + float freq_adjustment = (lms_phase_change / RRC_SPS / 2) * 0.3f; + nco_crcf_adjust_frequency(carrier_nco, freq_adjustment); + + printf("Frequency adjustment: %.6f - carrier frequency: %.6f\n", freq_adjustment, nco_crcf_get_frequency(carrier_nco)); + + if(i/RRC_SPS == 2*FREQ_EST_L) { + float complex tmp[FREQ_EST_L]; + for(unsigned int j = 0; j < FREQ_EST_L; j++) { + tmp[j] = unwrapped_phase_history[j]; + } + dump_array_cf(tmp, FREQ_EST_L, 1.0f, "/tmp/freq_est.cpx"); + printf("MARK\n"); } - dump_array_cf(tmp, FREQ_EST_L, 1.0f, "/tmp/freq_est.cpx"); - printf("MARK\n"); } } symsync_out_len += out_len; } - dump_array_cf(symsync_out, symsync_out_len, 1.0f, "/tmp/rx.cpx"); + dump_array_cf(symsync_out, symsync_out_len, 1.0f, "/tmp/synced.cpx"); #if 0 // demodulate