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

22
23
24
25
26
27
28
29
30
31
32
/*! \file PHY/LTE_TRANSPORT/pucch.c
* \brief Top-level routines for generating and decoding the PUCCH physical 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"
knopp's avatar
knopp committed
33
#include "PHY/extern.h" 
34
35
#include "LAYER2/MAC/extern.h"

36
37
38
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"

39
40
#include "T.h"

gauthier's avatar
gauthier committed
41
//uint8_t ncs_cell[20][7];
42
43
//#define DEBUG_PUCCH_TX
//#define DEBUG_PUCCH_RX
44

gauthier's avatar
gauthier committed
45
int16_t cfo_pucch_np[24*7] = {20787,-25330,27244,-18205,31356,-9512,32767,0,31356,9511,27244,18204,20787,25329,
46
47
48
49
50
51
52
                              27244,-18205,30272,-12540,32137,-6393,32767,0,32137,6392,30272,12539,27244,18204,
                              31356,-9512,32137,-6393,32609,-3212,32767,0,32609,3211,32137,6392,31356,9511,
                              32767,0,32767,0,32767,0,32767,0,32767,0,32767,0,32767,0,
                              31356,9511,32137,6392,32609,3211,32767,0,32609,-3212,32137,-6393,31356,-9512,
                              27244,18204,30272,12539,32137,6392,32767,0,32137,-6393,30272,-12540,27244,-18205,
                              20787,25329,27244,18204,31356,9511,32767,0,31356,-9512,27244,-18205,20787,-25330
                             };
53

gauthier's avatar
gauthier committed
54
int16_t cfo_pucch_ep[24*6] = {24278,-22005,29621,-14010,32412,-4808,32412,4807,29621,14009,24278,22004,
55
56
57
58
59
60
61
                              28897,-15447,31356,-9512,32609,-3212,32609,3211,31356,9511,28897,15446,
                              31785,-7962,32412,-4808,32727,-1608,32727,1607,32412,4807,31785,7961,
                              32767,0,32767,0,32767,0,32767,0,32767,0,32767,0,
                              31785,7961,32412,4807,32727,1607,32727,-1608,32412,-4808,31785,-7962,
                              28897,15446,31356,9511,32609,3211,32609,-3212,31356,-9512,28897,-15447,
                              24278,22004,29621,14009,32412,4807,32412,-4808,29621,-14010,24278,-22005
                             };
62
63


64
65
void init_ncs_cell(LTE_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7])
{
66

gauthier's avatar
gauthier committed
67
68
  uint8_t ns,l,reset=1,i,N_UL_symb;
  uint32_t x1,x2,j=0,s=0;
69

70
71
72
  N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6;
  x2 = frame_parms->Nid_cell;

73
  for (ns=0; ns<20; ns++) {
74

75
    for (l=0; l<N_UL_symb; l++) {
76
77
      ncs_cell[ns][l]=0;

78
79
80
81
82
83
84
85
86
87
88
      for (i=0; i<8; i++) {
        if ((j%32) == 0) {
          s = lte_gold_generic(&x1,&x2,reset);
          //    printf("s %x\n",s);
          reset=0;
        }

        if (((s>>(j%32))&1)==1)
          ncs_cell[ns][l] += (1<<i);

        j++;
89
      }
90

91
#ifdef DEBUG_PUCCH_TX
knopp's avatar
knopp committed
92
      printf("[PHY] PUCCH ncs_cell init (j %d): Ns %d, l %d => ncs_cell %d\n",j,ns,l,ncs_cell[ns][l]);
93
94
95
96
97
98
#endif
    }

  }
}

gauthier's avatar
gauthier committed
99
100
int16_t alpha_re[12] = {32767, 28377, 16383,     0,-16384,  -28378,-32768,-28378,-16384,    -1, 16383, 28377};
int16_t alpha_im[12] = {0,     16383, 28377, 32767, 28377,   16383,     0,-16384,-28378,-32768,-28378,-16384};
101

gauthier's avatar
gauthier committed
102
int16_t W4[3][4] = {{32767, 32767, 32767, 32767},
103
104
105
  {32767,-32768, 32767,-32768},
  {32767,-32768,-32768, 32767}
};
gauthier's avatar
gauthier committed
106
int16_t W3_re[3][6] = {{32767, 32767, 32767},
107
108
109
  {32767,-16384,-16384},
  {32767,-16384,-16384}
};
110

gauthier's avatar
gauthier committed
111
int16_t W3_im[3][6] = {{0    ,0     ,0     },
112
113
114
  {0    , 28377,-28378},
  {0    ,-28378, 28377}
};
115
116
117

char pucch_format_string[6][20] = {"format 1\0","format 1a\0","format 1b\0","format 2\0","format 2a\0","format 2b\0"};

knopp's avatar
knopp committed
118
119
120
121
122
123
124
125
126
127
void generate_pucch1x(int32_t **txdataF,
		      LTE_DL_FRAME_PARMS *frame_parms,
		      uint8_t ncs_cell[20][7],
		      PUCCH_FMT_t fmt,
		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
		      uint16_t n1_pucch,
		      uint8_t shortened_format,
		      uint8_t *payload,
		      int16_t amp,
		      uint8_t subframe)
128
129
{

gauthier's avatar
gauthier committed
130
131
132
133
134
135
136
137
138
139
140
  uint32_t u,v,n;
  uint32_t z[12*14],*zptr;
  int16_t d0;
  uint8_t ns,N_UL_symb,nsymb,n_oc,n_oc0,n_oc1;
  uint8_t c = (frame_parms->Ncp==0) ? 3 : 2;
  uint16_t nprime,nprime0,nprime1;
  uint16_t i,j,re_offset,thres,h;
  uint8_t Nprime_div_deltaPUCCH_Shift,Nprime,d;
  uint8_t m,l,refs;
  uint8_t n_cs,S,alpha_ind,rem;
  int16_t tmp_re,tmp_im,ref_re,ref_im,W_re=0,W_im=0;
141
  int32_t *txptr;
gauthier's avatar
gauthier committed
142
  uint32_t symbol_offset;
143

gauthier's avatar
gauthier committed
144
145
  uint8_t deltaPUCCH_Shift          = frame_parms->pucch_config_common.deltaPUCCH_Shift;
  uint8_t NRB2                      = frame_parms->pucch_config_common.nRB_CQI;
knopp's avatar
knopp committed
146
147
  uint8_t Ncs1                      = frame_parms->pucch_config_common.nCS_AN;
  uint8_t Ncs1_div_deltaPUCCH_Shift = Ncs1/deltaPUCCH_Shift;
148

fnabet's avatar
fnabet committed
149
150
151
  LOG_D(PHY,"generate_pucch Start [deltaPUCCH_Shift %d, NRB2 %d, Ncs1_div_deltaPUCCH_Shift %d, n1_pucch %d]\n", deltaPUCCH_Shift, NRB2, Ncs1_div_deltaPUCCH_Shift,n1_pucch);


gauthier's avatar
gauthier committed
152
153
154
155
  uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30;
  uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30;
  uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
  uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
156

157
  if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) {
knopp's avatar
knopp committed
158
    printf("[PHY] generate_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift);
159
160
161
162
    return;
  }

  if (Ncs1_div_deltaPUCCH_Shift > 7) {
knopp's avatar
knopp committed
163
    printf("[PHY] generate_pucch: Illegal Ncs1_div_deltaPUCCH_Shift %d (should be 0...7)\n",Ncs1_div_deltaPUCCH_Shift);
164
165
166
167
168
169
170
171
172
    return;
  }

  zptr = z;
  thres = (c*Ncs1_div_deltaPUCCH_Shift);
  Nprime_div_deltaPUCCH_Shift = (n1_pucch < thres) ? Ncs1_div_deltaPUCCH_Shift : (12/deltaPUCCH_Shift);
  Nprime = Nprime_div_deltaPUCCH_Shift * deltaPUCCH_Shift;

#ifdef DEBUG_PUCCH_TX
knopp's avatar
knopp committed
173
  printf("[PHY] PUCCH: cNcs1/deltaPUCCH_Shift %d, Nprime %d, n1_pucch %d\n",thres,Nprime,n1_pucch);
174
175
#endif

fnabet's avatar
fnabet committed
176
177
178
179
180
  LOG_D(PHY,"[PHY] PUCCH: n1_pucch %d, thres %d Ncs1_div_deltaPUCCH_Shift %d (12/deltaPUCCH_Shift) %d Nprime_div_deltaPUCCH_Shift %d \n",
		              n1_pucch, thres, Ncs1_div_deltaPUCCH_Shift, (int)(12/deltaPUCCH_Shift), Nprime_div_deltaPUCCH_Shift);
  LOG_D(PHY,"[PHY] PUCCH: deltaPUCCH_Shift %d, Nprime %d\n",deltaPUCCH_Shift,Nprime);


181
182
183
184
185
  N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6;

  if (n1_pucch < thres)
    nprime0=n1_pucch;
  else
186
187
    nprime0 = (n1_pucch - thres)%(12*c/deltaPUCCH_Shift);

188
189
190
191
192
  if (n1_pucch >= thres)
    nprime1= ((c*(nprime0+1))%((12*c/deltaPUCCH_Shift)+1))-1;
  else {
    d = (frame_parms->Ncp==0) ? 2 : 0;
    h= (nprime0+d)%(c*Nprime_div_deltaPUCCH_Shift);
193
194
195
#ifdef DEBUG_PUCCH_TX
    printf("[PHY] PUCCH: h %d, d %d\n",h,d);
#endif
196
    nprime1 = (h/c) + (h%c)*Nprime_div_deltaPUCCH_Shift;
197
198
199
  }

#ifdef DEBUG_PUCCH_TX
knopp's avatar
knopp committed
200
  printf("[PHY] PUCCH: nprime0 %d nprime1 %d, %s, payload (%d,%d)\n",nprime0,nprime1,pucch_format_string[fmt],payload[0],payload[1]);
201
202
203
#endif

  n_oc0 = nprime0/Nprime_div_deltaPUCCH_Shift;
204

205
206
207
208
  if (frame_parms->Ncp==1)
    n_oc0<<=1;

  n_oc1 = nprime1/Nprime_div_deltaPUCCH_Shift;
209

210
211
212
213
  if (frame_parms->Ncp==1)  // extended CP
    n_oc1<<=1;

#ifdef DEBUG_PUCCH_TX
214
  printf("[PHY] PUCCH: noc0 %d noc1 %d\n",n_oc0,n_oc1);
215
216
217
218
219
220
#endif

  nprime=nprime0;
  n_oc  =n_oc0;

  // loop over 2 slots
221
  for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) {
222
223
224
225
226
227
228

    if ((nprime&1) == 0)
      S=0;  // 1
    else
      S=1;  // j

    //loop over symbols in slot
229
    for (l=0; l<N_UL_symb; l++) {
230
231
      // Compute n_cs (36.211 p. 18)
      n_cs = ncs_cell[ns][l];
232

233
      if (frame_parms->Ncp==0) { // normal CP
234
235
236
        n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc%deltaPUCCH_Shift))%Nprime)%12;
      } else {
        n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc>>1))%Nprime)%12;
237
238
239
240
      }


      refs=0;
241

242
243
244
      // Comput W_noc(m) (36.211 p. 19)
      if ((ns==(1+(subframe<<1))) && (shortened_format==1)) {  // second slot and shortened format

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
        if (l<2) {                                         // data
          W_re=W3_re[n_oc][l];
          W_im=W3_im[n_oc][l];
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP
          W_re=W3_re[n_oc][l-2];
          W_im=W3_im[n_oc][l-2];
          refs=1;
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP
          W_re=W4[n_oc][l-2];
          W_im=0;
          refs=1;
        } else if ((l>=N_UL_symb-2)) {                      // data
          W_re=W3_re[n_oc][l-N_UL_symb+4];
          W_im=W3_im[n_oc][l-N_UL_symb+4];
        }
      } else {
        if (l<2) {                                         // data
          W_re=W4[n_oc][l];
          W_im=0;
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP
          W_re=W3_re[n_oc][l-2];
          W_im=W3_im[n_oc][l-2];
          refs=1;
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP
          W_re=W4[n_oc][l-2];
          W_im=0;
          refs=1;
        } else if ((l>=N_UL_symb-2)) {                     // data
          W_re=W4[n_oc][l-N_UL_symb+4];
          W_im=0;
        }
276
277
      }

278
      // multiply W by S(ns) (36.211 p.17). only for data, reference symbols do not have this factor
279
      if ((S==1)&&(refs==0)) {
280
281
282
        tmp_re = W_re;
        W_re = -W_im;
        W_im = tmp_re;
283
284
285
      }

#ifdef DEBUG_PUCCH_TX
knopp's avatar
knopp committed
286
      printf("[PHY] PUCCH: ncs[%d][%d]=%d, W_re %d, W_im %d, S %d, refs %d\n",ns,l,n_cs,W_re,W_im,S,refs);
287
288
#endif
      alpha_ind=0;
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
      // compute output sequence

      for (n=0; n<12; n++) {

        // this is r_uv^alpha(n)
        tmp_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
        tmp_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);

        // this is S(ns)*w_noc(m)*r_uv^alpha(n)
        ref_re = (tmp_re*W_re - tmp_im*W_im)>>15;
        ref_im = (tmp_re*W_im + tmp_im*W_re)>>15;

        if ((l<2)||(l>=(N_UL_symb-2))) { //these are PUCCH data symbols
          switch (fmt) {
          case pucch_format1:   //OOK 1-bit

            ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15;
            ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15;

            break;

          case pucch_format1a:  //BPSK 1-bit
            d0 = (payload[0]&1)==0 ? amp : -amp;
            ((int16_t *)&zptr[n])[0] = ((int32_t)d0*ref_re)>>15;
            ((int16_t *)&zptr[n])[1] = ((int32_t)d0*ref_im)>>15;
            //      printf("d0 %d\n",d0);
            break;

          case pucch_format1b:  //QPSK 2-bits (Table 5.4.1-1 from 36.211, pg. 18)
            if (((payload[0]&1)==0) && ((payload[1]&1)==0))  {// 1
              ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15;
              ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15;
            } else if (((payload[0]&1)==0) && ((payload[1]&1)==1))  { // -j
              ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_im)>>15;
              ((int16_t *)&zptr[n])[1] = (-(int32_t)amp*ref_re)>>15;
            } else if (((payload[0]&1)==1) && ((payload[1]&1)==0))  { // j
              ((int16_t *)&zptr[n])[0] = (-(int32_t)amp*ref_im)>>15;
              ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_re)>>15;
            } else  { // -1
              ((int16_t *)&zptr[n])[0] = (-(int32_t)amp*ref_re)>>15;
              ((int16_t *)&zptr[n])[1] = (-(int32_t)amp*ref_im)>>15;
            }

            break;

          case pucch_format2:
          case pucch_format2a:
          case pucch_format2b:
knopp's avatar
knopp committed
337
            AssertFatal(1==0,"should not go here\n");
338
339
340
341
342
343
344
345
346
            break;
          } // switch fmt
        } else { // These are PUCCH reference symbols

          ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15;
          ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15;
          //    printf("ref\n");
        }

347
#ifdef DEBUG_PUCCH_TX
knopp's avatar
knopp committed
348
        printf("[PHY] PUCCH subframe %d z(%d,%d) => %d,%d, alpha(%d) => %d,%d\n",subframe,l,n,((int16_t *)&zptr[n])[0],((int16_t *)&zptr[n])[1],
349
            alpha_ind,alpha_re[alpha_ind],alpha_im[alpha_ind]);
350
#endif
351
        alpha_ind = (alpha_ind + n_cs)%12;
352
      } // n
353

354
355
356
      zptr+=12;
    } // l

357
358
    nprime=nprime1;
    n_oc  =n_oc1;
359
360
361
362
363
364
365
  } // ns

  rem = ((((12*Ncs1_div_deltaPUCCH_Shift)>>3)&7)>0) ? 1 : 0;

  m = (n1_pucch < thres) ? NRB2 : (((n1_pucch-thres)/(12*c/deltaPUCCH_Shift))+NRB2+((deltaPUCCH_Shift*Ncs1_div_deltaPUCCH_Shift)>>3)+rem);

#ifdef DEBUG_PUCCH_TX
knopp's avatar
knopp committed
366
  printf("[PHY] PUCCH: m %d\n",m);
367
368
369
370
#endif
  nsymb = N_UL_symb<<1;

  //for (j=0,l=0;l<(nsymb-1);l++) {
371
  for (j=0,l=0; l<(nsymb); l++) {
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    if ((l<(nsymb>>1)) && ((m&1) == 0))
      re_offset = (m*6) + frame_parms->first_carrier_offset;
    else if ((l<(nsymb>>1)) && ((m&1) == 1))
      re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12;
    else if ((m&1) == 0)
      re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12;
    else
      re_offset = ((m-1)*6) + frame_parms->first_carrier_offset;

    if (re_offset > frame_parms->ofdm_symbol_size)
      re_offset -= (frame_parms->ofdm_symbol_size);

    symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb));
    txptr = &txdataF[0][symbol_offset];

387
    for (i=0; i<12; i++,j++) {
388
      txptr[re_offset++] = z[j];
389

390
      if (re_offset==frame_parms->ofdm_symbol_size)
391
392
        re_offset = 0;

393
#ifdef DEBUG_PUCCH_TX
knopp's avatar
knopp committed
394
      printf("[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]);
395
396
397
398
399
400
#endif
    }
  }

}

401
void generate_pucch_emul(PHY_VARS_UE *ue,
402
			 UE_rxtx_proc_t *proc,
403
404
405
                         PUCCH_FMT_t format,
                         uint8_t ncs1,
                         uint8_t *pucch_payload,
406
407
                         uint8_t sr)

408
{
409

410
  int subframe = proc->subframe_tx;
411

412
413
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_flag    = format;
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_Ncs1    = ncs1;
414

415

416
417
418
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.sr            = sr;
  // the value of ue->pucch_sel[subframe] is set by get_n1_pucch
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_sel      = ue->pucch_sel[subframe];
419

420
  // LOG_I(PHY,"subframe %d emu tx pucch_sel is %d sr is %d \n", subframe, UE_transport_info[ue->Mod_id].cntl.pucch_sel, sr);
421

422
  if (format == pucch_format1a) {
423

424
425
    ue->pucch_payload[0] = pucch_payload[0];
    UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_payload = pucch_payload[0];
426
  } else if (format == pucch_format1b) {
427
428
    ue->pucch_payload[0] = pucch_payload[0] + (pucch_payload[1]<<1);
    UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_payload = pucch_payload[0] + (pucch_payload[1]<<1);
429
  } else if (format == pucch_format1) {
knopp's avatar
knopp committed
430
    //    LOG_D(PHY,"[UE %d] Frame %d subframe %d Generating PUCCH for SR %d\n",ue->Mod_id,proc->frame_tx,subframe,sr);
431
  }
432

433
  ue->sr[subframe] = sr;
434
435
436

}

knopp's avatar
knopp committed
437
438
439
440
441
442
443
444

inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) __attribute__((always_inline));
inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) {

  uint32_t x1, x2, s=0;
  int i;
  uint8_t c;

445
  x2 = (rnti) + ((uint32_t)(1+subframe)<<16)*(1+(fp->Nid_cell<<1)); //this is c_init in 36.211 Sec 6.3.1
knopp's avatar
knopp committed
446
447
448
449
450
451
452
453
454
455
456
457
458
  s = lte_gold_generic(&x1, &x2, 1);
  for (i=0;i<19;i++) {
    c = (uint8_t)((s>>i)&1);
    btilde[i] = (((B>>i)&1) ^ c);
  }
}

inline void pucch2x_modulation(uint8_t *btilde,int16_t *d,int16_t amp) __attribute__((always_inline));
inline void pucch2x_modulation(uint8_t *btilde,int16_t *d,int16_t amp) {

  int i;

  for (i=0;i<20;i++) 
459
    d[i] = btilde[i] == 1 ? -amp : amp;
knopp's avatar
knopp committed
460
461
462

}

knopp's avatar
knopp committed
463
464


knopp's avatar
knopp committed
465
466
467
468
uint32_t pucch_code[13] = {0xFFFFF,0x5A933,0x10E5A,0x6339C,0x73CE0,
			   0xFFC00,0xD8E64,0x4F6B0,0x218EC,0x1B746,
			   0x0FFFF,0x33FFF,0x3FFFC};

knopp's avatar
knopp committed
469

knopp's avatar
knopp committed
470
471
472
473
474
475
void generate_pucch2x(int32_t **txdataF,
		      LTE_DL_FRAME_PARMS *fp,
		      uint8_t ncs_cell[20][7],
		      PUCCH_FMT_t fmt,
		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
		      uint16_t n2_pucch,
knopp's avatar
knopp committed
476
		      uint16_t *payload,
knopp's avatar
knopp committed
477
478
479
480
481
482
483
484
485
486
487
488
489
490
		      int A,
		      int B2,
		      int16_t amp,
		      uint8_t subframe,
		      uint16_t rnti) {

  int i,j;
  uint32_t B=0;
  uint8_t btilde[20];
  int16_t d[22];
  uint8_t deltaPUCCH_Shift          = fp->pucch_config_common.deltaPUCCH_Shift;
  uint8_t NRB2                      = fp->pucch_config_common.nRB_CQI;
  uint8_t Ncs1                      = fp->pucch_config_common.nCS_AN;

491
492
493
494
495
  uint32_t u0 = fp->pucch_config_common.grouphop[subframe<<1];
  uint32_t u1 = fp->pucch_config_common.grouphop[1+(subframe<<1)];
  uint32_t v0 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
  uint32_t v1 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];

knopp's avatar
knopp committed
496
497
  uint32_t z[12*14],*zptr;
  uint32_t u,v,n;
498
  uint8_t ns,N_UL_symb,nsymb_slot0,nsymb_pertti;
knopp's avatar
knopp committed
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  uint32_t nprime,l,n_cs;
  int alpha_ind,data_ind;
  int16_t ref_re,ref_im;
  int m,re_offset,symbol_offset;
  int32_t *txptr;

  if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) {
    printf("[PHY] generate_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift);
    return;
  }

  if (Ncs1 > 7) {
    printf("[PHY] generate_pucch: Illegal Ncs1 %d (should be 0...7)\n",Ncs1);
    return;
  }

  // pucch2x_encoding
  for (i=0;i<A;i++)
    if ((*payload & (1<<i)) > 0)
      B=B^pucch_code[i];

  // scrambling
  pucch2x_scrambling(fp,subframe,rnti,B,btilde);
  // modulation
  pucch2x_modulation(btilde,d,amp);

  // add extra symbol for 2a/2b
  d[20]=0;
  d[21]=0;
  if (fmt==pucch_format2a)
    d[20] = (B2 == 0) ? amp : -amp;
  else if (fmt==pucch_format2b) {
    switch (B2) {
    case 0:
      d[20] = amp;
      break;
    case 1:
      d[21] = -amp;
      break;
    case 2:
      d[21] = amp;
      break;
    case 3:
      d[20] = -amp;
      break;
    default:
      AssertFatal(1==0,"Illegal modulation symbol %d for PUCCH %s\n",B2,pucch_format_string[fmt]);
      break;
    }
  }


#ifdef DEBUG_PUCCH_TX
  printf("[PHY] PUCCH2x: n2_pucch %d\n",n2_pucch);
#endif

  N_UL_symb = (fp->Ncp==0) ? 7 : 6;
556
557
  data_ind  = 0;
  zptr      = z;
558
  nprime    = 0;
knopp's avatar
knopp committed
559
560
561
  for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) {

    if ((ns&1) == 0)
562
563
564
        nprime = (n2_pucch < 12*NRB2) ?
                n2_pucch % 12 :
                (n2_pucch+Ncs1 + 1)%12;
knopp's avatar
knopp committed
565
    else {
566
567
568
        nprime = (n2_pucch < 12*NRB2) ?
                ((12*(nprime+1)) % 13)-1 :
                (10-n2_pucch)%12;
knopp's avatar
knopp committed
569
    }
knopp's avatar
knopp committed
570
571
572
573
574
    //loop over symbols in slot
    for (l=0; l<N_UL_symb; l++) {
      // Compute n_cs (36.211 p. 18)
      n_cs = (ncs_cell[ns][l]+nprime)%12;

575
      alpha_ind = 0;
knopp's avatar
knopp committed
576
      for (n=0; n<12; n++) {
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
          // this is r_uv^alpha(n)
          ref_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
          ref_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);

          if ((l!=1)&&(l!=5)) { //these are PUCCH data symbols
              ((int16_t *)&zptr[n])[0] = ((int32_t)d[data_ind]*ref_re - (int32_t)d[data_ind+1]*ref_im)>>15;
              ((int16_t *)&zptr[n])[1] = ((int32_t)d[data_ind]*ref_im + (int32_t)d[data_ind+1]*ref_re)>>15;
              //LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n);
          }
          else {
              ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15);
              ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15);
              //LOG_I(PHY,"slot %d ofdm# %d ==> dmrs[%d] \n",ns,l,n);
          }
          alpha_ind = (alpha_ind + n_cs)%12;
knopp's avatar
knopp committed
592
      } // n
593
594
595
596
      zptr+=12;

      if ((l!=1)&&(l!=5))  //these are PUCCH data symbols so increment data index
	     data_ind+=2;
knopp's avatar
knopp committed
597
598
599
600
601
602
    } // l
  } //ns

  m = n2_pucch/12;

#ifdef DEBUG_PUCCH_TX
603
  LOG_D(PHY,"[PHY] PUCCH: n2_pucch %d m %d\n",n2_pucch,m);
knopp's avatar
knopp committed
604
#endif
605
606
607
608
609

  nsymb_slot0  = ((fp->Ncp==0) ? 7 : 6);
  nsymb_pertti = nsymb_slot0 << 1;

  //nsymb = nsymb_slot0<<1;
knopp's avatar
knopp committed
610
611

  //for (j=0,l=0;l<(nsymb-1);l++) {
612
613
614
  for (j=0,l=0; l<(nsymb_pertti); l++) {

    if ((l<nsymb_slot0) && ((m&1) == 0))
knopp's avatar
knopp committed
615
      re_offset = (m*6) + fp->first_carrier_offset;
616
    else if ((l<nsymb_slot0) && ((m&1) == 1))
knopp's avatar
knopp committed
617
618
619
620
621
622
623
624
625
      re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12;
    else if ((m&1) == 0)
      re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12;
    else
      re_offset = ((m-1)*6) + fp->first_carrier_offset;

    if (re_offset > fp->ofdm_symbol_size)
      re_offset -= (fp->ofdm_symbol_size);

626
627
628


    symbol_offset = (unsigned int)fp->ofdm_symbol_size*(l+(subframe*nsymb_pertti));
knopp's avatar
knopp committed
629
630
    txptr = &txdataF[0][symbol_offset];

631
632
    //LOG_I(PHY,"ofdmSymb %d/%d, firstCarrierOffset %d, symbolOffset[sfn %d] %d, reOffset %d, &txptr: %x \n", l, nsymb, fp->first_carrier_offset, subframe, symbol_offset, re_offset, &txptr[0]);

knopp's avatar
knopp committed
633
    for (i=0; i<12; i++,j++) {
634
635
636
      txptr[re_offset] = z[j];

      re_offset++;
knopp's avatar
knopp committed
637
638

      if (re_offset==fp->ofdm_symbol_size)
639
          re_offset -= (fp->ofdm_symbol_size);
knopp's avatar
knopp committed
640
641

#ifdef DEBUG_PUCCH_TX
642
      LOG_D(PHY,"[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]);
knopp's avatar
knopp committed
643
644
645
#endif
    }
  }
646
647
}

knopp's avatar
knopp committed
648

knopp's avatar
knopp committed
649
650
651
652
//#define Amax 13
//void init_pucch2x_rx() {};


653
uint32_t rx_pucch(PHY_VARS_eNB *eNB,
654
655
656
657
658
659
		  PUCCH_FMT_t fmt,
		  uint8_t UE_id,
		  uint16_t n1_pucch,
		  uint16_t n2_pucch,
		  uint8_t shortened_format,
		  uint8_t *payload,
660
		  int     frame,
661
662
		  uint8_t subframe,
		  uint8_t pucch1_thres)
663
{
664
665


666
  static int first_call=1;
667
668
669
670
671
672
673
674
675
  LTE_eNB_COMMON *common_vars                = &eNB->common_vars;
  LTE_DL_FRAME_PARMS *frame_parms                    = &eNB->frame_parms;
  //  PUCCH_CONFIG_DEDICATED *pucch_config_dedicated = &eNB->pucch_config_dedicated[UE_id];
  int8_t sigma2_dB                                   = eNB->measurements[0].n0_subband_power_tot_dB[0]-10;
  uint32_t *Po_PUCCH                                  = &(eNB->UE_stats[UE_id].Po_PUCCH);
  int32_t *Po_PUCCH_dBm                              = &(eNB->UE_stats[UE_id].Po_PUCCH_dBm);
  uint32_t *Po_PUCCH1_below                           = &(eNB->UE_stats[UE_id].Po_PUCCH1_below);
  uint32_t *Po_PUCCH1_above                           = &(eNB->UE_stats[UE_id].Po_PUCCH1_above);
  int32_t *Po_PUCCH_update                           = &(eNB->UE_stats[UE_id].Po_PUCCH_update);
gauthier's avatar
gauthier committed
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
  uint32_t u,v,n,aa;
  uint32_t z[12*14];
  int16_t *zptr;
  int16_t rxcomp[NB_ANTENNAS_RX][2*12*14];
  uint8_t ns,N_UL_symb,nsymb,n_oc,n_oc0,n_oc1;
  uint8_t c = (frame_parms->Ncp==0) ? 3 : 2;
  uint16_t nprime,nprime0,nprime1;
  uint16_t i,j,re_offset,thres,h,off;
  uint8_t Nprime_div_deltaPUCCH_Shift,Nprime,d;
  uint8_t m,l,refs,phase,re,l2,phase_max=0;
  uint8_t n_cs,S,alpha_ind,rem;
  int16_t tmp_re,tmp_im,W_re=0,W_im=0;
  int16_t *rxptr;
  uint32_t symbol_offset;
  int16_t stat_ref_re,stat_ref_im,*cfo,chest_re,chest_im;
  int32_t stat_re=0,stat_im=0;
692
  uint32_t stat,stat_max=0;
gauthier's avatar
gauthier committed
693
694
695
696
697
698
699
700
701

  uint8_t deltaPUCCH_Shift          = frame_parms->pucch_config_common.deltaPUCCH_Shift;
  uint8_t NRB2                      = frame_parms->pucch_config_common.nRB_CQI;
  uint8_t Ncs1_div_deltaPUCCH_Shift = frame_parms->pucch_config_common.nCS_AN;

  uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30;
  uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30;
  uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
  uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
702
  int chL;
703

704
705
706
  if (first_call == 1) {
    for (i=0;i<10;i++) {
      for (j=0;j<NUMBER_OF_UE_MAX;j++) {
707
708
	eNB->pucch1_stats_cnt[j][i]=0;
	eNB->pucch1ab_stats_cnt[j][i]=0;
709
710
711
712
      }
    }
    first_call=0;
  }
713
  /*
knopp's avatar
knopp committed
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
  switch (frame_parms->N_RB_UL) {

  case 6:
    sigma2_dB -= 8;
    break;
  case 25:
    sigma2_dB -= 14;
    break;
  case 50:
    sigma2_dB -= 17;
    break;
  case 100:
    sigma2_dB -= 20;
    break;
  default:
    sigma2_dB -= 14;
  }
731
  */  
knopp's avatar
knopp committed
732

733
    
734
735
736
737
738
739
740
741
742
743
  if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) {
    LOG_E(PHY,"[eNB] rx_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift);
    return(-1);
  }

  if (Ncs1_div_deltaPUCCH_Shift > 7) {
    LOG_E(PHY,"[eNB] rx_pucch: Illegal Ncs1_div_deltaPUCCH_Shift %d (should be 0...7)\n",Ncs1_div_deltaPUCCH_Shift);
    return(-1);
  }

gauthier's avatar
gauthier committed
744
  zptr = (int16_t *)z;
745
746
747
748
749
  thres = (c*Ncs1_div_deltaPUCCH_Shift);
  Nprime_div_deltaPUCCH_Shift = (n1_pucch < thres) ? Ncs1_div_deltaPUCCH_Shift : (12/deltaPUCCH_Shift);
  Nprime = Nprime_div_deltaPUCCH_Shift * deltaPUCCH_Shift;

#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
750
  printf("[eNB] PUCCH: cNcs1/deltaPUCCH_Shift %d, Nprime %d, n1_pucch %d\n",thres,Nprime,n1_pucch);
751
752
#endif

753
  N_UL_symb = (frame_parms->Ncp==NORMAL) ? 7 : 6;
754
755
756
757

  if (n1_pucch < thres)
    nprime0=n1_pucch;
  else
758
759
    nprime0 = (n1_pucch - thres)%(12*c/deltaPUCCH_Shift);

760
761
762
763
764
  if (n1_pucch >= thres)
    nprime1= ((c*(nprime0+1))%((12*c/deltaPUCCH_Shift)+1))-1;
  else {
    d = (frame_parms->Ncp==0) ? 2 : 0;
    h= (nprime0+d)%(c*Nprime_div_deltaPUCCH_Shift);
765
    nprime1 = (h/c) + (h%c)*Nprime_div_deltaPUCCH_Shift;
766
767
768
  }

#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
769
  printf("PUCCH: nprime0 %d nprime1 %d\n",nprime0,nprime1);
770
771
772
#endif

  n_oc0 = nprime0/Nprime_div_deltaPUCCH_Shift;
773

774
775
776
777
  if (frame_parms->Ncp==1)
    n_oc0<<=1;

  n_oc1 = nprime1/Nprime_div_deltaPUCCH_Shift;
778

779
780
781
782
  if (frame_parms->Ncp==1)  // extended CP
    n_oc1<<=1;

#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
783
  printf("[eNB] PUCCH: noc0 %d noc11 %d\n",n_oc0,n_oc1);
784
785
786
787
788
789
#endif

  nprime=nprime0;
  n_oc  =n_oc0;

  // loop over 2 slots
790
  for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) {
791
792
793
794
795

    if ((nprime&1) == 0)
      S=0;  // 1
    else
      S=1;  // j
796
797
798
799
800
801
    /*
    if (fmt==pucch_format1)
      LOG_I(PHY,"[eNB] subframe %d => PUCCH1: u%d %d, v%d %d : ", subframe,ns&1,u,ns&1,v);
    else
      LOG_I(PHY,"[eNB] subframe %d => PUCCH1a/b: u%d %d, v%d %d : ", subframe,ns&1,u,ns&1,v);
    */
802
803

    //loop over symbols in slot
804
    for (l=0; l<N_UL_symb; l++) {
805
      // Compute n_cs (36.211 p. 18)
806
      n_cs = eNB->ncs_cell[ns][l];
807

808
      if (frame_parms->Ncp==0) { // normal CP
809
810
811
        n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc%deltaPUCCH_Shift))%Nprime)%12;
      } else {
        n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc>>1))%Nprime)%12;
812
813
814
      }


815

816
      refs=0;
817

818
819
820
      // Comput W_noc(m) (36.211 p. 19)
      if ((ns==(1+(subframe<<1))) && (shortened_format==1)) {  // second slot and shortened format

821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
        if (l<2) {                                         // data
          W_re=W3_re[n_oc][l];
          W_im=W3_im[n_oc][l];
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP
          W_re=W3_re[n_oc][l-2];
          W_im=W3_im[n_oc][l-2];
          refs=1;
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP
          W_re=W4[n_oc][l-2];
          W_im=0;
          refs=1;
        } else if ((l>=N_UL_symb-2)) {                      // data
          W_re=W3_re[n_oc][l-N_UL_symb+4];
          W_im=W3_im[n_oc][l-N_UL_symb+4];
        }
      } else {
        if (l<2) {                                         // data
          W_re=W4[n_oc][l];
          W_im=0;
840
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==NORMAL)) { // reference and normal CP
841
842
843
          W_re=W3_re[n_oc][l-2];
          W_im=W3_im[n_oc][l-2];
          refs=1;
844
        } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==EXTENDED)) { // reference and extended CP
845
846
847
848
849
850
851
          W_re=W4[n_oc][l-2];
          W_im=0;
          refs=1;
        } else if ((l>=N_UL_symb-2)) {                     // data
          W_re=W4[n_oc][l-N_UL_symb+4];
          W_im=0;
        }
852
853
      }

854
      // multiply W by S(ns) (36.211 p.17). only for data, reference symbols do not have this factor
855
      if ((S==1)&&(refs==0)) {
856
857
858
        tmp_re = W_re;
        W_re = -W_im;
        W_im = tmp_re;
859
860
861
      }

#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
862
      printf("[eNB] PUCCH: ncs[%d][%d]=%d, W_re %d, W_im %d, S %d, refs %d\n",ns,l,n_cs,W_re,W_im,S,refs);
863
864
#endif
      alpha_ind=0;
865
      // compute output sequence
866

867
      for (n=0; n<12; n++) {
868

869
870
871
        // this is r_uv^alpha(n)
        tmp_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
        tmp_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);
872

873
874
875
        // this is S(ns)*w_noc(m)*r_uv^alpha(n)
        zptr[n<<1] = (tmp_re*W_re - tmp_im*W_im)>>15;
        zptr[1+(n<<1)] = -(tmp_re*W_im + tmp_im*W_re)>>15;
876
877

#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
878
        printf("[eNB] PUCCH subframe %d z(%d,%d) => %d,%d, alpha(%d) => %d,%d\n",subframe,l,n,zptr[n<<1],zptr[(n<<1)+1],
879
              alpha_ind,alpha_re[alpha_ind],alpha_im[alpha_ind]);
880
#endif
881

882
        alpha_ind = (alpha_ind + n_cs)%12;
883
      } // n
884

885
886
887
      zptr+=24;
    } // l

888
889
    nprime=nprime1;
    n_oc  =n_oc1;
890
891
892
893
894
895
896
  } // ns

  rem = ((((deltaPUCCH_Shift*Ncs1_div_deltaPUCCH_Shift)>>3)&7)>0) ? 1 : 0;

  m = (n1_pucch < thres) ? NRB2 : (((n1_pucch-thres)/(12*c/deltaPUCCH_Shift))+NRB2+((deltaPUCCH_Shift*Ncs1_div_deltaPUCCH_Shift)>>3)+rem);

#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
897
  printf("[eNB] PUCCH: m %d\n",m);
898
899
900
#endif
  nsymb = N_UL_symb<<1;

gauthier's avatar
gauthier committed
901
  zptr = (int16_t*)z;
902
903

  // Do detection
904
905
  for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {

906
    //for (j=0,l=0;l<(nsymb-1);l++) {
907
    for (j=0,l=0; l<nsymb; l++) {
908
      if ((l<(nsymb>>1)) && ((m&1) == 0))
909
        re_offset = (m*6) + frame_parms->first_carrier_offset;
910
      else if ((l<(nsymb>>1)) && ((m&1) == 1))
911
        re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12;
912
      else if ((m&1) == 0)
913
        re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12;
914
      else
915
916
        re_offset = ((m-1)*6) + frame_parms->first_carrier_offset;

917
      if (re_offset > frame_parms->ofdm_symbol_size)
918
919
        re_offset -= (frame_parms->ofdm_symbol_size);

920
      symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*l;
921
      rxptr = (int16_t *)&common_vars->rxdataF[0][aa][symbol_offset];
922
923

      for (i=0; i<12; i++,j+=2,re_offset++) {
924
925
        rxcomp[aa][j]   = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[j])>>15)   - ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[1+j])>>15);
        rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[j])>>15);
926
927
928
929

        if (re_offset==frame_parms->ofdm_symbol_size)
          re_offset = 0;

930
#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
931
        printf("[eNB] PUCCH subframe %d (%d,%d,%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,i,re_offset,m,j,
932
              rxptr[re_offset<<1],rxptr[1+(re_offset<<1)],
933
934
              zptr[j],zptr[1+j],
              rxcomp[aa][j],rxcomp[aa][1+j]);
935
936
937
938
939
940
941
942
943
944
945
#endif
      } //re
    } // symbol
  }  // antenna


  // PUCCH Format 1
  // Do cfo correction and MRC across symbols

  if (fmt == pucch_format1) {
#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
946
    printf("Doing PUCCH detection for format 1\n");
947
948
949
#endif

    stat_max = 0;
950
951
952


    for (phase=0; phase<7; phase++) {
953
      stat=0;
954
955
956
957
958
959
960
961
962

      for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
        for (re=0; re<12; re++) {
          stat_re=0;
          stat_im=0;
          off=re<<1;
          cfo =  (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase] : &cfo_pucch_ep[12*phase];

          for (l=0; l<(nsymb>>1); l++) {
963
964
            stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/nsymb;
            stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/nsymb;
965
            off+=2;
966
967

		    
968
#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
969
            printf("[eNB] PUCCH subframe %d (%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) , stat %d\n",subframe,phase,l,re,
970
971
                  rxcomp[aa][off],rxcomp[aa][1+off],
                  cfo[l<<1],cfo[1+(l<<1)],
972
                  stat_re,stat_im,stat);
973
974
975
976
#endif
          }

          for (l2=0,l=(nsymb>>1); l<(nsymb-1); l++,l2++) {
977
978
            stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15))/nsymb;
            stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15))/nsymb;
979
            off+=2;
980

981
#ifdef DEBUG_PUCCH_RX
knopp's avatar
knopp committed
982
            printf("[eNB] PUCCH subframe %d (%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d), stat %d\n",subframe,phase,l2,re,
983
984
                  rxcomp[aa][off],rxcomp[aa][1+off],
                  cfo[l2<<1],cfo[1+(l2<<1)],
985
                  stat_re,stat_im,stat);
986
987
#endif

988

989
          }
990
991
	  stat += ((stat_re*stat_re) + (stat_im*stat_im));

992
       } //re
993
994
      } // aa

995
 
996
      if (stat>stat_max) {
997
998
        stat_max = stat;
        phase_max = phase;
999
      }
1000

For faster browsing, not all history is shown. View entire blame