lte_sync_time.c 21.9 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
 * 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
 */
ghaddab's avatar
ghaddab committed
21

22 23 24
/* file: lte_sync_time.c
   purpose: coarse timing synchronization for LTE (using PSS)
   author: florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it
25
   date: 22.10.2009
26 27 28
*/

//#include <string.h>
29 30
#include "PHY/defs_UE.h"
#include "PHY/phy_extern_ue.h"
31 32
#include <math.h>

33 34 35 36 37

#include "LAYER2/MAC/mac.h"
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"

38 39
// Note: this is for prototype of generate_drs_pusch (OTA synchronization of RRUs)
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
40 41 42 43

int* sync_corr_ue0 = NULL;
int* sync_corr_ue1 = NULL;
int* sync_corr_ue2 = NULL;
44 45
int sync_tmp[2048*4] __attribute__((aligned(32)));
short syncF_tmp[2048*2] __attribute__((aligned(32)));
46 47 48



49 50
int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms )   // LTE_UE_COMMON *common_vars
{
51 52 53 54 55 56

  int i,k;

  sync_corr_ue0 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
  sync_corr_ue1 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
  sync_corr_ue2 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
57

58 59
  if (sync_corr_ue0) {
#ifdef DEBUG_PHY
60
    LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue0);
61 62
#endif
    //common_vars->sync_corr = sync_corr;
63
  } else {
64
    LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue0 not allocated\n");
65 66 67 68 69
    return(-1);
  }

  if (sync_corr_ue1) {
#ifdef DEBUG_PHY
70
    LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue1);
71 72
#endif
    //common_vars->sync_corr = sync_corr;
73
  } else {
74
    LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue1 not allocated\n");
75 76 77 78 79
    return(-1);
  }

  if (sync_corr_ue2) {
#ifdef DEBUG_PHY
80
    LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue2);
81 82
#endif
    //common_vars->sync_corr = sync_corr;
83
  } else {
84
    LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue2 not allocated\n");
85 86 87 88
    return(-1);
  }

  //  primary_synch0_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
89
  primary_synch0_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
90

91 92
  if (primary_synch0_time) {
    //    bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
93
    bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
94
#ifdef DEBUG_PHY
95
    LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time allocated at %p\n", primary_synch0_time);
96
#endif
97
  } else {
98
    LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time not allocated\n");
99 100 101 102
    return(-1);
  }

  //  primary_synch1_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
103
  primary_synch1_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
104

105 106
  if (primary_synch1_time) {
    //    bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
107
    bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
108
#ifdef DEBUG_PHY
109
    LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time allocated at %p\n", primary_synch1_time);
110
#endif
111
  } else {
112
    LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time not allocated\n");
113 114 115 116
    return(-1);
  }

  //  primary_synch2_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
117
  primary_synch2_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
118

119 120
  if (primary_synch2_time) {
    //    bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
121
    bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
122
#ifdef DEBUG_PHY
123
    LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time allocated at %p\n", primary_synch2_time);
124
#endif
125
  } else {
126
    LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time not allocated\n");
127 128 129 130 131 132
    return(-1);
  }


  // generate oversampled sync_time sequences
  k=frame_parms->ofdm_symbol_size-36;
133

134 135 136 137
  for (i=0; i<72; i++) {
    syncF_tmp[2*k] = primary_synch0[2*i]>>2;  //we need to shift input to avoid overflow in fft
    syncF_tmp[2*k+1] = primary_synch0[2*i+1]>>2;
    k++;
138

139 140 141 142 143 144
    if (k >= frame_parms->ofdm_symbol_size) {
      k++;  // skip DC carrier
      k-=frame_parms->ofdm_symbol_size;
    }
  }

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
  switch (frame_parms->N_RB_DL) {
  case 6:
    idft128((short*)syncF_tmp,          /// complex input
	   (short*)sync_tmp, /// complex output
	   1);
    break;
  case 25:
    idft512((short*)syncF_tmp,          /// complex input
	   (short*)sync_tmp, /// complex output
	   1);
    break;
  case 50:
    idft1024((short*)syncF_tmp,          /// complex input
	    (short*)sync_tmp, /// complex output
	    1);
    break;
    
  case 75:
    idft1536((short*)syncF_tmp,          /// complex input
164 165
	     (short*)sync_tmp,
	     1); /// complex output
166 167 168
    break;
  case 100:
    idft2048((short*)syncF_tmp,          /// complex input
169 170
	     (short*)sync_tmp, /// complex output
	     1);
171 172 173 174 175
    break;
  default:
    LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
    break;
  }
