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:
parent
c1dd039d6b
commit
b6713909f7
|
@ -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
|
||||||
|
|
|
@ -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,46 +126,49 @@ int main(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the frequency estimate
|
// update the frequency estimate
|
||||||
float unwrapped_phase_history[FREQ_EST_L];
|
if(((i/RRC_SPS) % FREQ_EST_L) == 0) {
|
||||||
memcpy(unwrapped_phase_history, phase_history, sizeof(unwrapped_phase_history));
|
float unwrapped_phase_history[FREQ_EST_L];
|
||||||
liquid_unwrap_phase(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
|
// calculate slope of LMS-fitted line
|
||||||
float mean_index = (FREQ_EST_L-1) / 2.0f;
|
float mean_index = (FREQ_EST_L-1) / 2.0f;
|
||||||
float mean_phase = 0.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];
|
|
||||||
for(unsigned int j = 0; j < FREQ_EST_L; j++) {
|
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;
|
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
|
||||||
|
|
Loading…
Reference in a new issue