phich.c 46.3 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5
6
7
8
    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.
9
10


ghaddab's avatar
ghaddab committed
11
12
13
14
    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.
15

ghaddab's avatar
ghaddab committed
16
    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
   see <http://www.gnu.org/licenses/>.
20
21

  Contact Information
ghaddab's avatar
ghaddab committed
22
23
24
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@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
27

ghaddab's avatar
ghaddab committed
28
 *******************************************************************************/
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

/*! \file PHY/LTE_TRANSPORT/phich.c
* \brief Top-level routines for generating and decoding  the PHICH/HI physical/transport channel V8.6 2009-03
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/

#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "defs.h"
#ifndef USER_MODE
#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
#endif

//#define DEBUG_PHICH 1

//extern unsigned short pcfich_reg[4];
//extern unsigned char pcfich_first_reg_idx;

//unsigned short phich_reg[MAX_NUM_PHICH_GROUPS][3];

knopp's avatar
   
knopp committed
56
57

uint8_t rv_table[4] = {0, 2, 3, 1};
58

59
60
uint8_t get_mi(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
{
61
62

  // for FDD
knopp's avatar
   
knopp committed
63
  if (frame_parms->frame_type == FDD)
64
65
66
67
68
    return 1;

  // for TDD
  switch (frame_parms->tdd_config) {

69
  case 0:
70
71
72
    if ((subframe==0) || (subframe==5))
      return(2);
    else return(1);
73

74
    break;
75
76

  case 1:
77
78
79
    if ((subframe==0) || (subframe==5))
      return(0);
    else return(1);
80

81
    break;
82
83

  case 2:
84
85
86
    if ((subframe==3) || (subframe==8))
      return(1);
    else return(0);
87

88
    break;
89
90

  case 3:
91
92
93
    if ((subframe==0) || (subframe==8) || (subframe==9))
      return(1);
    else return(0);
94

95
    break;
96

97
98
99
100
  case 4:
    if ((subframe==8) || (subframe==9))
      return(1);
    else return(0);
101

102
    break;
103

104
105
106
107
  case 5:
    if (subframe==8)
      return(1);
    else return(0);
108

109
    break;
110

111
  case 6:
112
113
114
    return(1);
    break;

115
116
117
118
119
  default:
    return(0);
  }
}

120
121
unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe)
{
122

knopp's avatar
   
knopp committed
123
  if (frame_parms->frame_type == FDD)
124
    return(subframe&7);
125

126
127
  switch (frame_parms->tdd_config) {
  case 3:
128
    if ( (subframe == 8) || (subframe == 9) ) {
129
      return(subframe-8);
130
    } else if (subframe==0)
131
132
133
      return(2);
    else {
      LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n",
134
            subframe,frame_parms->tdd_config);
135
136
      return(0);
    }
137

138
    break;
139

140
  }
141

142
143
144
  return(0);
}

145
146
uint8_t phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe)
{
knopp's avatar
   
knopp committed
147
  if (frame_parms->frame_type == FDD) {
148
    return((subframe<4) ? (frame - 1) : frame);
149
  } else {
150
151
152
153
154
    // Note this is not true, but it doesn't matter, the frame number is irrelevant for TDD!
    return(frame);
  }
}

155
156
uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
{
157

knopp's avatar
   
knopp committed
158
  if (frame_parms->frame_type == FDD)
159
    return(subframe<4 ? (subframe+6) : (subframe-4));
160

161
162
163
164
165
166
  switch (frame_parms->tdd_config) {
  case 0:
    if (subframe == 0)
      return(3);
    else if (subframe == 5) {
      return (8);
167
    } else if (subframe == 6)
168
169
170
171
172
      return (2);
    else if (subframe == 1)
      return (7);
    else {
      LOG_E(PHY, "phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
173
            subframe,frame_parms->tdd_config);
174
175
      return(0);
    }
176

177
    break;
178

179
180
181
  case 1:
    if (subframe == 6)
      return(2);
182
    else if (subframe == 9)
183
184
185
186
187
188
189
      return (3);
    else if (subframe == 1)
      return (7);
    else if (subframe == 4)
      return (8);
    else {
      LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
190
            subframe,frame_parms->tdd_config);
191
192
      return(0);
    }
193

194
    break;
195

196
197
198
199
200
201
202
  case 2:
    if (subframe == 8)
      return(2);
    else if (subframe == 3)
      return (7);
    else {
      LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
203
            subframe,frame_parms->tdd_config);
204
205
      return(0);
    }
206

207
    break;
208

209
  case 3:
210
    if ( (subframe == 8) || (subframe == 9) ) {
211
      return(subframe-6);
212
    } else if (subframe==0)
213
214
215
      return(4);
    else {
      LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
216
            subframe,frame_parms->tdd_config);
217
218
      return(0);
    }
219

220
    break;
221

222
  case 4:
223
    if ( (subframe == 8) || (subframe == 9) ) {
224
      return(subframe-6);
225
    } else {
226
      LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
227
            subframe,frame_parms->tdd_config);
228
229
      return(0);
    }
230
231
232

    break;

233
  case 5:
234
    if (subframe == 8) {
235
      return(2);
236
    } else {
237
      LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
238
            subframe,frame_parms->tdd_config);
239
240
      return(0);
    }
241

242
243
244
    break;

  case 6:
245
    if (subframe == 6) {
246
      return(2);
247
    } else if (subframe == 9) {
248
      return(3);
249
    } else if (subframe == 0) {
250
      return(4);
251
    } else if (subframe == 1) {
252
      return(7);
253
    } else if (subframe == 5) {
254
      return(8);
255
    } else {
256
      LOG_E(PHY,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n",
257
            subframe,frame_parms->tdd_config);
258
259
      return(0);
    }
260

261
    break;
262

263
  }
264

265
266
267
  return(0);
}

268
269
int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg)
{
270
271
272
273
274
275

  if ((reg == frame_parms->pcfich_reg[0]) ||
      (reg == frame_parms->pcfich_reg[1]) ||
      (reg == frame_parms->pcfich_reg[2]) ||
      (reg == frame_parms->pcfich_reg[3]))
    return(1);
276

277
278
279
  return(0);
}

280
281
void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
{
282
283
284
285
286
287

  unsigned short n0 = (frame_parms->N_RB_DL * 2) - 4;  // 2 REG per RB less the 4 used by PCFICH in first symbol
  unsigned short n1 = (frame_parms->N_RB_DL * 3);      // 3 REG per RB in second and third symbol
  unsigned short n2 = n1;
  unsigned short mprime = 0;
  unsigned short Ngroup_PHICH;
gauthier's avatar
gauthier committed
288
289
  //  uint16_t *phich_reg = frame_parms->phich_reg;
  uint16_t *pcfich_reg = frame_parms->pcfich_reg;
290
291
292

  // compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211
  Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
293

294

295
296
  if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
    Ngroup_PHICH++;
297

298
299
300
301
  // check if Extended prefix
  if (frame_parms->Ncp == 1) {
    Ngroup_PHICH<<=1;
  }
302

303
304
305
306
307
308
309
310
311
312
313
  //#ifdef DEBUG_PHICH
  printf("Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n",
	 ((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)),
	 frame_parms->phich_config_common.phich_resource,
	 frame_parms->phich_config_common.phich_duration==normal?"normal":"extended",
	 frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type,
	 pcfich_reg[frame_parms->pcfich_first_reg_idx],
	 n0,
	 n1,
	 ((frame_parms->Nid_cell*n0)/n1)%n0);
  //#endif
314

315
  // This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ...
316

317
318
319
320
321
  for (mprime=0; 
       mprime<((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)); 
       mprime++) {

    if (frame_parms->phich_config_common.phich_duration==normal) { // normal PHICH duration
322
323
324
325

      frame_parms->phich_reg[mprime][0] = (frame_parms->Nid_cell + mprime)%n0;

      if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
326
327
        frame_parms->phich_reg[mprime][0]++;

328
      if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3])
329
330
        frame_parms->phich_reg[mprime][0]++;

331
      if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3])
332
333
        frame_parms->phich_reg[mprime][0]++;

334
      if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
335
        frame_parms->phich_reg[mprime][0]++;
336
337
338

      frame_parms->phich_reg[mprime][1] = (frame_parms->Nid_cell + mprime + (n0/3))%n0;

339
      
340
      if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
341
        frame_parms->phich_reg[mprime][1]++;
342
      
343
      if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3])
344
345
        frame_parms->phich_reg[mprime][1]++;

346
      if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3])
347
348
        frame_parms->phich_reg[mprime][1]++;

349
      if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
350
        frame_parms->phich_reg[mprime][1]++;
351
      
352
353

      frame_parms->phich_reg[mprime][2] = (frame_parms->Nid_cell + mprime + (2*n0/3))%n0;
354
      
355
      if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
356
357
        frame_parms->phich_reg[mprime][2]++;

358
      if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3])
359
360
        frame_parms->phich_reg[mprime][2]++;

361
      if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3])
362
363
        frame_parms->phich_reg[mprime][2]++;

364
      if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
365
        frame_parms->phich_reg[mprime][2]++;
366
367
368
369
370
      
      //#ifdef DEBUG_PHICH
      printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
      //#endif
    } else { // extended PHICH duration
371
372
373
374
375
376
377
378
      frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0;
      frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0;

      frame_parms->phich_reg[mprime<<1][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1;
      frame_parms->phich_reg[mprime<<1][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2;

      frame_parms->phich_reg[1+(mprime<<1)][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1;
      frame_parms->phich_reg[1+(mprime<<1)][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2;
379
380
381
382
      //#ifdef DEBUG_PHICH
      printf("phich_reg :%d => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
      printf("phich_reg :%d => %d,%d,%d\n",1+(mprime<<1),frame_parms->phich_reg[1+(mprime<<1)][0],frame_parms->phich_reg[1+(mprime<<1)][1],frame_parms->phich_reg[1+(mprime<<1)][2]);
      //#endif
383
384
385
386
387
388
    }
  } // mprime loop
}  // num_pdcch_symbols loop


void generate_phich_emul(LTE_DL_FRAME_PARMS *frame_parms,
389
390
391
                         uint8_t HI,
                         uint8_t subframe)
{
392
393
394
395
396


}

mod_sym_t alam_bpsk_perm1[4] = {2,1,4,3}; // -conj(x) 1 (-1-j) -> 2 (1-j), 2->1, 3 (-1+j) -> (4) 1+j, 4->3
397
mod_sym_t alam_bpsk_perm2[4] = {3,4,2,1}; // conj(x) 1 (-1-j) -> 3 (-1+j), 3->1, 2 (1-j) -> 4 (1+j), 4->2
398

399
// This routine generates the PHICH
400
401

void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
402
403
404
405
406
407
408
409
                    int16_t amp,
                    uint8_t nseq_PHICH,
                    uint8_t ngroup_PHICH,
                    uint8_t HI,
                    uint8_t subframe,
                    mod_sym_t **y)
{

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  int16_t d[24],*dp;
  //  unsigned int i,aa;
  unsigned int re_offset;
  int16_t y0_16[8],y1_16[8];
  int16_t *y0,*y1;
  // scrambling
  uint32_t x1, x2, s=0;
  uint8_t reset = 1;
  int16_t cs[12];
  uint32_t i,i2,i3,m,j;
  int16_t gain_lin_QPSK;
  uint32_t subframe_offset=((frame_parms->Ncp==0)?14:12)*frame_parms->ofdm_symbol_size*subframe;

  memset(d,0,24*sizeof(int16_t));

425
426
  if (frame_parms->mode1_flag==1)
    gain_lin_QPSK = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2_Q15)>>15);
427
  else
428
    gain_lin_QPSK = amp/2;
429
430
431
432
433
434

  //printf("PHICH : gain_lin_QPSK %d\n",gain_lin_QPSK);

  // BPSK modulation of HI input (to be repeated 3 times, 36-212 Section 5.3.5, p. 56 in v8.6)
  if (HI>0)
    HI=1;
435

436
437
  //  c = (1-(2*HI))*SSS_AMP;
  // x1 is set in lte_gold_generic
438
439
  x2 = (((subframe+1)*(frame_parms->Nid_cell+1))<<9) + frame_parms->Nid_cell;

440
  s = lte_gold_generic(&x1, &x2, reset);
441

442
  // compute scrambling sequence
443
  for (i=0; i<12; i++) {
444
445
446
447
448
449
450
451
    cs[i] = (uint8_t)((s>>(i&0x1f))&1);
    cs[i] = (cs[i] == 0) ? (1-(HI<<1)) : ((HI<<1)-1);
  }

  if (frame_parms->Ncp == 0) { // Normal Cyclic Prefix

    //    printf("Doing PHICH : Normal CP, subframe %d\n",subframe);
    // 12 output symbols (Msymb)
452
    for (i=0,i2=0,i3=0; i<3; i++,i2+=4,i3+=8) {
453
454
      switch (nseq_PHICH) {
      case 0: // +1 +1 +1 +1
455
456
457
458
459
460
461
462
463
464
        d[i3]   = cs[i2];
        d[1+i3] = cs[i2];
        d[2+i3] = cs[1+i2];
        d[3+i3] = cs[1+i2];
        d[4+i3] = cs[2+i2];
        d[5+i3] = cs[2+i2];
        d[6+i3] = cs[3+i2];
        d[7+i3] = cs[3+i2];
        break;

465
      case 1: // +1 -1 +1 -1
466
467
468
469
470
471
472
473
474
475
        d[i3] = cs[i2];
        d[1+i3] = cs[i2];
        d[2+i3] = -cs[1+i2];
        d[3+i3] = -cs[1+i2];
        d[4+i3] = cs[2+i2];
        d[5+i3] = cs[2+i2];
        d[6+i3] = -cs[3+i2];
        d[7+i3] = -cs[3+i2];
        break;

476
      case 2: // +1 +1 -1 -1
477
478
479
480
481
482
483
484
485
486
        d[i3]   = cs[i2];
        d[1+i3]   = cs[i2];
        d[2+i3] = cs[1+i2];
        d[3+i3] = cs[1+i2];
        d[4+i3] = -cs[2+i2];
        d[5+i3] = -cs[2+i2];
        d[6+i3] = -cs[3+i2];
        d[7+i3] = -cs[3+i2];
        break;

487
      case 3: // +1 -1 -1 +1
488
489
490
491
492
493
494
495
496
497
        d[i3]   = cs[i2];
        d[1+i3]   = cs[i2];
        d[2+i3] = -cs[1+i2];
        d[3+i3] = -cs[1+i2];
        d[4+i3] = -cs[2+i2];
        d[5+i3] = -cs[2+i2];
        d[6+i3] = cs[3+i2];
        d[7+i3] = cs[3+i2];
        break;

498
      case 4: // +j +j +j +j
499
500
501
502
503
504
505
506
507
508
        d[i3]   = -cs[i2];
        d[1+i3] = cs[i2];
        d[2+i3] = -cs[1+i2];
        d[3+i3] = cs[1+i2];
        d[4+i3] = -cs[2+i2];
        d[5+i3] = cs[2+i2];
        d[6+i3] = -cs[3+i2];
        d[7+i3] = cs[3+i2];
        break;

509
      case 5: // +j -j +j -j
510
511
512
513
514
515
516
517
518
519
        d[1+i3] = cs[i2];
        d[3+i3] = -cs[1+i2];
        d[5+i3] = cs[2+i2];
        d[7+i3] = -cs[3+i2];
        d[i3]   = -cs[i2];
        d[2+i3] = cs[1+i2];
        d[4+i3] = -cs[2+i2];
        d[6+i3] = cs[3+i2];
        break;

520
      case 6: // +j +j -j -j
521
522
523
524
525
526
527
528
529
530
        d[1+i3] = cs[i2];
        d[3+i3] = cs[1+i2];
        d[5+i3] = -cs[2+i2];
        d[7+i3] = -cs[3+i2];
        d[i3]   = -cs[i2];
        d[2+i3] = -cs[1+i2];
        d[4+i3] = cs[2+i2];
        d[6+i3] = cs[3+i2];
        break;

531
      case 7: // +j -j -j +j
532
533
534
535
536
537
538
539
540
541
        d[1+i3] = cs[i2];
        d[3+i3] = -cs[1+i2];
        d[5+i3] = -cs[2+i2];
        d[7+i3] = cs[3+i2];
        d[i3]   = -cs[i2];
        d[2+i3] = cs[1+i2];
        d[4+i3] = cs[2+i2];
        d[6+i3] = -cs[3+i2];
        break;

542
      default:
543
        LOG_E(PHY,"phich_coding.c: Illegal PHICH Number\n");
544
545
      } // nseq_PHICH
    }
546

547
548
#ifdef DEBUG_PHICH
    LOG_D(PHY,"[PUSCH 0]PHICH d = ");
549
550

    for (i=0; i<24; i+=2)
551
      LOG_D(PHY,"(%d,%d)",d[i],d[i+1]);
552

553
554
    LOG_D(PHY,"\n");
#endif
555
556

    // modulation here
557
558
    if (frame_parms->mode1_flag == 0) {
      // do Alamouti precoding here
559

560
561
562
563
      // Symbol 0
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][0]*6);

      if (re_offset > frame_parms->ofdm_symbol_size)
564
        re_offset -= (frame_parms->ofdm_symbol_size-1);
565
566
567

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
      y1 = (int16_t*)&y[1][re_offset+subframe_offset];
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
      // first antenna position n -> x0
      y0_16[0]   = d[0]*gain_lin_QPSK;
      y0_16[1]   = d[1]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[0]   = -d[2]*gain_lin_QPSK;
      y1_16[1]   = d[3]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[2] = -y1_16[0];
      y0_16[3] = y1_16[1];
      y1_16[2] = y0_16[0];
      y1_16[3] = -y0_16[1];

      // first antenna position n -> x0
      y0_16[4]   = d[4]*gain_lin_QPSK;
      y0_16[5]   = d[5]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[4]   = -d[6]*gain_lin_QPSK;
      y1_16[5]   = d[7]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[6] = -y1_16[4];
      y0_16[7] = y1_16[5];
      y1_16[6] = y0_16[4];
      y1_16[7] = -y0_16[5];

593
594
595
596
597
598
599
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j]   += y0_16[m];
          y1[j]   += y1_16[m++];
          y0[j+1] += y0_16[m];
          y1[j+1] += y1_16[m++];
        }
600
      }
601

602
603
604
605
      // Symbol 1
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][1]*6);

      if (re_offset > frame_parms->ofdm_symbol_size)
606
        re_offset -= (frame_parms->ofdm_symbol_size-1);
607
608
609

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
      y1 = (int16_t*)&y[1][re_offset+subframe_offset];
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
      // first antenna position n -> x0
      y0_16[0]   = d[8]*gain_lin_QPSK;
      y0_16[1]   = d[9]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[0]   = -d[10]*gain_lin_QPSK;
      y1_16[1]   = d[11]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[2] = -y1_16[0];
      y0_16[3] = y1_16[1];
      y1_16[2] = y0_16[0];
      y1_16[3] = -y0_16[1];

      // first antenna position n -> x0
      y0_16[4]   = d[12]*gain_lin_QPSK;
      y0_16[5]   = d[13]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[4]   = -d[14]*gain_lin_QPSK;
      y1_16[5]   = d[15]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[6] = -y1_16[4];
      y0_16[7] = y1_16[5];
      y1_16[6] = y0_16[4];
      y1_16[7] = -y0_16[5];

635
636
637
638
639
640
641
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j]   += y0_16[m];
          y1[j]   += y1_16[m++];
          y0[j+1] += y0_16[m];
          y1[j+1] += y1_16[m++];
        }
642
643
644
645
646
647
      }

      // Symbol 2
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][2]*6);

      if (re_offset > frame_parms->ofdm_symbol_size)
648
        re_offset -= (frame_parms->ofdm_symbol_size-1);
649
650
651

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
      y1 = (int16_t*)&y[1][re_offset+subframe_offset];
652

653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
      // first antenna position n -> x0
      y0_16[0]   = d[16]*gain_lin_QPSK;
      y0_16[1]   = d[17]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[0]   = -d[18]*gain_lin_QPSK;
      y1_16[1]   = d[19]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[2] = -y1_16[0];
      y0_16[3] = y1_16[1];
      y1_16[2] = y0_16[0];
      y1_16[3] = -y0_16[1];

      // first antenna position n -> x0
      y0_16[4]   = d[20]*gain_lin_QPSK;
      y0_16[5]   = d[21]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[4]   = -d[22]*gain_lin_QPSK;
      y1_16[5]   = d[23]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[6] = -y1_16[4];
      y0_16[7] = y1_16[5];
      y1_16[6] = y0_16[4];
      y1_16[7] = -y0_16[5];

677
678
679
680
681
682
683
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j]   += y0_16[m];
          y1[j]   += y1_16[m++];
          y0[j+1] += y0_16[m];
          y1[j+1] += y1_16[m++];
        }
684
685
686
687
688
689
690
691
692
693
      }

    } // mode1_flag

    else {
      // Symbol 0
      //      printf("[PUSCH 0]PHICH REG %d\n",frame_parms->phich_reg[ngroup_PHICH][0]);
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][0]*6);

      if (re_offset > frame_parms->ofdm_symbol_size)
694
        re_offset -= (frame_parms->ofdm_symbol_size-1);
695
696
697
698
699
700
701
702
703
704
705
706
707

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
      //      printf("y0 %p\n",y0);

      y0_16[0]   = d[0]*gain_lin_QPSK;
      y0_16[1]   = d[1]*gain_lin_QPSK;
      y0_16[2]   = d[2]*gain_lin_QPSK;
      y0_16[3]   = d[3]*gain_lin_QPSK;
      y0_16[4]   = d[4]*gain_lin_QPSK;
      y0_16[5]   = d[5]*gain_lin_QPSK;
      y0_16[6]   = d[6]*gain_lin_QPSK;
      y0_16[7]   = d[7]*gain_lin_QPSK;

708
709
710
711
712
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j]   += y0_16[m++];
          y0[j+1] += y0_16[m++];
        }
713
      }
714

715
716
717
718
719
      // Symbol 1
      //      printf("[PUSCH 0]PHICH REG %d\n",frame_parms->phich_reg[ngroup_PHICH][1]);
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][1]*6);

      if (re_offset > frame_parms->ofdm_symbol_size)
720
        re_offset -= (frame_parms->ofdm_symbol_size-1);
721
722

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
723

724
725
726
727
728
729
730
731
732
      y0_16[0]   = d[8]*gain_lin_QPSK;
      y0_16[1]   = d[9]*gain_lin_QPSK;
      y0_16[2]   = d[10]*gain_lin_QPSK;
      y0_16[3]   = d[11]*gain_lin_QPSK;
      y0_16[4]   = d[12]*gain_lin_QPSK;
      y0_16[5]   = d[13]*gain_lin_QPSK;
      y0_16[6]   = d[14]*gain_lin_QPSK;
      y0_16[7]   = d[15]*gain_lin_QPSK;

733
734
735
736
737
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j]   += y0_16[m++];
          y0[j+1] += y0_16[m++];
        }
738
739
740
741
742
743
744
      }

      // Symbol 2
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][2]*6);

      //      printf("[PUSCH 0]PHICH REG %d\n",frame_parms->phich_reg[ngroup_PHICH][2]);
      if (re_offset > frame_parms->ofdm_symbol_size)
745
746
        re_offset -= (frame_parms->ofdm_symbol_size-1);

747
      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
748

749
750
751
752
753
754
755
756
757
      y0_16[0]   = d[16]*gain_lin_QPSK;
      y0_16[1]   = d[17]*gain_lin_QPSK;
      y0_16[2]   = d[18]*gain_lin_QPSK;
      y0_16[3]   = d[19]*gain_lin_QPSK;
      y0_16[4]   = d[20]*gain_lin_QPSK;
      y0_16[5]   = d[21]*gain_lin_QPSK;
      y0_16[6]   = d[22]*gain_lin_QPSK;
      y0_16[7]   = d[23]*gain_lin_QPSK;

758
759
760
761
762
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j]   += y0_16[m++];
          y0[j+1] += y0_16[m++];
        }
763
      }
764

765
766
      /*
      for (i=0;i<512;i++)
767
      printf("re %d (%d): %d,%d\n",i,subframe_offset+i,((int16_t*)&y[0][subframe_offset+i])[0],((int16_t*)&y[0][subframe_offset+i])[1]);
768
769
      */
    } // mode1_flag
