diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index f9b4991cfd..1f8be0fa38 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -162,6 +162,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx]; memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT)); + bool init_meas = measurements->n0_subband_power == NULL; allocCast2D(n0_subband_power, unsigned int, measurements->n0_subband_power, @@ -174,6 +175,9 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy if (nb_symb[rb] > 0) { for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { tmp_n0_subband[aarx][rb] /= nb_symb[rb]; + // Initialize n0_subband_power from the first measurement before EMA + if (init_meas) + n0_subband_power[aarx][rb] = tmp_n0_subband[aarx][rb]; // apply exponential moving average to smooth noise measurements n0_subband_power[aarx][rb] = 0.9 * n0_subband_power[aarx][rb] + 0.1 * tmp_n0_subband[aarx][rb]; n0_subband_tot_perPRB += n0_subband_power[aarx][rb]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 8a02933663..6e2e4970a0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -4190,6 +4190,21 @@ void nr_mac_pc_snr(nr_power_control_t *pc, int snrx10, int rssi) pc->tpc_in_flight = PC_AVG_CNST * pc->tpc_in_flight; // + (1 - PC_AVG_CNST) * 0.0f } +/** + * @brief Enter new SNR and RSSI value for the latest UL transmission as new + * fixed averages. Reset "TPC in flight" to zero. + * + * @param pc the power control loop + * @param snrx10 the current SNR measurement multiplied by 10 + * @param rssi the current RSSI measurement + */ +void nr_mac_pc_reset_snr(nr_power_control_t *pc, int snrx10, int rssi) +{ + pc->avg_snr = 0.1f * snrx10; + pc->avg_rssi = rssi; + pc->tpc_in_flight = 0.0f; +} + /** * @brief Set a new target SNR for this power control loop, which can be * updated on a continuous basis, and will be reflected immediately upon diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index a6f66d738a..d0ab235276 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -910,6 +910,9 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con NR_SCHED_UNLOCK(&nrmac->sched_lock); return; } + // Msg4 Ack: reset average with first measurement + if (uci_01->ul_cqi != 0xff) + nr_mac_pc_reset_snr(&UE->UE_sched_ctrl.pucch_pc, uci_01->ul_cqi * 5 - 640, uci_01->rssi); } if (harq_confidence == 1) { UE->mac_stats.pucch0_DTX++; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index db35776944..f1fbbe2dfc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -762,11 +762,9 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, } if (ul_cqi != 0xff) { - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - // Msg3: reset average. If this fails (e.g., ul_cqi == 0xff) + // Msg3: reset average with first measurement. If this fails (e.g., ul_cqi == 0xff) // everything starts from predetermined value - sched_ctrl->pusch_pc.avg_snr = 0.1 * (ul_cqi * 5 - 640); - sched_ctrl->pusch_pc.avg_rssi = rssi; + nr_mac_pc_reset_snr(&UE->UE_sched_ctrl.pusch_pc, ul_cqi * 5 - 640, rssi); } if (!sdu) { // NACK diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index fb2f12e6d2..5aeace199c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -500,6 +500,7 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE float nr_mac_get_snr(const nr_power_control_t *pc); void nr_mac_pc_snr(nr_power_control_t *pc, int snrx10, int rssi); +void nr_mac_pc_reset_snr(nr_power_control_t *pc, int snrx10, int rssi); void nr_mac_set_target_snrx10(nr_power_control_t *pc, int target_snrx10); void nr_mac_set_rssi_threshold(nr_power_control_t *pc, int rssi_threshold); void nr_mac_signal_dtx(nr_power_control_t *pc);