feature: Estimate CFO from CSI-RS tracking signal

TRS resources if configured by gnb, is present in two consequtive slots
and two symbols per slot. LS estimates from the first symbol is saved
and in second symbol frequency offset and time offset is estimated. The
estimated FO is saved in UE global structure which is used in the last
TRS slot. If the FO is above a threshold, the radio's center frequency
is adjusted.

Time offset is estimated but not used because time is already tracked
using PBCH DMRS.
Signed-off-by: default avatarSakthivel Velumani <s.velumani@northeastern.edu>
parent 0dab3bb6
...@@ -215,9 +215,8 @@ static void UE_synch(void *arg) { ...@@ -215,9 +215,8 @@ static void UE_synch(void *arg) {
((ret.rx_offset << 1) / fp->samples_per_subframe * fp->slots_per_subframe) ((ret.rx_offset << 1) / fp->samples_per_subframe * fp->slots_per_subframe)
+ round((float)((ret.rx_offset << 1) % fp->samples_per_subframe) / fp->samples_per_slot0); + round((float)((ret.rx_offset << 1) % fp->samples_per_subframe) / fp->samples_per_slot0);
if (get_nrUE_params()->cont_fo_comp) { UE->freq_offset = freq_offset - UE->dl_Doppler_shift;
UE->freq_offset = freq_offset - UE->dl_Doppler_shift; if (!get_nrUE_params()->cont_fo_comp) {
} else {
// rerun with new cell parameters and frequency-offset // rerun with new cell parameters and frequency-offset
nrue_ru_set_freq(UE, ul_carrier, dl_carrier, freq_offset); nrue_ru_set_freq(UE, ul_carrier, dl_carrier, freq_offset);
} }
...@@ -711,6 +710,18 @@ static inline int get_readBlockSize(uint16_t slot, const NR_DL_FRAME_PARMS *fp) ...@@ -711,6 +710,18 @@ static inline int get_readBlockSize(uint16_t slot, const NR_DL_FRAME_PARMS *fp)
return rem_samples + next_slot_first_symbol; return rem_samples + next_slot_first_symbol;
} }
void trs_freq_correction(PHY_VARS_NR_UE *ue, int cfo)
{
if (abs(cfo) > TRS_CFO_THRESH) {
LOG_A(PHY, "CFO estimated (%d) from TRS exceeded threshold (%d). Adjusting radio CF\n", cfo, TRS_CFO_THRESH);
ue->freq_offset += cfo;
uint64_t dl_carrier;
uint64_t ul_carrier;
nr_get_carrier_frequencies(ue, &dl_carrier, &ul_carrier);
nrue_ru_set_freq(ue, ul_carrier, dl_carrier, ue->freq_offset);
}
}
void *UE_thread(void *arg) void *UE_thread(void *arg)
{ {
//this thread should be over the processing thread to keep in real time //this thread should be over the processing thread to keep in real time
......
...@@ -463,6 +463,7 @@ typedef struct { ...@@ -463,6 +463,7 @@ typedef struct {
uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
uint8_t measurement_bitmap; // bit 0 RSRP, bit 1 RI, bit 2 LI, bit 3 PMI, bit 4 CQI, bit 5 i1 uint8_t measurement_bitmap; // bit 0 RSRP, bit 1 RI, bit 2 LI, bit 3 PMI, bit 4 CQI, bit 5 i1
uint8_t last_trs_slot; // indicates to PHY if the slot is end of TRS burst
} fapi_nr_dl_config_csirs_pdu_rel15_t; } fapi_nr_dl_config_csirs_pdu_rel15_t;
typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t; typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t;
......
This diff is collapsed.
...@@ -56,6 +56,11 @@ ...@@ -56,6 +56,11 @@
// (0 + 0 * 20) % 512 = 0 // (0 + 0 * 20) % 512 = 0
#define NUM_PROCESS_SLOT_TX_BARRIERS 512 #define NUM_PROCESS_SLOT_TX_BARRIERS 512
// CSI for tracking can have up to 2 resources per slot
#define MAX_CSI_RES_SLOT 2
// Threshold to change radio frequency
#define TRS_CFO_THRESH 500
#include "impl_defs_nr.h" #include "impl_defs_nr.h"
#include "time_meas.h" #include "time_meas.h"
#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_defs.h"
...@@ -553,7 +558,8 @@ typedef struct nr_phy_data_s { ...@@ -553,7 +558,8 @@ typedef struct nr_phy_data_s {
int n_dlsch_codewords; int n_dlsch_codewords;
// Sidelink Rx action decided by MAC // Sidelink Rx action decided by MAC
sl_nr_rx_config_type_enum_t sl_rx_action; sl_nr_rx_config_type_enum_t sl_rx_action;
NR_UE_CSI_RS csirs_vars; int num_csirs;
NR_UE_CSI_RS csirs_vars[MAX_CSI_RES_SLOT];
NR_UE_CSI_IM csiim_vars; NR_UE_CSI_IM csiim_vars;
} nr_phy_data_t; } nr_phy_data_t;
......
...@@ -134,7 +134,12 @@ void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, ...@@ -134,7 +134,12 @@ void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue,
void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu); fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
c16_t trs_estimates[][1][ue->frame_parms.ofdm_symbol_size],
const int res_idx,
const int trs_sym0);
void trs_freq_correction(PHY_VARS_NR_UE *ue, int cfo);
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp); void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp);
......
...@@ -150,8 +150,14 @@ static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac, ...@@ -150,8 +150,14 @@ static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac,
phy_data->csiim_vars.active = true; phy_data->csiim_vars.active = true;
break; break;
case FAPI_NR_DL_CONFIG_TYPE_CSI_RS: case FAPI_NR_DL_CONFIG_TYPE_CSI_RS:
phy_data->csirs_vars.csirs_config_pdu = pdu->csirs_config_pdu.csirs_config_rel15; AssertFatal(phy_data->num_csirs < MAX_CSI_RES_SLOT, "CSI resources per slot exceeded limit\n");
phy_data->csirs_vars.active = true; const int c = phy_data->num_csirs;
if (phy_data->csirs_vars[c].active) {
AssertFatal(false, "Resource should not be active before its configured\n");
}
phy_data->csirs_vars[c].csirs_config_pdu = pdu->csirs_config_pdu.csirs_config_rel15;
phy_data->csirs_vars[c].active = true;
phy_data->num_csirs++;
break; break;
case FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH: case FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH:
case FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH: case FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH:
......
...@@ -1184,16 +1184,35 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ ...@@ -1184,16 +1184,35 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
} }
// do procedures for CSI-RS // do procedures for CSI-RS
if (phy_data->csirs_vars.active == 1) { {
for(int symb = 0; symb < ue->frame_parms.symbols_per_slot; symb++) { /*
if(is_csi_rs_in_symbol(phy_data->csirs_vars.csirs_config_pdu, symb)) { CSI-RS for tracking use only one port.
if (!slot_fep_map[symb]) { Number of CSI-RS resources for tracking is always 2 per slot.
nr_slot_fep(ue, &ue->frame_parms, proc->nr_slot_rx, symb, rxdataF, link_type_dl, 0, ue->common_vars.rxdata); Computed estimates from first resource is saved and used while estimating second resource.
slot_fep_map[symb] = true; */
c16_t trs_estimates[ue->frame_parms.nb_antennas_rx][1][ue->frame_parms.ofdm_symbol_size];
for (int res = 0; res < MAX_CSI_RES_SLOT; res++) {
if (phy_data->csirs_vars[res].active == 1) {
for (int symb = 0; symb < ue->frame_parms.symbols_per_slot; symb++) {
if (is_csi_rs_in_symbol(phy_data->csirs_vars[res].csirs_config_pdu, symb)) {
if (!slot_fep_map[symb]) {
nr_slot_fep(ue, &ue->frame_parms, proc->nr_slot_rx, symb, rxdataF, link_type_dl, 0, ue->common_vars.rxdata);
slot_fep_map[symb] = true;
}
}
} }
if (res > 0 && phy_data->csirs_vars[res].csirs_config_pdu.csi_type == 0) // tracking CSI
AssertFatal(phy_data->csirs_vars[res - 1].active && (phy_data->csirs_vars[res - 1].csirs_config_pdu.csi_type == 0),
"CSI-RS for tracking must have two consecutive active resources\n");
nr_ue_csi_rs_procedures(ue,
proc,
rxdataF,
&phy_data->csirs_vars[res].csirs_config_pdu,
trs_estimates,
res,
(res == 1) ? phy_data->csirs_vars[0].csirs_config_pdu.symb_l0 : -1);
} }
} }
nr_ue_csi_rs_procedures(ue, proc, rxdataF, &phy_data->csirs_vars.csirs_config_pdu);
} }
int16_t *llr[2]; int16_t *llr[2];
......
...@@ -68,3 +68,7 @@ void configure_nr_nfapi_vnf(eth_params_t params) ...@@ -68,3 +68,7 @@ void configure_nr_nfapi_vnf(eth_params_t params)
{ {
UNUSED(params); UNUSED(params);
} }
void trs_freq_correction(PHY_VARS_NR_UE *ue, int cfo)
{
}
...@@ -1114,7 +1114,8 @@ static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MA ...@@ -1114,7 +1114,8 @@ static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MA
static NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *csi_measconfig, static NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *csi_measconfig,
NR_BWP_Id_t dl_bwp_id, NR_BWP_Id_t dl_bwp_id,
NR_NZP_CSI_RS_ResourceId_t csi_id) NR_NZP_CSI_RS_ResourceId_t csi_id,
bool *is_last_res)
{ {
bool found = false; bool found = false;
for (int csi_list = 0; csi_list < csi_measconfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { for (int csi_list = 0; csi_list < csi_measconfig->csi_ResourceConfigToAddModList->list.count; csi_list++) {
...@@ -1139,14 +1140,14 @@ static NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *cs ...@@ -1139,14 +1140,14 @@ static NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *cs
AssertFatal(csi_res->nzp_CSI_RS_Resources.list.array[k], "NZP_CSI_RS_ResourceId shoulan't be NULL\n"); AssertFatal(csi_res->nzp_CSI_RS_Resources.list.array[k], "NZP_CSI_RS_ResourceId shoulan't be NULL\n");
if (csi_id == *csi_res->nzp_CSI_RS_Resources.list.array[k]) { if (csi_id == *csi_res->nzp_CSI_RS_Resources.list.array[k]) {
found = true; found = true;
*is_last_res = (k == (csi_res->nzp_CSI_RS_Resources.list.count - 1));
break; break;
} }
} }
if (found && csi_res->trs_Info) if (found && csi_res->trs_Info)
// CRI-RS for Tracking (not implemented yet) /* CRI-RS for Tracking. In this case there is no associated CSI report
// in this case we there is no associated CSI report * therefore to signal this we return a value higher than
// therefore to signal this we return a value higher than * maxNrofCSI-ResourceConfigurations. */
// maxNrofCSI-ResourceConfigurations
return NR_maxNrofCSI_ResourceConfigurations + 1; return NR_maxNrofCSI_ResourceConfigurations + 1;
else if (found) else if (found)
return csires->csi_ResourceConfigId; return csires->csi_ResourceConfigId;
...@@ -1216,7 +1217,8 @@ static void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int sl ...@@ -1216,7 +1217,8 @@ static void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int sl
csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset); csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset);
if((frame * mac->frame_structure.numb_slots_frame + slot-offset) % period != 0) if((frame * mac->frame_structure.numb_slots_frame + slot-offset) % period != 0)
continue; continue;
NR_CSI_ResourceConfigId_t csi_res_id = find_CSI_resourceconfig(csi_measconfig, dl_bwp_id, nzpcsi->nzp_CSI_RS_ResourceId); bool is_last_res = false;
NR_CSI_ResourceConfigId_t csi_res_id = find_CSI_resourceconfig(csi_measconfig, dl_bwp_id, nzpcsi->nzp_CSI_RS_ResourceId, &is_last_res);
// do not schedule reseption of this CSI-RS if not associated with current BWP // do not schedule reseption of this CSI-RS if not associated with current BWP
if(csi_res_id < 0) if(csi_res_id < 0)
continue; continue;
...@@ -1226,9 +1228,12 @@ static void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int sl ...@@ -1226,9 +1228,12 @@ static void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int sl
csirs_config_pdu->subcarrier_spacing = mu; csirs_config_pdu->subcarrier_spacing = mu;
csirs_config_pdu->cyclic_prefix = current_DL_BWP->cyclicprefix ? *current_DL_BWP->cyclicprefix : 0; csirs_config_pdu->cyclic_prefix = current_DL_BWP->cyclicprefix ? *current_DL_BWP->cyclicprefix : 0;
if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) {
/* According to 38.214 5.1.6.1.1, the number of resources indicate if one
* or two consequtive slots for TRS is used. We indicate to phy the last slot. */
csirs_config_pdu->last_trs_slot = is_last_res;
csirs_config_pdu->csi_type = 0; // TRS csirs_config_pdu->csi_type = 0; // TRS
else } else
csirs_config_pdu->csi_type = 1; // NZP-CSI-RS csirs_config_pdu->csi_type = 1; // NZP-CSI-RS
csirs_config_pdu->scramb_id = nzpcsi->scramblingID; csirs_config_pdu->scramb_id = nzpcsi->scramblingID;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment