diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 2ef5ab00df..024f7eb3df 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1628,6 +1628,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 60aa5af33c..e49cb1a613 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -246,37 +246,25 @@ static void UE_synch(void *arg) { case pbch: LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + uint64_t dl_carrier, ul_carrier; + double rx_gain_off = 0; + nr_get_carrier_frequencies(&UE->frame_parms, &dl_carrier, &ul_carrier); + if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) { freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) + round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0); // rerun with new cell parameters and frequency-offset - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + // todo: the freq_offset computed on DL shall be scaled before being applied to UL + nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset); - if (freq_offset >= 0) - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset); - else - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset); - - if (uplink_frequency_offset[0][0]) - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] + uplink_frequency_offset[0][0]; - else - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+(UE->frame_parms.ul_CarrierFreq-UE->frame_parms.dl_CarrierFreq); - - //UE->frame_parms.dl_CarrierFreq = openair0_cfg[CC_id].rx_freq[i]; - } - - LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %f Hz, UL %f Hz), UE_scan_carrier %d\n", + LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n", hw_slot_offset, freq_offset, - UE->rx_total_gain_dB, + openair0_cfg[UE->rf_map.card].rx_gain[0], openair0_cfg[UE->rf_map.card].rx_freq[0], - openair0_cfg[UE->rf_map.card].tx_freq[0], - UE->UE_scan_carrier); + openair0_cfg[UE->rf_map.card].tx_freq[0]); // reconfigure for potentially different bandwidth switch(UE->frame_parms.N_RB_DL) { @@ -332,45 +320,21 @@ static void UE_synch(void *arg) { UE->is_synchronized = 1; } } else { - // initial sync failed - // calculate new offset and try again - if (UE->UE_scan_carrier == 1) { - uint64_t dl_carrier, ul_carrier; + if (UE->UE_scan_carrier == 1) { if (freq_offset >= 0) freq_offset += 100; freq_offset *= -1; - if (downlink_frequency[0][0]) - dl_carrier = downlink_frequency[0][0]; - else - dl_carrier = UE->frame_parms.dl_CarrierFreq; + nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset); - if (uplink_frequency_offset[0][0]) - ul_carrier = dl_carrier + uplink_frequency_offset[0][0]; - else - ul_carrier = dl_carrier + UE->frame_parms.ul_CarrierFreq - UE->frame_parms.dl_CarrierFreq; - - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = dl_carrier + freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = ul_carrier + freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - - LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %f, UL %f)\n", - freq_offset, - UE->rx_total_gain_dB, - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i], - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i]); - - if (UE->UE_scan_carrier==1) - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } + LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset); if (UE->mode != loop_through_memory) UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 + } break; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 45475d194f..f3c5a4bea6 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -40,7 +40,7 @@ //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all #include "openair1/PHY/MODULATION/nr_modulation.h" #include "PHY/phy_vars_nr_ue.h" -#include "PHY/LTE_TRANSPORT/transport_vars.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "SCHED/sched_common_vars.h" #include "PHY/MODULATION/modulation_vars.h" //#include "../../SIMU/USER/init_lte.h" @@ -304,6 +304,7 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ UE->no_timing_correction = UE_no_timing_correction; UE->mode = mode; UE->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE->tx_total_gain_dB = (int)tx_gain[CC_id][0]; UE->tx_power_max_dBm = tx_max_power[CC_id]; LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", mode, UE_fo_compensation, UE_scan, UE_scan_carrier, UE_no_timing_correction); @@ -328,10 +329,11 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ void init_openair0(void) { int card; - int i; + int freq_off = 0; NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms; for (card=0; cardthreequarter_fs; numerology = frame_parms->numerology_index; @@ -424,11 +426,6 @@ void init_openair0(void) { else openair0_cfg[card].duplex_mode = duplex_mode_FDD; - LOG_I(PHY, "HW: Configuring card %d, nb_antennas_tx/rx %hhu/%hhu\n", - card, - frame_parms->nb_antennas_tx, - frame_parms->nb_antennas_rx); - openair0_cfg[card].Mod_id = 0; openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL; openair0_cfg[card].clock_source = get_softmodem_params()->clock_source; @@ -436,36 +433,17 @@ void init_openair0(void) { openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx); openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx); - for (i=0; i<4; i++) { + LOG_I(PHY, "HW: Configuring card %d, tx/rx num_channels %d/%d, duplex_mode %s\n", + card, + openair0_cfg[card].tx_num_channels, + openair0_cfg[card].rx_num_channels, + duplex_mode[openair0_cfg[card].duplex_mode]); - if (idl_CarrierFreq; - } - else - openair0_cfg[card].rx_freq[i]=0.0; + nr_get_carrier_frequencies(frame_parms, &dl_carrier, &ul_carrier); - if (iul_CarrierFreq; - } - else - openair0_cfg[card].tx_freq[i]=0.0; + nr_rf_card_config(&openair0_cfg[card], rx_gain_off, ul_carrier, dl_carrier, freq_off); - openair0_cfg[card].autocal[i] = 1; - openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; - openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; - openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; - printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", - card,i, openair0_cfg[card].tx_gain[i], - openair0_cfg[card].rx_gain[i], - openair0_cfg[card].tx_freq[i], - openair0_cfg[card].rx_freq[i]); - } + openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 845eace8b6..746c7edfa9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1452,6 +1452,31 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, runmode_t mode, int n_frames); +/*! + \brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter + @param fp Pointer to frame params + @param dl_Carrier Pointer to DL carrier to be set + @param ul_Carrier Pointer to UL carrier to be set +*/ +void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, + uint64_t *dl_Carrier, + uint64_t *ul_Carrier); + +/*! + \brief This function sets the OAI RF card rx/tx params + @param openair0_cfg Pointer OAI config for a specific card + @param tx_gain_off Tx gain offset + @param rx_gain_off Rx gain offset + @param ul_Carrier UL carrier to be set + @param dl_Carrier DL carrier to be set + @param freq_offset Freq offset to be set +*/ +void nr_rf_card_config(openair0_config_t *openair0_cfg, + double rx_gain_off, + uint64_t ul_Carrier, + uint64_t dl_Carrier, + int freq_offset); + /*! \brief Encoding of PUSCH/ACK/RI/ACK from 36-212. diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c new file mode 100644 index 0000000000..7cf64b28bb --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c @@ -0,0 +1,90 @@ +/* + * 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 + */ + +/*! \file PHY/NR_UE_TRANSPORT/nr_ue_rf_config.c +* \brief Functional helpers to configure the RF boards at UE side +* \author Guido Casati +* \date 2020 +* \version 0.1 +* \company Fraunhofer IIS +* \email: guido.casati@iis.fraunhofer.de +*/ + +#include "PHY/defs_nr_UE.h" +#include "PHY/phy_extern_nr_ue.h" +#include "nr_transport_proto_ue.h" + +void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, uint64_t *dl_carrier, uint64_t *ul_carrier){ + + if (downlink_frequency[0][0]) + *dl_carrier = downlink_frequency[0][0]; + else + *dl_carrier = fp->dl_CarrierFreq; + + if (uplink_frequency_offset[0][0]) + *ul_carrier = *dl_carrier + uplink_frequency_offset[0][0]; + else + *ul_carrier = *dl_carrier + fp->ul_CarrierFreq - fp->dl_CarrierFreq; + +} + +void nr_rf_card_config(openair0_config_t *openair0_cfg, + double rx_gain_offset, + uint64_t ul_carrier, + uint64_t dl_carrier, + int freq_offset){ + + uint8_t mod_id = 0; + uint8_t cc_id = 0; + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[mod_id][cc_id]; + int rf_chain = ue->rf_map.chain; + double rx_gain = ue->rx_total_gain_dB; + double tx_gain = ue->tx_total_gain_dB; + + for (int i = rf_chain; i < rf_chain + 4; i++) { + + if (i < openair0_cfg->rx_num_channels) + openair0_cfg->rx_freq[i + rf_chain] = dl_carrier + freq_offset; + else + openair0_cfg->rx_freq[i] = 0.0; + + if (itx_num_channels) + openair0_cfg->tx_freq[i] = ul_carrier + freq_offset; + else + openair0_cfg->tx_freq[i] = 0.0; + + if (tx_gain) + openair0_cfg->tx_gain[i] = tx_gain; + if (rx_gain) + openair0_cfg->rx_gain[i] = rx_gain - rx_gain_offset; + + openair0_cfg->autocal[i] = 1; + + LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n", + i, + rf_chain, + openair0_cfg->tx_gain[i], + openair0_cfg->rx_gain[i], + openair0_cfg->tx_freq[i], + openair0_cfg->rx_freq[i]); + + } +} \ No newline at end of file