770
771
  } else { // extended prefix

772
773
774
    // 6 output symbols
    if ((ngroup_PHICH & 1) == 1)
      dp = &d[4];
775
    else
776
777
778
      dp = d;

    switch (nseq_PHICH) {
779
    case 0: // +1 +1
780
781
782
783
784
785
786
787
788
789
790
791
792
      dp[0]  = cs[0];
      dp[2]  = cs[1];
      dp[8]  = cs[2];
      dp[10] = cs[3];
      dp[16] = cs[4];
      dp[18] = cs[5];
      dp[1]  = cs[0];
      dp[3]  = cs[1];
      dp[9]  = cs[2];
      dp[11] = cs[3];
      dp[17] = cs[4];
      dp[19] = cs[5];
      break;
793

794
795
796
797
798
799
800
801
802
803
804
805
806
807
    case 1: // +1 -1
      dp[0]  = cs[0];
      dp[2]  = -cs[1];
      dp[8]  = cs[2];
      dp[10] = -cs[3];
      dp[16] = cs[4];
      dp[18] = -cs[5];
      dp[1]  = cs[0];
      dp[3]  = -cs[1];
      dp[9]  = cs[2];
      dp[11] = -cs[3];
      dp[17] = cs[4];
      dp[19] = -cs[5];
      break;
808
809

    case 2: // +j +j
810
811
812
813
814
815
816
817
818
819
820
821
      dp[1]  = cs[0];
      dp[3]  = cs[1];
      dp[9]  = cs[2];
      dp[11] = cs[3];
      dp[17] = cs[4];
      dp[19] = cs[5];
      dp[0]  = -cs[0];
      dp[2]  = -cs[1];
      dp[8]  = -cs[2];
      dp[10] = -cs[3];
      dp[16] = -cs[4];
      dp[18] = -cs[5];
822

823
      break;
824
825

    case 3: // +j -j
826
827
828
829
830
831
832
833
834
835
836
837
838
      dp[1]  = cs[0];
      dp[3]  = -cs[1];
      dp[9]  = cs[2];
      dp[11] = -cs[3];
      dp[17] = cs[4];
      dp[19] = -cs[5];
      dp[0]  = -cs[0];
      dp[2]  = cs[1];
      dp[8]  = -cs[2];
      dp[10] = cs[3];
      dp[16] = -cs[4];
      dp[18] = cs[5];
      break;
839

840
841
842
    default:
      LOG_E(PHY,"phich_coding.c: Illegal PHICH Number\n");
    }
843
844
845



846
847
848
849
    if (frame_parms->mode1_flag == 0) {
      // do Alamouti precoding here
      // Symbol 0
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][0]*6);
850

851
      if (re_offset > frame_parms->ofdm_symbol_size)
852
        re_offset -= (frame_parms->ofdm_symbol_size-1);
853
854
855

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
      y1 = (int16_t*)&y[1][re_offset+subframe_offset];
856

857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
      // first antenna position n -> x0
      y0_16[0]   = d[0]*gain_lin_QPSK;
      y0_16[1]   = d[1]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[0]   = -d[2]*gain_lin_QPSK;
      y1_16[1]   = d[3]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[2] = -y1_16[0];
      y0_16[3] = y1_16[1];
      y1_16[2] = y0_16[0];
      y1_16[3] = -y0_16[1];

      // first antenna position n -> x0
      y0_16[4]   = d[4]*gain_lin_QPSK;
      y0_16[5]   = d[5]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[4]   = -d[6]*gain_lin_QPSK;
      y1_16[5]   = d[7]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[6] = -y1_16[4];
      y0_16[7] = y1_16[5];
      y1_16[6] = y0_16[4];
      y1_16[7] = -y0_16[5];

881
882
883
884
885
886
887
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j] += y0_16[m];
          y1[j] += y1_16[m++];
          y0[j+1] += y0_16[m];
          y1[j+1] += y1_16[m++];
        }
888
889
890
891
      }

      // Symbol 1
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][1]<<2);
892

