Normalized PSS correlation result. Use real part only. Extended sync_test to more bandwidth

master
ismagom 10 years ago
parent 3dfb1824b4
commit 7658ced99d

@ -42,14 +42,18 @@ CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_dot_prod_32f HAVE_VOLK_DOTPROD_F_FUNCTION
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_s32f_atan2_32f HAVE_VOLK_ATAN_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_s32f_atan2_32f HAVE_VOLK_ATAN_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_s32f_convert_16i HAVE_VOLK_CONVERT_FI_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_s32f_convert_16i HAVE_VOLK_CONVERT_FI_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_32f_x2 HAVE_VOLK_DEINTERLEAVE_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_32f_x2 HAVE_VOLK_DEINTERLEAVE_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_subtract_32f HAVE_VOLK_SUB_FLOAT_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_subtract_32f HAVE_VOLK_SUB_FLOAT_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_real_32f HAVE_VOLK_DEINTERLEAVE_FUNCTION)
SET(VOLK_DEFINITIONS "HAVE_VOLK") SET(VOLK_DEFINITIONS "HAVE_VOLK")
IF(${HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION}) IF(${HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION")
ENDIF() ENDIF()
IF(${HAVE_VOLK_DEINTERLEAVE_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DEINTERLEAVE_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_SUB_FLOAT_FUNCTION}) IF(${HAVE_VOLK_SUB_FLOAT_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_SUB_FLOAT_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_SUB_FLOAT_FUNCTION")
ENDIF() ENDIF()

@ -81,8 +81,8 @@ ENDIF(${GRAPHICS_FIND} EQUAL -1)
IF(${CUHD_FIND} GREATER -1) IF(${CUHD_FIND} GREATER -1)
add_executable(scan_mib scan_mib.c) add_executable(cell_search cell_search.c)
target_link_libraries(scan_mib lte_phy cuhd ) target_link_libraries(cell_search lte_phy cuhd )
MESSAGE(STATUS " UHD examples will be installed.") MESSAGE(STATUS " UHD examples will be installed.")

@ -109,7 +109,6 @@ int main(int argc, char **argv) {
int peak_pos[3]; int peak_pos[3];
float *cfo; float *cfo;
float peak_value[3]; float peak_value[3];
float mean_value[3];
int frame_cnt; int frame_cnt;
cf_t *input; cf_t *input;
uint32_t m0, m1; uint32_t m0, m1;
@ -201,10 +200,10 @@ int main(int argc, char **argv) {
if (force_N_id_2 != -1) { if (force_N_id_2 != -1) {
N_id_2 = force_N_id_2; N_id_2 = force_N_id_2;
peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2], &mean_value[N_id_2]); peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]);
} else { } else {
for (N_id_2=0;N_id_2<3;N_id_2++) { for (N_id_2=0;N_id_2<3;N_id_2++) {
peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2], &mean_value[N_id_2]); peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]);
} }
float max_value=-99999; float max_value=-99999;
N_id_2=-1; N_id_2=-1;
@ -218,7 +217,7 @@ int main(int argc, char **argv) {
} }
/* If peak detected */ /* If peak detected */
if (peak_value[N_id_2]/mean_value[N_id_2] > corr_peak_threshold) { if (peak_value[N_id_2] > corr_peak_threshold) {
sss_idx = peak_pos[N_id_2]-2*(symbol_sz+CP(symbol_sz,CPNORM_LEN)); sss_idx = peak_pos[N_id_2]-2*(symbol_sz+CP(symbol_sz,CPNORM_LEN));
if (sss_idx >= 0) { if (sss_idx >= 0) {
@ -228,7 +227,7 @@ int main(int argc, char **argv) {
cfo[frame_cnt] = pss_synch_cfo_compute(&pss[N_id_2], &input[peak_pos[N_id_2]-128]); cfo[frame_cnt] = pss_synch_cfo_compute(&pss[N_id_2], &input[peak_pos[N_id_2]-128]);
printf("\t%d\t%d\t%d\t%d\t%.3f\t\t%3d\t%d\t%d\t%.3f\n", printf("\t%d\t%d\t%d\t%d\t%.3f\t\t%3d\t%d\t%d\t%.3f\n",
frame_cnt,N_id_2, sss_synch_N_id_1(&sss[N_id_2], m0, m1), frame_cnt,N_id_2, sss_synch_N_id_1(&sss[N_id_2], m0, m1),
sss_synch_subframe(m0, m1), peak_value[N_id_2]/mean_value[N_id_2], sss_synch_subframe(m0, m1), peak_value[N_id_2],
peak_pos[N_id_2], m0, m1, peak_pos[N_id_2], m0, m1,
cfo[frame_cnt]); cfo[frame_cnt]);
} }

@ -72,7 +72,7 @@ typedef struct LIBLTE_API {
cf_t *pss_signal_freq[3]; // One sequence for each N_id_2 cf_t *pss_signal_freq[3]; // One sequence for each N_id_2
cf_t *tmp_input; cf_t *tmp_input;
float *conv_abs; float *conv_real;
cf_t *conv_output; cf_t *conv_output;
}pss_synch_t; }pss_synch_t;
@ -102,8 +102,7 @@ LIBLTE_API int pss_synch_set_N_id_2(pss_synch_t *q,
LIBLTE_API int pss_synch_find_pss(pss_synch_t *q, LIBLTE_API int pss_synch_find_pss(pss_synch_t *q,
cf_t *input, cf_t *input,
float *corr_peak_value, float *corr_peak_value);
float *corr_mean_value);
LIBLTE_API float pss_synch_cfo_compute(pss_synch_t* q, LIBLTE_API float pss_synch_cfo_compute(pss_synch_t* q,
cf_t *pss_recv); cf_t *pss_recv);

@ -51,13 +51,10 @@
* functions sync_pss_det_absolute() and sync_pss_det_peakmean(). * functions sync_pss_det_absolute() and sync_pss_det_peakmean().
*/ */
enum sync_pss_det { ABSOLUTE, PEAK_MEAN};
typedef struct LIBLTE_API { typedef struct LIBLTE_API {
pss_synch_t pss_find; pss_synch_t pss_find;
pss_synch_t pss_track; pss_synch_t pss_track;
sss_synch_t sss; sss_synch_t sss;
enum sync_pss_det pss_mode;
float find_threshold; float find_threshold;
float track_threshold; float track_threshold;
float peak_value; float peak_value;
@ -103,12 +100,6 @@ LIBLTE_API void sync_set_threshold(sync_t *q,
float find_threshold, float find_threshold,
float track_threshold); float track_threshold);
/* Set peak comparison to absolute value */
LIBLTE_API void sync_pss_det_absolute(sync_t *q);
/* Set peak comparison to relative to the mean */
LIBLTE_API void sync_pss_det_peak_to_avg(sync_t *q);
/* Gets the slot id (0 or 10) */ /* Gets the slot id (0 or 10) */
LIBLTE_API uint32_t sync_get_slot_id(sync_t *q); LIBLTE_API uint32_t sync_get_slot_id(sync_t *q);

@ -72,6 +72,7 @@ LIBLTE_API void vec_sc_prod_fff(float *x, float h, float *z, uint32_t len);
LIBLTE_API void vec_convert_fi(float *x, int16_t *z, float scale, uint32_t len); LIBLTE_API void vec_convert_fi(float *x, int16_t *z, float scale, uint32_t len);
LIBLTE_API void vec_deinterleave_cf(cf_t *x, float *real, float *imag, uint32_t len); LIBLTE_API void vec_deinterleave_cf(cf_t *x, float *real, float *imag, uint32_t len);
LIBLTE_API void vec_deinterleave_real_cf(cf_t *x, float *real, uint32_t len);
/* vector product (element-wise) */ /* vector product (element-wise) */
LIBLTE_API void vec_prod_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); LIBLTE_API void vec_prod_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len);

@ -120,8 +120,6 @@ int ue_sync_init(ue_sync_t *q,
goto clean_exit; goto clean_exit;
} }
sync_pss_det_absolute(&q->s);
if (cfo_init(&q->cfocorr, MAXIMUM_SFLEN)) { if (cfo_init(&q->cfocorr, MAXIMUM_SFLEN)) {
fprintf(stderr, "Error initiating CFO\n"); fprintf(stderr, "Error initiating CFO\n");
goto clean_exit; goto clean_exit;

@ -227,7 +227,7 @@ int main(int argc, char **argv) {
} }
#endif #endif
pos = pss_synch_find_pss(&pss, input_buffer, &peak, NULL); pos = pss_synch_find_pss(&pss, input_buffer, &peak);
/*if (pos > 962 || pos < 958) { /*if (pos > 962 || pos < 958) {
unaligned++; unaligned++;
} }

@ -36,6 +36,7 @@
#include "liblte/phy/utils/dft.h" #include "liblte/phy/utils/dft.h"
#include "liblte/phy/utils/vector.h" #include "liblte/phy/utils/vector.h"
#include "liblte/phy/utils/convolution.h" #include "liblte/phy/utils/convolution.h"
#include "liblte/phy/utils/debug.h"
int pss_synch_init_N_id_2(cf_t *pss_signal_freq, uint32_t N_id_2, uint32_t fft_size) { int pss_synch_init_N_id_2(cf_t *pss_signal_freq, uint32_t N_id_2, uint32_t fft_size) {
@ -45,7 +46,7 @@ int pss_synch_init_N_id_2(cf_t *pss_signal_freq, uint32_t N_id_2, uint32_t fft_s
int ret = LIBLTE_ERROR_INVALID_INPUTS; int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (lte_N_id_2_isvalid(N_id_2) && if (lte_N_id_2_isvalid(N_id_2) &&
fft_size < 2048) fft_size <= 2048)
{ {
pss_generate(pss_signal_time, N_id_2); pss_generate(pss_signal_time, N_id_2);
@ -60,10 +61,10 @@ int pss_synch_init_N_id_2(cf_t *pss_signal_freq, uint32_t N_id_2, uint32_t fft_s
dft_plan_set_mirror(&plan, true); dft_plan_set_mirror(&plan, true);
dft_plan_set_dc(&plan, true); dft_plan_set_dc(&plan, true);
dft_plan_set_norm(&plan, true);
dft_run_c(&plan, pss_signal_pad, pss_signal_freq); dft_run_c(&plan, pss_signal_pad, pss_signal_freq);
vec_sc_prod_cfc(pss_signal_freq, (float) 1 / (fft_size), pss_signal_pad, fft_size); vec_conj_cc(pss_signal_freq, pss_signal_freq, fft_size);
vec_conj_cc(pss_signal_pad, pss_signal_freq, fft_size);
dft_plan_free(&plan); dft_plan_free(&plan);
@ -97,8 +98,8 @@ int pss_synch_init_fft(pss_synch_t *q, uint32_t frame_size, uint32_t fft_size) {
buffer_size = fft_size + frame_size + 1; buffer_size = fft_size + frame_size + 1;
q->conv_abs = vec_malloc(buffer_size * sizeof(float)); q->conv_real = vec_malloc(buffer_size * sizeof(float));
if (!q->conv_abs) { if (!q->conv_real) {
fprintf(stderr, "Error allocating memory\n"); fprintf(stderr, "Error allocating memory\n");
goto clean_and_exit; goto clean_and_exit;
} }
@ -160,8 +161,8 @@ void pss_synch_free(pss_synch_t *q) {
if (q->conv_output) { if (q->conv_output) {
free(q->conv_output); free(q->conv_output);
} }
if (q->conv_abs) { if (q->conv_real) {
free(q->conv_abs); free(q->conv_real);
} }
bzero(q, sizeof(pss_synch_t)); bzero(q, sizeof(pss_synch_t));
@ -231,8 +232,7 @@ int pss_synch_set_N_id_2(pss_synch_t *q, uint32_t N_id_2) {
* *
* Input buffer must be subframe_size long. * Input buffer must be subframe_size long.
*/ */
int pss_synch_find_pss(pss_synch_t *q, cf_t *input, int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value)
float *corr_peak_value, float *corr_mean_value)
{ {
int ret = LIBLTE_ERROR_INVALID_INPUTS; int ret = LIBLTE_ERROR_INVALID_INPUTS;
@ -252,6 +252,7 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input,
memcpy(q->tmp_input, input, q->frame_size * sizeof(cf_t)); memcpy(q->tmp_input, input, q->frame_size * sizeof(cf_t));
bzero(&q->tmp_input[q->frame_size], q->fft_size * sizeof(cf_t)); bzero(&q->tmp_input[q->frame_size], q->fft_size * sizeof(cf_t));
/* Correlate input with PSS sequence */
#ifdef CONVOLUTION_FFT #ifdef CONVOLUTION_FFT
conv_output_len = conv_fft_cc_run(&q->conv_fft, q->tmp_input, conv_output_len = conv_fft_cc_run(&q->conv_fft, q->tmp_input,
q->pss_signal_freq[q->N_id_2], q->conv_output); q->pss_signal_freq[q->N_id_2], q->conv_output);
@ -259,16 +260,16 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input,
conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size); conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size);
#endif #endif
vec_abs_cf(q->conv_output, q->conv_abs, conv_output_len); /* Take the real part of the convolution result and normalize */
corr_peak_pos = vec_max_fi(q->conv_abs, conv_output_len); vec_deinterleave_real_cf(q->conv_output, q->conv_real, conv_output_len);
vec_sc_prod_fff(q->conv_real, 1.0/62.0, q->conv_real, conv_output_len);
/* Find maximum */
corr_peak_pos = vec_max_fi(q->conv_real, conv_output_len);
if (corr_peak_value) { if (corr_peak_value) {
*corr_peak_value = q->conv_abs[corr_peak_pos]; *corr_peak_value = q->conv_real[corr_peak_pos];
}
if (corr_mean_value) {
*corr_mean_value = vec_acc_ff(q->conv_abs, conv_output_len)
/ conv_output_len;
} }
DEBUG("PSS correlation peak %.3f position %5d\n", q->conv_real[corr_peak_pos], corr_peak_pos);
ret = (int) corr_peak_pos; ret = (int) corr_peak_pos;
} }
return ret; return ret;

