nr_parms.c 10.6 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, 16, 32};
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 91
  mu = cfg->subframe_config.numerology_index_mu.value;

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;

96 97
  // checking if the ssb is transmitted in given frame according to periodicity
  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) 
104 105 106 107 108
        n_hf=0;
      else
        n_hf=1;
    }

109 110
    // to set a effective slot number between 0 to hf_slots-1 in the half frame where the SSB is supposed to be
    rel_slot = (n_hf)? (slot-hf_slots) : slot;
111 112 113 114

    // there are two potential SSB per slot
    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:
Raymond Knopp's avatar
Raymond Knopp committed
244 245
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
246
      fp->ssb_type = nr_ssb_type_D;
hongzhi wang's avatar
hongzhi wang committed
247 248 249
      break;

    case NR_MU_4:
Raymond Knopp's avatar
Raymond Knopp committed
250 251
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
252
      fp->ssb_type = nr_ssb_type_E;
hongzhi wang's avatar
hongzhi wang committed
253 254 255 256 257 258
      break;

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

Raymond Knopp's avatar
Raymond Knopp committed
259
  fp->slots_per_frame = 10* fp->slots_per_subframe;
260 261

  fp->nb_antenna_ports_eNB = 1; // default value until overwritten by RRCConnectionReconfiguration
262 263
  fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
  fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration
264

Raymond Knopp's avatar
Raymond Knopp committed
265 266 267
  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;
268 269
  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
270 271 272 273
  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
274

275 276 277 278 279 280 281 282 283 284
  // definition of Lmax according to ts 38.213 section 4.1
  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
    fp->Lmax = 64;

Guy De Souza's avatar
Guy De Souza committed
285

hongzhi wang's avatar
hongzhi wang committed
286 287 288
  return 0;
}

Raymond Knopp's avatar
Raymond Knopp committed
289
int nr_init_frame_parms(nfapi_nr_config_request_t* config,
yilmazt's avatar
yilmazt committed
290 291
                        NR_DL_FRAME_PARMS *fp)
{
292

293
  fp->eutra_band = config->nfapi_config.rf_bands.rf_band[0];
294
  fp->frame_type = config->subframe_config.duplex_mode.value;
295
  fp->L_ssb = config->sch_config.ssb_scg_position_in_burst.value;
296
  return nr_init_frame_parms0(fp,
297 298 299
			      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
300
}
hongzhi wang's avatar
hongzhi wang committed
301

Raymond Knopp's avatar
Raymond Knopp committed
302
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
Raymond Knopp's avatar
Raymond Knopp committed
303
			   int mu, 
Raymond Knopp's avatar
Raymond Knopp committed
304
			   int Ncp,
305
			   int N_RB_DL,
Raymond Knopp's avatar
Raymond Knopp committed
306 307
			   int n_ssb_crb,
			   int ssb_subcarrier_offset) 
Raymond Knopp's avatar
Raymond Knopp committed
308
{
309
  /*n_ssb_crb and ssb_subcarrier_offset are given in 15kHz SCS*/
310
  nr_init_frame_parms0(fp,mu,Ncp,N_RB_DL);
311
  fp->ssb_start_subcarrier = (12 * n_ssb_crb + ssb_subcarrier_offset)/(1<<mu);
312 313 314
  return 0;
}

Raymond Knopp's avatar
Raymond Knopp committed
315
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
316
{
Raymond Knopp's avatar
Raymond Knopp committed
317 318 319 320 321 322 323 324 325
  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);
326 327
  LOG_I(PHY,"fp->dl_CarrierFreq=%u\n",fp->dl_CarrierFreq);
  LOG_I(PHY,"fp->ul_CarrierFreq=%u\n",fp->ul_CarrierFreq);
328
}
329 330 331