893
      if (re_offset > frame_parms->ofdm_symbol_size)
894
895
        re_offset -= (frame_parms->ofdm_symbol_size-1);

896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
      re_offset += (frame_parms->ofdm_symbol_size);

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
      y1 = (int16_t*)&y[1][re_offset+subframe_offset];

      // first antenna position n -> x0
      y0_16[0]   = d[8]*gain_lin_QPSK;
      y0_16[1]   = d[9]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[0]   = -d[10]*gain_lin_QPSK;
      y1_16[1]   = d[11]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[2] = -y1_16[0];
      y0_16[3] = y1_16[1];
      y1_16[2] = y0_16[0];
      y1_16[3] = -y0_16[1];

      // first antenna position n -> x0
      y0_16[4]   = d[12]*gain_lin_QPSK;
      y0_16[5]   = d[13]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[4]   = -d[14]*gain_lin_QPSK;
      y1_16[5]   = d[15]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[6] = -y1_16[4];
      y0_16[7] = y1_16[5];
      y1_16[6] = y0_16[4];
      y1_16[7] = -y0_16[5];

925
926
927
928
929
      for (i=0,j=0,m=0; i<4; i++,j+=2) {
        y0[j] += y0_16[m];
        y1[j] += y1_16[m++];
        y0[j+1] += y0_16[m];
        y1[j+1] += y1_16[m++];
930
931
932
933
      }

      // Symbol 2
      re_offset = frame_parms->first_carrier_offset +  (frame_parms->phich_reg[ngroup_PHICH][2]<<2);
934

935
      if (re_offset > frame_parms->ofdm_symbol_size)
936
937
        re_offset -= (frame_parms->ofdm_symbol_size-1);

938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
      re_offset += (frame_parms->ofdm_symbol_size<<1);

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
      y1 = (int16_t*)&y[1][re_offset+subframe_offset];

      // first antenna position n -> x0
      y0_16[0]   = d[16]*gain_lin_QPSK;
      y0_16[1]   = d[17]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[0]   = -d[18]*gain_lin_QPSK;
      y1_16[1]   = d[19]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[2] = -y1_16[0];
      y0_16[3] = y1_16[1];
      y1_16[2] = y0_16[0];
      y1_16[3] = -y0_16[1];

      // first antenna position n -> x0
      y0_16[4]   = d[20]*gain_lin_QPSK;
      y0_16[5]   = d[21]*gain_lin_QPSK;
      // second antenna position n -> -x1*
      y1_16[4]   = -d[22]*gain_lin_QPSK;
      y1_16[5]   = d[23]*gain_lin_QPSK;
      // fill in the rest of the ALAMOUTI precoding
      y0_16[6] = -y1_16[4];
      y0_16[7] = y1_16[5];
      y1_16[6] = y0_16[4];
      y1_16[7] = -y0_16[5];

