SRSENB: calculate TA from PUCCH messages

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent df2c949417
commit 3aec23f7d8

@ -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);

@ -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;

@ -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++) {

@ -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");

@ -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);
}
}
}

@ -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;

@ -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];

@ -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

Loading…
Cancel
Save