nr_parms.c 10.9 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.1  (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
#include "phy_init.h"
23
#include "common/utils/LOG/log.h"
24

25 26
/// Subcarrier spacings in Hz indexed by numerology index
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
27
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
28

Raymond Knopp's avatar
Raymond Knopp committed
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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index)
{

  int mu = fp->numerology_index;
  int symbol = 0;
  uint8_t n, n_temp;
  nr_ssb_type_e type = fp->ssb_type;
  int case_AC[2] = {2,8};
  int case_BD[4] = {4,8,16,20};
  int case_E[8] = {8, 12, 16, 20, 32, 36, 40, 44};

  switch(mu) {

	case NR_MU_0: // case A
	    n = i_ssb >> 1;
	    symbol = case_AC[i_ssb % 2] + 14*n;
	break;

	case NR_MU_1: 
	    if (type == 1){ // case B
		n = i_ssb >> 2;
	    	symbol = case_BD[i_ssb % 4] + 28*n;
	    }
	    if (type == 2){ // case C
		n = i_ssb >> 1;
		symbol = case_AC[i_ssb % 2] + 14*n;
	    }
	 break;

	 case NR_MU_3: // case D
	    n_temp = i_ssb >> 2; 
	    n = n_temp + (n_temp >> 2);
	    symbol = case_BD[i_ssb % 4] + 28*n;
	 break;

	 case NR_MU_4:  // case E
	    n_temp = i_ssb >> 3; 
	    n = n_temp + (n_temp >> 2);
	    symbol = case_E[i_ssb % 8] + 56*n;
	 break;


	 default:
	      AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
  }

  if (half_frame_index)
    symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);

  return symbol;
}

82
int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot, int frame)
83 84 85
{

  uint8_t n_hf;
86
  uint16_t p,mu,hf_slots;
87
  uint64_t ssb_map;
88 89
  int rel_slot;

90
  mu = cfg->subframe_config.numerology_index_mu.value;
91

92 93
  ssb_map = cfg->sch_config.ssb_scg_position_in_burst.value;
  p = cfg->sch_config.ssb_periodicity.value;
94 95
  n_hf = cfg->sch_config.half_frame_index.value;

laurent's avatar
laurent committed
96
  // if SSB periodicity is 5ms, they are transmitted in both half frames
97
  if ( (p>10) && (frame%(p/10)) )  
98
    return 0;
99
  else {
100
    hf_slots = (10<<mu)>>1; // number of slots per half frame
101 102
    // if SSB periodicity is 5ms, they are transmitted in both half frames
    if ( p == 5) {
103
      if (slot<hf_slots) 
laurent's avatar
laurent committed
104 105 106 107
      n_hf=0;
    else
      n_hf=1;
  }
108

laurent's avatar
laurent committed
109
  // to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be
110
    rel_slot = (n_hf)? (slot-hf_slots) : slot;
111

laurent's avatar
laurent committed
112

113 114
    return ( ((ssb_map >> rel_slot*2) & 0x01) || ((ssb_map >> (1+rel_slot*2)) & 0x01) ); 
  }
115 116
}

117

118
int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
Raymond Knopp's avatar
Raymond Knopp committed
119
			 int mu,
120 121
			 int Ncp,
			 int N_RB_DL)
Raymond Knopp's avatar
Raymond Knopp committed
122

123 124
{

hongzhi wang's avatar
hongzhi wang committed
125
#if DISABLE_LOG_X
126
  printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp);
hongzhi wang's avatar
hongzhi wang committed
127
#else
128
  LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp);
hongzhi wang's avatar
hongzhi wang committed
129 130
#endif

Guy De Souza's avatar
Guy De Souza committed
131
  if (Ncp == NFAPI_CP_EXTENDED)
hongzhi wang's avatar
hongzhi wang committed
132 133
    AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu);

134 135 136
  fp->numerology_index = mu;
  fp->Ncp = Ncp;
  fp->N_RB_DL = N_RB_DL;
137

hongzhi wang's avatar
hongzhi wang committed
138 139 140
  switch(mu) {

    case NR_MU_0: //15kHz scs
Raymond Knopp's avatar
Raymond Knopp committed
141 142
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
143
      fp->ssb_type = nr_ssb_type_A;
hongzhi wang's avatar
hongzhi wang committed
144 145 146
      break;

    case NR_MU_1: //30kHz scs
Raymond Knopp's avatar
Raymond Knopp committed
147 148
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
hongzhi wang's avatar
hongzhi wang committed
149

150 151 152 153 154 155 156 157 158 159
      // selection of SS block pattern according to TS 38101-1 Table 5.4.3.3-1 for SCS 30kHz
      if (fp->eutra_band == 5 || fp->eutra_band == 66) 
	      fp->ssb_type = nr_ssb_type_B;
      else{  
      	if (fp->eutra_band == 41 || ( fp->eutra_band > 76 && fp->eutra_band < 80) )
		fp->ssb_type = nr_ssb_type_C;
	else
		AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->eutra_band, mu);
      }

