diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index e6ef981d1..667f0a93c 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -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; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 17ac71c54..95931e600 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -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= 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;