From 3aec23f7d8d0194ad45e677de0bd54780aab5003 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 29 Jul 2020 13:17:47 +0200 Subject: [PATCH] SRSENB: calculate TA from PUCCH messages --- lib/include/srslte/phy/phch/pucch.h | 4 ++++ lib/include/srslte/phy/phch/pucch_cfg.h | 1 + lib/src/phy/ch_estimation/chest_ul.c | 20 ++++++++++++++++++++ lib/src/phy/enb/enb_ul.c | 15 +++++++++++---- lib/src/phy/phch/pucch.c | 6 +++++- srsenb/hdr/phy/phy_interfaces.h | 1 + srsenb/src/phy/cc_worker.cc | 13 +++++++------ srsenb/src/phy/phy_ue_db.cc | 1 + 8 files changed, 50 insertions(+), 11 deletions(-) diff --git a/lib/include/srslte/phy/phch/pucch.h b/lib/include/srslte/phy/phch/pucch.h index fee99404f..9ffde001f 100644 --- a/lib/include/srslte/phy/phch/pucch.h +++ b/lib/include/srslte/phy/phch/pucch.h @@ -94,6 +94,10 @@ typedef struct SRSLTE_API { float dmrs_correlation; float correlation; bool detected; + + // PUCCH Measurements + bool ta_valid; + float ta_us; } srslte_pucch_res_t; SRSLTE_API int srslte_pucch_init_ue(srslte_pucch_t* q); diff --git a/lib/include/srslte/phy/phch/pucch_cfg.h b/lib/include/srslte/phy/phch/pucch_cfg.h index dd7e8b110..c1f3d32e8 100644 --- a/lib/include/srslte/phy/phch/pucch_cfg.h +++ b/lib/include/srslte/phy/phch/pucch_cfg.h @@ -77,6 +77,7 @@ typedef struct SRSLTE_API { float threshold_data_valid_format2; float threshold_data_valid_format3; float threshold_dmrs_detection; + bool meas_ta_en; // PUCCH configuration generated during a call to encode/decode srslte_pucch_format_t format; diff --git a/lib/src/phy/ch_estimation/chest_ul.c b/lib/src/phy/ch_estimation/chest_ul.c index 2995e2437..12334f7fb 100644 --- a/lib/src/phy/ch_estimation/chest_ul.c +++ b/lib/src/phy/ch_estimation/chest_ul.c @@ -455,6 +455,26 @@ int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t* q, srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->pilot_known_signal, q->pilot_estimates, nrefs_sf); } + if (cfg->meas_ta_en && n_rs > 0) { + float ta_err = 0.0; + for (int ns = 0; ns < SRSLTE_NOF_SLOTS_PER_SF; ns++) { + for (int i = 0; i < n_rs; i++) { + ta_err += srslte_vec_estimate_frequency(&q->pilot_estimates[(i + ns * n_rs) * SRSLTE_NRE], SRSLTE_NRE) / + (float)(SRSLTE_NOF_SLOTS_PER_SF * n_rs); + } + } + + // Calculate actual time alignment error in micro-seconds + if (isnormal(ta_err)) { + ta_err /= 15e3f; // Convert from normalized frequency to seconds + ta_err *= 1e6f; // Convert to micro-seconds + ta_err = roundf(ta_err * 10.0f) / 10.0f; // Round to one tenth of micro-second + res->ta_us = ta_err; + } else { + res->ta_us = 0.0f; + } + } + if (res->ce != NULL) { /* TODO: Currently averaging entire slot, performance good enough? */ for (int ns = 0; ns < 2; ns++) { diff --git a/lib/src/phy/enb/enb_ul.c b/lib/src/phy/enb/enb_ul.c index 2990e128a..27d8ca10c 100644 --- a/lib/src/phy/enb/enb_ul.c +++ b/lib/src/phy/enb/enb_ul.c @@ -175,10 +175,9 @@ void srslte_enb_ul_fft(srslte_enb_ul_t* q) static int get_pucch(srslte_enb_ul_t* q, srslte_ul_sf_cfg_t* ul_sf, srslte_pucch_cfg_t* cfg, srslte_pucch_res_t* res) { - int ret = SRSLTE_SUCCESS; - uint32_t n_pucch_i[SRSLTE_PUCCH_MAX_ALLOC] = {}; - srslte_pucch_res_t pucch_res = {}; - uint32_t uci_cfg_total_ack = srslte_uci_cfg_total_ack(&cfg->uci_cfg); + int ret = SRSLTE_SUCCESS; + uint32_t n_pucch_i[SRSLTE_PUCCH_MAX_ALLOC] = {}; + uint32_t uci_cfg_total_ack = srslte_uci_cfg_total_ack(&cfg->uci_cfg); // Drop CQI if there is collision with ACK if (!cfg->simul_cqi_ack && uci_cfg_total_ack > 0 && cfg->uci_cfg.cqi.data_enable) { @@ -204,6 +203,8 @@ static int get_pucch(srslte_enb_ul_t* q, srslte_ul_sf_cfg_t* ul_sf, srslte_pucch // Iterate possible resources and select the one with higher correlation for (int i = 0; i < nof_resources && ret == SRSLTE_SUCCESS; i++) { + srslte_pucch_res_t pucch_res = {}; + // Configure resource cfg->n_pucch = n_pucch_i[i]; @@ -213,6 +214,12 @@ static int get_pucch(srslte_enb_ul_t* q, srslte_ul_sf_cfg_t* ul_sf, srslte_pucch return SRSLTE_ERROR; } + // Copy measurements + if (cfg->meas_ta_en) { + pucch_res.ta_valid = !(isnan(q->chest_res.ta_us) || isinf(q->chest_res.ta_us)); + pucch_res.ta_us = q->chest_res.ta_us; + } + ret = srslte_pucch_decode(&q->pucch, ul_sf, cfg, &q->chest_res, q->sf_symbols, &pucch_res); if (ret < SRSLTE_SUCCESS) { ERROR("Error decoding PUCCH\n"); diff --git a/lib/src/phy/phch/pucch.c b/lib/src/phy/phch/pucch.c index 313a746dc..7431d63df 100644 --- a/lib/src/phy/phch/pucch.c +++ b/lib/src/phy/phch/pucch.c @@ -1394,6 +1394,10 @@ void srslte_pucch_rx_info(srslte_pucch_cfg_t* cfg, srslte_pucch_res_t* pucch_res n = srslte_print_check(str, str_len, n, ", corr=%.3f", pucch_res->correlation); - srslte_uci_data_info(&cfg->uci_cfg, &pucch_res->uci_data, &str[n], str_len - n); + n += srslte_uci_data_info(&cfg->uci_cfg, &pucch_res->uci_data, &str[n], str_len - n); + + if (pucch_res->ta_valid) { + n = srslte_print_check(str, str_len, n, ", ta=%.1f us", pucch_res->ta_us); + } } } diff --git a/srsenb/hdr/phy/phy_interfaces.h b/srsenb/hdr/phy/phy_interfaces.h index afc484524..7ff1dfa7f 100644 --- a/srsenb/hdr/phy/phy_interfaces.h +++ b/srsenb/hdr/phy/phy_interfaces.h @@ -57,6 +57,7 @@ struct phy_args_t { bool pusch_meas_epre = true; bool pusch_meas_evm = false; bool pusch_meas_ta = true; + bool pucch_meas_ta = true; srslte::channel::args_t dl_channel_args; srslte::channel::args_t ul_channel_args; diff --git a/srsenb/src/phy/cc_worker.cc b/srsenb/src/phy/cc_worker.cc index 3d097a952..ebd694e0d 100644 --- a/srsenb/src/phy/cc_worker.cc +++ b/srsenb/src/phy/cc_worker.cc @@ -332,12 +332,9 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ // Notify MAC UL channel quality phy->stack->snr_info(ul_sf.tti, rnti, cc_idx, snr_db); - if (ul_grant.dci.tb.rv == 0) { - // Notify MAC of Time Alignment only if it enabled and valid measurement, ignore value otherwise - if (ul_cfg.pusch.meas_ta_en and not std::isnan(enb_ul.chest_res.ta_us) and - not std::isinf(enb_ul.chest_res.ta_us)) { - phy->stack->ta_info(ul_sf.tti, rnti, enb_ul.chest_res.ta_us); - } + // Notify MAC of Time Alignment only if it enabled and valid measurement, ignore value otherwise + if (ul_cfg.pusch.meas_ta_en and not std::isnan(enb_ul.chest_res.ta_us) and not std::isinf(enb_ul.chest_res.ta_us)) { + phy->stack->ta_info(ul_sf.tti, rnti, enb_ul.chest_res.ta_us); } } @@ -404,6 +401,10 @@ int cc_worker::decode_pucch() // Send UCI data to MAC phy->ue_db.send_uci_data(tti_rx, rnti, cc_idx, ul_cfg.pucch.uci_cfg, pucch_res.uci_data); + if (pucch_res.detected and pucch_res.ta_valid) { + phy->stack->ta_info(tti_rx, rnti, pucch_res.ta_us); + } + // Logging if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { char str[512]; diff --git a/srsenb/src/phy/phy_ue_db.cc b/srsenb/src/phy/phy_ue_db.cc index 55bd797df..d34bc6866 100644 --- a/srsenb/src/phy/phy_ue_db.cc +++ b/srsenb/src/phy/phy_ue_db.cc @@ -103,6 +103,7 @@ inline void phy_ue_db::_set_common_config_rnti(uint16_t rnti, srslte::phy_cfg_t& phy_cfg.ul_cfg.pucch.threshold_data_valid_format2 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT2; phy_cfg.ul_cfg.pucch.threshold_data_valid_format3 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT3; phy_cfg.ul_cfg.pucch.threshold_dmrs_detection = SRSLTE_PUCCH_DEFAULT_THRESHOLD_DMRS; + phy_cfg.ul_cfg.pucch.meas_ta_en = phy_args->pucch_meas_ta; } inline uint32_t phy_ue_db::_get_ue_cc_idx(uint16_t rnti, uint32_t enb_cc_idx) const