176 177

  for (i=0; i<frame_parms->ofdm_symbol_size; i++)
178
    ((int32_t*)primary_synch0_time)[i] = sync_tmp[i];
179 180

  k=frame_parms->ofdm_symbol_size-36;
181

182 183 184 185
  for (i=0; i<72; i++) {
    syncF_tmp[2*k] = primary_synch1[2*i]>>2;  //we need to shift input to avoid overflow in fft
    syncF_tmp[2*k+1] = primary_synch1[2*i+1]>>2;
    k++;
186

187 188 189 190 191 192
    if (k >= frame_parms->ofdm_symbol_size) {
      k++;  // skip DC carrier
      k-=frame_parms->ofdm_symbol_size;
    }
  }

193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
  switch (frame_parms->N_RB_DL) {
  case 6:
    idft128((short*)syncF_tmp,          /// complex input
	   (short*)sync_tmp, /// complex output
	   1);
    break;
  case 25:
    idft512((short*)syncF_tmp,          /// complex input
	   (short*)sync_tmp, /// complex output
	   1);
    break;
  case 50:
    idft1024((short*)syncF_tmp,          /// complex input
	    (short*)sync_tmp, /// complex output
	    1);
    break;
    
  case 75:
    idft1536((short*)syncF_tmp,          /// complex input
212 213
	     (short*)sync_tmp, /// complex output
	     1);
214 215 216 217 218 219 220 221 222 223
    break;
  case 100:
    idft2048((short*)syncF_tmp,          /// complex input
	    (short*)sync_tmp, /// complex output
	    1);
    break;
  default:
    LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
    break;
  }
224 225

  for (i=0; i<frame_parms->ofdm_symbol_size; i++)
226
    ((int32_t*)primary_synch1_time)[i] = sync_tmp[i];
227 228

  k=frame_parms->ofdm_symbol_size-36;
229

230 231 232 233
  for (i=0; i<72; i++) {
    syncF_tmp[2*k] = primary_synch2[2*i]>>2;  //we need to shift input to avoid overflow in fft
    syncF_tmp[2*k+1] = primary_synch2[2*i+1]>>2;
    k++;
234

235 236 237 238 239 240
    if (k >= frame_parms->ofdm_symbol_size) {
      k++;  // skip DC carrier
      k-=frame_parms->ofdm_symbol_size;
    }
  }

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
  switch (frame_parms->N_RB_DL) {
  case 6:
    idft128((short*)syncF_tmp,          /// complex input
	   (short*)sync_tmp, /// complex output
	   1);
    break;
  case 25:
    idft512((short*)syncF_tmp,          /// complex input
	   (short*)sync_tmp, /// complex output
	   1);
    break;
  case 50:
    idft1024((short*)syncF_tmp,          /// complex input
	    (short*)sync_tmp, /// complex output
	    1);
    break;
    
  case 75:
    idft1536((short*)syncF_tmp,          /// complex input
260 261
	     (short*)sync_tmp, /// complex output
	     1);
262 263 264 265 266 267 268 269 270 271
    break;
  case 100:
    idft2048((short*)syncF_tmp,          /// complex input
	    (short*)sync_tmp, /// complex output
	    1);
    break;
  default:
    LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
    break;
  }
272 273

  for (i=0; i<frame_parms->ofdm_symbol_size; i++)
274
    ((int32_t*)primary_synch2_time)[i] = sync_tmp[i];
275 276 277 278




279
  if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
280 281 282 283
    LOG_M("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1);
    LOG_M("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1);
    LOG_M("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1);
  }
284 285 286 287
  return (1);
}


288 289
void lte_sync_time_free(void)
{
290

291

292
  if (sync_corr_ue0) {
293
    LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue0);
294 295
    free(sync_corr_ue0);
  }
296

297
  if (sync_corr_ue1) {
298
    LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue1);
299 300
    free(sync_corr_ue1);
  }
