/* * 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 */ #include "phy_init.h" #include "log.h" /// Subcarrier spacings in Hz indexed by numerology index uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 16, 32}; int nr_init_frame_parms(nfapi_nr_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms) { int N_RB = config->rf_config.dl_channel_bandwidth.value; int Ncp = config->subframe_config.dl_cyclic_prefix_type.value; int mu = config->subframe_config.numerology_index_mu.value; #if DISABLE_LOG_X printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp); #else LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp); #endif if (Ncp == EXTENDED) AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu); switch(mu) { case NR_MU_0: //15kHz scs frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_0]; break; case NR_MU_1: //30kHz scs frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_1]; switch(N_RB){ case 11: case 24: case 38: case 78: case 51: case 65: case 106: //40 MHz if (frame_parms->threequarter_fs) { frame_parms->ofdm_symbol_size = 1536; frame_parms->first_carrier_offset = 900; //1536 - 636 frame_parms->nb_prefix_samples0 = 132; frame_parms->nb_prefix_samples = 108; } else { frame_parms->ofdm_symbol_size = 2048; frame_parms->first_carrier_offset = 1412; //2048 - 636 frame_parms->nb_prefix_samples0 = 176; frame_parms->nb_prefix_samples = 144; } break; case 133: case 162: case 189: case 217: //80 MHz if (frame_parms->threequarter_fs) { frame_parms->ofdm_symbol_size = 3072; frame_parms->first_carrier_offset = 1770; //3072 - 1302 frame_parms->nb_prefix_samples0 = 264; frame_parms->nb_prefix_samples = 216; } else { frame_parms->ofdm_symbol_size = 4096; frame_parms->first_carrier_offset = 2794; //4096 - 1302 frame_parms->nb_prefix_samples0 = 352; frame_parms->nb_prefix_samples = 288; } break; case 245: case 273: default: AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms); } break; case NR_MU_2: //60kHz scs frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; switch(N_RB){ //FR1 bands only 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: AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms); } break; case NR_MU_3: frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_3]; break; case NR_MU_4: frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_4]; break; default: AssertFatal(1==0,"Invalid numerology index %d", mu); } frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe; frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; frame_parms->samples_per_subframe = (frame_parms->samples_per_subframe_wCP + (frame_parms->nb_prefix_samples0 * frame_parms->slots_per_subframe) + (frame_parms->nb_prefix_samples * frame_parms->slots_per_subframe * (frame_parms->symbols_per_slot - 1))); frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe; frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; return 0; } int nr_init_frame_parms_ue(nfapi_nr_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms) { int N_RB = 106; int Ncp = 0; int mu = 1; #if DISABLE_LOG_X printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp); #else LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp); #endif if (Ncp == EXTENDED) AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu); switch(mu) { case NR_MU_0: //15kHz scs frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_0]; break; case NR_MU_1: //30kHz scs frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_1]; switch(N_RB){ case 11: case 24: case 38: case 78: case 51: case 65: case 106: //40 MHz if (frame_parms->threequarter_fs) { frame_parms->ofdm_symbol_size = 1536; frame_parms->first_carrier_offset = 900; //1536 - 636 frame_parms->nb_prefix_samples0 = 132; frame_parms->nb_prefix_samples = 108; } else { frame_parms->ofdm_symbol_size = 2048; frame_parms->first_carrier_offset = 1412; //2048 - 636 frame_parms->nb_prefix_samples0 = 176; frame_parms->nb_prefix_samples = 144; } break; case 133: case 162: case 189: case 217: //80 MHz if (frame_parms->threequarter_fs) { frame_parms->ofdm_symbol_size = 3072; frame_parms->first_carrier_offset = 1770; //3072 - 1302 frame_parms->nb_prefix_samples0 = 264; frame_parms->nb_prefix_samples = 216; } else { frame_parms->ofdm_symbol_size = 4096; frame_parms->first_carrier_offset = 2794; //4096 - 1302 frame_parms->nb_prefix_samples0 = 352; frame_parms->nb_prefix_samples = 288; } break; case 245: case 273: default: AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms); } break; case NR_MU_2: //60kHz scs frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; switch(N_RB){ //FR1 bands only 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: AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms); } break; case NR_MU_3: frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_3]; break; case NR_MU_4: frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4]; frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_4]; break; default: AssertFatal(1==0,"Invalid numerology index %d", mu); } frame_parms->nb_prefix_samples0 = 160; frame_parms->nb_prefix_samples = 144; frame_parms->symbols_per_tti = 14; frame_parms->numerology_index = 0; frame_parms->ttis_per_subframe = 1; frame_parms->slots_per_tti = 2; //only slot config 1 is supported frame_parms->ofdm_symbol_size = 2048; frame_parms->samples_per_tti = 30720; frame_parms->samples_per_subframe = 30720 * frame_parms->ttis_per_subframe; frame_parms->first_carrier_offset = 2048-600; frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe; frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; //frame_parms->samples_per_subframe = (frame_parms->samples_per_subframe_wCP + (frame_parms->nb_prefix_samples0 * frame_parms->slots_per_subframe) + // (frame_parms->nb_prefix_samples * frame_parms->slots_per_subframe * (frame_parms->symbols_per_slot - 1))); frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe; frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; return 0; } void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms) { LOG_I(PHY,"frame_parms->scs=%d\n",frame_parms->subcarrier_spacing); LOG_I(PHY,"frame_parms->ofdm_symbol_size=%d\n",frame_parms->ofdm_symbol_size); LOG_I(PHY,"frame_parms->nb_prefix_samples0=%d\n",frame_parms->nb_prefix_samples0); LOG_I(PHY,"frame_parms->nb_prefix_samples=%d\n",frame_parms->nb_prefix_samples); LOG_I(PHY,"frame_parms->slots_per_subframe=%d\n",frame_parms->slots_per_subframe); LOG_I(PHY,"frame_parms->samples_per_subframe_wCP=%d\n",frame_parms->samples_per_subframe_wCP); LOG_I(PHY,"frame_parms->samples_per_frame_wCP=%d\n",frame_parms->samples_per_frame_wCP); LOG_I(PHY,"frame_parms->samples_per_subframe=%d\n",frame_parms->samples_per_subframe); LOG_I(PHY,"frame_parms->samples_per_frame=%d\n",frame_parms->samples_per_frame); }