160
      switch(N_RB_DL){
hongzhi wang's avatar
hongzhi wang committed
161 162 163 164 165 166 167 168
        case 11:
        case 24:
        case 38:
        case 78:
        case 51:
        case 65:

        case 106: //40 MHz
Raymond Knopp's avatar
Raymond Knopp committed
169 170
          if (fp->threequarter_fs) {
            fp->ofdm_symbol_size = 1536;
171
            fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
172 173
            fp->nb_prefix_samples0 = 132;
            fp->nb_prefix_samples = 108;
hongzhi wang's avatar
hongzhi wang committed
174 175
          }
          else {
Raymond Knopp's avatar
Raymond Knopp committed
176
            fp->ofdm_symbol_size = 2048;
177
            fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
178 179
            fp->nb_prefix_samples0 = 176;
            fp->nb_prefix_samples = 144;
hongzhi wang's avatar
hongzhi wang committed
180 181 182 183 184 185 186 187
          }
          break;

        case 133:
        case 162:
        case 189:

        case 217: //80 MHz
Raymond Knopp's avatar
Raymond Knopp committed
188 189
          if (fp->threequarter_fs) {
            fp->ofdm_symbol_size = 3072;
190
            fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
191 192
            fp->nb_prefix_samples0 = 264;
            fp->nb_prefix_samples = 216;
hongzhi wang's avatar
hongzhi wang committed
193
          }
Raymond Knopp's avatar
Raymond Knopp committed
194
	  else {
Raymond Knopp's avatar
Raymond Knopp committed
195
	    fp->ofdm_symbol_size = 4096;
196
	    fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
197 198
	    fp->nb_prefix_samples0 = 352;
	    fp->nb_prefix_samples = 288;
Raymond Knopp's avatar
Raymond Knopp committed
199
	  }
hongzhi wang's avatar
hongzhi wang committed
200 201 202
          break;

        case 245:
203
	  AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",N_RB_DL,mu); 
Raymond Knopp's avatar
Raymond Knopp committed
204
	  fp->ofdm_symbol_size = 4096;
205
	  fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
206 207
	  fp->nb_prefix_samples0 = 352;
	  fp->nb_prefix_samples = 288;
Raymond Knopp's avatar
Raymond Knopp committed
208
	  break;
hongzhi wang's avatar
hongzhi wang committed
209
        case 273:
210
	  AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",N_RB_DL,mu); 
Raymond Knopp's avatar
Raymond Knopp committed
211
	  fp->ofdm_symbol_size = 4096;
212
	  fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
213 214
	  fp->nb_prefix_samples0 = 352;
	  fp->nb_prefix_samples = 288;
Raymond Knopp's avatar
Raymond Knopp committed
215
	  break;
hongzhi wang's avatar
hongzhi wang committed
216
      default:
217
        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB_DL, mu, fp);
hongzhi wang's avatar
hongzhi wang committed
218 219 220 221
      }
      break;

    case NR_MU_2: //60kHz scs
Raymond Knopp's avatar
Raymond Knopp committed
222 223
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
hongzhi wang's avatar
hongzhi wang committed
224

225
      switch(N_RB_DL){ //FR1 bands only
hongzhi wang's avatar
hongzhi wang committed
226 227 228 229 230 231 232 233 234 235 236 237 238
        case 11:
        case 18:
        case 38:
        case 24:
        case 31:
        case 51:
        case 65:
        case 79:
        case 93:
        case 107:
        case 121:
        case 135:
      default:
239
        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB_DL, mu, fp);
hongzhi wang's avatar
hongzhi wang committed
240 241 242 243
      }
      break;

    case NR_MU_3:
244 245 246 247 248 249 250 251 252 253
      switch(N_RB_DL){
        case 66:
          fp->ofdm_symbol_size = 1024;
          fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 )
          fp->nb_prefix_samples0 = 88;
          fp->nb_prefix_samples = 72;
          fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
          fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
          fp->ssb_type = nr_ssb_type_D;
      }
hongzhi wang's avatar
hongzhi wang committed
254 255 256
      break;

    case NR_MU_4:
Raymond Knopp's avatar
Raymond Knopp committed
257 258
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
259
      fp->ssb_type = nr_ssb_type_E;
hongzhi wang's avatar
hongzhi wang committed
260 261 262 263 264 265
      break;

  default:
    AssertFatal(1==0,"Invalid numerology index %d", mu);
  }

Raymond Knopp's avatar
Raymond Knopp committed
266
  fp->slots_per_frame = 10* fp->slots_per_subframe;
267 268

  fp->nb_antenna_ports_eNB = 1; // default value until overwritten by RRCConnectionReconfiguration
269 270
  fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
  fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration
271

Raymond Knopp's avatar
Raymond Knopp committed
272 273 274
  fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
  fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
  fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
275 276
  fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; 
  fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); 
Raymond Knopp's avatar
Raymond Knopp committed
277 278 279 280
  fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) +
                                      (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1)));
  fp->samples_per_frame = 10 * fp->samples_per_subframe;
  fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
hongzhi wang's avatar
hongzhi wang committed
281

282
  // definition of Lmax according to ts 38.213 section 4.1
283 284 285 286 287 288
  if (fp->dl_CarrierFreq < 6e9) {
    if(fp->frame_type && (fp->ssb_type==2))
      fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
    else
      fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
  } else {
289
    fp->Lmax = 64;
290
  }
291

292 293 294
  fp->N_ssb = 0;
  for (int p=0; p<fp->Lmax; p++)
    fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
Guy De Souza's avatar
Guy De Souza committed
295

hongzhi wang's avatar
hongzhi wang committed
296 297 298
  return 0;
}

Raymond Knopp's avatar
Raymond Knopp committed
299
int nr_init_frame_parms(nfapi_nr_config_request_t* config,
yilmazt's avatar
yilmazt committed
300 301
                        NR_DL_FRAME_PARMS *fp)
{
302

303
  fp->eutra_band = config->nfapi_config.rf_bands.rf_band[0];
304
  fp->frame_type = config->subframe_config.duplex_mode.value;
305
  fp->L_ssb = config->sch_config.ssb_scg_position_in_burst.value;
306
  return nr_init_frame_parms0(fp,
307 308 309
			      config->subframe_config.numerology_index_mu.value,
			      config->subframe_config.dl_cyclic_prefix_type.value,
			      config->rf_config.dl_carrier_bandwidth.value);
Raymond Knopp's avatar
Raymond Knopp committed
310
}
hongzhi wang's avatar
hongzhi wang committed
311

Raymond Knopp's avatar
Raymond Knopp committed
312
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
Raymond Knopp's avatar
Raymond Knopp committed
313
			   int mu, 
Raymond Knopp's avatar
Raymond Knopp committed
314
			   int Ncp,
315
			   int N_RB_DL,
Raymond Knopp's avatar
Raymond Knopp committed
316 317
			   int n_ssb_crb,
			   int ssb_subcarrier_offset) 
Raymond Knopp's avatar
Raymond Knopp committed
318
{
319
  /*n_ssb_crb and ssb_subcarrier_offset are given in 15kHz SCS*/
320
  nr_init_frame_parms0(fp,mu,Ncp,N_RB_DL);
321
  fp->ssb_start_subcarrier = (12 * n_ssb_crb + ssb_subcarrier_offset)/(1<<mu);
322 323 324
  return 0;
}

Raymond Knopp's avatar
Raymond Knopp committed
325
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
326
{
Raymond Knopp's avatar
Raymond Knopp committed
327 328 329 330 331 332 333 334 335
  LOG_I(PHY,"fp->scs=%d\n",fp->subcarrier_spacing);
  LOG_I(PHY,"fp->ofdm_symbol_size=%d\n",fp->ofdm_symbol_size);
  LOG_I(PHY,"fp->nb_prefix_samples0=%d\n",fp->nb_prefix_samples0);
  LOG_I(PHY,"fp->nb_prefix_samples=%d\n",fp->nb_prefix_samples);
  LOG_I(PHY,"fp->slots_per_subframe=%d\n",fp->slots_per_subframe);
  LOG_I(PHY,"fp->samples_per_subframe_wCP=%d\n",fp->samples_per_subframe_wCP);
  LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP);
  LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe);
  LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
336
  LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq);
337
  LOG_I(PHY,"fp->ul_CarrierFreq=%u\n",fp->ul_CarrierFreq);
338
}
339 340 341