|
|
|
@ -549,9 +549,6 @@ void phch_recv::run_thread()
|
|
|
|
|
phy_state = IDLE;
|
|
|
|
|
is_in_idle = true;
|
|
|
|
|
|
|
|
|
|
uint32_t hf_len;
|
|
|
|
|
uint32_t fft_sz;
|
|
|
|
|
|
|
|
|
|
while (running)
|
|
|
|
|
{
|
|
|
|
|
if (phy_state != IDLE) {
|
|
|
|
@ -680,23 +677,9 @@ void phch_recv::run_thread()
|
|
|
|
|
}
|
|
|
|
|
workers_pool->start_worker(worker);
|
|
|
|
|
|
|
|
|
|
// Substract PSS/SSS from current cell before computing intrafrequency
|
|
|
|
|
hf_len = SRSLTE_SF_LEN_PRB(cell.nof_prb)/2;
|
|
|
|
|
fft_sz = srslte_symbol_sz(cell.nof_prb);
|
|
|
|
|
|
|
|
|
|
// Substract PSS/SSS from current cell before computing intra-frequency
|
|
|
|
|
if ((tti%5) == 0) {
|
|
|
|
|
srslte_vec_sc_prod_cfc(ue_sync.strack.pss_filt, 1.0/sqrtf(fft_sz), ue_sync.strack.pss_filt, fft_sz);
|
|
|
|
|
srslte_vec_sc_prod_cfc(ue_sync.strack.sss_filt, 1.0/sqrtf(fft_sz), ue_sync.strack.pss_filt, fft_sz);
|
|
|
|
|
|
|
|
|
|
srslte_vec_sub_ccc(&buffer[0][hf_len-fft_sz],
|
|
|
|
|
ue_sync.strack.pss_filt,
|
|
|
|
|
&buffer[0][hf_len-fft_sz],
|
|
|
|
|
fft_sz);
|
|
|
|
|
|
|
|
|
|
srslte_vec_sub_ccc(&buffer[0][hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)],
|
|
|
|
|
ue_sync.strack.sss_filt,
|
|
|
|
|
&buffer[0][hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)],
|
|
|
|
|
fft_sz);
|
|
|
|
|
substract_sync(buffer[0], cell.nof_prb, &ue_sync.strack);
|
|
|
|
|
}
|
|
|
|
|
intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
|
|
|
|
out_of_sync_cnt = 0;
|
|
|
|
@ -749,7 +732,24 @@ void phch_recv::out_of_sync() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phch_recv::substract_sync(cf_t *buffer, uint32_t nof_prb, srslte_sync_t *sync_obj)
|
|
|
|
|
{
|
|
|
|
|
uint32_t hf_len = SRSLTE_SF_LEN_PRB(nof_prb)/2;
|
|
|
|
|
uint32_t fft_sz = srslte_symbol_sz(nof_prb);
|
|
|
|
|
|
|
|
|
|
srslte_vec_sc_prod_cfc(sync_obj->pss_filt, 1.0/sqrtf(fft_sz), sync_obj->pss_filt, fft_sz);
|
|
|
|
|
srslte_vec_sc_prod_cfc(sync_obj->sss_filt, 1.0/sqrtf(fft_sz), sync_obj->sss_filt, fft_sz);
|
|
|
|
|
|
|
|
|
|
srslte_vec_sub_ccc(&buffer[hf_len-fft_sz],
|
|
|
|
|
sync_obj->pss_filt,
|
|
|
|
|
&buffer[hf_len-fft_sz],
|
|
|
|
|
fft_sz);
|
|
|
|
|
|
|
|
|
|
srslte_vec_sub_ccc(&buffer[hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)],
|
|
|
|
|
sync_obj->sss_filt,
|
|
|
|
|
&buffer[hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)],
|
|
|
|
|
fft_sz);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1070,6 +1070,10 @@ float phch_recv::measure::snr() {
|
|
|
|
|
return mean_snr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t phch_recv::measure::frame_st_idx() {
|
|
|
|
|
return final_offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phch_recv::measure::set_rx_gain_offset(float rx_gain_offset) {
|
|
|
|
|
this->rx_gain_offset = rx_gain_offset;
|
|
|
|
|
}
|
|
|
|
@ -1097,7 +1101,6 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in
|
|
|
|
|
|
|
|
|
|
ret_code ret = IDLE;
|
|
|
|
|
|
|
|
|
|
Info("INTRA: Here offset=%d\n", offset);
|
|
|
|
|
offset = offset-sf_len/2;
|
|
|
|
|
if (offset < 0) {
|
|
|
|
|
offset += sf_len;
|
|
|
|
@ -1133,15 +1136,13 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found_best) {
|
|
|
|
|
Info("INTRA: fine-tuned offset=%d\n", best_test_offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
offset = found_best?best_test_offset:offset;
|
|
|
|
|
if (offset >= 0 && offset < sf_len*max_sf) {
|
|
|
|
|
uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len;
|
|
|
|
|
|
|
|
|
|
Info("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf);
|
|
|
|
|
Debug("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf);
|
|
|
|
|
|
|
|
|
|
final_offset = offset;
|
|
|
|
|
|
|
|
|
|
for (uint32_t i=0;i<nof_sf;i++) {
|
|
|
|
|
memcpy(buffer[0], &input_buffer[offset+i*sf_len], sizeof(cf_t)*sf_len);
|
|
|
|
@ -1208,7 +1209,8 @@ void phch_recv::scell_recv::init(srslte::log *log_h)
|
|
|
|
|
uint32_t max_fft_sz = srslte_symbol_sz(100);
|
|
|
|
|
uint32_t max_sf_size = SRSLTE_SF_LEN(max_fft_sz);
|
|
|
|
|
|
|
|
|
|
sf_buffer[0] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*max_sf_size);
|
|
|
|
|
sf_buffer[0] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*max_sf_size);
|
|
|
|
|
input_cfo_corrected = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*15*max_sf_size);
|
|
|
|
|
|
|
|
|
|
measure_p.init(sf_buffer, log_h, 1, DEFAULT_MEASUREMENT_LEN);
|
|
|
|
|
|
|
|
|
@ -1250,9 +1252,6 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
|
|
|
|
|
current_fft_sz = fft_sz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srslte_sync_reset(&sync_find);
|
|
|
|
|
srslte_sync_cfo_reset(&sync_find);
|
|
|
|
|
|
|
|
|
|
int nof_cells = 0;
|
|
|
|
|
uint32_t peak_idx = 0;
|
|
|
|
|
uint32_t sf_idx = 0;
|
|
|
|
@ -1260,6 +1259,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
|
|
|
|
|
|
|
|
|
|
srslte_cell_t found_cell;
|
|
|
|
|
memcpy(&found_cell, &cell, sizeof(srslte_cell_t));
|
|
|
|
|
found_cell.id = 10000;
|
|
|
|
|
|
|
|
|
|
measure_p.set_rx_gain_offset(rx_gain_offset);
|
|
|
|
|
|
|
|
|
@ -1268,54 +1268,72 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
|
|
|
|
|
if (cell.id%3 != n_id_2) {
|
|
|
|
|
srslte_sync_set_N_id_2(&sync_find, n_id_2);
|
|
|
|
|
|
|
|
|
|
srslte_sync_find_ret_t sync_res = srslte_sync_find(&sync_find, input_buffer, 0, &peak_idx);
|
|
|
|
|
|
|
|
|
|
switch(sync_res) {
|
|
|
|
|
case SRSLTE_SYNC_ERROR:
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
fprintf(stderr, "Error finding correlation peak\n");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
case SRSLTE_SYNC_FOUND:
|
|
|
|
|
sf_idx = srslte_sync_get_sf_idx(&sync_find);
|
|
|
|
|
cell_id = srslte_sync_get_cell_id(&sync_find);
|
|
|
|
|
|
|
|
|
|
if (cell_id != -1) {
|
|
|
|
|
Info("INTRA: found peak_idx=%d, n_id_2=%d, cell_id=%d, sf=%d, cfo=%.1f Hz, psr=%f\n",
|
|
|
|
|
peak_idx, n_id_2, cell_id, sf_idx, 15000*srslte_sync_get_cfo(&sync_find), sync_find.peak_value);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
if (cell_id == 342) {
|
|
|
|
|
srslte_vec_save_file("input", input_buffer, 5*sf_len*sizeof(cf_t));
|
|
|
|
|
srslte_vec_save_file("conv", sync_find.pss.conv_output, sync_find.pss.frame_size*sizeof(cf_t));
|
|
|
|
|
exit(-1);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
found_cell.id = cell_id;
|
|
|
|
|
found_cell.nof_ports = 1; // Use port 0 only for measurement
|
|
|
|
|
measure_p.set_cell(found_cell);
|
|
|
|
|
|
|
|
|
|
switch(measure_p.run_multiple_subframes(input_buffer, peak_idx, sf_idx, nof_sf)) {
|
|
|
|
|
case measure::MEASURE_OK:
|
|
|
|
|
cells[nof_cells].pci = found_cell.id;
|
|
|
|
|
cells[nof_cells].rsrp = measure_p.rsrp();
|
|
|
|
|
cells[nof_cells].rsrq = measure_p.rsrq();
|
|
|
|
|
cells[nof_cells].offset = peak_idx;
|
|
|
|
|
nof_cells++;
|
|
|
|
|
break;
|
|
|
|
|
case measure::ERROR:
|
|
|
|
|
Error("Measuring neighbour cell\n");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
srslte_sync_find_ret_t sync_res;
|
|
|
|
|
do {
|
|
|
|
|
|
|
|
|
|
srslte_sync_reset(&sync_find);
|
|
|
|
|
srslte_sync_cfo_reset(&sync_find);
|
|
|
|
|
|
|
|
|
|
sync_res = srslte_sync_find(&sync_find, input_buffer, 0, &peak_idx);
|
|
|
|
|
|
|
|
|
|
switch(sync_res) {
|
|
|
|
|
case SRSLTE_SYNC_ERROR:
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
fprintf(stderr, "Error finding correlation peak\n");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
case SRSLTE_SYNC_FOUND:
|
|
|
|
|
sf_idx = srslte_sync_get_sf_idx(&sync_find);
|
|
|
|
|
cell_id = srslte_sync_get_cell_id(&sync_find);
|
|
|
|
|
|
|
|
|
|
if (cell_id >= 0) {
|
|
|
|
|
// We found the same cell as before, look another N_id_2
|
|
|
|
|
if ((uint32_t) cell_id == found_cell.id) {
|
|
|
|
|
sync_res = SRSLTE_SYNC_NOFOUND;
|
|
|
|
|
} else {
|
|
|
|
|
// We found a new cell ID
|
|
|
|
|
found_cell.id = cell_id;
|
|
|
|
|
found_cell.nof_ports = 1; // Use port 0 only for measurement
|
|
|
|
|
measure_p.set_cell(found_cell);
|
|
|
|
|
|
|
|
|
|
// Correct CFO
|
|
|
|
|
srslte_cfo_correct(&sync_find.cfo_corr_frame,
|
|
|
|
|
input_buffer,
|
|
|
|
|
input_cfo_corrected,
|
|
|
|
|
-srslte_sync_get_cfo(&sync_find)/sync_find.fft_size);
|
|
|
|
|
|
|
|
|
|
switch(measure_p.run_multiple_subframes(input_cfo_corrected, peak_idx, sf_idx, nof_sf)) {
|
|
|
|
|
case measure::MEASURE_OK:
|
|
|
|
|
cells[nof_cells].pci = found_cell.id;
|
|
|
|
|
cells[nof_cells].rsrp = measure_p.rsrp();
|
|
|
|
|
cells[nof_cells].rsrq = measure_p.rsrq();
|
|
|
|
|
cells[nof_cells].offset = measure_p.frame_st_idx();
|
|
|
|
|
nof_cells++;
|
|
|
|
|
|
|
|
|
|
// Substract interference from input buffer (for the next cell)
|
|
|
|
|
substract_sync(&input_buffer[measure_p.frame_st_idx()], cell.nof_prb, &sync_find);
|
|
|
|
|
|
|
|
|
|
Info("INTRA: Found neighbour cell: pci=%d, rsrp=%.1f dBm, peak_idx=%d, n_id_2=%d, cfo=%.1f Hz\n",
|
|
|
|
|
cell_id, measure_p.rsrq(), peak_idx, n_id_2, 15000*srslte_sync_get_cfo(&sync_find));
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case measure::ERROR:
|
|
|
|
|
Error("Measuring neighbour cell\n");
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
sync_res = SRSLTE_SYNC_NOFOUND;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_SYNC_FOUND_NOSPACE:
|
|
|
|
|
/* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SRSLTE_SYNC_FOUND_NOSPACE:
|
|
|
|
|
/* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} while(sync_res == SRSLTE_SYNC_FOUND);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nof_cells;
|
|
|
|
|