301

302
  if (sync_corr_ue2) {
303
    LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue2);
304 305
    free(sync_corr_ue2);
  }
306

307
  if (primary_synch0_time) {
308
    LOG_D(PHY,"Freeing primary_sync0_time ...\n");
309 310
    free(primary_synch0_time);
  }
311

312
  if (primary_synch1_time) {
313
    LOG_D(PHY,"Freeing primary_sync1_time ...\n");
314 315
    free(primary_synch1_time);
  }
316

317
  if (primary_synch2_time) {
318
    LOG_D(PHY,"Freeing primary_sync2_time ...\n");
319 320
    free(primary_synch2_time);
  }
321

322 323 324
  sync_corr_ue0 = NULL;
  sync_corr_ue1 = NULL;
  sync_corr_ue2 = NULL;
325 326 327
  primary_synch0_time = NULL;
  primary_synch1_time = NULL;
  primary_synch2_time = NULL;
328 329
}

330 331
static inline int abs32(int x)
{
332 333 334
  return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1]));
}

335 336
#define SHIFT 17

337
int lte_sync_time(int **rxdata, ///rx data in time domain
338 339 340
                  LTE_DL_FRAME_PARMS *frame_parms,
                  int *eNB_id)
{
341 342 343 344 345 346 347 348 349 350 351



  // perform a time domain correlation using the oversampled sync sequence

  unsigned int n, ar, s, peak_pos, peak_val, sync_source;
  int result,result2;
  int sync_out[3] = {0,0,0},sync_out2[3] = {0,0,0};
  int tmp[3] = {0,0,0};
  int length =   LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti>>1;

352
  //LOG_D(PHY,"[SYNC TIME] Calling sync_time.\n");
Eurecom's avatar
Eurecom committed
353 354 355 356 357 358
  AssertFatal(sync_corr_ue0 != NULL,
             "sync_corr_ue0 not yet allocated! Exiting.\n");
  AssertFatal(sync_corr_ue1 != NULL,
             "sync_corr_ue0 not yet allocated! Exiting.\n");
  AssertFatal(sync_corr_ue2 != NULL,
             "sync_corr_ue0 not yet allocated! Exiting.\n");
359 360 361 362 363

  peak_val = 0;
  peak_pos = 0;
  sync_source = 0;

364

365 366 367 368 369 370 371 372
  for (n=0; n<length; n+=4) {

    sync_corr_ue0[n] = 0;
    sync_corr_ue0[n+length] = 0;
    sync_corr_ue1[n] = 0;
    sync_corr_ue1[n+length] = 0;
    sync_corr_ue2[n] = 0;
    sync_corr_ue2[n+length] = 0;
373 374

    for (s=0; s<3; s++) {
375 376 377
      sync_out[s]=0;
      sync_out2[s]=0;
    }
378

379 380 381 382
    //    if (n<(length-frame_parms->ofdm_symbol_size-frame_parms->nb_prefix_samples)) {
    if (n<(length-frame_parms->ofdm_symbol_size)) {

      //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
383 384
      for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {

385 386
        result  = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
        result2 = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
387 388 389 390 391 392 393 394 395

        ((short*)sync_corr_ue0)[2*n] += ((short*) &result)[0];
        ((short*)sync_corr_ue0)[2*n+1] += ((short*) &result)[1];
        ((short*)sync_corr_ue0)[2*(length+n)] += ((short*) &result2)[0];
        ((short*)sync_corr_ue0)[(2*(length+n))+1] += ((short*) &result2)[1];
        ((short*)sync_out)[0] += ((short*) &result)[0];
        ((short*)sync_out)[1] += ((short*) &result)[1];
        ((short*)sync_out2)[0] += ((short*) &result2)[0];
        ((short*)sync_out2)[1] += ((short*) &result2)[1];
396
      }
397 398

      for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
399 400
        result = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
        result2 = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
401 402 403 404 405 406 407 408 409
        ((short*)sync_corr_ue1)[2*n] += ((short*) &result)[0];
        ((short*)sync_corr_ue1)[2*n+1] += ((short*) &result)[1];
        ((short*)sync_corr_ue1)[2*(length+n)] += ((short*) &result2)[0];
        ((short*)sync_corr_ue1)[(2*(length+n))+1] += ((short*) &result2)[1];

        ((short*)sync_out)[2] += ((short*) &result)[0];
        ((short*)sync_out)[3] += ((short*) &result)[1];
        ((short*)sync_out2)[2] += ((short*) &result2)[0];
        ((short*)sync_out2)[3] += ((short*) &result2)[1];
410 411
      }

412 413
      for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {

414 415
        result = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
        result2 = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
416 417 418 419 420 421 422 423
        ((short*)sync_corr_ue2)[2*n] += ((short*) &result)[0];
        ((short*)sync_corr_ue2)[2*n+1] += ((short*) &result)[1];
        ((short*)sync_corr_ue2)[2*(length+n)] += ((short*) &result2)[0];
        ((short*)sync_corr_ue2)[(2*(length+n))+1] += ((short*) &result2)[1];
        ((short*)sync_out)[4] += ((short*) &result)[0];
        ((short*)sync_out)[5] += ((short*) &result)[1];
        ((short*)sync_out2)[4] += ((short*) &result2)[0];
        ((short*)sync_out2)[5] += ((short*) &result2)[1];
424
      }
425

426
    }
427

428 429 430 431 432 433 434 435 436
    // calculate the absolute value of sync_corr[n]

    sync_corr_ue0[n] = abs32(sync_corr_ue0[n]);
    sync_corr_ue0[n+length] = abs32(sync_corr_ue0[n+length]);
    sync_corr_ue1[n] = abs32(sync_corr_ue1[n]);
    sync_corr_ue1[n+length] = abs32(sync_corr_ue1[n+length]);
    sync_corr_ue2[n] = abs32(sync_corr_ue2[n]);
    sync_corr_ue2[n+length] = abs32(sync_corr_ue2[n+length]);

437
    for (s=0; s<3; s++) {
438
      tmp[s] = (abs32(sync_out[s])>>1) + (abs32(sync_out2[s])>>1);
439

440
      if (tmp[s]>peak_val) {
441 442 443 444 445 446 447 448
        peak_val = tmp[s];
        peak_pos = n;
        sync_source = s;
        /*
        printf("s %d: n %d sync_out %d, sync_out2  %d (sync_corr %d,%d), (%d,%d) (%d,%d)\n",s,n,abs32(sync_out[s]),abs32(sync_out2[s]),sync_corr_ue0[n],
               sync_corr_ue0[n+length],((int16_t*)&sync_out[s])[0],((int16_t*)&sync_out[s])[1],((int16_t*)&sync_out2[s])[0],((int16_t*)&sync_out2[s])[1]);
        */
      }
449 450 451 452
    }
  }

  *eNB_id = sync_source;
453

454
  LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val,dB_fixed(peak_val)/2);
455

456

457
  if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
458 459 460 461 462 463 464 465
    static int debug_cnt;
    if (debug_cnt == 0) {
      LOG_M("sync_corr0_ue.m","synccorr0",sync_corr_ue0,2*length,1,2);
      LOG_M("sync_corr1_ue.m","synccorr1",sync_corr_ue1,2*length,1,2);
      LOG_M("sync_corr2_ue.m","synccorr2",sync_corr_ue2,2*length,1,2);
      LOG_M("rxdata0.m","rxd0",rxdata[0],length<<1,1,1);
      //    exit(-1);
    } else {
466 467
    debug_cnt++;
  }
468
} 
469 470 471 472 473 474


  return(peak_pos);

}

475

476

477 478 479
int ru_sync_time_init(RU_t *ru)   // LTE_UE_COMMON *common_vars
{

magounak's avatar
magounak committed
480
  /*
481 482
  int16_t dmrs[2048];
  int16_t *dmrsp[2] = {dmrs,NULL};
magounak's avatar
magounak committed
483
  */
484

magounak's avatar
magounak committed
485
  int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
486 487
//  int32_t *dmrsp[2] = {&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL};
  int32_t *dmrsp[2] = {&dmrs[0],NULL};
magounak's avatar
magounak committed
488 489 490

  generate_ul_ref_sigs();
 
magounak's avatar
magounak committed
491
  ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t)); 
