Merge remote-tracking branch 'origin/develop-SRS' into integration_2022_wk06_a
This commit is contained in:
@@ -2495,6 +2495,61 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : get_nr_srs_offset
|
||||
*
|
||||
* PARAMETERS : periodicityAndOffset for SRS
|
||||
*
|
||||
* RETURN : the offset parameter for SRS
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset) {
|
||||
|
||||
switch(periodicityAndOffset.present) {
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl1:
|
||||
return periodicityAndOffset.choice.sl1;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl2:
|
||||
return periodicityAndOffset.choice.sl2;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl4:
|
||||
return periodicityAndOffset.choice.sl4;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl5:
|
||||
return periodicityAndOffset.choice.sl5;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl8:
|
||||
return periodicityAndOffset.choice.sl8;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl10:
|
||||
return periodicityAndOffset.choice.sl10;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl16:
|
||||
return periodicityAndOffset.choice.sl16;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl20:
|
||||
return periodicityAndOffset.choice.sl20;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl32:
|
||||
return periodicityAndOffset.choice.sl32;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl40:
|
||||
return periodicityAndOffset.choice.sl40;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl64:
|
||||
return periodicityAndOffset.choice.sl64;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl80:
|
||||
return periodicityAndOffset.choice.sl80;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl160:
|
||||
return periodicityAndOffset.choice.sl160;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl320:
|
||||
return periodicityAndOffset.choice.sl320;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl640:
|
||||
return periodicityAndOffset.choice.sl640;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl1280:
|
||||
return periodicityAndOffset.choice.sl1280;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_sl2560:
|
||||
return periodicityAndOffset.choice.sl2560;
|
||||
case NR_SRS_PeriodicityAndOffset_PR_NOTHING:
|
||||
LOG_W(NR_MAC,"NR_SRS_PeriodicityAndOffset_PR_NOTHING\n");
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the transform precoding status according to 6.1.3 of 3GPP TS 38.214 version 16.3.0 Release 16:
|
||||
// - "UE procedure for applying transform precoding on PUSCH"
|
||||
uint8_t get_transformPrecoding(const NR_BWP_UplinkCommon_t *initialUplinkBWP,
|
||||
|
||||
@@ -119,6 +119,8 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
|
||||
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
|
||||
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
|
||||
|
||||
uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset);
|
||||
|
||||
void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
frame_t frameP,
|
||||
NR_MIB_t *mib,
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
|
||||
//#define SRS_DEBUG
|
||||
|
||||
static prach_association_pattern_t prach_assoc_pattern;
|
||||
static ssb_list_info_t ssb_list;
|
||||
|
||||
@@ -894,6 +896,133 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
}
|
||||
|
||||
// Periodic SRS scheduling
|
||||
bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slot) {
|
||||
|
||||
bool srs_scheduled = false;
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
|
||||
NR_SRS_Config_t *srs_config = NULL;
|
||||
if (mac->cg &&
|
||||
mac->cg->spCellConfig &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
|
||||
srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
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];
|
||||
if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_periodic) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the corresponding srs resource
|
||||
NR_SRS_Resource_t *srs_resource = NULL;
|
||||
for(int r1 = 0; r1 < srs_resource_set->srs_ResourceIdList->list.count; r1++) {
|
||||
for (int r2 = 0; r2 < srs_config->srs_ResourceToAddModList->list.count; r2++) {
|
||||
if ((*srs_resource_set->srs_ResourceIdList->list.array[r1] == srs_config->srs_ResourceToAddModList->list.array[r2]->srs_ResourceId) &&
|
||||
(srs_config->srs_ResourceToAddModList->list.array[r2]->resourceType.present == NR_SRS_Resource__resourceType_PR_periodic)) {
|
||||
srs_resource = srs_config->srs_ResourceToAddModList->list.array[r2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(srs_resource == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NR_BWP_t ubwp = mac->ULbwp[0] ?
|
||||
mac->ULbwp[0]->bwp_Common->genericParameters :
|
||||
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters;
|
||||
|
||||
uint16_t period = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present];
|
||||
uint16_t offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
|
||||
|
||||
int n_slots_frame = nr_slots_per_frame[ubwp.subcarrierSpacing];
|
||||
|
||||
// Check if UE should transmit the SRS
|
||||
if((frame*n_slots_frame+slot-offset)%period == 0) {
|
||||
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot);
|
||||
fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu;
|
||||
|
||||
srs_config_pdu->rnti = mac->crnti;
|
||||
srs_config_pdu->handle = 0;
|
||||
srs_config_pdu->bwp_size = NRRIV2BW(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
|
||||
srs_config_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
|
||||
srs_config_pdu->subcarrier_spacing = ubwp.subcarrierSpacing;
|
||||
srs_config_pdu->cyclic_prefix = 0;
|
||||
srs_config_pdu->num_ant_ports = srs_resource->nrofSRS_Ports;
|
||||
srs_config_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols;
|
||||
srs_config_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor;
|
||||
srs_config_pdu->time_start_position = srs_resource->resourceMapping.startPosition;
|
||||
srs_config_pdu->config_index = srs_resource->freqHopping.c_SRS;
|
||||
srs_config_pdu->sequence_id = srs_resource->sequenceId;
|
||||
srs_config_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS;
|
||||
srs_config_pdu->comb_size = srs_resource->transmissionComb.present - 1;
|
||||
|
||||
switch(srs_resource->transmissionComb.present) {
|
||||
case NR_SRS_Resource__transmissionComb_PR_n2:
|
||||
srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n2->combOffset_n2;
|
||||
srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n2->cyclicShift_n2;
|
||||
break;
|
||||
case NR_SRS_Resource__transmissionComb_PR_n4:
|
||||
srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n4->combOffset_n4;
|
||||
srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n4->cyclicShift_n4;
|
||||
break;
|
||||
default:
|
||||
LOG_W(NR_MAC, "Invalid or not implemented comb_size!\n");
|
||||
}
|
||||
|
||||
srs_config_pdu->frequency_position = srs_resource->freqDomainPosition;
|
||||
srs_config_pdu->frequency_shift = srs_resource->freqDomainShift;
|
||||
srs_config_pdu->frequency_hopping = srs_resource->freqHopping.b_hop;
|
||||
srs_config_pdu->group_or_sequence_hopping = srs_resource->groupOrSequenceHopping;
|
||||
srs_config_pdu->resource_type = srs_resource->resourceType.present - 1;
|
||||
srs_config_pdu->t_srs = period;
|
||||
srs_config_pdu->t_offset = offset;
|
||||
|
||||
#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);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->handle = %u\n", srs_config_pdu->handle);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bwp_size = %u\n", srs_config_pdu->bwp_size);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bwp_start = %u\n", srs_config_pdu->bwp_start);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->subcarrier_spacing = %u\n", srs_config_pdu->subcarrier_spacing);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->cyclic_prefix = %u (0: Normal; 1: Extended)\n", srs_config_pdu->cyclic_prefix);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_ant_ports = %u (0 = 1 port, 1 = 2 ports, 2 = 4 ports)\n", srs_config_pdu->num_ant_ports);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_symbols = %u (0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols)\n", srs_config_pdu->num_symbols);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_repetitions = %u (0 = 1, 1 = 2, 2 = 4)\n", srs_config_pdu->num_repetitions);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->time_start_position = %u\n", srs_config_pdu->time_start_position);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->config_index = %u\n", srs_config_pdu->config_index);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->sequence_id = %u\n", srs_config_pdu->sequence_id);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bandwidth_index = %u\n", srs_config_pdu->bandwidth_index);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->comb_size = %u (0 = comb size 2, 1 = comb size 4, 2 = comb size 8)\n", srs_config_pdu->comb_size);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->comb_offset = %u\n", srs_config_pdu->comb_offset);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->cyclic_shift = %u\n", srs_config_pdu->cyclic_shift);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_position = %u\n", srs_config_pdu->frequency_position);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_shift = %u\n", srs_config_pdu->frequency_shift);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_hopping = %u\n", srs_config_pdu->frequency_hopping);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->group_or_sequence_hopping = %u (0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping)\n", srs_config_pdu->group_or_sequence_hopping);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->resource_type = %u (0: aperiodic, 1: semi-persistent, 2: periodic)\n", srs_config_pdu->resource_type);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->t_srs = %u\n", srs_config_pdu->t_srs);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->t_offset = %u\n", srs_config_pdu->t_offset);
|
||||
#endif
|
||||
|
||||
fill_ul_config(ul_config, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS);
|
||||
srs_scheduled = true;
|
||||
}
|
||||
}
|
||||
return srs_scheduled;
|
||||
}
|
||||
|
||||
// Performs :
|
||||
// 1. TODO: Call RRC for link status return to PHY
|
||||
// 2. TODO: Perform SR/BSR procedures for scheduling feedback
|
||||
@@ -962,6 +1091,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
if (!ul_config) {
|
||||
LOG_E(NR_MAC, "mac->ul_config is null!\n");
|
||||
}
|
||||
|
||||
// Periodic SRS scheduling
|
||||
nr_ue_periodic_srs_scheduling(mod_id, frame_tx, slot_tx);
|
||||
|
||||
// Schedule ULSCH only if the current frame and slot match those in ul_config_req
|
||||
// AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus)
|
||||
if (ul_config){
|
||||
@@ -1052,7 +1185,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
}
|
||||
|
||||
if (dl_info) {
|
||||
return (CONNECTION_OK);
|
||||
return (UE_CONNECTION_OK);
|
||||
}
|
||||
module_id_t mod_id = ul_info->module_id;
|
||||
frame_t txFrameP = ul_info->frame_tx;
|
||||
|
||||
@@ -379,6 +379,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
if (slot == 0)
|
||||
nr_csi_meas_reporting(module_idP, frame, slot);
|
||||
|
||||
// Schedule SRS: check in slot 0 for the whole frame
|
||||
if (slot == 0)
|
||||
nr_schedule_srs(module_idP, frame);
|
||||
|
||||
// This schedule RA procedure if not in phy_test mode
|
||||
// Otherwise already consider 5G already connected
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
|
||||
@@ -2038,6 +2038,11 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
sched_ctrl->pucch_consecutive_dtx_cnt = 0;
|
||||
sched_ctrl->pusch_consecutive_dtx_cnt = 0;
|
||||
sched_ctrl->ul_failure = 0;
|
||||
|
||||
sched_ctrl->sched_srs.frame = -1;
|
||||
sched_ctrl->sched_srs.slot = -1;
|
||||
sched_ctrl->sched_srs.srs_scheduled = false;
|
||||
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
|
||||
sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file gNB_scheduler_srs.c
|
||||
* \brief MAC procedures related to SRS
|
||||
* \date 2021
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#include <softmodem-common.h>
|
||||
#include "NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "NR_MAC_gNB/mac_proto.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id, int UE_id, NR_SRS_Resource_t *srs_resource) {
|
||||
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
NR_BWP_t ubwp = sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
srs_pdu->rnti = UE_info->rnti[UE_id];
|
||||
srs_pdu->handle = 0;
|
||||
srs_pdu->bwp_size = NRRIV2BW(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
|
||||
srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
|
||||
srs_pdu->subcarrier_spacing = ubwp.subcarrierSpacing;
|
||||
srs_pdu->cyclic_prefix = 0;
|
||||
srs_pdu->num_ant_ports = srs_resource->nrofSRS_Ports;
|
||||
srs_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols;
|
||||
srs_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor;
|
||||
srs_pdu->time_start_position = srs_resource->resourceMapping.startPosition;
|
||||
srs_pdu->config_index = srs_resource->freqHopping.c_SRS;
|
||||
srs_pdu->sequence_id = srs_resource->sequenceId;
|
||||
srs_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS;
|
||||
srs_pdu->comb_size = srs_resource->transmissionComb.present - 1;
|
||||
|
||||
switch(srs_resource->transmissionComb.present) {
|
||||
case NR_SRS_Resource__transmissionComb_PR_n2:
|
||||
srs_pdu->comb_offset = srs_resource->transmissionComb.choice.n2->combOffset_n2;
|
||||
srs_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n2->cyclicShift_n2;
|
||||
break;
|
||||
case NR_SRS_Resource__transmissionComb_PR_n4:
|
||||
srs_pdu->comb_offset = srs_resource->transmissionComb.choice.n4->combOffset_n4;
|
||||
srs_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n4->cyclicShift_n4;
|
||||
break;
|
||||
default:
|
||||
LOG_W(NR_MAC, "Invalid or not implemented comb_size!\n");
|
||||
}
|
||||
|
||||
srs_pdu->frequency_position = srs_resource->freqDomainPosition;
|
||||
srs_pdu->frequency_shift = srs_resource->freqDomainShift;
|
||||
srs_pdu->frequency_hopping = srs_resource->freqHopping.b_hop;
|
||||
srs_pdu->group_or_sequence_hopping = srs_resource->groupOrSequenceHopping;
|
||||
srs_pdu->resource_type = srs_resource->resourceType.present - 1;
|
||||
srs_pdu->t_srs = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present];
|
||||
srs_pdu->t_offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
|
||||
}
|
||||
|
||||
void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) {
|
||||
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot];
|
||||
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_srs_pdu_t);
|
||||
nfapi_nr_srs_pdu_t *srs_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].srs_pdu;
|
||||
memset(srs_pdu, 0, sizeof(nfapi_nr_srs_pdu_t));
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
|
||||
nr_configure_srs(srs_pdu, module_id, CC_id, UE_id, srs_resource);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : nr_schedule_srs
|
||||
*
|
||||
* PARAMETERS : module id
|
||||
* frame number for possible SRS reception
|
||||
*
|
||||
* DESCRIPTION : It informs the PHY layer that has an SRS to receive.
|
||||
* Only for periodic scheduling yet.
|
||||
*
|
||||
*********************************************************************/
|
||||
void nr_schedule_srs(int module_id, frame_t frame) {
|
||||
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
const NR_list_t *UE_list = &UE_info->list;
|
||||
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
|
||||
const int CC_id = 0;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
sched_ctrl->sched_srs.frame = -1;
|
||||
sched_ctrl->sched_srs.slot = -1;
|
||||
sched_ctrl->sched_srs.srs_scheduled = false;
|
||||
|
||||
if(!UE_info->Msg4_ACKed[UE_id]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NR_SRS_Config_t *srs_config = NULL;
|
||||
if (cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) {
|
||||
srs_config = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
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];
|
||||
if (srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_periodic) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the corresponding srs resource
|
||||
NR_SRS_Resource_t *srs_resource = NULL;
|
||||
for (int r1 = 0; r1 < srs_resource_set->srs_ResourceIdList->list.count; r1++) {
|
||||
for (int r2 = 0; r2 < srs_config->srs_ResourceToAddModList->list.count; r2++) {
|
||||
if ((*srs_resource_set->srs_ResourceIdList->list.array[r1] ==
|
||||
srs_config->srs_ResourceToAddModList->list.array[r2]->srs_ResourceId) &&
|
||||
(srs_config->srs_ResourceToAddModList->list.array[r2]->resourceType.present ==
|
||||
NR_SRS_Resource__resourceType_PR_periodic)) {
|
||||
srs_resource = srs_config->srs_ResourceToAddModList->list.array[r2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (srs_resource == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NR_BWP_t ubwp = sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
uint16_t period = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present];
|
||||
uint16_t offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
|
||||
|
||||
int n_slots_frame = nr_slots_per_frame[ubwp.subcarrierSpacing];
|
||||
|
||||
// Check if UE will transmit the SRS in this frame
|
||||
if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) {
|
||||
LOG_D(NR_MAC,"Scheduling SRS reception for %d.%d\n", frame, offset%n_slots_frame);
|
||||
nr_fill_nfapi_srs(module_id, CC_id, UE_id, offset%n_slots_frame, srs_resource);
|
||||
sched_ctrl->sched_srs.frame = frame;
|
||||
sched_ctrl->sched_srs.slot = offset%n_slots_frame;
|
||||
sched_ctrl->sched_srs.srs_scheduled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1408,6 +1408,15 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
if (sched_ctrl->active_ubwp==NULL && is_mixed_slot)
|
||||
return false;
|
||||
|
||||
// Avoid slots with the SRS
|
||||
const NR_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_idx = UE_list->head; UE_idx >= 0; UE_idx = UE_list->next[UE_idx]) {
|
||||
NR_sched_srs_t sched_srs = UE_info->UE_sched_ctrl[UE_idx].sched_srs;
|
||||
if(sched_srs.srs_scheduled && sched_srs.frame==sched_frame && sched_srs.slot==sched_slot) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
@@ -1649,7 +1658,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
|
||||
LOG_D(NR_MAC, "%4d.%2d Scheduling UE specific PUSCH for sched %d.%d, ul_tto_req %d.%d\n", frame, slot,
|
||||
LOG_D(NR_MAC, "%4d.%2d Scheduling UE specific PUSCH for sched %d.%d, ul_tti_req %d.%d\n", frame, slot,
|
||||
sched_pusch->frame,sched_pusch->slot,future_ul_tti_req->SFN,future_ul_tti_req->Slot);
|
||||
|
||||
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
|
||||
|
||||
@@ -190,6 +190,8 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
void nr_schedule_srs(int module_id, frame_t frame);
|
||||
|
||||
void nr_csirs_scheduling(int Mod_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
|
||||
@@ -378,6 +378,12 @@ typedef struct NR_sched_pusch {
|
||||
int time_domain_allocation;
|
||||
} NR_sched_pusch_t;
|
||||
|
||||
typedef struct NR_sched_srs {
|
||||
int frame;
|
||||
int slot;
|
||||
bool srs_scheduled;
|
||||
} NR_sched_srs_t;
|
||||
|
||||
/* PDSCH semi-static configuratio: as long as the TDA/DMRS/mcsTable remains the
|
||||
* same, there is no need to recalculate all S/L or DMRS-related parameters
|
||||
* over and over again. Hence, we store them in this struct for easy
|
||||
@@ -565,9 +571,12 @@ typedef struct {
|
||||
|
||||
/// PUSCH semi-static configuration: is not cleared across TTIs
|
||||
NR_pusch_semi_static_t pusch_semi_static;
|
||||
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
|
||||
/// Sched PUSCH: scheduling decisions, copied into HARQ and cleared every TTI
|
||||
NR_sched_pusch_t sched_pusch;
|
||||
|
||||
/// Sched SRS: scheduling decisions
|
||||
NR_sched_srs_t sched_srs;
|
||||
|
||||
/// uplink bytes that are currently scheduled
|
||||
int sched_ul_bytes;
|
||||
/// estimation of the UL buffer size
|
||||
|
||||
Reference in New Issue
Block a user