initial_sync.c 22 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 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
 */

22 23 24 25 26 27 28 29 30 31 32
/*! \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"
33
#include "PHY/defs_UE.h"
34
#include "targets/RT/USER/lte-softmodem.h"
35 36
#include "PHY/phy_extern_ue.h"
#include "SCHED_UE/sched_UE.h"
37 38 39 40 41
#include "transport_proto_ue.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "openair2/LAYER2/MAC/mac_proto.h"
42
#include "common_lib.h"
43 44
#include "PHY/INIT/phy_init.h"

45
extern openair0_config_t openair0_cfg[];
46

47
//#define DEBUG_INITIAL_SYNCH
48

49
int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) {
50 51 52
  uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy;
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
  char phich_resource[6];
53
  LOG_D(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
54
        ue->rx_offset);
55

56
  for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
57
    slot_fep(ue,
58 59 60 61 62
             l,
             0,
             ue->rx_offset,
             0,
             1);
63
  }
64

65
  for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
66
    slot_fep(ue,
67 68 69 70 71
             l,
             1,
             ue->rx_offset,
             0,
             1);
72
  }
73

74 75 76 77 78 79
  slot_fep(ue,
           0,
           2,
           ue->rx_offset,
           0,
           1);
80
  lte_ue_measurements(ue,
81 82 83
                      ue->rx_offset,
                      0,
                      0,
84 85 86
                      0,
                      0);

87 88
  if (ue->frame_parms.frame_type == TDD) {
    ue_rrc_measurements(ue,
89 90 91
                        2,
                        0);
  } else {
92
    ue_rrc_measurements(ue,
93 94
                        0,
                        0);
95
  }
96

97
  LOG_D(PHY,"[UE %d] RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
98 99 100 101 102 103 104 105 106
        ue->Mod_id,
        ue->measurements.rx_rssi_dBm[0] - ((ue->frame_parms.nb_antennas_rx==2) ? 3 : 0),
        ue->measurements.rx_power_dB[0][0],
        ue->measurements.rx_power_dB[0][1],
        ue->measurements.rx_power[0][0],
        ue->measurements.rx_power[0][1],
        ue->measurements.rx_power_avg_dB[0],
        ue->measurements.rx_power_avg[0],
        ue->rx_total_gain_dB);
107
  LOG_D(PHY,"[UE %d] N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n",
108 109 110 111 112 113 114 115
        ue->Mod_id,
        ue->measurements.n0_power_tot_dBm,
        ue->measurements.n0_power_dB[0],
        ue->measurements.n0_power_dB[1],
        ue->measurements.n0_power[0],
        ue->measurements.n0_power[1],
        ue->measurements.n0_power_avg_dB,
        ue->measurements.n0_power_avg);
116
  pbch_decoded = 0;
117 118

  for (frame_mod4=0; frame_mod4<4; frame_mod4++) {
119
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
120 121

    if (ue->FeMBMS_active != 2) {
122
#endif
laurent's avatar
laurent committed
123 124 125 126 127 128 129
      pbch_tx_ant = rx_pbch(&ue->common_vars,
                            ue->pbch_vars[0],
                            frame_parms,
                            0,
                            SISO,
                            ue->high_speed_flag,
                            frame_mod4);
130
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
131 132 133 134 135 136 137 138 139 140
    } else {
      pbch_tx_ant = rx_pbch_fembms(&ue->common_vars,
                                   ue->pbch_vars[0],
                                   frame_parms,
                                   0,
                                   SISO,
                                   ue->high_speed_flag,
                                   frame_mod4);
    }

141
#endif
142

laurent's avatar
laurent committed
143 144 145
    if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) {
      pbch_decoded = 1;
      break;
146
    }
147

148
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
149 150

    if (ue->FeMBMS_active != 2) {
151
#endif
laurent's avatar
laurent committed
152 153 154 155 156 157 158
      pbch_tx_ant = rx_pbch(&ue->common_vars,
                            ue->pbch_vars[0],
                            frame_parms,
                            0,
                            ALAMOUTI,
                            ue->high_speed_flag,
                            frame_mod4);
159
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
160 161 162 163 164 165 166 167
    } else {
      pbch_tx_ant = rx_pbch_fembms(&ue->common_vars,
                                   ue->pbch_vars[0],
                                   frame_parms,
                                   0,
                                   ALAMOUTI,
                                   ue->high_speed_flag,
                                   frame_mod4);
168
    }
laurent's avatar
laurent committed
169

170
#endif
171

172 173 174 175 176
    if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) {
      pbch_decoded = 1;
      break;
    }
  }
177

178
  if (pbch_decoded) {
Xiwen JIANG's avatar
Xiwen JIANG committed
179
    frame_parms->nb_antenna_ports_eNB = pbch_tx_ant;
180 181 182
    // set initial transmission mode to 1 or 2 depending on number of detected TX antennas
    // openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
    // flip byte endian on 24-bits for MIB
183 184 185
    //    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;
186
    // now check for Bandwidth of Cell
187
    dummy = (ue->pbch_vars[0]->decoded_output[2]>>5)&7;
188

189
    switch (dummy) {
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
      case 0 :
        frame_parms->N_RB_DL = 6;
        break;

      case 1 :
        frame_parms->N_RB_DL = 15;
        break;

      case 2 :
        frame_parms->N_RB_DL = 25;
        break;

      case 3 :
        frame_parms->N_RB_DL = 50;
        break;

      case 4 :
        frame_parms->N_RB_DL = 75;
        break;

      case 5:
        frame_parms->N_RB_DL = 100;
        break;

      default:
        LOG_E(PHY,"[UE%d] Initial sync: PBCH decoding: Unknown N_RB_DL\n",ue->Mod_id);
        return -1;
        break;
218
    }
219

220
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
221

laurent's avatar
laurent committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
    if(ue->FeMBMS_active != 2) {
#endif
      // now check for PHICH parameters
      frame_parms->phich_config_common.phich_duration = (PHICH_DURATION_t)((ue->pbch_vars[0]->decoded_output[2]>>4)&1);
      dummy = (ue->pbch_vars[0]->decoded_output[2]>>2)&3;

      switch (dummy) {
        case 0:
          frame_parms->phich_config_common.phich_resource = oneSixth;
          sprintf(phich_resource,"1/6");
          break;

        case 1:
          frame_parms->phich_config_common.phich_resource = half;
          sprintf(phich_resource,"1/2");
          break;

        case 2:
          frame_parms->phich_config_common.phich_resource = one;
          sprintf(phich_resource,"1");
          break;

        case 3:
          frame_parms->phich_config_common.phich_resource = two;
          sprintf(phich_resource,"2");
          break;

        default:
          LOG_E(PHY,"[UE%d] Initial sync: Unknown PHICH_DURATION\n",ue->Mod_id);
          return -1;
          break;
      }
254

laurent's avatar
laurent committed
255 256 257 258 259
      for(int i=0; i<RX_NB_TH; i++) {
        ue->proc.proc_rxtx[i].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
        ue->proc.proc_rxtx[i].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
        ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
      }
260

laurent's avatar
laurent committed
261 262 263 264 265 266 267 268
      LOG_D(PHY,"[UE%d] Initial sync: pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, phich_duration %d, phich_resource %s!\n",
            ue->Mod_id,
            frame_parms->nb_antenna_ports_eNB,
            pbch_tx_ant,
            ue->proc.proc_rxtx[0].frame_rx,
            frame_parms->N_RB_DL,
            frame_parms->phich_config_common.phich_duration,
            phich_resource);  //frame_parms->phich_config_common.phich_resource);
269
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
270 271 272 273 274 275 276
    } else {
      for(int i=0; i<RX_NB_TH; i++) {
        ue->proc.proc_rxtx[i].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&31)<<1) + (ue->pbch_vars[0]->decoded_output[1]>>7))<<4;
        ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
      }

      LOG_D(PHY,"[UE%d] Initial sync: FeMBMS pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, AdditionalNonMBSFN_SF %d, frame_mod4 %d\n",
277 278 279 280 281
            ue->Mod_id,
            frame_parms->nb_antenna_ports_eNB,
            pbch_tx_ant,
            ue->proc.proc_rxtx[0].frame_rx,
            frame_parms->N_RB_DL,
laurent's avatar
laurent committed
282 283 284 285 286
            0,
            frame_mod4
           );
    }

287
#endif
288
    return(0);
289
  } else {
290 291 292 293
    return(-1);
  }
}

294 295 296 297
char phich_string[13][4] = {"","1/6","","1/2","","","one","","","","","","two"};
char duplex_string[2][4] = {"FDD","TDD"};
char prefix_string[2][9] = {"NORMAL","EXTENDED"};

298
int initial_sync(PHY_VARS_UE *ue, runmode_t mode) {
299
  int32_t sync_pos,sync_pos2,sync_pos_slot;
300 301 302 303
  int32_t metric_fdd_ncp=0,metric_fdd_ecp=0,metric_tdd_ncp=0,metric_tdd_ecp=0;
  uint8_t phase_fdd_ncp,phase_fdd_ecp,phase_tdd_ncp,phase_tdd_ecp;
  uint8_t flip_fdd_ncp,flip_fdd_ecp,flip_tdd_ncp,flip_tdd_ecp;
  //  uint16_t Nid_cell_fdd_ncp=0,Nid_cell_fdd_ecp=0,Nid_cell_tdd_ncp=0,Nid_cell_tdd_ecp=0;
304
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
305 306 307
  int ret=-1;
  int aarx,rx_power=0;
  // First try FDD normal prefix
Raymond Knopp's avatar
 
Raymond Knopp committed
308 309
  frame_parms->Ncp=NORMAL;
  frame_parms->frame_type=FDD;
310
  frame_parms->nb_antenna_ports_eNB = 2;
311
  init_frame_parms(frame_parms,1);
kaltenbe's avatar
kaltenbe committed
312
  /*
bruno mongazon's avatar
bruno mongazon committed
313
  LOG_M("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
kaltenbe's avatar
kaltenbe committed
314 315
  exit(-1);
  */
316
  sync_pos = lte_sync_time(ue->common_vars.rxdata,
317
                           frame_parms,
318
                           (int *)&ue->common_vars.eNb_id);
319

bruno mongazon's avatar
bruno mongazon committed
320
  //  LOG_M("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
321 322 323 324 325
  if (sync_pos >= frame_parms->nb_prefix_samples)
    sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;
  else
    sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples;

326
  LOG_D(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n",ue->Mod_id,sync_pos,ue->common_vars.eNb_id);
327 328 329 330 331
  // SSS detection
  // PSS is hypothesized in last symbol of first slot in Frame
  sync_pos_slot = (frame_parms->samples_per_tti>>1) - frame_parms->ofdm_symbol_size - frame_parms->nb_prefix_samples;

  if (sync_pos2 >= sync_pos_slot)
332
    ue->rx_offset = sync_pos2 - sync_pos_slot;
333
  else
334
    ue->rx_offset = FRAME_LENGTH_COMPLEX_SAMPLES + sync_pos2 - sync_pos_slot;
335

336
  if (((sync_pos2 - sync_pos_slot) >=0 ) &&
337
      ((sync_pos2 - sync_pos_slot) < ((FRAME_LENGTH_COMPLEX_SAMPLES-frame_parms->samples_per_tti/2)))) {
338
    LOG_D(PHY,"Calling sss detection (FDD normal CP)\n");
339
    rx_sss(ue,&metric_fdd_ncp,&flip_fdd_ncp,&phase_fdd_ncp);
340
    frame_parms->nushift  = frame_parms->Nid_cell%6;
341

342
    if (flip_fdd_ncp==1)
343
      ue->rx_offset += (FRAME_LENGTH_COMPLEX_SAMPLES>>1);
344

345 346 347
    init_frame_parms(&ue->frame_parms,1);
    lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell);
    ret = pbch_detection(ue,mode);
bruno mongazon's avatar
bruno mongazon committed
348
    //   LOG_M("rxdata2.m","rxd2",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
349
    LOG_D(PHY,"FDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
350
          frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret);
351
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
352 353 354 355 356 357 358 359 360 361

    if (ret==-1) {
      ue->FeMBMS_active = 2;
      ret = pbch_detection(ue,mode);

      if (ret==-1) {
        ue->FeMBMS_active = 0;
        frame_parms->FeMBMS_active = 0;
      } else frame_parms->FeMBMS_active = 1;

362
      LOG_D(PHY,"FeMBMS Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
laurent's avatar
laurent committed
363 364 365
            frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret);
    }

366 367
#endif
  } else {
368
    LOG_D(PHY,"FDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot);
369 370 371 372
  }

  if (ret==-1) {
    // Now FDD extended prefix
Raymond Knopp's avatar
 
Raymond Knopp committed
373 374
    frame_parms->Ncp=EXTENDED;
    frame_parms->frame_type=FDD;
375
    init_frame_parms(frame_parms,1);
376

377 378 379 380
    if (sync_pos < frame_parms->nb_prefix_samples)
      sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples;
    else
      sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;
381

382 383
    // PSS is hypothesized in last symbol of first slot in Frame
    sync_pos_slot = (frame_parms->samples_per_tti>>1) - frame_parms->ofdm_symbol_size - (frame_parms->nb_prefix_samples);
384

385
    if (sync_pos2 >= sync_pos_slot)
386
      ue->rx_offset = sync_pos2 - sync_pos_slot;
387
    else
388
      ue->rx_offset = FRAME_LENGTH_COMPLEX_SAMPLES + sync_pos2 - sync_pos_slot;
389

390
    //msg("nb_prefix_samples %d, rx_offset %d\n",frame_parms->nb_prefix_samples,ue->rx_offset);
391

392 393
    if (((sync_pos2 - sync_pos_slot) >=0 ) &&
        ((sync_pos2 - sync_pos_slot) < ((FRAME_LENGTH_COMPLEX_SAMPLES-frame_parms->samples_per_tti/2)))) {
394
      rx_sss(ue,&metric_fdd_ecp,&flip_fdd_ecp,&phase_fdd_ecp);
395
      frame_parms->nushift  = frame_parms->Nid_cell%6;
396

397
      if (flip_fdd_ecp==1)
398
        ue->rx_offset += (FRAME_LENGTH_COMPLEX_SAMPLES>>1);
399

400 401 402
      init_frame_parms(&ue->frame_parms,1);
      lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell);
      ret = pbch_detection(ue,mode);
bruno mongazon's avatar
bruno mongazon committed
403
      //     LOG_M("rxdata3.m","rxd3",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
404
      LOG_D(PHY,"FDD Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
405
            frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret);
406 407
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))

laurent's avatar
laurent committed
408 409 410
      if (ret==-1) {
        ue->FeMBMS_active = 2;
        ret = pbch_detection(ue,mode);
411

laurent's avatar
laurent committed
412 413 414 415 416 417 418 419
        if (ret==-1) {
          ue->FeMBMS_active = 0;
          frame_parms->FeMBMS_active = 0;
        } else frame_parms->FeMBMS_active = 1;

        LOG_I(PHY,"FeMBMS CAS Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
              frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret);
      }
420

laurent's avatar
laurent committed
421
#endif
422
    } else {
423
      LOG_D(PHY,"FDD Extended prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot);
424 425 426 427
    }

    if (ret==-1) {
      // Now TDD normal prefix
Raymond Knopp's avatar
 
Raymond Knopp committed
428 429
      frame_parms->Ncp=NORMAL;
      frame_parms->frame_type=TDD;
430
      frame_parms->tdd_config=1;
431 432 433
      init_frame_parms(frame_parms,1);

      if (sync_pos >= frame_parms->nb_prefix_samples)
434
        sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;
435
      else
436
        sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples;
437 438

      // PSS is hypothesized in 2nd symbol of third slot in Frame (S-subframe)
439 440 441 442 443
      sync_pos_slot = frame_parms->samples_per_tti +
                      (frame_parms->ofdm_symbol_size<<1) +
                      frame_parms->nb_prefix_samples0 +
                      (frame_parms->nb_prefix_samples);

444
      if (sync_pos2 >= sync_pos_slot)
445
        ue->rx_offset = sync_pos2 - sync_pos_slot;
446
      else
447
        ue->rx_offset = (FRAME_LENGTH_COMPLEX_SAMPLES>>1) + sync_pos2 - sync_pos_slot;
448

449
      rx_sss(ue,&metric_tdd_ncp,&flip_tdd_ncp,&phase_tdd_ncp);
450 451

      if (flip_tdd_ncp==1)
452
        ue->rx_offset += (FRAME_LENGTH_COMPLEX_SAMPLES>>1);
453 454

      frame_parms->nushift  = frame_parms->Nid_cell%6;
455 456 457
      init_frame_parms(&ue->frame_parms,1);
      lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell);
      ret = pbch_detection(ue,mode);
bruno mongazon's avatar
bruno mongazon committed
458
      //      LOG_M("rxdata4.m","rxd4",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
459
      LOG_D(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
460 461 462 463 464 465
            frame_parms->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,flip_tdd_ncp,ret);

      if (ret==-1) {
        // Now TDD extended prefix
        frame_parms->Ncp=EXTENDED;
        frame_parms->frame_type=TDD;
466
        frame_parms->tdd_config=1;
467 468 469 470 471 472 473 474 475 476 477 478
        init_frame_parms(frame_parms,1);
        sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;

        if (sync_pos >= frame_parms->nb_prefix_samples)
          sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;
        else
          sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples;

        // PSS is hypothesized in 2nd symbol of third slot in Frame (S-subframe)
        sync_pos_slot = frame_parms->samples_per_tti + (frame_parms->ofdm_symbol_size<<1) + (frame_parms->nb_prefix_samples<<1);

        if (sync_pos2 >= sync_pos_slot)
479
          ue->rx_offset = sync_pos2 - sync_pos_slot;
480
        else
481
          ue->rx_offset = (FRAME_LENGTH_COMPLEX_SAMPLES>>1) + sync_pos2 - sync_pos_slot;
482

483
        rx_sss(ue,&metric_tdd_ecp,&flip_tdd_ecp,&phase_tdd_ecp);
484 485 486
        frame_parms->nushift  = frame_parms->Nid_cell%6;

        if (flip_tdd_ecp==1)
487
          ue->rx_offset += (FRAME_LENGTH_COMPLEX_SAMPLES>>1);
488

489 490 491
        init_frame_parms(&ue->frame_parms,1);
        lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell);
        ret = pbch_detection(ue,mode);
492
        //  LOG_M("rxdata5.m","rxd5",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
493
        LOG_D(PHY,"TDD Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
494
              frame_parms->Nid_cell,metric_tdd_ecp,phase_tdd_ecp,flip_tdd_ecp,ret);
495 496 497
      }
    }
  }
498

499
  /* Consider this is a false detection if the offset is > 1000 Hz */
500 501 502
  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);
503 504
  }

505
  if (ret==0) {  // PBCH found so indicate sync to higher layers and configure frame parameters
Cedric Roux's avatar
Cedric Roux committed
506
    LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
507

508
    if (ue->UE_scan_carrier == 0) {
509
#if UE_AUTOTEST_TRACE
510
      LOG_I(PHY,"[UE  %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
511 512 513 514 515 516
            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
517 518
      generate_pcfich_reg_mapping(frame_parms);
      generate_phich_reg_mapping(frame_parms);
519
      ue->pbch_vars[0]->pdu_errors_conseq=0;
520
    }
521

Cedric Roux's avatar
Cedric Roux committed
522
    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,
523 524 525 526 527 528 529
          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])));
Cedric Roux's avatar
Cedric Roux committed
530
    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",
531 532 533 534 535 536 537 538 539
          ue->Mod_id,
          ue->proc.proc_rxtx[0].frame_rx,
          duplex_string[ue->frame_parms.frame_type],
          prefix_string[ue->frame_parms.Ncp],
          ue->frame_parms.Nid_cell,
          ue->frame_parms.N_RB_DL,
          ue->frame_parms.phich_config_common.phich_duration,
          phich_string[ue->frame_parms.phich_config_common.phich_resource],
          ue->frame_parms.nb_antenna_ports_eNB);
Cedric Roux's avatar
Cedric Roux committed
540
    LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
541 542 543 544
          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);
545
  } else {
546 547
    LOG_D(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id);
    LOG_D(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n",ue->Mod_id,sync_pos,ue->common_vars.eNb_id);
548
    /*      LOG_I(PHY,"[UE%d] Initial sync: (metric fdd_ncp %d (%d), metric fdd_ecp %d (%d), metric_tdd_ncp %d (%d), metric_tdd_ecp %d (%d))\n",
549
          ue->Mod_id,
550 551 552 553
          metric_fdd_ncp,Nid_cell_fdd_ncp,
          metric_fdd_ecp,Nid_cell_fdd_ecp,
          metric_tdd_ncp,Nid_cell_tdd_ncp,
          metric_tdd_ecp,Nid_cell_tdd_ecp);*/
554
    LOG_D(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id,
555
          frame_parms->Nid_cell,frame_parms->frame_type);
556 557 558 559
    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++;
560 561
  }

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

566 567
    // do a measurement on the best guess of the PSS
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
568
      rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2],
569
                                frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
570

571 572
    /*
    // do a measurement on the full frame
573
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
574
      rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0],
575
        frame_parms->samples_per_tti*10);
576
    */
577
    // we might add a low-pass filter here later
578
    ue->measurements.rx_power_avg[0] = rx_power/frame_parms->nb_antennas_rx;
579
    ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
580
    LOG_I(PHY,"[UE%d] Initial sync : Estimated power: %d dB\n",ue->Mod_id,ue->measurements.rx_power_avg_dB[0] );
581

laurent's avatar
laurent committed
582
    if (IS_SOFTMODEM_BASICSIM )
583
      phy_adjust_gain(ue,ue->measurements.rx_power_avg_dB[0],0);
584
  } else {
laurent's avatar
laurent committed
585
    if (IS_SOFTMODEM_BASICSIM )
586
      phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0);
587 588
  }

589 590
  return ret;
}
591