492 493
  ru->dmrs_corr = (uint64_t*)malloc16_clear(ru->frame_parms.samples_per_tti*10*sizeof(uint64_t));

494 495
  generate_drs_pusch(NULL,NULL,
		     &ru->frame_parms,
496
		     dmrsp,
497 498 499 500 501 502 503 504 505
		     0,
		     AMP,
		     0,
		     0,
		     ru->frame_parms.N_RB_DL,
		     0);

  switch (ru->frame_parms.N_RB_DL) {
  case 6:
506
    idft128((int16_t*)(&dmrsp[0][3*ru->frame_parms.ofdm_symbol_size]),
507 508 509 510
	    ru->dmrssync, /// complex output
	    1);
    break;
  case 25:
511
    idft512((int16_t*)(&dmrsp[0][3*ru->frame_parms.ofdm_symbol_size]),
512 513 514 515
	    ru->dmrssync, /// complex output
	    1);
    break;
  case 50:
516
    idft1024((int16_t*)(&dmrsp[0][3*ru->frame_parms.ofdm_symbol_size]),
517 518 519
	    ru->dmrssync, /// complex output
	    1);
    break;
520
     
521
  case 75:
522
    idft1536((int16_t*)(&dmrsp[0][3*ru->frame_parms.ofdm_symbol_size]),
523 524 525 526
	     ru->dmrssync,
	     1); /// complex output
    break;
  case 100:
527
    idft2048((int16_t*)(&dmrsp[0][3*ru->frame_parms.ofdm_symbol_size]),
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
	     ru->dmrssync, /// complex output
	     1);
    break;
  default:
    AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms.N_RB_DL);
    break;
  }

  return(0);
}

void ru_sync_time_free(RU_t *ru) {

  AssertFatal(ru->dmrssync!=NULL,"ru->dmrssync is NULL\n");
  free(ru->dmrssync);
543
  if (ru->dmrs_corr) free(ru->dmrs_corr);
544 545
}

546 547
//#define DEBUG_PHY

548
int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
549 550 551 552 553
                      LTE_DL_FRAME_PARMS *frame_parms,
                      uint32_t length,
                      uint32_t *peak_val_out,
                      uint32_t *sync_corr_eNB)
{
554 555 556

  // perform a time domain correlation using the oversampled sync sequence

557 558
  unsigned int n, ar, peak_val, peak_pos;
  uint64_t mean_val;
559 560 561 562
  int result;
  short *primary_synch_time;
  int eNB_id = frame_parms->Nid_cell%3;

563
  // LOG_E(PHY,"[SYNC TIME] Calling sync_time_eNB(%p,%p,%d,%d)\n",rxdata,frame_parms,eNB_id,length);
564
  if (sync_corr_eNB == NULL) {
565
    LOG_E(PHY,"[SYNC TIME] sync_corr_eNB not yet allocated! Exiting.\n");
566 567 568 569 570 571 572
    return(-1);
  }

  switch (eNB_id) {
  case 0:
    primary_synch_time = (short*)primary_synch0_time;
    break;
573

574 575 576
  case 1:
    primary_synch_time = (short*)primary_synch1_time;
    break;
577

578 579 580
  case 2:
    primary_synch_time = (short*)primary_synch2_time;
    break;
581

582
  default:
583
    LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n");
584 585 586 587 588 589 590 591 592 593 594 595 596 597
    return (-1);
  }

  peak_val = 0;
  peak_pos = 0;
  mean_val = 0;

  for (n=0; n<length; n+=4) {

    sync_corr_eNB[n] = 0;

    if (n<(length-frame_parms->ofdm_symbol_size-frame_parms->nb_prefix_samples)) {

      //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
598
      for (ar=0; ar<frame_parms->nb_antennas_rx; ar++)  {
599

600
        result = dot_product((short*)primary_synch_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
601 602 603
        //((short*)sync_corr)[2*n]   += ((short*) &result)[0];
        //((short*)sync_corr)[2*n+1] += ((short*) &result)[1];
        sync_corr_eNB[n] += abs32(result);
604 605 606 607

      }

    }
608

609 610 611
    /*
    if (eNB_id == 2) {
      printf("sync_time_eNB %d : %d,%d (%d)\n",n,sync_corr_eNB[n],mean_val,
612
       peak_val);
613 614
    }
    */
615
    mean_val += sync_corr_eNB[n];
616 617 618 619 620 621 622

    if (sync_corr_eNB[n]>peak_val) {
      peak_val = sync_corr_eNB[n];
      peak_pos = n;
    }
  }

623 624
  mean_val/=length;

625 626
  *peak_val_out = peak_val;

627
  if (peak_val <= (40*(uint32_t)mean_val)) {
Eurecom's avatar
Eurecom committed
628
    LOG_I(PHY,"[SYNC TIME] No peak found (%u,%u,%"PRIu64",%"PRIu64")\n",peak_pos,peak_val,mean_val,40*mean_val);
629
    return(-1);
630
  } else {
Eurecom's avatar
Eurecom committed
631
    LOG_I(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %"PRIu64"\n",peak_pos,peak_val,mean_val);
632 633 634 635 636
    return(peak_pos);
  }

}

637

638 639 640 641 642 643
static inline int64_t abs64(int64_t x)
{
  return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t)
((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1]));
}

