diff --git a/lib/include/srslte/phy/ue/ue_ul.h b/lib/include/srslte/phy/ue/ue_ul.h index 98dae48b4..c6eb96a17 100644 --- a/lib/include/srslte/phy/ue/ue_ul.h +++ b/lib/include/srslte/phy/ue/ue_ul.h @@ -98,8 +98,10 @@ typedef struct SRSLTE_API { cf_t *refsignal; cf_t *srs_signal; - cf_t *sf_symbols; - + cf_t *sf_symbols; + + float last_amplitude; + uint16_t current_rnti; bool signals_pregenerated; }srslte_ue_ul_t; @@ -126,7 +128,9 @@ SRSLTE_API void srslte_ue_ul_set_cfo_enable(srslte_ue_ul_t *q, bool enabled); SRSLTE_API void srslte_ue_ul_set_normalization(srslte_ue_ul_t *q, - bool enabled); + bool enabled); + +SRSLTE_API float srslte_ue_ul_get_last_amplitude(srslte_ue_ul_t *q); SRSLTE_API void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg, diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index bf394944f..32629da3e 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -138,6 +138,7 @@ SRSLTE_API float srslte_vec_corr_ccc(const cf_t *x, cf_t *y, const uint32_t len) /* return the index of the maximum value in the vector */ SRSLTE_API uint32_t srslte_vec_max_fi(const float *x, const uint32_t len); +SRSLTE_API uint32_t srslte_vec_max_abs_fi(const float *x, const uint32_t len); SRSLTE_API uint32_t srslte_vec_max_abs_ci(const cf_t *x, const uint32_t len); /* quantify vector of floats or int16 and convert to uint8_t */ diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index e7c616643..dc19ac855 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -294,6 +294,25 @@ void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format } } +static float limit_norm_factor(srslte_ue_ul_t *q, float norm_factor, cf_t *output_signal) +{ + uint32_t p = srslte_vec_max_abs_fi((float*) output_signal, 2*SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); + float amp = fabsf(*((float*) output_signal + p)); + + if (amp*norm_factor > 0.95) { + norm_factor = 0.95/amp; + } + if (amp*norm_factor < 0.1) { + norm_factor = 0.1/amp; + } + q->last_amplitude = norm_factor*amp; + return norm_factor; +} + +float srslte_ue_ul_get_last_amplitude(srslte_ue_ul_t *q) { + return q->last_amplitude; +} + /* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal */ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, @@ -353,7 +372,10 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, } if (q->normalize_en) { - float norm_factor = (float) q->cell.nof_prb/15/10; + float norm_factor = (float) q->cell.nof_prb/15/40; + + norm_factor = limit_norm_factor(q, norm_factor, output_signal); + srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } ret = SRSLTE_SUCCESS; @@ -424,6 +446,9 @@ int srslte_ue_ul_srs_encode(srslte_ue_ul_t *q, uint32_t tti, cf_t *output_signal if (q->normalize_en) { float norm_factor = (float) q->cell.nof_prb/15/sqrtf(srslte_refsignal_srs_M_sc(&q->signals)); + + norm_factor = limit_norm_factor(q, norm_factor, output_signal); + srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } @@ -491,7 +516,10 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, } if (q->normalize_en) { - float norm_factor = (float) q->cell.nof_prb/15/sqrtf(q->pusch_cfg.grant.L_prb); + float norm_factor = (float) q->cell.nof_prb/15/sqrtf(q->pusch_cfg.grant.L_prb)/2; + + norm_factor = limit_norm_factor(q, norm_factor, output_signal); + srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 79e6f92b8..ff63b09ce 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -368,6 +368,10 @@ uint32_t srslte_vec_max_fi(const float *x, const uint32_t len) { return srslte_vec_max_fi_simd(x, len); } +uint32_t srslte_vec_max_abs_fi(const float *x, const uint32_t len) { + return srslte_vec_max_fi_simd(x, len); +} + // CP autocorr uint32_t srslte_vec_max_abs_ci(const cf_t *x, const uint32_t len) { return srslte_vec_max_ci_simd(x, len); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 43a31ba0e..f44f4f9a0 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1296,8 +1296,8 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui uint8_t dummy[2] = {0,0}; log_h->info_hex(payload, grant->mcs.tbs/8, - "PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s\n", - (tti + HARQ_DELAY_MS) % 10240, + "PUSCH: tti_tx=%d, amp=%.2f, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s\n", + (tti + HARQ_DELAY_MS) % 10240, srslte_ue_ul_get_last_amplitude(&ue_ul), grant->n_prb[0], grant->n_prb[0] + grant->L_prb, grant->mcs.tbs / 8, grant->mcs.idx, rv, uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? ", ack=1" : ", ack=0") : "", @@ -1350,8 +1350,8 @@ void phch_worker::encode_pucch() srslte_cqi_value_tostring(&cqi_report, cqi_str, SRSLTE_CQI_STR_MAX_CHAR); } - Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n", - (tti + 4) % 10240, + Info("PUCCH: tti_tx=%d, amp=%.2f, n_pucch=%d, n_prb=%d, ack=%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n", + (tti + 4) % 10240, srslte_ue_ul_get_last_amplitude(&ue_ul), ue_ul.pucch.last_n_pucch, ue_ul.pucch.last_n_prb, uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? "1" : "0") : "no", uci_data.uci_ack_len > 1 ? (uci_data.uci_ack_2 ? "1" : "0") : "", @@ -1384,7 +1384,8 @@ void phch_worker::encode_srs() float tx_power = srslte_ue_ul_srs_power(&ue_ul, phy->pathloss); float gain = set_power(tx_power); - Info("SRS: power=%.2f dBm, tti_tx=%d%s\n", tx_power, TTI_TX(tti), timestr); + + Info("SRS: power=%.2f dBm, amp=%.2f, tti_tx=%d%s\n", tx_power, srslte_ue_ul_get_last_amplitude(&ue_ul), TTI_TX(tti), timestr); } void phch_worker::enable_pregen_signals(bool enabled)