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.
This commit is contained in:
Thomas Kolb 2022-01-30 20:23:41 +01:00
parent c1dd039d6b
commit b6713909f7
2 changed files with 37 additions and 34 deletions

View file

@ -17,7 +17,7 @@
#define RRC_DELAY 7 // delay in symbols #define RRC_DELAY 7 // delay in symbols
#define RRC_BETA 0.2f #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 #define TRANSMISSION_RAMP_DOWN_LEN 32 // symbols
#endif // CONFIG_H #endif // CONFIG_H

View file

@ -22,7 +22,7 @@ int main(void)
float snr = 50.0f; float snr = 50.0f;
channel_cccf_add_awgn(channel, -snr, snr); 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; packet_mod_ctx_t pmod;
@ -89,7 +89,7 @@ int main(void)
float complex symsync_out[burst_len]; float complex symsync_out[burst_len];
unsigned int symsync_out_len = 0; unsigned int symsync_out_len = 0;
#define FREQ_EST_L 16 #define FREQ_EST_L 8
float phase_history[FREQ_EST_L]; float phase_history[FREQ_EST_L];
memset(phase_history, 0, sizeof(phase_history)); memset(phase_history, 0, sizeof(phase_history));
@ -126,6 +126,7 @@ int main(void)
} }
// update the frequency estimate // update the frequency estimate
if(((i/RRC_SPS) % FREQ_EST_L) == 0) {
float unwrapped_phase_history[FREQ_EST_L]; float unwrapped_phase_history[FREQ_EST_L];
memcpy(unwrapped_phase_history, phase_history, sizeof(unwrapped_phase_history)); memcpy(unwrapped_phase_history, phase_history, sizeof(unwrapped_phase_history));
liquid_unwrap_phase(unwrapped_phase_history, FREQ_EST_L); liquid_unwrap_phase(unwrapped_phase_history, FREQ_EST_L);
@ -148,9 +149,10 @@ int main(void)
float lms_phase_change = numerator / denominator; float lms_phase_change = numerator / denominator;
nco_crcf_adjust_frequency(carrier_nco, lms_phase_change / RRC_SPS / 32); float freq_adjustment = (lms_phase_change / RRC_SPS / 2) * 0.3f;
nco_crcf_adjust_frequency(carrier_nco, freq_adjustment);
printf("Phase change: %.6f - carrier frequency: %.6f\n", lms_phase_change, nco_crcf_get_frequency(carrier_nco)); printf("Frequency adjustment: %.6f - carrier frequency: %.6f\n", freq_adjustment, nco_crcf_get_frequency(carrier_nco));
if(i/RRC_SPS == 2*FREQ_EST_L) { if(i/RRC_SPS == 2*FREQ_EST_L) {
float complex tmp[FREQ_EST_L]; float complex tmp[FREQ_EST_L];
@ -161,11 +163,12 @@ int main(void)
printf("MARK\n"); printf("MARK\n");
} }
} }
}
symsync_out_len += out_len; 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 #if 0
// demodulate // demodulate