diff --git a/src/constants.h b/src/constants.h
index b8df1d7c421f9aa4d4ac650c7730c42e52fdc762..cf60b6a4006f107d1970bd643c4b4958640d92e1 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -45,5 +45,7 @@
 #define C_Q_fft 2
 #define C_N_sub 512
 #define C_N_beamsets 2
+#define C_N_step 1
+#define C_N_crosslets_max 7
 
 #endif
diff --git a/src/fpga.cpp b/src/fpga.cpp
index bd03ebcc0b9f74a3d7a69d110e54175f2fa9c0c0..65c122ad21f89037d614d7791d78410922b550b4 100644
--- a/src/fpga.cpp
+++ b/src/fpga.cpp
@@ -84,6 +84,20 @@ Fpga::Fpga(list<class Node*>& nodelist)
     // pointMap->add_register("FPGA_bst_offload_nof_beamlets_per_packet_R",     "fpga/bst_offload_nof_beamlets_per_packet",    nodes.size(), C_N_beamsets, "RO", REG_FORMAT_UINT32);
     // pointMap->add_register("FPGA_bst_offload_nof_beamlets_per_packet_RW",    "fpga/bst_offload_nof_beamlets_per_packet",    nodes.size(), C_N_beamsets, "RW", REG_FORMAT_UINT32);
 
+    pointMap->add_register("FPGA_xst_subband_select_R",                      "fpga/xst_subband_select",                     nodes.size(), 1+C_N_crosslets_max, "RO", REG_FORMAT_UINT32);
+    pointMap->add_register("FPGA_xst_subband_select_RW",                     "fpga/xst_subband_select",                     nodes.size(), 1+C_N_crosslets_max, "RW", REG_FORMAT_UINT32);
+    pointMap->add_register("FPGA_xst_integration_interval_R",                "fpga/xst_integration_interval",               nodes.size(), 1, "RO", REG_FORMAT_DOUBLE);
+    pointMap->add_register("FPGA_xst_integration_interval_RW",               "fpga/xst_integration_interval",               nodes.size(), 1, "RW", REG_FORMAT_DOUBLE);
+    pointMap->add_register("FPGA_xst_processing_enable_R",                   "fpga/xst_processing_enable",                  nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
+    pointMap->add_register("FPGA_xst_processing_enable_RW",                  "fpga/xst_processing_enable",                  nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
+    pointMap->add_register("FPGA_xst_offload_enable_R",                      "fpga/xst_offload_enable",                     nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
+    pointMap->add_register("FPGA_xst_offload_enable_RW",                     "fpga/xst_offload_enable",                     nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
+    pointMap->add_register("FPGA_xst_offload_hdr_eth_destination_mac_R",     "fpga/xst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RO", REG_FORMAT_STRING);
+    pointMap->add_register("FPGA_xst_offload_hdr_eth_destination_mac_RW",    "fpga/xst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RW", REG_FORMAT_STRING);
+    pointMap->add_register("FPGA_xst_offload_hdr_ip_destination_address_R",  "fpga/xst_offload_hdr_ip_destination_address", nodes.size(), 1, "RO", REG_FORMAT_STRING);
+    pointMap->add_register("FPGA_xst_offload_hdr_ip_destination_address_RW", "fpga/xst_offload_hdr_ip_destination_address", nodes.size(), 1, "RW", REG_FORMAT_STRING);
+    pointMap->add_register("FPGA_xst_offload_hdr_udp_destination_port_R",    "fpga/xst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RO", REG_FORMAT_UINT16);
+    pointMap->add_register("FPGA_xst_offload_hdr_udp_destination_port_RW",   "fpga/xst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RW", REG_FORMAT_UINT16);
 
     pointMap->add_register("FPGA_processing_enable_R",                       "fpga/processing_enable",                      nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
     pointMap->add_register("FPGA_processing_enable_RW",                      "fpga/processing_enable",                      nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
@@ -205,6 +219,9 @@ bool Fpga::point(TermOutput& termout, const char cmd, const string addr,
                  const unsigned int *data, const int nvalues)
 {
     bool ret, retval = false;
+    uint mask_cnt = 0;
+    uint exec_cnt = 0;
+    uint reply_cnt = 0;
     uint retcnt = 0;
 
     termout.clear();
@@ -241,6 +258,8 @@ bool Fpga::point(TermOutput& termout, const char cmd, const string addr,
     }
 
     for (uint idx = 0; idx<nodes.size(); idx++) {
+
+        mask_cnt++;
         auto node = select_node(nodes[idx]);
         // if (node->getEnabled() == false) { continue; }
 
@@ -258,13 +277,18 @@ bool Fpga::point(TermOutput& termout, const char cmd, const string addr,
             if (cmd == 'W') {
                 if (format == REG_FORMAT_STRING) {
                     didx = idx * nof_values * (SIZE1STRING/4);
-                } else {
+                }
+                else if ((format == REG_FORMAT_UINT64) || (format == REG_FORMAT_INT64) || (format == REG_FORMAT_DOUBLE)) {
+                    didx = idx * nof_values * 2;
+                }
+                else {
                     didx = idx * nof_values;
                 }
             }
             if ((ret = node->exec_cmd(cmd, relative_addr, type, instance,
                                       &data[didx], nof_values, format))) {
                 retcnt++;
+                exec_cnt++;
             }
         } catch (exception& e) {
             cerr << e.what() << endl;
@@ -287,6 +311,7 @@ bool Fpga::point(TermOutput& termout, const char cmd, const string addr,
         try {
             if ((ret = node->exec_reply(termresults))) {
                 retcnt++;
+                reply_cnt++;
             }
         } catch (exception& e) {
             cerr << e.what() << endl;
diff --git a/src/node.cpp b/src/node.cpp
index c2856b5389da2a1c4763392909b487bbb99ea1b7..f2dadc60ad4808843ffed6acd37d6f05ae13394e 100644
--- a/src/node.cpp
+++ b/src/node.cpp
@@ -294,8 +294,12 @@ bool Node::exec_cmd(const char cmd, const string relative_addr,
     if (cmd == 'W') {
         if (format == REG_FORMAT_STRING) {
             memcpy((void *)p.data, (void *)data, nvalues*SIZE1STRING);
-        } else {
-            memcpy((void *)p.data, (void *)data, nvalues*sizeof(unsigned int));
+        } 
+        else if ((format == REG_FORMAT_UINT64) || (format == REG_FORMAT_INT64) || (format == REG_FORMAT_DOUBLE)) {
+            memcpy((void *)p.data, (void *)data, nvalues*sizeof(uint64_t));
+        }
+        else {
+            memcpy((void *)p.data, (void *)data, nvalues*sizeof(uint32_t));
         }
         // cout << " p.relative_addr=" << p.relative_addr 
         //      << " p.nvalues=" << p.nvalues
diff --git a/src/opcua/ua_server.cpp b/src/opcua/ua_server.cpp
index 29632ef3034f611cbc25418a951dda877ed381c1..9ef6bb421f23bab3a210122f7564d3786f2b729b 100644
--- a/src/opcua/ua_server.cpp
+++ b/src/opcua/ua_server.cpp
@@ -125,6 +125,7 @@ static UA_StatusCode ua_read_DataSource(UA_Server *server,
             cerr << "ua_read_DataSource error: " << e.what() << endl;
         }
 
+
         // TR_* has only scalars
         switch (ntype.identifier.numeric - 1) {
             case UA_TYPES_STRING: {
@@ -1077,9 +1078,13 @@ static void ua_add_Variable_boolean(UA_Server *server, string regname, unsigned
     }
 }
 
-static void ua_add_Variable(UA_Server *server, string regname, int format, unsigned int size, string perm, bool is_scalar)
+static void ua_add_Variable(UA_Server *server, string regname, int format, unsigned int size, string perm)
 {
     cout << "regname=" << regname << " format=" << format << " size=" << size << endl;
+    bool is_scalar = false;
+    if (size == 1) {
+        is_scalar = true;
+    }
     switch (format) {
         case REG_FORMAT_STRING: {
             ua_add_Variable_string(server, regname, size, perm, is_scalar);
@@ -1135,7 +1140,7 @@ int ua_server_init(bool warm_start)
             int format = pointmap->getFormat(m);
             unsigned int size = pointmap->getNodesSize(m) * pointmap->getDataSize(m);
             string perm = pointmap->getPerm(m);
-            ua_add_Variable(mUaServer, m, format, size, perm, false);
+            ua_add_Variable(mUaServer, m, format, size, perm);
         }
 
         UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "UA Server add translatorMap");
@@ -1145,7 +1150,7 @@ int ua_server_init(bool warm_start)
             int format = trmap->getFormat(m);
             unsigned int size = pointmap->getNodesSize(m) * pointmap->getDataSize(m);
             string perm = trmap->getPerm(m);
-            ua_add_Variable(mUaServer, m, format, size, perm, true);
+            ua_add_Variable(mUaServer, m, format, size, perm);
         }
     }
     return 0;
diff --git a/src/periph/fpga.cpp b/src/periph/fpga.cpp
index a32002def23caa2c52a0bac9e6b23feeff3996bf..1d354e9c5f15867047340cb911405e362b2b5d08 100644
--- a/src/periph/fpga.cpp
+++ b/src/periph/fpga.cpp
@@ -74,7 +74,8 @@ Periph_fpga::Periph_fpga(string ipaddr, string expected_design_name, uint expect
     my_jesd_csr_rbd_count {0},
     my_jesd_csr_dev_syncn {0},
     my_jesd_rx_err0 {0},
-    my_jesd_rx_err1 {0}
+    my_jesd_rx_err1 {0},
+    my_xst_processing_enable(false)
 {
     ucp = new UCP(ipaddr);
 
@@ -123,6 +124,14 @@ Periph_fpga::Periph_fpga(string ipaddr, string expected_design_name, uint expect
     registerMap->add_register("fpga/bst_offload_hdr_udp_destination_port",   "-", 1, 2, "RW", REG_FORMAT_UINT16);
     registerMap->add_register("fpga/bst_offload_nof_beamlets_per_packet",    "-", 1, 2, "RW", REG_FORMAT_UINT32);
 
+    registerMap->add_register("fpga/xst_subband_select",                     "-", 1, 1+C_N_crosslets_max, "RW", REG_FORMAT_UINT32);
+    registerMap->add_register("fpga/xst_integration_interval",               "-", 1, 1, "RW", REG_FORMAT_DOUBLE);
+    registerMap->add_register("fpga/xst_processing_enable",                  "-", 1, 1, "RW", REG_FORMAT_BOOLEAN);
+    registerMap->add_register("fpga/xst_offload_enable",                     "-", 1, 1, "RW", REG_FORMAT_BOOLEAN);
+    registerMap->add_register("fpga/xst_offload_hdr_eth_destination_mac",    "-", 1, 1, "RW", REG_FORMAT_STRING);
+    registerMap->add_register("fpga/xst_offload_hdr_ip_destination_address", "-", 1, 1, "RW", REG_FORMAT_STRING);
+    registerMap->add_register("fpga/xst_offload_hdr_udp_destination_port",   "-", 1, 1, "RW", REG_FORMAT_UINT16);
+
     registerMap->add_register("fpga/sdp_info_station_id",                    "-", 1, 1, "RW", REG_FORMAT_UINT32);
     registerMap->add_register("fpga/sdp_info_observation_id",                "-", 1, 1, "RW", REG_FORMAT_UINT32);
     registerMap->add_register("fpga/sdp_info_nyquist_sampling_zone_index",   "-", 1, 1, "RW", REG_FORMAT_UINT32);
@@ -360,6 +369,12 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
 
     termout.datatype = format;
     termout.nof_vals = 0;
+
+    if (addr == "fpga/enable_mask") {
+        retval = read_fpga_enable_mask(termout, format);
+        return retval;
+    }
+
     if (!Enabled) { return false; }
 
     if (type == "mm") {
@@ -440,6 +455,27 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
         else if (addr == "fpga/bst_offload_nof_beamlets_per_packet") {
             retval = read_bst_offload_nof_beamlets_per_packet(termout, format);
         }
+        else if (addr == "fpga/xst_offload_enable") {
+            retval = read_xst_offload_enable(termout, format);
+        }
+        else if (addr == "fpga/xst_offload_hdr_eth_destination_mac") {
+            retval = read_xst_offload_hdr_eth_destination_mac(termout, format);
+        }
+        else if (addr == "fpga/xst_offload_hdr_ip_destination_address") {
+            retval = read_xst_offload_hdr_ip_destination_address(termout, format);
+        }
+        else if (addr == "fpga/xst_offload_hdr_udp_destination_port") {
+            retval = read_xst_offload_hdr_udp_destination_port(termout, format);
+        }
+        else if (addr == "fpga/xst_processing_enable") {
+            retval = read_xst_processing_enable(termout, format);
+        }
+        else if (addr == "fpga/xst_integration_interval") {
+            retval = read_xst_integration_interval(termout, format);
+        }
+        else if (addr == "fpga/xst_subband_select") {
+            retval = read_xst_subband_select(termout, format);
+        }
         else if (addr == "fpga/processing_enable") {
             retval = read_processing_enable(termout, format);
         }
@@ -519,6 +555,11 @@ bool Periph_fpga::write(TermOutput& termout, const string addr, const string typ
 {
     bool retval = false;
 
+    if (addr == "fpga/enable_mask") {
+        retval = write_fpga_enable_mask(data);
+        return retval;
+    }
+
     if (!Enabled) { return false; }
 
     uint32_t *data_ptr = (uint32_t *)data;
@@ -558,9 +599,6 @@ bool Periph_fpga::write(TermOutput& termout, const string addr, const string typ
             // write to FIFO
             retval = Write("mm/0/REG_MMDP_DATA/data", data_ptr);
         }
-        else if (addr == "fpga/enable_mask") {
-            retval = write_fpga_enable_mask(data);
-        }
         else if (addr == "fpga/scrap") {
             retval = write_fpga_scrap(data_ptr);
         }
@@ -597,6 +635,27 @@ bool Periph_fpga::write(TermOutput& termout, const string addr, const string typ
         else if (addr == "fpga/bst_offload_nof_beamlets_per_packet") {
             retval = write_bst_offload_nof_beamlets_per_packet(data_ptr);
         }
+        else if (addr == "fpga/xst_offload_enable") {
+            retval = write_xst_offload_enable(data_ptr);
+        }
+        else if (addr == "fpga/xst_offload_hdr_eth_destination_mac") {
+            retval = write_xst_offload_hdr_eth_destination_mac(data);
+        }
+        else if (addr == "fpga/xst_offload_hdr_ip_destination_address") {
+            retval = write_xst_offload_hdr_ip_destination_address(data);
+        }
+        else if (addr == "fpga/xst_offload_hdr_udp_destination_port") {
+            retval = write_xst_offload_hdr_udp_destination_port(data_ptr);
+        }
+        else if (addr == "fpga/xst_processing_enable") {
+            retval = write_xst_processing_enable(data_ptr);
+        }
+        else if (addr == "fpga/xst_integration_interval") {
+            retval = write_xst_integration_interval(data_ptr);
+        }
+        else if (addr == "fpga/xst_subband_select") {
+            retval = write_xst_subband_select(data_ptr);
+        }
         else if (addr == "fpga/processing_enable") {
             retval = write_processing_enable(data_ptr);
         }
@@ -1143,9 +1202,7 @@ bool Periph_fpga::read_bst_offload_enable(TermOutput& termout, int format)
     for (uint32_t i=0; i<C_N_beamsets; i++) {
         memset((void *)data, 0, sizeof(data));
         regname = "mm/" + to_string(i) + "/REG_STAT_ENABLE_BST/0/enable";
-        if (Read(regname, data) == false) {
-           retval = false;
-        }
+        retval &= Read(regname, data);
 
         bool select = (bool)data[0];
         *_ptr = select;
@@ -1162,9 +1219,7 @@ bool Periph_fpga::write_bst_offload_enable(uint32_t *data)
     string regname;
     for (uint32_t i=0; i<C_N_beamsets; i++) {
         regname = "mm/" + to_string(i) + "/REG_STAT_ENABLE_BST/0/enable";
-        if (Write(regname, &data[i]) == false) {
-            retval = false;
-        }
+        retval &= Write(regname, &data[i]);
     }
     return retval;
 }
@@ -1182,9 +1237,7 @@ bool Periph_fpga::read_bst_offload_hdr_eth_destination_mac(TermOutput& termout,
     for (uint32_t i=0; i<C_N_beamsets; i++) {
         memset((void *)data, 0, sizeof(data));
         regname = "mm/" + to_string(i) + "/REG_STAT_HDR_DAT_BST/0/eth_destination_mac";
-        if (Read(regname, data) == false) {
-            retval = false;
-        }
+        retval &= Read(regname, data);
         uint64_t mac = (uint64_t)data[1] << 32 | data[0];
 
         mac_ss.clear();
@@ -1196,7 +1249,7 @@ bool Periph_fpga::read_bst_offload_hdr_eth_destination_mac(TermOutput& termout,
             }
         }
         mac_str = mac_ss.str();
-        cout << "bst_eth_destination_mac: " << regname << ", data[0]=" << to_string(data[0]) << ", str=" << mac_str << ", retval=" << retval << endl;
+        // cout << "bst_eth_destination_mac: " << regname << ", data[0]=" << to_string(data[0]) << ", str=" << mac_str << ", retval=" << retval << endl;
         strcpy(&(termout.val[i*SIZE1STRING]), mac_str.c_str());
     }
     termout.nof_vals = C_N_beamsets;
@@ -1222,15 +1275,13 @@ bool Periph_fpga::write_bst_offload_hdr_eth_destination_mac(const char *data)
         ss << ds;
         ss >> setbase(16) >> m0 >> sep >> m1 >> sep >> m2 >> sep >> m3 >> sep >> m4 >> sep >> m5;
         if (ss.fail() || ss.bad()) {
-            cout << "parse error in write_sst_offload_hdr_eth_destination_mac (" << ds << ")" << endl;
+            cout << "parse error in write_bst_offload_hdr_eth_destination_mac (" << ds << ")" << endl;
             return false;
         }
         mac[1] = (m0 << 8) + (m1 << 0);
         mac[0] = (m2 << 24) + (m3 << 16) + (m4 << 8) + m5;
         // cout << "mac=" << mac[1] << ", " << mac[0] << endl;
-        if (Write(regname, mac) == false) {
-            retval = false;
-        }
+        retval &= Write(regname, mac);
     }
     return retval;
 }
@@ -1246,9 +1297,7 @@ bool Periph_fpga::read_bst_offload_hdr_ip_destination_address(TermOutput& termou
     for (uint32_t i=0; i<C_N_beamsets; i++) {
         memset((void *)data, 0, sizeof(data));
         regname = "mm/" + to_string(i) + "/REG_STAT_HDR_DAT_BST/0/ip_destination_address";
-        if (Read(regname, data) == false) {
-            retval = false;
-        }
+        retval &= Read(regname, data);
         ip_ss.clear();
         ip_ss.str("");
         for (int j=3; j>=0; j--) {
@@ -1291,7 +1340,7 @@ bool Periph_fpga::write_bst_offload_hdr_ip_destination_address(const char *data)
         ss >> setbase(10) >> ip3;
         // cout << "ip0=" << to_string(ip0) << " ip1=" << to_string(ip1) << " ip2=" << to_string(ip2) << " ip3=" << to_string(ip3) << endl;
         if (ss.fail() || ss.bad()) {
-            cout << "parse error in write_sst_offload_hdr_ip_destination_address (" << ds << ")" << endl;
+            cout << "parse error in write_bst_offload_hdr_ip_destination_address (" << ds << ")" << endl;
             return false;
         }
         ip[0]  = (ip0 & 0xff) << 24;
@@ -1317,9 +1366,7 @@ bool Periph_fpga::read_bst_offload_hdr_udp_destination_port(TermOutput& termout,
     for (uint32_t i=0; i<C_N_beamsets; i++) {
         memset((void *)data, 0, sizeof(data));
         regname = "mm/" + to_string(i) + "/REG_STAT_HDR_DAT_BST/0/udp_destination_port";
-        if (Read(regname, data) == false) {
-            retval = false;
-        }
+        retval &= Read(regname, data);
         // cout << "read_bst_offload_hdr_udp_destination_port " << i << "=" << data[0] << endl;
         uint16_t port = (uint16_t)data[0];
         *_ptr = port;
@@ -1336,9 +1383,7 @@ bool Periph_fpga::write_bst_offload_hdr_udp_destination_port(uint32_t *data)
     string regname;
     for (uint32_t i=0; i<C_N_beamsets; i++) {
         regname = "mm/" + to_string(i) + "/REG_STAT_HDR_DAT_BST/0/udp_destination_port";
-        if (Write(regname, &data[i]) == false) {
-            retval = false;
-        }
+        retval &= Write(regname, &data[i]);
     }
     return retval;
 }
@@ -1353,9 +1398,7 @@ bool Periph_fpga::read_bst_offload_nof_beamlets_per_packet(TermOutput& termout,
     for (uint32_t i=0; i<C_N_beamsets; i++) {
         memset((void *)data, 0, sizeof(data));
         regname = "mm/" + to_string(i) + "/REG_STAT_HDR_DAT_BST/0/TODO";
-        if (Read(regname, data) == false) {
-            retval = false;
-        }
+        retval &= Read(regname, data);
         int packets = (int)data[i];
         *_ptr = packets;
         _ptr++;
@@ -1378,6 +1421,240 @@ bool Periph_fpga::write_bst_offload_nof_beamlets_per_packet(uint32_t *data)
     return retval;
 }
 
+bool Periph_fpga::read_xst_offload_enable(TermOutput& termout, int format)
+{
+    bool retval = true;
+
+    uint32_t data[20];
+    memset((void *)data, 0, sizeof(data));
+    retval = Read("mm/0/REG_STAT_ENABLE_XST/0/enable", data);
+
+    bool enable = (bool)data[0];
+
+    bool *_ptr = (bool *)termout.val;
+    *_ptr = enable;
+    termout.nof_vals = 1;
+    termout.datatype = format;
+    return retval;
+}
+
+bool Periph_fpga::write_xst_offload_enable(uint32_t *data)
+{
+    return Write("mm/0/REG_STAT_ENABLE_XST/0/enable", data);
+}
+
+
+bool Periph_fpga::read_xst_offload_hdr_eth_destination_mac(TermOutput& termout, int format)
+{
+    bool retval = true;
+
+    uint32_t data[20];
+    memset((void *)data, 0, sizeof(data));
+    retval = Read("mm/0/REG_STAT_HDR_DAT_XST/0/eth_destination_mac", data);
+
+    uint64_t mac = (uint64_t)data[1] << 32 | data[0];
+
+    stringstream mac_ss;
+    for (int i=5; i>=0; i--) {
+        mac_ss << setfill('0') << setw(2) << right << hex << ((mac >> (i * 8)) & 0xff);
+        if (i > 0) {
+            mac_ss << ":";
+        }
+    }
+
+    string mac_str = mac_ss.str();
+    strcpy(termout.val, mac_str.c_str());
+    termout.nof_vals = 1;
+    termout.datatype = format;
+    return retval;
+}
+
+bool Periph_fpga::write_xst_offload_hdr_eth_destination_mac(const char *data)
+{
+    // cout << "data=" << string(data) << endl;
+    char sep;
+    uint32_t m0, m1, m2, m3, m4, m5;
+    uint32_t mac[2] {0, 0};
+    string ds(data);
+    stringstream ss(ds);
+    ss >> setbase(16) >> m0 >> sep >> m1 >> sep >> m2 >> sep >> m3 >> sep >> m4 >> sep >> m5;
+    if (ss.fail() || ss.bad()) {
+        cout << "parse error in write_xst_offload_hdr_eth_destination_mac (" << ds << ")" << endl;
+        return false;
+    }
+    mac[1] = (m0 << 8) + (m1 << 0);
+    mac[0] = (m2 << 24) + (m3 << 16) + (m4 << 8) + m5;
+    // cout << "mac=" << mac[1] << ", " << mac[0] << endl;
+    return Write("mm/0/REG_STAT_HDR_DAT_XST/0/eth_destination_mac", mac);
+}
+
+bool Periph_fpga::read_xst_offload_hdr_ip_destination_address(TermOutput& termout, int format)
+{
+    bool retval = true;
+
+    uint32_t data[20];
+    memset((void *)data, 0, sizeof(data));
+    retval = Read("mm/0/REG_STAT_HDR_DAT_XST/0/ip_destination_address", data);
+
+    stringstream ip_ss;
+    for (int i=3; i>=0; i--) {
+        ip_ss << dec << ((data[0] >> (i * 8)) & 0xff);
+        if (i > 0) {
+            ip_ss << ".";
+        }
+    }
+
+    string ip_str = ip_ss.str();
+    strcpy(termout.val, ip_str.c_str());
+    termout.nof_vals = 1;
+    termout.datatype = format;
+    return retval;
+}
+
+bool Periph_fpga::write_xst_offload_hdr_ip_destination_address(const char *data)
+{
+    char sep;
+    uint ip0, ip1, ip2, ip3;
+    uint32_t ip[1] = {0};
+    string ds(data);
+    cout << "write_ip=[" << ds << "]" << endl;
+    stringstream ss(ds);
+    ss >> setbase(10) >> ip0;
+    ss >> sep;
+    ss >> setbase(10) >> ip1;
+    ss >> sep;
+    ss >> setbase(10) >> ip2;
+    ss >> sep;
+    ss >> setbase(10) >> ip3;
+    // cout << "ip0=" << to_string(ip0) << " ip1=" << to_string(ip1) << " ip2=" << to_string(ip2) << " ip3=" << to_string(ip3) << endl;
+    if (ss.fail() || ss.bad()) {
+        cout << "parse error in write_xst_offload_hdr_ip_destination_address (" << ds << ")" << endl;
+        return false;
+    }
+    ip[0] += (ip0 & 0xff) << 24;
+    ip[0] += (ip1 & 0xff) << 16;
+    ip[0] += (ip2 & 0xff) << 8;
+    ip[0] += ip3 & 0xff;
+    cout << "ip=" << hex << ip[0] << endl;
+    return Write("mm/0/REG_STAT_HDR_DAT_XST/0/ip_destination_address", ip);
+}
+
+bool Periph_fpga::read_xst_offload_hdr_udp_destination_port(TermOutput& termout, int format)
+{
+    bool retval = true;
+
+    uint32_t data[20];
+    memset((void *)data, 0, sizeof(data));
+    retval = Read("mm/0/REG_STAT_HDR_DAT_XST/0/udp_destination_port", data);
+    uint16_t port = (uint16_t)data[0];
+
+    uint16_t *_ptr = (uint16_t *)termout.val;
+    *_ptr = port;
+
+    termout.nof_vals = 1;
+    termout.datatype = format;
+    return retval;
+}
+
+bool Periph_fpga::write_xst_offload_hdr_udp_destination_port(uint32_t *data)
+{
+    return Write("mm/0/REG_STAT_HDR_DAT_XST/0/udp_destination_port", data);
+}
+
+bool Periph_fpga::read_xst_processing_enable(TermOutput& termout, int format)
+{
+    bool retval = true;
+
+    // uint32_t data[20];
+    // memset((void *)data, 0, sizeof(data));
+    // retval = Read("mm/0/REG_BSN_SCHEDULER_XSUB/0/enable", data);
+    // bool processing_enable = (bool)data[0];
+
+    bool *_ptr = (bool *)termout.val;
+    *_ptr = my_xst_processing_enable;
+    termout.nof_vals = 1;
+    termout.datatype = format;
+    return retval;
+}
+
+bool Periph_fpga::write_xst_processing_enable(uint32_t *data)
+{
+    bool retval = true;
+    uint32_t *reg = new uint32_t[2];
+    bool processing_enable = (bool)data[0];
+    uint64_t scheduled_bsn;
+    if (processing_enable == true) {
+        // get bsn and add latency
+        retval &= Read("mm/0/REG_BSN_SCHEDULER_XSUB/0/scheduled_bsn", reg);
+        if (retval == true) {
+            scheduled_bsn = (((uint64_t)reg[1] << 32) + reg[0]);
+            cout << "bsn=" << to_string(scheduled_bsn) << endl;
+            scheduled_bsn += C_BSN_LATENCY;
+            cout << "new bsn=" << to_string(scheduled_bsn) << endl;
+            reg[0] = (uint32_t)(scheduled_bsn & 0xffffffff);
+            reg[1] = (uint32_t)((scheduled_bsn >> 32) & 0xffffffff);
+            // write sheduled bsn
+            retval &= Write("mm/0/REG_BSN_SCHEDULER_XSUB/0/scheduled_bsn", reg);
+            if (retval == true) {
+                my_xst_processing_enable = processing_enable;
+            }
+        }
+    }
+    return retval;
+}
+
+bool Periph_fpga::read_xst_integration_interval(TermOutput& termout, int format)
+{
+    // TODO, fill in if supported in FW
+    bool retval = true;
+
+    // uint32_t data[20];
+    // memset((void *)data, 0, sizeof(data));
+    // retval = Read("mm/0/REG_STAT_HDR_DAT_XST/0/??", data);
+    // double interval = ??;
+
+    double interval = 1.0;
+    double *_ptr = (double *)termout.val;
+    *_ptr = interval;
+    termout.nof_vals = 1;
+    termout.datatype = format;
+    return retval;
+}
+
+bool Periph_fpga::write_xst_integration_interval(uint32_t *data)
+{
+    // TODO, fill in if supported in FW
+    // return Write("mm/0/REG_STAT_HDR_DAT_XST/0/??", data);
+    return true;
+}
+
+bool Periph_fpga::read_xst_subband_select(TermOutput& termout, int format)
+{
+    bool retval = true;
+
+    uint32_t data[20];
+    memset((void *)data, 0, sizeof(data));
+    retval &= Read("mm/0/REG_CROSSLETS_INFO/0/step", data);
+    retval &= Read("mm/0/REG_CROSSLETS_INFO/0/offset", &data[1]);
+
+    uint32_t *_ptr = (uint32_t *)termout.val;
+    for (uint i=0; i<(C_N_step+C_N_crosslets_max); i++) {
+        *_ptr = data[i];
+        _ptr++;
+    }
+    termout.nof_vals = C_N_step + C_N_crosslets_max;
+    termout.datatype = format;
+    return retval;
+}
+
+bool Periph_fpga::write_xst_subband_select(uint32_t *data)
+{
+    bool retval = true;
+    retval &= Write("mm/0/REG_CROSSLETS_INFO/0/offset", &data[1]);
+    retval &= Write("mm/0/REG_CROSSLETS_INFO/0/step", &data[0]);
+    return retval;
+}
+
 bool Periph_fpga::read_processing_enable(TermOutput& termout, int format)
 {
     bool retval = true;
@@ -1775,14 +2052,14 @@ bool Periph_fpga::read_wg_frequency(TermOutput& termout, int format) {
     uint32_t data[20];
     memset((void *)data, 0, sizeof(data));
     string regname;
-    for (uint i=0; i< C_S_pn; i++) {
+    for (uint i=0; i<C_S_pn; i++) {
         regname = "mm/0/REG_WG/" + to_string(i) + "/freq";
         retval = Read(regname, &data[i]);
     }
 
     double freq;
     double *_ptr = (double *)termout.val ;
-    for (uint i=0; i< C_S_pn; i++) {
+    for (uint i=0; i<C_S_pn; i++) {
         freq = (((double)data[i]) / C_WG_FREQ_UNIT) * C_F_adc;
         *_ptr = freq;
         _ptr++;
@@ -1800,7 +2077,7 @@ bool Periph_fpga::write_wg_frequency(uint32_t *data) {
     double freq, intpart;
     string regname;
     double *_ptr = (double *)data;
-    for (uint i=0; i< C_S_pn; i++) {
+    for (uint i=0; i<C_S_pn; i++) {
         regname = "mm/0/REG_WG/" + to_string(i) + "/freq";
         freq = (*_ptr) / C_F_adc;
         freq = modf(freq, &intpart);
diff --git a/src/periph/fpga.h b/src/periph/fpga.h
index 984aad2ba65b4f0dfb7be1f4fb5631306ed26800..59746dc8f8e7a2e0523bcf9033309c171a364d79 100644
--- a/src/periph/fpga.h
+++ b/src/periph/fpga.h
@@ -66,6 +66,7 @@ private:
   uint32_t my_jesd_csr_dev_syncn[C_S_pn];
   uint32_t my_jesd_rx_err0[C_S_pn];
   uint32_t my_jesd_rx_err1[C_S_pn];
+  bool    my_xst_processing_enable;
 
   std::ofstream rbf_wf;
   uint32_t Flash_page_start, Flash_page_size_bytes, Flash_user_sector_start,
@@ -125,6 +126,21 @@ private:
   bool read_bst_offload_nof_beamlets_per_packet(TermOutput& termout, int format);
   bool write_bst_offload_nof_beamlets_per_packet(uint32_t *data);
 
+  bool read_xst_subband_select(TermOutput& termout, int format);
+  bool write_xst_subband_select(uint32_t *data);
+  bool read_xst_integration_interval(TermOutput& termout, int format);
+  bool write_xst_integration_interval(uint32_t *data);
+  bool read_xst_processing_enable(TermOutput& termout, int format);
+  bool write_xst_processing_enable(uint32_t *data);
+  bool read_xst_offload_enable(TermOutput& termout, int format);
+  bool write_xst_offload_enable(uint32_t *data);
+  bool read_xst_offload_hdr_eth_destination_mac(TermOutput& termout, int format);
+  bool write_xst_offload_hdr_eth_destination_mac(const char *data);
+  bool read_xst_offload_hdr_ip_destination_address(TermOutput& termout, int format);
+  bool write_xst_offload_hdr_ip_destination_address(const char *data);
+  bool read_xst_offload_hdr_udp_destination_port(TermOutput& termout, int format);
+  bool write_xst_offload_hdr_udp_destination_port(uint32_t *data);
+
   bool read_processing_enable(TermOutput& termout, int format);
   bool write_processing_enable(uint32_t *data);
 
diff --git a/src/uniboard.conf b/src/uniboard.conf
index dab0735c914e85e8e522037dd2d6947f34f170a0..fca499bb15023f4091297a0365b31d90a385e6ce 100644
--- a/src/uniboard.conf
+++ b/src/uniboard.conf
@@ -5,7 +5,7 @@
 #   gn  ipaddr     expected firmware  expected version  enabled
 
 # UNB 0
-node 0   10.99.2.1   lofar2_unb2b_sdp_station_bf    2                 1
+node 0   10.99.2.1   lofar2_unb2b_sdp_station_xsub_one    2                 1
 node 1   10.99.2.2   lofar2_unb2b_sdp_station_xsub_one    2                 1
 node 2   10.99.2.3   lofar2_unb2b_sdp_station_xsub_one    2                 1
 node 3   10.99.2.4   lofar2_unb2b_sdp_station_xsub_one    2                 1