Merge remote-tracking branch 'origin/NR_UE_cell_search' into integration_2024_w22
This commit is contained in:
@@ -706,7 +706,6 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
|
||||
void phy_term_nr_top(void)
|
||||
{
|
||||
free_ul_reference_signal_sequences();
|
||||
free_context_synchro_nr();
|
||||
}
|
||||
|
||||
static void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id)
|
||||
|
||||
@@ -109,9 +109,8 @@ void set_Lmax(NR_DL_FRAME_PARMS *fp) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) {
|
||||
|
||||
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb)
|
||||
{
|
||||
int mu = fp->numerology_index;
|
||||
int symbol = 0;
|
||||
uint8_t n, n_temp;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
|
||||
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb);
|
||||
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
|
||||
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
|
||||
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
|
||||
|
||||
@@ -61,12 +61,11 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
uint32_t sample_offset,
|
||||
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]);
|
||||
|
||||
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
int nr_slot_fep_init_sync(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
unsigned char symbol,
|
||||
int sample_offset,
|
||||
bool pbch_decoded,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
const c16_t **rxdata,
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
|
||||
int link_type);
|
||||
|
||||
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
|
||||
|
||||
@@ -203,31 +203,19 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
int nr_slot_fep_init_sync(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
unsigned char symbol,
|
||||
int sample_offset,
|
||||
bool pbch_decoded,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
const c16_t **rxdata,
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
|
||||
int link_type)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||
int Ns = proc->nr_slot_rx;
|
||||
int Ns = 0;
|
||||
|
||||
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
|
||||
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
|
||||
|
||||
unsigned int nb_prefix_samples;
|
||||
unsigned int nb_prefix_samples0;
|
||||
if (pbch_decoded) {
|
||||
nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
|
||||
}
|
||||
else {
|
||||
nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
|
||||
}
|
||||
unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
unsigned int frame_length_samples = frame_parms->samples_per_frame;
|
||||
|
||||
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
|
||||
@@ -236,10 +224,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
|
||||
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
unsigned int rx_offset = sample_offset + slot_offset;
|
||||
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
|
||||
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
|
||||
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
|
||||
rx_offset += frame_parms->ofdm_symbol_size * symbol;
|
||||
rx_offset += (frame_parms->ofdm_symbol_size + nb_prefix_samples) * symbol + nb_prefix_samples;
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
@@ -256,38 +241,29 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
// rxdata is 2 frames len
|
||||
// we have to wrap on the end
|
||||
|
||||
memcpy((void *)&tmp_dft_in[0],
|
||||
(void *)&common_vars->rxdata[aa][rx_offset],
|
||||
(frame_length_samples*2 - rx_offset) * sizeof(int32_t));
|
||||
memcpy((void *)&tmp_dft_in[frame_length_samples*2 - rx_offset],
|
||||
(void *)&common_vars->rxdata[aa][0],
|
||||
(frame_parms->ofdm_symbol_size - (frame_length_samples*2 - rx_offset)) * sizeof(int32_t));
|
||||
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], (frame_length_samples * 2 - rx_offset) * sizeof(int32_t));
|
||||
memcpy((void *)&tmp_dft_in[frame_length_samples * 2 - rx_offset],
|
||||
(void *)&rxdata[aa][0],
|
||||
(frame_parms->ofdm_symbol_size - (frame_length_samples * 2 - rx_offset)) * sizeof(int32_t));
|
||||
rxdata_ptr = (int16_t *)tmp_dft_in;
|
||||
|
||||
} else if ((rx_offset & 7) != 0) {
|
||||
|
||||
// if input to dft is not 256-bit aligned
|
||||
memcpy((void *)&tmp_dft_in[0],
|
||||
(void *)&common_vars->rxdata[aa][rx_offset],
|
||||
frame_parms->ofdm_symbol_size * sizeof(int32_t));
|
||||
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size * sizeof(int32_t));
|
||||
rxdata_ptr = (int16_t *)tmp_dft_in;
|
||||
|
||||
} else {
|
||||
|
||||
// use dft input from RX buffer directly
|
||||
rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
|
||||
|
||||
rxdata_ptr = (int16_t *)&rxdata[aa][rx_offset];
|
||||
}
|
||||
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
|
||||
dft(dftsize,
|
||||
rxdata_ptr,
|
||||
(int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
1);
|
||||
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
|
||||
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
|
||||
c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset];
|
||||
rot2.i=-rot2.i;
|
||||
|
||||
@@ -202,7 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
return(0);
|
||||
}
|
||||
|
||||
void nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink)
|
||||
void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink)
|
||||
{
|
||||
int m,m0,m1;
|
||||
uint8_t idx=0;
|
||||
|
||||
@@ -21,15 +21,13 @@
|
||||
|
||||
#include "refsig_defs_ue.h"
|
||||
|
||||
void nr_gold_pbch(PHY_VARS_NR_UE* ue)
|
||||
void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax)
|
||||
{
|
||||
unsigned int n = 0, x1 = 0, x2 = 0;
|
||||
unsigned int Nid, i_ssb, i_ssb2;
|
||||
unsigned char Lmax, l, n_hf, N_hf;
|
||||
unsigned int i_ssb, i_ssb2;
|
||||
unsigned char l, n_hf, N_hf;
|
||||
uint8_t reset;
|
||||
|
||||
Nid = ue->frame_parms.Nid_cell;
|
||||
Lmax = ue->frame_parms.Lmax;
|
||||
N_hf = (Lmax == 4)? 2:1;
|
||||
|
||||
for (n_hf = 0; n_hf < N_hf; n_hf++) {
|
||||
@@ -42,7 +40,7 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
|
||||
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
||||
|
||||
for (n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) {
|
||||
ue->nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,8 +76,17 @@
|
||||
#define SYNCF_TMP_SIZE (SYNCHRO_FFT_SIZE_MAX*IQ_SIZE)
|
||||
|
||||
void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
|
||||
void free_context_synchro_nr(void);
|
||||
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change);
|
||||
int pss_synchro_nr(const c16_t **rxdata,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size],
|
||||
int is,
|
||||
bool fo_flag,
|
||||
int target_Nid_cell,
|
||||
int *nid2,
|
||||
int *f_off,
|
||||
int *pssPeak,
|
||||
int *pssAvg);
|
||||
void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssbFirstSCS, c16_t pssTime[fp->ofdm_symbol_size]);
|
||||
int16_t *get_primary_synchro_nr2(const int nid2);
|
||||
|
||||
#endif /* PSS_NR_H */
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
|
||||
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
||||
*/
|
||||
void nr_pbch_dmrs_rx(int dmrss, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink);
|
||||
void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink);
|
||||
|
||||
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
|
||||
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
||||
@@ -51,7 +51,7 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
unsigned short nb_pdsch_rb,
|
||||
uint8_t config_type);
|
||||
|
||||
void nr_gold_pbch(PHY_VARS_NR_UE* ue);
|
||||
void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax);
|
||||
|
||||
void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
|
||||
unsigned short n_idDMRS);
|
||||
|
||||
@@ -95,11 +95,15 @@ void free_context_sss_nr(void);
|
||||
void insert_sss_nr(int16_t *sss_time,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nid2,
|
||||
int target_Nid_cell,
|
||||
int freq_offset_pss,
|
||||
int ssb_start_subcarrier,
|
||||
int *Nid_cell,
|
||||
int32_t *tot_metric,
|
||||
uint8_t *phase_max,
|
||||
int *freq_offset_sss,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP]);
|
||||
#endif /* SSS_NR_H */
|
||||
|
||||
|
||||
@@ -555,21 +555,24 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
return(0);
|
||||
}
|
||||
|
||||
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
|
||||
c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const int symbol,
|
||||
const int dmrss,
|
||||
const int Nid_cell,
|
||||
const int ssb_start_subcarrier,
|
||||
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
|
||||
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP])
|
||||
{
|
||||
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
|
||||
|
||||
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
|
||||
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
|
||||
unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
|
||||
if (ssb_offset >= fp->ofdm_symbol_size)
|
||||
ssb_offset -= fp->ofdm_symbol_size;
|
||||
|
||||
int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
|
||||
int symbol_offset = fp->ofdm_symbol_size * symbol;
|
||||
|
||||
unsigned int k = ue->frame_parms.Nid_cell % 4;
|
||||
unsigned int k = Nid_cell % 4;
|
||||
|
||||
DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%u symbol %d\n",
|
||||
proc->gNB_id,
|
||||
@@ -583,8 +586,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
|
||||
c16_t pilot[200] __attribute__((aligned(16)));
|
||||
nr_pbch_dmrs_rx(dmrss, (uint32_t *)nr_gold_pbch, pilot, false);
|
||||
c32_t computed_val = {0};
|
||||
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
|
||||
int re_offset = ssb_offset;
|
||||
c16_t *pil = pilot;
|
||||
const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
|
||||
@@ -599,49 +601,50 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
|
||||
DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
|
||||
|
||||
pil++;
|
||||
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
|
||||
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
|
||||
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
|
||||
|
||||
DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
|
||||
|
||||
pil++;
|
||||
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
|
||||
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
|
||||
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
|
||||
|
||||
DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
|
||||
|
||||
pil++;
|
||||
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
|
||||
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
|
||||
|
||||
for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) {
|
||||
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
|
||||
if (dmrss == 1 && pilot_cnt == 12) {
|
||||
pilot_cnt=48;
|
||||
re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size;
|
||||
re_offset = (re_offset + 144) % fp->ofdm_symbol_size;
|
||||
}
|
||||
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
|
||||
|
||||
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
|
||||
|
||||
pil++;
|
||||
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
|
||||
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
|
||||
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
|
||||
|
||||
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
|
||||
pil++;
|
||||
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
|
||||
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
|
||||
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
|
||||
|
||||
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
|
||||
pil++;
|
||||
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
|
||||
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
return computed_val;
|
||||
}
|
||||
|
||||
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
NR_DL_FRAME_PARMS *fp,
|
||||
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
||||
const sl_nr_ue_phy_params_t *sl_phy_params,
|
||||
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
|
||||
@@ -650,7 +653,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
int dmrss,
|
||||
uint8_t ssb_index,
|
||||
uint8_t n_hf,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
int ssb_start_subcarrier,
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
bool sidelink,
|
||||
uint16_t Nid)
|
||||
{
|
||||
@@ -659,13 +663,11 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
//int slot_pbch;
|
||||
|
||||
uint8_t nushift = 0, lastsymbol = 0, num_rbs = 0;
|
||||
uint32_t *gold_seq = NULL;
|
||||
const uint32_t *gold_seq = NULL;
|
||||
|
||||
if (sidelink) {
|
||||
AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), "symbol %d is illegal for PSBCH DM-RS \n", dmrss);
|
||||
|
||||
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
|
||||
|
||||
LOG_D(PHY, "PSBCH Channel Estimation SLSSID:%d\n", Nid);
|
||||
|
||||
gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid];
|
||||
@@ -673,16 +675,16 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL;
|
||||
|
||||
} else {
|
||||
nushift = fp->Nid_cell % 4;
|
||||
nushift = Nid % 4;
|
||||
|
||||
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
|
||||
|
||||
gold_seq = ue->nr_gold_pbch[n_hf][ssb_index];
|
||||
gold_seq = nr_gold_pbch[n_hf][ssb_index];
|
||||
lastsymbol = 2;
|
||||
num_rbs = 20;
|
||||
}
|
||||
|
||||
unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier;
|
||||
unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
|
||||
if (ssb_offset >= fp->ofdm_symbol_size)
|
||||
ssb_offset -= fp->ofdm_symbol_size;
|
||||
|
||||
@@ -739,7 +741,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
|
||||
int re_offset = ssb_offset;
|
||||
c16_t *pil = pilot;
|
||||
c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
|
||||
const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
|
||||
c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset];
|
||||
|
||||
memset(dl_ch, 0, sizeof(c16_t) * fp->ofdm_symbol_size);
|
||||
@@ -824,15 +826,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
{
|
||||
// do ifft of channel estimate
|
||||
LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
|
||||
freq2time(ue->frame_parms.ofdm_symbol_size,
|
||||
(int16_t *)&dl_ch_estimates[aarx][ch_offset],
|
||||
(int16_t *)&dl_ch_estimates_time[aarx]);
|
||||
freq2time(fp->ofdm_symbol_size, (int16_t *)&dl_ch_estimates[aarx][ch_offset], (int16_t *)&dl_ch_estimates_time[aarx]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sidelink && dmrss == lastsymbol)
|
||||
UEscopeCopy(ue, pbchDlChEstimateTime, (void *)dl_ch_estimates_time, sizeof(c16_t), fp->nb_antennas_rx, fp->ofdm_symbol_size, 0);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,15 +57,18 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
|
||||
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
|
||||
c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const int symbol,
|
||||
const int dmrss,
|
||||
const int Nid_cell,
|
||||
const int ssb_start_subcarrier,
|
||||
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
|
||||
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP]);
|
||||
|
||||
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
NR_DL_FRAME_PARMS *fp,
|
||||
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
||||
const sl_nr_ue_phy_params_t *sl_phy_params,
|
||||
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
|
||||
@@ -74,7 +77,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
int dmrss,
|
||||
uint8_t ssb_index,
|
||||
uint8_t n_hf,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
int ssb_start_subcarrier,
|
||||
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
bool sidelink,
|
||||
uint16_t Nid);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "PHY/NR_REFSIG/sss_nr.h"
|
||||
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "nr-uesoftmodem.h"
|
||||
|
||||
//static nfapi_nr_config_request_t config_t;
|
||||
//static nfapi_nr_config_request_t* config =&config_t;
|
||||
@@ -64,24 +65,35 @@ static int ssb_sort(const void *a, const void *b)
|
||||
}
|
||||
|
||||
static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int Nid_cell,
|
||||
int pbch_initial_symbol,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
int ssb_start_subcarrier,
|
||||
int *half_frame_bit,
|
||||
int *ssb_index,
|
||||
int *symbol_offset,
|
||||
fapiPbch_t *result,
|
||||
const uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
|
||||
const c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
|
||||
const int N_L = (frame_parms->Lmax == 4) ? 4 : 8;
|
||||
const int N_hf = (frame_parms->Lmax == 4) ? 2 : 1;
|
||||
NR_UE_SSB best_ssb[N_L * N_hf];
|
||||
NR_UE_SSB *current_ssb = best_ssb;
|
||||
// loops over possible pbch dmrs cases to retrieve best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
for (int hf = 0; hf < N_hf; hf++) {
|
||||
for (int l = 0; l < N_L; l++) {
|
||||
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
|
||||
cd_t cumul = {0};
|
||||
for (int i = pbch_initial_symbol; i < pbch_initial_symbol + 3; i++) {
|
||||
c32_t meas = nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, ue->nr_gold_pbch[hf][l], rxdataF);
|
||||
c32_t meas = nr_pbch_dmrs_correlation(frame_parms,
|
||||
proc,
|
||||
i,
|
||||
i - pbch_initial_symbol,
|
||||
Nid_cell,
|
||||
ssb_start_subcarrier,
|
||||
nr_gold_pbch_ref[hf][l],
|
||||
rxdataF);
|
||||
csum(cumul, cumul, meas);
|
||||
}
|
||||
*current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf, .metric = squaredMod(cumul)};
|
||||
@@ -89,19 +101,18 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
}
|
||||
}
|
||||
qsort(best_ssb, N_L * N_hf, sizeof(NR_UE_SSB), ssb_sort);
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
|
||||
const int nb_ant = frame_parms->nb_antennas_rx;
|
||||
for (NR_UE_SSB *ssb = best_ssb; ssb < best_ssb + N_L * N_hf; ssb++) {
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
// computing channel estimation for selected best ssb
|
||||
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
|
||||
__attribute__((aligned(32))) c16_t dl_ch_estimates[nb_ant][estimateSz];
|
||||
__attribute__((aligned(32))) c16_t dl_ch_estimates_time[nb_ant][frame_parms->ofdm_symbol_size];
|
||||
|
||||
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
||||
nr_pbch_channel_estimation(ue,
|
||||
&ue->frame_parms,
|
||||
nr_pbch_channel_estimation(frame_parms,
|
||||
NULL,
|
||||
nr_gold_pbch_ref,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
dl_ch_estimates_time,
|
||||
@@ -110,13 +121,27 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
i - pbch_initial_symbol,
|
||||
ssb->i_ssb,
|
||||
ssb->n_hf,
|
||||
ssb_start_subcarrier,
|
||||
rxdataF,
|
||||
false,
|
||||
frame_parms->Nid_cell);
|
||||
Nid_cell);
|
||||
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
fapiPbch_t result = {0};
|
||||
if (0 == nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, ssb->i_ssb, &result, rxdataF)) {
|
||||
if (0
|
||||
== nr_rx_pbch(NULL,
|
||||
proc,
|
||||
false,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
frame_parms,
|
||||
ssb->i_ssb,
|
||||
ssb_start_subcarrier,
|
||||
Nid_cell,
|
||||
result,
|
||||
half_frame_bit,
|
||||
ssb_index,
|
||||
symbol_offset,
|
||||
frame_parms->samples_per_frame_wCP,
|
||||
rxdataF)) {
|
||||
if (DUMP_PBCH_CH_ESTIMATES) {
|
||||
write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, nb_ant * estimateSz, 1, 1);
|
||||
write_output("pbch_ch_estimates_time.m",
|
||||
@@ -126,26 +151,32 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
1,
|
||||
1);
|
||||
}
|
||||
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
|
||||
LOG_I(PHY, "Initial sync: pbch decoded sucessfully, ssb index %d\n", *ssb_index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
|
||||
LOG_W(PHY, "Initial sync: pbch not decoded, ssb index %d\n", frame_parms->ssb_index);
|
||||
return false;
|
||||
}
|
||||
|
||||
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa)
|
||||
static void compensate_freq_offset(c16_t **x, const NR_DL_FRAME_PARMS *fp, const int offset, const int sn)
|
||||
{
|
||||
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
|
||||
double s_time = 1 / (1.0e3 * fp->samples_per_subframe); // sampling time
|
||||
double off_angle = -2 * M_PI * s_time * (offset); // offset rotation angle compensation per sample
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
nr_initial_sync_t ret = {.cell_detected = false};
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
|
||||
|
||||
LOG_D(PHY, "nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
|
||||
for (int n = sn * fp->samples_per_frame; n < (sn + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar = 0; ar < fp->nb_antennas_rx; ar++) {
|
||||
const double re = x[ar][n].r;
|
||||
const double im = x[ar][n].i;
|
||||
x[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
x[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_scan_ssb(void *arg)
|
||||
{
|
||||
/* Initial synchronisation
|
||||
*
|
||||
* 1 radio frame = 10 ms
|
||||
@@ -159,45 +190,51 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i
|
||||
* sync_pos SS/PBCH block
|
||||
*/
|
||||
|
||||
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
|
||||
__attribute__((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
|
||||
nr_ue_ssb_scan_t *ssbInfo = (nr_ue_ssb_scan_t *)arg;
|
||||
c16_t **rxdata = ssbInfo->rxdata;
|
||||
const NR_DL_FRAME_PARMS *fp = ssbInfo->fp;
|
||||
|
||||
// Generate PSS time signal for this GSCN.
|
||||
__attribute__((aligned(32))) c16_t pssTime[NUMBER_PSS_SEQUENCE][fp->ofdm_symbol_size];
|
||||
const int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
|
||||
for (int nid2 = 0; nid2 < pss_sequence; nid2++)
|
||||
generate_pss_nr_time(fp, nid2, ssbInfo->gscnInfo.ssbFirstSC, pssTime[nid2]);
|
||||
|
||||
// initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame
|
||||
// only one frame is used for symulation tools
|
||||
for (int frame_id = 0; frame_id < n_frames && !ret.cell_detected; frame_id++) {
|
||||
// only one frame is used for simulation tools
|
||||
for (int frame_id = 0; frame_id < ssbInfo->nFrames && !ssbInfo->syncRes.cell_detected; frame_id++) {
|
||||
/* process pss search on received buffer */
|
||||
sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE);
|
||||
ssbInfo->syncRes.frame_id = frame_id;
|
||||
int nid2;
|
||||
int freq_offset_pss;
|
||||
const int sync_pos = pss_synchro_nr((const c16_t **)rxdata,
|
||||
fp,
|
||||
pssTime,
|
||||
frame_id,
|
||||
ssbInfo->foFlag,
|
||||
ssbInfo->targetNidCell,
|
||||
&nid2,
|
||||
&freq_offset_pss,
|
||||
&ssbInfo->pssCorrPeakPower,
|
||||
&ssbInfo->pssCorrAvgPower);
|
||||
if (sync_pos < fp->nb_prefix_samples)
|
||||
continue;
|
||||
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
|
||||
ssbInfo->ssbOffset = sync_pos - fp->nb_prefix_samples;
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2);
|
||||
LOG_I(PHY, "sync_pos %d ssb_offset %d \n", sync_pos, ue->ssb_offset);
|
||||
#endif
|
||||
/* check that SSS/PBCH block is continuous inside the received buffer */
|
||||
if (ue->ssb_offset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) >= fp->samples_per_frame) {
|
||||
LOG_I(PHY, "Can't try to decode SSS from PSS position, will retry (PSS circular buffer wrapping): sync_pos %d\n", sync_pos);
|
||||
if (ssbInfo->ssbOffset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) >= fp->samples_per_frame) {
|
||||
LOG_D(PHY, "Can't try to decode SSS from PSS position, will retry (PSS circular buffer wrapping): sync_pos %d\n", sync_pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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 off_angle = -2 * M_PI * s_time * (ue->common_vars.freq_offset); // offset rotation angle compensation per sample
|
||||
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar = 0; ar < fp->nb_antennas_rx; ar++) {
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
if (ssbInfo->foFlag) {
|
||||
compensate_freq_offset(rxdata, fp, freq_offset_pss, frame_id);
|
||||
}
|
||||
|
||||
/* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
@@ -209,8 +246,15 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i
|
||||
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
|
||||
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
|
||||
|
||||
const uint32_t rxdataF_sz = fp->samples_per_slot_wCP;
|
||||
__attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz];
|
||||
for (int i = 0; i < NR_N_SYMBOLS_SSB; i++)
|
||||
nr_slot_fep_init_sync(ue, proc, i, frame_id * fp->samples_per_frame + ue->ssb_offset, false, rxdataF, link_type_dl);
|
||||
nr_slot_fep_init_sync(fp,
|
||||
i,
|
||||
frame_id * fp->samples_per_frame + ssbInfo->ssbOffset,
|
||||
(const c16_t **)rxdata,
|
||||
rxdataF,
|
||||
link_type_dl);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY, "Calling sss detection (normal CP)\n");
|
||||
@@ -219,69 +263,179 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i
|
||||
int freq_offset_sss = 0;
|
||||
int32_t metric_tdd_ncp = 0;
|
||||
uint8_t phase_tdd_ncp;
|
||||
ret.cell_detected = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF);
|
||||
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (freq_offset_sss && ue->UE_fo_compensation) {
|
||||
double s_time = 1 / (1.0e3 * fp->samples_per_subframe); // sampling time
|
||||
double off_angle = -2 * M_PI * s_time * freq_offset_sss; // offset rotation angle compensation per sample
|
||||
ssbInfo->syncRes.cell_detected = rx_sss_nr(fp,
|
||||
nid2,
|
||||
ssbInfo->targetNidCell,
|
||||
freq_offset_pss,
|
||||
ssbInfo->gscnInfo.ssbFirstSC,
|
||||
&ssbInfo->nidCell,
|
||||
&metric_tdd_ncp,
|
||||
&phase_tdd_ncp,
|
||||
&freq_offset_sss,
|
||||
rxdataF);
|
||||
|
||||
ssbInfo->freqOffset = freq_offset_pss + freq_offset_sss;
|
||||
|
||||
uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
||||
if (ssbInfo->syncRes.cell_detected) { // we got sss channel
|
||||
nr_gold_pbch(nr_gold_pbch_ref, ssbInfo->nidCell, fp->Lmax);
|
||||
ssbInfo->syncRes.cell_detected = nr_pbch_detection(ssbInfo->proc,
|
||||
ssbInfo->fp,
|
||||
ssbInfo->nidCell,
|
||||
1,
|
||||
ssbInfo->gscnInfo.ssbFirstSC,
|
||||
&ssbInfo->halfFrameBit,
|
||||
&ssbInfo->ssbIndex,
|
||||
&ssbInfo->symbolOffset,
|
||||
&ssbInfo->pbchResult,
|
||||
nr_gold_pbch_ref,
|
||||
rxdataF); // start pbch detection at first symbol after pss
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
int n_frames,
|
||||
int sa,
|
||||
nr_gscn_info_t gscnInfo[MAX_GSCN_BAND],
|
||||
int numGscn)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
|
||||
notifiedFIFO_t nf;
|
||||
initNotifiedFIFO(&nf);
|
||||
|
||||
// Perform SSB scanning in parallel. One GSCN per thread.
|
||||
LOG_I(NR_PHY,
|
||||
"Starting cell search with center freq: %ld, bandwidth: %d. Scanning for %d number of GSCN.\n",
|
||||
fp->dl_CarrierFreq,
|
||||
fp->N_RB_DL,
|
||||
numGscn);
|
||||
for (int s = 0; s < numGscn; s++) {
|
||||
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(nr_ue_ssb_scan_t), gscnInfo[s].gscn, &nf, &nr_scan_ssb);
|
||||
nr_ue_ssb_scan_t *ssbInfo = (nr_ue_ssb_scan_t *)NotifiedFifoData(req);
|
||||
ssbInfo->gscnInfo = gscnInfo[s];
|
||||
ssbInfo->rxdata = malloc16_clear(fp->nb_antennas_rx * sizeof(c16_t *));
|
||||
for (int ant = 0; ant < fp->nb_antennas_rx; ant++) {
|
||||
ssbInfo->rxdata[ant] = malloc16_clear((fp->samples_per_frame * 2 + fp->ofdm_symbol_size) * sizeof(c16_t));
|
||||
memcpy(ssbInfo->rxdata[ant], ue->common_vars.rxdata[ant], sizeof(c16_t) * fp->samples_per_frame * 2);
|
||||
}
|
||||
LOG_I(NR_PHY,
|
||||
"Scanning GSCN: %d, with SSB offset: %d, SSB Freq: %lf\n",
|
||||
ssbInfo->gscnInfo.gscn,
|
||||
ssbInfo->gscnInfo.ssbFirstSC,
|
||||
ssbInfo->gscnInfo.ssRef);
|
||||
ssbInfo->fp = &ue->frame_parms;
|
||||
ssbInfo->proc = proc;
|
||||
ssbInfo->syncRes.cell_detected = false;
|
||||
ssbInfo->nFrames = n_frames;
|
||||
ssbInfo->foFlag = ue->UE_fo_compensation;
|
||||
ssbInfo->targetNidCell = ue->target_Nid_cell;
|
||||
pushTpool(&get_nrUE_params()->Tpool, req);
|
||||
}
|
||||
|
||||
// Collect the scan results
|
||||
nr_ue_ssb_scan_t res = {0};
|
||||
while (numGscn) {
|
||||
notifiedFIFO_elt_t *req = pullTpool(&nf, &get_nrUE_params()->Tpool);
|
||||
nr_ue_ssb_scan_t *ssbInfo = (nr_ue_ssb_scan_t *)NotifiedFifoData(req);
|
||||
if (ssbInfo->syncRes.cell_detected) {
|
||||
LOG_A(NR_PHY,
|
||||
"Cell Detected with GSCN: %d, SSB SC offset: %d, SSB Ref: %lf, PSS Corr peak: %d dB, PSS Corr Average: %d\n",
|
||||
ssbInfo->gscnInfo.gscn,
|
||||
ssbInfo->gscnInfo.ssbFirstSC,
|
||||
ssbInfo->gscnInfo.ssRef,
|
||||
ssbInfo->pssCorrPeakPower,
|
||||
ssbInfo->pssCorrAvgPower);
|
||||
if (!res.syncRes.cell_detected) { // take the first cell detected
|
||||
res = *ssbInfo;
|
||||
}
|
||||
}
|
||||
for (int ant = 0; ant < fp->nb_antennas_rx; ant++) {
|
||||
free(ssbInfo->rxdata[ant]);
|
||||
}
|
||||
free(ssbInfo->rxdata);
|
||||
delNotifiedFIFO_elt(req);
|
||||
numGscn--;
|
||||
}
|
||||
|
||||
// Set globals based on detected cell
|
||||
if (res.syncRes.cell_detected) {
|
||||
fp->Nid_cell = res.nidCell;
|
||||
fp->ssb_start_subcarrier = res.gscnInfo.ssbFirstSC;
|
||||
fp->half_frame_bit = res.halfFrameBit;
|
||||
fp->ssb_index = res.ssbIndex;
|
||||
ue->symbol_offset = res.symbolOffset;
|
||||
ue->common_vars.freq_offset = res.freqOffset;
|
||||
}
|
||||
|
||||
// In initial sync, we indicate PBCH to MAC after the scan is complete.
|
||||
nr_downlink_indication_t dl_indication;
|
||||
fapi_nr_rx_indication_t rx_ind = {0};
|
||||
uint16_t number_pdus = 1;
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind,
|
||||
FAPI_NR_RX_PDU_TYPE_SSB,
|
||||
ue,
|
||||
NULL,
|
||||
NULL,
|
||||
number_pdus,
|
||||
proc,
|
||||
res.syncRes.cell_detected ? (void *)&res.pbchResult : NULL,
|
||||
NULL);
|
||||
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
|
||||
|
||||
LOG_D(PHY, "nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
|
||||
|
||||
if (res.syncRes.cell_detected) {
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (res.freqOffset && ue->UE_fo_compensation) {
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar = 0; ar < fp->nb_antennas_rx; ar++) {
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
ue->common_vars.freq_offset += freq_offset_sss;
|
||||
compensate_freq_offset(ue->common_vars.rxdata, fp, res.freqOffset, res.syncRes.frame_id);
|
||||
}
|
||||
nr_gold_pbch(ue->nr_gold_pbch, fp->Nid_cell, fp->Lmax);
|
||||
// sync at symbol ue->symbol_offset
|
||||
// computing the offset wrt the beginning of the frame
|
||||
int mu = fp->numerology_index;
|
||||
// number of symbols with different prefix length
|
||||
// every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
|
||||
int n_symb_prefix0 = (res.symbolOffset / (7 * (1 << mu))) + 1;
|
||||
const int sync_pos_frame = n_symb_prefix0 * (fp->ofdm_symbol_size + fp->nb_prefix_samples0)
|
||||
+ (res.symbolOffset - n_symb_prefix0) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of
|
||||
// the n_frames we got sync
|
||||
ue->init_sync_frame = n_frames - 1 - res.syncRes.frame_id;
|
||||
|
||||
// compute the scramblingID_pdcch and the gold pdcch
|
||||
ue->scramblingID_pdcch = fp->Nid_cell;
|
||||
nr_gold_pdcch(ue, fp->Nid_cell);
|
||||
|
||||
// compute the scrambling IDs for PDSCH DMRS
|
||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_dlsch[i] = fp->Nid_cell;
|
||||
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
||||
}
|
||||
|
||||
if (ret.cell_detected) { // we got sss channel
|
||||
nr_gold_pbch(ue);
|
||||
ret.cell_detected = nr_pbch_detection(proc, ue, 1, rxdataF); // start pbch detection at first symbol after pss
|
||||
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
|
||||
|
||||
// initialize the pusch dmrs
|
||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_ulsch[i] = fp->Nid_cell;
|
||||
nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i);
|
||||
}
|
||||
|
||||
if (ret.cell_detected) {
|
||||
// sync at symbol ue->symbol_offset
|
||||
// computing the offset wrt the beginning of the frame
|
||||
int mu = fp->numerology_index;
|
||||
// number of symbols with different prefix length
|
||||
// every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
|
||||
int n_symb_prefix0 = (ue->symbol_offset / (7 * (1 << mu))) + 1;
|
||||
sync_pos_frame = n_symb_prefix0 * (fp->ofdm_symbol_size + fp->nb_prefix_samples0)
|
||||
+ (ue->symbol_offset - n_symb_prefix0) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of
|
||||
// the n_frames we got sync
|
||||
ue->init_sync_frame = n_frames - 1 - frame_id;
|
||||
|
||||
// compute the scramblingID_pdcch and the gold pdcch
|
||||
ue->scramblingID_pdcch = fp->Nid_cell;
|
||||
nr_gold_pdcch(ue, fp->Nid_cell);
|
||||
|
||||
// compute the scrambling IDs for PDSCH DMRS
|
||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_dlsch[i] = fp->Nid_cell;
|
||||
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
||||
}
|
||||
|
||||
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
|
||||
|
||||
// initialize the pusch dmrs
|
||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_ulsch[i] = fp->Nid_cell;
|
||||
nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i);
|
||||
}
|
||||
|
||||
// we also need to take into account the shift by samples_per_frame in case the if is true
|
||||
if (ue->ssb_offset < sync_pos_frame) {
|
||||
ret.rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
|
||||
ue->init_sync_frame += 1;
|
||||
} else
|
||||
ret.rx_offset = ue->ssb_offset - sync_pos_frame;
|
||||
}
|
||||
// we also need to take into account the shift by samples_per_frame in case the if is true
|
||||
if (res.ssbOffset < sync_pos_frame) {
|
||||
res.syncRes.rx_offset = fp->samples_per_frame - sync_pos_frame + res.ssbOffset;
|
||||
ue->init_sync_frame += 1;
|
||||
} else
|
||||
res.syncRes.rx_offset = res.ssbOffset - sync_pos_frame;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,
|
||||
@@ -292,74 +446,47 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i
|
||||
ret.cell_detected,
|
||||
ret.rx_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Consider this is a false detection if the offset is > 1000 Hz
|
||||
Not to be used now that offest estimation is in place
|
||||
if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
|
||||
{
|
||||
ret=-1;
|
||||
LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
|
||||
}*/
|
||||
|
||||
if (ret.cell_detected) { // PBCH found so indicate sync to higher layers and configure frame parameters
|
||||
|
||||
//#ifdef DEBUG_INITIAL_SYNCH
|
||||
|
||||
LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n", ue->Mod_id, ret.rx_offset);
|
||||
|
||||
//#endif
|
||||
|
||||
if (ue->UE_scan_carrier == 0) {
|
||||
#if UE_AUTOTEST_TRACE
|
||||
LOG_I(PHY,
|
||||
"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n",
|
||||
ue->Mod_id,
|
||||
ue->rx_offset,
|
||||
ue->common_vars.freq_offset);
|
||||
#endif
|
||||
|
||||
// send sync status to higher layers later when timing offset converge to target timing
|
||||
}
|
||||
|
||||
LOG_I(PHY, "[UE %d] Measured Carrier Frequency offset %d Hz\n", ue->Mod_id, ue->common_vars.freq_offset);
|
||||
} else {
|
||||
if (res.syncRes.cell_detected) {
|
||||
LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n", ue->Mod_id, res.syncRes.rx_offset);
|
||||
LOG_I(PHY, "[UE %d] Measured Carrier Frequency offset %d Hz\n", ue->Mod_id, res.freqOffset);
|
||||
} else {
|
||||
#ifdef DEBUG_INITIAL_SYNC
|
||||
LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id);
|
||||
LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2);
|
||||
LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id,
|
||||
frame_parms->Nid_cell,frame_parms->frame_type);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// gain control
|
||||
if (!ret.cell_detected) { // we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
|
||||
int rx_power = 0;
|
||||
if (!res.syncRes.cell_detected) { // we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
|
||||
int rx_power = 0;
|
||||
|
||||
// do a measurement on the best guess of the PSS
|
||||
// for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
|
||||
// rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2],
|
||||
// frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
|
||||
// do a measurement on the best guess of the PSS
|
||||
// for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
|
||||
// rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2],
|
||||
// frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
|
||||
|
||||
/*
|
||||
// do a measurement on the full frame
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
|
||||
rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0],
|
||||
frame_parms->samples_per_subframe*10);
|
||||
*/
|
||||
/*
|
||||
// do a measurement on the full frame
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
|
||||
rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0],
|
||||
frame_parms->samples_per_subframe*10);
|
||||
*/
|
||||
|
||||
// we might add a low-pass filter here later
|
||||
ue->measurements.rx_power_avg[0] = rx_power/fp->nb_antennas_rx;
|
||||
// we might add a low-pass filter here later
|
||||
ue->measurements.rx_power_avg[0] = rx_power / fp->nb_antennas_rx;
|
||||
|
||||
ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
|
||||
ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY, "[UE%d] Initial sync : Estimated power: %d dB\n", ue->Mod_id, ue->measurements.rx_power_avg_dB[0]);
|
||||
#endif
|
||||
} else {
|
||||
LOG_A(PHY, "Initial sync successful\n");
|
||||
}
|
||||
} else {
|
||||
LOG_A(PHY, "Initial sync successful\n");
|
||||
}
|
||||
// exit_fun("debug exit");
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
|
||||
return ret;
|
||||
return res.syncRes;
|
||||
}
|
||||
|
||||
@@ -462,8 +462,9 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t decoded_output[4];
|
||||
|
||||
for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) {
|
||||
nr_pbch_channel_estimation(UE,
|
||||
frame_parms,
|
||||
nr_pbch_channel_estimation(frame_parms,
|
||||
&UE->SL_UE_PHY_PARAMS,
|
||||
UE->nr_gold_pbch,
|
||||
rxdataF_sz,
|
||||
dl_ch_estimates,
|
||||
dl_ch_estimates_time,
|
||||
@@ -472,6 +473,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
|
||||
symbol,
|
||||
0,
|
||||
0,
|
||||
frame_parms->ssb_start_subcarrier,
|
||||
rxdataF,
|
||||
1,
|
||||
rx_slss_id);
|
||||
|
||||
@@ -47,14 +47,15 @@
|
||||
#define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7])
|
||||
|
||||
static uint16_t nr_pbch_extract(uint32_t rxdataF_sz,
|
||||
c16_t rxdataF[][rxdataF_sz],
|
||||
const c16_t rxdataF[][rxdataF_sz],
|
||||
const int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
uint32_t symbol,
|
||||
uint32_t s_offset,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
int ssb_start_subcarrier,
|
||||
const NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
uint16_t rb;
|
||||
uint8_t i, j, aarx;
|
||||
@@ -64,9 +65,9 @@ static uint16_t nr_pbch_extract(uint32_t rxdataF_sz,
|
||||
symbol);
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
|
||||
unsigned int rx_offset = frame_parms->first_carrier_offset + ssb_start_subcarrier;
|
||||
rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size);
|
||||
struct complex16 *rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
|
||||
const struct complex16 *rxF = &rxdataF[aarx][(symbol + s_offset) * frame_parms->ofdm_symbol_size];
|
||||
struct complex16 *rxF_ext = rxdataF_ext[aarx];
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("extract_rbs (nushift %d): rx_offset=%d, symbol %u\n",
|
||||
@@ -203,8 +204,9 @@ static uint16_t nr_pbch_extract(uint32_t rxdataF_sz,
|
||||
|
||||
//compute average channel_level on each (TX,RX) antenna pair
|
||||
int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nb_re) {
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nb_re)
|
||||
{
|
||||
int16_t nb_rb=nb_re/12;
|
||||
simde__m128i avg128;
|
||||
simde__m128i *dl_ch128;
|
||||
@@ -244,7 +246,7 @@ void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER
|
||||
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
int nb_re,
|
||||
struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t output_shift)
|
||||
{
|
||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
@@ -365,35 +367,31 @@ const uint8_t pbch_deinterleaving_pattern[32] = {28, 0, 31, 30, 7, 29, 25, 27,
|
||||
|
||||
int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
bool is_synchronized,
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t i_ssb,
|
||||
int ssb_start_subcarrier,
|
||||
int Nid_cell,
|
||||
fapiPbch_t *result,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
int *half_frame_bit,
|
||||
int *ssb_index,
|
||||
int *ret_symbol_offset,
|
||||
int rxdataFSize,
|
||||
const struct complex16 rxdataF[][rxdataFSize])
|
||||
{
|
||||
int max_h=0;
|
||||
int symbol;
|
||||
// uint8_t pbch_a[64];
|
||||
// FT ?? cppcheck doesn't like pbch_a allocation because of line 525..and i don't get what this variable is for..
|
||||
// uint8_t *pbch_a = malloc(sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||
uint8_t Lmax=frame_parms->Lmax;
|
||||
int M = NR_POLAR_PBCH_E;
|
||||
int nushift = (Lmax == 4) ? i_ssb & 3 : i_ssb & 7;
|
||||
//uint16_t crc;
|
||||
//unsigned short idx_demod =0;
|
||||
uint32_t decoderState=0;
|
||||
//uint8_t decoderListSize = 8, pathMetricAppr = 0;
|
||||
//time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
|
||||
//time_stats_t path_metric,sorting,update_LLR;
|
||||
// FT ?? cppcheck fix memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||
//printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell);
|
||||
int16_t pbch_e_rx[960]= {0}; //Fixme: previous version erase only NR_POLAR_PBCH_E bytes
|
||||
int16_t pbch_unClipped[960]= {0};
|
||||
int pbch_e_rx_idx=0;
|
||||
int symbol_offset=1;
|
||||
|
||||
if (ue->is_synchronized > 0)
|
||||
if (is_synchronized)
|
||||
symbol_offset=nr_get_ssb_start_symbol(frame_parms, i_ssb)%(frame_parms->symbols_per_slot);
|
||||
else
|
||||
symbol_offset=0;
|
||||
@@ -411,7 +409,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
__attribute__ ((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
|
||||
memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext);
|
||||
nr_pbch_extract(ue->frame_parms.samples_per_slot_wCP,
|
||||
nr_pbch_extract(frame_parms->samples_per_slot_wCP,
|
||||
rxdataF,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
@@ -419,6 +417,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
dl_ch_estimates_ext,
|
||||
symbol,
|
||||
symbol_offset,
|
||||
ssb_start_subcarrier,
|
||||
frame_parms);
|
||||
#ifdef DEBUG_PBCH
|
||||
LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size);
|
||||
@@ -457,8 +456,10 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
// legacy code use int16, but it is complex16
|
||||
UEscopeCopy(ue, pbchRxdataF_comp, pbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, pbch_e_rx_idx / 2, 0);
|
||||
UEscopeCopy(ue, pbchLlr, pbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, pbch_e_rx_idx, 0);
|
||||
if (ue) {
|
||||
UEscopeCopy(ue, pbchRxdataF_comp, pbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, pbch_e_rx_idx / 2, 0);
|
||||
UEscopeCopy(ue, pbchLlr, pbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, pbch_e_rx_idx, 0);
|
||||
}
|
||||
#ifdef DEBUG_PBCH
|
||||
for (int cnt = 0; cnt < 864 ; cnt++)
|
||||
printf("pbch rx llr %d\n", *(pbch_e_rx + cnt));
|
||||
@@ -467,23 +468,29 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041;
|
||||
uint32_t pbch_a_interleaved=0;
|
||||
uint32_t pbch_a_prime=0;
|
||||
nr_pbch_unscrambling(pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_E,
|
||||
nr_pbch_unscrambling(pbch_e_rx, Nid_cell, nushift, M, NR_POLAR_PBCH_E,
|
||||
0, 0, pbch_a_prime, &pbch_a_interleaved);
|
||||
//polar decoding de-rate matching
|
||||
uint64_t tmp=0;
|
||||
decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&tmp,0,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
|
||||
const uint32_t decoderState = polar_decoder_int16(pbch_e_rx,
|
||||
(uint64_t *)&tmp,
|
||||
0,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
NR_POLAR_PBCH_AGGREGATION_LEVEL);
|
||||
pbch_a_prime = tmp;
|
||||
|
||||
nr_downlink_indication_t dl_indication;
|
||||
fapi_nr_rx_indication_t rx_ind = {0};
|
||||
uint16_t number_pdus = 1;
|
||||
|
||||
if(decoderState) {
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL, NULL);
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
if (decoderState) {
|
||||
if (ue) { // decoding failed in synced state
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL, NULL);
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
}
|
||||
return(decoderState);
|
||||
}
|
||||
// printf("polar decoder output 0x%08x\n",pbch_a_prime);
|
||||
@@ -494,7 +501,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
|
||||
nushift = ((pbch_a_prime>>24)&1) ^ (((pbch_a_prime>>6)&1)<<1);
|
||||
pbch_a_interleaved=0;
|
||||
nr_pbch_unscrambling(pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
nr_pbch_unscrambling(pbch_e_rx, Nid_cell, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
1, unscrambling_mask, pbch_a_prime, &pbch_a_interleaved);
|
||||
//printf("nushift %d sfn 3rd %d 2nd %d", nushift,((pbch_a_prime>>6)&1), ((pbch_a_prime>>24)&1) );
|
||||
//payload deinterleaving
|
||||
@@ -514,19 +521,19 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
for (int i=0; i<3; i++)
|
||||
result->decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff);
|
||||
|
||||
frame_parms->half_frame_bit = (result->xtra_byte>>4)&0x01; // computing the half frame index from the extra byte
|
||||
frame_parms->ssb_index = i_ssb; // ssb index corresponds to i_ssb for Lmax = 4,8
|
||||
|
||||
|
||||
*half_frame_bit = (result->xtra_byte >> 4) & 0x01; // computing the half frame index from the extra byte
|
||||
*ssb_index = i_ssb; // ssb index corresponds to i_ssb for Lmax = 4,8
|
||||
|
||||
if (Lmax == 64) { // for Lmax = 64 ssb index 4th,5th and 6th bits are in extra byte
|
||||
for (int i=0; i<3; i++)
|
||||
frame_parms->ssb_index += (((result->xtra_byte>>(7-i))&0x01)<<(3+i));
|
||||
*ssb_index += (((result->xtra_byte >> (7 - i)) & 0x01) << (3 + i));
|
||||
}
|
||||
|
||||
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,frame_parms->ssb_index);
|
||||
*ret_symbol_offset = nr_get_ssb_start_symbol(frame_parms, *ssb_index);
|
||||
|
||||
if (frame_parms->half_frame_bit)
|
||||
ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
|
||||
if (*half_frame_bit)
|
||||
*ret_symbol_offset += (frame_parms->slots_per_frame >> 1) * frame_parms->symbols_per_slot;
|
||||
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("xtra_byte %x payload %x\n", result->xtra_byte, payload);
|
||||
@@ -538,11 +545,13 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
#endif
|
||||
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, (void *)result, NULL);
|
||||
if (ue) {
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, (void *)result, NULL);
|
||||
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -291,12 +291,19 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
|
||||
|
||||
int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const int estimateSz,
|
||||
bool is_synchronized,
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t i_ssb,
|
||||
int ssb_start_subcarrier,
|
||||
int Nid_cell,
|
||||
fapiPbch_t *result,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
int *half_frame_bit,
|
||||
int *ssb_index,
|
||||
int *ret_symbol_offset,
|
||||
int rxdataFSize,
|
||||
const struct complex16 rxdataF[][rxdataFSize]);
|
||||
|
||||
#ifndef modOrder
|
||||
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
|
||||
@@ -319,11 +326,12 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
@param n_frames
|
||||
@param sa current running mode
|
||||
*/
|
||||
typedef struct {
|
||||
bool cell_detected;
|
||||
int rx_offset;
|
||||
} nr_initial_sync_t;
|
||||
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa);
|
||||
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
PHY_VARS_NR_UE *phy_vars_ue,
|
||||
int n_frames,
|
||||
int sa,
|
||||
nr_gscn_info_t gscnInfo[MAX_GSCN_BAND],
|
||||
int numGscn);
|
||||
|
||||
/*!
|
||||
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the
|
||||
@@ -435,13 +443,13 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
|
||||
|
||||
// Reuse already existing PBCH functions
|
||||
int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nb_re);
|
||||
void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
int nb_re,
|
||||
struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t output_shift);
|
||||
void nr_pbch_unscrambling(int16_t *demod_pbch_e,
|
||||
uint16_t Nid,
|
||||
|
||||
@@ -50,10 +50,19 @@
|
||||
|
||||
//#define DBG_PSS_NR
|
||||
static time_stats_t generic_time[TIME_LAST];
|
||||
static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is);
|
||||
static int pss_search_time_nr(const c16_t **rxdata,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size],
|
||||
bool fo_flag,
|
||||
int is,
|
||||
int target_Nid_cell,
|
||||
int *nid2,
|
||||
int *f_off,
|
||||
int *pssPeak,
|
||||
int *pssAvg);
|
||||
|
||||
static int16_t *primary_synchro_nr2[NUMBER_PSS_SEQUENCE] = {0};
|
||||
static c16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE] = {0};
|
||||
static int16_t primary_synchro_nr2[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0};
|
||||
static c16_t primary_synchro[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0};
|
||||
int16_t *get_primary_synchro_nr2(const int nid2)
|
||||
{
|
||||
return primary_synchro_nr2[nid2];
|
||||
@@ -80,7 +89,6 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2)
|
||||
int16_t d_pss[LENGTH_PSS_NR];
|
||||
int16_t x[LENGTH_PSS_NR];
|
||||
|
||||
c16_t primary_synchro[LENGTH_PSS_NR] = {0};
|
||||
int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */
|
||||
|
||||
#define INITIAL_PSS_NR (7)
|
||||
@@ -98,7 +106,7 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2)
|
||||
|
||||
/* PSS is directly mapped to subcarrier without modulation 38.211 */
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
primary_synchro[i].r = (d_pss[i] * SHRT_MAX) >> SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
|
||||
primary_synchro[N_ID_2][i].r = (d_pss[i] * SHRT_MAX) >> SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
|
||||
primary_synchro2[i] = d_pss[i];
|
||||
}
|
||||
|
||||
@@ -115,6 +123,7 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2)
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* call of IDFT should be done with ordered input as below
|
||||
*
|
||||
@@ -137,21 +146,22 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2)
|
||||
*
|
||||
* sample 0 is for continuous frequency which is used here
|
||||
*/
|
||||
|
||||
void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssbFirstSCS, c16_t pssTime[fp->ofdm_symbol_size])
|
||||
{
|
||||
unsigned int subcarrier_start = get_softmodem_params()->sl_mode == 0 ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL;
|
||||
unsigned int k = fp->first_carrier_offset + fp->ssb_start_subcarrier + subcarrier_start;
|
||||
unsigned int k = fp->first_carrier_offset + ssbFirstSCS + subcarrier_start;
|
||||
if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size;
|
||||
c16_t synchroF_tmp[fp->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
memset(synchroF_tmp, 0, sizeof(synchroF_tmp));
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
synchroF_tmp[k % fp->ofdm_symbol_size] = primary_synchro[i];
|
||||
synchroF_tmp[k % fp->ofdm_symbol_size] = primary_synchro[N_ID_2][i];
|
||||
k++;
|
||||
}
|
||||
|
||||
/* IFFT will give temporal signal of Pss */
|
||||
idft((int16_t)get_idft(fp->ofdm_symbol_size),
|
||||
(int16_t *)synchroF_tmp, /* complex input but legacy type is wrong*/
|
||||
(int16_t *)primary_synchro_time_nr[N_ID_2], /* complex output */
|
||||
(int16_t *)pssTime, /* complex output */
|
||||
1); /* scaling factor */
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
@@ -239,34 +249,10 @@ static void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
AssertFatal(frame_parms_ue->ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n", frame_parms_ue->ofdm_symbol_size);
|
||||
int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
|
||||
for (int i = 0; i < pss_sequence; i++) {
|
||||
primary_synchro_nr2[i] = malloc16_clear(LENGTH_PSS_NR * sizeof(int16_t));
|
||||
AssertFatal(primary_synchro_nr2[i], "Fatal memory allocation problem \n");
|
||||
primary_synchro_time_nr[i] = malloc16_clear(frame_parms_ue->ofdm_symbol_size * sizeof(c16_t));
|
||||
AssertFatal(primary_synchro_time_nr[i], "Fatal memory allocation problem \n");
|
||||
generate_pss_nr(frame_parms_ue,i);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : free_context_pss_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : free context related to pss
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static void free_context_pss_nr(void)
|
||||
{
|
||||
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
|
||||
free_and_zero(primary_synchro_nr2[i]);
|
||||
free_and_zero(primary_synchro_time_nr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : init_context_synchro_nr
|
||||
@@ -286,23 +272,6 @@ void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
init_context_sss_nr(AMP);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : free_context_synchro_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : free context for pss and sss
|
||||
*
|
||||
* DESCRIPTION : deallocate memory of synchronisation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void free_context_synchro_nr(void)
|
||||
{
|
||||
free_context_pss_nr();
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : set_frame_context_pss_nr
|
||||
@@ -321,8 +290,6 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change
|
||||
frame_parms_ue->ofdm_symbol_size = (frame_parms_ue->ofdm_symbol_size / rate_change);
|
||||
frame_parms_ue->samples_per_subframe = (frame_parms_ue->samples_per_subframe / rate_change);
|
||||
|
||||
free_context_pss_nr();
|
||||
|
||||
/* pss reference have to be rebuild with new parameters ie ofdm symbol size */
|
||||
init_context_synchro_nr(frame_parms_ue);
|
||||
|
||||
@@ -348,8 +315,6 @@ void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_ch
|
||||
frame_parms_ue->ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size * rate_change;
|
||||
frame_parms_ue->samples_per_subframe = frame_parms_ue->samples_per_subframe * rate_change;
|
||||
|
||||
free_context_pss_nr();
|
||||
|
||||
/* pss reference have to be rebuild with new parameters ie ofdm symbol size */
|
||||
init_context_synchro_nr(frame_parms_ue);
|
||||
#ifdef SYNCHRO_DECIMAT
|
||||
@@ -420,13 +385,17 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
|
||||
int pss_synchro_nr(const c16_t **rxdata,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size],
|
||||
int is,
|
||||
bool fo_flag,
|
||||
int target_Nid_cell,
|
||||
int *nid2,
|
||||
int *f_off,
|
||||
int *pssPeak,
|
||||
int *pssAvg)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
|
||||
int synchro_position;
|
||||
c16_t **rxdata = NULL;
|
||||
int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SYNCHRO_NR, VCD_FUNCTION_IN);
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
@@ -434,24 +403,6 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
|
||||
|
||||
#endif
|
||||
|
||||
if (rate_change != 1) {
|
||||
|
||||
rxdata = (c16_t**)malloc16(frame_parms->nb_antennas_rx * sizeof(c16_t*));
|
||||
|
||||
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
rxdata[aa] = (c16_t*)malloc16_clear((frame_parms->samples_per_frame + 8192) * sizeof(c16_t));
|
||||
}
|
||||
#ifdef SYNCHRO_DECIMAT
|
||||
|
||||
decimation_synchro_nr(PHY_vars_UE, rate_change, rxdata);
|
||||
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
||||
rxdata = PHY_vars_UE->common_vars.rxdata;
|
||||
}
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame,1,1);
|
||||
@@ -468,7 +419,8 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_IN);
|
||||
|
||||
synchro_position = pss_search_time_nr(rxdata, PHY_vars_UE, fo_flag, is);
|
||||
int synchro_position =
|
||||
pss_search_time_nr(rxdata, frame_parms, pssTime, fo_flag, is, target_Nid_cell, nid2, f_off, pssPeak, pssAvg);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_OUT);
|
||||
|
||||
@@ -480,7 +432,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
|
||||
|
||||
#ifndef NR_UNIT_TEST
|
||||
|
||||
LOG_I(PHY,"PSS execution duration %4d microseconds \n", duration_ms);
|
||||
LOG_D(PHY,"PSS execution duration %4d microseconds \n", duration_ms);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -507,8 +459,6 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
|
||||
return synchro_position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pss_search_time_nr
|
||||
@@ -559,11 +509,17 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is)
|
||||
static int pss_search_time_nr(const c16_t **rxdata,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size],
|
||||
bool fo_flag,
|
||||
int is,
|
||||
int target_Nid_cell,
|
||||
int *nid2,
|
||||
int *f_off,
|
||||
int *pssPeak,
|
||||
int *pssAvg)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
int *nid2 = (int *)&ue->common_vars.nid2;
|
||||
int *f_off = (int *)&ue->common_vars.freq_offset;
|
||||
unsigned int n, ar, peak_position, pss_source;
|
||||
int64_t peak_value;
|
||||
int64_t avg[NUMBER_PSS_SEQUENCE] = {0};
|
||||
@@ -587,8 +543,8 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
|
||||
int max_size = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
|
||||
for (int j = 0; j < max_size; j++)
|
||||
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
|
||||
maxval = max(maxval, abs(primary_synchro_time_nr[j][i].r));
|
||||
maxval = max(maxval, abs(primary_synchro_time_nr[j][i].i));
|
||||
maxval = max(maxval, abs(pssTime[j][i].r));
|
||||
maxval = max(maxval, abs(pssTime[j][i].i));
|
||||
}
|
||||
int shift = log2_approx(maxval);//*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*2);
|
||||
|
||||
@@ -598,8 +554,8 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
|
||||
|
||||
uint16_t pss_index_start = 0;
|
||||
uint16_t pss_index_end = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
|
||||
if (ue->target_Nid_cell != -1) {
|
||||
pss_index_start = GET_NID2(ue->target_Nid_cell);
|
||||
if (target_Nid_cell != -1) {
|
||||
pss_index_start = GET_NID2(target_Nid_cell);
|
||||
pss_index_end = pss_index_start + 1;
|
||||
}
|
||||
|
||||
@@ -612,7 +568,7 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
|
||||
for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
|
||||
|
||||
/* perform correlation of rx data and pss sequence ie it is a dot product */
|
||||
const c32_t result = dot_product(primary_synchro_time_nr[pss_index],
|
||||
const c32_t result = dot_product(pssTime[pss_index],
|
||||
&(rxdata[ar][n + is * frame_parms->samples_per_frame]),
|
||||
frame_parms->ofdm_symbol_size,
|
||||
shift);
|
||||
@@ -645,13 +601,13 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
|
||||
// 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.
|
||||
|
||||
// Computing cross-correlation at peak on half the symbol size for first half of data
|
||||
c32_t r1 = dot_product(primary_synchro_time_nr[pss_source],
|
||||
c32_t r1 = dot_product(pssTime[pss_source],
|
||||
&(rxdata[0][peak_position + is * frame_parms->samples_per_frame]),
|
||||
frame_parms->ofdm_symbol_size >> 1,
|
||||
shift);
|
||||
// Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size
|
||||
// as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
|
||||
c32_t r2 = dot_product(primary_synchro_time_nr[pss_source] + (frame_parms->ofdm_symbol_size >> 1),
|
||||
c32_t r2 = dot_product(pssTime[pss_source] + (frame_parms->ofdm_symbol_size >> 1),
|
||||
&(rxdata[0][peak_position + is * frame_parms->samples_per_frame]) + (frame_parms->ofdm_symbol_size >> 1),
|
||||
frame_parms->ofdm_symbol_size >> 1,
|
||||
shift);
|
||||
@@ -671,8 +627,10 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
|
||||
avg[pss_index] /= (length / 4);
|
||||
|
||||
*nid2 = pss_source;
|
||||
*pssPeak = dB_fixed64(peak_value);
|
||||
*pssAvg = dB_fixed64(avg[pss_source]);
|
||||
|
||||
LOG_I(PHY,
|
||||
LOG_D(PHY,
|
||||
"[UE] nr_synchro_time: Sync source (nid2) = %d, Peak found at pos %d, val = %ld (%d dB power over signal avg %d dB), ffo "
|
||||
"%lf\n",
|
||||
pss_source,
|
||||
|
||||
@@ -187,13 +187,14 @@ void insert_sss_nr(int16_t *sss_time,
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
|
||||
static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nid2,
|
||||
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
|
||||
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
|
||||
{
|
||||
int16_t *pss = get_primary_synchro_nr2(ue->common_vars.nid2);
|
||||
int16_t *pss = get_primary_synchro_nr2(nid2);
|
||||
|
||||
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
c16_t *sss_ext2 = sss_ext[aarx];
|
||||
c16_t *pss_ext2 = pss_ext[aarx];
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
@@ -250,16 +251,15 @@ static int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
|
||||
*********************************************************************/
|
||||
|
||||
static int do_pss_sss_extract_nr(
|
||||
PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
|
||||
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
|
||||
uint8_t doPss,
|
||||
uint8_t doSss,
|
||||
uint8_t subframe,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
|
||||
int ssb_start_subcarrier,
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n");
|
||||
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
@@ -275,11 +275,8 @@ static int do_pss_sss_extract_nr(
|
||||
c16_t *pss_rxF_ext = pss_ext[aarx];
|
||||
c16_t *sss_rxF_ext = sss_ext[aarx];
|
||||
|
||||
unsigned int k = frame_parms->first_carrier_offset +
|
||||
frame_parms->ssb_start_subcarrier +
|
||||
((get_softmodem_params()->sl_mode == 0) ?
|
||||
PSS_SSS_SUB_CARRIER_START :
|
||||
PSS_SSS_SUB_CARRIER_START_SL);
|
||||
unsigned int k = frame_parms->first_carrier_offset + ssb_start_subcarrier
|
||||
+ ((get_softmodem_params()->sl_mode == 0) ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL);
|
||||
|
||||
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
|
||||
|
||||
@@ -333,14 +330,21 @@ static int do_pss_sss_extract_nr(
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
|
||||
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
|
||||
uint8_t subframe,
|
||||
c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP])
|
||||
int ssb_start_subcarrier,
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
|
||||
{
|
||||
return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe, rxdataF);
|
||||
return do_pss_sss_extract_nr(frame_parms,
|
||||
pss_ext,
|
||||
sss_ext,
|
||||
1 /* doPss */,
|
||||
1 /* doSss */,
|
||||
subframe,
|
||||
ssb_start_subcarrier,
|
||||
rxdataF);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -355,31 +359,29 @@ static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
* so Nid_cell in ue context is set according to Nid1 & Nid2
|
||||
*
|
||||
*********************************************************************/
|
||||
bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nid2,
|
||||
int target_Nid_cell,
|
||||
int freq_offset_pss,
|
||||
int ssb_start_subcarrier,
|
||||
int *Nid_cell,
|
||||
int32_t *tot_metric,
|
||||
uint8_t *phase_max,
|
||||
int *freq_offset_sss,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
|
||||
{
|
||||
uint8_t i;
|
||||
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0};
|
||||
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0};
|
||||
uint8_t Nid2 = GET_NID2(ue->common_vars.nid2);
|
||||
uint8_t Nid2 = GET_NID2(nid2);
|
||||
uint16_t Nid1;
|
||||
uint8_t phase;
|
||||
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
|
||||
int32_t metric, metric_re;
|
||||
int16_t *d;
|
||||
|
||||
|
||||
// pss sss extraction
|
||||
pss_sss_extract_nr(ue,
|
||||
proc,
|
||||
pss_ext,
|
||||
sss_ext,
|
||||
0,
|
||||
rxdataF); /* subframe */
|
||||
pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, 0, ssb_start_subcarrier, rxdataF); /* subframe */
|
||||
|
||||
#ifdef DEBUG_PLOT_SSS
|
||||
|
||||
@@ -406,9 +408,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
// get conjugated channel estimate from PSS, H* = R* \cdot PSS
|
||||
// and do channel estimation and compensation based on PSS
|
||||
|
||||
pss_ch_est_nr(ue,
|
||||
pss_ext,
|
||||
sss_ext);
|
||||
pss_ch_est_nr(frame_parms, nid2, pss_ext, sss_ext);
|
||||
|
||||
// now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h
|
||||
*tot_metric = INT_MIN;
|
||||
@@ -453,8 +453,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
|
||||
uint16_t Nid1_start = 0;
|
||||
uint16_t Nid1_end = N_ID_1_NUMBER;
|
||||
if (ue->target_Nid_cell != -1) {
|
||||
Nid1_start = GET_NID1(ue->target_Nid_cell);
|
||||
if (target_Nid_cell != -1) {
|
||||
Nid1_start = GET_NID1(target_Nid_cell);
|
||||
Nid1_end = Nid1_start + 1;
|
||||
}
|
||||
|
||||
@@ -476,7 +476,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
// if the current metric is better than the last save it
|
||||
if (metric > *tot_metric) {
|
||||
*tot_metric = metric;
|
||||
ue->frame_parms.Nid_cell = Nid2+(3*Nid1);
|
||||
*Nid_cell = Nid2 + (3 * Nid1);
|
||||
*phase_max = phase;
|
||||
|
||||
#ifdef DEBUG_SSS_NR
|
||||
@@ -490,9 +490,9 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
|
||||
//#ifdef DEBUG_SSS_NR
|
||||
#define SSS_METRIC_FLOOR_NR (30000)
|
||||
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
|
||||
Nid2 = GET_NID2(frame_parms->Nid_cell);
|
||||
Nid1 = GET_NID1(frame_parms->Nid_cell);
|
||||
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
|
||||
Nid2 = GET_NID2(*Nid_cell);
|
||||
Nid1 = GET_NID1(*Nid_cell);
|
||||
LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
|
||||
}
|
||||
// #endif
|
||||
@@ -500,11 +500,11 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
int re = 0;
|
||||
int im = 0;
|
||||
if (Nid1 == N_ID_1_NUMBER) {
|
||||
LOG_W(PHY,
|
||||
LOG_D(PHY,
|
||||
"Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n",
|
||||
*tot_metric,
|
||||
SSS_METRIC_FLOOR_NR,
|
||||
frame_parms->Nid_cell);
|
||||
*Nid_cell);
|
||||
return false;
|
||||
}
|
||||
d = (int16_t *)&d_sss[Nid2][Nid1];
|
||||
@@ -515,10 +515,10 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
double ffo_sss = atan2(im,re)/M_PI/4.3;
|
||||
*freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing);
|
||||
|
||||
double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing;
|
||||
LOG_W(NR_PHY,
|
||||
double ffo_pss = ((double)freq_offset_pss) / frame_parms->subcarrier_spacing;
|
||||
LOG_D(NR_PHY,
|
||||
"SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n",
|
||||
frame_parms->Nid_cell,
|
||||
*Nid_cell,
|
||||
ffo_pss,
|
||||
(int)(ffo_pss * frame_parms->subcarrier_spacing),
|
||||
ffo_sss,
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "common_lib.h"
|
||||
#include "fapi_nr_ue_interface.h"
|
||||
#include "assertions.h"
|
||||
//#include "openair1/SCHED_NR_UE/defs.h"
|
||||
|
||||
#ifdef MEX
|
||||
#define msg mexPrintf
|
||||
@@ -60,9 +61,9 @@
|
||||
#endif
|
||||
#define msg(aRGS...) LOG_D(PHY, ##aRGS)
|
||||
#endif
|
||||
//use msg in the real-time thread context
|
||||
// use msg in the real-time thread context
|
||||
#define msg_nrt printf
|
||||
//use msg_nrt in the non real-time context (for initialization, ...)
|
||||
// use msg_nrt in the non real-time context (for initialization, ...)
|
||||
#ifndef malloc16
|
||||
#define malloc16(x) memalign(32,x)
|
||||
#endif
|
||||
@@ -123,6 +124,11 @@ typedef enum {
|
||||
|
||||
#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg
|
||||
|
||||
typedef struct {
|
||||
uint8_t decoded_output[3]; // PBCH paylod not larger than 3B
|
||||
uint8_t xtra_byte;
|
||||
} fapiPbch_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
// RRC measurements
|
||||
@@ -614,6 +620,32 @@ typedef struct {
|
||||
int frame_rx;
|
||||
} UE_nr_rxtx_proc_t;
|
||||
|
||||
typedef struct {
|
||||
bool cell_detected;
|
||||
int rx_offset;
|
||||
int frame_id;
|
||||
} nr_initial_sync_t;
|
||||
|
||||
typedef struct {
|
||||
nr_gscn_info_t gscnInfo;
|
||||
int foFlag;
|
||||
int targetNidCell;
|
||||
c16_t **rxdata;
|
||||
NR_DL_FRAME_PARMS *fp;
|
||||
UE_nr_rxtx_proc_t *proc;
|
||||
int nFrames;
|
||||
int halfFrameBit;
|
||||
int symbolOffset;
|
||||
int ssbIndex;
|
||||
int ssbOffset;
|
||||
int nidCell;
|
||||
int freqOffset;
|
||||
nr_initial_sync_t syncRes;
|
||||
fapiPbch_t pbchResult;
|
||||
int pssCorrPeakPower;
|
||||
int pssCorrAvgPower;
|
||||
} nr_ue_ssb_scan_t;
|
||||
|
||||
typedef struct nr_phy_data_tx_s {
|
||||
NR_UE_ULSCH_t ulsch;
|
||||
NR_UE_PUCCH pucch_vars;
|
||||
|
||||
@@ -81,12 +81,6 @@
|
||||
#define DAQ_AGC_ON 1
|
||||
#define DAQ_AGC_OFF 0
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t decoded_output[3]; // PBCH paylod not larger than 3B
|
||||
uint8_t xtra_byte;
|
||||
} fapiPbch_t;
|
||||
|
||||
/** @addtogroup _PHY_PROCEDURES_
|
||||
* @{
|
||||
*/
|
||||
|
||||
@@ -371,13 +371,21 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
|
||||
LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id);
|
||||
fapiPbch_t result;
|
||||
int hf_frame_bit, ssb_index, symb_offset;
|
||||
ret = nr_rx_pbch(ue,
|
||||
proc,
|
||||
ue->is_synchronized,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
&ue->frame_parms,
|
||||
(ue->frame_parms.ssb_index)&7,
|
||||
(ue->frame_parms.ssb_index) & 7,
|
||||
ue->frame_parms.ssb_start_subcarrier,
|
||||
ue->frame_parms.Nid_cell,
|
||||
&result,
|
||||
&hf_frame_bit,
|
||||
&ssb_index,
|
||||
&symb_offset,
|
||||
ue->frame_parms.samples_per_frame_wCP,
|
||||
rxdataF);
|
||||
|
||||
if (ret==0) {
|
||||
@@ -868,8 +876,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
||||
nr_slot_fep(ue, fp, proc, (ssb_start_symbol + i) % (fp->symbols_per_slot), rxdataF, link_type_dl);
|
||||
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
nr_pbch_channel_estimation(ue,
|
||||
&ue->frame_parms,
|
||||
nr_pbch_channel_estimation(&ue->frame_parms,
|
||||
NULL,
|
||||
ue->nr_gold_pbch,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
dl_ch_estimates_time,
|
||||
@@ -878,10 +887,20 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
||||
i - 1,
|
||||
ssb_index & 7,
|
||||
ssb_slot_2 == nr_slot_rx,
|
||||
fp->ssb_start_subcarrier,
|
||||
rxdataF,
|
||||
false,
|
||||
fp->Nid_cell);
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
|
||||
if (i - 1 == 2)
|
||||
UEscopeCopy(ue,
|
||||
pbchDlChEstimateTime,
|
||||
(void *)dl_ch_estimates_time,
|
||||
sizeof(c16_t),
|
||||
fp->nb_antennas_rx,
|
||||
fp->ofdm_symbol_size,
|
||||
0);
|
||||
}
|
||||
|
||||
nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, rxdataF);
|
||||
|
||||
@@ -193,8 +193,9 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
nr_slot_fep(ue, fp, proc, sym, rxdataF, link_type_ul);
|
||||
|
||||
start_meas(&sl_phy_params->channel_estimation_stats);
|
||||
nr_pbch_channel_estimation(ue,
|
||||
fp,
|
||||
nr_pbch_channel_estimation(fp,
|
||||
&ue->SL_UE_PHY_PARAMS,
|
||||
ue->nr_gold_pbch,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
dl_ch_estimates_time,
|
||||
@@ -203,10 +204,19 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
sym,
|
||||
0,
|
||||
0,
|
||||
fp->ssb_start_subcarrier,
|
||||
rxdataF,
|
||||
true,
|
||||
sl_phy_params->sl_config.sl_sync_source.rx_slss_id);
|
||||
stop_meas(&sl_phy_params->channel_estimation_stats);
|
||||
if (sym == 12)
|
||||
UEscopeCopy(ue,
|
||||
pbchDlChEstimateTime,
|
||||
(void *)dl_ch_estimates_time,
|
||||
sizeof(c16_t),
|
||||
fp->nb_antennas_rx,
|
||||
fp->ofdm_symbol_size,
|
||||
0);
|
||||
|
||||
// PSBCH present in symbols 0, 5-12 for normal cp
|
||||
sym = (sym == 0) ? 5 : sym + 1;
|
||||
|
||||
@@ -830,7 +830,7 @@ int main(int argc, char **argv)
|
||||
|
||||
init_nr_ue_transport(UE);
|
||||
|
||||
nr_gold_pbch(UE);
|
||||
nr_gold_pbch(UE->nr_gold_pbch, frame_parms->Nid_cell, frame_parms->Lmax);
|
||||
|
||||
// compute the scramblingID_pdcch and the gold pdcch
|
||||
UE->scramblingID_pdcch = frame_parms->Nid_cell;
|
||||
|
||||
@@ -199,6 +199,7 @@ int main(int argc, char **argv)
|
||||
uint16_t Nid_cell=0;
|
||||
uint64_t SSB_positions=0x01;
|
||||
int ssb_subcarrier_offset = 0;
|
||||
int ssb_scan_threads = 0;
|
||||
|
||||
channel_desc_t *gNB2UE;
|
||||
get_softmodem_params()->sa = 1;
|
||||
@@ -500,8 +501,9 @@ int main(int argc, char **argv)
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
|
||||
phy_init_nr_gNB(gNB);
|
||||
frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset;
|
||||
initFloatingCoresTpool(ssb_scan_threads, &nrUE_params.Tpool, false, "UE-tpool");
|
||||
|
||||
uint8_t n_hf = 0;
|
||||
int n_hf = 0;
|
||||
int cyclic_prefix_type = NFAPI_CP_NORMAL;
|
||||
|
||||
double fs=0, eps;
|
||||
@@ -615,7 +617,7 @@ int main(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
nr_gold_pbch(UE);
|
||||
nr_gold_pbch(UE->nr_gold_pbch, Nid_cell, frame_parms->Lmax);
|
||||
|
||||
processingData_L1tx_t msgDataTx;
|
||||
// generate signal
|
||||
@@ -766,13 +768,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (n_trials==1) {
|
||||
LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_parms->samples_per_frame,1,1);
|
||||
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||
LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_frame,1,1);
|
||||
LOG_M("rxsig0.m", "rxs0", UE->common_vars.rxdata[0], frame_parms->samples_per_frame, 1, 1);
|
||||
if (gNB->frame_parms.nb_antennas_tx > 1)
|
||||
LOG_M("rxsig1.m", "rxs1", UE->common_vars.rxdata[1], frame_parms->samples_per_frame, 1, 1);
|
||||
}
|
||||
if (UE->is_synchronized == 0) {
|
||||
UE_nr_rxtx_proc_t proc={0};
|
||||
nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0);
|
||||
UE_nr_rxtx_proc_t proc = {0};
|
||||
nr_gscn_info_t gscnInfo[MAX_GSCN_BAND] = {0};
|
||||
const int numGscn = 1;
|
||||
gscnInfo[0].ssbFirstSC = frame_parms->ssb_start_subcarrier;
|
||||
nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0, gscnInfo, numGscn);
|
||||
printf("nr_initial_sync1 returns %s\n", ret.cell_detected ? "cell detected" : "cell not detected");
|
||||
if (!ret.cell_detected)
|
||||
n_errors++;
|
||||
@@ -795,8 +800,9 @@ int main(int argc, char **argv)
|
||||
for (int i = UE->symbol_offset + 1; i < UE->symbol_offset + 4; i++) {
|
||||
nr_slot_fep(UE, frame_parms, &proc, i % frame_parms->symbols_per_slot, rxdataF, link_type_dl);
|
||||
|
||||
nr_pbch_channel_estimation(UE,
|
||||
&UE->frame_parms,
|
||||
nr_pbch_channel_estimation(&UE->frame_parms,
|
||||
&UE->SL_UE_PHY_PARAMS,
|
||||
UE->nr_gold_pbch,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
dl_ch_estimates_time,
|
||||
@@ -805,12 +811,29 @@ int main(int argc, char **argv)
|
||||
i - (UE->symbol_offset + 1),
|
||||
ssb_index % 8,
|
||||
n_hf,
|
||||
frame_parms->ssb_start_subcarrier,
|
||||
rxdataF,
|
||||
false,
|
||||
frame_parms->Nid_cell);
|
||||
}
|
||||
fapiPbch_t result;
|
||||
ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF);
|
||||
int ret_ssb_idx;
|
||||
int ret_symbol_offset;
|
||||
ret = nr_rx_pbch(UE,
|
||||
&proc,
|
||||
true,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
frame_parms,
|
||||
ssb_index % 8,
|
||||
frame_parms->ssb_start_subcarrier,
|
||||
Nid_cell,
|
||||
&result,
|
||||
&n_hf,
|
||||
&ret_ssb_idx,
|
||||
&ret_symbol_offset,
|
||||
frame_parms->samples_per_frame_wCP,
|
||||
rxdataF);
|
||||
|
||||
if (ret == 0) {
|
||||
// UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically
|
||||
|
||||
Reference in New Issue
Block a user