diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 1cdcf218969ecf325fc099426b1c43fd2ebdc467..91afe812170618d9d6d31e85958f04ba5ed5ef44 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -1211,13 +1211,11 @@ static void *ru_stats_thread(void *param) {
     sleep(1);
 
     if (opp_enabled == 1) {
-      if (ru->feptx_prec) {
-        print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL);
-      }
 
       if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
 
       if (ru->feptx_ofdm){
+        print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL);
         print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL);
         print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL);
         print_meas(&ru->ofdm_total_stats,"feptx_total",NULL,NULL);
@@ -1281,9 +1279,9 @@ static void *ru_thread_tx( void *param ) {
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );
 
     // do TX front-end processing if needed (precoding and/or IDFTs)
-    //if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
+    if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
 
-    // do OFDM if needed
+    // do OFDM with/without TX front-end processing  if needed
     if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx);
 
     if(!emulate_rf) {
@@ -1524,9 +1522,9 @@ static void *ru_thread( void *param ) {
 
     if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_gNB==0) {
       // do TX front-end processing if needed (precoding and/or IDFTs)
-      //if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
+      if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
 
-      // do OFDM if needed
+      // do OFDM with/without TX front-end processing  if needed
       if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
 
       if(!emulate_rf) {
@@ -1734,7 +1732,6 @@ void init_RU_proc(RU_t *ru) {
     if (ru->feprx) nr_init_feprx_thread(ru);
 
     if (ru->feptx_ofdm) nr_init_feptx_thread(ru);
-    //if (ru->feptx_prec) nr_init_feptx_prec_thread(ru);
   }
 
   if (opp_enabled == 1) threadCreate(&ru->ru_stats_thread,ru_stats_thread,(void *)ru, "emulateRF", -1, OAI_PRIORITY_RT_LOW);
@@ -2047,9 +2044,9 @@ void set_function_spec_param(RU_t *ru) {
         malloc_IF4p5_buffer(ru);
       } else if (ru->function == gNodeB_3GPP) {
         ru->do_prach             = 0;                       // no prach processing in RU
-        ru->feprx                = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full;                // RX DFTs
+        ru->feprx                = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread   : nr_fep_full;                // RX DFTs
         ru->feptx_ofdm           = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm;              // this is fep with idft and precoding
-        ru->feptx_prec           = nr_feptx_prec;           // this is fep with idft and precoding
+        ru->feptx_prec           = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL                  : nr_feptx_prec;           // this is fep with idft and precoding
         ru->fh_north_in          = NULL;                    // no incoming fronthaul from north
         ru->fh_north_out         = NULL;                    // no outgoing fronthaul to north
         ru->nr_start_if          = NULL;                    // no if interface
@@ -2077,8 +2074,8 @@ void set_function_spec_param(RU_t *ru) {
 
     case REMOTE_IF5: // the remote unit is IF5 RRU
       ru->do_prach               = 0;
-      ru->feprx                  = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full;     // this is frequency-shift + DFTs
-      ru->feptx_prec             = nr_feptx_prec;          // need to do transmit Precoding + IDFTs
+      ru->feprx                  = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread   : nr_fep_full;     // this is frequency-shift + DFTs
+      ru->feptx_prec             = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL                  : nr_feptx_prec;          // need to do transmit Precoding + IDFTs
       ru->feptx_ofdm             = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs
       ru->fh_south_in            = fh_if5_south_in;     // synchronous IF5 reception
       ru->fh_south_out           = fh_if5_south_out;    // synchronous IF5 transmission
@@ -2102,7 +2099,7 @@ void set_function_spec_param(RU_t *ru) {
     case REMOTE_IF4p5:
       ru->do_prach               = 0;
       ru->feprx                  = NULL;                // DFTs
-      ru->feptx_prec             = nr_feptx_prec;          // Precoding operation
+      ru->feptx_prec             = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec;          // Precoding operation
       ru->feptx_ofdm             = NULL;                // no OFDM mod
       ru->fh_south_in            = fh_if4p5_south_in;   // synchronous IF4p5 reception
       ru->fh_south_out           = fh_if4p5_south_out;  // synchronous IF4p5 transmission
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index a4318f1d60e1fa0f44504b1543b3bb1661145cf7..c286bd5dee9402b7c2eb4de06220518ecdb3bbea 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -239,9 +239,22 @@ static void *nr_feptx_thread(void *param) {
     nb_antenna_ports = feptx->nb_antenna_ports;
     ofdm_mask_full   = (1<<(ru->nb_tx*2))-1;
 
-    bw  = ru->beam_weights[0];
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1);
     start_meas(&ru->precoding_stats);
-    nr_beam_precoding(ru->common.txdataF,
+    if (ru->nb_tx == 1) {
+      AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx);
+      for (int p=0; p<fp->Lmax; p++) {
+        if ((fp->L_ssb >> p) & 0x01){
+          memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size],
+                 (void*)&ru->common.txdataF[p][l*fp->ofdm_symbol_size],
+                 fp->ofdm_symbol_size*sizeof(int32_t));
+        }
+      }
+    }
+    else {
+      bw  = ru->beam_weights[0];
+      nr_beam_precoding(ru->common.txdataF,
                         ru->common.txdataF_BF,
                         fp,
                         bw,
@@ -249,7 +262,10 @@ static void *nr_feptx_thread(void *param) {
                         l,
                         aa,
                         nb_antenna_ports);
+    }
     stop_meas(&ru->precoding_stats);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0);
+
 
     start_meas(&ru->ofdm_mod_stats);
     nr_feptx0(ru,slot,start,1,aa);
@@ -270,24 +286,6 @@ static void *nr_feptx_thread(void *param) {
   return(NULL);
 }
 
-void nr_init_feptx_thread(RU_t *ru) {
-
-  RU_proc_t  *proc  = &ru->proc;
-  RU_feptx_t *feptx = proc->feptx;
-  int i = 0;
-
-  for(i=0; i<16; i++){
-    feptx[i].instance_cnt_feptx         = -1;
-    
-    pthread_mutex_init( &feptx[i].mutex_feptx, NULL);
-    pthread_cond_init( &feptx[i].cond_feptx, NULL);
-
-    threadCreate(&feptx[i].pthread_feptx, nr_feptx_thread, (void*)&feptx[i], "feptx", -1, OAI_PRIORITY_RT);
-    LOG_I(PHY,"init feptx thread %d\n", i);
-  }
-
-}
-
 
 // is this supposed to generate a slot or a subframe???
 // seems to be hardcoded to numerology 1 (2 slots=1 subframe)
@@ -323,95 +321,25 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
 }
 
 
-static void *nr_feptx_prec_thread(void *param) {
-
-  RU_prec_t *prec                = (RU_prec_t *) param;
-  RU_t *ru;
-  NR_DL_FRAME_PARMS *fp;
-  int symbol;
-  int p;
-  int aa;
-  int32_t *bw;
-  int32_t **txdataF;
-  int32_t **txdataF_BF;
-
-  while(!oai_exit)
-  {
-    if (wait_on_condition(&prec->mutex_feptx_prec,&prec->cond_feptx_prec,&prec->instance_cnt_feptx_prec,"NR feptx prec thread")<0) break;
-    ru                   = prec->ru;
-    symbol               = prec->symbol;
-    p                    = prec->p;
-    aa                   = prec->aa;
-    fp                   = ru->nr_frame_parms;
-    bw                   = ru->beam_weights[0][p][aa];
-    txdataF              = ru->common.txdataF;
-    txdataF_BF           = ru->common.txdataF_BF;
-    multadd_cpx_vector((int16_t*)&txdataF[p][symbol*fp->ofdm_symbol_size],
-			 (int16_t*)bw, 
-			 (int16_t*)&txdataF_BF[aa][symbol*fp->ofdm_symbol_size], 
-			 0, 
-			 fp->ofdm_symbol_size, 
-			 15);
-
-    if (release_thread(&prec->mutex_feptx_prec,&prec->instance_cnt_feptx_prec,"NR feptx thread")<0) break;
-  }
-  return 0;
-}
-
-void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx) {
-
-  int ret    = 0;
-  int i      = 0;
-  int symbol = 0;
-  int p      = 0;
-  int aa     = 0;
-  NR_DL_FRAME_PARMS *fp   = ru->nr_frame_parms;
-  int nb_antenna_ports    = fp->Lmax; // for now logical antenna ports corresponds to SSB
-  RU_prec_t *prec         = ru->proc.prec;
-  PHY_VARS_gNB **gNB_list = ru->gNB_list,*gNB;
+void nr_init_feptx_thread(RU_t *ru) {
 
-  gNB = gNB_list[0];
+  RU_proc_t  *proc  = &ru->proc;
+  RU_feptx_t *feptx = proc->feptx;
+  int i = 0;
 
-  start_meas(&ru->precoding_stats);
-  for(i=0; i<nb_antenna_ports; ++i)
-    memcpy((void*)ru->common.txdataF[i],
-           (void*)gNB->common_vars.txdataF[i],
-           fp->samples_per_slot_wCP*sizeof(int32_t));
+  for(i=0; i<16; i++){
+    feptx[i].instance_cnt_feptx         = -1;
+    
+    pthread_mutex_init( &feptx[i].mutex_feptx, NULL);
+    pthread_cond_init( &feptx[i].cond_feptx, NULL);
 
-  for(symbol = 0; symbol < fp->symbols_per_slot; ++symbol){
-    for(p=0; p<nb_antenna_ports; p++){
-      for(aa=0;aa<ru->nb_tx;aa++){
-        if ((fp->L_ssb >> p) & 0x01){
-          while(1){
-            if(prec[i].instance_cnt_feptx_prec == -1){
-              AssertFatal((ret=pthread_mutex_lock(&prec[i].mutex_feptx_prec))==0,"mutex_lock return %d\n",ret);
-              prec[i].instance_cnt_feptx_prec = 0;
-              prec[i].symbol                  = symbol;
-              prec[i].p                       = p;
-              prec[i].aa                      = aa;
-              prec[i].index                   = i;
-              prec[i].ru                      = ru;
-              AssertFatal(pthread_cond_signal(&prec[i].cond_feptx_prec) == 0,"ERROR pthread_cond_signal for gNB_L1_thread\n");
-              AssertFatal((ret=pthread_mutex_unlock(&prec[i].mutex_feptx_prec))==0,"mutex_lock returns %d\n",ret);
-              i = (i+1) % 16;
-              break;
-            }
-            i = (i+1) % 16;
-          }
-        }//(frame_params->Lssb >> p) & 0x01
-      }//aa
-    }//p
-  }//symbol
-  
-  i = 0;
-  while(1){
-    if(prec[i].instance_cnt_feptx_prec == -1) ++i;
-    if(i == 16) break;
+    threadCreate(&feptx[i].pthread_feptx, nr_feptx_thread, (void*)&feptx[i], "feptx", -1, OAI_PRIORITY_RT);
+    LOG_I(PHY,"init feptx thread %d\n", i);
   }
 
-  stop_meas(&ru->precoding_stats);
 }
 
+
 void nr_feptx_prec(RU_t *ru,int frame,int tti_tx) {
 
   int l,aa;
@@ -467,21 +395,6 @@ void nr_feptx_prec(RU_t *ru,int frame,int tti_tx) {
   stop_meas(&ru->precoding_stats);
 }
 
-void nr_init_feptx_prec_thread(RU_t *ru){
-
-  RU_proc_t *proc = &ru->proc;
-  RU_prec_t *prec = proc->prec;
-  int i=0;
-
-  for(i=0; i<16; ++i){
-    prec[i].instance_cnt_feptx_prec         = -1;
-    pthread_mutex_init( &prec[i].mutex_feptx_prec, NULL);
-    pthread_cond_init( &prec[i].cond_feptx_prec, NULL);
-
-    threadCreate(&prec[i].pthread_feptx_prec, nr_feptx_prec_thread, (void*)&prec[i], "nr_feptx_prec", -1, OAI_PRIORITY_RT);
-  }
-}
-
 void nr_fep0(RU_t *ru, int first_half) {
   
   uint8_t start_symbol, end_symbol, l, aa;