Look for multiple cells on each n_id_2 while cancelling the self interference

This commit is contained in:
Ismael Gomez 2017-12-02 12:02:01 +01:00
parent 8f39a622fe
commit f3b1bc0e2d
2 changed files with 94 additions and 71 deletions

View File

@ -102,6 +102,8 @@ private:
bool set_frequency();
bool set_cell();
static void substract_sync(cf_t *buffer, uint32_t nof_prb, srslte_sync_t *sync_obj);
void cell_search_inc();
void resync_sfn(bool is_connected = false, bool rx_now = false);
bool stop_sync();
@ -175,6 +177,7 @@ private:
float rsrp();
float rsrq();
float snr();
uint32_t frame_st_idx();
void set_rx_gain_offset(float rx_gain_offset);
private:
srslte::log *log_h;
@ -185,6 +188,7 @@ private:
uint32_t current_prb;
float rx_gain_offset;
float mean_rsrp, mean_rsrq, mean_snr;
uint32_t final_offset;
const static int RSRP_MEASURE_NOF_FRAMES = 5;
};
@ -205,6 +209,7 @@ private:
const static int DEFAULT_MEASUREMENT_LEN = 10;
cf_t *input_cfo_corrected;
cf_t *sf_buffer[SRSLTE_MAX_PORTS];
srslte::log *log_h;
srslte_sync_t sync_find;

View File

@ -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);
srslte_sync_find_ret_t sync_res;
do {
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);
srslte_sync_reset(&sync_find);
srslte_sync_cfo_reset(&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);
sync_res = srslte_sync_find(&sync_find, input_buffer, 0, &peak_idx);
/*
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);
}*/
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);
found_cell.id = cell_id;
found_cell.nof_ports = 1; // Use port 0 only for measurement
measure_p.set_cell(found_cell);
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);
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;
// 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;