nr_initial_sync.c 12.7 KB
Newer Older
Wang's avatar
Wang committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file PHY/LTE_TRANSPORT/initial_sync.c
* \brief Routines for initial UE synchronization procedure (PSS,SSS,PBCH and frame format detection)
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,kaltenberger@eurecom.fr
* \note
* \warning
*/
#include "PHY/types.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
hongzhi wang's avatar
hongzhi wang committed
35 36 37
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "nr_transport_proto_ue.h"
Wang's avatar
Wang committed
38 39 40 41 42 43 44
//#include "SCHED/defs.h"
//#include "SCHED/extern.h"

#include "common_lib.h"

#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
45
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
Wang's avatar
Wang committed
46 47

extern openair0_config_t openair0_cfg[];
hongzhi wang's avatar
hongzhi wang committed
48 49
//static  nfapi_nr_config_request_t config_t;
//static  nfapi_nr_config_request_t* config =&config_t;
50
int cnt=0;
Wang's avatar
Wang committed
51 52 53

//#define DEBUG_INITIAL_SYNCH

hongzhi wang's avatar
hongzhi wang committed
54
int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
Wang's avatar
Wang committed
55 56
{
  NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
57
  int ret =-1;
Wang's avatar
Wang committed
58 59 60 61 62 63

#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

knopp's avatar
knopp committed
64
  // save the nb_prefix_samples0 since we are not synchronized to subframes yet and the SSB has all symbols with nb_prefix_samples
hongzhi wang's avatar
hongzhi wang committed
65
  int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
knopp's avatar
knopp committed
66
  frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
hongzhi wang's avatar
hongzhi wang committed
67

Wang's avatar
Wang committed
68
  //symbol 1
69
  nr_slot_fep(ue,
knopp's avatar
knopp committed
70 71 72 73 74 75 76
	      1,
	      0,
	      ue->ssb_offset,
	      0,
	      1,
	      NR_PBCH_EST);
  
Wang's avatar
Wang committed
77
  //symbol 2
78
  nr_slot_fep(ue,
knopp's avatar
knopp committed
79 80 81 82 83 84
	      2,
	      0,
	      ue->ssb_offset,
	      0,
	      1,
	      NR_PBCH_EST);
Wang's avatar
Wang committed
85 86

  //symbol 3
87
  nr_slot_fep(ue,
knopp's avatar
knopp committed
88 89 90 91 92 93 94 95
	      3,
	      0,
	      ue->ssb_offset,
	      0,
	      1,
	      NR_PBCH_EST);

  //put back nb_prefix_samples0
hongzhi wang's avatar
hongzhi wang committed
96
  frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
knopp's avatar
knopp committed
97
  
98
  
knopp's avatar
knopp committed
99 100 101 102 103 104 105 106 107
  ret = nr_rx_pbch(ue,
		   &ue->proc.proc_rxtx[0],
		   ue->pbch_vars[0],
		   frame_parms,
		   0,
		   SISO,
		   ue->high_speed_flag);
  
  
108
  if (ret==0) {
knopp's avatar
knopp committed
109
    
110
    frame_parms->nb_antenna_ports_eNB = 1; //pbch_tx_ant;
knopp's avatar
knopp committed
111
    
Wang's avatar
Wang committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
    // 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;


    // flip byte endian on 24-bits for MIB
    //    dummy = ue->pbch_vars[0]->decoded_output[0];
    //    ue->pbch_vars[0]->decoded_output[0] = ue->pbch_vars[0]->decoded_output[2];
    //    ue->pbch_vars[0]->decoded_output[2] = dummy;

    for(int i=0; i<RX_NB_TH;i++)
    {

        ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
    }
#ifdef DEBUG_INITIAL_SYNCH
Hongzhi Wang's avatar
Hongzhi Wang committed
128
    LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully mode1_flag %d, tx_ant %d, frame %d\n",
Wang's avatar
Wang committed
129 130 131
          ue->Mod_id,
          frame_parms->mode1_flag,
          pbch_tx_ant,
Hongzhi Wang's avatar
Hongzhi Wang committed
132
          ue->proc.proc_rxtx[0].frame_rx,);
Wang's avatar
Wang committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146
#endif
    return(0);
  } else {
    return(-1);
  }

}

char duplex_string[2][4] = {"FDD","TDD"};
char prefix_string[2][9] = {"NORMAL","EXTENDED"};

int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
{

147
  int32_t sync_pos, sync_pos2, sync_pos_slot; // k_ssb, N_ssb_crb,
knopp's avatar
knopp committed
148 149
  int32_t metric_tdd_ncp=0;
  uint8_t phase_tdd_ncp;
Wang's avatar
Wang committed
150

knopp's avatar
knopp committed
151
  NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
Wang's avatar
Wang committed
152
  int ret=-1;
hongzhi wang's avatar
hongzhi wang committed
153
  int rx_power=0; //aarx,
Guy De Souza's avatar
Guy De Souza committed
154
  //nfapi_nr_config_request_t* config;
Wang's avatar
Wang committed
155

knopp's avatar
knopp committed
156
  int n_ssb_crb=(fp->N_RB_DL-20)>>1;
knopp's avatar
knopp committed
157
  // First try TDD normal prefix, mu 1
knopp's avatar
knopp committed
158 159 160 161
  fp->Ncp=NORMAL;
  fp->frame_type=TDD;
  nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0);
  LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
Wang's avatar
Wang committed
162
  /*
knopp's avatar
knopp committed
163
  write_output("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*fp->samples_per_tti,1,1);
Wang's avatar
Wang committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
  exit(-1);
  */

  /*   Initial synchronisation
   *
  *                                 1 radio frame = 10 ms
  *     <--------------------------------------------------------------------------->
  *     -----------------------------------------------------------------------------
  *     |                                 Received UE data buffer                    |
  *     ----------------------------------------------------------------------------
  *                     --------------------------
  *     <-------------->| pss | pbch | sss | pbch |
  *                     --------------------------
  *          sync_pos            SS/PBCH block
  */
knopp's avatar
knopp committed
179 180


181
  cnt++;
182
  if (1){ // (cnt>100)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
183
    cnt =0;
184

Wang's avatar
Wang committed
185 186 187
  /* process pss search on received buffer */
  sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);

knopp's avatar
knopp committed
188
  
knopp's avatar
knopp committed
189 190
  if (sync_pos >= fp->nb_prefix_samples)
      ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
knopp's avatar
knopp committed
191
  else
knopp's avatar
knopp committed
192
    ue->ssb_offset = sync_pos + (fp->samples_per_tti * 10) - fp->nb_prefix_samples;
knopp's avatar
knopp committed
193 194
  
  LOG_D(PHY,"sync_pos %d ssb_offset %d\n",sync_pos,ue->ssb_offset);
195

Wang's avatar
Wang committed
196

knopp's avatar
knopp committed
197
  //  write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_tti,1,1);
Wang's avatar
Wang committed
198 199 200 201 202 203

#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.eNb_id);
#endif

  /* check that SSS/PBCH block is continuous inside the received buffer */
knopp's avatar
knopp committed
204
  if (sync_pos < (10*fp->ttis_per_subframe*fp->samples_per_tti - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) {
Wang's avatar
Wang committed
205 206 207 208 209

#ifdef DEBUG_INITIAL_SYNCH
    LOG_I(PHY,"Calling sss detection (normal CP)\n");
#endif

knopp's avatar
knopp committed
210
    rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp);
Wang's avatar
Wang committed
211

knopp's avatar
knopp committed
212
    nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0);
Hongzhi Wang's avatar
Hongzhi Wang committed
213

Hongzhi Wang's avatar
Hongzhi Wang committed
214
    nr_gold_pbch(ue);
hongzhi wang's avatar
hongzhi wang committed
215
    ret = nr_pbch_detection(ue,mode);
216 217
    
    nr_gold_pdcch(ue,0, 2);
knopp's avatar
knopp committed
218
    /*
hongzhi wang's avatar
hongzhi wang committed
219
    int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
knopp's avatar
knopp committed
220 221 222 223
    frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples.
	  
    nr_slot_fep(ue,0, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
    nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
hongzhi wang's avatar
hongzhi wang committed
224
    frame_parms->nb_prefix_samples0 = nb_prefix_samples0;	
225

226
    LOG_I(PHY,"[UE  %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
227 228 229 230
              ue->Mod_id,
              ue->proc.proc_rxtx[0].frame_rx,
              ue->rx_offset,
              ue->common_vars.freq_offset );
knopp's avatar
knopp committed
231
    */
Wang's avatar
Wang committed
232 233

#ifdef DEBUG_INITIAL_SYNCH
knopp's avatar
knopp committed
234 235
    LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
          frame_parms->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,flip_tdd_ncp,ret);
Wang's avatar
Wang committed
236 237 238 239
#endif
  }
  else {
#ifdef DEBUG_INITIAL_SYNCH
knopp's avatar
knopp committed
240
    LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot);
Wang's avatar
Wang committed
241 242
#endif
  }
243 244 245 246
  }
  else {
	  ret = -1;
  }
