Commit c5b6195a authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/fix-sleeping-ue-at-synchro' into integration_2024_w14

parents ad77def8 7106f3c1
......@@ -48,8 +48,6 @@
//static nfapi_nr_config_request_t config_t;
//static nfapi_nr_config_request_t* config =&config_t;
int cnt=0;
// #define DEBUG_INITIAL_SYNCH
#define DUMP_PBCH_CH_ESTIMATES 0
......@@ -137,12 +135,9 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa)
{
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
int32_t metric_tdd_ncp = 0;
uint8_t phase_tdd_ncp;
int frame_id;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
nr_initial_sync_t ret = {true, 0};
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);
......@@ -163,162 +158,137 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i
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];
cnt++;
if (1) { // (cnt>100)
cnt = 0;
// 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 (frame_id = 0; frame_id < n_frames; frame_id++) {
/* process pss search on received buffer */
sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE);
if (sync_pos < fp->nb_prefix_samples)
continue;
// 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++) {
/* process pss search on received buffer */
sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE);
if (sync_pos < fp->nb_prefix_samples)
continue;
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
ue->ssb_offset = 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);
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);
continue;
}
/* 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) {
// 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)));
}
}
// 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)));
}
}
}
/* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
/* symbol number are from beginning of SS/PBCH blocks as below: */
/* Signal PSS PBCH SSS PBCH */
/* symbol number 0 1 2 3 */
/* 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 */
/* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
/* symbol number are from beginning of SS/PBCH blocks as below: */
/* Signal PSS PBCH SSS PBCH */
/* symbol number 0 1 2 3 */
/* 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 */
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);
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);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY, "Calling sss detection (normal CP)\n");
LOG_I(PHY, "Calling sss detection (normal CP)\n");
#endif
int freq_offset_sss = 0;
bool ret_sss = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF);
ret.cell_detected = ret_sss; // rx_sss_nr returns true if success
// 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 * freq_offset_sss; // 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)));
}
}
ue->common_vars.freq_offset += freq_offset_sss;
}
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
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
// 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;
}
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;
}
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
}
/*
int nb_prefix_samples0 = fp->nb_prefix_samples0;
fp->nb_prefix_samples0 = fp->nb_prefix_samples;
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_slot_fep(ue, proc, 0, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
nr_slot_fep(ue, proc, 1, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
fp->nb_prefix_samples0 = nb_prefix_samples0;
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
ue->rx_offset,
ue->common_vars.freq_offset );
*/
// 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);
}
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,
"TDD Normal prefix: CellId %d metric %d, phase %d, pbch detected %d, measured offset %d\n",
fp->Nid_cell,
metric_tdd_ncp,
phase_tdd_ncp,
ret.cell_detected,
ret.rx_offset);
#endif
// 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;
}
} else {
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY, "TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos);
LOG_I(PHY,
"TDD Normal prefix: CellId %d metric %d, phase %d, pbch detected %d, measured offset %d\n",
fp->Nid_cell,
metric_tdd_ncp,
phase_tdd_ncp,
ret.cell_detected,
ret.rx_offset);
#endif
}
if (ret.cell_detected)
break;
}
} else {
ret.cell_detected = false;
}
/* Consider this is a false detection if the offset is > 1000 Hz
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment