diff --git a/oaienv b/oaienv
index 383c75a4b146859d63f75eefd792df1b2475f9b2..f6b298debf69e2e24c2c65cce458291b9ff0a513 100644
--- a/oaienv
+++ b/oaienv
@@ -5,7 +5,8 @@ export OPENAIR1_DIR=$OPENAIR_HOME/openair1
 export OPENAIR2_DIR=$OPENAIR_HOME/openair2
 export OPENAIR3_DIR=$OPENAIR_HOME/openair3
 export OPENAIR_TARGETS=$OPENAIR_HOME/targets
-export OPENAIRITS_DIR=$OPENAIR_HOME/openairITS
+
+export PATH=$PATH:$OPENAIR_TARGETS/bin
 
 alias  oai='cd $OPENAIR_HOME'
 alias oai0='cd $OPENAIR0_DIR'
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index a77501e14c78357872f489c2f5b3c33e7a958c68..6d6f36bc63469c4b50efe756998158ffefb0c626 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -1102,8 +1102,12 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
     dlsch[0]->harq_ids[subframe] = harq_pid;
 
-    if (dlsch0_harq->round == 0)
+    if (dlsch0_harq->round == 0) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch[0], harq_pid);
       dlsch0_harq->status = ACTIVE;
+    }
 
     break;
 
@@ -1237,6 +1241,9 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
 
     if (dlsch0_harq->round == 0) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch[0], harq_pid);
       dlsch0_harq->status = ACTIVE;
       //            printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
       // MCS and TBS don't change across HARQ rounds
@@ -1605,10 +1612,16 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
     // reset HARQ process if this is the first transmission
     if (dlsch0_harq->round == 0) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch0, harq_pid);
       dlsch0_harq->status = ACTIVE;
     }
 
     if (dlsch1_harq->round == 0) {
+      /* necessary test? */
+      if (dlsch1_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch1, harq_pid);
       dlsch1_harq->status = ACTIVE;
     }
 
@@ -1986,10 +1999,16 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
     // reset HARQ process if this is the first transmission
     if ((dlsch0->active==1) && (dlsch0_harq->round == 0)) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch0, harq_pid);
       dlsch0_harq->status = ACTIVE;
     }
 
     if ((dlsch1->active==1) && (dlsch1_harq->round == 0)) {
+      /* necessary test? */
+      if (dlsch1_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch1, harq_pid);
       dlsch1_harq->status = ACTIVE;
     }
 
@@ -2131,16 +2150,23 @@ int generate_eNB_dlsch_params_from_dci(int frame,
     // check if either TB is disabled (see 36-213 V8.6 p. 26)
 
 
-    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0))
+    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
+      LOG_W(PHY, "what to do with respect to remove_harq_pid_from_freelist?\n");
       dlsch0_harq->status = DISABLED;
+    }
 
-    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0))
+    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
+      LOG_W(PHY, "what to do with respect to remove_harq_pid_from_freelist?\n");
       dlsch1_harq->status = DISABLED;
+    }
 
     dlsch0_harq->Nl        = 1;
 
 
     if (dlsch0_harq->round == 0) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch0, harq_pid);
       dlsch0_harq->status = ACTIVE;
       //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
     }
@@ -2305,11 +2331,17 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
 
     if ((dlsch0_harq->round == 0) && (dlsch0->active == 1) ) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch0, harq_pid);
       dlsch0_harq->status      = ACTIVE;
       dlsch0_harq->mcs         = mcs1;
     }
 
     if ((dlsch1_harq->round == 0) && (dlsch1->active == 1) ) {
+      /* necessary test? */
+      if (dlsch1_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch1, harq_pid);
       dlsch1_harq->status      = ACTIVE;
       dlsch1_harq->mcs         = mcs2;
     }
@@ -2473,6 +2505,9 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
 
     if (dlsch0_harq->round == 0) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch0, harq_pid);
       dlsch0_harq->status = ACTIVE;
       //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
     }
