FFO estimation and compensation optional via command line
This commit is contained in:
@@ -137,6 +137,7 @@ int set_pss_nr(int ofdm_symbol_size);
|
|||||||
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change);
|
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change);
|
||||||
int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
|
int fo_flag,
|
||||||
int *eNB_id,
|
int *eNB_id,
|
||||||
int *f_off);
|
int *f_off);
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// digital compensation of FFO for SSB symbols
|
// digital compensation of FFO for SSB symbols
|
||||||
|
if (ue->UE_fo_compensation){
|
||||||
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
|
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
|
||||||
double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
|
double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
|
||||||
|
|
||||||
@@ -217,6 +218,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
|
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* check that SSS/PBCH block is continuous inside the received buffer */
|
/* check that SSS/PBCH block is continuous inside the received buffer */
|
||||||
|
|||||||
@@ -663,6 +663,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
|
|||||||
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
|
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
|
||||||
int synchro_position;
|
int synchro_position;
|
||||||
int **rxdata = NULL;
|
int **rxdata = NULL;
|
||||||
|
int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation
|
||||||
|
|
||||||
#ifdef DBG_PSS_NR
|
#ifdef DBG_PSS_NR
|
||||||
|
|
||||||
@@ -706,6 +707,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
|
|||||||
|
|
||||||
synchro_position = pss_search_time_nr(rxdata,
|
synchro_position = pss_search_time_nr(rxdata,
|
||||||
frame_parms,
|
frame_parms,
|
||||||
|
fo_flag,
|
||||||
(int *)&PHY_vars_UE->common_vars.eNb_id,
|
(int *)&PHY_vars_UE->common_vars.eNb_id,
|
||||||
(int *)&PHY_vars_UE->common_vars.freq_offset);
|
(int *)&PHY_vars_UE->common_vars.freq_offset);
|
||||||
|
|
||||||
@@ -817,14 +819,15 @@ static inline double angle64(int64_t x)
|
|||||||
|
|
||||||
int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
|
int fo_flag,
|
||||||
int *eNB_id,
|
int *eNB_id,
|
||||||
int *f_off)
|
int *f_off)
|
||||||
{
|
{
|
||||||
unsigned int n, ar, peak_position, pss_source;
|
unsigned int n, ar, peak_position, pss_source;
|
||||||
int64_t peak_value;
|
int64_t peak_value;
|
||||||
int64_t result,result1,result2;
|
int64_t result;
|
||||||
int64_t avg[NUMBER_PSS_SEQUENCE];
|
int64_t avg[NUMBER_PSS_SEQUENCE];
|
||||||
double ffo_est;
|
double ffo_est=0;
|
||||||
|
|
||||||
|
|
||||||
unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */
|
unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */
|
||||||
@@ -894,10 +897,11 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fo_flag){
|
||||||
// fractional frequency offser computation according to Cross-correlation Synchronization Algorithm Using PSS
|
// fractional frequency offser computation according to Cross-correlation Synchronization Algorithm Using PSS
|
||||||
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th International Conference on Communications and Networking in China, 2012.
|
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th International Conference on Communications and Networking in China, 2012.
|
||||||
|
|
||||||
|
int64_t result1,result2;
|
||||||
// Computing cross-correlation at peak on half the symbol size for first half of data
|
// Computing cross-correlation at peak on half the symbol size for first half of data
|
||||||
result1 = dot_product64((short*)primary_synchro_time_nr[pss_source],
|
result1 = dot_product64((short*)primary_synchro_time_nr[pss_source],
|
||||||
(short*) &(rxdata[0][peak_position]),
|
(short*) &(rxdata[0][peak_position]),
|
||||||
@@ -922,6 +926,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
#ifdef DBG_PSS_NR
|
#ifdef DBG_PSS_NR
|
||||||
printf("ffo %lf\n",ffo_est);
|
printf("ffo %lf\n",ffo_est);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// computing absolute value of frequency offset
|
// computing absolute value of frequency offset
|
||||||
*f_off = ffo_est*frame_parms->subcarrier_spacing;
|
*f_off = ffo_est*frame_parms->subcarrier_spacing;
|
||||||
|
|||||||
@@ -983,6 +983,8 @@ typedef struct {
|
|||||||
int UE_scan;
|
int UE_scan;
|
||||||
/// \brief Indicator that UE should perform coarse scanning around carrier
|
/// \brief Indicator that UE should perform coarse scanning around carrier
|
||||||
int UE_scan_carrier;
|
int UE_scan_carrier;
|
||||||
|
/// \brief Indicator that UE should enable estimation and compensation of frequency offset
|
||||||
|
int UE_fo_compensation;
|
||||||
/// \brief Indicator that UE is synchronized to an eNB
|
/// \brief Indicator that UE is synchronized to an eNB
|
||||||
int is_synchronized;
|
int is_synchronized;
|
||||||
/// Data structure for UE process scheduling
|
/// Data structure for UE process scheduling
|
||||||
|
|||||||
@@ -462,6 +462,9 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
UE->perfect_ce = 0;
|
UE->perfect_ce = 0;
|
||||||
|
|
||||||
|
if(eps!=0.0)
|
||||||
|
UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
|
||||||
|
|
||||||
if (init_nr_ue_signal(UE, 1, 0) != 0)
|
if (init_nr_ue_signal(UE, 1, 0) != 0)
|
||||||
{
|
{
|
||||||
printf("Error at UE NR initialisation\n");
|
printf("Error at UE NR initialisation\n");
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ static char *itti_dump_file = NULL;
|
|||||||
|
|
||||||
int UE_scan = 0;
|
int UE_scan = 0;
|
||||||
int UE_scan_carrier = 0;
|
int UE_scan_carrier = 0;
|
||||||
|
int UE_fo_compensation = 0;
|
||||||
runmode_t mode = normal_txrx;
|
runmode_t mode = normal_txrx;
|
||||||
|
|
||||||
FILE *input_fd=NULL;
|
FILE *input_fd=NULL;
|
||||||
@@ -978,6 +979,7 @@ int main( int argc, char **argv ) {
|
|||||||
|
|
||||||
UE[CC_id]->UE_scan = UE_scan;
|
UE[CC_id]->UE_scan = UE_scan;
|
||||||
UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
|
UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
|
||||||
|
UE[CC_id]->UE_fo_compensation = UE_fo_compensation;
|
||||||
UE[CC_id]->mode = mode;
|
UE[CC_id]->mode = mode;
|
||||||
printf("UE[%d]->mode = %d\n",CC_id,mode);
|
printf("UE[%d]->mode = %d\n",CC_id,mode);
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
|
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
|
||||||
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
|
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
|
||||||
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
|
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
|
||||||
|
#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n"
|
||||||
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
|
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
|
||||||
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
|
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
|
||||||
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
|
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
|
||||||
@@ -135,6 +136,7 @@
|
|||||||
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
|
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
|
||||||
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
|
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
|
||||||
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
|
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
|
||||||
|
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&UE_fo_compensation, defintval:0, TYPE_INT, 0}, \
|
||||||
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
|
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
|
||||||
{"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \
|
{"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \
|
||||||
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||||
|
|||||||
Reference in New Issue
Block a user