mirror of https://github.com/PentHertz/srsLTE.git
Improved initial CFO estimation for PRACH. Fixed bug in PDCCH after changing cell
This commit is contained in:
parent
f1bacd009a
commit
394d8f166a
|
@ -75,6 +75,8 @@ typedef struct SRSLTE_API {
|
|||
uint32_t frame_size;
|
||||
uint32_t max_offset;
|
||||
bool enable_cfo_corr;
|
||||
bool mean_cfo2_isunset;
|
||||
bool mean_cfo_isunset;
|
||||
float mean_cfo;
|
||||
float mean_cfo2;
|
||||
int cfo_i;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <complex.h>
|
||||
#include <math.h>
|
||||
#include <srslte/srslte.h>
|
||||
#include <srslte/phy/sync/sync.h>
|
||||
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
#include "srslte/phy/common/phy_common.h"
|
||||
|
@ -79,6 +80,8 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o
|
|||
q->max_offset = max_offset;
|
||||
q->sss_alg = SSS_FULL;
|
||||
q->max_frame_size = frame_size;
|
||||
q->mean_cfo_isunset = true;
|
||||
q->mean_cfo2_isunset = true;
|
||||
|
||||
q->enable_cfo_corr = true;
|
||||
if (srslte_cfo_init(&q->cfocorr, q->frame_size)) {
|
||||
|
@ -288,6 +291,9 @@ float srslte_sync_get_cfo(srslte_sync_t *q) {
|
|||
|
||||
void srslte_sync_set_cfo(srslte_sync_t *q, float cfo) {
|
||||
q->mean_cfo = cfo;
|
||||
q->mean_cfo2 = cfo;
|
||||
q->mean_cfo2_isunset = false;
|
||||
q->mean_cfo_isunset = false;
|
||||
}
|
||||
|
||||
void srslte_sync_set_cfo_i(srslte_sync_t *q, int cfo_i) {
|
||||
|
@ -517,8 +523,13 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t
|
|||
if (q->enable_cfo_corr) {
|
||||
float cfo = cfo_estimate(q, input);
|
||||
|
||||
if (q->mean_cfo_isunset) {
|
||||
q->mean_cfo = cfo;
|
||||
q->mean_cfo_isunset = false;
|
||||
} else {
|
||||
/* compute exponential moving average CFO */
|
||||
q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha);
|
||||
}
|
||||
|
||||
/* Correct CFO with the averaged CFO estimation */
|
||||
srslte_cfo_correct(&q->cfocorr2, input, q->temp, -q->mean_cfo / q->fft_size);
|
||||
|
@ -574,7 +585,12 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t
|
|||
|
||||
if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) {
|
||||
float cfo2 = srslte_pss_synch_cfo_compute(&q->pss, &input[find_offset + peak_pos - q->fft_size]);
|
||||
if (q->mean_cfo2_isunset) {
|
||||
q->mean_cfo2 = cfo2;
|
||||
q->mean_cfo2_isunset = true;
|
||||
} else {
|
||||
q->mean_cfo2 = SRSLTE_VEC_EMA(cfo2, q->mean_cfo2, q->cfo_ema_alpha);
|
||||
}
|
||||
|
||||
ret = SRSLTE_SYNC_FOUND;
|
||||
} else {
|
||||
|
@ -596,6 +612,8 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t
|
|||
}
|
||||
|
||||
void srslte_sync_reset(srslte_sync_t *q) {
|
||||
q->mean_cfo2_isunset = true;
|
||||
q->mean_cfo_isunset = true;
|
||||
q->M_ext_avg = 0;
|
||||
q->M_norm_avg = 0;
|
||||
srslte_pss_synch_reset(&q->pss);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "srslte/phy/ue/ue_dl.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <srslte/srslte.h>
|
||||
|
||||
|
||||
#define CURRENT_FFTSIZE srslte_symbol_sz(q->cell.nof_prb)
|
||||
|
@ -228,6 +229,7 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell)
|
|||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
q->current_rnti = 0;
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
} else {
|
||||
|
@ -242,6 +244,7 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell)
|
|||
* For the connection procedure, use srslte_pusch_encode_rnti() or srslte_pusch_decode_rnti() functions
|
||||
*/
|
||||
void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q, uint16_t rnti) {
|
||||
|
||||
srslte_pdsch_set_rnti(&q->pdsch, rnti);
|
||||
|
||||
// Compute UE-specific and Common search space for this RNTI
|
||||
|
|
|
@ -149,8 +149,6 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input,
|
|||
int ret = SRSLTE_SUCCESS;
|
||||
cf_t *ce_slot1[SRSLTE_MAX_PORTS];
|
||||
|
||||
|
||||
|
||||
/* Run FFT for the slot symbols */
|
||||
srslte_ofdm_rx_sf(&q->fft, input, q->sf_symbols);
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ private:
|
|||
uint32_t current_earfcn;
|
||||
|
||||
uint32_t sync_sfn_cnt;
|
||||
const static uint32_t SYNC_SFN_TIMEOUT = 100;
|
||||
const static uint32_t SYNC_SFN_TIMEOUT = 200;
|
||||
float ul_dl_factor;
|
||||
int cur_earfcn_index;
|
||||
bool cell_search_in_progress;
|
||||
|
|
|
@ -95,7 +95,7 @@ void phch_recv:: init(srslte::radio_multi *_radio_handler, mac_interface_phy *_
|
|||
|
||||
if (srslte_ue_cellsearch_init_multi(&cs, 5, radio_recv_wrapper_cs, nof_rx_antennas,
|
||||
radio_h)) {
|
||||
Error("Initiating UE cell search\n");
|
||||
Error("SYNC: Initiating UE cell search\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -109,22 +109,22 @@ void phch_recv:: init(srslte::radio_multi *_radio_handler, mac_interface_phy *_
|
|||
}
|
||||
|
||||
if (srslte_ue_dl_init(&ue_dl_measure, SRSLTE_MAX_PRB, nof_rx_antennas)) {
|
||||
Error("Initiating ue_dl_measure\n");
|
||||
Error("SYNC: Initiating ue_dl_measure\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (srslte_ue_mib_init(&ue_mib, SRSLTE_MAX_PRB)) {
|
||||
Error("Initiating UE MIB decoder\n");
|
||||
Error("SYNC: Initiating UE MIB decoder\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (srslte_ue_sync_init_multi(&ue_sync, SRSLTE_MAX_PRB, false, radio_recv_wrapper_cs, nof_rx_antennas, radio_h)) {
|
||||
Error("Initiating ue_sync\n");
|
||||
Error("SYNC: Initiating ue_sync\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (srslte_ue_mib_sync_init_multi(&ue_mib_sync, radio_recv_wrapper_cs, nof_rx_antennas, radio_h)) {
|
||||
Error("Initiating UE MIB synchronization\n");
|
||||
Error("SYNC: Initiating UE MIB synchronization\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) {
|
|||
} else if (!worker_com->args->sss_algorithm.compare("full")) {
|
||||
sss_alg = SSS_FULL;
|
||||
} else {
|
||||
Warning("Invalid SSS algorithm %s. Using 'full'\n", worker_com->args->sss_algorithm.c_str());
|
||||
Warning("SYNC: Invalid SSS algorithm %s. Using 'full'\n", worker_com->args->sss_algorithm.c_str());
|
||||
}
|
||||
srslte_sync_set_sss_algorithm(&q->strack, (sss_alg_t) sss_alg);
|
||||
srslte_sync_set_sss_algorithm(&q->sfind, (sss_alg_t) sss_alg);
|
||||
|
@ -195,11 +195,11 @@ void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) {
|
|||
bool phch_recv::set_cell() {
|
||||
cell_is_set = false;
|
||||
if (srslte_ue_mib_set_cell(&ue_mib, cell)) {
|
||||
Error("Setting cell: initiating ue_mib\n");
|
||||
Error("SYNC: Setting cell: initiating ue_mib\n");
|
||||
return false;
|
||||
}
|
||||
if (srslte_ue_sync_set_cell(&ue_sync, cell)) {
|
||||
Error("Setting cell: initiating ue_sync");
|
||||
Error("SYNC: Setting cell: initiating ue_sync");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ bool phch_recv::set_cell() {
|
|||
set_ue_sync_opts(&ue_sync);
|
||||
|
||||
if (srslte_ue_dl_set_cell(&ue_dl_measure, cell)) {
|
||||
Error("Setting cell: initiating ue_dl_measure\n");
|
||||
Error("SYNC: Setting cell: initiating ue_dl_measure\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ bool phch_recv::set_cell() {
|
|||
|
||||
for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) {
|
||||
if (!((phch_worker *) workers_pool->get_worker(i))->set_cell(cell)) {
|
||||
Error("Setting cell: initiating PHCH worker\n");
|
||||
Error("SYNC: Setting cell: initiating PHCH worker\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ bool phch_recv::cell_search(int force_N_id_2) {
|
|||
uint32_t max_peak_cell = 0;
|
||||
int ret = SRSLTE_ERROR;
|
||||
|
||||
Info("Searching for cell...\n");
|
||||
Info("SYNC: Searching for cell...\n");
|
||||
printf("."); fflush(stdout);
|
||||
|
||||
if (force_N_id_2 >= 0 && force_N_id_2 < 3) {
|
||||
|
@ -260,11 +260,11 @@ bool phch_recv::cell_search(int force_N_id_2) {
|
|||
|
||||
if (ret < 0) {
|
||||
radio_h->stop_rx();
|
||||
Error("Error decoding MIB: Error searching PSS\n");
|
||||
Error("SYNC: Error decoding MIB: Error searching PSS\n");
|
||||
return false;
|
||||
} else if (ret == 0) {
|
||||
radio_h->stop_rx();
|
||||
Info("Could not find any cell in this frequency\n");
|
||||
Info("SYNC: Could not find any cell in this frequency\n");
|
||||
return false;
|
||||
}
|
||||
// Save result
|
||||
|
@ -277,7 +277,7 @@ bool phch_recv::cell_search(int force_N_id_2) {
|
|||
cell.id, cellsearch_cfo/1000, srslte_cp_string(cell.cp));
|
||||
|
||||
if (srslte_ue_mib_sync_set_cell(&ue_mib_sync, cell.id, cell.cp)) {
|
||||
Error("Setting UE MIB cell\n");
|
||||
Error("SYNC: Setting UE MIB cell\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ bool phch_recv::cell_search(int force_N_id_2) {
|
|||
|
||||
return true;
|
||||
} else {
|
||||
Warning("Found PSS but could not decode PBCH\n");
|
||||
Warning("SYNC: Found PSS but could not decode PBCH\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -328,14 +328,15 @@ int phch_recv::cell_sync_sfn(void) {
|
|||
srslte_ue_sync_decode_sss_on_track(&ue_sync, true);
|
||||
ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
|
||||
if (ret < 0) {
|
||||
Error("Error calling ue_sync_get_buffer");
|
||||
Error("SYNC: Error calling ue_sync_get_buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
|
||||
int sfn_offset = 0;
|
||||
Info("SYNC: Trying to decode MIB...\n");
|
||||
Info("SYNC: Trying to decode MIB... SNR=%.1f dB\n",
|
||||
10*log10(srslte_chest_dl_get_snr(&ue_mib.chest)));
|
||||
int n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset);
|
||||
if (n < 0) {
|
||||
Error("SYNC: Error decoding MIB while synchronising SFN");
|
||||
|
@ -375,10 +376,11 @@ int phch_recv::cell_meas_rsrp() {
|
|||
return -1;
|
||||
}
|
||||
float rsrp = srslte_chest_dl_get_rsrp(&ue_dl_measure.chest);
|
||||
float snr = srslte_chest_dl_get_snr(&ue_dl_measure.chest);
|
||||
measure_rsrp = SRSLTE_VEC_CMA(rsrp, measure_rsrp, measure_cnt);
|
||||
measure_cnt++;
|
||||
log_h->info("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm\n",
|
||||
measure_cnt, RSRP_MEASURE_NOF_FRAMES, sf_idx, 10 * log10(rsrp / 1000));
|
||||
log_h->info("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, SNR=%.1f dB\n",
|
||||
measure_cnt, RSRP_MEASURE_NOF_FRAMES, sf_idx, 10 * log10(rsrp / 1000), 10*log10(snr));
|
||||
if (measure_cnt >= RSRP_MEASURE_NOF_FRAMES) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -433,7 +435,7 @@ void phch_recv::cell_search_next() {
|
|||
if (cell_search_in_progress) {
|
||||
cell_search_in_progress = false;
|
||||
if (!stop_sync()) {
|
||||
log_h->warning("Couldn't stop sync\n");
|
||||
log_h->warning("SYNC: Couldn't stop PHY\n");
|
||||
}
|
||||
cell_search_inc();
|
||||
phy_state = CELL_SEARCH;
|
||||
|
@ -446,9 +448,9 @@ void phch_recv::cell_search_start() {
|
|||
cell_search_in_progress = true;
|
||||
cur_earfcn_index = -1;
|
||||
cell_search_next();
|
||||
log_h->info("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size());
|
||||
log_h->info("SYNC: Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size());
|
||||
} else {
|
||||
log_h->info("Empty EARFCN list. Stopping cell search...\n");
|
||||
log_h->info("SYNC: Empty EARFCN list. Stopping cell search...\n");
|
||||
log_h->console("Empty EARFCN list. Stopping cell search...\n");
|
||||
}
|
||||
}
|
||||
|
@ -500,7 +502,7 @@ bool phch_recv::set_frequency()
|
|||
float dl_freq = 1e6*srslte_band_fd(current_earfcn);
|
||||
float ul_freq = 1e6*srslte_band_fu(srslte_band_ul_earfcn(current_earfcn));
|
||||
if (dl_freq > 0 && ul_freq > 0) {
|
||||
log_h->info("Set DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz\n",
|
||||
log_h->info("SYNC: Set DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz\n",
|
||||
current_earfcn, dl_freq / 1e6, ul_freq / 1e6);
|
||||
|
||||
log_h->console("Searching cell in DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz\n",
|
||||
|
@ -514,7 +516,7 @@ bool phch_recv::set_frequency()
|
|||
|
||||
return true;
|
||||
} else {
|
||||
log_h->error("Cell Search: Invalid EARFCN=%d\n", current_earfcn);
|
||||
log_h->error("SYNC: Cell Search: Invalid EARFCN=%d\n", current_earfcn);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -523,7 +525,7 @@ void phch_recv::set_sampling_rate()
|
|||
{
|
||||
float srate = (float) srslte_sampling_freq_hz(cell.nof_prb);
|
||||
|
||||
Info("Setting sampling rate %.1f MHz\n", srate/1000000);
|
||||
Info("SYNC: Setting sampling rate %.2f MHz\n", srate/1000000);
|
||||
|
||||
if (30720 % ((int) srate / 1000) == 0) {
|
||||
radio_h->set_master_clock_rate(30.72e6);
|
||||
|
@ -545,13 +547,13 @@ void phch_recv::run_thread() {
|
|||
while (running) {
|
||||
if (phy_state != IDLE) {
|
||||
is_in_idle = false;
|
||||
Debug("SYNC state=%d\n", phy_state);
|
||||
Debug("SYNC: state=%d\n", phy_state);
|
||||
}
|
||||
switch (phy_state) {
|
||||
case CELL_SEARCH:
|
||||
if (cell_search() && cell_search_in_progress) {
|
||||
if (!srslte_cell_isvalid(&cell)) {
|
||||
Error("Detected invalid cell\n");
|
||||
Error("SYNC: Detected invalid cell\n");
|
||||
phy_state = IDLE;
|
||||
break;
|
||||
}
|
||||
|
@ -572,7 +574,7 @@ void phch_recv::run_thread() {
|
|||
|
||||
switch (cell_sync_sfn()) {
|
||||
default:
|
||||
log_h->console("Going IDLE\n");
|
||||
log_h->console("SYNC: Going IDLE\n");
|
||||
phy_state = IDLE;
|
||||
break;
|
||||
case 1:
|
||||
|
@ -592,14 +594,14 @@ void phch_recv::run_thread() {
|
|||
sync_sfn_cnt++;
|
||||
if (sync_sfn_cnt >= SYNC_SFN_TIMEOUT) {
|
||||
sync_sfn_cnt = 0;
|
||||
phy_state = IDLE;
|
||||
log_h->warning("Timeout while synchronizing SFN\n");
|
||||
phy_state = CELL_SEARCH;
|
||||
log_h->warning("SYNC: Timeout while synchronizing SFN\n");
|
||||
}
|
||||
break;
|
||||
case CELL_MEASURE:
|
||||
switch(cell_meas_rsrp()) {
|
||||
case 1:
|
||||
log_h->info("Measured OK. Camping on cell PCI=%d...\n", cell.id);
|
||||
log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id);
|
||||
phy_state = CELL_CAMP;
|
||||
rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000));
|
||||
break;
|
||||
|
@ -623,7 +625,7 @@ void phch_recv::run_thread() {
|
|||
|
||||
log_h->step(tti);
|
||||
|
||||
Debug("Worker %d synchronized\n", worker->get_id());
|
||||
Debug("SYNC: Worker %d synchronized\n", worker->get_id());
|
||||
|
||||
metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync);
|
||||
metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync);
|
||||
|
@ -640,7 +642,7 @@ void phch_recv::run_thread() {
|
|||
srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec);
|
||||
worker->set_tx_time(tx_time);
|
||||
|
||||
Debug("Setting TTI=%d, tx_mutex=%d to worker %d\n", tti, tx_mutex_cnt, worker->get_id());
|
||||
Debug("SYNC: Setting TTI=%d, tx_mutex=%d to worker %d\n", tti, tx_mutex_cnt, worker->get_id());
|
||||
worker->set_tti(tti, tx_mutex_cnt);
|
||||
tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex;
|
||||
|
||||
|
@ -657,10 +659,10 @@ void phch_recv::run_thread() {
|
|||
// Notify RRC in-sync every 1 frame
|
||||
if ((tti % 10) == 0) {
|
||||
rrc->in_sync();
|
||||
log_h->debug("Sending in-sync to RRC\n");
|
||||
log_h->debug("SYNC: Sending in-sync to RRC\n");
|
||||
}
|
||||
} else {
|
||||
log_h->error("Sync error. Sending out-of-sync to RRC\n");
|
||||
log_h->error("SYNC: Sync error. Sending out-of-sync to RRC\n");
|
||||
// Notify RRC of out-of-sync frame
|
||||
rrc->out_of_sync();
|
||||
worker->release();
|
||||
|
|
|
@ -405,7 +405,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant)
|
|||
srslte_dci_msg_t dci_msg;
|
||||
srslte_ra_dl_dci_t dci_unpacked;
|
||||
|
||||
Debug("Looking for RNTI=0x%x\n", dl_rnti);
|
||||
Info("Looking for RNTI=0x%x\n", dl_rnti);
|
||||
|
||||
if (srslte_ue_dl_find_dl_dci_type(&ue_dl, phy->config->dedicated.antenna_info_explicit_value.tx_mode, cfi, tti%10,
|
||||
dl_rnti, type, &dci_msg) != 1) {
|
||||
|
@ -681,7 +681,7 @@ void phch_worker::reset_uci()
|
|||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
}
|
||||
|
||||
void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], uint32_t nof_tb) {
|
||||
void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], uint32_t nof_tb) {
|
||||
if (nof_tb > 0) {
|
||||
uci_data.uci_ack = (uint8_t) ((ack[0]) ? 1 : 0);
|
||||
}
|
||||
|
@ -696,7 +696,7 @@ void phch_worker::reset_uci()
|
|||
|
||||
uci_data.uci_ack_len = nof_tb;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void phch_worker::set_uci_sr()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue