diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 96ec7e27593e2f16d704453dcc88450ee502a831..3d9b581a63ee6f7fb0824966a9d505fbfd2b81cd 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -733,7 +733,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
     T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4));
   int sf_extension = 0;
   int siglen=fp->get_samples_per_slot(slot,fp);
-  int flags = 0;
+  int flags=0,flags_burst=0,flags_gpio=0;
 
   if (cfg->cell_config.frame_duplex_type.value == TDD && !get_softmodem_params()->continuous_tx) {
     int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame);
@@ -760,39 +760,37 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
       }
 
       //+ ru->end_of_burst_delay;
-      flags = 3; // end of burst
+      flags_burst = 3; // end of burst
     } else if (slot_type == NR_DOWNLINK_SLOT) {
       int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame);
       int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame);
       if (prevslot_type == NR_UPLINK_SLOT) {
-        flags = 2; // start of burst
+        flags_burst = 2; // start of burst
         sf_extension = ru->sf_extension;
       } else if (nextslot_type == NR_UPLINK_SLOT) {
-        flags = 3; // end of burst
+        flags_burst = 3; // end of burst
       } else {
-        flags = 1; // middle of burst
+        flags_burst = 1; // middle of burst
       }
     }
   } else { // FDD
     if (proc->first_tx == 1) {
-      flags = 2; // start of burst
+      flags_burst = 2; // start of burst
     } else {
-      flags = 1; // middle of burst
+      flags_burst = 1; // middle of burst
     }
   }
 
-  if (flags) {
     if (fp->freq_range==nr_FR2) {
-      // the beam index is written in bits 8-10 of the flags
-      // bit 11 enables the gpio programming
       // currently we switch beams every 10 slots (should = 1 TDD period in FR2) and we take the beam index of the first symbol of the first slot of this period
       int beam=0;
 
       if (slot%10==0) {
         if ( ru->common.beam_id && (ru->common.beam_id[0][slot*fp->symbols_per_slot] < 8)) {
-          beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 8;
+          beam = ru->common.beam_id[0][slot*fp->symbols_per_slot];
         }
       }
+      LOG_D(HW,"slot %d, beam %d\n",slot,ru->common.beam_id[0][slot*fp->symbols_per_slot]);
 
       /*
       if (slot==0 || slot==40) beam=0|8;
@@ -800,9 +798,12 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
       if (slot==20 || slot==60) beam=2|8;
       if (slot==30 || slot==70) beam=3|8;
       */
-      flags |= beam<<8;
-      LOG_D(HW,"slot %d, beam %d\n",slot,ru->common.beam_id[0][slot*fp->symbols_per_slot]);
+
+      flags_gpio = beam & 0x1000; //enable change of gpio
     }
+
+    flags = flags_burst | flags_gpio<<4;
+    
     if (proc->first_tx == 1) proc->first_tx = 0;
 
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags );
@@ -825,7 +826,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
 	  (long long unsigned int)(timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension),frame,slot,proc->frame_tx_unwrap,slot, flags, siglen+sf_extension, txs,10*log10((double)signal_energy(txp[0],siglen+sf_extension)));
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
       //AssertFatal(txs == 0,"trx write function error %d\n", txs);
-  }
+  
 }
 
 // this is for RU with local RF unit
diff --git a/maketags b/maketags
index 5c7232320a0abea10d81e4484aeffbdd2eccd623..87f445dd217b86d5a759854d840b97b9ebc1feb4 100755
--- a/maketags
+++ b/maketags
@@ -1,4 +1,4 @@
 #!/bin/sh
 echo "building ctags for openair1 and openair2 ..."
-ctags -e -R  --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables
+ctags -e -R  --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables sdr
 
diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h
index 3733914ef42debc75d7c9652ebb77b46a3407b0c..2db3494956951e7fe962e7abac69ad638e264fcc 100644
--- a/radio/COMMON/common_lib.h
+++ b/radio/COMMON/common_lib.h
@@ -315,7 +315,7 @@ typedef struct {
   int cc;
   signed char first_packet;
   signed char last_packet;
-  int flags_msb;
+  int flags_gpio;
 } openair0_write_package_t;
 
 typedef struct {
diff --git a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp
index 1f6fbd34b13b3b26f3604bf9f0eae4fddfc322af..374411734c5acfc37b667a0e78eb8c0c29fb023e 100644
--- a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -59,7 +59,6 @@
 /** @addtogroup _USRP_PHY_RF_INTERFACE_
  * @{
  */
-int gpio789=0;
 extern int usrp_tx_thread;
 
 
@@ -88,6 +87,9 @@ typedef struct {
   //! TX forward samples. We use usrp_time_offset to get this value
   int tx_forward_nsamps; //166 for 20Mhz
 
+  //! gpio bank to use
+  std::string gpio_bank;
+  
   // --------------------------------
   // Debug and output control
   // --------------------------------
@@ -258,27 +260,41 @@ static int sync_to_gps(openair0_device *device) {
   return EXIT_SUCCESS;
 }
 
+#define ATR_MASK 0x7f //pins controlled by ATR
+#define ATR_RX   0x50 //data[4] and data[6]
+#define ATR_XX   0x20 //data[5]
+#define MAN_MASK ATR_MASK^0xFFF //manually controlled pins 
+
 /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
     @param device pointer to the device structure specific to the RF hardware target
 */
 static int trx_usrp_start(openair0_device *device) {
   usrp_state_t *s = (usrp_state_t *)device->priv;
 
-  if (device->type != USRP_X400_DEV) {
-    // setup GPIO for TDD, GPIO(4) = ATR_RX
-    //set data direction register (DDR) to output
-    s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff);
-    //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually)
-    s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff);
-    //set pins 4 (RX_TX_Switch) and 6 (Shutdown PA) to 1 when the radio is only receiving (ATR_RX)
-    s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f);
-    // set pin 5 (Shutdown LNA) to 1 when the radio is transmitting and receiveing (ATR_XX)
-    // (we use full duplex here, because our RX is on all the time - this might need to change later)
-    s->usrp->set_gpio_attr("FP0", "ATR_XX", (1<<5), 0x7f);
-    // set the output pins to 1
-    s->usrp->set_gpio_attr("FP0", "OUT", 7<<7, 0xf80);
-  }
+  s->gpio_bank = "FP0"; //good for B210, X310 and N310
 
+#if UHD_VERSION>4000000
+  if (device->type == USRP_X400_DEV) {
+    // Set every pin on GPIO0 to be controlled by DB0_RF0
+    std::vector<std::string> sxx{12, "DB0_RF0"};
+    s->gpio_bank = "GPIO0";
+    s->usrp->set_gpio_src(s->gpio_bank, sxx);
+  }
+#endif  
+
+  // setup GPIO for TDD, GPIO(4) = ATR_RX
+  //set data direction register (DDR) to output
+  s->usrp->set_gpio_attr(s->gpio_bank, "DDR", 0xfff, 0xfff);
+  //set bits to be controlled automatically by ATR 
+  s->usrp->set_gpio_attr(s->gpio_bank, "CTRL", ATR_MASK, 0xfff);
+  //set bits to 1 when the radio is only receiving (ATR_RX)
+  s->usrp->set_gpio_attr(s->gpio_bank, "ATR_RX", ATR_RX, ATR_MASK);
+  // set bits to 1 when the radio is transmitting and receiveing (ATR_XX)
+  // (we use full duplex here, because our RX is on all the time - this might need to change later)
+  s->usrp->set_gpio_attr(s->gpio_bank, "ATR_XX", ATR_XX, ATR_MASK);
+  // set all other pins to manual
+  s->usrp->set_gpio_attr(s->gpio_bank, "OUT", MAN_MASK, 0xfff);
+  
   s->wait_for_first_pps = 1;
   s->rx_count = 0;
   s->tx_count = 0;
@@ -373,8 +389,8 @@ static int trx_usrp_write(openair0_device *device,
   usrp_state_t *s = (usrp_state_t *)device->priv;
   int nsamps2;  // aligned to upper 32 or 16 byte boundary
 
-  int flags_lsb = flags&0xff;
-  int flags_msb = (flags>>8)&0xff;
+  int flags_burst = flags&0xf;
+  int flags_gpio = (flags>>4)&0x1fff; //MSB to enable sending GPIO command, 12 LSB carry GPIO values
 
   int end;
   openair0_thread_t *write_thread = &device->write_thread;
@@ -384,28 +400,28 @@ static int trx_usrp_write(openair0_device *device,
 
   bool first_packet_state=false,last_packet_state=false;
 
-    if (flags_lsb == 2) { // start of burst
+    if (flags_burst == 2) { // start of burst
       //      s->tx_md.start_of_burst = true;
       //      s->tx_md.end_of_burst = false;
       first_packet_state = true;
       last_packet_state  = false;
-    } else if (flags_lsb == 3) { // end of burst
+    } else if (flags_burst == 3) { // end of burst
       //s->tx_md.start_of_burst = false;
       //s->tx_md.end_of_burst = true;
       first_packet_state = false;
       last_packet_state  = true;
-    } else if (flags_lsb == 4) { // start and end
+    } else if (flags_burst == 4) { // start and end
     //  s->tx_md.start_of_burst = true;
     //  s->tx_md.end_of_burst = true;
       first_packet_state = true;
       last_packet_state  = true;
-    } else if (flags_lsb==1) { // middle of burst
+    } else if (flags_burst==1) { // middle of burst
     //  s->tx_md.start_of_burst = false;
     //  s->tx_md.end_of_burst = false;
       first_packet_state = false;
       last_packet_state  = false;
     }
-    else if (flags_lsb==10) { // fail safe mode
+    else if (flags_burst==10) { // fail safe mode
      // s->tx_md.has_time_spec = false;
      // s->tx_md.start_of_burst = false;
      // s->tx_md.end_of_burst = true;
@@ -449,12 +465,11 @@ static int trx_usrp_write(openair0_device *device,
     s->tx_count++;
 
 VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO,1);
-    // bit 3 enables gpio (for backward compatibility)
-    if (flags_msb&8) {
-      // push GPIO bits 7-9 from flags_msb
-      int gpio789=(flags_msb&7)<<7;
+    // bit 13 enables gpio 
+    if (flags_gpio&0x1000) {
+      // push GPIO bits 
       s->usrp->set_command_time(s->tx_md.time_spec);
-      s->usrp->set_gpio_attr("FP0", "OUT", gpio789, 0x380);
+      s->usrp->set_gpio_attr(s->gpio_bank, "OUT", flags_gpio, MAN_MASK);
       s->usrp->clear_command_time();
     }
 VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO,0);
@@ -489,7 +504,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI
     write_package[end].cc           = cc;
     write_package[end].first_packet = first_packet_state;
     write_package[end].last_packet  = last_packet_state;
-    write_package[end].flags_msb    = flags_msb;
+    write_package[end].flags_gpio    = flags_gpio;
     for (int i = 0; i < cc; i++)
       write_package[end].buff[i]    = buff[i];
     write_thread->count_write++;
@@ -526,7 +541,7 @@ void *trx_usrp_write_thread(void * arg){
   int                cc;
   signed char        first_packet;
   signed char        last_packet;
-  int                flags_msb;
+  int                flags_gpio;
 
   while(1){
     pthread_mutex_lock(&write_thread->mutex_write);
@@ -544,7 +559,7 @@ void *trx_usrp_write_thread(void * arg){
     cc           = write_package[start].cc;
     first_packet = write_package[start].first_packet;
     last_packet  = write_package[start].last_packet;
-    flags_msb    = write_package[start].flags_msb;
+    flags_gpio    = write_package[start].flags_gpio;
     write_thread->start = (write_thread->start + 1)% MAX_WRITE_THREAD_PACKAGE;
     write_thread->count_write--;
     pthread_mutex_unlock(&write_thread->mutex_write);
@@ -589,11 +604,10 @@ void *trx_usrp_write_thread(void * arg){
     s->tx_count++;
 
     // bit 3 enables gpio (for backward compatibility)
-    if (flags_msb&8) {
-      // push GPIO bits 7-9 from flags_msb
-      int gpio789=(flags_msb&7)<<7;
+    if (flags_gpio&0x1000) {
+      // push GPIO bits 
       s->usrp->set_command_time(s->tx_md.time_spec);
-      s->usrp->set_gpio_attr("FP0", "OUT", gpio789, 0x380);
+      s->usrp->set_gpio_attr(s->gpio_bank, "OUT", flags_gpio, MAN_MASK);
       s->usrp->clear_command_time();
     }
 
@@ -740,11 +754,6 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
   s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate);
   *ptimestamp = s->rx_timestamp;
 
-  // push GPIO bits 7-9 from flags_msb
-   /*s->usrp->set_command_time(uhd::time_spec_t::from_ticks((s->rx_timestamp+(2*nsamps)),s->sample_rate));
-   s->usrp->set_gpio_attr("FP0", "OUT", gpio789<<7, 0x380);
-   s->usrp->clear_command_time();
-   gpio789 = (gpio789+1)&7;*/
   recplay_state_t *recPlay=device->recplay_state;
 
   if ( recPlay != NULL) { // record mode