ru_procedures.c 26.8 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 * 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 ru_procedures.c
 * \brief Implementation of RU procedures
 * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas
 * \date 2011
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk
 * \note
 * \warning
 */
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
32 33 34 35 36 37
 
/*! \function feptx_prec
 * \brief Implementation of precoding for beamforming in one eNB
 * \author TY Hsu, SY Yeh(fdragon), TH Wang(Judy)
 * \date 2018
 * \version 0.1
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
38
 * \company ISIP@NCTU and Eurecom
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
39 40 41 42
 * \email: tyhsu@cs.nctu.edu.tw,fdragon.cs96g@g2.nctu.edu.tw,Tsu-Han.Wang@eurecom.fr
 * \note
 * \warning
 */
43 44


45 46 47
#include "PHY/defs_eNB.h"
#include "PHY/phy_extern.h"
#include "SCHED/sched_eNB.h"
48
#include "PHY/MODULATION/modulation_eNB.h"
49 50
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
51
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
52
#include "PHY/LTE_TRANSPORT/transport_proto.h"
Raymond Knopp's avatar
Raymond Knopp committed
53
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
54
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
55

56
#include "LAYER2/MAC/mac.h"
57 58
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
59 60 61 62 63 64


#include "assertions.h"
#include "msc.h"

#include <time.h>
Raymond Knopp's avatar
Raymond Knopp committed
65

66 67 68 69 70
#include "targets/RT/USER/rt_wrapper.h"

extern int oai_exit;


71

72 73 74
void feptx0(RU_t *ru,int slot) {

  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
75
  //int dummy_tx_b[7680*2] __attribute__((aligned(32)));
76 77 78 79 80 81

  unsigned int aa,slot_offset;
  int slot_sizeF = (fp->ofdm_symbol_size)*
                   ((fp->Ncp==1) ? 6 : 7);
  int subframe = ru->proc.subframe_tx;

82

ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
83
  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 1 );
84

85 86
  slot_offset = subframe*fp->samples_per_tti + (slot*(fp->samples_per_tti>>1));

87
  //LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d\n",ru->proc.frame_tx, ru->proc.subframe_tx,slot);
88 89 90

  for (aa=0; aa<ru->nb_tx; aa++) {
    if (fp->Ncp == EXTENDED) PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF],
91 92 93 94 95
					                      (int*)&ru->common.txdata[aa][slot_offset],
					                      fp->ofdm_symbol_size,
					                      6,
					                      fp->nb_prefix_samples,
					                      CYCLIC_PREFIX);
96
    else {
magounak's avatar
magounak committed
97
     /* AssertFatal(ru->generate_dmrs_sync==1 && (fp->frame_type != TDD || ru->is_slave == 1),
98 99
		  "ru->generate_dmrs_sync should not be set, frame_type %d, is_slave %d\n",
		  fp->frame_type,ru->is_slave);
magounak's avatar
magounak committed
100
*/
101
      int num_symb = 7;
magounak's avatar
magounak committed
102

103
      if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe+1;
104
   
105
      if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) {
106 107
	//int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
        //int32_t *dmrsp[2] ={dmrs,NULL}; //{&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL};
magounak's avatar
magounak committed
108
  
109 110 111
	generate_drs_pusch((PHY_VARS_UE *)NULL,
			   (UE_rxtx_proc_t*)NULL,
			   fp,
112
			   ru->common.txdataF_BF,
113 114
			   0,
			   AMP,
115
			   0,
116 117 118
			   0,
			   fp->N_RB_DL,
			   aa);
119 120
      } 
      normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF],
magounak's avatar
magounak committed
121
                        (int*)&ru->common.txdata[aa][slot_offset],
122
                        num_symb,
magounak's avatar
magounak committed
123 124
                        fp);

125
       
magounak's avatar
magounak committed
126
  }
127
   /* 
128 129
    len = fp->samples_per_tti>>1;

130
    
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
    if ((slot_offset+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti)) {
      tx_offset = (int)slot_offset;
      txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
      len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
      for (i=0; i<(len2<<1); i++) {
	txdata[i] = ((int16_t*)dummy_tx_b)[i];
      }
      txdata = (int16_t*)&ru->common.txdata[aa][0];
      for (j=0; i<(len<<1); i++,j++) {
	txdata[j++] = ((int16_t*)dummy_tx_b)[i];
      }
    }
    else {
      tx_offset = (int)slot_offset;
      txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
146
      memcpy((void*)txdata,(void*)dummy_tx_b,len<<2);   
147
    }
148
*/
149
    // TDD: turn on tx switch N_TA_offset before by setting buffer in these samples to 0    
Wang Tsu-Han's avatar
Wang Tsu-Han committed
150
/*    if ((slot == 0) &&
151 152 153 154 155 156
        (fp->frame_type == TDD) && 
        ((fp->tdd_config==0) ||
         (fp->tdd_config==1) ||
         (fp->tdd_config==2) ||
         (fp->tdd_config==6)) &&  
        ((subframe==0) || (subframe==5))) {
157 158 159 160 161 162 163 164 165 166
      for (i=0; i<ru->N_TA_offset; i++) {
	tx_offset = (int)slot_offset+i-ru->N_TA_offset/2;
	if (tx_offset<0)
	  tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
	
	if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti))
	  tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
	
	ru->common.txdata[aa][tx_offset] = 0x00000000;
      }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
167
    }*/
168
  }
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
169
  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 0);
170 171 172 173 174 175
}

static void *feptx_thread(void *param) {

  RU_t *ru = (RU_t *)param;
  RU_proc_t *proc  = &ru->proc;
176 177
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
178 179 180 181 182 183
  
  thread_top_init("feptx_thread",1,85000,120000,500000);
  pthread_setname_np( pthread_self(),"feptx processing");
  LOG_I(PHY,"thread feptx created id=%ld\n", syscall(__NR_gettid));
  //CPU_SET(6, &cpuset);
  //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
184
  //wait_sync("feptx_thread");
185

186
  
187 188 189 190

  while (!oai_exit) {

    if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break;  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
191
    if (oai_exit) break;
192
    //stop_meas(&ru->ofdm_mod_wakeup_stats);
193 194 195 196 197 198 199 200
    feptx0(ru,1);
    if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break;

    if (pthread_cond_signal(&proc->cond_feptx) != 0) {
      printf("[eNB] ERROR pthread_cond_signal for feptx thread exit\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return NULL;
    }
laurent's avatar
laurent committed
201
	/*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.p_time>30*3000){
202 203 204
      print_meas_now(&ru->ofdm_mod_wakeup_stats,"fep wakeup",stderr);
      printf("delay in fep wakeup in frame_tx: %d  subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx);
    }*/
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
  }



  return(NULL);
}

void feptx_ofdm_2thread(RU_t *ru) {

  LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
  RU_proc_t *proc = &ru->proc;
  struct timespec wait;
  int subframe = ru->proc.subframe_tx;

  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
221
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 1 );
222
  start_meas(&ru->ofdm_mod_stats);
223 224 225

  if (subframe_select(fp,subframe) == SF_UL) return;

ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
226
  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
227

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
  if (subframe_select(fp,subframe)==SF_DL) {
    // If this is not an S-subframe
    if (pthread_mutex_timedlock(&proc->mutex_feptx,&wait) != 0) {
      printf("[RU] ERROR pthread_mutex_lock for feptx thread (IC %d)\n", proc->instance_cnt_feptx);
      exit_fun( "error locking mutex_feptx" );
      return;
    }
    
    if (proc->instance_cnt_feptx==0) {
      printf("[RU] FEPtx thread busy\n");
      exit_fun("FEPtx thread busy");
      pthread_mutex_unlock( &proc->mutex_feptx );
      return;
    }
    
    ++proc->instance_cnt_feptx;
    
    
    if (pthread_cond_signal(&proc->cond_feptx) != 0) {
      printf("[RU] ERROR pthread_cond_signal for feptx thread\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return;
    }
251
	//start_meas(&ru->ofdm_mod_wakeup_stats);
252 253 254 255 256 257
    
    pthread_mutex_unlock( &proc->mutex_feptx );
  }

  // call first slot in this thread
  feptx0(ru,0);
258
  start_meas(&ru->ofdm_mod_wait_stats);
259
  wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread");  
260
  stop_meas(&ru->ofdm_mod_wait_stats);
laurent's avatar
laurent committed
261
  /*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.p_time>30*3000){
262 263
    print_meas_now(&ru->ofdm_mod_wait_stats,"fep wakeup",stderr);
    printf("delay in feptx wait on codition in frame_rx: %d  subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
264
  }*/
265

ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
266
  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 );
267

268
  stop_meas(&ru->ofdm_mod_stats);
269
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 0 );
270 271 272

}

273
void feptx_ofdm(RU_t *ru) {
Raymond Knopp's avatar
Raymond Knopp committed
274 275 276 277 278 279 280 281 282 283
     
  LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;

  unsigned int aa,slot_offset, slot_offset_F;
  int dummy_tx_b[7680*4] __attribute__((aligned(32)));
  int i,j, tx_offset;
  int slot_sizeF = (fp->ofdm_symbol_size)*
                   ((fp->Ncp==1) ? 6 : 7);
  int len,len2;
  int16_t *txdata;
284 285
  int subframe = ru->proc.subframe_tx;

Raymond Knopp's avatar
Raymond Knopp committed
286 287
//  int CC_id = ru->proc.CC_id;

288
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 1 );
Cedric Roux's avatar
Cedric Roux committed
289
  slot_offset_F = 0;
Raymond Knopp's avatar
Raymond Knopp committed
290 291 292 293 294 295 296

  slot_offset = subframe*fp->samples_per_tti;

  if ((subframe_select(fp,subframe)==SF_DL)||
      ((subframe_select(fp,subframe)==SF_S))) {
    //    LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);

297 298
    start_meas(&ru->ofdm_mod_stats);

Raymond Knopp's avatar
Raymond Knopp committed
299 300
    for (aa=0; aa<ru->nb_tx; aa++) {
      if (fp->Ncp == EXTENDED) {
301
        PHY_ofdm_mod(&ru->common.txdataF_BF[aa][0],
Raymond Knopp's avatar
Raymond Knopp committed
302 303 304 305 306
                     dummy_tx_b,
                     fp->ofdm_symbol_size,
                     6,
                     fp->nb_prefix_samples,
                     CYCLIC_PREFIX);
307
        PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_sizeF],
Raymond Knopp's avatar
Raymond Knopp committed
308 309 310 311 312 313
                     dummy_tx_b+(fp->samples_per_tti>>1),
                     fp->ofdm_symbol_size,
                     6,
                     fp->nb_prefix_samples,
                     CYCLIC_PREFIX);
      } else {
314
        normal_prefix_mod(&ru->common.txdataF_BF[aa][slot_offset_F],
Raymond Knopp's avatar
Raymond Knopp committed
315 316 317 318 319
                          dummy_tx_b,
                          7,
                          fp);
	// if S-subframe generate first slot only
	if (subframe_select(fp,subframe) == SF_DL) 
320
	  normal_prefix_mod(&ru->common.txdataF_BF[aa][slot_offset_F+slot_sizeF],
Raymond Knopp's avatar
Raymond Knopp committed
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
			    dummy_tx_b+(fp->samples_per_tti>>1),
			    7,
			    fp);
      }

      // if S-subframe generate first slot only
      if (subframe_select(fp,subframe) == SF_S)
	len = fp->samples_per_tti>>1;
      else
	len = fp->samples_per_tti;
      /*
      for (i=0;i<len;i+=4) {
	dummy_tx_b[i] = 0x100;
	dummy_tx_b[i+1] = 0x01000000;
	dummy_tx_b[i+2] = 0xff00;
	dummy_tx_b[i+3] = 0xff000000;
	}*/
      
339 340 341
      if (slot_offset<0) {
	txdata = (int16_t*)&ru->common.txdata[aa][(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti)+tx_offset];
        len2 = -(slot_offset);
Raymond Knopp's avatar
Raymond Knopp committed
342 343
	len2 = (len2>len) ? len : len2;
	for (i=0; i<(len2<<1); i++) {
344
	  txdata[i] = ((int16_t*)dummy_tx_b)[i];
Raymond Knopp's avatar
Raymond Knopp committed
345 346
	}
	if (len2<len) {
347
	  txdata = (int16_t*)&ru->common.txdata[aa][0];
Raymond Knopp's avatar
Raymond Knopp committed
348
	  for (j=0; i<(len<<1); i++,j++) {
349
	    txdata[j++] = ((int16_t*)dummy_tx_b)[i];
Raymond Knopp's avatar
Raymond Knopp committed
350 351 352
	  }
	}
      }  
353 354 355
      else if ((slot_offset+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti)) {
	tx_offset = (int)slot_offset;
	txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
Raymond Knopp's avatar
Raymond Knopp committed
356 357
	len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
	for (i=0; i<(len2<<1); i++) {
358
	  txdata[i] = ((int16_t*)dummy_tx_b)[i];
Raymond Knopp's avatar
Raymond Knopp committed
359
	}
360
	txdata = (int16_t*)&ru->common.txdata[aa][0];
Raymond Knopp's avatar
Raymond Knopp committed
361
	for (j=0; i<(len<<1); i++,j++) {
362
          txdata[j++] = ((int16_t*)dummy_tx_b)[i];
Raymond Knopp's avatar
Raymond Knopp committed
363 364 365
	}
      }
      else {
366
	//LOG_D(PHY,"feptx_ofdm: Writing to position %d\n",slot_offset);
367 368
	tx_offset = (int)slot_offset;
	txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
Raymond Knopp's avatar
Raymond Knopp committed
369 370

	for (i=0; i<(len<<1); i++) {
371
	  txdata[i] = ((int16_t*)dummy_tx_b)[i];
Raymond Knopp's avatar
Raymond Knopp committed
372 373 374 375 376 377 378 379 380 381 382
	}
      }
      
     // if S-subframe switch to RX in second subframe
      /*
     if (subframe_select(fp,subframe) == SF_S) {
       for (i=0; i<len; i++) {
	 ru->common_vars.txdata[0][aa][tx_offset++] = 0x00010001;
       }
     }
      */
Wang Tsu-Han's avatar
Wang Tsu-Han committed
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403

//     if ((fp->frame_type == TDD) &&
//         ((fp->tdd_config==0) ||
//	   (fp->tdd_config==1) ||
//	   (fp->tdd_config==2) ||
//	   (fp->tdd_config==6)) &&
//	     ((subframe==0) || (subframe==5))) {
//       // turn on tx switch N_TA_offset before
//       //LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,ru->N_TA_offset,slot_offset);
//       for (i=0; i<ru->N_TA_offset; i++) {
//         tx_offset = (int)slot_offset+i-ru->N_TA_offset/2;
//         if (tx_offset<0)
//           tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
//
//         if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti))
//           tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
//
//         ru->common.txdata[aa][tx_offset] = 0x00000000;
//       }
//     }

404
     stop_meas(&ru->ofdm_mod_stats);
405
     LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, subframe %d: txp (time %p) %d dB, txp (freq) %d dB\n",
Raymond Knopp's avatar
Raymond Knopp committed
406
	   ru->proc.frame_tx,subframe,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_tti)),
407
	   dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
Raymond Knopp's avatar
Raymond Knopp committed
408 409
    }
  }
410
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 0 );
Raymond Knopp's avatar
Raymond Knopp committed
411 412
}

413
void feptx_prec(RU_t *ru) {
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
414
	
415
  int l,i,aa,p;
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
416 417 418
  int subframe = ru->proc.subframe_tx;
  PHY_VARS_eNB **eNB_list = ru->eNB_list,*eNB; 
  LTE_DL_FRAME_PARMS *fp;
419

ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
420
  /* fdragon
421 422 423 424 425
  int l,i,aa;
  PHY_VARS_eNB **eNB_list = ru->eNB_list,*eNB;
  LTE_DL_FRAME_PARMS *fp;
  int32_t ***bw;
  int subframe = ru->proc.subframe_tx;
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
426
  */
427

428

429
  if (ru->num_eNB == 1) {
430

431
    eNB = eNB_list[0];
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
432 433 434
    fp  = &eNB->frame_parms;
    LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[subframe&1]; 
    
435 436
    if (subframe_select(fp,subframe) == SF_UL) return;

437
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 1);
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
438 439

    for (aa=0;aa<ru->nb_tx;aa++) {
440 441
      memset(ru->common.txdataF_BF[aa],0,sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti);
      for (p=0;p<NB_ANTENNA_PORTS_ENB;p++) {
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
	if (ru->do_precoding == 0) {	
	  if (p==0) 
	    memcpy((void*)ru->common.txdataF_BF[aa],
	    (void*)&eNB->common_vars.txdataF[aa][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size],
	    sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti);
	} else {
	  if (p<fp->nb_antenna_ports_eNB) {				
	    // For the moment this does nothing different than below, except ignore antenna ports 5,7,8.	     
	    for (l=0;l<pdcch_vars->num_pdcch_symbols;l++)
	      beam_precoding(eNB->common_vars.txdataF,
			     ru->common.txdataF_BF,
			     subframe,
			     fp,
			     ru->beam_weights,
			     l,
			     aa,
			     p,
			     eNB->Mod_id);
	  } //if (p<fp->nb_antenna_ports_eNB)
	  
462
	  // PDSCH region
463 464 465 466 467 468 469 470 471 472 473 474 475 476
	  if (p<fp->nb_antenna_ports_eNB || p==5 || p==7 || p==8) {
	    for (l=pdcch_vars->num_pdcch_symbols;l<fp->symbols_per_tti;l++) {
	      beam_precoding(eNB->common_vars.txdataF,
			     ru->common.txdataF_BF,
			     subframe,
			     fp,
			     ru->beam_weights,
			     l,
			     aa,
			     p,
			     eNB->Mod_id);			
	    } // for (l=pdcch_vars ....)
	  } // if (p<fp->nb_antenna_ports_eNB) ...
	} // ru->do_precoding!=0	
477
      } // for (p=0...)
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
478
    } // for (aa=0 ...)
479
    
Wang Tsu-Han's avatar
Wang Tsu-Han committed
480 481
    if(ru->idx<2)
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 0);
482
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 0);
483 484
  }
  else {
485
    AssertFatal(1==0,"Handling of multi-L1 case not ready yet\n");
486 487 488 489 490 491 492 493
    for (i=0;i<ru->num_eNB;i++) {
      eNB = eNB_list[i];
      fp  = &eNB->frame_parms;
      
      for (l=0;l<fp->symbols_per_tti;l++) {
	for (aa=0;aa<ru->nb_tx;aa++) {
	  beam_precoding(eNB->common_vars.txdataF,
			 ru->common.txdataF_BF,
494
			 subframe,
495
			 fp,
496
			 ru->beam_weights,
497 498
			 subframe<<1,
			 l,
499 500
			 aa,
			 eNB->Mod_id);
501
	}
502 503 504 505
      }
    }
  }
}
Raymond Knopp's avatar
Raymond Knopp committed
506 507 508

void fep0(RU_t *ru,int slot) {

509 510
  RU_proc_t *proc       = &ru->proc;
  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
Raymond Knopp's avatar
Raymond Knopp committed
511 512
  int l;

513
    //printf("fep0: slot %d\n",slot);
Raymond Knopp's avatar
Raymond Knopp committed
514

ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
515
  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 1);
Raymond Knopp's avatar
Raymond Knopp committed
516 517
  remove_7_5_kHz(ru,(slot&1)+(proc->subframe_rx<<1));
  for (l=0; l<fp->symbols_per_tti/2; l++) {
518
    slot_fep_ul(ru,
Raymond Knopp's avatar
Raymond Knopp committed
519
		l,
520
		(slot&1),
Raymond Knopp's avatar
Raymond Knopp committed
521 522 523
		0
		);
  }
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
524
  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 0);
Raymond Knopp's avatar
Raymond Knopp committed
525 526 527 528 529 530 531
}



static void *fep_thread(void *param) {

  RU_t *ru = (RU_t *)param;
532
  RU_proc_t *proc  = &ru->proc;
533

534 535 536
  thread_top_init("fep_thread",1,100000,120000,5000000);
  pthread_setname_np( pthread_self(),"fep processing");
  LOG_I(PHY,"thread fep created id=%ld\n", syscall(__NR_gettid));
537

538 539
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
540 541
  //CPU_SET(2, &cpuset);
  //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
542
  //wait_sync("fep_thread");
543

Raymond Knopp's avatar
Raymond Knopp committed
544 545
  while (!oai_exit) {

546
    if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break; 
Wang Tsu-Han's avatar
Wang Tsu-Han committed
547
    if (oai_exit) break;
548
	//stop_meas(&ru->ofdm_demod_wakeup_stats);
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
549
	//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 ); 
Raymond Knopp's avatar
Raymond Knopp committed
550
    fep0(ru,0);
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
551
	//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 ); 
Raymond Knopp's avatar
Raymond Knopp committed
552 553 554 555 556 557 558
    if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"fep thread")<0) break;

    if (pthread_cond_signal(&proc->cond_fep) != 0) {
      printf("[eNB] ERROR pthread_cond_signal for fep thread exit\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return NULL;
    }
laurent's avatar
laurent committed
559
    /*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){
560 561 562
      print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
      printf("delay in fep wakeup in frame_rx: %d  subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
    }*/
Raymond Knopp's avatar
Raymond Knopp committed
563 564 565 566 567 568 569
  }



  return(NULL);
}

570 571 572 573 574 575 576 577 578 579 580 581 582 583
void init_feptx_thread(RU_t *ru,pthread_attr_t *attr_feptx) {

  RU_proc_t *proc = &ru->proc;

  proc->instance_cnt_feptx         = -1;
    
  pthread_mutex_init( &proc->mutex_feptx, NULL);
  pthread_cond_init( &proc->cond_feptx, NULL);

  pthread_create(&proc->pthread_feptx, attr_feptx, feptx_thread, (void*)ru);


}

584
void init_fep_thread(RU_t *ru,pthread_attr_t *attr_fep) {
Raymond Knopp's avatar
Raymond Knopp committed
585

586
  RU_proc_t *proc = &ru->proc;
Raymond Knopp's avatar
Raymond Knopp committed
587 588 589 590 591 592

  proc->instance_cnt_fep         = -1;
    
  pthread_mutex_init( &proc->mutex_fep, NULL);
  pthread_cond_init( &proc->cond_fep, NULL);

593
  pthread_create(&proc->pthread_fep, attr_fep, fep_thread, (void*)ru);
Raymond Knopp's avatar
Raymond Knopp committed
594 595 596


}
Wang Tsu-Han's avatar
Wang Tsu-Han committed
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623

extern void kill_fep_thread(RU_t *ru)
{
  RU_proc_t *proc = &ru->proc;
  pthread_mutex_lock( &proc->mutex_fep );
  proc->instance_cnt_fep         = 0;
  pthread_cond_signal(&proc->cond_fep);
  pthread_mutex_unlock( &proc->mutex_fep );
  LOG_D(PHY, "Joining pthread_fep\n");
  pthread_join(proc->pthread_fep, NULL);
  pthread_mutex_destroy( &proc->mutex_fep );
  pthread_cond_destroy( &proc->cond_fep );
}

extern void kill_feptx_thread(RU_t *ru)
{
  RU_proc_t *proc = &ru->proc;
  pthread_mutex_lock( &proc->mutex_feptx );
  proc->instance_cnt_feptx         = 0;
  pthread_cond_signal(&proc->cond_feptx);
  pthread_mutex_unlock( &proc->mutex_feptx );
  LOG_D(PHY, "Joining pthread_feptx\n");
  pthread_join(proc->pthread_feptx, NULL);
  pthread_mutex_destroy( &proc->mutex_feptx );
  pthread_cond_destroy( &proc->cond_feptx );
}

Raymond Knopp's avatar
Raymond Knopp committed
624 625
void ru_fep_full_2thread(RU_t *ru) {

626
  RU_proc_t *proc = &ru->proc;
627 628 629
  //PHY_VARS_eNB *eNB = RC.eNB[0][0];
  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
  RU_CALIBRATION *calibration = &ru->calibration;
630
  RRU_CONFIG_msg_t rru_config_msg;
631
  int check_sync_pos;
Raymond Knopp's avatar
Raymond Knopp committed
632 633

  struct timespec wait;
634 635 636 637 638 639
  if (proc->subframe_rx==1){
  	//LOG_I(PHY,"subframe type %d, RU %d\n",subframe_select(fp,proc->subframe_rx),ru->idx);
  }
  else if ((fp->frame_type == TDD) && (subframe_select(fp,proc->subframe_rx) != SF_UL)) {
  	return;
  }
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
640
  //if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
641

Raymond Knopp's avatar
Raymond Knopp committed
642 643 644
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;

645
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 1 );
Raymond Knopp's avatar
Raymond Knopp committed
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
  start_meas(&ru->ofdm_demod_stats);

  if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) {
    printf("[RU] ERROR pthread_mutex_lock for fep thread (IC %d)\n", proc->instance_cnt_fep);
    exit_fun( "error locking mutex_fep" );
    return;
  }

  if (proc->instance_cnt_fep==0) {
    printf("[RU] FEP thread busy\n");
    exit_fun("FEP thread busy");
    pthread_mutex_unlock( &proc->mutex_fep );
    return;
  }
  
  ++proc->instance_cnt_fep;


  if (pthread_cond_signal(&proc->cond_fep) != 0) {
    printf("[RU] ERROR pthread_cond_signal for fep thread\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return;
  }
669
  //start_meas(&ru->ofdm_demod_wakeup_stats);
Raymond Knopp's avatar
Raymond Knopp committed
670 671 672 673 674 675
  
  pthread_mutex_unlock( &proc->mutex_fep );

  // call second slot in this symbol
  fep0(ru,1);

676
  start_meas(&ru->ofdm_demod_wait_stats);
Raymond Knopp's avatar
Raymond Knopp committed
677
  wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread");  
678
  stop_meas(&ru->ofdm_demod_wait_stats);
laurent's avatar
laurent committed
679
  if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){
680
    print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
681
    printf("delay in fep wait on condition in frame_rx: %d  subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
682
  }
Raymond Knopp's avatar
Raymond Knopp committed
683

684 685
  if (proc->subframe_rx==1 && ru->is_slave==1/* && ru->state == RU_CHECK_SYNC*/) {

686
        //LOG_I(PHY,"Running check synchronization procedure for frame %d\n", proc->frame_rx);
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
  	ulsch_extract_rbs_single(ru->common.rxdataF,
                                 calibration->rxdataF_ext,
                                 0,
                                 fp->N_RB_DL,
                                 3%(fp->symbols_per_tti/2),// l = symbol within slot
                                 3/(fp->symbols_per_tti/2),// Ns = slot number 
                                 fp);
        
	/*lte_ul_channel_estimation((PHY_VARS_eNB *)NULL,
				  proc,
                                  ru->idx,
                                  3%(fp->symbols_per_tti/2),
                                  3/(fp->symbols_per_tti/2));
        */
	lte_ul_channel_estimation_RRU(fp,
                                  calibration->drs_ch_estimates,
                                  calibration->drs_ch_estimates_time,
                                  calibration->rxdataF_ext,
                                  fp->N_RB_DL, //N_rb_alloc,
				  proc->frame_rx,
				  proc->subframe_rx,
				  0,//u = 0..29
				  0,//v = 0,1
				  /*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/0,
				  3,//l,
 			          0,//interpolate,
				  0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/);
 
        

        check_sync_pos = lte_est_timing_advance_pusch((PHY_VARS_eNB *)NULL,
     				     		       ru->idx);
        if (ru->state == RU_CHECK_SYNC) {
          if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) {
721
    		  LOG_I(PHY,"~~~~~~~~~~~    check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check); 
722 723 724
                  ru->wait_check++;
          }

725
          if (ru->wait_check==20) { 
726
	  	ru->state = RU_RUN;
727 728 729 730 731 732 733
 		ru->wait_check = 0;
		// Send RRU_sync_ok
                rru_config_msg.type = RRU_sync_ok;
        	rru_config_msg.len  = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len
        	LOG_I(PHY,"Sending RRU_sync_ok to RAU\n");
        	AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU %d\n",ru->idx);
                //LOG_I(PHY,"~~~~~~~~~ RU_RUN\n");
734 735 736 737 738 739 740 741 742 743
          	/*LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1);
		LOG_M("rxdataF_ext.m","rxdataFext",&calibration->rxdataF_ext[0][36*fp->N_RB_DL], 12*(fp->N_RB_DL),1,1);		
		LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1);
		LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1);
		exit(-1);*/
	 } 
       }
       else if (ru->state == RU_RUN) {
       	// check for synchronization error
       	if (check_sync_pos >= 8 || check_sync_pos<=-8) {
744 745 746
	 	LOG_E(PHY,"~~~~~~~~~~~~~~ check_sync_pos %d, frame %d ---> LOST SYNC-EXIT\n", check_sync_pos, proc->frame_rx);
LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1);		
exit(-1);
747 748 749 750 751 752 753 754
	}
       }
    
    else {
       	 AssertFatal(1==0,"Should not get here\n");
    }
 }

Raymond Knopp's avatar
Raymond Knopp committed
755
  stop_meas(&ru->ofdm_demod_stats);
756
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 0 );
Raymond Knopp's avatar
Raymond Knopp committed
757 758 759 760
}



761
void fep_full(RU_t *ru) {
Raymond Knopp's avatar
Raymond Knopp committed
762

763
  RU_proc_t *proc = &ru->proc;
Raymond Knopp's avatar
Raymond Knopp committed
764
  int l;
765
  LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
Raymond Knopp's avatar
Raymond Knopp committed
766

767 768
  if ((fp->frame_type == TDD) && 
     (subframe_select(fp,proc->subframe_rx) != SF_UL)) return;
Raymond Knopp's avatar
Raymond Knopp committed
769

770
  start_meas(&ru->ofdm_demod_stats);
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
771
  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 1 );
Cedric Roux's avatar
Cedric Roux committed
772

Raymond Knopp's avatar
Raymond Knopp committed
773 774
  remove_7_5_kHz(ru,proc->subframe_rx<<1);
  remove_7_5_kHz(ru,1+(proc->subframe_rx<<1));
775

Raymond Knopp's avatar
Raymond Knopp committed
776
  for (l=0; l<fp->symbols_per_tti/2; l++) {
777
    slot_fep_ul(ru,
Raymond Knopp's avatar
Raymond Knopp committed
778
		l,
779
		0,
Raymond Knopp's avatar
Raymond Knopp committed
780 781
		0
		);
782
    slot_fep_ul(ru,
Raymond Knopp's avatar
Raymond Knopp committed
783
		l,
784
		1,
Raymond Knopp's avatar
Raymond Knopp committed
785 786 787
		0
		);
  }
ISIP CS/NCTU's avatar
ISIP CS/NCTU committed
788
  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 0 );
Raymond Knopp's avatar
Raymond Knopp committed
789 790 791 792 793 794 795 796
  stop_meas(&ru->ofdm_demod_stats);
  
  
}


void do_prach_ru(RU_t *ru) {

797 798
  RU_proc_t *proc = &ru->proc;
  LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
Raymond Knopp's avatar
Raymond Knopp committed
799 800

  // check if we have to detect PRACH first
801
  if (is_prach_subframe(fp,proc->frame_prach,proc->subframe_prach)>0) { 
802
    //accept some delay in processing - up to 5ms
Raymond Knopp's avatar
Raymond Knopp committed
803 804
    int i;
    for (i = 0; i < 10 && proc->instance_cnt_prach == 0; i++) {
805 806
      LOG_W(PHY,"Frame %d Subframe %d, PRACH thread busy (IC %d)!!\n", proc->frame_prach,proc->subframe_prach,
	    proc->instance_cnt_prach);
Raymond Knopp's avatar
Raymond Knopp committed
807 808 809 810 811 812 813 814 815
      usleep(500);
    }
    if (proc->instance_cnt_prach == 0) {
      exit_fun( "PRACH thread busy" );
      return;
    }
    
    // wake up thread for PRACH RX
    if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
816
      LOG_E( PHY, "ERROR pthread_mutex_lock for PRACH thread (IC %d)\n", proc->instance_cnt_prach );
Raymond Knopp's avatar
Raymond Knopp committed
817 818 819 820 821 822 823 824
      exit_fun( "error locking mutex_prach" );
      return;
    }
    
    ++proc->instance_cnt_prach;
    
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_prach) != 0) {
825
      LOG_E( PHY, "ERROR pthread_cond_signal for PRACH thread\n");
Raymond Knopp's avatar
Raymond Knopp committed
826 827 828 829 830 831 832 833
      exit_fun( "ERROR pthread_cond_signal" );
      return;
    }
    
    pthread_mutex_unlock( &proc->mutex_prach );
  }

}