lte_ul_ref_NB_IoT.c 16.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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
 */
21 22 23
/*! \file PHY/LTE_REFSIG/lte_ul_ref_NB_IoT.c
* \function called by lte_dl_cell_spec_NB_IoT.c ,  TS 36-211, V13.4.0 2017-02
* \author: Vincent Savaux
Matthieu Kanj's avatar
Matthieu Kanj committed
24
* \date 2018
25 26 27 28 29 30
* \version 0.0
* \company b<>com
* \email: vincent.savaux@b-com.com
* \note
* \warning
*/
31 32 33 34 35 36

#ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#endif
37 38 39
// #include "defs.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "PHY/defs_NB_IoT.h"
40

41
// uint16_t dftsizes[33] = {12,24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,864,900,960,972,1080,1152,1200};
42

43
// uint16_t ref_primes[33] = {11,23,31,47,59,71,89,107,113,139,179,191,211,239,283,293,317,359,383,431,479,523,571,599,647,719,863,887,953,971,1069,1151,1193};
44

Matthieu Kanj's avatar
Matthieu Kanj committed
45
uint16_t sequence_length[4] = {100,100,100,100}; //the "32" value corresponds to the max gold sequence length 
46 47

// int16_t *ul_ref_sigs[30][33];
48
int16_t *ul_ref_sigs_rx_NB_IoT[30][4]; //these contain the sequences in repeated format and quantized to QPSK ifdef IFFT_FPGA
49
int16_t *ul_ref_sigs_f2_rx_NB_IoT[16]; //this table contain the 16 possible pilots for format 2 NPUSCH
50
uint16_t u_max[4] = {16,12,14,30}; // maximum u value, see 36.211, Section 10.1.4
51 52

/* 36.211 table 5.5.1.2-1 */
53
char ref12_NB_IoT[360] = {-1,1,3,-3,3,3,1,1,3,1,-3,3,1,1,3,3,3,-1,1,-3,-3,1,-3,3,1,1,-3,-3,-3,-1,-3,-3,1,-3,1,-1,-1,1,1,1,1,-1,-3,-3,1,-3,3,-1,-1,3,1,-1,1,-1,-3,-1,1,-1,1,3,1,-3,3,-1,-1,1,1,-1,-1,3,-3,1,-1,3,-3,-3,-3,3,1,-1,3,3,-3,1,-3,-1,-1,-1,1,-3,3,-1,1,-3,3,1,1,-3,3,1,-1,-1,-1,1,1,3,-1,1,1,-3,-1,3,3,-1,-3,1,1,1,1,1,-1,3,-1,1,1,-3,-3,-1,-3,-3,3,-1,3,1,-1,-1,3,3,-3,1,3,1,3,3,1,-3,1,1,-3,1,1,1,-3,-3,-3,1,3,3,-3,3,-3,1,1,3,-1,-3,3,3,-3,1,-1,-3,-1,3,1,3,3,3,-1,1,3,-1,1,-3,-1,-1,1,1,3,1,-1,-3,1,3,1,-1,1,3,3,3,-1,-1,3,-1,-3,1,1,3,-3,3,-3,-3,3,1,3,-1,-3,3,1,1,-3,1,-3,-3,-1,-1,1,-3,-1,3,1,3,1,-1,-1,3,-3,-1,-3,-1,-1,-3,1,1,1,1,3,1,-1,1,-3,-1,-1,3,-1,1,-3,-3,-3,-3,-3,1,-1,-3,1,1,-3,-3,-3,-3,-1,3,-3,1,-3,3,1,1,-1,-3,-1,-3,1,-1,1,3,-1,1,1,1,3,1,3,3,-1,1,-1,-3,-3,1,1,-3,3,3,1,3,3,1,-3,-1,-1,3,1,3,-3,-3,3,-3,1,-1,-1,3,-1,-3,-3,-1,-3,-1,-3,3,1,-1,1,3,-3,-3,-1,3,-3,3,-1,3,3,-3,3,3,-1,-1,3,-3,-3,-1,-1,-3,-1,3,-3,3,1,-1};
54 55 56 57 58 59 60 61 62 63 64 65 66 67

