Added option for Doppler frequency correction

master
Ismael Gomez 7 years ago
parent c0aea5ae13
commit f9d770e50e

@ -475,6 +475,7 @@ typedef struct {
int cqi_fixed; int cqi_fixed;
float snr_ema_coeff; float snr_ema_coeff;
std::string snr_estim_alg; std::string snr_estim_alg;
bool cfo_is_doppler;
bool cfo_integer_enabled; bool cfo_integer_enabled;
float cfo_correct_tol_hz; float cfo_correct_tol_hz;
float cfo_pss_ema; float cfo_pss_ema;

@ -104,6 +104,8 @@ private:
void cell_search_inc(); void cell_search_inc();
void cell_reselect(); void cell_reselect();
float get_cfo();
uint32_t new_earfcn; uint32_t new_earfcn;
srslte_cell_t new_cell; srslte_cell_t new_cell;

@ -73,7 +73,6 @@ public:
float get_rsrp(); float get_rsrp();
float get_noise(); float get_noise();
float get_cfo(); float get_cfo();
float get_ul_cfo();
private: private:
/* Inherited from thread_pool::worker. Function called every subframe to run the DL/UL processing */ /* Inherited from thread_pool::worker. Function called every subframe to run the DL/UL processing */

@ -203,6 +203,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
bpo::value<string>(&args->expert.phy.equalizer_mode)->default_value("mmse"), bpo::value<string>(&args->expert.phy.equalizer_mode)->default_value("mmse"),
"Equalizer mode") "Equalizer mode")
("expert.cfo_is_doppler",
bpo::value<bool>(&args->expert.phy.cfo_is_doppler)->default_value(false),
"Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed"
"to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator.")
("expert.cfo_integer_enabled", ("expert.cfo_integer_enabled",
bpo::value<bool>(&args->expert.phy.cfo_integer_enabled)->default_value(false), bpo::value<bool>(&args->expert.phy.cfo_integer_enabled)->default_value(false),
"Enables integer CFO estimation and correction.") "Enables integer CFO estimation and correction.")
@ -215,12 +220,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
bpo::value<float>(&args->expert.phy.cfo_pss_ema)->default_value(DEFAULT_CFO_EMA_TRACK), bpo::value<float>(&args->expert.phy.cfo_pss_ema)->default_value(DEFAULT_CFO_EMA_TRACK),
"CFO Exponential Moving Average coefficient for PSS estimation during TRACK.") "CFO Exponential Moving Average coefficient for PSS estimation during TRACK.")
/* REF EMA is currently not used
("expert.cfo_ref_ema",
bpo::value<float>(&args->expert.phy.cfo_ref_ema)->default_value(0.01),
"CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition")
*/
("expert.cfo_ref_mask", ("expert.cfo_ref_mask",
bpo::value<uint32_t>(&args->expert.phy.cfo_ref_mask)->default_value(1023), bpo::value<uint32_t>(&args->expert.phy.cfo_ref_mask)->default_value(1023),
"Bitmask for subframes on which to run RS estimation (set to 0 to disable, default all sf)") "Bitmask for subframes on which to run RS estimation (set to 0 to disable, default all sf)")

@ -428,6 +428,25 @@ bool phch_recv::set_frequency()
} }
} }
float phch_recv::get_cfo()
{
float cfo = srslte_ue_sync_get_cfo(&ue_sync);
float ret = cfo*ul_dl_factor;
if (worker_com->args->cfo_is_doppler) {
ret *= -1;
}
if (radio_h->get_freq_offset() != 0.0f) {
/* Compensates the radio frequency offset applied equally to DL and UL */
const float offset_hz = (float) radio_h->get_freq_offset() * (1.0f - ul_dl_factor);
ret = cfo - offset_hz;
}
return ret/15000;
}
void phch_recv::set_sampling_rate() void phch_recv::set_sampling_rate()
{ {
current_srate = (float) srslte_sampling_freq_hz(cell.nof_prb); current_srate = (float) srslte_sampling_freq_hz(cell.nof_prb);
@ -633,7 +652,7 @@ void phch_recv::run_thread()
metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync);
metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync);
worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); worker->set_cfo(get_cfo());
worker_com->set_sync_metrics(metrics); worker_com->set_sync_metrics(metrics);
/* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */
@ -659,7 +678,7 @@ void phch_recv::run_thread()
if (prach_buffer->is_ready_to_send(tti)) { if (prach_buffer->is_ready_to_send(tti)) {
srslte_timestamp_copy(&tx_time_prach, &rx_time); srslte_timestamp_copy(&tx_time_prach, &rx_time);
srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3); srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3);
prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach); prach_buffer->send(radio_h, get_cfo(), worker_com->pathloss, tx_time_prach);
radio_h->tx_end(); radio_h->tx_end();
worker_com->p0_preamble = prach_buffer->get_p0_preamble(); worker_com->p0_preamble = prach_buffer->get_p0_preamble();
worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble); worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble);

@ -223,20 +223,6 @@ float phch_worker::get_cfo()
return cfo; return cfo;
} }
float phch_worker::get_ul_cfo() {
srslte::radio *radio = phy->get_radio();
if (radio->get_freq_offset() != 0.0f) {
/* Compensates the radio frequency offset applied equally to DL and UL */
const float ul_dl_ratio = (float) radio->get_tx_freq() / (float) radio->get_rx_freq();
const float offset_hz = (float) radio->get_freq_offset() * (1.0f - ul_dl_ratio);
return cfo - offset_hz / (15000);
} else {
return cfo;
}
}
void phch_worker::work_imp() void phch_worker::work_imp()
{ {
if (!cell_initiated) { if (!cell_initiated) {
@ -360,7 +346,7 @@ void phch_worker::work_imp()
} }
/* Set UL CFO before transmission */ /* Set UL CFO before transmission */
srslte_ue_ul_set_cfo(&ue_ul, get_ul_cfo()); srslte_ue_ul_set_cfo(&ue_ul, cfo);
/* Transmit PUSCH, PUCCH or SRS */ /* Transmit PUSCH, PUCCH or SRS */
bool signal_ready = false; bool signal_ready = false;

@ -172,6 +172,8 @@ enable = false
# cfo_correct_tol_hz: Tolerance (in Hz) for digial CFO compensation. Lower tolerance means that # cfo_correct_tol_hz: Tolerance (in Hz) for digial CFO compensation. Lower tolerance means that
# a new table will be generated more often. # a new table will be generated more often.
# #
# cfo_is_doppler: Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed
# to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator.
# cfo_pss_ema: CFO Exponential Moving Average coefficient for PSS estimation during TRACK. # cfo_pss_ema: CFO Exponential Moving Average coefficient for PSS estimation during TRACK.
# cfo_ref_ema: CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition # cfo_ref_ema: CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition
# cfo_ref_mask: Bitmask for subframes on which to run RS estimation (set to 0 to disable, default sf=[1, 5]) # cfo_ref_mask: Bitmask for subframes on which to run RS estimation (set to 0 to disable, default sf=[1, 5])
@ -211,6 +213,7 @@ enable = false
#pdsch_csi_enabled = true # Caution! Only TM1 supported! #pdsch_csi_enabled = true # Caution! Only TM1 supported!
# CFO related values # CFO related values
#cfo_is_doppler = false
#cfo_integer_enabled = false #cfo_integer_enabled = false
#cfo_correct_tol_hz = 1.0 #cfo_correct_tol_hz = 1.0
#cfo_pss_ema = 0.05 #cfo_pss_ema = 0.05

Loading…
Cancel
Save