-adding more prach tests to make test, removing some variables from stack

-PRACH time offset to TA unit conversion
master
yagoda 4 years ago committed by Justin Tallon
parent 59082770d3
commit b5a8d82058

@ -107,6 +107,8 @@ typedef struct SRSLTE_API {
cf_t* cross; cf_t* cross;
cf_t* corr_freq; cf_t* corr_freq;
srslte_prach_cancellation_t prach_cancel; srslte_prach_cancellation_t prach_cancel;
cf_t sub[839 * 2];
float phase[839];
} srslte_prach_t; } srslte_prach_t;

@ -48,7 +48,8 @@ float save_corr[4096];
int srslte_prach_set_cell_(srslte_prach_t* p, int srslte_prach_set_cell_(srslte_prach_t* p,
uint32_t N_ifft_ul, uint32_t N_ifft_ul,
srslte_prach_cfg_t* cfg); srslte_prach_cfg_t* cfg,
srslte_tdd_config_t* tdd_config);
uint32_t srslte_prach_get_preamble_format(uint32_t config_idx) uint32_t srslte_prach_get_preamble_format(uint32_t config_idx)
{ {
@ -324,9 +325,7 @@ int srslte_prach_gen_seqs(srslte_prach_t* p)
int srslte_prach_set_cfg(srslte_prach_t* p, srslte_prach_cfg_t* cfg, uint32_t nof_prb) int srslte_prach_set_cfg(srslte_prach_t* p, srslte_prach_cfg_t* cfg, uint32_t nof_prb)
{ {
return srslte_prach_set_cell_(p, return srslte_prach_set_cell_(p, srslte_symbol_sz(nof_prb), cfg, &cfg->tdd_config);
srslte_symbol_sz(nof_prb),
cfg);
} }
int srslte_prach_init(srslte_prach_t* p, uint32_t max_N_ifft_ul) int srslte_prach_init(srslte_prach_t* p, uint32_t max_N_ifft_ul)
@ -392,7 +391,8 @@ int srslte_prach_init(srslte_prach_t* p, uint32_t max_N_ifft_ul)
int srslte_prach_set_cell_(srslte_prach_t* p, int srslte_prach_set_cell_(srslte_prach_t* p,
uint32_t N_ifft_ul, uint32_t N_ifft_ul,
srslte_prach_cfg_t* cfg) srslte_prach_cfg_t* cfg,
srslte_tdd_config_t* tdd_config)
{ {
int ret = SRSLTE_ERROR; int ret = SRSLTE_ERROR;
if (p != NULL && N_ifft_ul < 2049 && cfg->config_idx < 64 && cfg->root_seq_idx < MAX_ROOTS) { if (p != NULL && N_ifft_ul < 2049 && cfg->config_idx < 64 && cfg->root_seq_idx < MAX_ROOTS) {
@ -415,8 +415,8 @@ int srslte_prach_set_cell_(srslte_prach_t* p,
p->successive_cancellation = false; p->successive_cancellation = false;
} }
p->freq_domain_offset_calc = cfg->enable_freq_domain_offset_calc; p->freq_domain_offset_calc = cfg->enable_freq_domain_offset_calc;
if (&cfg->tdd_config) { if (tdd_config) {
p->tdd_config = cfg->tdd_config; p->tdd_config = *tdd_config;
} }
// Determine N_zc and N_cs // Determine N_zc and N_cs
@ -578,22 +578,23 @@ int srslte_prach_detect(srslte_prach_t* p,
/// be detected more easily in the subsequent searches /// be detected more easily in the subsequent searches
void srslte_prach_cancellation(srslte_prach_t* p) void srslte_prach_cancellation(srslte_prach_t* p)
{ {
cf_t sub[p->N_zc * 2]; srslte_vec_cf_zero(p->sub, p->N_zc * 2);
srslte_vec_cf_copy(sub, &p->dft_seqs[p->root_seqs_idx[p->prach_cancel.idx]][0], p->N_zc); srslte_vec_cf_copy(p->sub, &p->dft_seqs[p->root_seqs_idx[p->prach_cancel.idx]][0], p->N_zc);
srslte_vec_prod_ccc(sub, p->prach_cancel.phase_array, sub, p->N_zc); srslte_vec_prod_ccc(p->sub, p->prach_cancel.phase_array, p->sub, p->N_zc);
#ifdef PRACH_CANCELLATION_HARD #ifdef PRACH_CANCELLATION_HARD
srslte_vec_prod_conj_ccc(p->prach_bins, sub, p->corr_spec, p->N_zc); srslte_vec_prod_conj_ccc(p->prach_bins, p->sub, p->corr_spec, p->N_zc);
srslte_dft_run(&p->zc_ifft, p->corr_spec, p->corr_spec); srslte_dft_run(&p->zc_ifft, p->corr_spec, p->corr_spec);
srslte_vec_abs_square_cf(p->corr_spec, p->corr, p->N_zc); srslte_vec_abs_square_cf(p->corr_spec, p->corr, p->N_zc);
prach_cancel->factor = sqrt(p->corr[0] / (p->N_zc * p->N_zc)); prach_cancel->factor = sqrt(p->corr[0] / (p->N_zc * p->N_zc));
#endif #endif
srslte_vec_sc_prod_cfc(sub, p->prach_cancel.factor, sub, p->N_zc); srslte_vec_sc_prod_cfc(p->sub, p->prach_cancel.factor, p->sub, p->N_zc);
srslte_vec_sub_ccc(p->prach_bins, sub, p->prach_bins, p->N_zc); srslte_vec_sub_ccc(p->prach_bins, p->sub, p->prach_bins, p->N_zc);
} }
// this function checks if we have already detected and stored this particular PRACH index and if so, doesnt store it // this function checks if we have already detected and stored this particular PRACH index and if so, doesnt store it
// again in the detected prachs array // again in the detected prachs array
bool srslte_prach_have_stored(srslte_prach_t* p,int current_idx, uint32_t* indices, uint32_t n_indices) { bool srslte_prach_have_stored(int current_idx, uint32_t* indices, uint32_t n_indices)
{
for(int i = 0; i < n_indices; i++) { for(int i = 0; i < n_indices; i++) {
if (indices[i] == current_idx) { if (indices[i] == current_idx) {
return true; return true;
@ -603,14 +604,7 @@ bool srslte_prach_have_stored(srslte_prach_t* p,int current_idx, uint32_t* indic
} }
// set the offset based on the time domain time offset estimation // set the offset based on the time domain time offset estimation
float srslte_prach_set_offset(srslte_prach_t* p, int n_win) { float srslte_prach_set_offset(srslte_prach_t* p, int n_win) {
float corr = 1.0; return (float)p->peak_offsets[n_win] / (float)(DELTA_F_RA * p->N_zc);
if (p->peak_offsets[n_win] > 30) {
corr = 1.9;
}
if (p->peak_offsets[n_win] > 250) {
corr = 1.91;
}
return corr * p->peak_offsets[n_win] / (DELTA_F_RA * p->N_zc);
} }
// calculates the timing offset of the incoming PRACH by calculating the phase in frequency - alternative to time domain // calculates the timing offset of the incoming PRACH by calculating the phase in frequency - alternative to time domain
@ -626,10 +620,9 @@ int srslte_prach_calculate_time_offset(srslte_prach_t* p, cf_t* cross)
// before it is subtracted from the input // before it is subtracted from the input
void srslte_prach_calculate_correction_array(srslte_prach_t* p, cf_t* corr_freq) void srslte_prach_calculate_correction_array(srslte_prach_t* p, cf_t* corr_freq)
{ {
float phase[p->N_zc]; srslte_vec_arg_deg_cf(corr_freq, 0, p->phase, p->N_zc);
srslte_vec_arg_deg_cf(corr_freq, 0, phase, p->N_zc);
for (int i = 0; i < p->N_zc; i++) { for (int i = 0; i < p->N_zc; i++) {
p->prach_cancel.phase_array[i] = cexpf(_Complex_I * (phase[i] / (180.0f / M_PI))); p->prach_cancel.phase_array[i] = cexpf(_Complex_I * (p->phase[i] / (180.0f / M_PI)));
} }
} }
@ -704,7 +697,7 @@ int srslte_prach_process(srslte_prach_t* p,
p->prach_cancel.factor = (sqrt(max_peak / (p->N_zc * p->N_zc))); p->prach_cancel.factor = (sqrt(max_peak / (p->N_zc * p->N_zc)));
srslte_prach_calculate_correction_array(p, p->corr_freq); srslte_prach_calculate_correction_array(p, p->corr_freq);
} }
if (srslte_prach_have_stored(p, ((i * n_wins) + j), indices, *n_indices)) { if (srslte_prach_have_stored(((i * n_wins) + j), indices, *n_indices)) {
break; break;
} }
} }

@ -582,6 +582,37 @@ add_test(prach_test_multi_n16 prach_test_multi -n 16)
add_test(prach_test_multi_n8 prach_test_multi -n 8) add_test(prach_test_multi_n8 prach_test_multi -n 8)
add_test(prach_test_multi_n4 prach_test_multi -n 4) add_test(prach_test_multi_n4 prach_test_multi -n 4)
add_test(prach_test_multi_stagger_power prach_test_multi -s -S)
add_test(prach_test_multi_stagger_power prach_test_multi -s -S -N 50)
add_test(prach_test_multi_offset_test prach_test_multi -O)
add_test(prach_test_multi_offset_test_50 prach_test_multi -O -N 50)
add_test(prach_test_multi_freq_offset_test_n1_o100_prb6 prach_test_multi -n 1 -F -z 0 -o 100)
add_test(prach_test_multi_freq_offset_test_n1_o500_prb6 prach_test_multi -n 1 -F -z 0 -o 500)
add_test(prach_test_multi_freq_offset_test_n1_o800_prb6 prach_test_multi -n 1 -F -z 0 -o 800)
add_test(prach_test_multi_freq_offset_test_n1_o100_prb50 prach_test_multi -n 1 -F -z 0 -o 100 -N 50)
add_test(prach_test_multi_freq_offset_test_n1_o500_prb50 prach_test_multi -n 1 -F -z 0 -o 500 -N 50)
add_test(prach_test_multi_freq_offset_test_n1_o800_prb50 prach_test_multi -n 1 -F -z 0 -o 800 -N 50)
add_test(prach_test_multi_freq_offset_test_n2_o100_prb6 prach_test_multi -n 2 -F -z 0 -o 100)
add_test(prach_test_multi_freq_offset_test_n2_o500_prb6 prach_test_multi -n 2 -F -z 0 -o 500)
add_test(prach_test_multi_freq_offset_test_n2_o800_prb6 prach_test_multi -n 2 -F -z 0 -o 800)
add_test(prach_test_multi_freq_offset_test_n2_o100_prb50 prach_test_multi -n 2 -F -z 0 -o 100 -N 50)
add_test(prach_test_multi_freq_offset_test_n2_o500_prb50 prach_test_multi -n 2 -F -z 0 -o 500 -N 50)
add_test(prach_test_multi_freq_offset_test_n2_o800_prb50 prach_test_multi -n 2 -F -z 0 -o 800 -N 50)
add_test(prach_test_multi_freq_offset_test_n4_o100_prb6 prach_test_multi -n 4 -F -z 0 -o 100)
add_test(prach_test_multi_freq_offset_test_n4_o500_prb6 prach_test_multi -n 4 -F -z 0 -o 500)
add_test(prach_test_multi_freq_offset_test_n4_o800_prb6 prach_test_multi -n 4 -F -z 0 -o 800)
add_test(prach_test_multi_freq_offset_test_n4_o100_prb50 prach_test_multi -n 4 -F -z 0 -o 100 -N 50)
add_test(prach_test_multi_freq_offset_test_n4_o500_prb50 prach_test_multi -n 4 -F -z 0 -o 500 -N 50)
add_test(prach_test_multi_freq_offset_test_n4_o800_prb50 prach_test_multi -n 4 -F -z 0 -o 800 -N 50)
if(RF_FOUND) if(RF_FOUND)
add_executable(prach_test_usrp prach_test_usrp.c) add_executable(prach_test_usrp prach_test_usrp.c)
target_link_libraries(prach_test_usrp srslte_rf srslte_phy pthread) target_link_libraries(prach_test_usrp srslte_rf srslte_phy pthread)

@ -59,12 +59,16 @@ void usage(char* prog)
printf("\t-r Root sequence index [Default 0]\n"); printf("\t-r Root sequence index [Default 0]\n");
printf("\t-z Zero correlation zone config [Default 1]\n"); printf("\t-z Zero correlation zone config [Default 1]\n");
printf("\t-n Number of sequences used for each test [Default 64]\n"); printf("\t-n Number of sequences used for each test [Default 64]\n");
printf("\t-S stagger_prach_power_and_phase [Default false]\n");
printf("\t-s test_successive_cancellation [Default false]\n");
printf("\t-O test_offset_calculation [Default false]\n");
printf("\t-F freq_domain_offset_calc [Default false]\n");
} }
void parse_args(int argc, char** argv) void parse_args(int argc, char** argv)
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "Nfrznio")) != -1) { while ((opt = getopt(argc, argv, "NfrznioSsOF")) != -1) {
switch (opt) { switch (opt) {
case 'N': case 'N':
nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); nof_prb = (uint32_t)strtol(argv[optind], NULL, 10);
@ -87,6 +91,18 @@ void parse_args(int argc, char** argv)
case 'o': case 'o':
offset = (uint32_t)strtol(argv[optind], NULL, 10); offset = (uint32_t)strtol(argv[optind], NULL, 10);
break; break;
case 's':
test_successive_cancellation = true;
break;
case 'O':
test_offset_calculation = true;
break;
case 'S':
stagger_prach_power_and_phase = true;
break;
case 'F':
freq_domain_offset_calc = true;
break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); exit(-1);

@ -149,7 +149,10 @@ int prach_worker::run_tti(sf_buffer* b)
max_prach_offset_us); max_prach_offset_us);
if (prach_offsets[i] * 1e6 < max_prach_offset_us) { if (prach_offsets[i] * 1e6 < max_prach_offset_us) {
stack->rach_detected(b->tti, cc_idx, prach_indices[i], (uint32_t)(prach_offsets[i] * 1e6)); // Convert time offset to Time Alignment command
uint32_t n_ta = (uint32_t)(prach_offsets[i] / (16 * SRSLTE_LTE_TS));
stack->rach_detected(b->tti, cc_idx, prach_indices[i], n_ta);
#if defined(ENABLE_GUI) and ENABLE_PRACH_GUI #if defined(ENABLE_GUI) and ENABLE_PRACH_GUI
uint32_t nof_samples = SRSLTE_MIN(nof_sf * SRSLTE_SF_LEN_PRB(cell.nof_prb), 3 * SRSLTE_SF_LEN_MAX); uint32_t nof_samples = SRSLTE_MIN(nof_sf * SRSLTE_SF_LEN_PRB(cell.nof_prb), 3 * SRSLTE_SF_LEN_MAX);

Loading…
Cancel
Save