/* 36.211 table 5.5.1.2-2 */
// char ref24[720] = {
//   -1,3,1,-3,3,-1,1,3,-3,3,1,3,-3,3,1,1,-1,1,3,-3,3,-3,-1,-3,-3,3,-3,-3,-3,1,-3,-3,3,-1,1,1,1,3,1,-1,3,-3,-3,1,3,1,1,-3,3,-1,3,3,1,1,-3,3,3,3,3,1,-1,3,-1,1,1,-1,-3,-1,-1,1,3,3,-1,-3,1,1,3,-3,1,1,-3,-1,-1,1,3,1,3,1,-1,3,1,1,-3,-1,-3,-1,-1,-1,-1,-3,-3,-1,1,1,3,3,-1,3,-1,1,-1,-3,1,-1,-3,-3,1,-3,-1,-1,-3,1,1,3,-1,1,3,1,-3,1,-3,1,1,-1,-1,3,-1,-3,3,-3,-3,-3,1,1,1,1,-1,-1,3,-3,-3,3,-3,1,-1,-1,1,-1,1,1,-1,-3,-1,1,-1,3,-1,-3,-3,3,3,-1,-1,-3,-1,3,1,3,1,3,1,1,-1,3,1,-1,1,3,-3,-1,-1,1,-3,1,3,-3,1,-1,-3,3,-3,3,-1,-1,-1,-1,1,-3,-3,-3,1,-3,-3,-3,1,-3,1,1,-3,3,3,-1,-3,-1,3,-3,3,3,3,-1,1,1,-3,1,-1,1,1,-3,1,1,-1,1,-3,-3,3,-1,3,-1,-1,-3,-3,-3,-1,-3,-3,1,-1,1,3,3,-1,1,-1,3,1,3,3,-3,-3,1,3,1,-1,-3,-3,-3,3,3,-3,3,3,-1,-3,3,-1,1,-3,1,1,3,3,1,1,1,-1,-1,1,-3,3,-1,1,1,-3,3,3,-1,-3,3,-3,-1,-3,-1,3,-1,-1,-1,-1,-3,-1,3,3,1,-1,1,3,3,3,-1,1,1,-3,1,3,-1,-3,3,-3,-3,3,1,3,1,-3,3,1,3,1,1,3,3,-1,-1,-3,1,-3,-1,3,1,1,3,-1,-1,1,-3,1,3,-3,1,-1,-3,-1,3,1,3,1,-1,-3,-3,-1,-1,-3,-3,-3,-1,-1,-3,3,-1,-1,-1,-1,1,1,-3,3,1,3,3,1,-1,1,-3,1,-3,1,1,-3,-1,1,3,-1,3,3,-1,-3,1,-1,-3,3,3,3,-1,1,1,3,-1,-3,-1,3,-1,-1,-1,1,1,1,1,1,-1,3,-1,-3,1,1,3,-3,1,-3,-1,1,1,-3,-3,3,1,1,-3,1,3,3,1,-1,-3,3,-1,3,3,3,-3,1,-1,1,-1,-3,-1,1,3,-1,3,-3,-3,-1,-3,3,-3,-3,-3,-1,-1,-3,-1,-3,3,1,3,-3,-1,3,-1,1,-1,3,-3,1,-1,-3,-3,1,1,-1,1,-1,1,-1,3,1,-3,-1,1,-1,1,-1,-1,3,3,-3,-1,1,-3,-3,-1,-3,3,1,-1,-3,-1,-3,-3,3,-3,3,-3,-1,1,3,1,-3,1,3,3,-1,-3,-1,-1,-1,-1,3,3,3,1,3,3,-3,1,3,-1,3,-1,3,3,-3,3,1,-1,3,3,1,-1,3,3,-1,-3,3,-3,-1,-1,3,-1,3,-1,-1,1,1,1,1,-1,-1,-3,-1,3,1,-1,1,-1,3,-1,3,1,1,-1,-1,-3,1,1,-3,1,3,-3,1,1,-3,-3,-1,-1,-3,-1,1,3,1,1,-3,-1,-1,-3,3,-3,3,1,-3,3,-3,1,-1,1,-3,1,1,1,-1,-3,3,3,1,1,3,-1,-3,-1,-1,-1,3,1,-3,-3,-1,3,-3,-1,-3,-1,-3,-1,-1,-3,-1,-1,1,-3,-1,-1,1,-1,-3,1,1,-3,1,-3,-3,3,1,1,-1,3,-1,-1,1,1,-1,-1,-3,-1,3,-1,3,-1,1,3,1,-1,3,1,3,-3,-3,1,-1,-1,1,3
// }; 

// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-1 
char ref3[36] = {1,  -3,  -3, 1, -3,  -1, 1, -3,  3, 1, -1,  -1, 1, -1,  1, 1, -1,  3, 1, 1, -3, 1, 1, -1, 1, 1, 3, 1, 3, -1, 1, 3, 1, 1, 3, 3 }; 

// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-2 
char ref6[84] = {1,  1, 1, 1, 3, -3, 1, 1, 3, 1, -3,  3, 1, -1,  -1,  -1,  1, -3, 1, -1,  3, -3,  -1,  -1, 1, 3, 1, -1,  -1,  3, 1, -3,  -3,  1, 3, 1, -1,  -1,  1, -3,  -3,  -1, 
                -1,  -1,  -1,  3, -3,  -1, 3, -1,  1, -3,  -3,  3, 3, -1,  3, -3,  -1,  1, 3, -3,  3, -1,  3, 3, -3,  1, 3, 1, -3,  -1, -3,  1, -3,  3, -3,  -1, -3,  3, -3,  1, 1, -3};

// NB-IoT: 36.211, Section 10.1.4.1.1, Table 10.1.4.1.1-1
68
int16_t w_n[256] = {
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
  1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,
  1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1,
  1, 1, 1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1,
  1,-1, 1,-1,-1, 1,-1, 1, 1,-1, 1,-1,-1, 1,-1, 1,
  1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,
  1,-1,-1, 1,-1, 1, 1,-1, 1,-1,-1, 1,-1, 1, 1,-1,
  1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,
  1,-1, 1,-1, 1,-1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,
  1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1,
  1,-1,-1, 1, 1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1,
  1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,
  1,-1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1, 1,-1, 1,-1,
  1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1, 1, 1,-1,-1,
  1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 1,-1,-1, 1
}; 

87 88


89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
// void generate_ul_ref_sigs(void)
// {
//   double qbar,phase;
//   unsigned int u,v,Msc_RS,q,m,n;

//   // These are the Zadoff-Chu sequences (for RB 3-100)
//   for (Msc_RS=2; Msc_RS<33; Msc_RS++) {
//     for (u=0; u<30; u++) {
//       for (v=0; v<2; v++) {
//         qbar = ref_primes[Msc_RS] * (u+1)/(double)31;
//         ul_ref_sigs[u][v][Msc_RS] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[Msc_RS]);

//         if ((((int)floor(2*qbar))&1) == 0)
//           q = (int)(floor(qbar+.5)) - v;
//         else
//           q = (int)(floor(qbar+.5)) + v;

// #ifdef MAIN
//         printf("Msc_RS %d (%d), u %d, v %d -> q %d (qbar %f)\n",Msc_RS,dftsizes[Msc_RS],u,v,q,qbar);
// #endif

//         for (n=0; n<dftsizes[Msc_RS]; n++) {
//           m=n%ref_primes[Msc_RS];
//           phase = (double)q*m*(m+1)/ref_primes[Msc_RS];
//           ul_ref_sigs[u][v][Msc_RS][n<<1]     =(int16_t)(floor(32767*cos(M_PI*phase)));
//           ul_ref_sigs[u][v][Msc_RS][1+(n<<1)] =-(int16_t)(floor(32767*sin(M_PI*phase)));
// #ifdef MAIN

//           if (Msc_RS<5)
//             printf("(%d,%d) ",ul_ref_sigs[u][v][Msc_RS][n<<1],ul_ref_sigs[u][v][Msc_RS][1+(n<<1)]);

// #endif
//         }

// #ifdef MAIN

//         if (Msc_RS<5)
//           printf("\n");

// #endif
//       }
//     }
//   }

//   // These are the sequences for RB 1
//   for (u=0; u<30; u++) {
//     ul_ref_sigs[u][0][0] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[0]);

//     for (n=0; n<dftsizes[0]; n++) {
//       ul_ref_sigs[u][0][0][n<<1]    =(int16_t)(floor(32767*cos(M_PI*ref12[(u*12) + n]/4)));
//       ul_ref_sigs[u][0][0][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref12[(u*12) + n]/4)));
//     }

//   }

//   // These are the sequences for RB 2
//   for (u=0; u<30; u++) {
//     ul_ref_sigs[u][0][1] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[1]);

//     for (n=0; n<dftsizes[1]; n++) {
//       ul_ref_sigs[u][0][1][n<<1]    =(int16_t)(floor(32767*cos(M_PI*ref24[(u*24) + n]/4)));
//       ul_ref_sigs[u][0][1][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref24[(u*24) + n]/4)));
//     }
//   }
// }

Matthieu Kanj's avatar
Matthieu Kanj committed
155
/*void generate_ul_ref_sigs_rx_NB_IoT(void)
156 157
{

158
  unsigned int u,index_Nsc_RU,n; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12 
159
  uint8_t npusch_format = 1; // NB-IoT: format 1 (data), or 2: ack. Should be defined in higher layer 
160 161
  int16_t  a;
  int16_t   qpsk[2]; 
162
  unsigned int x1, x2=35; // NB-IoT: defined in 36.211, Section 10.1.4.1.1
163 164 165 166 167 168 169 170 171 172
  int16_t ref_sigs_sc1[2*sequence_length[0]]; 
  uint32_t s; 

  a = (ONE_OVER_SQRT2_Q15_NB_IoT)>>15;
  qpsk[0] = a; 
  qpsk[1] = -a;
  s = lte_gold_generic_NB_IoT(&x1, &x2, 1);

  for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++) {
    for (u=0; u<u_max[index_Nsc_RU]; u++) { 
173
      // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc16(2*sizeof(int16_t)*sequence_length[index_Nsc_RU]); 
174 175
      switch (index_Nsc_RU){
        case 0: // 36.211, Section 10.1.4.1.1
Matthieu Kanj's avatar
Matthieu Kanj committed
176
          ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*sequence_length[index_Nsc_RU]*12+24)); // *12 is mandatory to fit channel estimation functions
177
          // NB-IoT: for same reason, +24 is added in order to fit the possible subcarrier start shift when index_Nsc_RU = 0, 1, 2 --> see ul_sc_start in channel estimation function
178
          for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
Matthieu Kanj's avatar
Matthieu Kanj committed
179 180 181 182 183
    if (n!=0 && n%32==0)
    {
      s = lte_gold_generic_NB_IoT(&x1, &x2, 0);   
    }
            ref_sigs_sc1[n<<1]    = qpsk[(s>>(n%32))&1]*w_n[16*u+n%16]; 
184 185
            // ref_sigs_sc1[1+(n<<1)] = qpsk[(s>>n)&1]*w_n[16*u+n%16];
            ref_sigs_sc1[1+(n<<1)] = ref_sigs_sc1[n<<1];  
Matthieu Kanj's avatar
Matthieu Kanj committed
186
      
187 188 189
          }
          if (npusch_format==1){
            for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
190 191 192 193
              // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1]    = ref_sigs_sc1[n<<1];
              // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= ref_sigs_sc1[1+(n<<1)];
              ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][12*(n<<1)+24]    = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, real part
              ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+12*(n<<1)+24]= ref_sigs_sc1[1+(n<<1)]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, imaginary part    
194 195 196 197 198
            }
          }
          if (npusch_format==2){// NB-IoT: to be implemented
            printf("Not coded yet\n"); 
          }
199
          break; 
200
        case 1: // 36.211, Section 10.1.4.1.2
Matthieu Kanj's avatar
Matthieu Kanj committed
201
          ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*12+24)); // *12 is mandatory to fit channel estimation functions
202
          for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
203 204 205 206
            // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1]    = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift])));
            // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift]))); 
            ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][(n<<1)+24]    = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 )));
            ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)+24]= (int16_t)(floor(32767*sin(M_PI*ref3[(u*3) + n]/4 )));
207 208 209
          }
          break; 
        case 2:
Matthieu Kanj's avatar
Matthieu Kanj committed
210
          ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*12+24)); // *12 is mandatory to fit channel estimation functions
211
          for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
212 213 214 215
            // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1]    = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
            // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
            ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][(n<<1)+24]    = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 )));
            ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)+24]= (int16_t)(floor(32767*sin(M_PI*ref6[(u*6) + n]/4 )));
216 217 218
          }
          break; 
        case 3:
Matthieu Kanj's avatar
Matthieu Kanj committed
219
          ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*12+24)); // *12 is mandatory to fit channel estimation functions
220
          for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
221 222
            ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1]    = (int16_t)(floor(32767*cos(M_PI*ref12_NB_IoT[(u*12) + n]/4)));
            ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref12_NB_IoT[(u*12) + n]/4)));
223 224 225 226 227 228 229
          }
          break; 
      }
    }
  }


Matthieu Kanj's avatar
Matthieu Kanj committed
230 231 232 233 234
}*/ 

void generate_ul_ref_sigs_rx_NB_IoT(void)
{

Matthieu Kanj's avatar
Matthieu Kanj committed
235
  unsigned int u,index_Nsc_RU,n,m; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12 
236
  //uint8_t npusch_format = 1; // NB-IoT: format 1 (data), or 2: ack. Should be defined in higher layer 
Matthieu Kanj's avatar
Matthieu Kanj committed
237 238
  int16_t  a;
  int16_t   qpsk[2]; 
239 240 241
  unsigned int x1, x2; // NB-IoT: defined in 36.211, Section 10.1.4.1.1
  int16_t ref_sigs_sc1[2*sequence_length[0]]; // this is for format 1
  //int16_t ref_sigs_sc1_f2[2*sequence_length[0]]; // this is for format 2
Matthieu Kanj's avatar
Matthieu Kanj committed
242 243 244 245 246
  uint32_t s; 

  a = ONE_OVER_SQRT2_Q15_NB_IoT;
  qpsk[0] = a; 
  qpsk[1] = -a;
247
  
Matthieu Kanj's avatar
Matthieu Kanj committed
248 249 250 251 252 253 254 255 256
  //printf("\n\n\n in generate_ul_ref_sigs_rx_NB_IoT  %d \n\n\n",a);
  for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++) 
  {
    for (u=0; u<u_max[index_Nsc_RU]; u++) 
    { 
      // ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc16(2*sizeof(int16_t)*sequence_length[index_Nsc_RU]); 
      switch (index_Nsc_RU)
      {
        case 0: // 36.211, Section 10.1.4.1.1
257 258
    x2=35;
    s = lte_gold_generic_NB_IoT(&x1, &x2, 1);
Matthieu Kanj's avatar
Matthieu Kanj committed
259
          ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*sequence_length[index_Nsc_RU]*12+24)); // *12 is mandatory to fit channel estimation functions
260
    ul_ref_sigs_f2_rx_NB_IoT[u] = (int16_t*)malloc(sizeof(int16_t)*(2*12*12+24)); // first "*12" is mandatory to fit channel estimation functions; first "*12" is the length of pilot sequence for                        format 2
Matthieu Kanj's avatar
Matthieu Kanj committed
261
          // NB-IoT: for same reason, +24 is added in order to fit the possible subcarrier start shift when index_Nsc_RU = 0, 1, 2 --> see ul_sc_start in channel estimation function
262
          for (n=0; n<sequence_length[index_Nsc_RU]; n++) 
Matthieu Kanj's avatar
Matthieu Kanj committed
263
    {
264 265 266 267 268 269 270
        if (n>0 && n%32==0)
        {
            s = lte_gold_generic_NB_IoT(&x1, &x2, 0);   
        }
              ref_sigs_sc1[n<<1]    = qpsk[(s>>(n%32))&1]*w_n[16*u+n%16]; 
              // ref_sigs_sc1[1+(n<<1)] = qpsk[(s>>n)&1]*w_n[16*u+n%16];
              ref_sigs_sc1[1+(n<<1)] = ref_sigs_sc1[n<<1];  
Matthieu Kanj's avatar
Matthieu Kanj committed
271 272 273
      
          }

274 275 276 277 278
            for (n=0; n<sequence_length[index_Nsc_RU]; n++) 
    {
                  ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][12*(n<<1)+24]    = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, real part
                  ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+12*(n<<1)+24]= ref_sigs_sc1[1+(n<<1)]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, imaginary part    
              }
Matthieu Kanj's avatar
Matthieu Kanj committed
279
            for (n=0; n<4; n++) 
280 281 282 283 284
    {
              for (m=0; m<3; m++) 
      {
                    ul_ref_sigs_f2_rx_NB_IoT[u][12*((3*n+m)<<1)+24] = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, real part
                    ul_ref_sigs_f2_rx_NB_IoT[u][1+12*((3*n+m)<<1)+24] = ref_sigs_sc1[1+(n<<1)]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, imaginary part    
Matthieu Kanj's avatar
Matthieu Kanj committed
285
                }  
286
              }
Matthieu Kanj's avatar
Matthieu Kanj committed
287

Matthieu Kanj's avatar
Matthieu Kanj committed
288 289 290 291
          break;
      }
    }
  }
292 293
}

294
void free_ul_ref_sigs_NB_IoT(void)
295 296
{

297
  unsigned int u,index_Nsc_RU;
298

299
  for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++) {
300
    for (u=0; u<30; u++) {
301 302
        if (ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU])
          free16(ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU],4*sizeof(int16_t)*sequence_length[index_Nsc_RU]);
303 304 305 306
    }
  }
}

307 308 309 310 311 312 313
// void free_ul_ref_sigs(void)
// {

//   unsigned int u,index_Nsc_RU;

//   for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++) {
//     for (u=0; u<30; u++) {
314 315
//         if (ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU])
//           free16(ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU],4*sizeof(int16_t)*sequence_length[index_Nsc_RU]);
316 317 318 319
//     }
//   }
// }

320 321 322 323 324 325 326 327 328
#ifdef MAIN
main()
{

  //generate_ul_ref_sigs();
  generate_ul_ref_sigs_rx();
  free_ul_ref_sigs();
}
#endif