967
968
969
970
971
      for (i=0,j=0,m=0; i<4; i++,j+=2) {
        y0[j]   += y0_16[m];
        y1[j]   += y1_16[m++];
        y0[j+1] += y0_16[m];
        y1[j+1] += y1_16[m++];
972
      }
973
    } else {
974
975
976

      // Symbol 0
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][0]*6);
977

978
      if (re_offset > frame_parms->ofdm_symbol_size)
979
        re_offset -= (frame_parms->ofdm_symbol_size-1);
980
981

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
982

983
984
985
986
987
988
989
990
991
      y0_16[0]   = d[0]*gain_lin_QPSK;
      y0_16[1]   = d[1]*gain_lin_QPSK;
      y0_16[2]   = d[2]*gain_lin_QPSK;
      y0_16[3]   = d[3]*gain_lin_QPSK;
      y0_16[4]   = d[4]*gain_lin_QPSK;
      y0_16[5]   = d[5]*gain_lin_QPSK;
      y0_16[6]   = d[6]*gain_lin_QPSK;
      y0_16[7]   = d[7]*gain_lin_QPSK;

992
993
994
995
996
      for (i=0,j=0,m=0; i<6; i++,j+=2) {
        if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
          y0[j] += y0_16[m++];
          y0[j+1] += y0_16[m++];
        }