@ -44,7 +44,7 @@ void generate_N_id_1_table(uint32_t table[30][30]);
int sss_synch_init(sss_synch_t *q, uint32_t fft_size) { int sss_synch_init(sss_synch_t *q, uint32_t fft_size) {
if (q != NULL && if (q != NULL &&
fft_size < 2048) fft_size <= 2048)
{ {
uint32_t N_id_2; uint32_t N_id_2;
struct sss_tables sss_tables; struct sss_tables sss_tables;
@ -73,7 +73,7 @@ int sss_synch_init(sss_synch_t *q, uint32_t fft_size) {
int sss_synch_realloc(sss_synch_t *q, uint32_t fft_size) { int sss_synch_realloc(sss_synch_t *q, uint32_t fft_size) {
if (q != NULL && if (q != NULL &&
fft_size < 2048) fft_size <= 2048)
{ {
dft_plan_free(&q->dftp_input); dft_plan_free(&q->dftp_input);
if (dft_plan(&q->dftp_input, fft_size, FORWARD, COMPLEX)) { if (dft_plan(&q->dftp_input, fft_size, FORWARD, COMPLEX)) {

@ -51,7 +51,6 @@ int sync_init(sync_t *q, uint32_t find_frame_size, uint32_t track_frame_size, ui
fft_size_isvalid(fft_size)) fft_size_isvalid(fft_size))
{ {
bzero(q, sizeof(sync_t)); bzero(q, sizeof(sync_t));
q->pss_mode = PEAK_MEAN;
q->detect_cp = true; q->detect_cp = true;
q->sss_en = true; q->sss_en = true;
q->N_id_2 = 1000; q->N_id_2 = 1000;
@ -126,13 +125,6 @@ void sync_free(sync_t *q) {
} }
} }
void sync_pss_det_absolute(sync_t *q) {
q->pss_mode = ABSOLUTE;
}
void sync_pss_det_peak_to_avg(sync_t *q) {
q->pss_mode = PEAK_MEAN;
}
void sync_set_threshold(sync_t *q, float find_threshold, float track_threshold) { void sync_set_threshold(sync_t *q, float find_threshold, float track_threshold) {
q->find_threshold = find_threshold; q->find_threshold = find_threshold;
q->track_threshold = track_threshold; q->track_threshold = track_threshold;
@ -277,27 +269,14 @@ int sync_track(sync_t *q, cf_t *input, uint32_t offset, uint32_t *peak_position)
input != NULL && input != NULL &&
fft_size_isvalid(q->fft_size)) fft_size_isvalid(q->fft_size))
{ {
float peak_value, mean_value, *mean_ptr;
uint32_t peak_pos; uint32_t peak_pos;
pss_synch_set_N_id_2(&q->pss_track, q->N_id_2); pss_synch_set_N_id_2(&q->pss_track, q->N_id_2);
if (q->pss_mode == ABSOLUTE) { peak_pos = pss_synch_find_pss(&q->pss_track, &input[offset], &q->peak_value);
mean_ptr = NULL;
} else {
mean_ptr = &mean_value;
}
peak_pos = pss_synch_find_pss(&q->pss_track, &input[offset], &peak_value, mean_ptr);
if (q->pss_mode == ABSOLUTE) {
q->peak_value = peak_value;
} else {
q->peak_value = peak_value / mean_value;
}
DEBUG("PSS possible tracking peak pos=%d peak=%.2f threshold=%.2f\n", DEBUG("PSS possible tracking peak pos=%d peak=%.2f threshold=%.2f\n",
peak_pos, peak_value, q->track_threshold); peak_pos, q->peak_value, q->track_threshold);
if (q->peak_value > q->track_threshold) { if (q->peak_value > q->track_threshold) {
if (offset + peak_pos > q->fft_size) { if (offset + peak_pos > q->fft_size) {
@ -326,20 +305,13 @@ int sync_track(sync_t *q, cf_t *input, uint32_t offset, uint32_t *peak_position)
int sync_find(sync_t *q, cf_t *input, uint32_t *peak_position) { int sync_find(sync_t *q, cf_t *input, uint32_t *peak_position) {
uint32_t N_id_2, peak_pos[3]; uint32_t N_id_2, peak_pos[3];
float peak_value[3]; float peak_value[3];
float mean_value[3];
float max=-999; float max=-999;
uint32_t i; uint32_t i;
int ret; int ret;
float *mean_ptr;
for (N_id_2=0;N_id_2<3;N_id_2++) { for (N_id_2=0;N_id_2<3;N_id_2++) {
if (q->pss_mode == ABSOLUTE) {
mean_ptr = NULL;
} else {
mean_ptr = &mean_value[N_id_2];
}
pss_synch_set_N_id_2(&q->pss_find, N_id_2); pss_synch_set_N_id_2(&q->pss_find, N_id_2);
ret = pss_synch_find_pss(&q->pss_find, input, &peak_value[N_id_2], mean_ptr); ret = pss_synch_find_pss(&q->pss_find, input, &peak_value[N_id_2]);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error finding PSS for N_id_2=%d\n", N_id_2); fprintf(stderr, "Error finding PSS for N_id_2=%d\n", N_id_2);
return LIBLTE_ERROR; return LIBLTE_ERROR;
@ -354,19 +326,12 @@ int sync_find(sync_t *q, cf_t *input, uint32_t *peak_position) {
} }
} }
if (q->pss_mode == ABSOLUTE) {
q->peak_value = peak_value[N_id_2]; q->peak_value = peak_value[N_id_2];
} else {
q->peak_value = peak_value[N_id_2] / mean_value[N_id_2];
}
if (peak_position) { if (peak_position) {
*peak_position = 0; *peak_position = 0;
} }
DEBUG("PSS possible peak N_id_2=%d, pos=%d peak=%.2f threshold=%.2f\n",
N_id_2, peak_pos[N_id_2], peak_value[N_id_2], q->find_threshold);
/* If peak detected */ /* If peak detected */
if (q->peak_value > q->find_threshold) { if (q->peak_value > q->find_threshold) {
if (peak_pos[N_id_2] > q->fft_size && if (peak_pos[N_id_2] > q->fft_size &&
@ -376,8 +341,8 @@ int sync_find(sync_t *q, cf_t *input, uint32_t *peak_position) {
pss_synch_set_N_id_2(&q->pss_find, q->N_id_2); pss_synch_set_N_id_2(&q->pss_find, q->N_id_2);
q->cfo = pss_synch_cfo_compute(&q->pss_find, &input[peak_pos[N_id_2]-q->fft_size]); q->cfo = pss_synch_cfo_compute(&q->pss_find, &input[peak_pos[N_id_2]-q->fft_size]);
DEBUG("PSS peak detected N_id_2=%d, pos=%d peak=%.2f par=%.2f th=%.2f cfo=%.4f\n", N_id_2, DEBUG("PSS peak detected N_id_2=%d, pos=%d peak=%.2f th=%.2f cfo=%.4f\n", N_id_2,
peak_pos[N_id_2], peak_value[N_id_2], q->peak_value, q->find_threshold, q->cfo); peak_pos[N_id_2], q->peak_value, q->find_threshold, q->cfo);
if (q->sss_en) { if (q->sss_en) {
if (sync_sss(q, input, peak_pos[q->N_id_2], q->detect_cp) < 0) { if (sync_sss(q, input, peak_pos[q->N_id_2], q->detect_cp) < 0) {

@ -32,6 +32,11 @@ ADD_TEST(sync_test_400 sync_test -o 400)
ADD_TEST(sync_test_100_e sync_test -o 100 -e) ADD_TEST(sync_test_100_e sync_test -o 100 -e)
ADD_TEST(sync_test_400_e sync_test -o 400 -e) ADD_TEST(sync_test_400_e sync_test -o 400 -e)
ADD_TEST(sync_test_100 sync_test -o 100 -p 50)
ADD_TEST(sync_test_400 sync_test -o 400 -p 50)
ADD_TEST(sync_test_100_e sync_test -o 100 -e -p 50)
ADD_TEST(sync_test_400_e sync_test -o 400 -e -p 50)
######################################################################## ########################################################################
# CFO TEST # CFO TEST
######################################################################## ########################################################################

@ -32,18 +32,21 @@
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <stdbool.h> #include <stdbool.h>
#include "liblte/phy/phy.h" #include "liblte/phy/phy.h"
int cell_id = -1, offset = 0; int cell_id = -1, offset = 0;
lte_cp_t cp = CPNORM; lte_cp_t cp = CPNORM;
uint32_t nof_prb=6;
#define FLEN 9600 #define FLEN SF_LEN(fft_size, cp)
void usage(char *prog) { void usage(char *prog) {
printf("Usage: %s [coev]\n", prog); printf("Usage: %s [cpoev]\n", prog);
printf("\t-c cell_id [Default check for all]\n"); printf("\t-c cell_id [Default check for all]\n");
printf("\t-p nof_prb [Default %d]\n", nof_prb);
printf("\t-o offset [Default %d]\n", offset); printf("\t-o offset [Default %d]\n", offset);
printf("\t-e extended CP [Default normal]\n"); printf("\t-e extended CP [Default normal]\n");
printf("\t-v verbose\n"); printf("\t-v verbose\n");
@ -51,11 +54,14 @@ void usage(char *prog) {
void parse_args(int argc, char **argv) { void parse_args(int argc, char **argv) {
int opt; int opt;
while ((opt = getopt(argc, argv, "coev")) != -1) { while ((opt = getopt(argc, argv, "cpoev")) != -1) {
switch (opt) { switch (opt) {
case 'c': case 'c':
cell_id = atoi(argv[optind]); cell_id = atoi(argv[optind]);
break; break;
case 'p':
nof_prb = atoi(argv[optind]);
break;
case 'o': case 'o':
offset = atoi(argv[optind]); offset = atoi(argv[optind]);
break; break;
@ -82,32 +88,40 @@ int main(int argc, char **argv) {
uint32_t find_idx; uint32_t find_idx;
sync_t sync; sync_t sync;
lte_fft_t ifft; lte_fft_t ifft;
int fft_size;
parse_args(argc, argv); parse_args(argc, argv);
fft_size = lte_symbol_sz(nof_prb);
if (fft_size < 0) {
fprintf(stderr, "Invalid nof_prb=%d\n", nof_prb);
exit(-1);
}
buffer = malloc(sizeof(cf_t) * FLEN); buffer = malloc(sizeof(cf_t) * FLEN);
if (!buffer) { if (!buffer) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
fft_buffer = malloc(sizeof(cf_t) * 2 * FLEN); fft_buffer = malloc(sizeof(cf_t) * FLEN);
if (!fft_buffer) { if (!fft_buffer) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
if (lte_ifft_init(&ifft, cp, 6)) { if (lte_ifft_init(&ifft, cp, nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n"); fprintf(stderr, "Error creating iFFT object\n");
exit(-1); exit(-1);
} }
if (sync_init(&sync, FLEN, 128, 128)) { if (sync_init(&sync, FLEN, fft_size, fft_size)) {
fprintf(stderr, "Error initiating PSS/SSS\n"); fprintf(stderr, "Error initiating PSS/SSS\n");
return -1; return -1;
} }
sync_set_threshold(&sync, 1, 1); /* Set a very high threshold to make sure the correlation is ok */
sync_set_threshold(&sync, 0.99, 0.99);
if (cell_id == -1) { if (cell_id == -1) {
cid = 0; cid = 0;
@ -125,19 +139,21 @@ int main(int argc, char **argv) {
for (ns=0;ns<2;ns++) { for (ns=0;ns<2;ns++) {
memset(buffer, 0, sizeof(cf_t) * FLEN); memset(buffer, 0, sizeof(cf_t) * FLEN);
pss_put_slot(pss_signal, buffer, 6, cp); pss_put_slot(pss_signal, buffer, nof_prb, cp);
sss_put_slot(ns?sss_signal5:sss_signal0, buffer, 6, cp); sss_put_slot(ns?sss_signal5:sss_signal0, buffer, nof_prb, cp);
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
memset(fft_buffer, 0, sizeof(cf_t) * 2 * FLEN); memset(fft_buffer, 0, sizeof(cf_t) * FLEN);
lte_ifft_run_slot(&ifft, buffer, &fft_buffer[offset]); lte_ifft_run_slot(&ifft, buffer, &fft_buffer[offset]);
vec_save_file("input", fft_buffer, sizeof(cf_t) * FLEN);
sync_find(&sync, fft_buffer, &find_idx); sync_find(&sync, fft_buffer, &find_idx);
find_ns = sync_get_slot_id(&sync); find_ns = sync_get_slot_id(&sync);
printf("cell_id: %d find: %d, offset: %d, ns=%d find_ns=%d\n", cid, find_idx, offset, printf("cell_id: %d find: %d, offset: %d, ns=%d find_ns=%d\n", cid, find_idx, offset,
ns, find_ns); ns, find_ns);
if (find_idx != offset + 960) { if (find_idx != offset + FLEN/2) {
printf("offset != find_offset: %d != %d\n", find_idx, offset + 960); printf("offset != find_offset: %d != %d\n", find_idx, offset + FLEN/2);
exit(-1); exit(-1);
} }
if (ns*10 != find_ns) { if (ns*10 != find_ns) {

@ -53,6 +53,9 @@ int conv_fft_cc_init(conv_fft_cc_t *q, uint32_t input_len, uint32_t filter_len)
if (dft_plan(&q->output_plan,q->output_len,BACKWARD,COMPLEX)) { if (dft_plan(&q->output_plan,q->output_len,BACKWARD,COMPLEX)) {
return LIBLTE_ERROR; return LIBLTE_ERROR;
} }
dft_plan_set_norm(&q->input_plan, true);
dft_plan_set_norm(&q->filter_plan, true);
dft_plan_set_norm(&q->output_plan, false);
return LIBLTE_SUCCESS; return LIBLTE_SUCCESS;
} }
@ -80,7 +83,7 @@ uint32_t conv_fft_cc_run(conv_fft_cc_t *q, cf_t *input, cf_t *filter, cf_t *outp
dft_run_c(&q->output_plan, q->output_fft, output); dft_run_c(&q->output_plan, q->output_fft, output);
return q->output_len; return q->output_len-1;
} }

@ -32,6 +32,7 @@
#include <string.h> #include <string.h>
#include "liblte/phy/utils/dft.h" #include "liblte/phy/utils/dft.h"
#include "liblte/phy/utils/vector.h"
#define dft_ceil(a,b) ((a-1)/b+1) #define dft_ceil(a,b) ((a-1)/b+1)
#define dft_floor(a,b) (a/b) #define dft_floor(a,b) (a/b)
@ -144,11 +145,8 @@ void dft_run_c(dft_plan_t *plan, dft_c_t *in, dft_c_t *out) {
plan->forward, plan->mirror, plan->dc); plan->forward, plan->mirror, plan->dc);
fftwf_execute(plan->p); fftwf_execute(plan->p);
if (plan->norm) { if (plan->norm) {
/**FIXME: Use VOLK */ norm = 1.0/sqrtf(plan->size);
norm = sqrtf(plan->size); vec_sc_prod_cfc(f_out, norm, f_out, plan->size);
for (i=0;i<plan->size;i++) {
f_out[i] /= norm;
}
} }
if (plan->db) { if (plan->db) {
for (i=0;i<plan->size;i++) { for (i=0;i<plan->size;i++) {
@ -168,10 +166,8 @@ void dft_run_r(dft_plan_t *plan, dft_r_t *in, dft_r_t *out) {
memcpy(plan->in,in,sizeof(dft_r_t)*plan->size); memcpy(plan->in,in,sizeof(dft_r_t)*plan->size);
fftwf_execute(plan->p); fftwf_execute(plan->p);
if (plan->norm) { if (plan->norm) {
norm = plan->size; norm = 1.0/plan->size;
for (i=0;i<len;i++) { vec_sc_prod_fff(f_out, norm, f_out, plan->size);
f_out[i] /= norm;
}
} }
if (plan->db) { if (plan->db) {
for (i=0;i<len;i++) { for (i=0;i<len;i++) {

@ -155,6 +155,17 @@ void vec_deinterleave_cf(cf_t *x, float *real, float *imag, uint32_t len) {
#endif #endif
} }
void vec_deinterleave_real_cf(cf_t *x, float *real, uint32_t len) {
#ifdef HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION
volk_32fc_deinterleave_real_32f(real, x, len);
#else
int i;
for (i=0;i<len;i++) {
real[i] = __real__ x[i];
}
#endif
}
void *vec_malloc(uint32_t size) { void *vec_malloc(uint32_t size) {
#ifndef HAVE_VOLK #ifndef HAVE_VOLK
return malloc(size); return malloc(size);

@ -0,0 +1,6 @@
function [ y ] = addnoise( x, snr_db )
v = 10^(-snr_db/10);
y=x+sqrt(v)*(randn(size(x))+1i*randn(size(x)))/sqrt(2);
y=y/sqrt(mean(y.*conj(y)));
end

@ -1,18 +1,16 @@
function [ fs eps p_m w2] = find_pss( x, N_id_2, fft_size) function [ w2] = find_pss2( x, N_id_2, fft_size)
c=lte_pss_zc(N_id_2); c=lte_pss_zc(N_id_2);
cc=[zeros(fft_size/2-31,1); c; zeros(fft_size/2-31,1)]; cc=[zeros(fft_size/2-31,1); c; zeros(fft_size/2-31,1)];
cc=[0; cc(fft_size/2+1:fft_size); cc(2:fft_size/2)]; ccd=[0; cc(fft_size/2+1:fft_size); cc(2:fft_size/2)];
ccf=conj(ifft(cc)); ccf=sqrt(fft_size)*conj(ifft(ccd));
w2=conv(x,ccf); w2=real(conv(x,ccf))/62;
%plot(10*log10(abs(w2)));%./mean(abs(w2)))); plot(w2)
plot(abs(w2)) [m i]=max(w2);
%axis([0 length(w2) 0 20]) en=var(x,1);
[m i]=max(abs(w2)); p_m = m/en;
p_m = m/mean(abs(w2));
fprintf('Frame starts at %d, m=%g, p=%g, p/m=%g dB\n',i, ...
mean(abs(w2)), m, 10*log10(m/mean(abs(w2))));
fprintf('Frame starts at %d, energy=%g, p=%g, p/en=%g dB\n',i, ...
en, m, m/en);
end end

Loading…
Cancel
Save