cfo: srslte_sync_get_cfo() returns PSS-based CFO estimation. Gives better results than CP-based

master
Ismael Gomez 8 years ago
parent 811ad420ef
commit 1f6e63ae4f

@ -511,12 +511,6 @@ int main(int argc, char **argv) {
if (n < 0) {
// fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
} else if (n > 0) {
/*
printf("Saving signal...\n");
srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv, prog_args.rnti);
exit(-1);
*/
/* Send data if socket active */
if (prog_args.net_port > 0) {

@ -76,6 +76,7 @@ typedef struct SRSLTE_API {
uint32_t max_offset;
bool enable_cfo_corr;
float mean_cfo;
float mean_cfo2;
int cfo_i;
bool find_cfo_i;
bool find_cfo_i_initiated;
@ -93,6 +94,7 @@ typedef struct SRSLTE_API {
float m1_value;
float M_norm_avg;
float M_ext_avg;
cf_t *temp;
}srslte_sync_t;

@ -341,6 +341,10 @@ double rf_blade_set_rx_freq(void *h, double freq)
(uint32_t) freq, bladerf_strerror(status));
return -1;
}
f_int=0;
bladerf_get_frequency(handler->dev, BLADERF_MODULE_RX, &f_int);
printf("set RX frequency to %u\n", f_int);
return freq;
}
@ -355,6 +359,9 @@ double rf_blade_set_tx_freq(void *h, double freq)
return -1;
}
f_int=0;
bladerf_get_frequency(handler->dev, BLADERF_MODULE_TX, &f_int);
printf("set TX frequency to %u\n", f_int);
return freq;
}

@ -61,6 +61,7 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset,
q->detect_cp = true;
q->sss_en = true;
q->mean_cfo = 0;
q->mean_cfo2 = 0;
q->N_id_2 = 1000;
q->N_id_1 = 1000;
q->cfo_i = 0;
@ -78,8 +79,8 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset,
goto clean_exit;
}
// Set a CFO tolerance of approx 100 Hz
srslte_cfo_set_tol(&q->cfocorr, 100.0/(15000.0*q->fft_size));
// Set a CFO tolerance of approx 50 Hz
srslte_cfo_set_tol(&q->cfocorr, 50.0/(15000.0*q->fft_size));
for (int i=0;i<2;i++) {
q->cfo_i_corr[i] = srslte_vec_malloc(sizeof(cf_t)*q->frame_size);
@ -89,6 +90,12 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset,
}
}
q->temp = srslte_vec_malloc(sizeof(cf_t)*2*q->frame_size);
if (!q->temp) {
perror("malloc");
goto clean_exit;
}
srslte_sync_set_cp(q, SRSLTE_CP_NORM);
if (srslte_pss_synch_init_fft(&q->pss, max_offset, fft_size)) {
@ -131,6 +138,9 @@ void srslte_sync_free(srslte_sync_t *q) {
}
srslte_pss_synch_free(&q->pss_i[i]);
}
if (q->temp) {
free(q->temp);
}
}
}
@ -185,7 +195,7 @@ uint32_t srslte_sync_get_sf_idx(srslte_sync_t *q) {
}
float srslte_sync_get_cfo(srslte_sync_t *q) {
return q->mean_cfo + q->cfo_i;
return q->mean_cfo2 + q->cfo_i;
}
void srslte_sync_set_cfo(srslte_sync_t *q, float cfo) {
@ -413,6 +423,8 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t
if (peak_position) {
*peak_position = 0;
}
cf_t *input_cfo = input;
if (q->enable_cfo_corr) {
float cfo = cfo_estimate(q, input);
@ -421,19 +433,21 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t
q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha);
/* Correct CFO with the averaged CFO estimation */
srslte_cfo_correct(&q->cfocorr, input, input, -q->mean_cfo / q->fft_size);
srslte_cfo_correct(&q->cfocorr, input, q->temp, -q->mean_cfo / q->fft_size);
input_cfo = q->temp;
}
/* If integer CFO is enabled, find max PSS correlation for shifted +1/0/-1 integer versions */
if (q->find_cfo_i && q->enable_cfo_corr) {
q->cfo_i = cfo_i_estimate(q, input, find_offset, &peak_pos);
q->cfo_i = cfo_i_estimate(q, input_cfo, find_offset, &peak_pos);
if (q->cfo_i != 0) {
srslte_vec_prod_ccc(input, q->cfo_i_corr[q->cfo_i<0?0:1], input, q->frame_size);
srslte_vec_prod_ccc(input_cfo, q->cfo_i_corr[q->cfo_i<0?0:1], input_cfo, q->frame_size);
INFO("Compensating cfo_i=%d\n", q->cfo_i);
}
} else {
srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2);
peak_pos = srslte_pss_synch_find_pss(&q->pss, &input[find_offset], &q->peak_value);
peak_pos = srslte_pss_synch_find_pss(&q->pss, &input_cfo[find_offset], &q->peak_value);
if (peak_pos < 0) {
fprintf(stderr, "Error calling finding PSS sequence\n");
return SRSLTE_ERROR;
@ -449,7 +463,7 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t
// Set an invalid N_id_1 indicating SSS is yet to be detected
q->N_id_1 = 1000;
if (sync_sss(q, input, find_offset + peak_pos, q->cp) < 0) {
if (sync_sss(q, input_cfo, find_offset + peak_pos, q->cp) < 0) {
DEBUG("No space for SSS processing. Frame starts at %d\n", peak_pos);
}
}
@ -459,13 +473,16 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t
if (q->detect_cp) {
if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) {
srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input, peak_pos + find_offset));
srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input_cfo, peak_pos + find_offset));
} else {
DEBUG("Not enough room to detect CP length. Peak position: %d\n", peak_pos);
}
}
if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) {
float cfo2 = srslte_pss_synch_cfo_compute(&q->pss, &input[find_offset + peak_pos - q->fft_size]);
q->mean_cfo2 = SRSLTE_VEC_EMA(cfo2, q->mean_cfo2, q->cfo_ema_alpha);
ret = SRSLTE_SYNC_FOUND;
} else {
ret = SRSLTE_SYNC_FOUND_NOSPACE;

@ -302,6 +302,13 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint
fprintf(stderr, "Error calling srslte_pdsch_decode()\n");
}
}
printf("Saving signal...\n");
srslte_vec_save_file("input", input, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
srslte_ue_dl_save_signal(q, &q->softbuffer, sf_idx, rvidx, rnti, cfi);
//exit(-1);
}
q->pkts_total++;

@ -605,14 +605,12 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) {
}
q->frame_total_cnt++;
} else {
if (q->correct_cfo) {
srslte_cfo_correct(&q->sfind.cfocorr,
}
if (q->correct_cfo) {
srslte_cfo_correct(&q->sfind.cfocorr,
input_buffer,
input_buffer,
-srslte_sync_get_cfo(&q->strack) / q->fft_size);
}
-srslte_sync_get_cfo(&q->strack) / q->fft_size);
}
break;
}

Loading…
Cancel
Save