PUCCH power control state.
This commit is contained in:
@@ -577,7 +577,9 @@ typedef struct NR_UE_MAC_INST_s {
|
|||||||
|
|
||||||
//SIDELINK MAC PARAMETERS
|
//SIDELINK MAC PARAMETERS
|
||||||
sl_nr_ue_mac_params_t *SL_MAC_PARAMS;
|
sl_nr_ue_mac_params_t *SL_MAC_PARAMS;
|
||||||
|
// PUCCH closed loop power control state
|
||||||
|
int G_b_f_c;
|
||||||
|
bool pucch_power_control_initialized;
|
||||||
} NR_UE_MAC_INST_t;
|
} NR_UE_MAC_INST_t;
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|||||||
@@ -217,14 +217,8 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
uint8_t add_dmrs_flag,
|
uint8_t add_dmrs_flag,
|
||||||
uint8_t N_symb_PUCCH,
|
uint8_t N_symb_PUCCH,
|
||||||
int subframe_number,
|
int subframe_number,
|
||||||
int O_uci);
|
int O_uci,
|
||||||
|
uint16_t start_prb);
|
||||||
int get_deltatf(uint16_t nb_of_prbs,
|
|
||||||
uint8_t N_symb_PUCCH,
|
|
||||||
uint8_t freq_hop_flag,
|
|
||||||
uint8_t add_dmrs_flag,
|
|
||||||
int N_sc_ctrl_RB,
|
|
||||||
int O_UCI);
|
|
||||||
|
|
||||||
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||||
int slot,
|
int slot,
|
||||||
@@ -235,6 +229,8 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb);
|
int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb);
|
||||||
|
|
||||||
|
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame);
|
||||||
|
|
||||||
/* Random Access */
|
/* Random Access */
|
||||||
|
|
||||||
/* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x
|
/* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
|||||||
|
|
||||||
for (int i = 0; i < NR_MAX_SR_ID; i++)
|
for (int i = 0; i < NR_MAX_SR_ID; i++)
|
||||||
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
|
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
|
||||||
|
|
||||||
|
mac->pucch_power_control_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
||||||
|
|||||||
@@ -31,6 +31,40 @@
|
|||||||
|
|
||||||
#include "LAYER2/NR_MAC_UE/mac_proto.h"
|
#include "LAYER2/NR_MAC_UE/mac_proto.h"
|
||||||
|
|
||||||
|
#define DEFAULT_P0_NOMINAL_PUCCH_0_DBM 0
|
||||||
|
#define DEFAULT_DELTA_F_PUCCH_0_DB 0
|
||||||
|
|
||||||
|
// TODO: This should be part of mac instance
|
||||||
|
/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
|
||||||
|
/* this is a counter of number of pucch format 4 per subframe */
|
||||||
|
static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = {0};
|
||||||
|
|
||||||
|
/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
|
||||||
|
static const int nb_symbols_excluding_dmrs[11][2][2]
|
||||||
|
= {
|
||||||
|
/* No additional DMRS Additional DMRS */
|
||||||
|
/* PUCCH length No hopping hopping No hopping hopping */
|
||||||
|
/* index 0 1 0 1 */
|
||||||
|
/* 4 */ {{ 3 , 2 } , { 3 , 2 }},
|
||||||
|
/* 5 */ {{ 3 , 3 } , { 3 , 3 }},
|
||||||
|
/* 6 */ {{ 4 , 4 } , { 4 , 4 }},
|
||||||
|
/* 7 */ {{ 5 , 5 } , { 5 , 5 }},
|
||||||
|
/* 8 */ {{ 6 , 6 } , { 6 , 6 }},
|
||||||
|
/* 9 */ {{ 7 , 7 } , { 7 , 7 }},
|
||||||
|
/* 10 */ {{ 8 , 8 } , { 6 , 6 }},
|
||||||
|
/* 11 */ {{ 9 , 9 } , { 7 , 7 }},
|
||||||
|
/* 12 */ {{ 10 , 10 } , { 8 , 8 }},
|
||||||
|
/* 13 */ {{ 11 , 11 } , { 9 , 9 }},
|
||||||
|
/* 14 */ {{ 12 , 12 } , { 10 , 10 }},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_deltatf(uint16_t nb_of_prbs,
|
||||||
|
uint8_t N_symb_PUCCH,
|
||||||
|
uint8_t freq_hop_flag,
|
||||||
|
uint8_t add_dmrs_flag,
|
||||||
|
int N_sc_ctrl_RB,
|
||||||
|
int O_UCI);
|
||||||
|
|
||||||
// Implementation of 6.2.4 Configured ransmitted power
|
// Implementation of 6.2.4 Configured ransmitted power
|
||||||
// 3GPP TS 38.101-1 version 16.5.0 Release 16
|
// 3GPP TS 38.101-1 version 16.5.0 Release 16
|
||||||
// -
|
// -
|
||||||
@@ -156,3 +190,171 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback
|
||||||
|
// slot. The correct way to do this would be to calculate the K_PUCCH (delta_PUCCH summation window end) for each PUCCH occasion and
|
||||||
|
// compare PUCCH transmission symbol with the reception symbol of the DCI containing delta_PUCCH to determine if the delta_PUCCH
|
||||||
|
// should be added at each occasion.
|
||||||
|
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame)
|
||||||
|
{
|
||||||
|
int delta_tpc_sum = 0;
|
||||||
|
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
|
||||||
|
if (mac->dl_harq_info[i].active && mac->dl_harq_info[i].ul_slot == slot && mac->dl_harq_info[i].ul_frame == frame) {
|
||||||
|
delta_tpc_sum += mac->dl_harq_info[i].delta_pucch;
|
||||||
|
mac->dl_harq_info[i].delta_pucch = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return delta_tpc_sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUCCH Power control according to 38.213 section 7.2.1
|
||||||
|
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||||
|
int scs,
|
||||||
|
NR_PUCCH_Config_t *pucch_Config,
|
||||||
|
int sum_delta_pucch,
|
||||||
|
uint8_t format_type,
|
||||||
|
uint16_t nb_of_prbs,
|
||||||
|
uint8_t freq_hop_flag,
|
||||||
|
uint8_t add_dmrs_flag,
|
||||||
|
uint8_t N_symb_PUCCH,
|
||||||
|
int subframe_number,
|
||||||
|
int O_uci,
|
||||||
|
uint16_t start_prb)
|
||||||
|
{
|
||||||
|
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
||||||
|
AssertFatal(current_UL_BWP && current_UL_BWP->pucch_ConfigCommon,
|
||||||
|
"Missing configuration: need UL_BWP and pucch_ConfigCommon to calculate PUCCH tx power\n");
|
||||||
|
int PUCCH_POWER_DEFAULT = 0;
|
||||||
|
// p0_nominal is optional
|
||||||
|
int16_t P_O_NOMINAL_PUCCH = DEFAULT_P0_NOMINAL_PUCCH_0_DBM;
|
||||||
|
if (current_UL_BWP->pucch_ConfigCommon->p0_nominal != NULL) {
|
||||||
|
P_O_NOMINAL_PUCCH = *current_UL_BWP->pucch_ConfigCommon->p0_nominal;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NR_PUCCH_PowerControl *power_config = pucch_Config ? pucch_Config->pucch_PowerControl : NULL;
|
||||||
|
|
||||||
|
if (!power_config)
|
||||||
|
return (PUCCH_POWER_DEFAULT);
|
||||||
|
|
||||||
|
int16_t P_O_UE_PUCCH = 0;
|
||||||
|
|
||||||
|
if (pucch_Config->spatialRelationInfoToAddModList != NULL) { /* FFS TODO NR */
|
||||||
|
LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented\n");
|
||||||
|
return (PUCCH_POWER_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_b_f_c = 0;
|
||||||
|
if (power_config->p0_Set != NULL) {
|
||||||
|
P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */
|
||||||
|
}
|
||||||
|
|
||||||
|
int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
|
||||||
|
|
||||||
|
int16_t delta_F_PUCCH = DEFAULT_DELTA_F_PUCCH_0_DB;
|
||||||
|
long *delta_F_PUCCH_config = NULL;
|
||||||
|
int DELTA_TF;
|
||||||
|
uint16_t N_ref_PUCCH;
|
||||||
|
int N_sc_ctrl_RB = 0;
|
||||||
|
|
||||||
|
/* computing of pucch transmission power adjustment */
|
||||||
|
switch (format_type) {
|
||||||
|
case 0:
|
||||||
|
N_ref_PUCCH = 2;
|
||||||
|
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
|
||||||
|
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
N_ref_PUCCH = 14;
|
||||||
|
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH * O_uci);
|
||||||
|
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
N_sc_ctrl_RB = 10;
|
||||||
|
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||||
|
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
N_sc_ctrl_RB = 14;
|
||||||
|
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||||
|
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]);
|
||||||
|
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
||||||
|
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LOG_E(MAC,"PUCCH unknown pucch format %d\n", format_type);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (delta_F_PUCCH_config != NULL) {
|
||||||
|
delta_F_PUCCH = *delta_F_PUCCH_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUCCH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
|
||||||
|
// TODO: P_CMAX for format 2
|
||||||
|
int P_CMAX = nr_get_Pcmax(mac, 2, false, mac->current_UL_BWP->scs, mac->current_UL_BWP->BWPSize, true, 1, start_prb);
|
||||||
|
int P_CMIN = -40; // TODO: minimum TX power, possibly 38.101-1 6.3.1
|
||||||
|
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||||
|
|
||||||
|
if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) {
|
||||||
|
LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented\n");
|
||||||
|
return (PUCCH_POWER_DEFAULT);
|
||||||
|
}
|
||||||
|
int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs)));
|
||||||
|
|
||||||
|
int16_t pucch_power_without_g_pucch = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF;
|
||||||
|
|
||||||
|
if (power_config->p0_Set == NULL) {
|
||||||
|
if (mac->pucch_power_control_initialized == false) {
|
||||||
|
// Initialize power control state
|
||||||
|
// Assuming only sending on PCell
|
||||||
|
NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources;
|
||||||
|
float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
|
||||||
|
float DELTA_P_rampup = P_CMAX - (P_O_PUCCH + pathloss + delta_F_PUCCH + DELTA_TF + sum_delta_pucch);
|
||||||
|
DELTA_P_rampup = max(min(0, DELTA_P_rampup), DELTA_P_rampup_requested);
|
||||||
|
mac->G_b_f_c = DELTA_P_rampup + sum_delta_pucch;
|
||||||
|
mac->pucch_power_control_initialized = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// PUCCH closed loop power control state
|
||||||
|
G_b_f_c = mac->G_b_f_c;
|
||||||
|
if (!((pucch_power_without_g_pucch + G_b_f_c >= P_CMAX && sum_delta_pucch > 0) ||
|
||||||
|
(pucch_power_without_g_pucch + G_b_f_c <= P_CMIN && sum_delta_pucch < 0))) {
|
||||||
|
G_b_f_c += sum_delta_pucch;
|
||||||
|
}
|
||||||
|
mac->G_b_f_c = G_b_f_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int pucch_power = min(P_CMAX, pucch_power_without_g_pucch + G_b_f_c);
|
||||||
|
|
||||||
|
LOG_D(MAC, "PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
|
||||||
|
pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c);
|
||||||
|
|
||||||
|
return pucch_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_deltatf(uint16_t nb_of_prbs,
|
||||||
|
uint8_t N_symb_PUCCH,
|
||||||
|
uint8_t freq_hop_flag,
|
||||||
|
uint8_t add_dmrs_flag,
|
||||||
|
int N_sc_ctrl_RB,
|
||||||
|
int O_UCI)
|
||||||
|
{
|
||||||
|
int DELTA_TF;
|
||||||
|
int O_CRC = compute_pucch_crc_size(O_UCI);
|
||||||
|
int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag];
|
||||||
|
float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb;
|
||||||
|
float K1 = 6;
|
||||||
|
if (O_UCI + O_CRC < 12)
|
||||||
|
DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE)));
|
||||||
|
else {
|
||||||
|
float K2 = 2.4;
|
||||||
|
float BPRE = (O_UCI + O_CRC) / N_RE;
|
||||||
|
DELTA_TF = 10 * log10((double)(pow(2, (K2 * BPRE)) - 1));
|
||||||
|
}
|
||||||
|
return DELTA_TF;
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,18 +58,11 @@
|
|||||||
#include "common/utils/LOG/log.h"
|
#include "common/utils/LOG/log.h"
|
||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
|
|
||||||
#define DEFAULT_P0_NOMINAL_PUCCH_0_DBM 0
|
|
||||||
#define DEFAULT_DELTA_F_PUCCH_0_DB 0
|
|
||||||
|
|
||||||
// #define DEBUG_MIB
|
// #define DEBUG_MIB
|
||||||
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
|
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
|
||||||
// #define DEBUG_RAR
|
// #define DEBUG_RAR
|
||||||
extern uint32_t N_RB_DL;
|
extern uint32_t N_RB_DL;
|
||||||
|
|
||||||
/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
|
|
||||||
/* this is a counter of number of pucch format 4 per subframe */
|
|
||||||
static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = { 0 } ;
|
|
||||||
|
|
||||||
/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
|
/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
|
||||||
static const int sequence_cyclic_shift_1_harq_ack_bit[2]
|
static const int sequence_cyclic_shift_1_harq_ack_bit[2]
|
||||||
/* HARQ-ACK Value 0 1 */
|
/* HARQ-ACK Value 0 1 */
|
||||||
@@ -104,7 +97,6 @@ random-access procedure
|
|||||||
@returns timing advance or 0xffff if preamble doesn't match
|
@returns timing advance or 0xffff if preamble doesn't match
|
||||||
*/
|
*/
|
||||||
static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id);
|
static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id);
|
||||||
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame);
|
|
||||||
|
|
||||||
int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const int sr_payload)
|
int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const int sr_payload)
|
||||||
{
|
{
|
||||||
@@ -127,25 +119,6 @@ int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const
|
|||||||
return mcs;
|
return mcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
|
|
||||||
static const int nb_symbols_excluding_dmrs[11][2][2]
|
|
||||||
= {
|
|
||||||
/* No additional DMRS Additional DMRS */
|
|
||||||
/* PUCCH length No hopping hopping No hopping hopping */
|
|
||||||
/* index 0 1 0 1 */
|
|
||||||
/* 4 */ {{ 3 , 2 } , { 3 , 2 }},
|
|
||||||
/* 5 */ {{ 3 , 3 } , { 3 , 3 }},
|
|
||||||
/* 6 */ {{ 4 , 4 } , { 4 , 4 }},
|
|
||||||
/* 7 */ {{ 5 , 5 } , { 5 , 5 }},
|
|
||||||
/* 8 */ {{ 6 , 6 } , { 6 , 6 }},
|
|
||||||
/* 9 */ {{ 7 , 7 } , { 7 , 7 }},
|
|
||||||
/* 10 */ {{ 8 , 8 } , { 6 , 6 }},
|
|
||||||
/* 11 */ {{ 9 , 9 } , { 7 , 7 }},
|
|
||||||
/* 12 */ {{ 10 , 10 } , { 8 , 8 }},
|
|
||||||
/* 13 */ {{ 11 , 11 } , { 9 , 9 }},
|
|
||||||
/* 14 */ {{ 12 , 12 } , { 10 , 10 }},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
|
/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
|
||||||
const initial_pucch_resource_t initial_pucch_resource[16] = {
|
const initial_pucch_resource_t initial_pucch_resource[16] = {
|
||||||
/* format first symbol Number of symbols PRB offset nb index for set of initial CS */
|
/* format first symbol Number of symbols PRB offset nb index for set of initial CS */
|
||||||
@@ -1395,8 +1368,6 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
|||||||
const int scs = current_UL_BWP->scs;
|
const int scs = current_UL_BWP->scs;
|
||||||
|
|
||||||
int subframe_number = slot / (nr_slots_per_frame[scs]/10);
|
int subframe_number = slot / (nr_slots_per_frame[scs]/10);
|
||||||
nb_pucch_format_4_in_subframes[subframe_number] = 0;
|
|
||||||
|
|
||||||
pucch_pdu->rnti = rnti;
|
pucch_pdu->rnti = rnti;
|
||||||
|
|
||||||
LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource);
|
LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource);
|
||||||
@@ -1593,7 +1564,8 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
|||||||
pucch_pdu->add_dmrs_flag,
|
pucch_pdu->add_dmrs_flag,
|
||||||
pucch_pdu->nr_of_symbols,
|
pucch_pdu->nr_of_symbols,
|
||||||
subframe_number,
|
subframe_number,
|
||||||
n_uci);
|
n_uci,
|
||||||
|
pucch_pdu->prb_start);
|
||||||
} else {
|
} else {
|
||||||
LOG_E(NR_MAC, "problem with pucch configuration\n");
|
LOG_E(NR_MAC, "problem with pucch configuration\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1629,135 +1601,6 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUCCH Power control according to 38.213 section 7.2.1
|
|
||||||
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
|
||||||
int scs,
|
|
||||||
NR_PUCCH_Config_t *pucch_Config,
|
|
||||||
int sum_delta_pucch,
|
|
||||||
uint8_t format_type,
|
|
||||||
uint16_t nb_of_prbs,
|
|
||||||
uint8_t freq_hop_flag,
|
|
||||||
uint8_t add_dmrs_flag,
|
|
||||||
uint8_t N_symb_PUCCH,
|
|
||||||
int subframe_number,
|
|
||||||
int O_uci)
|
|
||||||
{
|
|
||||||
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
|
||||||
AssertFatal(current_UL_BWP && current_UL_BWP->pucch_ConfigCommon,
|
|
||||||
"Missing configuration: need UL_BWP and pucch_ConfigCommon to calculate PUCCH tx power\n");
|
|
||||||
int PUCCH_POWER_DEFAULT = 0;
|
|
||||||
// p0_nominal is optional
|
|
||||||
int16_t P_O_NOMINAL_PUCCH = DEFAULT_P0_NOMINAL_PUCCH_0_DBM;
|
|
||||||
if (current_UL_BWP->pucch_ConfigCommon->p0_nominal != NULL) {
|
|
||||||
P_O_NOMINAL_PUCCH = *current_UL_BWP->pucch_ConfigCommon->p0_nominal;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NR_PUCCH_PowerControl *power_config = pucch_Config ? pucch_Config->pucch_PowerControl : NULL;
|
|
||||||
|
|
||||||
if (!power_config)
|
|
||||||
return (PUCCH_POWER_DEFAULT);
|
|
||||||
|
|
||||||
int16_t P_O_UE_PUCCH;
|
|
||||||
int16_t G_b_f_c = 0;
|
|
||||||
|
|
||||||
if (pucch_Config->spatialRelationInfoToAddModList != NULL) { /* FFS TODO NR */
|
|
||||||
LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented\n");
|
|
||||||
return (PUCCH_POWER_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (power_config->p0_Set != NULL) {
|
|
||||||
P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */
|
|
||||||
G_b_f_c = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
G_b_f_c = sum_delta_pucch;
|
|
||||||
LOG_E(MAC,"PUCCH Transmit power control command not yet implemented for NR\n");
|
|
||||||
return (PUCCH_POWER_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
|
|
||||||
|
|
||||||
int16_t delta_F_PUCCH = DEFAULT_DELTA_F_PUCCH_0_DB;
|
|
||||||
long *delta_F_PUCCH_config = NULL;
|
|
||||||
int DELTA_TF;
|
|
||||||
uint16_t N_ref_PUCCH;
|
|
||||||
int N_sc_ctrl_RB = 0;
|
|
||||||
|
|
||||||
/* computing of pucch transmission power adjustment */
|
|
||||||
switch (format_type) {
|
|
||||||
case 0:
|
|
||||||
N_ref_PUCCH = 2;
|
|
||||||
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH);
|
|
||||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
N_ref_PUCCH = 14;
|
|
||||||
DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH * O_uci);
|
|
||||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
N_sc_ctrl_RB = 10;
|
|
||||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
|
||||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f2;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
N_sc_ctrl_RB = 14;
|
|
||||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
|
||||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f3;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]);
|
|
||||||
DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci);
|
|
||||||
delta_F_PUCCH_config = power_config->deltaF_PUCCH_f4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
LOG_E(MAC,"PUCCH unknown pucch format %d\n", format_type);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (delta_F_PUCCH_config != NULL) {
|
|
||||||
delta_F_PUCCH = *delta_F_PUCCH_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) {
|
|
||||||
LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented\n");
|
|
||||||
return (PUCCH_POWER_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
|
||||||
int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs)));
|
|
||||||
|
|
||||||
int16_t pucch_power = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF + G_b_f_c;
|
|
||||||
|
|
||||||
LOG_D(MAC, "PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
|
|
||||||
pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c);
|
|
||||||
|
|
||||||
return (pucch_power);
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_deltatf(uint16_t nb_of_prbs,
|
|
||||||
uint8_t N_symb_PUCCH,
|
|
||||||
uint8_t freq_hop_flag,
|
|
||||||
uint8_t add_dmrs_flag,
|
|
||||||
int N_sc_ctrl_RB,
|
|
||||||
int O_UCI)
|
|
||||||
{
|
|
||||||
int DELTA_TF;
|
|
||||||
int O_CRC = compute_pucch_crc_size(O_UCI);
|
|
||||||
int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag];
|
|
||||||
float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb;
|
|
||||||
float K1 = 6;
|
|
||||||
if (O_UCI + O_CRC < 12)
|
|
||||||
DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE)));
|
|
||||||
else {
|
|
||||||
float K2 = 2.4;
|
|
||||||
float BPRE = (O_UCI + O_CRC) / N_RE;
|
|
||||||
DELTA_TF = 10 * log10((double)(pow(2,(K2*BPRE)) - 1));
|
|
||||||
}
|
|
||||||
return DELTA_TF;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_pucch_resource_set(NR_PUCCH_Config_t *pucch_Config, int size)
|
static int find_pucch_resource_set(NR_PUCCH_Config_t *pucch_Config, int size)
|
||||||
{
|
{
|
||||||
// Procedure described in 38.213 Section 9.2.1
|
// Procedure described in 38.213 Section 9.2.1
|
||||||
@@ -4068,19 +3911,3 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm)
|
|||||||
|
|
||||||
return pathloss;
|
return pathloss;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback
|
|
||||||
// slot. The correct way to do this would be to calculate the K_PUCCH (delta_PUCCH summation window end) for each PUCCH occasion and
|
|
||||||
// compare PUCCH transmission symbol with the reception symbol of the DCI containing delta_PUCCH to determine if the delta_PUCCH
|
|
||||||
// should be added at each occasion.
|
|
||||||
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame)
|
|
||||||
{
|
|
||||||
int delta_tpc_sum = 0;
|
|
||||||
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
|
|
||||||
if (mac->dl_harq_info[i].active && mac->dl_harq_info[i].ul_slot == slot && mac->dl_harq_info[i].ul_frame == frame) {
|
|
||||||
delta_tpc_sum += mac->dl_harq_info[i].delta_pucch;
|
|
||||||
mac->dl_harq_info[i].delta_pucch = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return delta_tpc_sum;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user