first implementation of MAC function for SSB RSRP (to be verified)
This commit is contained in:
@@ -82,6 +82,17 @@ int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
|
|||||||
return MIN_RSRP_VALUE;
|
return MIN_RSRP_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reverse_n_bits(uint8_t *value, uint16_t bitlen) {
|
||||||
|
uint16_t j;
|
||||||
|
uint8_t i;
|
||||||
|
for(j = bitlen - 1,i = 0; j > i; j--, i++) {
|
||||||
|
if(((*value>>j)&1) != ((*value>>i)&1)) {
|
||||||
|
*value ^= (1<<j);
|
||||||
|
*value ^= (1<<i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// start symbols for SSB types A,B,C,D,E
|
// start symbols for SSB types A,B,C,D,E
|
||||||
uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
|
uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ void find_period_offest_SR (NR_SchedulingRequestResourceConfig_t *SchedulingReqR
|
|||||||
void csi_period_offset(const NR_CSI_ReportConfig_t *csirep,
|
void csi_period_offset(const NR_CSI_ReportConfig_t *csirep,
|
||||||
int *period, int *offset);
|
int *period, int *offset);
|
||||||
|
|
||||||
|
void reverse_n_bits(uint8_t *value, uint16_t bitlen);
|
||||||
|
|
||||||
bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
|
bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
|
||||||
uint16_t rbSize, uint8_t mcsIndex, uint8_t mcsTable,
|
uint16_t rbSize, uint8_t mcsIndex, uint8_t mcsTable,
|
||||||
uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex,
|
uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex,
|
||||||
|
|||||||
@@ -137,6 +137,24 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
|
|||||||
frame_t frame,
|
frame_t frame,
|
||||||
int slot);
|
int slot);
|
||||||
|
|
||||||
|
uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac,
|
||||||
|
frame_t frame,
|
||||||
|
int slot,
|
||||||
|
PUCCH_sched_t *pucch);
|
||||||
|
|
||||||
|
uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||||
|
|
||||||
|
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig);
|
||||||
|
|
||||||
|
uint8_t get_rsrp_index(int rsrp);
|
||||||
|
uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp);
|
||||||
|
|
||||||
/* \brief Get payload (MAC PDU) from UE PHY
|
/* \brief Get payload (MAC PDU) from UE PHY
|
||||||
@param dl_info pointer to dl indication
|
@param dl_info pointer to dl indication
|
||||||
@param ul_time_alignment pointer to timing advance parameters
|
@param ul_time_alignment pointer to timing advance parameters
|
||||||
|
|||||||
@@ -2114,6 +2114,225 @@ int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac,
|
||||||
|
frame_t frame,
|
||||||
|
int slot,
|
||||||
|
PUCCH_sched_t *pucch) {
|
||||||
|
|
||||||
|
NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
|
||||||
|
NR_PUCCH_Config_t *pucch_Config = NULL;
|
||||||
|
int csi_bits = 0;
|
||||||
|
|
||||||
|
if(mac->cg &&
|
||||||
|
mac->cg->spCellConfig &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig) {
|
||||||
|
|
||||||
|
NR_CSI_MeasConfig_t *csi_measconfig = mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
|
||||||
|
|
||||||
|
for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||||
|
const NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||||
|
|
||||||
|
if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic){
|
||||||
|
int period, offset;
|
||||||
|
csi_period_offset(csirep, &period, &offset);
|
||||||
|
|
||||||
|
int scs;
|
||||||
|
NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
|
||||||
|
NR_BWP_UplinkCommon_t *initialUplinkBWP;
|
||||||
|
if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP;
|
||||||
|
else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
|
||||||
|
|
||||||
|
if (ubwp &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)
|
||||||
|
scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||||
|
else
|
||||||
|
scs = initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||||
|
|
||||||
|
if (bwp_id>0 &&
|
||||||
|
mac->ULbwp[bwp_id-1] &&
|
||||||
|
mac->ULbwp[bwp_id-1]->bwp_Dedicated &&
|
||||||
|
mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config &&
|
||||||
|
mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup) {
|
||||||
|
pucch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup;
|
||||||
|
}
|
||||||
|
else if (bwp_id==0 &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config &&
|
||||||
|
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||||
|
pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int n_slots_frame = nr_slots_per_frame[scs];
|
||||||
|
if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) {
|
||||||
|
|
||||||
|
NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
|
||||||
|
NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1
|
||||||
|
int n = pucchresset->resourceList.list.count;
|
||||||
|
|
||||||
|
int res_index;
|
||||||
|
for (res_index = 0; res_index < n; res_index++) {
|
||||||
|
if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AssertFatal(res_index < n,
|
||||||
|
"CSI resource not found among PUCCH resources\n");
|
||||||
|
|
||||||
|
pucch->resource_indicator = pucchcsires->pucch_Resource;
|
||||||
|
csi_bits = nr_get_csi_payload(mac, pucch, csi_measconfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertFatal(1==0,"Only periodic CSI reporting is currently implemented\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return csi_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||||
|
|
||||||
|
int n_csi_bits = 0;
|
||||||
|
|
||||||
|
AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count>0,"No CSI Report configuration available\n");
|
||||||
|
|
||||||
|
for (int csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||||
|
switch(csi_reportconfig->reportQuantity.present) {
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_none:
|
||||||
|
break;
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||||
|
n_csi_bits +=get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
|
||||||
|
break;
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||||
|
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
|
||||||
|
AssertFatal(1==0,"Measurement report based on CSI-RS not availalble\n");
|
||||||
|
default:
|
||||||
|
AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (n_csi_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||||
|
PUCCH_sched_t *pucch,
|
||||||
|
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
|
||||||
|
NR_CSI_MeasConfig_t *csi_MeasConfig) {
|
||||||
|
|
||||||
|
int nb_ssb = 0; // nb of ssb in the resource
|
||||||
|
int nb_meas = 0; // nb of ssb to report measurements on
|
||||||
|
int bits = 0;
|
||||||
|
uint32_t temp_payload = 0;
|
||||||
|
|
||||||
|
for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) {
|
||||||
|
struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
|
||||||
|
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) {
|
||||||
|
|
||||||
|
if (csi_reportconfig->groupBasedBeamReporting.present == NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled) {
|
||||||
|
if (csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS != NULL)
|
||||||
|
nb_meas = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1;
|
||||||
|
else
|
||||||
|
nb_meas = 1;
|
||||||
|
} else
|
||||||
|
nb_meas = 2;
|
||||||
|
|
||||||
|
for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
|
||||||
|
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId ==
|
||||||
|
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
|
||||||
|
|
||||||
|
///only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
|
||||||
|
nb_ssb = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertFatal(nb_ssb>0,"No SSB found in the resource set\n");
|
||||||
|
int ssbri_bits = ceil(log2(nb_ssb));
|
||||||
|
|
||||||
|
//TODO measurement of multiple SSBs at PHY and indication to MAC
|
||||||
|
if(nb_ssb>1)
|
||||||
|
LOG_E(MAC, "In current implementation only the SSB of synchronization is measured at PHY. This works only for a single SSB scenario\n");
|
||||||
|
|
||||||
|
int ssb_rsrp[2][nb_meas]; // the array contains index and RSRP of each SSB to be reported (nb_meas highest RSRPs)
|
||||||
|
|
||||||
|
//TODO replace the following 2 lines with a function to order the nb_meas highest SSB RSRPs
|
||||||
|
ssb_rsrp[0][0] = mac->mib_ssb;
|
||||||
|
ssb_rsrp[1][0] = mac->ssb_rsrp_dBm;
|
||||||
|
|
||||||
|
uint8_t ssbi;
|
||||||
|
|
||||||
|
if (ssbri_bits > 0) {
|
||||||
|
ssbi = ssb_rsrp[0][0];
|
||||||
|
reverse_n_bits(&ssbi, ssbri_bits);
|
||||||
|
temp_payload = ssbi;
|
||||||
|
bits += ssbri_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rsrp_idx = get_rsrp_index(ssb_rsrp[1][0]);
|
||||||
|
reverse_n_bits(&rsrp_idx, 7);
|
||||||
|
temp_payload |= (rsrp_idx<<bits);
|
||||||
|
bits += 7; // 7 bits for highest RSRP
|
||||||
|
|
||||||
|
// from the second SSB, differential report
|
||||||
|
for (int i=1; i<nb_meas; i++){
|
||||||
|
ssbi = ssb_rsrp[0][i];
|
||||||
|
reverse_n_bits(&ssbi, ssbri_bits);
|
||||||
|
temp_payload = ssbi;
|
||||||
|
bits += ssbri_bits;
|
||||||
|
|
||||||
|
rsrp_idx = get_rsrp_diff_index(ssb_rsrp[1][0],ssb_rsrp[1][i]);
|
||||||
|
reverse_n_bits(&rsrp_idx, 4);
|
||||||
|
temp_payload |= (rsrp_idx<<bits);
|
||||||
|
bits += 4; // 7 bits for highest RSRP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break; // resorce found
|
||||||
|
}
|
||||||
|
pucch->csi_part1_payload = temp_payload;
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns index from RSRP
|
||||||
|
// according to Table 10.1.6.1-1 in 38.133
|
||||||
|
|
||||||
|
uint8_t get_rsrp_index(int rsrp) {
|
||||||
|
|
||||||
|
int index = rsrp + 157;
|
||||||
|
if (rsrp>-44)
|
||||||
|
index = 113;
|
||||||
|
if (rsrp<-140)
|
||||||
|
index = 16;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns index from differential RSRP
|
||||||
|
// according to Table 10.1.6.1-2 in 38.133
|
||||||
|
uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp) {
|
||||||
|
|
||||||
|
int diff = best_rsrp-current_rsrp;
|
||||||
|
if (diff>30)
|
||||||
|
return 15;
|
||||||
|
else
|
||||||
|
return (diff>>1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){
|
void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
|
||||||
|
|||||||
@@ -1842,15 +1842,16 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
|
|||||||
uint16_t rnti = mac->crnti; //FIXME not sure this is valid for all pucch instances
|
uint16_t rnti = mac->crnti; //FIXME not sure this is valid for all pucch instances
|
||||||
|
|
||||||
// SR
|
// SR
|
||||||
if(trigger_periodic_scheduling_request(mac, pucch, frameP, slotP))
|
if(trigger_periodic_scheduling_request(mac, pucch, frameP, slotP)) {
|
||||||
|
O_SR = 1;
|
||||||
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
|
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
|
||||||
pucch->sr_payload = nr_ue_get_SR(module_idP,
|
pucch->sr_payload = nr_ue_get_SR(module_idP,
|
||||||
frameP,
|
frameP,
|
||||||
slotP);
|
slotP);
|
||||||
|
}
|
||||||
|
|
||||||
// CSI
|
// CSI
|
||||||
|
O_CSI = nr_get_csi_measurements(mac, frameP, slotP, pucch);
|
||||||
|
|
||||||
// ACKNACK
|
// ACKNACK
|
||||||
O_ACK = get_downlink_ack(mac, frameP, slotP, pucch);
|
O_ACK = get_downlink_ack(mac, frameP, slotP, pucch);
|
||||||
|
|||||||
@@ -820,16 +820,6 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
|||||||
}//is-triggering_beam_switch
|
}//is-triggering_beam_switch
|
||||||
}//tci handling
|
}//tci handling
|
||||||
|
|
||||||
void reverse_n_bits(uint8_t *value, uint16_t bitlen) {
|
|
||||||
uint16_t j;
|
|
||||||
uint8_t i;
|
|
||||||
for(j = bitlen - 1,i = 0; j > i; j--, i++) {
|
|
||||||
if(((*value>>j)&1) != ((*value>>i)&1)) {
|
|
||||||
*value ^= (1<<j);
|
|
||||||
*value ^= (1<<i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig,
|
void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||||
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
|
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
|
||||||
|
|||||||
Reference in New Issue
Block a user