diff --git a/src/constants.h b/src/constants.h
index 8a5affb1627d39ea6f4388fdddbdd749e75d9ff5..35b5e4f81ad006202d37482cc0e08002ce38f520 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -54,6 +54,7 @@
 // #define C_N_beamlets 976  // Number of beamlets per antenna band  488, 976
 #define C_V_si_db 1024  // Size of the databuffer per signal input (SI), to capture
                         // a snapshot of the signal input data (ADC JESD204B data or WG data)
+#define C_V_si_histogram 512  // Number of bins of the histogram per signal input (SI).
 
 #define C_200MHZ_1_CNT_NS 5  // Time of one cnt in nS
 #define C_N_CLK_PER_PPS 200000000
diff --git a/src/fpga.cpp b/src/fpga.cpp
index 50f763b92b5230767974b964310e991aa4cc5519..82e0e2a70c74233dc7d4fbf99017f1317042434f 100644
--- a/src/fpga.cpp
+++ b/src/fpga.cpp
@@ -61,10 +61,10 @@ Fpga::Fpga(list<class Node*>& nodelist, const int32_t n_beamsets):
 
     pointMap->add_register("FPGA_global_node_index_R",                       "fpga/global_node_index",                      nodes.size(), 1, "RO", REG_FORMAT_UINT32);
 
-    pointMap->add_register("FPGA_sst_offload_weighted_subbands_R",           "fpga/sst_offload_weighted_subbands",          nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
-    pointMap->add_register("FPGA_sst_offload_weighted_subbands_RW",          "fpga/sst_offload_weighted_subbands",          nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
-    pointMap->add_register("FPGA_sst_offload_enable_R",                      "fpga/sst_offload_enable",                     nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN);
-    pointMap->add_register("FPGA_sst_offload_enable_RW",                     "fpga/sst_offload_enable",                     nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN);
+    pointMap->add_register("FPGA_sst_offload_weighted_subbands_R",           "fpga/sst_offload_weighted_subbands",          nodes.size(), 1, "RO", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_sst_offload_weighted_subbands_RW",          "fpga/sst_offload_weighted_subbands",          nodes.size(), 1, "RW", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_sst_offload_enable_R",                      "fpga/sst_offload_enable",                     nodes.size(), 1, "RO", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_sst_offload_enable_RW",                     "fpga/sst_offload_enable",                     nodes.size(), 1, "RW", REG_FORMAT_UINT8);
     pointMap->add_register("FPGA_sst_offload_hdr_eth_destination_mac_R",     "fpga/sst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RO", REG_FORMAT_STRING);
     pointMap->add_register("FPGA_sst_offload_hdr_eth_destination_mac_RW",    "fpga/sst_offload_hdr_eth_destination_mac",    nodes.size(), 1, "RW", REG_FORMAT_STRING);
     pointMap->add_register("FPGA_sst_offload_hdr_ip_destination_address_R",  "fpga/sst_offload_hdr_ip_destination_address", nodes.size(), 1, "RO", REG_FORMAT_STRING);
@@ -72,8 +72,8 @@ Fpga::Fpga(list<class Node*>& nodelist, const int32_t n_beamsets):
     pointMap->add_register("FPGA_sst_offload_hdr_udp_destination_port_R",    "fpga/sst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RO", REG_FORMAT_UINT16);
     pointMap->add_register("FPGA_sst_offload_hdr_udp_destination_port_RW",   "fpga/sst_offload_hdr_udp_destination_port",   nodes.size(), 1, "RW", REG_FORMAT_UINT16);
 
-    pointMap->add_register("FPGA_bst_offload_enable_R",                      "fpga/bst_offload_enable",                     nodes.size(), nBeamsets, "RO", REG_FORMAT_BOOLEAN);
-    pointMap->add_register("FPGA_bst_offload_enable_RW",                     "fpga/bst_offload_enable",                     nodes.size(), nBeamsets, "RW", REG_FORMAT_BOOLEAN);
+    pointMap->add_register("FPGA_bst_offload_enable_R",                      "fpga/bst_offload_enable",                     nodes.size(), nBeamsets, "RO", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_bst_offload_enable_RW",                     "fpga/bst_offload_enable",                     nodes.size(), nBeamsets, "RW", REG_FORMAT_UINT8);
     pointMap->add_register("FPGA_bst_offload_hdr_eth_destination_mac_R",     "fpga/bst_offload_hdr_eth_destination_mac",    nodes.size(), nBeamsets, "RO", REG_FORMAT_STRING);
     pointMap->add_register("FPGA_bst_offload_hdr_eth_destination_mac_RW",    "fpga/bst_offload_hdr_eth_destination_mac",    nodes.size(), nBeamsets, "RW", REG_FORMAT_STRING);
     pointMap->add_register("FPGA_bst_offload_hdr_ip_destination_address_R",  "fpga/bst_offload_hdr_ip_destination_address", nodes.size(), nBeamsets, "RO", REG_FORMAT_STRING);
@@ -85,10 +85,10 @@ Fpga::Fpga(list<class Node*>& nodelist, const int32_t n_beamsets):
     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_processing_enable_R",                   "fpga/xst_processing_enable",                  nodes.size(), 1, "RO", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_xst_processing_enable_RW",                  "fpga/xst_processing_enable",                  nodes.size(), 1, "RW", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_xst_offload_enable_R",                      "fpga/xst_offload_enable",                     nodes.size(), 1, "RO", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_xst_offload_enable_RW",                     "fpga/xst_offload_enable",                     nodes.size(), 1, "RW", REG_FORMAT_UINT8);
     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);
@@ -96,8 +96,8 @@ Fpga::Fpga(list<class Node*>& nodelist, const int32_t n_beamsets):
     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);
+    pointMap->add_register("FPGA_processing_enable_R",                       "fpga/processing_enable",                      nodes.size(), 1, "RO", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_processing_enable_RW",                      "fpga/processing_enable",                      nodes.size(), 1, "RW", REG_FORMAT_UINT8);
     pointMap->add_register("FPGA_sdp_info_station_id_R",                     "fpga/sdp_info_station_id",                    nodes.size(), 1, "RO", REG_FORMAT_UINT32);
     pointMap->add_register("FPGA_sdp_info_station_id_RW",                    "fpga/sdp_info_station_id",                    nodes.size(), 1, "RW", REG_FORMAT_UINT32);
     pointMap->add_register("FPGA_sdp_info_observation_id_R",                 "fpga/sdp_info_observation_id",                nodes.size(), 1, "RO", REG_FORMAT_UINT32);
@@ -109,8 +109,8 @@ Fpga::Fpga(list<class Node*>& nodelist, const int32_t n_beamsets):
     pointMap->add_register("FPGA_sdp_info_fsub_type_R",                      "fpga/sdp_info_fsub_type",                     nodes.size(), 1, "RO", REG_FORMAT_UINT32);
     pointMap->add_register("FPGA_sdp_info_block_period_R",                   "fpga/sdp_info_block_period",                  nodes.size(), 1, "RO", REG_FORMAT_UINT32);
 
-    pointMap->add_register("FPGA_wg_enable_R",                               "fpga/wg_enable",                              nodes.size(), C_S_pn, "RO", REG_FORMAT_BOOLEAN);
-    pointMap->add_register("FPGA_wg_enable_RW",                              "fpga/wg_enable",                              nodes.size(), C_S_pn, "RW", REG_FORMAT_BOOLEAN);
+    pointMap->add_register("FPGA_wg_enable_R",                               "fpga/wg_enable",                              nodes.size(), C_S_pn, "RO", REG_FORMAT_UINT8);
+    pointMap->add_register("FPGA_wg_enable_RW",                              "fpga/wg_enable",                              nodes.size(), C_S_pn, "RW", REG_FORMAT_UINT8);
     pointMap->add_register("FPGA_wg_amplitude_R",                            "fpga/wg_amplitude",                           nodes.size(), C_S_pn, "RO", REG_FORMAT_DOUBLE);
     pointMap->add_register("FPGA_wg_amplitude_RW",                           "fpga/wg_amplitude",                           nodes.size(), C_S_pn, "RW", REG_FORMAT_DOUBLE);
     pointMap->add_register("FPGA_wg_phase_R",                                "fpga/wg_phase",                               nodes.size(), C_S_pn, "RO", REG_FORMAT_DOUBLE);
@@ -143,6 +143,7 @@ Fpga::Fpga(list<class Node*>& nodelist, const int32_t n_beamsets):
     pointMap->add_register("FPGA_weights_RW",                                "fpga/weights",                                nodes.size(), C_S_pn*nBeamsets*C_N_sub_bf, "RW", REG_FORMAT_INT16);
     
     pointMap->add_register("FPGA_signal_input_data_buffer_R",                "fpga/signal_input_data_buffer",               nodes.size(), C_S_pn*C_V_si_db, "RO", REG_FORMAT_INT16);
+    pointMap->add_register("FPGA_signal_input_histogram_R",                  "fpga/signal_input_histogram",                 nodes.size(), C_S_pn*C_V_si_histogram, "RO", REG_FORMAT_UINT32);
 }
 
 Fpga::~Fpga()
@@ -303,7 +304,7 @@ bool Fpga::point(TermOutput& termout, const char cmd, const string addr,
         }
         if (cmd == 'R') {
             switch (termresults.datatype) {
-                case REG_FORMAT_BOOLEAN: {
+                case REG_FORMAT_UINT8: {
                     bool *ptr_in = (bool *)termresults.val;
                     bool *ptr_out = (bool *)termout.val;
                     for (unsigned int i=0; i<termresults.nof_vals; i++) {
diff --git a/src/opcua/ua_server.cpp b/src/opcua/ua_server.cpp
index e29b9f684905e8803dc2458306284e55918abd97..ed15434d6cadf263871a7ef7b3d2a167ee41c135 100644
--- a/src/opcua/ua_server.cpp
+++ b/src/opcua/ua_server.cpp
@@ -270,6 +270,7 @@ static void ua_add_Variable_string(UA_Server *server, string regname, unsigned i
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_String *values = NULL;
     if (is_scalar) {
         UA_String value = UA_STRING_ALLOC((char *)"unknown");
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_STRING]);
@@ -310,7 +311,7 @@ static void ua_add_Variable_string(UA_Server *server, string regname, unsigned i
         // handle error
         cout << "Error adding node" << endl;
     }
-
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_STRING]);
 }
 
 static void ua_add_Variable_int64(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -328,8 +329,9 @@ static void ua_add_Variable_int64(UA_Server *server, string regname, unsigned in
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_Int64 *values = NULL;
     if (is_scalar) {
-        UA_Int32 value = UA_Int64(0);
+        UA_Int64 value = UA_Int64(0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_INT64]);
         vattr.valueRank = UA_VALUERANK_SCALAR;
     }
@@ -367,6 +369,7 @@ static void ua_add_Variable_int64(UA_Server *server, string regname, unsigned in
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_INT64]);
 }
 
 static void ua_add_Variable_uint64(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -384,6 +387,7 @@ static void ua_add_Variable_uint64(UA_Server *server, string regname, unsigned i
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_UInt64 *values = NULL;
     if (is_scalar) {
         UA_UInt64 value = UA_UInt64(0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_UINT64]);
@@ -423,6 +427,7 @@ static void ua_add_Variable_uint64(UA_Server *server, string regname, unsigned i
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_UINT64]);
 }
 
 static void ua_add_Variable_int32(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -440,6 +445,7 @@ static void ua_add_Variable_int32(UA_Server *server, string regname, unsigned in
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_Int32 *values = NULL;
     if (is_scalar) {
         UA_Int32 value = UA_Int32(0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_INT32]);
@@ -479,6 +485,7 @@ static void ua_add_Variable_int32(UA_Server *server, string regname, unsigned in
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_INT32]);
 }
 
 static void ua_add_Variable_uint32(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -496,6 +503,7 @@ static void ua_add_Variable_uint32(UA_Server *server, string regname, unsigned i
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_UInt32 *values = NULL;
     if (is_scalar) {
         UA_UInt32 value = UA_UInt32(0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_UINT32]);
@@ -535,6 +543,7 @@ static void ua_add_Variable_uint32(UA_Server *server, string regname, unsigned i
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_UINT32]);
 }
 
 static void ua_add_Variable_int16(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -552,6 +561,7 @@ static void ua_add_Variable_int16(UA_Server *server, string regname, unsigned in
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_Int16 *values = NULL;
     if (is_scalar) {
         UA_Int16 value = UA_Int16(0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_INT16]);
@@ -591,6 +601,8 @@ static void ua_add_Variable_int16(UA_Server *server, string regname, unsigned in
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_INT16]);
+    
 }
 
 static void ua_add_Variable_uint16(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -608,6 +620,7 @@ static void ua_add_Variable_uint16(UA_Server *server, string regname, unsigned i
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_UInt16 *values = NULL;
     if (is_scalar) {
         UA_UInt16 value = UA_UInt16(0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_UINT16]);
@@ -647,6 +660,65 @@ static void ua_add_Variable_uint16(UA_Server *server, string regname, unsigned i
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_UINT16]);
+}
+
+static void ua_add_Variable_byte(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
+{
+    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "ua_add_Variable_byte: %s", (char *)regname.c_str());
+    UA_VariableAttributes vattr = UA_VariableAttributes_default;
+
+    if (perm == "RW") {
+        vattr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;
+    }
+    else if (perm == "WO") {
+        vattr.accessLevel = UA_ACCESSLEVELMASK_WRITE;
+    }
+    else if (perm == "RO") {
+        vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
+    }
+
+    UA_Byte *values = NULL;
+    if (is_scalar) {
+        UA_Byte value = UA_Byte(0);
+        UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_BYTE]);
+        vattr.valueRank = UA_VALUERANK_SCALAR;
+    }
+    else {
+        UA_Byte *values = (UA_Byte *) UA_Array_new(size, &UA_TYPES[UA_TYPES_BYTE]);
+        for (unsigned int i=0; i<size; i++) {
+            values[i] = UA_Byte(0);
+        }
+        vattr.valueRank = UA_VALUERANK_ONE_DIMENSION;
+
+        UA_UInt32 myArrayDimensions[1] = {size};
+        vattr.arrayDimensions = myArrayDimensions;
+        vattr.arrayDimensionsSize = 1;
+
+        UA_Variant_setArray(&vattr.value, values, size, &UA_TYPES[UA_TYPES_BYTE]);
+        vattr.value.arrayDimensions = myArrayDimensions;
+        vattr.value.arrayDimensionsSize = 1;
+    }
+
+    vattr.dataType = UA_TYPES[UA_TYPES_BYTE].typeId;
+    vattr.displayName = UA_LOCALIZEDTEXT((char *)"locale", (char *)regname.c_str());
+
+    UA_DataSource DataSource;
+    DataSource.read = ua_read_DataSource;
+    DataSource.write = ua_write_DataSource;
+
+    UA_StatusCode retval = UA_Server_addDataSourceVariableNode(server,
+                                       UA_NODEID_STRING(mUaLofarNameSpace, (char *)regname.c_str()), // currentNodeId
+                                       UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), // parentNodeId
+                                       UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), // parentReferenceNodeId
+                                       UA_QUALIFIEDNAME(mUaLofarNameSpace, (char *)regname.c_str()), // node browse name
+                                       UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
+                                       vattr, DataSource, NULL, NULL);
+    if (retval != UA_STATUSCODE_GOOD) {
+        // handle error
+        cout << "Error adding node" << endl;
+    }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_BYTE]);
 }
 
 static void ua_add_Variable_float(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -664,6 +736,7 @@ static void ua_add_Variable_float(UA_Server *server, string regname, unsigned in
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_Float *values = NULL;
     if (is_scalar) {
         UA_Float value = UA_Float(0.0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_FLOAT]);
@@ -703,6 +776,7 @@ static void ua_add_Variable_float(UA_Server *server, string regname, unsigned in
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_FLOAT]);
 }
 
 static void ua_add_Variable_double(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -719,7 +793,8 @@ static void ua_add_Variable_double(UA_Server *server, string regname, unsigned i
     else if (perm == "RO") {
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
-
+    
+    UA_Double *values = NULL;
     if (is_scalar) {
         UA_Double value = UA_Double(0.0);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_DOUBLE]);
@@ -759,6 +834,7 @@ static void ua_add_Variable_double(UA_Server *server, string regname, unsigned i
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_DOUBLE]);
 }
 
 static void ua_add_Variable_boolean(UA_Server *server, string regname, unsigned int size, string perm, bool is_scalar)
@@ -776,6 +852,7 @@ static void ua_add_Variable_boolean(UA_Server *server, string regname, unsigned
         vattr.accessLevel = UA_ACCESSLEVELMASK_READ;
     }
 
+    UA_Boolean *values = NULL;
     if (is_scalar) {
         UA_Boolean value = UA_Boolean(false);
         UA_Variant_setScalar(&vattr.value, &value, &UA_TYPES[UA_TYPES_BOOLEAN]);
@@ -816,6 +893,7 @@ static void ua_add_Variable_boolean(UA_Server *server, string regname, unsigned
         // handle error
         cout << "Error adding node" << endl;
     }
+    if (values) UA_Array_delete(values, size, &UA_TYPES[UA_TYPES_BOOLEAN]);
 }
 /* end of ua_add_Variable_[data_type]() functions */
 
@@ -852,6 +930,9 @@ static void ua_add_Variable(UA_Server *server, string regname, int format, unsig
         case REG_FORMAT_UINT16: {
             ua_add_Variable_uint16(server, regname, size, perm, is_scalar);
         } break;
+        case REG_FORMAT_UINT8: {
+            ua_add_Variable_byte(server, regname, size, perm, is_scalar);
+        } break;
         case REG_FORMAT_FLOAT: {
             ua_add_Variable_float(server, regname, size, perm, is_scalar);
         } break;
diff --git a/src/periph/fpga.cpp b/src/periph/fpga.cpp
index ddfecd2a02d54f4b6a54a32ba65cc0a98769b304..cfdc546d306a718675d90de44f6b6facf630fdf4 100644
--- a/src/periph/fpga.cpp
+++ b/src/periph/fpga.cpp
@@ -126,7 +126,7 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
     
     if (addr == "fpga/global_node_index") {
         retval = read_global_node_index(termout, format);
-        return true;
+        return retval;
     }
 
     if (!Masked) {  // Not selected
@@ -181,10 +181,10 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
             retval = read_fpga_weights(termout, format);
         }
         else if (addr == "fpga/sst_offload_weighted_subbands") {
-            retval = read_sst_offload_weighted_subbands(termout, format);
+            retval = read_mm_port(termout, "REG_DP_SELECTOR", "input_select", format);
         }
         else if (addr == "fpga/sst_offload_enable") {
-            retval = read_sst_offload_enable(termout, format);
+            retval = read_mm_port(termout, "REG_STAT_ENABLE_SST", "enable", format);
         }
         else if (addr == "fpga/sst_offload_hdr_eth_destination_mac") {
             retval = read_sst_offload_hdr_eth_destination_mac(termout, format);
@@ -193,10 +193,10 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
             retval = read_sst_offload_hdr_ip_destination_address(termout, format);
         }
         else if (addr == "fpga/sst_offload_hdr_udp_destination_port") {
-            retval = read_sst_offload_hdr_udp_destination_port(termout, format);
+            retval = read_mm_port(termout, "REG_STAT_HDR_DAT_SST", "udp_destination_port", format);
         }
         else if (addr == "fpga/bst_offload_enable") {
-            retval = read_bst_offload_enable(termout, format);
+            retval = read_mm_port(termout, "REG_STAT_ENABLE_BST", "enable", format);
         }
         else if (addr == "fpga/bst_offload_hdr_eth_destination_mac") {
             retval = read_bst_offload_hdr_eth_destination_mac(termout, format);
@@ -205,10 +205,10 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
             retval = read_bst_offload_hdr_ip_destination_address(termout, format);
         }
         else if (addr == "fpga/bst_offload_hdr_udp_destination_port") {
-            retval = read_bst_offload_hdr_udp_destination_port(termout, format);
+            retval = read_mm_port(termout,"REG_STAT_HDR_DAT_BST", "udp_destination_port", format);
         }
         else if (addr == "fpga/xst_offload_enable") {
-            retval = read_xst_offload_enable(termout, format);
+            retval = read_mm_port(termout, "REG_STAT_ENABLE_XST", "enable", format);
         }
         else if (addr == "fpga/xst_offload_hdr_eth_destination_mac") {
             retval = read_xst_offload_hdr_eth_destination_mac(termout, format);
@@ -217,7 +217,7 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
             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);
+            retval = read_mm_port(termout, "REG_STAT_HDR_DAT_XST", "udp_destination_port", format);
         }
         else if (addr == "fpga/xst_processing_enable") {
             retval = read_xst_processing_enable(termout, format);
@@ -229,31 +229,31 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
             retval = read_xst_subband_select(termout, format);
         }
         else if (addr == "fpga/processing_enable") {
-            retval = read_processing_enable(termout, format);
+            retval = read_mm_port(termout, "REG_BSN_SOURCE_V2", "dp_on", format);
         }
         else if (addr == "fpga/sdp_info_station_id") {
-            retval = read_sdp_info_station_id(termout, format);
+            retval = read_mm_port(termout, "REG_SDP_INFO", "station_id", format);
         }
         else if (addr == "fpga/sdp_info_observation_id") {
-            retval = read_sdp_info_observation_id(termout, format);
+            retval = read_mm_port(termout, "REG_SDP_INFO", "observation_id", format);
         }
         else if (addr == "fpga/sdp_info_nyquist_sampling_zone_index") {
-            retval = read_sdp_info_nyquist_sampling_zone_index(termout, format);
+            retval = read_mm_port(termout,"REG_SDP_INFO", "nyquist_zone_index", format);
         }
         else if (addr == "fpga/sdp_info_antenna_band_index") {
-            retval = read_sdp_info_antenna_band_index(termout, format);
+            retval = read_mm_port(termout, "REG_SDP_INFO", "antenna_band_index", format);
         }
         else if (addr == "fpga/sdp_info_f_adc") {
-            retval = read_sdp_info_f_adc(termout, format);
+            retval = read_mm_port(termout, "REG_SDP_INFO", "f_adc", format);
         }
         else if (addr == "fpga/sdp_info_fsub_type") {
-            retval = read_sdp_info_fsub_type(termout, format);
+            retval = read_mm_port(termout, "REG_SDP_INFO", "fsub_type", format);
         }
         else if (addr == "fpga/sdp_info_block_period") {
-            retval = read_sdp_info_block_period(termout, format);
+            retval = read_mm_port(termout, "REG_SDP_INFO", "block_period", format);
         }
         else if (addr == "fpga/wg_enable") {
-            retval = read_wg_enable(termout, format);
+            retval = read_mm_port(termout, "REG_WG", "mode", format);
         }
         else if (addr == "fpga/wg_amplitude") {
             retval = read_wg_amplitude(termout, format);
@@ -295,13 +295,16 @@ bool Periph_fpga::read(TermOutput& termout, const string addr,
             retval = read_signal_input_rms(termout, format, R_MEM);
         }
         else if (addr == "fpga/signal_input_samples_delay") {
-            retval = read_signal_input_samples_delay(termout, format);
+            retval = read_mm_port(termout, "REG_DP_SHIFTRAM", "shift", format);
         }
         else if (addr == "fpga/subband_weights") {
-            retval = read_subband_weights(termout, format);
+            retval = read_mm_port(termout, "RAM_EQUALIZER_GAINS", "data", format);
         }
         else if (addr == "fpga/signal_input_data_buffer") {
-            retval = read_signal_input_data_buffer(termout, format);
+            retval = read_mm_port(termout, "RAM_DIAG_DATA_BUFFER_BSN", "data", format);
+        }
+        else if (addr == "fpga/signal_input_histogram") {
+            retval = read_mm_port(termout, "RAM_ST_HISTOGRAM", "data", format);
         }
         else {
             throw runtime_error("address " + addr + " not found!");
@@ -1003,23 +1006,6 @@ bool Periph_fpga::write_fpga_weights(const char *data)
     return retval;
 }
 
-bool Periph_fpga::read_sst_offload_weighted_subbands(TermOutput& termout, int format)
-{
-    bool retval = true;
-
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_DP_SELECTOR/0/input_select", data);
-
-    bool select = !(bool)data[0];
-
-    bool *_ptr = (bool *)termout.val;
-    *_ptr = select;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_sst_offload_weighted_subbands(const char *data)
 {
     uint32_t *_ptr = (uint32_t *)data;
@@ -1031,23 +1017,6 @@ bool Periph_fpga::write_sst_offload_weighted_subbands(const char *data)
     return retval;
 }
 
-bool Periph_fpga::read_sst_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_SST/0/enable", data);
-
-    bool select = (bool)data[0];
-
-    bool *_ptr = (bool *)termout.val;
-    *_ptr = select;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_sst_offload_enable(const char *data)
 {
     uint32_t _data[1];
@@ -1151,50 +1120,12 @@ bool Periph_fpga::write_sst_offload_hdr_ip_destination_address(const char *data)
     return Write("mm/0/REG_STAT_HDR_DAT_SST/0/ip_destination_address", ip);
 }
 
-bool Periph_fpga::read_sst_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_SST/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_sst_offload_hdr_udp_destination_port(const char *data)
 {
     uint32_t *_ptr = (uint32_t *)data;
     return Write("mm/0/REG_STAT_HDR_DAT_SST/0/udp_destination_port", _ptr);
 }
 
-bool Periph_fpga::read_bst_offload_enable(TermOutput& termout, int format)
-{
-    bool retval = true;
-    string regname;
-    uint32_t data[20];
-    // bool select;
-    bool *_ptr = (bool *)termout.val;
-    for (uint32_t i=0; i<nBeamsets; i++) {
-        memset((void *)data, 0, sizeof(data));
-        regname = "mm/" + to_string(i) + "/REG_STAT_ENABLE_BST/0/enable";
-        retval &= Read(regname, data);
-
-        bool select = (bool)data[0];
-        *_ptr = select;
-        _ptr++;
-    }
-    termout.nof_vals = nBeamsets;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_bst_offload_enable(const char *data)
 {
     bool *_ptr = (bool *)data;
@@ -1342,28 +1273,6 @@ bool Periph_fpga::write_bst_offload_hdr_ip_destination_address(const char *data)
     return retval;
 }
 
-bool Periph_fpga::read_bst_offload_hdr_udp_destination_port(TermOutput& termout, int format)
-{
-    bool retval = true;
-    string regname;
-
-    uint32_t data[20];
-    // int port;
-    uint16_t *_ptr = (uint16_t *)termout.val;
-    for (uint32_t i=0; i<nBeamsets; i++) {
-        memset((void *)data, 0, sizeof(data));
-        regname = "mm/" + to_string(i) + "/REG_STAT_HDR_DAT_BST/0/udp_destination_port";
-        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;
-        _ptr++;
-    }
-    termout.nof_vals = nBeamsets;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_bst_offload_hdr_udp_destination_port(const char *data)
 {
     uint32_t *_ptr = (uint32_t *)data;
@@ -1376,23 +1285,6 @@ bool Periph_fpga::write_bst_offload_hdr_udp_destination_port(const char *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(const char *data)
 {
     uint32_t _data[1];
@@ -1496,23 +1388,6 @@ bool Periph_fpga::write_xst_offload_hdr_ip_destination_address(const char *data)
     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(const char *data)
 {
     uint32_t *_ptr = (uint32_t *)data;
@@ -1615,23 +1490,6 @@ bool Periph_fpga::write_xst_subband_select(const char *data)
     return retval;
 }
 
-bool Periph_fpga::read_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_SOURCE_V2/0/dp_on", data);
-    bool dp_on = (bool)data[0];
-
-    bool *_ptr = (bool *)termout.val;
-    *_ptr = dp_on;
-
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_processing_enable(const char *data)
 {
     // write dp_on 0
@@ -1696,129 +1554,24 @@ bool Periph_fpga::write_processing_enable(const char *data)
     return true;
 }
 
-bool Periph_fpga::read_sdp_info_station_id(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_SDP_INFO/0/station_id", data);
-
-    uint32_t station_id = (uint32_t)data[0];
-
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    *_ptr = station_id;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_sdp_info_station_id(const char *data) {
     uint32_t *_ptr = (uint32_t *)data;
     bool retval = Write("mm/0/REG_SDP_INFO/0/station_id", _ptr);
     return retval;
 }
 
-bool Periph_fpga::read_sdp_info_observation_id(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_SDP_INFO/0/observation_id", data);
-
-    uint32_t observation_id = (uint32_t)data[0];
-
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    *_ptr = observation_id;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_sdp_info_observation_id(const char *data) {
     uint32_t *_ptr = (uint32_t *)data;
     bool retval = Write("mm/0/REG_SDP_INFO/0/observation_id", _ptr);
     return retval;
 }
 
-bool Periph_fpga::read_sdp_info_nyquist_sampling_zone_index(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_SDP_INFO/0/nyquist_zone_index", data);
-
-    uint32_t nyquist_zone_index = (uint32_t)data[0];
-
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    *_ptr = nyquist_zone_index;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::write_sdp_info_nyquist_sampling_zone_index(const char *data) {
     uint32_t *_ptr = (uint32_t *)data;
     bool retval = Write("mm/0/REG_SDP_INFO/0/nyquist_zone_index", _ptr);
     return retval;
 }
 
-bool Periph_fpga::read_sdp_info_antenna_band_index(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_SDP_INFO/0/antenna_band_index", data);
-
-    uint32_t antenna_band_index = (uint32_t)data[0];
-
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    *_ptr = antenna_band_index;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
-bool Periph_fpga::read_sdp_info_f_adc(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_SDP_INFO/0/f_adc", data);
-
-    uint32_t f_adc = (uint32_t)data[0];
-
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    *_ptr = f_adc;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
-bool Periph_fpga::read_sdp_info_fsub_type(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_SDP_INFO/0/fsub_type", data);
-
-    uint32_t fsub_type = (uint32_t)data[0];
-
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    *_ptr = fsub_type;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
-bool Periph_fpga::read_sdp_info_block_period(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    retval = Read("mm/0/REG_SDP_INFO/0/block_period", data);
-
-    uint32_t block_period = (uint32_t)data[0];
-
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    *_ptr = block_period;
-    termout.nof_vals = 1;
-    termout.datatype = format;
-    return retval;
-}
-
 // Waveform generator functions "_wg_"
 /*
 When FPGA_wg_enable_RW is set False, then disable the WG via mode = c_mode_off = 0.
@@ -1834,28 +1587,6 @@ The MP reports False when mode = c_mode_off = 0, else True.
 Note:
   The nof_samples field and mode field share an address in REG_DIAG_WG. The nof_samples = 2**W_wg_buf = 1024.
 */
-bool Periph_fpga::read_wg_enable(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    string regname;
-    for (uint i=0; i< C_S_pn; i++) {
-        regname = "mm/0/REG_WG/" + to_string(i) + "/mode";
-        retval = Read(regname, &data[i]);
-    }
-
-    bool enabled;
-    bool *_ptr = (bool *)termout.val ;
-    for (uint i=0; i< C_S_pn; i++) {
-        enabled = (bool)data[i];
-        *_ptr = enabled;
-        _ptr++;
-    }
-
-    termout.nof_vals = C_S_pn;
-    termout.datatype = format;
-    return retval;
-}
 
 bool Periph_fpga::write_wg_enable(const char *data) {
     bool *_ptr = (bool *)data;
@@ -2274,23 +2005,6 @@ bool Periph_fpga::write_signal_input_samples_delay(const char *data) {
     return retval;
 }
 
-bool Periph_fpga::read_signal_input_samples_delay(TermOutput& termout, int format) {
-    bool retval = true;
-    uint32_t data[20];
-    memset((void *)data, 0, sizeof(data));
-    uint32_t *_ptr = (uint32_t *)termout.val;
-    string regname;
-    for (uint i=0; i< C_S_pn; i++) {
-        regname = "mm/0/REG_DP_SHIFTRAM/" + to_string(i) + "/shift";
-        retval = Read(regname, data);
-        *_ptr = (uint32_t)data[0];
-        _ptr++;
-    }
-    termout.nof_vals = C_S_pn;
-    termout.datatype = format;
-    return retval;
-}
-
 bool Periph_fpga::read_signal_input_mean(TermOutput& termout, int format, int mode) {
     bool retval = true;
     if (mode == R_UCP) {
@@ -2359,46 +2073,85 @@ bool Periph_fpga::write_subband_weights(const char *data) {
     return retval;
 }
 
-bool Periph_fpga::read_subband_weights(TermOutput& termout, int format) {
+bool Periph_fpga::read_mm_port(TermOutput& termout, const string& port_name, const string& field_name, const int format) {
     bool retval = true;
-    uint32_t *_ptr = (uint32_t *)termout.val;
 
-    string regname;
-    uint32_t span;
-    uint32_t n_regs = (int32_t)(C_S_pn / C_Q_fft);
+    string regname = "mm/0/" + port_name + "/0/" + field_name;
+    uint32_t n_periph = mmap->getNPeripherals(regname);
+    uint32_t n_ports = mmap->getNPorts(regname);
+    uint32_t n_fields = mmap->getNFields(regname);
+    uint32_t span = mmap->getSpan(regname);
 
-    for (uint i=0; i<n_regs; i++) {
-        regname = "mm/0/RAM_EQUALIZER_GAINS/" + to_string(i) + "/data";
-        span = mmap->getSpan((regname));
-        retval = Read(regname, _ptr);
-        _ptr += span;
+    uint32_t format_size = reg_format_size_in_bytes(format);
+
+    uint32_t *data = new uint32_t[span];
+    char *_ptr = termout.val;
+
+    for (uint i=0; i<n_periph; i++) {
+        for (uint j=0; j<n_ports; j++) {
+            regname = "mm/" + to_string(i) + "/" + port_name + "/" + to_string(j) + "/" + field_name;
+            cout << "regname=" << regname << endl;
+
+            memset((void *)data, 0, (span * sizeof(uint32_t)));
+            retval &= Read(regname, data);
+            if (retval) {
+                // if a string
+                if (format == REG_FORMAT_STRING) {
+                    memcpy(_ptr, data, n_fields);
+                }
+                // if >= 4 bytes (uint32_t)
+                else if (format_size >= sizeof(uint32_t)) {
+                    memcpy(_ptr, data, (n_fields * format_size));
+                }
+                // if < 4 (uint32_t)
+                else {
+                    for (uint field_nr=0; field_nr<n_fields; field_nr++) {
+                        memcpy(_ptr, &data[field_nr], format_size);
+                        _ptr += format_size;
+                    }
+                }
+            }
+            // not valid data, set pointer to memory for next port data
+            else {
+                _ptr += format_size * n_fields;
+            }
+        }
     }
-    termout.nof_vals = C_S_pn * C_N_sub;
+    termout.nof_vals = n_periph * n_ports * n_fields;
     termout.datatype = format;
+    delete[] data;
     return retval;
 }
 
-bool Periph_fpga::read_signal_input_data_buffer(TermOutput& termout, int format) {
+/*bool Periph_fpga::write_mm_port(const char *data, TermOutput& termout, const string port_name, const string field_name, const int format) {
     bool retval = true;
-    uint32_t data[C_V_si_db];
-    int16_t *_ptr = (int16_t *)termout.val;
-
-    string regname;
 
-    for (uint i=0; i<C_S_pn; i++) {
-        regname = "mm/0/RAM_DIAG_DATA_BUFFER_BSN/" + to_string(i) + "/data";
-        retval &= Read(regname, data);
-        for (uint j=0; j<C_V_si_db; j++) {
-            if (retval) {
-                *_ptr = (int16_t)data[j];
+    string regname = "mm/0/" + port_name + "/0/" + field_name;
+    uint32_t n_periph = mmap->getNPeripherals(regname);
+    uint32_t n_ports = mmap->getNPorts(regname);
+    uint32_t n_fields = mmap->getNFields(regname);
+    uint32_t format_size = reg_format_size_in_bytes(format);
+    uint32_t *reg = new uint32_t[n_fields];
+
+    char *_ptr = data;
+
+    for (uint i=0; i<n_periph; i++) {
+        for (uint j=0; j<n_ports; j++) {
+            regname = "mm/" + to_string(i) + "/" + port_name + "/" + to_string(j) + "/" + field_name;
+            
+            for (uint field_nr=0; field_nr<n_fields; field_nr++) {
+                memcpy(&reg[field_nr], _ptr, format_size);
+                _ptr += format_size;
             }
-             _ptr++;
+            retval &= Write(regname, reg);
         }
     }
-    termout.nof_vals = C_S_pn * C_V_si_db;
+    termout.nof_vals = n_periph * n_ports * n_fields;
     termout.datatype = format;
+    delete[] reg;
     return retval;
-}
+}*/
+
 
 bool Periph_fpga::read_time_since_last_pps(TermOutput& termout, int format, int mode) {
     bool retval = true;
diff --git a/src/periph/fpga.h b/src/periph/fpga.h
index 20697ab26c8a617f1b0962b95e5836598cb9feb5..a537008216f50593c5d9dd7c431e8b2ec099cffd 100644
--- a/src/periph/fpga.h
+++ b/src/periph/fpga.h
@@ -109,24 +109,19 @@ private:
   bool read_fpga_weights(TermOutput& termout, int format);
   bool write_fpga_weights(const char *data);
 
-  bool read_sst_offload_weighted_subbands(TermOutput& termout, int format);
   bool write_sst_offload_weighted_subbands(const char *data);
-  bool read_sst_offload_enable(TermOutput& termout, int format);
   bool write_sst_offload_enable(const char *data);
   bool read_sst_offload_hdr_eth_destination_mac(TermOutput& termout, int format);
   bool write_sst_offload_hdr_eth_destination_mac(const char *data);
   bool read_sst_offload_hdr_ip_destination_address(TermOutput& termout, int format);
   bool write_sst_offload_hdr_ip_destination_address(const char *data);
-  bool read_sst_offload_hdr_udp_destination_port(TermOutput& termout, int format);
   bool write_sst_offload_hdr_udp_destination_port(const char *data);
 
-  bool read_bst_offload_enable(TermOutput& termout, int format);
   bool write_bst_offload_enable(const char *data);
   bool read_bst_offload_hdr_eth_destination_mac(TermOutput& termout, int format);
   bool write_bst_offload_hdr_eth_destination_mac(const char *data);
   bool read_bst_offload_hdr_ip_destination_address(TermOutput& termout, int format);
   bool write_bst_offload_hdr_ip_destination_address(const char *data);
-  bool read_bst_offload_hdr_udp_destination_port(TermOutput& termout, int format);
   bool write_bst_offload_hdr_udp_destination_port(const char *data);
   bool read_bst_offload_nof_beamlets_per_packet(TermOutput& termout, int format);
   bool write_bst_offload_nof_beamlets_per_packet(const char *data);
@@ -137,28 +132,18 @@ private:
   bool write_xst_integration_interval(const char *data);
   bool read_xst_processing_enable(TermOutput& termout, int format);
   bool write_xst_processing_enable(const char *data);
-  bool read_xst_offload_enable(TermOutput& termout, int format);
   bool write_xst_offload_enable(const char *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(const char *data);
 
-  bool read_processing_enable(TermOutput& termout, int format);
   bool write_processing_enable(const char *data);
 
-  bool read_sdp_info_station_id(TermOutput& termout, int format);
   bool write_sdp_info_station_id(const char *data);
-  bool read_sdp_info_observation_id(TermOutput& termout, int format);
   bool write_sdp_info_observation_id(const char *data);
-  bool read_sdp_info_nyquist_sampling_zone_index(TermOutput& termout, int format);
   bool write_sdp_info_nyquist_sampling_zone_index(const char *data);
-  bool read_sdp_info_antenna_band_index(TermOutput& termout, int format);
-  bool read_sdp_info_f_adc(TermOutput& termout, int format);
-  bool read_sdp_info_fsub_type(TermOutput& termout, int format);
-  bool read_wg_enable(TermOutput& termout, int format);
 
   bool write_wg_enable(const char *data);
   bool read_wg_amplitude(TermOutput& termout, int format);
@@ -180,20 +165,16 @@ private:
   bool read_jesd204b_rx_err1(TermOutput& termout, int format, int mode);
 
   bool write_signal_input_samples_delay(const char *data);
-  bool read_signal_input_samples_delay(TermOutput& termout, int format);
   bool read_signal_input_mean(TermOutput& termout, int format, int mode);
   bool read_signal_input_rms(TermOutput& termout, int format, int mode);
 
   bool write_subband_weights(const char *data);
-  bool read_subband_weights(TermOutput& termout, int format);
-
-  bool read_signal_input_data_buffer(TermOutput& termout, int format);
-
-  bool read_sdp_info_block_period(TermOutput& termout, int format);
 
   bool read_time_since_last_pps(TermOutput& termout, int format, int mode);
   bool write_wdi_override(TermOutput& termout);
 
+  bool read_mm_port(TermOutput& termout, const std::string& port_name, const std::string& field_name, const int format);
+
   CMMap read_reg_map();
 
 public:
diff --git a/src/registers.cpp b/src/registers.cpp
index 1639254c44243ee5e5189b33aa9d18ef636f67b5..a82d026a3c19291348bbb50da24097535e89f000 100644
--- a/src/registers.cpp
+++ b/src/registers.cpp
@@ -94,9 +94,9 @@ int32_t reg_format_size_in_words(int32_t type) {
 CMMap::CMMap() {}
 CMMap::~CMMap() { reg.clear(); }
 
-bool CMMap::add_register(const string name, const uint32_t base, const uint32_t n_mm_ports,
+bool CMMap::add_register(const string name, const uint32_t base, const uint32_t n_peripherals, const uint32_t n_mm_ports,
                          const uint32_t span, const uint32_t mask,
-                         const uint32_t shift, const string access,
+                         const uint32_t shift, const uint32_t n_fields, const string access, const string radix,
                          const string type, const uint32_t peripheral_span, const uint32_t mm_port_span)
 {
     // cout << "CMMap::add_register: " << name << endl;
@@ -104,14 +104,14 @@ bool CMMap::add_register(const string name, const uint32_t base, const uint32_t
         cerr << "CMMap::add_register: " << name << " already exist!" << endl;
         return false;
     }
-    register_info r = {base, n_mm_ports, span, mask, shift, access, type, mm_port_span, peripheral_span};
+    register_info r = {base, n_peripherals, n_mm_ports, span, mask, shift, n_fields, access, radix, type, mm_port_span, peripheral_span};
     reg.insert(reg.end(), pair<string, register_info>(name, r));
     return true;
 }
 
-bool CMMap::update_register(const string name, const uint32_t base, const uint32_t n_mm_ports,
+bool CMMap::update_register(const string name, const uint32_t base, const uint32_t n_peripherals, const uint32_t n_mm_ports,
                             const uint32_t span, const uint32_t mask,
-                            const uint32_t shift, const string access,
+                            const uint32_t shift, const uint32_t n_fields, const string access, const string radix,
                             const string type, const uint32_t peripheral_span, const uint32_t mm_port_span)
 {
     // cout << "CMMap::update_register: " << name << endl;
@@ -120,11 +120,14 @@ bool CMMap::update_register(const string name, const uint32_t base, const uint32
         return false;
     }
     reg[name].type = type;
+    reg[name].radix = radix;
     reg[name].access = access;
     reg[name].shift = shift;
+    reg[name].n_fields = n_fields;
     reg[name].mask = mask;
     reg[name].span = span;
     reg[name].base = base;
+    reg[name].n_peripherals = n_peripherals;
     reg[name].n_mm_ports = n_mm_ports;
     reg[name].mm_port_span = mm_port_span;
     reg[name].peripheral_span = peripheral_span;
diff --git a/src/registers.h b/src/registers.h
index 04d1d5fd4b0d2d93106acb63a039f00665b1d6da..17bb6c274aaf9e69aa6a45aefa404f97c22b3c44 100644
--- a/src/registers.h
+++ b/src/registers.h
@@ -64,12 +64,15 @@ private:
 
   typedef struct {
     uint32_t base;
+    uint32_t n_peripherals;
     uint32_t n_mm_ports;
     uint32_t span;
     uint32_t mask;
     uint32_t shift;
+    uint32_t n_fields;
     std::string access;
     std::string type;
+    std::string radix;
     uint32_t mm_port_span;
     uint32_t peripheral_span;
   } register_info;
@@ -81,11 +84,12 @@ public:
    ~CMMap();
    bool empty() { return reg.empty(); }
    void clear() { reg.clear(); }
-   bool add_register(const std::string name, const uint32_t base, const uint32_t n_mm_ports, const uint32_t span,
-                     const uint32_t mask, const uint32_t shift, const std::string access,
+   bool add_register(const std::string name, const uint32_t base, const uint32_t n_peripherals, const uint32_t n_mm_ports, const uint32_t span,
+                     const uint32_t mask, const uint32_t shift, const uint32_t n_fields, const std::string access, const std::string radix,
                      const std::string type, const uint32_t peripheral_span, const uint32_t mm_port_span);
-   bool update_register(const std::string name, const uint32_t base, const uint32_t n_mm_ports, const uint32_t span,
-                     const uint32_t mask, const uint32_t shift, const std::string access,
+
+   bool update_register(const std::string name, const uint32_t base, const uint32_t n_peripherals, const uint32_t n_mm_ports, const uint32_t span,
+                     const uint32_t mask, const uint32_t shift, const uint32_t n_fields, const std::string access, const std::string radix,
                      const std::string type, const uint32_t peripheral_span, const uint32_t mm_port_span);
 
    bool find_register(std::string name);
@@ -97,7 +101,10 @@ public:
    std::string getPerm(const std::string name) { return reg[name].access; }
    uint32_t getMask(const std::string name) { return reg[name].mask; }
    uint32_t getShift(const std::string name) { return reg[name].shift; }
+   uint32_t getNFields(const std::string name) { return reg[name].n_fields; }
+   std::string getRadix(const std::string name) { return reg[name].radix; }
    std::string getType(const std::string name) { return reg[name].type; }
+   uint32_t getNPeripherals(const std::string name) { return reg[name].n_peripherals; }
    uint32_t getNPorts(const std::string name) { return reg[name].n_mm_ports; }
    uint32_t getPortSpan(const std::string name) { return reg[name].mm_port_span; }
    uint32_t getPeripheralSpan(const std::string name) { return reg[name].peripheral_span; }
diff --git a/src/tools/mmap.cpp b/src/tools/mmap.cpp
index a14315eb00451ea62076cffa30885e2056ab7b2c..1dd0a2e0db9e8f5f71f1df2b789c7705953e6066 100644
--- a/src/tools/mmap.cpp
+++ b/src/tools/mmap.cpp
@@ -72,11 +72,14 @@ void mmap_add_register(CMMap& regmap, mm_info_t mm_info)
             if (update) {
                 regmap.update_register(full_name,
                                        addr,
+                                       mm_info.n_peripherals,
                                        mm_info.n_ports,
                                        mm_info.span,
                                        mm_info.mm_mask,
                                        mm_info.shift,
+                                       mm_info.n_fields,
                                        mm_info.acces_mode,
+                                       mm_info.radix,
                                        mm_info.port_type,
                                        mm_info.peripheral_span,
                                        mm_info.mm_port_span);
@@ -84,11 +87,14 @@ void mmap_add_register(CMMap& regmap, mm_info_t mm_info)
             else {
                 regmap.add_register(full_name,
                                     addr,
+                                    mm_info.n_peripherals,
                                     mm_info.n_ports,
                                     mm_info.span,
                                     mm_info.mm_mask,
                                     mm_info.shift,
+                                    mm_info.n_fields,
                                     mm_info.acces_mode,
+                                    mm_info.radix,
                                     mm_info.port_type,
                                     mm_info.peripheral_span,
                                     mm_info.mm_port_span);
diff --git a/src/tr.cpp b/src/tr.cpp
index 10b3dc2e4d8c2ffb052ebc9ecc0e3ce47fc50ae9..0a578c3f03055553f6442fe6d96d9d9de35d528f 100644
--- a/src/tr.cpp
+++ b/src/tr.cpp
@@ -49,15 +49,15 @@ TranslatorMap::TranslatorMap()
 {
     translatorMap = new CPointMap();
 
-    translatorMap->add_register("TR_fpga_mask_R",                "-", SD.n_fpgas, 1, "RO", REG_FORMAT_BOOLEAN);
-    translatorMap->add_register("TR_fpga_mask_RW",               "-", SD.n_fpgas, 1, "RW", REG_FORMAT_BOOLEAN);
+    translatorMap->add_register("TR_fpga_mask_R",                "-", SD.n_fpgas, 1, "RO", REG_FORMAT_UINT8);
+    translatorMap->add_register("TR_fpga_mask_RW",               "-", SD.n_fpgas, 1, "RW", REG_FORMAT_UINT8);
     translatorMap->add_register("TR_software_version_R",         "-", 1,          1, "RO", REG_FORMAT_STRING);
     translatorMap->add_register("TR_start_time_R",               "-", 1,          1, "RO", REG_FORMAT_INT64);
-    // translatorMap->add_register("TR_tod_client_status_R",        "-", 1,       1, "RO", REG_FORMAT_BOOLEAN);  // TODO: PTP client is part of linux, can I get a status?
+    // translatorMap->add_register("TR_tod_client_status_R",        "-", 1,       1, "RO", REG_FORMAT_UINT8);  // TODO: PTP client is part of linux, can I get a status?
     translatorMap->add_register("TR_tod_R",                      "-", 1,          2, "RO", REG_FORMAT_INT64);
     translatorMap->add_register("TR_tod_pps_delta_R",            "-", 1,          1, "RO", REG_FORMAT_DOUBLE);
-    translatorMap->add_register("TR_fpga_communication_error_R", "-", SD.n_fpgas, 1, "RO", REG_FORMAT_BOOLEAN);
-    // translatorMap->add_register("TR_reload_RW",                  "-", 1,      1, "RW", REG_FORMAT_BOOLEAN);  // Maybe for future.
+    translatorMap->add_register("TR_fpga_communication_error_R", "-", SD.n_fpgas, 1, "RO", REG_FORMAT_UINT8);
+    // translatorMap->add_register("TR_reload_RW",                  "-", 1,      1, "RW", REG_FORMAT_UINT8);  // Maybe for future.
     translatorMap->add_register("TR_sdp_config_first_fpga_nr_R", "-", 1,          1, "RO", REG_FORMAT_UINT32);
     translatorMap->add_register("TR_sdp_config_nof_fpgas_R",     "-", 1,          1, "RO", REG_FORMAT_UINT32);
     translatorMap->add_register("TR_sdp_config_nof_beamsets_R",  "-", 1,          1, "RO", REG_FORMAT_UINT32);