lte_dl_channel_estimation.c 27.8 KB
Newer Older
ghaddab's avatar
ghaddab committed
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16
    Copyright(c) 1999 - 2014 Eurecom

    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.


    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19 20 21 22 23
   see <http://www.gnu.org/licenses/>.

  Contact Information
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
ghaddab's avatar
ghaddab committed
27 28

 *******************************************************************************/
29 30 31 32 33 34
#ifdef USER_MODE
#include <string.h>
#endif
#include "defs.h"
#include "PHY/defs.h"
#include "filt96_32.h"
35
//#define DEBUG_CH
36

37
int lte_dl_channel_estimation(PHY_VARS_UE *ue,
38 39 40 41 42 43 44 45
                              uint8_t eNB_id,
                              uint8_t eNB_offset,
                              unsigned char Ns,
                              unsigned char p,
                              unsigned char l,
                              unsigned char symbol)
{

46 47 48


  int pilot[2][200] __attribute__((aligned(16)));
49
  unsigned char nu,aarx;
50 51
  unsigned short k;
  unsigned int rb,pilot_cnt;
52
  int16_t ch[2],*pil,*rxF,*dl_ch,*dl_ch_prev,*f,*f2,*fl,*f2l2,*fr,*f2r2,*f2_dc,*f_dc;
53 54 55 56
  int ch_offset,symbol_offset;
  //  unsigned int n;
  //  int i;

57
  uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
58

gauthier's avatar
gauthier committed
59
  uint8_t nushift,pilot1,pilot2,pilot3;
60 61
  int **dl_ch_estimates=ue->common_vars.dl_ch_estimates[eNB_offset];
  int **rxdataF=ue->common_vars.rxdataF;
62

63
  if (ue->frame_parms.Ncp == 0) {  // normal prefix
64 65 66
    pilot1 = 4;
    pilot2 = 7;
    pilot3 = 11;
67
  } else { // extended prefix
68 69 70
    pilot1 = 3;
    pilot2 = 6;
    pilot3 = 9;
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
  }

  // recompute nushift with eNB_offset corresponding to adjacent eNB on which to perform channel estimation
  nushift =  Nid_cell%6;

  if ((p==0) && (l==0) )
    nu = 0;
  else if ((p==0) && (l>0))
    nu = 3;
  else if ((p==1) && (l==0))
    nu = 3;
  else if ((p==1) && (l>0))
    nu = 0;
  else {
    msg("lte_dl_channel_estimation: p %d, l %d -> ERROR\n",p,l);
    return(-1);
  }


90 91 92
  //ch_offset     = (l*(ue->frame_parms.ofdm_symbol_size));
  if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
    ch_offset     = ue->frame_parms.ofdm_symbol_size ;
93
  else
94
    ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
95

96
  symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
97 98

  k = (nu + nushift)%6;
99

100
#ifdef DEBUG_CH
101 102
  printf("Channel Estimation : eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size,
         ue->frame_parms.Ncp,l,Ns,k);
103
#endif
104

105 106 107 108 109
  switch (k) {
  case 0 :
    f=filt24_0;  //for first pilot of RB, first half
    f2=filt24_2; //for second pilot of RB, first half
    fl=filt24_0; //for first pilot of leftmost RB
110
    f2l2=filt24_2;
111 112 113 114 115
    //    fr=filt24_2r; //for first pilot of rightmost RB
    fr=filt24_0r2; //for first pilot of rightmost RB
    //    f2r2=filt24_0r2;
    f2r2=filt24_2r;

116 117
    f_dc=filt24_0_dcr;
    f2_dc=filt24_2_dcl;
118 119

    break;
120

121 122 123 124 125 126 127 128 129 130
  case 1 :
    f=filt24_1;
    f2=filt24_3;
    fl=filt24_1l;
    f2l2=filt24_3l2;
    fr=filt24_1r2;
    f2r2=filt24_3r;
    f_dc=filt24_1_dcr;  //for first pilot of RB, first half
    f2_dc=filt24_3_dcl;  //for first pilot of RB, first half
    break;
131 132

  case 2 :
133 134 135
    f=filt24_2;
    f2=filt24_4;
    fl=filt24_2l;
136
    f2l2=filt24_4l2;
137 138 139 140 141
    fr=filt24_2r2;
    f2r2=filt24_4r;
    f_dc=filt24_2_dcr;  //for first pilot of RB, first half
    f2_dc=filt24_4_dcl;  //for first pilot of RB, first half
    break;
142

143 144 145 146 147 148 149 150 151 152
  case 3 :
    f=filt24_3;
    f2=filt24_5;
    fl=filt24_3l;
    f2l2=filt24_5l2;
    fr=filt24_3r2;
    f2r2=filt24_5r;
    f_dc=filt24_3_dcr;  //for first pilot of RB, first half
    f2_dc=filt24_5_dcl;  //for first pilot of RB, first half
    break;
153

154 155 156 157 158 159 160 161 162 163
  case 4 :
    f=filt24_4;
    f2=filt24_6;
    fl=filt24_4l;
    f2l2=filt24_6l2;
    fr=filt24_4r2;
    f2r2=filt24_6r;
    f_dc=filt24_4_dcr;  //for first pilot of RB, first half
    f2_dc=filt24_6_dcl;  //for first pilot of RB, first half
    break;
164

165 166 167 168 169 170 171 172 173 174
  case 5 :
    f=filt24_5;
    f2=filt24_7;
    fl=filt24_5l;
    f2l2=filt24_7l2;
    fr=filt24_5r2;
    f2r2=filt24_7r;
    f_dc=filt24_5_dcr;  //for first pilot of RB, first half
    f2_dc=filt24_7_dcl;  //for first pilot of RB, first half
    break;
175

176 177 178 179 180
  default:
    msg("lte_dl_channel_estimation: k=%d -> ERROR\n",k);
    return(-1);
    break;
  }
181

182 183 184


  // generate pilot
185
  lte_dl_cell_spec_rx(ue,
186 187 188 189 190 191 192
                      eNB_offset,
                      &pilot[p][0],
                      Ns,
                      (l==0)?0:1,
                      p);


193
  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
194

195
    pil   = (int16_t *)&pilot[p][0];
196
    rxF   = (int16_t *)&rxdataF[aarx][((symbol_offset+k+ue->frame_parms.first_carrier_offset))];
197
    dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
198

199

200
    //    if (eNb_id==0)
201 202 203 204 205
    memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
    if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
      multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         1,ue->frame_parms.ofdm_symbol_size);
206
#ifdef DEBUG_CH
207
    printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
208
#endif
209 210 211
    if ((ue->frame_parms.N_RB_DL==6)  ||
        (ue->frame_parms.N_RB_DL==50) ||
        (ue->frame_parms.N_RB_DL==100)) {
212

213 214
      //First half of pilots
      // Treat first 2 pilots specially (left edge)
215 216
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
217 218 219
#ifdef DEBUG_CH
      printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
220
      multadd_real_vector_complex_scalar(fl,
221 222 223
                                         ch,
                                         dl_ch,
                                         24);
224 225 226
      pil+=2;    // Re Im
      rxF+=12;
      dl_ch+=8;
227

228 229
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
230 231 232
#ifdef DEBUG_CH
      printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
233
      multadd_real_vector_complex_scalar(f2l2,
234 235 236
                                         ch,
                                         dl_ch,
                                         24);
237 238 239 240
      pil+=2;
      rxF+=12;
      dl_ch+=16;

241
      for (pilot_cnt=2; pilot_cnt<((ue->frame_parms.N_RB_DL)-1); pilot_cnt+=2) {
242 243 244



245 246
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); //Re
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); //Im
247 248 249
#ifdef DEBUG_CH
	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
250 251 252 253 254 255 256 257 258 259
        multadd_real_vector_complex_scalar(f,
                                           ch,
                                           dl_ch,
                                           24);


        pil+=2;    // Re Im
        rxF+=12;
        dl_ch+=8;

260 261
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
262 263 264
#ifdef DEBUG_CH
	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
265 266 267 268 269 270 271 272
        multadd_real_vector_complex_scalar(f2,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=16;

273
      }
274

275 276
      //       printf("Second half\n");
      // Second half of RBs
277

278
      k = (nu + nushift)%6;
279

280
      if (k > 6)
281 282
        k -=6;

283
      rxF   = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))];
284

285 286 287
#ifdef DEBUG_CH
      printf("second half k %d\n",k);
#endif
288
      for (pilot_cnt=0; pilot_cnt<((ue->frame_parms.N_RB_DL)-3); pilot_cnt+=2) {
289 290


291 292
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
293 294 295
#ifdef DEBUG_CH
	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
296 297 298 299 300 301 302 303
        multadd_real_vector_complex_scalar(f,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=8;

304 305
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
306 307 308
#ifdef DEBUG_CH
	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
309 310 311 312 313 314 315 316
        multadd_real_vector_complex_scalar(f2,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=16;

317
      }
318

319 320
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
321 322 323
#ifdef DEBUG_CH
      printf("pilot %d: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
324
      multadd_real_vector_complex_scalar(fr,
325 326 327
                                         ch,
                                         dl_ch,
                                         24);
328 329 330
      pil+=2;    // Re Im
      rxF+=12;
      dl_ch+=8;
331

332 333
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
334 335 336
#ifdef DEBUG_CH
      printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
337
      multadd_real_vector_complex_scalar(f2r2,
338 339 340
                                         ch,
                                         dl_ch,
                                         24);
341 342 343


    }
344

345
    else if (ue->frame_parms.N_RB_DL==25) {
346 347 348
      //printf("Channel estimation\n");

      // Treat first 2 pilots specially (left edge)
349 350
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
351 352 353 354 355 356 357 358 359

#ifdef DEBUG_CH
      printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);

      //      ch[0] = 1024;
      //      ch[1] = -128;
#endif

      multadd_real_vector_complex_scalar(fl,
360 361 362
                                         ch,
                                         dl_ch,
                                         24);
363 364 365
      pil+=2;    // Re Im
      rxF+=12;
      dl_ch+=8;
366

367 368
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
369 370 371 372 373 374 375 376 377

#ifdef DEBUG_CH
      printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);

      //      ch[0] = 1024;
      //      ch[1] = -128;
#endif

      multadd_real_vector_complex_scalar(f2l2,
378 379 380
                                         ch,
                                         dl_ch,
                                         24);
381 382 383 384
      pil+=2;
      rxF+=12;
      dl_ch+=16;

385
      for (pilot_cnt=2; pilot_cnt<24; pilot_cnt+=2) {
386

387
        // printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
388
        // printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
389

390 391
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
392 393

#ifdef DEBUG_CH
394 395 396 397
        printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);

        //  ch[0] = 1024;
        //  ch[1] = -128;
398
#endif
399 400 401 402 403 404 405 406 407 408


        multadd_real_vector_complex_scalar(f,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;    // Re Im
        rxF+=12;
        dl_ch+=8;

409 410
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
411 412

#ifdef DEBUG_CH
413
        printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
414

415 416
        //  ch[0] = 1024;
        //  ch[1] = -128;
417
#endif
418 419 420 421 422 423 424 425
        multadd_real_vector_complex_scalar(f2,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=16;

426
      }
427

428 429
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
430 431 432 433 434 435 436
#ifdef DEBUG_CH
      printf("pilot 24: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);

      //      ch[0] = 1024;
      //      ch[1] = -128;
#endif

437

438
      multadd_real_vector_complex_scalar(f_dc,
439 440 441
                                         ch,
                                         dl_ch,
                                         24);
442 443
      pil+=2;    // Re Im
      dl_ch+=8;
444

445 446
      // printf("Second half\n");
      // Second half of RBs
447
      rxF   = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))];
knopp's avatar
 
knopp committed
448

449 450
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
451 452 453 454 455 456 457 458
#ifdef DEBUG_CH
      printf("pilot 25: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);

      //      ch[0] = 1024;
      //      ch[1] = -128;
#endif

      multadd_real_vector_complex_scalar(f2_dc,
459 460 461
                                         ch,
                                         dl_ch,
                                         24);
462 463 464 465
      pil+=2;
      rxF+=12;
      dl_ch+=16;

466 467 468
      for (pilot_cnt=0; pilot_cnt<22; pilot_cnt+=2) {

        // printf("* pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
469
        // printf("rx[%d][%d] -> (%d,%d)\n",p,ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
470

471 472
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
473
#ifdef DEBUG_CH
474
        printf("pilot %d rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",26+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
475

476 477
        //  ch[0] = 1024;
        //  ch[1] = -128;
478 479
#endif

480 481 482 483 484 485 486 487
        multadd_real_vector_complex_scalar(f,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=8;

488 489
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
490
#ifdef DEBUG_CH
491
        printf("pilot %d : rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",27+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
492

493 494
        //  ch[0] = 1024;
        //  ch[1] = -128;
495
#endif
496 497 498 499 500 501 502 503 504

        multadd_real_vector_complex_scalar(f2,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=16;

505 506
      }

507 508
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
509 510 511 512 513 514 515 516 517 518

#ifdef DEBUG_CH
      printf("pilot 49: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);

      //      ch[0] = 1024;
      //      ch[1] = -128;
#endif


      multadd_real_vector_complex_scalar(fr,
519 520 521
                                         ch,
                                         dl_ch,
                                         24);
522 523 524
      pil+=2;    // Re Im
      rxF+=12;
      dl_ch+=8;
525

526 527
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
528 529 530 531 532 533 534 535 536 537

#ifdef DEBUG_CH

      printf("pilot 50: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);

      //      ch[0] = 1024;
      //      ch[1] = -128;
#endif

      multadd_real_vector_complex_scalar(f2r2,
538 539 540 541
                                         ch,
                                         dl_ch,
                                         24);

542
    } else if (ue->frame_parms.N_RB_DL==15) {
543 544

      //printf("First Half\n");
545 546 547 548 549
      for (rb=0; rb<28; rb+=4) {

        //printf("aarx=%d\n",aarx);
        //printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
        //printf("rx[%d][%d] -> (%d,%d)\n",p,
550
        //       ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),
551 552
        //       rxF[0],
        //       rxF[1]);
553 554
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
555 556 557 558 559 560 561 562 563
        //printf("ch -> (%d,%d)\n",ch[0],ch[1]);
        multadd_real_vector_complex_scalar(f,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;    // Re Im
        rxF+=12;
        dl_ch+=8;

564 565
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
566 567 568 569 570 571 572 573 574
        //printf("ch -> (%d,%d)\n",ch[0],ch[1]);
        multadd_real_vector_complex_scalar(f2,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=16;

575
      }
576

577 578
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
579 580
      //     printf("ch -> (%d,%d)\n",ch[0],ch[1]);
      multadd_real_vector_complex_scalar(f,
581 582 583
                                         ch,
                                         dl_ch,
                                         24);
584 585
      pil+=2;    // Re Im
      dl_ch+=8;
586

587 588
      //printf("Second half\n");
      //Second half of RBs
589 590 591
      rxF   = (int16_t *)&rxdataF[aarx][((symbol_offset+1+nushift + (3*p)))];
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
592

593
      multadd_real_vector_complex_scalar(f2,
594 595 596
                                         ch,
                                         dl_ch,
                                         24);
597 598 599
      pil+=2;
      rxF+=12;
      dl_ch+=16;
600 601 602 603 604

      for (rb=0; rb<28; rb+=4) {
        //printf("aarx=%d\n",aarx);
        //printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
        //printf("rx[%d][%d] -> (%d,%d)\n",p,
605
        //       ue->frame_parms.first_carrier_offset + ue->frame_parms.nushift + 6*rb+(3*p),
606 607
        //       rxF[0],
        //       rxF[1]);
608 609
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
610 611 612 613 614 615 616 617 618

        multadd_real_vector_complex_scalar(f,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=8;

619 620
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
621 622 623 624 625 626 627 628 629

        multadd_real_vector_complex_scalar(f2,
                                           ch,
                                           dl_ch,
                                           24);
        pil+=2;
        rxF+=12;
        dl_ch+=16;

630
      }
631
    } else {
632
      msg("channel estimation not implemented for ue->frame_parms.N_RB_DL = %d\n",ue->frame_parms.N_RB_DL);
633
    }
634 635


636
    if (ue->perfect_ce == 0) {
637 638 639
      // Temporal Interpolation
      // printf("ch_offset %d\n",ch_offset);

640
      dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
641

642
      if (ue->high_speed_flag == 0) {
643
        multadd_complex_vector_real_scalar(dl_ch,
644 645
                                           32767-ue->ch_est_alpha,
                                           dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),0,ue->frame_parms.ofdm_symbol_size);
646 647
      } else { // high_speed_flag == 1
        if (symbol == 0) {
648 649 650
          //      printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp);
          //      dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)];
          dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)];
651

652 653
          multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
          multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
654

655 656
          multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
          multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
657 658
        } // this is 1/3,2/3 combination for pilots spaced by 3 symbols
        else if (symbol == pilot1) {
659
          dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0];
660

661 662 663
          if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
            multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
664

665 666
            multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
667

668 669
            multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
670
          } else {
671 672
            multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
673

674 675
            multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
676 677
          } // pilot spacing 3 symbols (1/3,2/3 combination)
        } else if (symbol == pilot2) {
678
          dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(ue->frame_parms.ofdm_symbol_size)];
679

680 681
          multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
          multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
682

683 684
          multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
          multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
685
        } else { // symbol == pilot3
686 687
          //      printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp);
          dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)];
688

689 690 691
          if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
            multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
692

693 694
            multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
695

696 697
            multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
698
          } else {
699 700
            multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size);
701

702 703
            multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size);
            multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size);
704 705 706
          } // pilot spacing 3 symbols (1/3,2/3 combination)
        }

707
      }
knopp's avatar
 
knopp committed
708
    }
709 710
  }

711
  void (*idft)(int16_t *,int16_t *, int);
712

713
  switch (ue->frame_parms.ofdm_symbol_size) {
714
  case 128:
715 716
    idft = idft128;
    break;
717

718
  case 256:
719 720
    idft = idft256;
    break;
721

722
  case 512:
723 724
    idft = idft512;
    break;
725

726
  case 1024:
727 728
    idft = idft1024;
    break;
729

730 731 732 733 734
  case 1536:
    idft = idft1536;
    break;

  case 2048:
735 736
    idft = idft2048;
    break;
737

738 739 740 741
  default:
    idft = idft512;
    break;
  }
742

743
  // do ifft of channel estimate
744 745 746 747 748
  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
    for (p=0; p<ue->frame_parms.nb_antennas_tx_eNB; p++) {
      if (ue->common_vars.dl_ch_estimates[eNB_offset][(p<<1)+aarx])
        idft((int16_t*) &ue->common_vars.dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
             (int16_t*) ue->common_vars.dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
749
    }
750 751

  return(0);
752 753
}