Wang's avatar
Wang committed
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298

  /* Consider this is a false detection if the offset is > 1000 Hz */
  if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
  {
	  ret=-1;
#if DISABLE_LOG_X
	  printf("Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
#else
	  LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
#endif
  }

  if (ret==0) {  // PBCH found so indicate sync to higher layers and configure frame parameters

    //#ifdef DEBUG_INITIAL_SYNCH
#if DISABLE_LOG_X
    printf("[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
#else
    LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
#endif
    //#endif

    if (ue->UE_scan_carrier == 0) {

    #if UE_AUTOTEST_TRACE
      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 );
    #endif

// send sync status to higher layers later when timing offset converge to target timing

      ue->pbch_vars[0]->pdu_errors_conseq=0;

    }

#if DISABLE_LOG_X
    printf("[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm,  rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
	  ue->proc.proc_rxtx[0].frame_rx,
	  10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
	  10*log10(ue->measurements.rssi),
	  ue->rx_total_gain_dB,
	  ue->measurements.n0_power_tot_dBm,
	  10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
	  (10*log10(ue->measurements.rsrq[0])));


    printf("[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
	  ue->Mod_id,
	  ue->proc.proc_rxtx[0].frame_rx,
knopp's avatar
knopp committed
299 300 301 302 303 304 305
	  duplex_string[fp->frame_type],
	  prefix_string[fp->Ncp],
	  fp->Nid_cell,
	  fp->N_RB_DL,
	  fp->phich_config_common.phich_duration,
	  phich_string[fp->phich_config_common.phich_resource],
	  fp->nb_antenna_ports_eNB);
Wang's avatar
Wang committed
306 307 308 309 310 311 312 313 314 315 316 317 318
#else
    LOG_I(PHY, "[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm,  rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
	  ue->proc.proc_rxtx[0].frame_rx,
	  10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
	  10*log10(ue->measurements.rssi),
	  ue->rx_total_gain_dB,
	  ue->measurements.n0_power_tot_dBm,
	  10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
	  (10*log10(ue->measurements.rsrq[0])));

/*    LOG_I(PHY, "[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
	  ue->Mod_id,
	  ue->proc.proc_rxtx[0].frame_rx,
knopp's avatar
knopp committed
319 320 321 322 323 324 325
	  duplex_string[fp->frame_type],
	  prefix_string[fp->Ncp],
	  fp->Nid_cell,
	  fp->N_RB_DL,
	  fp->phich_config_common.phich_duration,
	  phich_string[fp->phich_config_common.phich_resource],
	  fp->nb_antenna_ports_eNB);*/
Wang's avatar
Wang committed
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
#endif

#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
#  if DISABLE_LOG_X
    printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
	  ue->Mod_id,
	  ue->proc.proc_rxtx[0].frame_rx,
	  openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
	  ue->common_vars.freq_offset);
#  else
    LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
	  ue->Mod_id,
	  ue->proc.proc_rxtx[0].frame_rx,
	  openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
	  ue->common_vars.freq_offset);
#  endif
#endif
  } 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.eNb_id);
    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

    ue->UE_mode[0] = NOT_SYNCHED;
    ue->pbch_vars[0]->pdu_errors_last=ue->pbch_vars[0]->pdu_errors;
    ue->pbch_vars[0]->pdu_errors++;
    ue->pbch_vars[0]->pdu_errors_conseq++;

  }

  // gain control
  if (ret!=0) { //we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
    rx_power = 0;

    // do a measurement on the best guess of the PSS
363 364 365
    //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);
Wang's avatar
Wang committed
366 367 368 369 370 371 372 373 374

    /*
    // 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
knopp's avatar
knopp committed
375
    ue->measurements.rx_power_avg[0] = rx_power/fp->nb_antennas_rx;
Wang's avatar
Wang committed
376 377 378 379 380 381 382 383 384 385 386

    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

#ifndef OAI_USRP
#ifndef OAI_BLADERF
#ifndef OAI_LMSSDR
#ifndef OAI_ADRV9371_ZC706
387
  //phy_adjust_gain(ue,ue->measurements.rx_power_avg_dB[0],0);
Wang's avatar
Wang committed
388 389 390 391 392 393 394 395 396 397 398 399
#endif
#endif
#endif
#endif

  }
  else {

#ifndef OAI_USRP
#ifndef OAI_BLADERF
#ifndef OAI_LMSSDR
#ifndef OAI_ADRV9371_ZC706
400
  //phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0);
Wang's avatar
Wang committed
401 402 403 404 405 406 407 408 409 410 411
#endif
#endif
#endif
#endif

  }

  //  exit_fun("debug exit");
  return ret;
}