lte_init_ru.c 10.3 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 23 24 25
#include "phy_init.h"
#include "SCHED/sched_eNB.h"
#include "PHY/phy_extern.h"
#include "SIMULATION/TOOLS/sim.h"
26 27 28 29
#include "LTE_RadioResourceConfigCommonSIB.h"
#include "LTE_RadioResourceConfigDedicated.h"
#include "LTE_TDD-Config.h"
#include "LTE_MBSFN-SubframeConfigList.h"
30
#include "common/utils/LOG/vcd_signal_dumper.h"
31 32 33
#include "assertions.h"
#include <math.h>

34
void init_7_5KHz(void);
35

36 37 38
int phy_init_RU(RU_t *ru) {

  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
39
  RU_CALIBRATION *calibration = &ru->calibration;
40 41 42
  int i,j;
  int p;
  int re;
Raymond Knopp's avatar
Raymond Knopp committed
43 44
  
  init_dfts();  
45 46 47

  LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx);

48 49 50 51
  if (ru->is_slave == 1) {
 	 generate_ul_ref_sigs_rx();
  }

52 53 54 55 56 57 58 59 60 61
  if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals 
    // Time-domain signals
    ru->common.txdata        = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*));
    ru->common.rxdata        = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );

    for (i=0; i<ru->nb_tx; i++) {
      // Allocate 10 subframes of I/Q TX signal data (time) if not
      ru->common.txdata[i]  = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
      LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i],
	     fp->samples_per_tti*10*sizeof(int32_t));
62
    }
63

64 65 66 67 68
    if (ru->is_slave == 1) {
        calibration->drs_ch_estimates_time = (int32_t**)malloc16_clear(ru->nb_rx*sizeof(int32_t*));
        for (i=0; i<ru->nb_rx; i++) {    
        	calibration->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear(2*sizeof(int32_t)*fp->ofdm_symbol_size);
        }
69
    }
70 71


72 73 74 75 76
    for (i=0;i<ru->nb_rx;i++) {
      ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
    }
  } // IF5 or local RF
  else {
77
    //    LOG_I(PHY,"No rxdata/txdata for RU\n");
78 79 80 81 82
    ru->common.txdata        = (int32_t**)NULL;
    ru->common.rxdata        = (int32_t**)NULL;

  }
  if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
83
    init_dfts();
84
    init_7_5KHz();
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
    LOG_I(PHY,"nb_tx %d\n",ru->nb_tx);
    ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
    for (i=0;i<ru->nb_rx;i++) {
      ru->common.rxdata_7_5kHz[i] = (int32_t*)malloc16_clear( 2*fp->samples_per_tti*2*sizeof(int32_t) );
      LOG_I(PHY,"rxdata_7_5kHz[%d] %p for RU %d\n",i,ru->common.rxdata_7_5kHz[i],ru->idx);
    }
  

    // allocate IFFT input buffers (TX)
    ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
    LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF,
	  ru->nb_tx*sizeof(int32_t*));
    for (i=0; i<ru->nb_tx; i++) {
      ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->symbols_per_tti*fp->ofdm_symbol_size*sizeof(int32_t) );
      LOG_I(PHY,"txdataF_BF[%d] %p for RU %d\n",i,ru->common.txdataF_BF[i],ru->idx);
    }
    // allocate FFT output buffers (RX)
    ru->common.rxdataF     = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
    for (i=0; i<ru->nb_rx; i++) {    
      // allocate 2 subframes of I/Q signal data (frequency)
      ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) ); 
      LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx);
    }
108 109 110 111 112 113 114 115 116 117 118 119
    
     if (ru->is_slave == 1) {
     	// allocate FFT output buffers after extraction (RX)
    	calibration->rxdataF_ext = (int32_t**)malloc16(2*sizeof(int32_t*));
	calibration->drs_ch_estimates = (int32_t**)malloc16(2*sizeof(int32_t*));
    	for (i=0; i<ru->nb_rx; i++) {    
      		// allocate 2 subframes of I/Q signal data (frequency)
      		calibration->rxdataF_ext[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); 
      		LOG_I(PHY,"rxdataF_ext[%d] %p for RU %d\n",i,calibration->rxdataF_ext[i],ru->idx);
                calibration->drs_ch_estimates[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti);
    	}
     }
120 121

    /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
122 123
    //AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
		//"nb_antennas_rx too large");
124 125 126 127 128 129
    ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
    for (j=0;j<4;j++) ru->prach_rxsigF_br[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));

    for (i=0; i<ru->nb_rx; i++) {
      ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
      LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
130
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
131 132 133 134 135 136 137 138 139 140
      for (j=0;j<4;j++) {
	ru->prach_rxsigF_br[j][i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
	LOG_D(PHY,"[INIT] prach_vars_br->rxsigF[%d] = %p\n",i,ru->prach_rxsigF_br[j][i]);
      }
#endif
    }
    
    AssertFatal(RC.nb_L1_inst <= NUMBER_OF_eNB_MAX,"eNB instances %d > %d\n",
		RC.nb_L1_inst,NUMBER_OF_eNB_MAX);

141
    LOG_D(PHY,"[INIT] %s() RC.nb_L1_inst:%d \n", __FUNCTION__, RC.nb_L1_inst);
142

143 144 145
    int starting_antenna_index=0;
    for (i=0; i<ru->idx;i++) starting_antenna_index+=ru->nb_tx;

146 147 148 149 150 151 152 153
    for (i=0; i<RC.nb_L1_inst; i++) {
      for (p=0;p<15;p++) {
        LOG_D(PHY,"[INIT] %s() nb_antenna_ports_eNB:%d \n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB);
	if (p<ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p==5) {
          LOG_D(PHY,"[INIT] %s() DO BEAM WEIGHTS nb_antenna_ports_eNB:%d nb_tx:%d\n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB, ru->nb_tx);
	  ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
	  for (j=0; j<ru->nb_tx; j++) {
	    ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
154 155
	    // antenna ports 0-3 are mapped on antennas 0-3 as follows
	    //    - antenna port p is mapped to antenna j on ru->idx as: p = (starting_antenna_index+j)%nb_anntena_ports_eNB 
156
	    // antenna port 4 is mapped on antenna 0
157 158 159 160 161
	    // antenna ports 5-14 are mapped on all antennas
	    
	    if (((p<4) && 
		 (p==((starting_antenna_index+j)%ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB))) || 
		((p==4) && (j==0))) {
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
	      for (re=0; re<fp->ofdm_symbol_size; re++) 
              {
		ru->beam_weights[i][p][j][re] = 0x00007fff; 

                //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
              }
	    }
	    else if (p>4) {
	      for (re=0; re<fp->ofdm_symbol_size; re++) 
              {
		ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; 
                //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
              }
	    }  
	    //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); 
	  } // for (j=0
	} // if (p<ru
      } // for p
    } //for i
  } // !=IF5
  ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_tti );

  return(0);
}
186 187 188 189 190

void phy_free_RU(RU_t *ru)
{
  int i,j;
  int p;
191
  RU_CALIBRATION *calibration = &ru->calibration;
192 193 194 195 196 197

  LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx);

  if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
    for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]);
    for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata[i]);
198 199 200 201 202 203
    if (ru->is_slave == 1) {  
    	for (i = 0; i < ru->nb_rx; i++) {
       		free_and_zero(calibration->drs_ch_estimates_time[i]);
        }
        free_and_zero(calibration->drs_ch_estimates_time);
    }
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
    free_and_zero(ru->common.txdata);
    free_and_zero(ru->common.rxdata);
  } // else: IF5 or local RF -> nothing to free()

  if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
    for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]);
    free_and_zero(ru->common.rxdata_7_5kHz);

    // free IFFT input buffers (TX)
    for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]);
    free_and_zero(ru->common.txdataF_BF);

    // free FFT output buffers (RX)
    for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]);
    free_and_zero(ru->common.rxdataF);
219 220 221 222 223 224 225 226
    if (ru->is_slave == 1) {
    	for (i = 0; i < ru->nb_rx; i++) {
        	free_and_zero(calibration->rxdataF_ext[i]);
  		free_and_zero(calibration->drs_ch_estimates[i]);
        }
        free_and_zero(calibration->rxdataF_ext);
        free_and_zero(calibration->drs_ch_estimates);
    }
227 228 229

    for (i = 0; i < ru->nb_rx; i++) {
      free_and_zero(ru->prach_rxsigF[i]);
230
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
      for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]);
#endif
    }
    for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]);
    free_and_zero(ru->prach_rxsigF);
    /* ru->prach_rxsigF_br is not allocated -> don't free */

    for (i = 0; i < RC.nb_L1_inst; i++) {
      for (p = 0; p < 15; p++) {
	if (p < ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p == 5) {
	  for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
	  free_and_zero(ru->beam_weights[i][p]);
	}
      }
    }
  }
  free_and_zero(ru->common.sync_corr);
}