@@ -2602,6 +2637,9 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
     //    dlsch0_harq->Ndi         = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
     if (dlsch0_harq->round == 0) {
+      /* necessary test? */
+      if (dlsch0_harq->status == SCH_IDLE)
+        remove_harq_pid_from_freelist(dlsch0, harq_pid);
       dlsch0_harq->status = ACTIVE;
       //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
     }
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index a21693fea0e9865aa11ec495cecaf3a001006fd4..55b9c4fe4453772d8177e36f92718b55e545834a 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -258,6 +258,13 @@ typedef struct {
   uint8_t error_threshold;
   /// Pointers to 8 HARQ processes for the DLSCH
   LTE_DL_eNB_HARQ_t *harq_processes[8];
+  /// circular list of free harq PIDs (the oldest come first)
+  /// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE)
+  int harq_pid_freelist[10];
+  /// the head position of the free list (if list is free then head=tail)
+  int head_freelist;
+  /// the tail position of the free list
+  int tail_freelist;
   /// Number of soft channel bits
   uint32_t G;
   /// Codebook index for this dlsch (0,1,2,3)
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 83066480b49e966bc485fb9e38323171c504bbc0..f051dc3ecfe9869bf993c4dfe06ea61e0edf793c 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -152,6 +152,9 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne
     for (i=0; i<10; i++)
       dlsch->harq_ids[i] = Mdlharq;
 
+    dlsch->head_freelist = 0;
+    dlsch->tail_freelist = 0;
+
     for (i=0; i<Mdlharq; i++) {
       dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t));
       LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
@@ -192,6 +195,8 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne
         msg("Can't get harq_p %d\n",i);
         exit_flag=3;
       }
+
+      put_harq_pid_in_freelist(dlsch, i);
     }
 
     if (exit_flag==0) {
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index bebe476dcd2fd3ab194549d5cfdb39fd2dfb2ecd..a88327ba92e6b1ddc1e0121bb55b61d16a04a70a 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -401,6 +401,8 @@ uint16_t get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1);
 
 int get_nCCE_offset(unsigned char L, int nCCE, int common_dci, unsigned short rnti, unsigned char subframe);
 
+void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid);
+void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid);
 
 int8_t find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
 int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 165f2fbac61ebda4df560c9588465d505dfcd84d..d0736575192e47fc1909572bb2e0ca84ad7d4afc 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -136,6 +136,30 @@ uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_su
   return(0);
 }
 
+void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
+{
+  DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->tail_freelist] = harq_pid;
+  DLSCH_ptr->tail_freelist = (DLSCH_ptr->tail_freelist + 1) % 10;
+}
+
+void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
+{
+  if (DLSCH_ptr->head_freelist == DLSCH_ptr->tail_freelist) {
+    LOG_E(PHY, "%s:%d: you cannot read this!\n", __FILE__, __LINE__);
+    abort();
+  }
+  /* basic check, in case several threads deal with the free list at the same time
+   * in normal situations it should not happen, that's also why we don't use any
+   * locking mechanism to protect the free list
+   * to be refined in case things don't work properly
+   */
+  if (harq_pid != DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]) {
+    LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
+    abort();
+  }
+  DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
+}
+
 int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
 {
   uint8_t i;
@@ -178,6 +202,7 @@ int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
 int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction_flag)
 {
   uint8_t i;
+  int j;
 
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
     if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
@@ -196,6 +221,13 @@ int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction
         //phy_vars_eNB->eNB_UE_stats[i].crnti = 0;
         memset(&phy_vars_eNB->eNB_UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
         //  mac_exit_wrapper("Removing UE");
+
+        /* clear the harq pid freelist */
+        phy_vars_eNB->dlsch_eNB[i][0]->head_freelist = 0;
+        phy_vars_eNB->dlsch_eNB[i][0]->tail_freelist = 0;
+        for (j = 0; j < 8; j++)
+          put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], j);
+
         return(i);
       }
     }
@@ -224,14 +256,12 @@ int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB)
 
 int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t ul_flag)
 {
-
   LTE_eNB_DLSCH_t *DLSCH_ptr;
   LTE_eNB_ULSCH_t *ULSCH_ptr;
   uint8_t ulsch_subframe,ulsch_frame;
   uint8_t i;
   int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
   int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
-  int first_proc_found=0;
 
   if (UE_id==-1) {
     LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
@@ -247,18 +277,7 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
 
     for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
       if (DLSCH_ptr->harq_processes[i]!=NULL) {
-	if (DLSCH_ptr->harq_processes[i]->status != ACTIVE) {
-	  // store first inactive process
-	  if (first_proc_found == 0) {
-	    first_proc_found = 1;
-	    *harq_pid = i;
-	    *round = 0;
-	    LOG_D(PHY,"process %d is first free process\n",i);
-	  }
-	  else {
-	    LOG_D(PHY,"process %d is free\n",i);
-	  }
-	} else {
+	if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
 	  sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe;
 	  if (sf2<=sf1)
 	    sfdiff = sf1-sf2;
@@ -270,7 +289,6 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
 	    sfdiff_max = sfdiff; 
 	    *harq_pid = i;
 	    *round = DLSCH_ptr->harq_processes[i]->round;
-	    first_proc_found = 1;
 	  }
 	}
       } else { // a process is not defined
@@ -278,6 +296,14 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
 	return(-1);
       }
     }
