SRS tx power with power control state
This commit is contained in:
@@ -609,6 +609,9 @@ typedef struct NR_UE_MAC_INST_s {
|
||||
bool pucch_power_control_initialized;
|
||||
int f_b_f_c;
|
||||
bool pusch_power_control_initialized;
|
||||
int h_b_f_c;
|
||||
bool srs_power_control_initialized;
|
||||
int delta_msg2;
|
||||
} NR_UE_MAC_INST_t;
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -240,6 +240,12 @@ int get_pusch_tx_power_ue(
|
||||
bool is_rar_tx_retx,
|
||||
bool transform_precoding);
|
||||
|
||||
int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
NR_SRS_Resource_t *srs_resource,
|
||||
NR_SRS_ResourceSet_t *srs_resource_set,
|
||||
int delta_srs,
|
||||
bool is_configured_for_pusch_on_current_bwp);
|
||||
|
||||
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||
int slot,
|
||||
frame_t frame,
|
||||
|
||||
@@ -578,6 +578,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup));
|
||||
mac->f_b_f_c = DELTA_P_rampup + delta_pusch;
|
||||
mac->pusch_power_control_initialized = true;
|
||||
mac->delta_msg2 = delta_pusch;
|
||||
} else {
|
||||
if (!((pusch_power_without_f_b_f_c + mac->f_b_f_c >= P_CMAX && delta_pusch > 0) ||
|
||||
(pusch_power_without_f_b_f_c + mac->f_b_f_c <= P_CMIN && delta_pusch < 0))) {
|
||||
@@ -595,3 +596,84 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
f_b_f_c);
|
||||
return min(P_CMAX, P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF + f_b_f_c);
|
||||
}
|
||||
|
||||
int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
NR_SRS_Resource_t *srs_resource,
|
||||
NR_SRS_ResourceSet_t *srs_resource_set,
|
||||
int delta_srs,
|
||||
bool is_configured_for_pusch_on_current_bwp)
|
||||
{
|
||||
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
||||
AssertFatal(current_UL_BWP, "Missing configuration: need UL_BWP to calculate SRS tx power\n");
|
||||
AssertFatal(srs_resource_set->p0, "P0 mantatory present at configuration\n");
|
||||
int P_0_SRS = *srs_resource_set->p0;
|
||||
|
||||
// alpha is optional, use same default as PUSCH
|
||||
const float alpha_factor_table[8] = {0.0f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f};
|
||||
float alpha = srs_resource_set->alpha ? alpha_factor_table[*srs_resource_set->alpha] : 1.0f;
|
||||
int m_srs_component =
|
||||
10 * log10(pow(2, current_UL_BWP->scs) * get_m_srs(srs_resource->freqHopping.c_SRS, srs_resource->freqHopping.b_SRS));
|
||||
|
||||
// The allowed MPR for SRS, PUCCH formats 0, 1, 3 and 4, and PRACH shall be as specified for QPSK modulated DFTs-OFDM of
|
||||
// equivalent RB allocation. The allowed MPR for PUCCH format 2 shall be as specified for QPSK modulated CP-OFDM of equivalent RB
|
||||
// allocation.
|
||||
int P_CMAX = nr_get_Pcmax(mac->p_Max,
|
||||
mac->nr_band,
|
||||
mac->frame_type,
|
||||
mac->frequency_range,
|
||||
mac->current_UL_BWP->channel_bandwidth,
|
||||
2,
|
||||
false,
|
||||
mac->current_UL_BWP->scs,
|
||||
mac->current_UL_BWP->BWPSize,
|
||||
true,
|
||||
get_m_srs(srs_resource->freqHopping.c_SRS, srs_resource->freqHopping.b_SRS),
|
||||
0); // TODO: Determine SRS start RB
|
||||
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||
|
||||
int srs_power_without_h_b_f_c = P_0_SRS + alpha * pathloss + m_srs_component;
|
||||
|
||||
// Power adjustment state
|
||||
int h_b_f_c = 0;
|
||||
bool use_pusch_power_adjustment_state = srs_resource_set->srs_PowerControlAdjustmentStates == NULL;
|
||||
if (is_configured_for_pusch_on_current_bwp && use_pusch_power_adjustment_state) {
|
||||
// Case 1: Use PUSCH power control adjustment state
|
||||
h_b_f_c = mac->f_b_f_c;
|
||||
} else {
|
||||
// Case 2: Separate power control adjustment state
|
||||
AssertFatal(srs_resource_set->srs_PowerControlAdjustmentStates == NULL
|
||||
|| *srs_resource_set->srs_PowerControlAdjustmentStates
|
||||
!= NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_sameAsFci2,
|
||||
"Two PUSCH power adjustment states not supported");
|
||||
|
||||
bool is_tpc_accumulation_provided = current_UL_BWP->srs_Config != NULL && current_UL_BWP->srs_Config->tpc_Accumulation != NULL;
|
||||
bool separate_pc_adjustment_state = srs_resource_set->srs_PowerControlAdjustmentStates
|
||||
&& *srs_resource_set->srs_PowerControlAdjustmentStates
|
||||
== NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop;
|
||||
|
||||
if (!is_tpc_accumulation_provided && (!is_configured_for_pusch_on_current_bwp || separate_pc_adjustment_state)) {
|
||||
if (!mac->srs_power_control_initialized) {
|
||||
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_0_SRS + m_srs_component + alpha * pathloss);
|
||||
DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup));
|
||||
mac->srs_power_control_initialized = true;
|
||||
mac->h_b_f_c = DELTA_P_rampup + mac->delta_msg2;
|
||||
} else {
|
||||
int P_CMIN = mac->current_UL_BWP->P_CMIN;
|
||||
if (!((srs_power_without_h_b_f_c + mac->h_b_f_c >= P_CMAX && delta_srs > 0)
|
||||
|| (srs_power_without_h_b_f_c + mac->h_b_f_c <= P_CMIN && delta_srs < 0))) {
|
||||
mac->h_b_f_c += delta_srs;
|
||||
}
|
||||
}
|
||||
h_b_f_c = mac->h_b_f_c;
|
||||
} else {
|
||||
// Case 3: No accumulation
|
||||
h_b_f_c = delta_srs;
|
||||
}
|
||||
}
|
||||
|
||||
return min(P_CMAX, srs_power_without_h_b_f_c + h_b_f_c);
|
||||
}
|
||||
|
||||
@@ -1058,7 +1058,8 @@ int configure_srs_pdu(NR_UE_MAC_INST_t *mac,
|
||||
NR_SRS_Resource_t *srs_resource,
|
||||
fapi_nr_ul_config_srs_pdu *srs_config_pdu,
|
||||
int period,
|
||||
int offset)
|
||||
int offset,
|
||||
NR_SRS_ResourceSet_t *srs_resource_set)
|
||||
{
|
||||
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
||||
|
||||
@@ -1100,6 +1101,11 @@ int configure_srs_pdu(NR_UE_MAC_INST_t *mac,
|
||||
srs_config_pdu->t_offset = offset;
|
||||
}
|
||||
|
||||
bool is_configured_for_pusch_on_current_bwp = true;
|
||||
int delta_srs = 0; // DCI format 2_3 not implemented
|
||||
srs_config_pdu->tx_power =
|
||||
get_srs_tx_power_ue(mac, srs_resource, srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_MAC,"Frame = %i, slot = %i\n", frame, slot);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti);
|
||||
@@ -1142,10 +1148,11 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger
|
||||
|
||||
int slot_offset = 0;
|
||||
NR_SRS_Resource_t *srs_resource = NULL;
|
||||
NR_SRS_ResourceSet_t *srs_resource_set = NULL;
|
||||
for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) {
|
||||
|
||||
// Find aperiodic resource set
|
||||
NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs];
|
||||
srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs];
|
||||
if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_aperiodic)
|
||||
continue;
|
||||
// the resource trigger need to match the DCI one
|
||||
@@ -1186,7 +1193,7 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger
|
||||
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS);
|
||||
if (!pdu)
|
||||
return;
|
||||
int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, 0, 0);
|
||||
int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, 0, 0, srs_resource_set);
|
||||
if (ret != 0)
|
||||
remove_ul_config_last_item(pdu);
|
||||
release_ul_config(pdu, false);
|
||||
@@ -1204,9 +1211,10 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame,
|
||||
}
|
||||
|
||||
bool srs_scheduled = false;
|
||||
NR_SRS_ResourceSet_t *srs_resource_set = NULL;
|
||||
for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) {
|
||||
// Find periodic resource set
|
||||
NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs];
|
||||
srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs];
|
||||
if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_periodic) {
|
||||
continue;
|
||||
}
|
||||
@@ -1237,7 +1245,7 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame,
|
||||
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS);
|
||||
if (!pdu)
|
||||
return false;
|
||||
int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, period, offset);
|
||||
int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, period, offset, srs_resource_set);
|
||||
if (ret != 0)
|
||||
remove_ul_config_last_item(pdu);
|
||||
else
|
||||
|
||||
@@ -594,6 +594,126 @@ TEST(test_pcmax, test_non_obvious_bwp_size)
|
||||
nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start));
|
||||
}
|
||||
|
||||
TEST(test_srs_power, use_pusch_power_adjustment_state)
|
||||
{
|
||||
NR_UE_MAC_INST_t mac = {0};
|
||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_SRS_Resource_t srs_resource = {0};
|
||||
NR_SRS_ResourceSet_t srs_resource_set = {0};
|
||||
bool is_configured_for_pusch_on_current_bwp = true;
|
||||
int delta_srs = 0;
|
||||
srs_resource_set.srs_PowerControlAdjustmentStates = NULL;
|
||||
mac.nr_band = 78;
|
||||
mac.f_b_f_c = 0;
|
||||
mac.pusch_power_control_initialized = true;
|
||||
long p0 = 0;
|
||||
srs_resource_set.p0 = &p0;
|
||||
|
||||
int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
|
||||
mac.f_b_f_c = 4;
|
||||
|
||||
int increased_tx_power =
|
||||
get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
EXPECT_EQ(tx_power + mac.f_b_f_c, increased_tx_power);
|
||||
}
|
||||
|
||||
TEST(test_srs_power, no_support_for_two_pusch_power_adjustment_states)
|
||||
{
|
||||
NR_UE_MAC_INST_t mac = {0};
|
||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_SRS_Resource_t srs_resource = {0};
|
||||
NR_SRS_ResourceSet_t srs_resource_set = {0};
|
||||
long p0 = 0;
|
||||
srs_resource_set.p0 = &p0;
|
||||
bool is_configured_for_pusch_on_current_bwp = true;
|
||||
int delta_srs = 0;
|
||||
long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_sameAsFci2;
|
||||
srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates;
|
||||
mac.nr_band = 78;
|
||||
mac.f_b_f_c = 0;
|
||||
mac.pusch_power_control_initialized = true;
|
||||
|
||||
EXPECT_DEATH(get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp),
|
||||
"Two PUSCH power adjustment states not supported");
|
||||
}
|
||||
|
||||
TEST(test_srs_power, no_tpc_accumulation)
|
||||
{
|
||||
NR_UE_MAC_INST_t mac = {0};
|
||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_SRS_Resource_t srs_resource = {0};
|
||||
NR_SRS_ResourceSet_t srs_resource_set = {0};
|
||||
long p0 = 0;
|
||||
srs_resource_set.p0 = &p0;
|
||||
bool is_configured_for_pusch_on_current_bwp = true;
|
||||
int delta_srs = 0;
|
||||
long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop;
|
||||
srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates;
|
||||
mac.nr_band = 78;
|
||||
mac.f_b_f_c = 0;
|
||||
mac.pusch_power_control_initialized = true;
|
||||
|
||||
NR_SRS_Config_t srs_Config = {0};
|
||||
long tpc_Accumulation = 0;
|
||||
srs_Config.tpc_Accumulation = &tpc_Accumulation;
|
||||
current_UL_BWP.srs_Config = &srs_Config;
|
||||
|
||||
int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
|
||||
delta_srs = 4;
|
||||
|
||||
int increased_tx_power =
|
||||
get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
EXPECT_EQ(tx_power + delta_srs, increased_tx_power);
|
||||
}
|
||||
|
||||
TEST(test_srs_power, tpc_accumulation)
|
||||
{
|
||||
NR_UE_MAC_INST_t mac = {0};
|
||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_SRS_Resource_t srs_resource = {0};
|
||||
NR_SRS_ResourceSet_t srs_resource_set = {0};
|
||||
long p0 = 0;
|
||||
srs_resource_set.p0 = &p0;
|
||||
bool is_configured_for_pusch_on_current_bwp = true;
|
||||
int delta_srs = 0;
|
||||
long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop;
|
||||
srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates;
|
||||
mac.nr_band = 78;
|
||||
mac.f_b_f_c = 0;
|
||||
mac.pusch_power_control_initialized = true;
|
||||
mac.srs_power_control_initialized = true;
|
||||
mac.h_b_f_c = 0;
|
||||
|
||||
NR_SRS_Config_t srs_Config = {0};
|
||||
current_UL_BWP.srs_Config = &srs_Config;
|
||||
|
||||
int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
|
||||
delta_srs = 4;
|
||||
|
||||
int increased_tx_power =
|
||||
get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
EXPECT_EQ(tx_power + delta_srs, increased_tx_power);
|
||||
|
||||
int more_tx_power =
|
||||
get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp);
|
||||
EXPECT_EQ(tx_power + delta_srs * 2, more_tx_power);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
logInit();
|
||||
|
||||
Reference in New Issue
Block a user