644 645 646 647 648 649 650
int ru_sync_time(RU_t *ru,
		 int64_t *lev,
		 int64_t *avg)
{


  LTE_DL_FRAME_PARMS *frame_parms = &ru->frame_parms;
651
  RU_CALIBRATION *calibration = &ru->calibration;
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
		      
  // perform a time domain correlation using the oversampled sync sequence

  int length =   LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti;
  

  // circular copy of beginning to end of rxdata buffer. Note: buffer should be big enough upon calling this function
  for (int ar=0;ar<ru->nb_rx;ar++) memcpy((void*)&ru->common.rxdata[ar][2*length],
					  (void*)&ru->common.rxdata[ar][0],
					  frame_parms->ofdm_symbol_size);
  
  int32_t tmp0;
  int32_t magtmp0,maxlev0=0;
  int     maxpos0=0;
  int64_t avg0=0;
667 668
  int64_t result;
  int64_t dmrs_corr;
669

670 671 672 673 674
  int maxval=0;
  for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
    maxval = max(maxval,ru->dmrssync[i]);
    maxval = max(maxval,-ru->dmrssync[i]);
  }
675 676 677 678 679 680 681 682

  if (ru->state == RU_CHECK_SYNC) {
  	for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
    		maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]);
	        maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]);
        }
  }

683
  int shift = log2_approx(maxval);
684 685 686

  for (int n=0; n<length; n+=4) {

687
    dmrs_corr = 0;
688 689 690 691

    //calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
    for (int ar=0; ar<ru->nb_rx; ar++) {
      
692 693 694 695
      result  = dot_product64(ru->dmrssync,
			      (int16_t*) &ru->common.rxdata[ar][n],
			      frame_parms->ofdm_symbol_size,
			      shift);     
696 697 698 699 700 701 702

      if (ru->state == RU_CHECK_SYNC) {
      	result  = dot_product64((int16_t*) &calibration->drs_ch_estimates_time[ar],
                              (int16_t*) &ru->common.rxdata[ar][n],
                              frame_parms->ofdm_symbol_size,
                              shift);
      }
703
      dmrs_corr += abs64(result);
704
    }
705
    if (ru->dmrs_corr != NULL) ru->dmrs_corr[n] = dmrs_corr;
706 707 708 709

    // tmpi holds <synchi,rx0>+<synci,rx1>+...+<synchi,rx_{nbrx-1}>


710 711
    if (dmrs_corr>maxlev0) { maxlev0 = dmrs_corr; maxpos0 = n; }
    avg0 += dmrs_corr;
712 713 714
  }
  avg0/=(length/4);

715
  int dmrsoffset = frame_parms->samples_per_tti + (3*frame_parms->ofdm_symbol_size)+(3*frame_parms->nb_prefix_samples) + frame_parms->nb_prefix_samples0;
716
  
717
  if ((int64_t)maxlev0 > (10*avg0)) {*lev = maxlev0; *avg=avg0; return((length+maxpos0-dmrsoffset)%length);}
718 719 720 721 722

  return(-1);


}
723