|
|
@ -112,6 +112,7 @@ public:
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
ch_snr.acc_tpc_values = 0;
|
|
|
|
ch_snr.acc_tpc_values = 0;
|
|
|
|
ch_snr.snr_avg.push(ch_snr.pending_snr, ch_snr.last_snr_sample_count);
|
|
|
|
ch_snr.snr_avg.push(ch_snr.pending_snr, ch_snr.last_snr_sample_count);
|
|
|
|
|
|
|
|
ch_snr.last_snr_sample = ch_snr.pending_snr;
|
|
|
|
ch_snr.last_snr_sample_count = 1;
|
|
|
|
ch_snr.last_snr_sample_count = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ch_snr.pending_snr = null_snr;
|
|
|
|
ch_snr.pending_snr = null_snr;
|
|
|
@ -166,7 +167,7 @@ private:
|
|
|
|
|
|
|
|
|
|
|
|
float target_snr_dB = cc == PUSCH_CODE ? target_pusch_snr_dB : target_pucch_snr_dB;
|
|
|
|
float target_snr_dB = cc == PUSCH_CODE ? target_pusch_snr_dB : target_pucch_snr_dB;
|
|
|
|
if (target_snr_dB < 0) {
|
|
|
|
if (target_snr_dB < 0) {
|
|
|
|
// undefined target sinr case, or no more PHR
|
|
|
|
// undefined target SINR case
|
|
|
|
return encode_tpc_delta(0);
|
|
|
|
return encode_tpc_delta(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((tti_count - ch_snr.last_tpc_tti_count) < min_tpc_tti_interval) {
|
|
|
|
if ((tti_count - ch_snr.last_tpc_tti_count) < min_tpc_tti_interval) {
|
|
|
@ -176,12 +177,13 @@ private:
|
|
|
|
if (cc == PUSCH_CODE and last_phr < 0 and not ch_snr.phr_flag) {
|
|
|
|
if (cc == PUSCH_CODE and last_phr < 0 and not ch_snr.phr_flag) {
|
|
|
|
// if negative PHR and PUSCH
|
|
|
|
// if negative PHR and PUSCH
|
|
|
|
logger.info("TPC: rnti=0x%x, PUSCH command=0 due to PHR=%d<0", rnti, last_phr);
|
|
|
|
logger.info("TPC: rnti=0x%x, PUSCH command=0 due to PHR=%d<0", rnti, last_phr);
|
|
|
|
ch_snr.phr_flag = true;
|
|
|
|
ch_snr.phr_flag = true;
|
|
|
|
return encode_tpc_delta(-1);
|
|
|
|
ch_snr.pending_delta = -1;
|
|
|
|
|
|
|
|
return encode_tpc_delta(ch_snr.pending_delta);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// target SINR is finite and there is power headroom
|
|
|
|
// target SINR is finite and there is power headroom
|
|
|
|
float diff = target_snr_dB - ch_snr.snr_avg.value();
|
|
|
|
float diff = target_snr_dB - ch_snr.last_snr_sample;
|
|
|
|
diff -= ch_snr.win_tpc_values.value() + ch_snr.acc_tpc_values;
|
|
|
|
diff -= ch_snr.win_tpc_values.value() + ch_snr.acc_tpc_values;
|
|
|
|
if (diff >= 1) {
|
|
|
|
if (diff >= 1) {
|
|
|
|
ch_snr.pending_delta = diff > 3 ? 3 : 1;
|
|
|
|
ch_snr.pending_delta = diff > 3 ? 3 : 1;
|
|
|
@ -194,6 +196,15 @@ private:
|
|
|
|
ch_snr.pending_delta = -1;
|
|
|
|
ch_snr.pending_delta = -1;
|
|
|
|
ch_snr.last_tpc_tti_count = tti_count;
|
|
|
|
ch_snr.last_tpc_tti_count = tti_count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ch_snr.pending_delta != 0) {
|
|
|
|
|
|
|
|
logger.debug("TPC: rnti=0x%x, %s command=%d, last SNR=%d, SNR average=%f, diff_acc=%f",
|
|
|
|
|
|
|
|
rnti,
|
|
|
|
|
|
|
|
cc == PUSCH_CODE ? "PUSCH" : "PUCCH",
|
|
|
|
|
|
|
|
encode_tpc_delta(ch_snr.pending_delta),
|
|
|
|
|
|
|
|
ch_snr.last_snr_sample,
|
|
|
|
|
|
|
|
ch_snr.snr_avg.value(),
|
|
|
|
|
|
|
|
diff);
|
|
|
|
|
|
|
|
}
|
|
|
|
return encode_tpc_delta(ch_snr.pending_delta);
|
|
|
|
return encode_tpc_delta(ch_snr.pending_delta);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -221,6 +232,7 @@ private:
|
|
|
|
// SNR average estimation with irregular sample spacing
|
|
|
|
// SNR average estimation with irregular sample spacing
|
|
|
|
uint32_t last_snr_sample_count = 1; // jump in spacing
|
|
|
|
uint32_t last_snr_sample_count = 1; // jump in spacing
|
|
|
|
srsran::exp_average_irreg_sampling<float> snr_avg;
|
|
|
|
srsran::exp_average_irreg_sampling<float> snr_avg;
|
|
|
|
|
|
|
|
int last_snr_sample;
|
|
|
|
// Accumulation of past TPC commands
|
|
|
|
// Accumulation of past TPC commands
|
|
|
|
srsran::sliding_sum<int> win_tpc_values;
|
|
|
|
srsran::sliding_sum<int> win_tpc_values;
|
|
|
|
int8_t pending_delta = 0;
|
|
|
|
int8_t pending_delta = 0;
|
|
|
@ -228,7 +240,9 @@ private:
|
|
|
|
uint32_t last_tpc_tti_count = 0;
|
|
|
|
uint32_t last_tpc_tti_count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
explicit ul_ch_snr_estim(float exp_avg_alpha, int initial_snr) :
|
|
|
|
explicit ul_ch_snr_estim(float exp_avg_alpha, int initial_snr) :
|
|
|
|
snr_avg(exp_avg_alpha, initial_snr), win_tpc_values(FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS)
|
|
|
|
snr_avg(exp_avg_alpha, initial_snr),
|
|
|
|
|
|
|
|
win_tpc_values(FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS),
|
|
|
|
|
|
|
|
last_snr_sample(initial_snr)
|
|
|
|
{}
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
std::array<ul_ch_snr_estim, nof_ul_ch_code> snr_estim_list;
|
|
|
|
std::array<ul_ch_snr_estim, nof_ul_ch_code> snr_estim_list;
|
|
|
|