mirror of https://github.com/PentHertz/srsLTE.git
SRSENB: calculate TA from PUCCH messages
This commit is contained in:
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…
Reference in New Issue