997
998
999
1000
      }

      // Symbol 1
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][1]<<2);
1001

1002
      if (re_offset > frame_parms->ofdm_symbol_size)
1003
1004
        re_offset -= (frame_parms->ofdm_symbol_size-1);

1005
1006
1007
      re_offset += (frame_parms->ofdm_symbol_size);

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
1008

1009
1010
1011
1012
1013
1014
1015
1016
1017
      y0_16[0]   = d[8]*gain_lin_QPSK;
      y0_16[1]   = d[9]*gain_lin_QPSK;
      y0_16[2]   = d[10]*gain_lin_QPSK;
      y0_16[3]   = d[11]*gain_lin_QPSK;
      y0_16[4]   = d[12]*gain_lin_QPSK;
      y0_16[5]   = d[13]*gain_lin_QPSK;
      y0_16[6]   = d[14]*gain_lin_QPSK;
      y0_16[7]   = d[15]*gain_lin_QPSK;

1018
1019
1020
      for (i=0,j=0,m=0; i<4; i++,j+=2) {
        y0[j] += y0_16[m++];
        y0[j+1] += y0_16[m++];
1021
1022
1023
1024
1025
      }


      // Symbol 2
      re_offset = frame_parms->first_carrier_offset + (frame_parms->phich_reg[ngroup_PHICH][2]<<2);
1026

1027
      if (re_offset > frame_parms->ofdm_symbol_size)
1028
1029
        re_offset -= (frame_parms->ofdm_symbol_size-1);

1030
1031
1032
      re_offset += (frame_parms->ofdm_symbol_size<<1);

      y0 = (int16_t*)&y[0][re_offset+subframe_offset];
1033

1034
1035
1036
1037
1038
1039
1040
1041
1042
      y0_16[0]   = d[16]*gain_lin_QPSK;
      y0_16[1]   = d[17]*gain_lin_QPSK;
      y0_16[2]   = d[18]*gain_lin_QPSK;
      y0_16[3]   = d[19]*gain_lin_QPSK;
      y0_16[4]   = d[20]*gain_lin_QPSK;
      y0_16[5]   = d[21]*gain_lin_QPSK;
      y0_16[6]   = d[22]*gain_lin_QPSK;
      y0_16[7]   = d[23]*gain_lin_QPSK;

1043
1044
1045
      for (i=0,j=0,m=0; i<4; i++) {
        y0[j]   += y0_16[m++];
        y0[j+1] += y0_16[m++];
1046
1047
1048
1049
      }

    } // mode1_flag
  } // normal/extended prefix
1050
}
1051
1052
1053
1054
1055

// This routine demodulates the PHICH and updates PUSCH/ULSCH parameters


void rx_phich(PHY_VARS_UE *phy_vars_ue,
1056
1057
1058
              uint8_t subframe,
              uint8_t eNB_id)
{
1059
1060
1061
1062
1063
1064


  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->lte_frame_parms;
  LTE_UE_PDCCH **lte_ue_pdcch_vars = phy_vars_ue->lte_ue_pdcch_vars;

  //  uint8_t HI;
knopp's avatar
   
knopp committed
1065
  uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,phy_vars_ue->frame_rx,subframe);
1066
1067
1068
1069
  LTE_UE_ULSCH_t *ulsch = phy_vars_ue->ulsch_ue[eNB_id];
  int16_t phich_d[24],*phich_d_ptr,HI16;
  //  unsigned int i,aa;
  int8_t d[24],*dp;
gauthier's avatar
gauthier committed
1070
  uint16_t reg_offset;
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080

  // scrambling
  uint32_t x1, x2, s=0;
  uint8_t reset = 1;
  int16_t cs[12];
  uint32_t i,i2,i3,phich_quad;
  int32_t **rxdataF_comp = lte_ue_pdcch_vars[eNB_id]->rxdataF_comp;
  uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH;
  uint8_t NSF_PHICH = 4;
  uint8_t pusch_subframe;
1081

1082
  // check if we're expecting a PHICH in this subframe
knopp's avatar
   
knopp committed
1083
  LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX\n",phy_vars_ue->Mod_id,harq_pid,phy_vars_ue->frame_rx,subframe);
1084

1085
  if (ulsch->harq_processes[harq_pid]->status == ACTIVE) {
knopp's avatar
   
knopp committed
1086
    LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX ACTIVE\n",phy_vars_ue->Mod_id,harq_pid,phy_vars_ue->frame_rx,subframe);
1087
    Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
1088

1089
1090
    if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
      Ngroup_PHICH++;
1091

1092
1093
1094
    if (frame_parms->Ncp == 1)
      NSF_PHICH = 2;

1095
1096
1097
1098

    ngroup_PHICH = (ulsch->harq_processes[harq_pid]->first_rb +
                    ulsch->harq_processes[harq_pid]->n_DMRS)%Ngroup_PHICH;

knopp's avatar
   
knopp committed
1099
    if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) {
1100
      pusch_subframe = phich_subframe2_pusch_subframe(frame_parms,subframe);
1101

1102
      if ((pusch_subframe == 4) || (pusch_subframe == 9))
1103
        ngroup_PHICH += Ngroup_PHICH;
1104
    }
1105
1106
1107
1108

    nseq_PHICH = ((ulsch->harq_processes[harq_pid]->first_rb/Ngroup_PHICH) +
                  ulsch->harq_processes[harq_pid]->n_DMRS)%(2*NSF_PHICH);
  } else {
1109
1110
1111
1112
1113
1114
1115
    return;
  }

  memset(d,0,24*sizeof(int8_t));
  phich_d_ptr = phich_d;

  // x1 is set in lte_gold_generic
1116
1117
  x2 = (((subframe+1)*(frame_parms->Nid_cell+1))<<9) + frame_parms->Nid_cell;

1118
  s = lte_gold_generic(&x1, &x2, reset);
1119

1120
  // compute scrambling sequence
1121