diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index ca6221133..186a4bdf0 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -734,6 +734,7 @@ typedef struct { uint32_t intra_freq_meas_len_ms; uint32_t intra_freq_meas_period_ms; bool pregenerate_signals; + float force_ul_amplitude; srslte::channel::args_t dl_channel_args; srslte::channel::args_t ul_channel_args; diff --git a/lib/include/srslte/phy/ue/ue_ul.h b/lib/include/srslte/phy/ue/ue_ul.h index a1611d9e4..7b392a7dd 100644 --- a/lib/include/srslte/phy/ue/ue_ul.h +++ b/lib/include/srslte/phy/ue/ue_ul.h @@ -80,6 +80,7 @@ typedef struct SRSLTE_API { uint32_t cc_idx; bool normalize_en; + float force_peak_amplitude; bool cfo_en; float cfo_tol; float cfo_value; diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index 544700d4e..bcabe30b6 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -248,9 +248,26 @@ static void apply_cfo(srslte_ue_ul_t* q, srslte_ue_ul_cfg_t* cfg) static void apply_norm(srslte_ue_ul_t* q, srslte_ue_ul_cfg_t* cfg, float norm_factor) { + uint32_t sf_len = SRSLTE_SF_LEN_PRB(q->cell.nof_prb); + if (cfg->normalize_en) { norm_factor = limit_norm_factor(q, norm_factor, q->out_buffer); - srslte_vec_sc_prod_cfc(q->out_buffer, norm_factor, q->out_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); + srslte_vec_sc_prod_cfc(q->out_buffer, norm_factor, q->out_buffer, sf_len); + } else if (cfg->force_peak_amplitude > 0.0f) { + // Typecast buffer + float* buf = (float*)q->out_buffer; + + // Get index of maximum absolute sample + uint32_t idx = srslte_vec_max_abs_fi(buf, sf_len * 2); + + // Get maximum value + float scale = fabsf(buf[idx]); + + // Avoid zero division + if (scale != 0.0f && scale != INFINITY) { + // Apply maximum peak amplitude + srslte_vec_sc_prod_cfc(q->out_buffer, cfg->force_peak_amplitude / scale, q->out_buffer, sf_len); + } } } diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 4e96fa6e0..93a915054 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -325,7 +325,11 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("expert.pdsch_8bit_decoder", bpo::value(&args->phy.pdsch_8bit_decoder)->default_value(false), - "Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental)"); + "Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental)") + + ("expert.force_ul_amplitude", + bpo::value(&args->phy.force_ul_amplitude)->default_value(0.0), + "Forces the peak amplitude in the PUCCH, PUSCH and SRS (set 0.0 to 1.0, set to 0 or negative for disabling)"); // Positional options - config file location bpo::options_description position("Positional options"); diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index b5f8ffc22..6263206a1 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -178,7 +178,12 @@ void phy_common::set_ue_ul_cfg(srslte_ue_ul_cfg_t* ue_ul_cfg) // Setup uplink configuration bzero(ue_ul_cfg, sizeof(srslte_ue_ul_cfg_t)); ue_ul_cfg->cfo_en = true; - ue_ul_cfg->normalize_en = true; + if (args->force_ul_amplitude > 0.0f) { + ue_ul_cfg->force_peak_amplitude = args->force_ul_amplitude; + ue_ul_cfg->normalize_en = false; + } else { + ue_ul_cfg->normalize_en = true; + } ue_ul_cfg->ul_cfg.pucch.ack_nack_feedback_mode = SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_NORMAL; } diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 8bab35586..182a7ec2b 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -285,6 +285,7 @@ enable = false # used in TM1. It is True by default. # # pdsch_8bit_decoder: Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental) +# force_ul_amplitude: Forces the peak amplitude in the PUCCH, PUSCH and SRS (set 0.0 to 1.0, set to 0 or negative for disabling) # ##################################################################### [expert] @@ -312,6 +313,7 @@ enable = false #metrics_csv_filename = /tmp/ue_metrics.csv #pdsch_csi_enabled = true #pdsch_8bit_decoder = false +#force_ul_amplitude = 0 # CFO related values #cfo_is_doppler = false