diff --git a/lib/include/srslte/phy/ch_estimation/chest_ul.h b/lib/include/srslte/phy/ch_estimation/chest_ul.h index b40c34014..04688c250 100644 --- a/lib/include/srslte/phy/ch_estimation/chest_ul.h +++ b/lib/include/srslte/phy/ch_estimation/chest_ul.h @@ -47,7 +47,7 @@ typedef struct SRSLTE_API { float epre_dBfs; float snr; float snr_db; - float cfo; + float cfo_hz; float ta_us; } srslte_chest_ul_res_t; diff --git a/lib/src/phy/ch_estimation/chest_ul.c b/lib/src/phy/ch_estimation/chest_ul.c index bdd8aa654..e7fe3fcb2 100644 --- a/lib/src/phy/ch_estimation/chest_ul.c +++ b/lib/src/phy/ch_estimation/chest_ul.c @@ -288,6 +288,15 @@ static void chest_ul_estimate(srslte_chest_ul_t* q, uint32_t n_prb[SRSLTE_NOF_SLOTS_PER_SF], srslte_chest_ul_res_t* res) { + // Calculate CFO + if (nslots == 2) { + float phase = cargf(srslte_vec_dot_prod_conj_ccc( + &q->pilot_estimates[0 * nrefs_sym], &q->pilot_estimates[1 * nrefs_sym], nrefs_sym)); + res->cfo_hz = phase / (2.0f * (float)M_PI * 0.0005f); + } else { + res->cfo_hz = NAN; + } + // Calculate time alignment error float ta_err = 0.0f; if (meas_ta_en) { diff --git a/lib/src/phy/ch_estimation/dmrs_pucch.c b/lib/src/phy/ch_estimation/dmrs_pucch.c index 51d2aa77d..b53bee7a1 100644 --- a/lib/src/phy/ch_estimation/dmrs_pucch.c +++ b/lib/src/phy/ch_estimation/dmrs_pucch.c @@ -256,7 +256,7 @@ int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, } // Measure CFO - res->cfo = NAN; // Not implemented + res->cfo_hz = NAN; // Not implemented // Do averaging here // ... Not implemented diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index cfa11b3dd..8c142333a 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -515,6 +515,11 @@ uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg, len = srslte_print_check(str, str_len, len, ", ta=%.1f us", chest_res->ta_us); } + // Append CFO information if available + if (!isnan(chest_res->cfo_hz)) { + len = srslte_print_check(str, str_len, len, ", cfo=%.1f hz", chest_res->cfo_hz); + } + // Append EVM measurement if available if (cfg->meas_evm_en) { len = srslte_print_check(str, str_len, len, ", evm=%.1f %%", res->evm * 100);