Commit 0a9cb163 authored by Laurent THOMAS's avatar Laurent THOMAS Committed by sagar arora

make explicit return of the clock drift to shift the corresponding number of samples

remove corresponding global variables
parent 12a20546
......@@ -439,11 +439,13 @@ static void UE_synch(void *arg) {
uint64_t dl_carrier, ul_carrier;
nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier);
if (nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa) == 0) {
nr_initial_sync_t ret = nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa);
if (!ret.cell_notdetected) {
syncD->rx_offset = ret.rx_offset;
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) +
round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0);
hw_slot_offset =
((ret.rx_offset << 1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe)
+ round((float)((ret.rx_offset << 1) % UE->frame_parms.samples_per_subframe) / UE->frame_parms.samples_per_slot0);
// rerun with new cell parameters and frequency-offset
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
......@@ -462,7 +464,6 @@ static void UE_synch(void *arg) {
else
UE->is_synchronized = 1;
} else {
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
......@@ -607,8 +608,9 @@ void processSlotTX(void *arg)
RU_write(rxtxD);
}
static void UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data)
static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data)
{
int sampleShift = 0;
if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
// Start synchronization with a target gNB
......@@ -636,20 +638,16 @@ static void UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *pro
UE->if_inst->dl_indication(&dl_indication);
}
uint64_t a=rdtsc_oai();
pbch_pdcch_processing(UE, proc, phy_data);
sampleShift = pbch_pdcch_processing(UE, proc, phy_data);
if (phy_data->dlsch[0].active && phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_) {
// indicate to tx thread to wait for DLSCH decoding
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
LOG_D(NR_PHY, "Adding one event to wait after decoding slot %d, for futre tx slot %d\n", proc->nr_slot_rx, ack_nack_slot);
tx_wait_for_dlsch[ack_nack_slot]++;
}
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
}
ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
return;
return sampleShift;
}
void UE_dl_processing(void *arg) {
......@@ -710,37 +708,39 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash)
}
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// Resynchonize by slot (will work with numerology 1 only)
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe/2 ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe/2 ? UE->frame_parms.samples_per_subframe/2 : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
}
} else {
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
// we write before read because gNB waits for UE to write and both executions halt
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
}
static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int rx_offset)
{
LOG_I(PHY, "Resynchronizing RX by %d samples\n", rx_offset);
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// Resynchonize by slot (will work with numerology 1 only)
for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe / 2) {
int unitTransfer = size > UE->frame_parms.samples_per_subframe / 2 ? UE->frame_parms.samples_per_subframe / 2 : size;
AssertFatal(unitTransfer
== UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),
"");
}
} else {
*timestamp += UE->frame_parms.get_samples_per_slot(1, &UE->frame_parms);
for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe) {
int unitTransfer = size > UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size;
// we write before read because gNB waits for UE to write and both executions halt
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
if (IS_SOFTMODEM_RFSIM)
dummyWrite(UE, *timestamp, unitTransfer);
AssertFatal(unitTransfer
== UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),
"");
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
}
}
}
static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
......@@ -764,8 +764,6 @@ void *UE_thread(void *arg)
//this thread should be over the processing thread to keep in real time
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
// int tx_enabled = 0;
openair0_timestamp timestamp = 0;
openair0_timestamp writeTimestamp = 0;
void *rxp[NB_ANTENNAS_RX];
int start_rx_stream = 0;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
......@@ -796,9 +794,10 @@ void *UE_thread(void *arg)
for(int i=0; i < num_ind_fifo; i++) {
initNotifiedFIFO(UE->tx_resume_ind_fifo + i);
}
int shiftForNextFrame = 0;
int intialSyncOffset = 0;
openair0_timestamp sync_timestamp;
while (!oai_exit) {
if (syncRunning) {
notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
......@@ -806,25 +805,28 @@ void *UE_thread(void *arg)
syncRunning=false;
if (UE->is_synchronized) {
decoded_frame_rx = mac->mib_frame;
LOG_I(PHY,"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n",
LOG_A(PHY,
"UE synchronized! decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n",
decoded_frame_rx,
UE->init_sync_frame,
trashed_frames);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
decoded_frame_rx = (decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(res);
intialSyncOffset = syncMsg->rx_offset;
}
delNotifiedFIFO_elt(res);
start_rx_stream=0;
} else {
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// For IQ recorder/player we force synchronization to happen in 280 ms
// For IQ recorder-player we force synchronization to happen in 280 ms
while (trashed_frames != 28) {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
readFrame(UE, &sync_timestamp, true);
trashed_frames += 2;
}
} else {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
readFrame(UE, &sync_timestamp, true);
trashed_frames += 2;
}
continue;
}
......@@ -833,7 +835,7 @@ void *UE_thread(void *arg)
AssertFatal(!syncRunning, "At this point synchronization can't be running\n");
if (!UE->is_synchronized) {
readFrame(UE, &timestamp, false);
readFrame(UE, &sync_timestamp, false);
notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
syncMsg->UE = UE;
......@@ -846,16 +848,16 @@ void *UE_thread(void *arg)
if (start_rx_stream == 0) {
start_rx_stream=1;
syncInFrame(UE, &timestamp);
UE->rx_offset=0;
UE->time_sync_cell=0;
syncInFrame(UE, &sync_timestamp, intialSyncOffset);
shiftForNextFrame = 0; // will be used to track clock drift
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void **)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx),"");
AssertFatal(UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0
== UE->rfdevice.trx_read_func(&UE->rfdevice,
&sync_timestamp,
(void **)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx),
"");
// we have the decoded frame index in the return of the synch process
// and we shifted above to the first slot of next frame
decoded_frame_rx++;
......@@ -871,7 +873,7 @@ void *UE_thread(void *arg)
continue;
}
// start of normal case, the UE is in sync
absolute_slot++;
int slot_nr = absolute_slot % nb_slot_frame;
......@@ -893,26 +895,21 @@ void *UE_thread(void *arg)
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
int readBlockSize, writeBlockSize;
rxp[i] = (void *)&UE->common_vars
.rxdata[i][firstSymSamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, 0)];
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms);
writeBlockSize = UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms);
if (UE->apply_timing_offset && (slot_nr == nb_slot_frame - 1)) {
const int sampShift = -(UE->rx_offset>>1);
readBlockSize -= sampShift;
writeBlockSize -= sampShift;
UE->apply_timing_offset = false;
int iq_shift_to_apply = 0;
if (slot_nr == nb_slot_frame - 1) {
// we shift of half of measured drift, at each beginning of frame for both rx and tx
iq_shift_to_apply = shiftForNextFrame;
shiftForNextFrame = 0; // We will get a new measured offset if we decode PBCH
}
AssertFatal(readBlockSize ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
const int readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms) - iq_shift_to_apply;
openair0_timestamp rx_timestamp;
AssertFatal(readBlockSize
== UE->rfdevice.trx_read_func(&UE->rfdevice, &rx_timestamp, rxp, readBlockSize, UE->frame_parms.nb_antennas_rx),
"");
if(slot_nr == (nb_slot_frame - 1)) {
// read in first symbol of next frame and adjust for timing drift
......@@ -931,11 +928,13 @@ void *UE_thread(void *arg)
}
// use previous timing_advance value to compute writeTimestamp
writeTimestamp = timestamp +
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX)
- firstSymSamp - UE->N_TA_offset - timing_advance;
const openair0_timestamp writeTimestamp =
rx_timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, DURATION_RX_TO_TX) - firstSymSamp
- UE->N_TA_offset - timing_advance;
// but use current UE->timing_advance value to compute writeBlockSize
int writeBlockSize =
UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms) - iq_shift_to_apply;
if (UE->timing_advance != timing_advance) {
writeBlockSize -= UE->timing_advance - timing_advance;
timing_advance = UE->timing_advance;
......@@ -948,7 +947,12 @@ void *UE_thread(void *arg)
notifiedFIFO_elt_t *newRx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_rx, NULL, UE_dl_processing);
nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newRx);
*curMsgRx = (nr_rxtx_thread_data_t){.proc = curMsg.proc, .UE = UE};
UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data);
int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data);
if (ret)
// if ret is 0, no rx_offset has been computed,
// or the computed value is 0 = no offset to do
// we store it to apply the drift compensation at beginning of next frame
shiftForNextFrame = ret;
pushTpool(&(get_nrUE_params()->Tpool), newRx);
// Start TX slot processing here. It runs in parallel with RX slot processing
......
......@@ -33,29 +33,22 @@
// The adjustment is performed once per frame based on the
// last channel estimate of the receiver
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
module_id_t gNB_id,
const int estimateSz,
struct complex16 dl_ch_estimates_time[][estimateSz],
uint8_t frame,
uint8_t subframe,
unsigned char clear,
short coef)
int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
module_id_t gNB_id,
const int estimateSz,
struct complex16 dl_ch_estimates_time[][estimateSz],
uint8_t frame,
uint8_t slot,
short coef)
{
static int count_max_pos_ok = 0;
static int first_time = 1;
int max_val = 0, max_pos = 0;
const int sync_pos = 0;
uint8_t sync_offset = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
short ncoef = 32767 - coef;
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
// search for maximum position within the cyclic prefix
for (int i = -frame_parms->nb_prefix_samples/2; i < frame_parms->nb_prefix_samples/2; i++) {
int temp = 0;
......@@ -74,54 +67,40 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
}
// filter position to reduce jitter
<<<<<<< HEAD
if (clear == 1){
AssertFatal(max_pos > -1, "The result of the left shift is undefined if the left operand is negative");
ue->max_pos_fil = max_pos << 15;
} else
ue->max_pos_fil = ((ue->max_pos_fil * coef) >> 15) + (max_pos * ncoef);
=======
ue->max_pos_avg = ((ue->max_pos_avg * coef) >> 15) + (max_pos * ncoef);
>>>>>>> c5e4bea6b (make explicit return of the clock drift to shift the corresponding number of samples)
// do not filter to have proactive timing adjustment
//ue->max_pos_fil = max_pos << 15;
int diff = (ue->max_pos_fil >> 15) - sync_pos;
int diff = ue->max_pos_avg >> 15;
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
int sampleShift = 0;
if (abs(diff) > (NR_SYNCH_HYST + sync_offset))
sampleShift = diff;
const int sample_shift = -(ue->rx_offset>>1);
const int sample_shift = -(sampleShift / 2);
// reset IIR filter for next offset calculation
ue->max_pos_fil += sample_shift * 32768;
if(abs(diff)<5)
count_max_pos_ok ++;
else
count_max_pos_ok = 0;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if(count_max_pos_ok > 10 && first_time == 1) {
first_time = 0;
ue->time_sync_cell = 1;
}
ue->max_pos_avg += sample_shift * 32768;
#ifdef DEBUG_PHY
LOG_I(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
subframe,
LOG_D(PHY,
"Slot %d: diff = %i, rx_offset (final) = %i : max_pos = %d, max_pos filtered = %ld, max_power = %d\n",
slot,
diff,
ue->rx_offset,
clear,
sampleShift,
max_pos,
ue->max_pos_fil,
max_val,
sync_pos);
#endif //DEBUG_PHY
ue->max_pos_avg,
max_val);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
return sample_shift;
}
......@@ -30,7 +30,7 @@
*/
/*!\brief Timing drift hysterisis in samples*/
#define SYNCH_HYST 2
#define NR_SYNCH_HYST 1
/* A function to perform the channel estimation of DL PRS signal */
int nr_prs_channel_estimation(uint8_t gNB_id,
......@@ -91,15 +91,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
int rxdataFsize,
c16_t rxdataF[][rxdataFsize]);
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
module_id_t gNB_id,
int estimateSz,
struct complex16 dl_ch_estimates_time [][estimateSz],
uint8_t frame,
uint8_t subframe,
unsigned char clear,
short coef);
int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
module_id_t gNB_id,
int estimateSz,
struct complex16 dl_ch_estimates_time[][estimateSz],
uint8_t frame,
uint8_t subframe,
short coef);
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
......
......@@ -50,7 +50,7 @@ extern openair0_config_t openair0_cfg[];
//static nfapi_nr_config_request_t* config =&config_t;
int cnt=0;
#define DEBUG_INITIAL_SYNCH
// #define DEBUG_INITIAL_SYNCH
#define DUMP_PBCH_CH_ESTIMATES 0
// create a new node of SSB structure
......@@ -111,11 +111,6 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
NR_UE_SSB *best_ssb = NULL;
NR_UE_SSB *current_ssb;
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
ue->rx_offset);
#endif
uint8_t N_L = (frame_parms->Lmax == 4)? 4:8;
uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1;
......@@ -129,7 +124,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
start_meas(&ue->dlsch_channel_estimation_stats);
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_dmrs_correlation(ue,proc,i,i-pbch_initial_symbol,current_ssb,rxdataF);
nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, current_ssb, rxdataF);
stop_meas(&ue->dlsch_channel_estimation_stats);
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
......@@ -147,7 +142,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
while (ret!=0 && temp_ptr != NULL) {
start_meas(&ue->dlsch_channel_estimation_stats);
// computing channel estimation for selected best ssb
// computing channel estimation for selected best ssb
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
......@@ -178,242 +173,230 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
free_list(best_ssb);
if (ret==0) {
frame_parms->nb_antenna_ports_gNB = 1; //pbch_tx_ant;
// set initial transmission mode to 1 or 2 depending on number of detected TX antennas
//frame_parms->mode1_flag = (pbch_tx_ant==1);
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
if (ret == 0)
frame_parms->nb_antenna_ports_gNB = 1; // pbch_tx_ant;
// set initial transmission mode to 1 or 2 depending on number of detected TX antennas
// frame_parms->mode1_flag = (pbch_tx_ant==1);
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
#endif
return(0);
} else {
return(-1);
}
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
return ret;
}
int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa)
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;
int32_t metric_tdd_ncp = 0;
uint8_t phase_tdd_ncp;
int frame_id;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int ret=-1;
int rx_power=0; //aarx,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
nr_initial_sync_t ret = {true, 0};
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);
LOG_D(PHY, "nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
/* Initial synchronisation
*
* 1 radio frame = 10 ms
* <--------------------------------------------------------------------------->
* -----------------------------------------------------------------------------
* | Received UE data buffer |
* ----------------------------------------------------------------------------
* --------------------------
* <-------------->| pss | pbch | sss | pbch |
* --------------------------
* sync_pos SS/PBCH block
*/
* 1 radio frame = 10 ms
* <--------------------------------------------------------------------------->
* -----------------------------------------------------------------------------
* | Received UE data buffer |
* ----------------------------------------------------------------------------
* --------------------------
* <-------------->| pss | pbch | sss | pbch |
* --------------------------
* 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];
__attribute__((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
cnt++;
if (1){ // (cnt>100)
cnt =0;
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 (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;
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) {
// 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)));
/* 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)));
}
}
}
}
/* 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 = !ret_sss;
// 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)));
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_notdetected = !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==0) { //we got sss channel
nr_gold_pbch(ue);
ret = nr_pbch_detection(proc, ue, 1, rxdataF); // start pbch detection at first symbol after pss
}
ue->common_vars.freq_offset += freq_offset_sss;
}
if (ret == 0) {
// 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]);
if (ret.cell_notdetected == 0) { // we got sss channel
nr_gold_pbch(ue);
ret.cell_notdetected = 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);
if (ret.cell_notdetected == 0) {
// 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]);
}
// 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);
}
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){
ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
ue->init_sync_frame += 1;
// 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
ue->rx_offset = ue->ssb_offset - sync_pos_frame;
}
/*
int nb_prefix_samples0 = fp->nb_prefix_samples0;
fp->nb_prefix_samples0 = fp->nb_prefix_samples;
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;
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 );
*/
/*
int nb_prefix_samples0 = fp->nb_prefix_samples0;
fp->nb_prefix_samples0 = fp->nb_prefix_samples;
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;
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 );
*/
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n",
fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret);
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_notdetected,
ret.rx_offset);
#endif
}
else {
} 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: SSS error condition: sync_pos %d\n", sync_pos);
#endif
}
if (ret == 0) break;
}
}
else {
ret = -1;
if (ret.cell_notdetected == 0)
break;
}
} else {
ret.cell_notdetected = true;
}
/* Consider this is a false detection if the offset is > 1000 Hz
/* 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( (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==0) { // PBCH found so indicate sync to higher layers and configure frame parameters
if (ret.cell_notdetected == 0) { // 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, ue->rx_offset);
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
#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
// send sync status to higher layers later when timing offset converge to target timing
}
LOG_I(PHY,
......@@ -428,23 +411,22 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
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!=0) { //we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
rx_power = 0;
if (ret.cell_notdetected != 0) { // 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++)
// 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);
// 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);
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
......@@ -453,12 +435,10 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
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] );
LOG_I(PHY, "[UE%d] Initial sync : Estimated power: %d dB\n", ue->Mod_id, ue->measurements.rx_power_avg_dB[0]);
#endif
}
// exit_fun("debug exit");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
return ret;
}
......@@ -287,6 +287,7 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
/*! \brief receiver for the PBCH
\returns number of tx antennas or -1 if error
*/
int nr_rx_pbch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const int estimateSz,
......@@ -297,11 +298,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
fapiPbch_t *result,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
int pbch_initial_symbol,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
#ifndef modOrder
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
#endif
......@@ -323,7 +319,11 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue,
@param n_frames
@param sa current running mode
*/
int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa);
typedef struct {
bool cell_notdetected;
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);
/*!
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the
......
......@@ -482,12 +482,8 @@ typedef struct PHY_VARS_NR_UE_s {
uint8_t init_sync_frame;
/// temporary offset during cell search prior to MIB decoding
int ssb_offset;
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
int rx_offset; /// Timing offset
int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
int64_t max_pos_fil; /// Timing offset IIR filter
bool apply_timing_offset; /// Do time sync for current frame
int time_sync_cell;
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
int64_t max_pos_avg; /// Timing offset IIR filter
/// Timing Advance updates variables
/// Timing advance update computed from the TA command signalled from gNB
......@@ -641,6 +637,7 @@ typedef struct nr_rxtx_thread_data_s {
int writeBlockSize;
nr_phy_data_t phy_data;
int tx_wait_for_dlsch;
int rx_offset;
} nr_rxtx_thread_data_t;
typedef struct LDPCDecode_ue_s {
......
......@@ -98,7 +98,7 @@ typedef struct {
*/
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
......
......@@ -827,7 +827,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *
return dec;
}
void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
{
int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx;
......@@ -835,6 +835,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
fapi_nr_config_request_t *cfg = &ue->nrUE_config;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
int sampleShift = 0;
nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
......@@ -897,17 +898,9 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
if (ue->no_timing_correction==0 && pbchSuccess == 0) {
LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
nr_adjust_synch_ue(fp,
ue,
gNB_id,
fp->ofdm_symbol_size,
dl_ch_estimates_time,
frame_rx,
nr_slot_rx,
0,
16384);
sampleShift =
nr_adjust_synch_ue(fp, ue, gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384);
}
ue->apply_timing_offset = true;
}
LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
nr_ue_rrc_measurements(ue, proc, rxdataF);
......@@ -997,6 +990,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
phy_pdcch_config->nb_search_space = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
return sampleShift;
}
void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
......
......@@ -959,7 +959,6 @@ int main(int argc, char **argv)
//multipath channel
//multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
UE->rx_offset=0;
UE_proc.frame_rx = frame;
UE_proc.nr_slot_rx = slot;
UE_proc.gNB_id = 0;
......
......@@ -766,21 +766,22 @@ int main(int argc, char **argv)
}
if (UE->is_synchronized == 0) {
UE_nr_rxtx_proc_t proc={0};
ret = nr_initial_sync(&proc, UE, 1, 0);
printf("nr_initial_sync1 returns %d\n",ret);
if (ret<0) n_errors++;
nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0);
printf("nr_initial_sync1 returns %d\n", ret.cell_notdetected);
if (ret.cell_notdetected)
n_errors++;
}
else {
UE_nr_rxtx_proc_t proc={0};
UE->rx_offset=0;
uint8_t ssb_index = 0;
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
__attribute__((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz];
__attribute__((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
while (!((SSB_positions >> ssb_index) & 0x01))
ssb_index++; // to select the first transmitted ssb
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index);
uint8_t ssb_index = 0;
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
__attribute__((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz];
__attribute__((
aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
while (!((SSB_positions >> ssb_index) & 0x01))
ssb_index++; // to select the first transmitted ssb
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index);
int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
proc.nr_slot_rx = ssb_slot;
......
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