+
+    /* if no active harq pid, get the oldest in the freelist, if any */
+    if (*harq_pid == 255 && DLSCH_ptr->head_freelist != DLSCH_ptr->tail_freelist) {
+      *harq_pid = DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist];
+      *round = 0;
+      LOG_D(PHY,"process %d is first free process\n", *harq_pid);
+    }
+
     LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
 	  frame,subframe,*harq_pid);
   } else { // This is a UL request
@@ -296,7 +322,6 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
   return(0);
 }
 
-
 int CCE_table[800];
 
 void init_nCCE_table(void)
@@ -2868,6 +2893,7 @@ void process_HARQ_feedback(uint8_t UE_id,
               dlsch_harq_proc->round = 0;
               ue_stats->dlsch_l2_errors[dl_harq_pid[m]]++;
               dlsch_harq_proc->status = SCH_IDLE;
+              put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
               dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;
             }
           } else {
@@ -2880,6 +2906,7 @@ void process_HARQ_feedback(uint8_t UE_id,
             // Received ACK so set round to 0 and set dlsch_harq_pid IDLE
             dlsch_harq_proc->round  = 0;
             dlsch_harq_proc->status = SCH_IDLE;
+            put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
             dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;
 
             ue_stats->total_TBS = ue_stats->total_TBS +
@@ -3949,6 +3976,9 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_
             phy_vars_eNB->eNB_UE_stats[i].sr_received++;
 
             if (phy_vars_eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4
+              /* is this test necessary? */
+              if (phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status != SCH_IDLE)
+                put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], 0);
               phy_vars_eNB->first_sr[i] = 0;
               phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->round=0;
               phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status=SCH_IDLE;
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 227a100692fef69d7bc72b37fd5641c989acab61..156da0c4ce6991c3b54c4901650f34d826d8348f 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -60,6 +60,11 @@ typedef enum {
   max_gain=0,med_gain,byp_gain
 } rx_gain_t;
 
+typedef enum {
+  duplex_mode_TDD=1,duplex_mode_FDD=0
+} duplex_mode_t;
+
+
 /** @addtogroup _PHY_RF_INTERFACE_
  * @{
  */
@@ -76,6 +81,8 @@ typedef struct {
   int Mod_id;
   // device log level
   int log_level;
+  //! duplexing mode
+  duplex_mode_t duplex_mode;
   //! number of downlink resource blocks
   int num_rb_dl;
   //! number of samples per frame 
diff --git a/targets/ARCH/EXMIMO/DEFS/pcie_interface.h b/targets/ARCH/EXMIMO/DEFS/pcie_interface.h
index 925787cabfbb955e1cb20d17b0d73ecb0c5a5694..713480b40bbdcadcb042af1c14c9c3c199a0555d 100644
--- a/targets/ARCH/EXMIMO/DEFS/pcie_interface.h
+++ b/targets/ARCH/EXMIMO/DEFS/pcie_interface.h
@@ -316,7 +316,9 @@ typedef struct {
 //
 //    In TDD mode, there are two ways to control the RX/TX switch:
 //    1. using the LSB from the TX data (TXRXSWITCH_LSB)
+//       only the LSB from RF chain set in the ACTIVE_RF register controls the switch on all the chains
 //    2. using FPGA logic, based on switch_offset[0..3]
+//       this mode is not tested well and should be used with care
 #define DUPLEXMODE_MASK   (1<<0)
 #define DUPLEXMODE_FDD     0
 #define DUPLEXMODE_TDD    (1<<0)
@@ -330,6 +332,11 @@ typedef struct {
 #define SWITCHSTATE_1     (1<<3)
 #define TEST_ADACLOOP_MASK  (1<<4)
 #define TEST_ADACLOOP_EN    (1<<4)
+#define RF_ACTIVE_MASK      (15<<5)
+#define RF_ACTIVE_1         (1<<5)
+#define RF_ACTIVE_2         (2<<5)
+#define RF_ACTIVE_3         (4<<5)
+#define RF_ACTIVE_4         (8<<5)
 
 typedef enum {
   BW5,
diff --git a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
index df9900d3bc98720090143b73c2989a30ad0868ea..238c94bd7e97a6ce6d6330f260ca99c38e83e5b5 100644
--- a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
+++ b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
@@ -296,6 +296,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
   int ant, card;
   int resampling_factor=2;
   int rx_filter=RXLPF25, tx_filter=TXLPF25;
+  int ACTIVE_RF=0;
 
   exmimo_config_t         *p_exmimo_config;
   exmimo_id_t             *p_exmimo_id;
@@ -315,8 +316,6 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
     else
       p_exmimo_config->framing.eNB_flag   = !UE_flag;
 
-    p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD + TXRXSWITCH_LSB;
-
     if (openair0_num_detected_cards==1)
       p_exmimo_config->framing.multicard_syncmode=SYNCMODE_FREE;
     else if (card==0)
@@ -355,6 +354,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
 
     for (ant=0; ant<4; ant++) {
       if (openair0_cfg[card].rx_freq[ant] || openair0_cfg[card].tx_freq[ant]) {
+	ACTIVE_RF += (1<<ant)<<5;
         p_exmimo_config->rf.rf_mode[ant] = RF_MODE_BASE;
         p_exmimo_config->rf.do_autocal[ant] = 1;//openair0_cfg[card].autocal[ant];
 	printf("card %d, antenna %d, autocal %d\n",card,ant,openair0_cfg[card].autocal[ant]);
@@ -408,6 +408,15 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
       }
     }
 
+    if (openair0_cfg[card].duplex_mode==duplex_mode_FDD) {
+      p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD;
+      printf("!!!!!setting FDD (tdd_config=%d)\n",p_exmimo_config->framing.tdd_config);
+    } 
+    else {
+      p_exmimo_config->framing.tdd_config = DUPLEXMODE_TDD + TXRXSWITCH_LSB + ACTIVE_RF;
+      printf("!!!!!setting TDD (tdd_config=%d)\n",p_exmimo_config->framing.tdd_config);
+    }
+
     ret = ioctl(openair0_fd, openair_DUMP_CONFIG, card);
 
     if (ret!=0)
diff --git a/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/sdr_expressmimo2_v10 b/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/sdr_expressmimo2_v10
index 2889dfa80f8f6a9128af6e9ca6dd1a309c9e1b39..d79e46df76881a3d2bf476b82f988b0a9bfd4839 100755
Binary files a/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/sdr_expressmimo2_v10 and b/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/sdr_expressmimo2_v10 differ
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.exmimo2.conf
index 0071b7d002ab33c880b125fdfa8791b35a927339..9444a6f95e8c610b95a87dd6ce3ecc52765ac811 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.exmimo2.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.exmimo2.conf
@@ -17,7 +17,7 @@ eNBs =
 
     mobile_country_code =  "208";
 
-    mobile_network_code =  "92";
+    mobile_network_code =  "93";
 
        ////////// Physical parameters:
 
@@ -131,7 +131,7 @@ eNBs =
     };
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.13.11";
+    mme_ip_address      = ( { ipv4       = "192.168.12.70";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -141,10 +141,10 @@ eNBs =
     NETWORK_INTERFACES :
     {
       ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
-      ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.13.10/24";
+      ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.212/24";
 
       ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
-      ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.13.10/24";
+      ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.212/24";
       ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf
index 212f341580f6acbab2cb4fc8994e38beb4f6b47e..3ce32398f7ac5d6fe42720447565c0fb6326213a 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf
@@ -17,7 +17,7 @@ eNBs =
 
     mobile_country_code =  "208";
 
-    mobile_network_code =  "92";
+    mobile_network_code =  "93";
 
        ////////// Physical parameters:
 
@@ -31,7 +31,7 @@ eNBs =
         downlink_frequency      			      = 2680000000L;
         uplink_frequency_offset 			      = -120000000;
         Nid_cell					      = 0;
-        N_RB_DL                 			      = 50;
+        N_RB_DL                 			      = 25;
         Nid_cell_mbsfn          			      = 0;
         nb_antennas_tx          			      = 1;
         nb_antennas_rx          			      = 1;
@@ -131,7 +131,7 @@ eNBs =
     };
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "10.0.1.1";
+    mme_ip_address      = ( { ipv4       = "192.168.12.171";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -140,11 +140,11 @@ eNBs =
 
     NETWORK_INTERFACES :
     {
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth3";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "10.0.1.229/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth2";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.80/24";
 
-        ENB_INTERFACE_NAME_FOR_S1U               = "eth3";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "10.0.1.229/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth2";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.80/24";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 19e1c5b65366b88df81e559d95aaa92ef9ba8569..f09f5d35dbcaae4a9142a2a61aebcd568eeab14c 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -289,6 +289,8 @@ double bw = 10.0e6;
 
 static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
 
+int chain_offset=0;
+
 #ifndef EXMIMO
 char ref[128] = "internal";
 char channels[128] = "0";
@@ -418,7 +420,7 @@ void help (void) {
   printf("  --ue-txgain set UE TX gain\n");
   printf("  --ue-scan_carrier set UE to scan around carrier\n");
   printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
-  printf("  -C Set the downlink frequecny for all Component carrier\n");
+  printf("  -C Set the downlink frequency for all component carriers\n");
   printf("  -d Enable soft scope and L1 and L2 stats (Xforms)\n");
   printf("  -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n");
   printf("  -g Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n");
@@ -432,6 +434,7 @@ void help (void) {
   printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
   printf("  -S Skip the missed slots/subframes \n");    
   printf("  -t Set the maximum uplink MCS\n");
+  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
   printf("  -U Set the lte softmodem as a UE\n");
   printf("  -W Enable L2 wireshark messages on localhost \n");
   printf("  -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n");
@@ -966,6 +969,25 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
 	 phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset++] = 0x00010001;
        }
      }
+
+     if ((((phy_vars_eNB->lte_frame_parms.tdd_config==0) ||
+	  (phy_vars_eNB->lte_frame_parms.tdd_config==1) ||
+	  (phy_vars_eNB->lte_frame_parms.tdd_config==2) ||
+	  (phy_vars_eNB->lte_frame_parms.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,phy_vars_eNB->N_TA_offset,slot_offset);
+       for (i=0; i<phy_vars_eNB->N_TA_offset; i++) {
+	 tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2;
+	 if (tx_offset<0)
+	   tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti;
+	 
+	 if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti))
+	   tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti;
+	 
+	 phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset] = 0x00000000;
+       }
+     }
     }
   }
 }
@@ -2037,7 +2059,7 @@ static void get_options (int argc, char **argv)
     {NULL, 0, NULL, 0}
   };
 
-  while ((c = getopt_long (argc, argv, "C:dK:g:F:G:hqO:m:SUVRM:r:P:Ws:t:x:",long_options,NULL)) != -1) {
+  while ((c = getopt_long (argc, argv, "a:C:dK:g:F:G:hqO:m:SUVRM:r:P:Ws:t:Tx:",long_options,NULL)) != -1) {
     switch (c) {
     case LONG_OPTION_MAXPOWER:
       tx_max_power[0]=atoi(optarg);
@@ -2125,6 +2147,10 @@ static void get_options (int argc, char **argv)
 
       break;
 
+    case 'a':
+      chain_offset = atoi(optarg);
+      break;
+
     case 'd':
 #ifdef XFORMS
       do_forms=1;
@@ -2302,8 +2328,13 @@ static void get_options (int argc, char **argv)
         printf("Transmission mode > 2 (%d) not supported for the moment\n",transmission_mode);
         exit(-1);
       }
+      break;
 
+    case 'T':
+      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
+	frame_parms[CC_id]->frame_type = TDD;
       break;
+
     case 'h':
       help ();
       exit (-1);
@@ -2463,12 +2494,10 @@ int main( int argc, char **argv )
   memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
   set_latency_target();
 
-
-
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS));
     /* Set some default values that may be overwritten while reading options */
-    frame_parms[CC_id]->frame_type         = FDD; /* TDD */
+    frame_parms[CC_id]->frame_type          = FDD;
     frame_parms[CC_id]->tdd_config          = 3;
     frame_parms[CC_id]->tdd_config_S        = 0;
     frame_parms[CC_id]->N_RB_DL             = 100;
@@ -2816,7 +2845,7 @@ int main( int argc, char **argv )
       }
 
 #else
-      //already taken care of in lte-softmodem
+      //already taken care of in lte-softmodem.c
       PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
 #endif
 
@@ -2863,7 +2892,12 @@ int main( int argc, char **argv )
       openair0_cfg[card].tx_bw = 1.5e6;
       openair0_cfg[card].rx_bw = 1.5e6;
     }
-    
+
+    if (frame_parms[0]->frame_type==TDD)
+      openair0_cfg[card].duplex_mode = duplex_mode_TDD;
+    else //FDD
+      openair0_cfg[card].duplex_mode = duplex_mode_FDD;
+
 #ifdef ETHERNET
 
     //calib needed
@@ -3025,7 +3059,7 @@ int main( int argc, char **argv )
 
   for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     rf_map[CC_id].card=0;
-    rf_map[CC_id].chain=CC_id;
+    rf_map[CC_id].chain=CC_id+chain_offset;
   }
 
   // connect the TX/RX buffers