Select Git revision
fpga_map.cpp

L2SDP-998: add pps_error_cnt
Pieter Donker authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
fpga_map.cpp 47.14 KiB
/* *************************************************************************
* Copyright 2020
* ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
* P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* *********************************************************************** */
/* *************************************************************************
* Author:
* . Leon Hiemstra
* . Pieter Donker
* Purpose:
* . opc-ua to ucp translator
* Description:
* . class with fpga registers available for opc-ua server
* *********************************************************************** */
// You need to compile with _REENTRANT defined since this uses threads
#ifndef _REENTRANT
#define _REENTRANT 1
#endif
#include <cstdio>
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <exception>
#include <unistd.h>
#include <thread>
#include <chrono>
#include "sdptr.h"
#include "constants.h"
#include "fpga_map.h"
#include "tools/loguru.h"
#include "periph/fpga.h"
using namespace std;
// Everything addressed with FPGA_...
extern int debug;
extern Serverdat SD;
FpgaMap::FpgaMap()
{
nFilterbanks = (uint32_t)SD.n_filterbanks;
nBeamsets = (uint32_t)SD.n_beamsets;
nFpgas = (uint32_t)SD.n_fpgas;
pointMap = new CPointMap();
// Add all opc-ua points:
// opc-ua name, intern cmdID, n_nodes, n_data, permision, data_format
pointMap->add_register("FPGA_ucp_block_comm_R", UCP_BLOCK, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_ucp_block_comm_RW", UCP_BLOCK, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_ucp_status_R", UCP_STATUS, nFpgas, 6, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_ucp_status_reset_WO", UCP_STATUS, nFpgas, 1, "WO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_temp_R", TEMP, nFpgas, 1, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_firmware_version_R", FIRMWARE_VERSION, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_hardware_version_R", HARDWARE_VERSION, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_global_node_index_R", GLOBAL_NODE_INDEX, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sst_offload_weighted_subbands_R", SST_OFFLOAD_WEIGHTED_SUBBANDS, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_sst_offload_weighted_subbands_RW", SST_OFFLOAD_WEIGHTED_SUBBANDS, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_sst_offload_enable_R", SST_OFFLOAD_ENABLE, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_sst_offload_enable_RW", SST_OFFLOAD_ENABLE, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_sst_offload_hdr_eth_destination_mac_R", SST_OFFLOAD_HDR_ETH_DESTINATION_MAC, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_sst_offload_hdr_eth_destination_mac_RW", SST_OFFLOAD_HDR_ETH_DESTINATION_MAC, nFpgas, 1, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_sst_offload_hdr_ip_destination_address_R", SST_OFFLOAD_HDR_IP_DESTINATION_ADDRESS, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_sst_offload_hdr_ip_destination_address_RW", SST_OFFLOAD_HDR_IP_DESTINATION_ADDRESS, nFpgas, 1, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_sst_offload_hdr_udp_destination_port_R", SST_OFFLOAD_HDR_UDP_DESTINATION_PORT, nFpgas, 1, "RO", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_sst_offload_hdr_udp_destination_port_RW", SST_OFFLOAD_HDR_UDP_DESTINATION_PORT, nFpgas, 1, "RW", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_sst_offload_nof_packets_R", SST_OFFLOAD_NOF_PACKETS, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_sst_offload_nof_valid_R", SST_OFFLOAD_NOF_VALID, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_sst_offload_bsn_R", SST_OFFLOAD_BSN, nFpgas, 1, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_bst_offload_enable_R", BST_OFFLOAD_ENABLE, nFpgas, nBeamsets, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_bst_offload_enable_RW", BST_OFFLOAD_ENABLE, nFpgas, nBeamsets, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_bst_offload_hdr_eth_destination_mac_R", BST_OFFLOAD_HDR_ETH_DESTINATION_MAC, nFpgas, nBeamsets, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_bst_offload_hdr_eth_destination_mac_RW", BST_OFFLOAD_HDR_ETH_DESTINATION_MAC, nFpgas, nBeamsets, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_bst_offload_hdr_ip_destination_address_R", BST_OFFLOAD_HDR_IP_DESTINATION_ADDRESS, nFpgas, nBeamsets, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_bst_offload_hdr_ip_destination_address_RW", BST_OFFLOAD_HDR_IP_DESTINATION_ADDRESS, nFpgas, nBeamsets, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_bst_offload_hdr_udp_destination_port_R", BST_OFFLOAD_HDR_UDP_DESTINATION_PORT, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_bst_offload_hdr_udp_destination_port_RW", BST_OFFLOAD_HDR_UDP_DESTINATION_PORT, nFpgas, nBeamsets, "RW", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_bst_offload_nof_packets_R", BST_OFFLOAD_NOF_PACKETS, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bst_offload_nof_valid_R", BST_OFFLOAD_NOF_VALID, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bst_offload_bsn_R", BST_OFFLOAD_BSN, nFpgas, nBeamsets, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_subband_select_R", XST_SUBBAND_SELECT, nFpgas, 1+C_N_crosslets_max, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_subband_select_RW", XST_SUBBAND_SELECT, nFpgas, 1+C_N_crosslets_max, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_integration_interval_R", XST_INTEGRATION_INTERVAL, nFpgas, 1, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_xst_integration_interval_RW", XST_INTEGRATION_INTERVAL, nFpgas, 1, "RW", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_xst_start_time_R", XST_START_TIME, nFpgas, 1, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_xst_start_time_RW", XST_START_TIME, nFpgas, 1, "RW", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_xst_processing_enable_R", XST_PROCESSING_ENABLE, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_processing_enable_RW", XST_PROCESSING_ENABLE, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_offload_enable_R", XST_OFFLOAD_ENABLE, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_offload_enable_RW", XST_OFFLOAD_ENABLE, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_offload_nof_crosslets_R", XST_OFFLOAD_NOF_CROSSLETS, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_offload_nof_crosslets_RW", XST_OFFLOAD_NOF_CROSSLETS, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_offload_hdr_eth_destination_mac_R", XST_OFFLOAD_HDR_ETH_DESTINATION_MAC, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_xst_offload_hdr_eth_destination_mac_RW", XST_OFFLOAD_HDR_ETH_DESTINATION_MAC, nFpgas, 1, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_xst_offload_hdr_ip_destination_address_R", XST_OFFLOAD_HDR_IP_DESTINATION_ADDRESS, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_xst_offload_hdr_ip_destination_address_RW", XST_OFFLOAD_HDR_IP_DESTINATION_ADDRESS, nFpgas, 1, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_xst_offload_hdr_udp_destination_port_R", XST_OFFLOAD_HDR_UDP_DESTINATION_PORT, nFpgas, 1, "RO", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_xst_offload_hdr_udp_destination_port_RW", XST_OFFLOAD_HDR_UDP_DESTINATION_PORT, nFpgas, 1, "RW", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_xst_input_bsn_at_sync_R", XST_INPUT_SYNC_AT_BSN, nFpgas, 1, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_output_sync_bsn_R", XST_OUTPUT_SYNC_BSN, nFpgas, 1, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_offload_nof_packets_R", XST_OFFLOAD_NOF_PACKETS, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_offload_nof_valid_R", XST_OFFLOAD_NOF_VALID, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_offload_bsn_R", XST_OFFLOAD_BSN, nFpgas, 1, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_ring_nof_transport_hops_R", XST_RING_NOF_TRANSPORT_HOPS, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_ring_nof_transport_hops_RW", XST_RING_NOF_TRANSPORT_HOPS, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_ring_rx_clear_total_counts_R", XST_RING_RX_CLEAR_TOTAL_COUNTS, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_ring_rx_clear_total_counts_RW", XST_RING_RX_CLEAR_TOTAL_COUNTS, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_rx_align_stream_enable_R", XST_RX_ALIGN_STREAM_ENABLE, nFpgas, C_P_sq, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_rx_align_stream_enable_RW", XST_RX_ALIGN_STREAM_ENABLE, nFpgas, C_P_sq, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_xst_rx_align_nof_replaced_packets_R", XST_RX_ALIGN_NOF_REPLACED_PACKETS, nFpgas, C_P_sq, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_ring_rx_total_nof_packets_received_R", XST_RING_RX_TOTAL_NOF_PACKETS_RECEIVED, nFpgas, 1, "RO", REG_FORMAT_UINT64);
pointMap->add_register("FPGA_xst_ring_rx_total_nof_packets_discarded_R", XST_RING_RX_TOTAL_NOF_PACKETS_DISCARDED, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_ring_rx_total_nof_sync_received_R", XST_RING_RX_TOTAL_NOF_SYNC_RECEIVED, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_ring_rx_total_nof_sync_discarded_R", XST_RING_RX_TOTAL_NOF_SYNC_DISCARDED, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_xst_ring_rx_bsn_R", XST_RING_RX_BSN, nFpgas, nFpgas, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_ring_rx_nof_packets_R", XST_RING_RX_NOF_PACKETS, nFpgas, nFpgas, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_ring_rx_nof_valid_R", XST_RING_RX_NOF_VALID, nFpgas, nFpgas, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_ring_rx_latency_R", XST_RING_RX_LATENCY, nFpgas, nFpgas, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_rx_align_bsn_R", XST_RX_ALIGN_BSN, nFpgas, C_P_sq, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_rx_align_nof_packets_R", XST_RX_ALIGN_NOF_PACKETS, nFpgas, C_P_sq, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_rx_align_nof_valid_R", XST_RX_ALIGN_NOF_VALID, nFpgas, C_P_sq, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_rx_align_latency_R", XST_RX_ALIGN_LATENCY, nFpgas, C_P_sq, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_aligned_bsn_R", XST_ALIGNED_BSN, nFpgas, 1, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_aligned_nof_packets_R", XST_ALIGNED_NOF_PACKETS, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_aligned_nof_valid_R", XST_ALIGNED_NOF_VALID, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_aligned_latency_R", XST_ALIGNED_LATENCY, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_ring_tx_bsn_R", XST_RING_TX_BSN, nFpgas, nFpgas, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_xst_ring_tx_nof_packets_R", XST_RING_TX_NOF_PACKETS, nFpgas, nFpgas, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_ring_tx_nof_valid_R", XST_RING_TX_NOF_VALID, nFpgas, nFpgas, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_xst_ring_tx_latency_R", XST_RING_TX_LATENCY, nFpgas, nFpgas, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_beamlet_output_enable_R", BEAMLET_OUTPUT_ENABLE, nFpgas, nBeamsets, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_beamlet_output_enable_RW", BEAMLET_OUTPUT_ENABLE, nFpgas, nBeamsets, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_beamlet_output_scale_R", BEAMLET_OUTPUT_SCALE, nFpgas, nBeamsets, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_beamlet_output_scale_RW", BEAMLET_OUTPUT_SCALE, nFpgas, nBeamsets, "RW", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_beamlet_output_nof_beamlets_R", BEAMLET_OUTPUT_NOF_BEAMLETS, nFpgas, 1, "RO", REG_FORMAT_UINT32); // not implemented in sdpfw
pointMap->add_register("FPGA_beamlet_output_nof_beamlets_RW", BEAMLET_OUTPUT_NOF_BEAMLETS, nFpgas, 1, "RW", REG_FORMAT_UINT32); // not implemented in sdpfw
pointMap->add_register("FPGA_beamlet_output_hdr_eth_destination_mac_R", BEAMLET_OUTPUT_HDR_ETH_DESTINATION_MAC, nFpgas, nBeamsets, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_eth_destination_mac_RW", BEAMLET_OUTPUT_HDR_ETH_DESTINATION_MAC, nFpgas, nBeamsets, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_ip_destination_address_R", BEAMLET_OUTPUT_HDR_IP_DESTINATION_ADDRESS, nFpgas, nBeamsets, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_ip_destination_address_RW", BEAMLET_OUTPUT_HDR_IP_DESTINATION_ADDRESS, nFpgas, nBeamsets, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_udp_destination_port_R", BEAMLET_OUTPUT_HDR_UDP_DESTINATION_PORT, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_beamlet_output_hdr_udp_destination_port_RW", BEAMLET_OUTPUT_HDR_UDP_DESTINATION_PORT, nFpgas, nBeamsets, "RW", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_beamlet_output_nof_destinations_R", BEAMLET_OUTPUT_NOF_DESTINATIONS, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT8);
pointMap->add_register("FPGA_beamlet_output_nof_destinations_RW", BEAMLET_OUTPUT_NOF_DESTINATIONS, nFpgas, nBeamsets, "RW", REG_FORMAT_UINT8);
pointMap->add_register("FPGA_beamlet_output_multiple_hdr_eth_destination_mac_R", BEAMLET_OUTPUT_MULTIPLE_HDR_ETH_DESTINATION_MAC, nFpgas, nBeamsets*C_N_bdo_destinations_mm, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_multiple_hdr_eth_destination_mac_RW", BEAMLET_OUTPUT_MULTIPLE_HDR_ETH_DESTINATION_MAC, nFpgas, nBeamsets*C_N_bdo_destinations_mm, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_multiple_hdr_ip_destination_address_R", BEAMLET_OUTPUT_MULTIPLE_HDR_IP_DESTINATION_ADDRESS, nFpgas, nBeamsets*C_N_bdo_destinations_mm, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_multiple_hdr_ip_destination_address_RW", BEAMLET_OUTPUT_MULTIPLE_HDR_IP_DESTINATION_ADDRESS, nFpgas, nBeamsets*C_N_bdo_destinations_mm, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_multiple_hdr_udp_destination_port_R", BEAMLET_OUTPUT_MULTIPLE_HDR_UDP_DESTINATION_PORT, nFpgas, nBeamsets*C_N_bdo_destinations_mm, "RO", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_beamlet_output_multiple_hdr_udp_destination_port_RW", BEAMLET_OUTPUT_MULTIPLE_HDR_UDP_DESTINATION_PORT, nFpgas, nBeamsets*C_N_bdo_destinations_mm, "RW", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_beamlet_output_nof_destinations_act_R", BEAMLET_OUTPUT_NOF_DESTINATIONS_ACT, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT8);
pointMap->add_register("FPGA_beamlet_output_nof_destinations_max_R", BEAMLET_OUTPUT_NOF_DESTINATIONS_MAX, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT8);
pointMap->add_register("FPGA_beamlet_output_nof_blocks_per_packet_R", BEAMLET_OUTPUT_NOF_BLOCKS_PER_PACKET, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT8);
pointMap->add_register("FPGA_beamlet_output_hdr_eth_source_mac_R", BEAMLET_OUTPUT_HDR_ETH_SOURCE_MAC, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_eth_source_mac_RW", BEAMLET_OUTPUT_HDR_ETH_SOURCE_MAC, nFpgas, 1, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_ip_source_address_R", BEAMLET_OUTPUT_HDR_IP_SOURCE_ADDRESS, nFpgas, 1, "RO", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_ip_source_address_RW", BEAMLET_OUTPUT_HDR_IP_SOURCE_ADDRESS, nFpgas, 1, "RW", REG_FORMAT_STRING);
pointMap->add_register("FPGA_beamlet_output_hdr_udp_source_port_R", BEAMLET_OUTPUT_HDR_UDP_SOURCE_PORT, nFpgas, 1, "RO", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_beamlet_output_hdr_udp_source_port_RW", BEAMLET_OUTPUT_HDR_UDP_SOURCE_PORT, nFpgas, 1, "RW", REG_FORMAT_UINT16);
pointMap->add_register("FPGA_beamlet_subband_select_R", BEAMLET_SUBBAND_SELECT, nFpgas, C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_beamlet_subband_select_RW", BEAMLET_SUBBAND_SELECT, nFpgas, C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_beamlet_output_nof_packets_R", BEAMLET_OUTPUT_NOF_PACKETS, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_beamlet_output_nof_valid_R", BEAMLET_OUTPUT_NOF_VALID, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_beamlet_output_bsn_R", BEAMLET_OUTPUT_BSN, nFpgas, nBeamsets, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_beamlet_output_ready_R", BEAMLET_OUTPUT_READY, nFpgas, nBeamsets, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_beamlet_output_xon_R", BEAMLET_OUTPUT_XON, nFpgas, nBeamsets, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_processing_enable_R", PROCESSING_ENABLE, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_processing_enable_RW", PROCESSING_ENABLE, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_sdp_info_station_id_R", SDP_INFO_STATION_ID, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_station_id_RW", SDP_INFO_STATION_ID, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_antenna_field_index_R", SDP_INFO_ANTENNA_FIELD_INDEX, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_antenna_field_index_RW", SDP_INFO_ANTENNA_FIELD_INDEX, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_observation_id_R", SDP_INFO_OBSERVATION_ID, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_observation_id_RW", SDP_INFO_OBSERVATION_ID, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_nyquist_sampling_zone_index_R", SDP_INFO_NYQUIST_SAMPLING_ZONE_INDEX, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_nyquist_sampling_zone_index_RW", SDP_INFO_NYQUIST_SAMPLING_ZONE_INDEX, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_antenna_band_index_R", SDP_INFO_ANTENNA_BAND_INDEX, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_antenna_band_index_RW", SDP_INFO_ANTENNA_BAND_INDEX, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_f_adc_R", SDP_INFO_F_ADC, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_fsub_type_R", SDP_INFO_FSUB_TYPE, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_sdp_info_block_period_R", SDP_INFO_BLOCK_PERIOD, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_wg_enable_R", WG_ENABLE, nFpgas, C_S_pn, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_wg_enable_RW", WG_ENABLE, nFpgas, C_S_pn, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_wg_amplitude_R", WG_AMPLITUDE, nFpgas, C_S_pn, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_wg_amplitude_RW", WG_AMPLITUDE, nFpgas, C_S_pn, "RW", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_wg_phase_R", WG_PHASE, nFpgas, C_S_pn, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_wg_phase_RW", WG_PHASE, nFpgas, C_S_pn, "RW", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_wg_frequency_R", WG_FREQUENCY, nFpgas, C_S_pn, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_wg_frequency_RW", WG_FREQUENCY, nFpgas, C_S_pn, "RW", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_signal_input_bsn_R", SIGNAL_INPUT_BSN, nFpgas, 1, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_signal_input_nof_blocks_R", SIGNAL_INPUT_NOF_BLOCKS, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_signal_input_nof_samples_R", SIGNAL_INPUT_NOF_SAMPLES, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_jesd204b_csr_rbd_count_R", JESD204B_CSR_RBD_COUNT, nFpgas, C_S_pn, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_jesd204b_csr_dev_syncn_R", JESD204B_CSR_DEV_SYNCN, nFpgas, C_S_pn, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_jesd204b_rx_err0_R", JESD204B_RX_ERR0, nFpgas, C_S_pn, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_jesd204b_rx_err1_R", JESD204B_RX_ERR1, nFpgas, C_S_pn, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_jesd_ctrl_R", JESD_CTRL, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_jesd_ctrl_RW", JESD_CTRL, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_signal_input_mean_R", SIGNAL_INPUT_MEAN, nFpgas, C_S_pn, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_signal_input_rms_R", SIGNAL_INPUT_RMS, nFpgas, C_S_pn, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_signal_input_std_R", SIGNAL_INPUT_STD, nFpgas, C_S_pn, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_signal_input_samples_delay_R", SIGNAL_INPUT_SAMPLES_DELAY, nFpgas, C_S_pn, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_signal_input_samples_delay_RW", SIGNAL_INPUT_SAMPLES_DELAY, nFpgas, C_S_pn, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_subband_weights_R", SUBBAND_WEIGHTS, nFpgas, nFilterbanks*C_S_pn*C_N_sub, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_subband_weights_RW", SUBBAND_WEIGHTS, nFpgas, nFilterbanks*C_S_pn*C_N_sub, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_subband_weights_cross_R", SUBBAND_WEIGHTS_CROSS, nFpgas, nFilterbanks*C_S_pn*C_N_sub, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_subband_weights_cross_RW", SUBBAND_WEIGHTS_CROSS, nFpgas, nFilterbanks*C_S_pn*C_N_sub, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_subband_fir_filter_coefficients_R", SUBBAND_FIR_FILTER_COEFFICIENTS, nFpgas, nFilterbanks*C_N_tap*C_N_fft, "RO", REG_FORMAT_INT16);
pointMap->add_register("FPGA_subband_fir_filter_coefficients_RW", SUBBAND_FIR_FILTER_COEFFICIENTS, nFpgas, nFilterbanks*C_N_tap*C_N_fft, "RW", REG_FORMAT_INT16);
pointMap->add_register("FPGA_scrap_R", SCRAP, nFpgas, C_N_scrap, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_scrap_RW", SCRAP, nFpgas, C_N_scrap, "RW", REG_FORMAT_UINT32);
// Beam Former Weights
// FPGA_bf_weights_R and FPGA_bf_weights_RW => raw data
pointMap->add_register("FPGA_bf_weights_R", BF_WEIGHTS, nFpgas, nBeamsets*C_N_pol_bf*C_A_pn*C_N_pol*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_RW", BF_WEIGHTS, nFpgas, nBeamsets*C_N_pol_bf*C_A_pn*C_N_pol*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xx_yy_R", BF_WEIGHTS_XX_YY, nFpgas, C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xx_yy_RW", BF_WEIGHTS_XX_YY, nFpgas, C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xy_yx_R", BF_WEIGHTS_XY_YX, nFpgas, C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xy_yx_RW", BF_WEIGHTS_XY_YX, nFpgas, C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xx_xy_yx_yy_R", BF_WEIGHTS_XX_XY_YX_YY, nFpgas, C_N_pol_bf*C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xx_xy_yx_yy_RW", BF_WEIGHTS_XX_XY_YX_YY, nFpgas, C_N_pol_bf*C_A_pn*C_N_pol*nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xx_R", BF_WEIGHTS_XX, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xx_RW", BF_WEIGHTS_XX, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xy_R", BF_WEIGHTS_XY, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_xy_RW", BF_WEIGHTS_XY, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_yx_R", BF_WEIGHTS_YX, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_yx_RW", BF_WEIGHTS_YX, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_yy_R", BF_WEIGHTS_YY, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RO", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_yy_RW", BF_WEIGHTS_YY, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_pp_R", BF_WEIGHTS_PP, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_weights_pp_RW", BF_WEIGHTS_PP, nFpgas, C_A_pn* nBeamsets*C_S_sub_bf, "RW", REG_FORMAT_UINT32); // cint16
pointMap->add_register("FPGA_bf_ring_nof_transport_hops_R", BF_RING_NOF_TRANSPORT_HOPS, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_bf_ring_nof_transport_hops_RW", BF_RING_NOF_TRANSPORT_HOPS, nFpgas, nBeamsets, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_bf_ring_rx_clear_total_counts_R", BF_RING_RX_CLEAR_TOTAL_COUNTS, nFpgas, nBeamsets, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_bf_ring_rx_clear_total_counts_RW", BF_RING_RX_CLEAR_TOTAL_COUNTS, nFpgas, nBeamsets, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_bf_rx_align_stream_enable_R", BF_RX_ALIGN_STREAM_ENABLE, nFpgas, nBeamsets*C_P_sum, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_bf_rx_align_stream_enable_RW", BF_RX_ALIGN_STREAM_ENABLE, nFpgas, nBeamsets*C_P_sum, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_bf_rx_align_nof_replaced_packets_R", BF_RX_ALIGN_NOF_REPLACED_PACKETS, nFpgas, nBeamsets*C_P_sum, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_ring_rx_total_nof_packets_received_R", BF_RING_RX_TOTAL_NOF_PACKETS_RECEIVED, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT64);
pointMap->add_register("FPGA_bf_ring_rx_total_nof_packets_discarded_R", BF_RING_RX_TOTAL_NOF_PACKETS_DISCARDED, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_bf_ring_rx_total_nof_sync_received_R", BF_RING_RX_TOTAL_NOF_SYNC_RECEIVED, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_bf_ring_rx_total_nof_sync_discarded_R", BF_RING_RX_TOTAL_NOF_SYNC_DISCARDED, nFpgas, nBeamsets, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_bf_ring_rx_bsn_R", BF_RING_RX_BSN, nFpgas, nBeamsets, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_bf_ring_rx_nof_packets_R", BF_RING_RX_NOF_PACKETS, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_ring_rx_nof_valid_R", BF_RING_RX_NOF_VALID, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_ring_rx_latency_R", BF_RING_RX_LATENCY, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_rx_align_bsn_R", BF_RX_ALIGN_BSN, nFpgas, nBeamsets*C_P_sum, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_bf_rx_align_nof_packets_R", BF_RX_ALIGN_NOF_PACKETS, nFpgas, nBeamsets*C_P_sum, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_rx_align_nof_valid_R", BF_RX_ALIGN_NOF_VALID, nFpgas, nBeamsets*C_P_sum, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_rx_align_latency_R", BF_RX_ALIGN_LATENCY, nFpgas, nBeamsets*C_P_sum, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_aligned_bsn_R", BF_ALIGNED_BSN, nFpgas, nBeamsets, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_bf_aligned_nof_packets_R", BF_ALIGNED_NOF_PACKETS, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_aligned_nof_valid_R", BF_ALIGNED_NOF_VALID, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_aligned_latency_R", BF_ALIGNED_LATENCY, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_ring_tx_bsn_R", BF_RING_TX_BSN, nFpgas, nBeamsets, "RO", REG_FORMAT_INT64);
pointMap->add_register("FPGA_bf_ring_tx_nof_packets_R", BF_RING_TX_NOF_PACKETS, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_ring_tx_nof_valid_R", BF_RING_TX_NOF_VALID, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_bf_ring_tx_latency_R", BF_RING_TX_LATENCY, nFpgas, nBeamsets, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_signal_input_data_buffer_R", SIGNAL_INPUT_DATA_BUFFER, nFpgas, C_S_pn*C_V_si_db, "RO", REG_FORMAT_INT16);
pointMap->add_register("FPGA_signal_input_histogram_R", SIGNAL_INPUT_HISTOGRAM, nFpgas, C_S_pn*C_V_si_histogram, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_spectral_inversion_R", SPECTRAL_INVERSION, nFpgas, C_S_pn, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_spectral_inversion_RW", SPECTRAL_INVERSION, nFpgas, C_S_pn, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_pps_expected_cnt_R", PPS_EXPECTED_CNT, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_pps_expected_cnt_RW", PPS_EXPECTED_CNT, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_pps_present_R", PPS_PRESENT, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_pps_capture_cnt_R", PPS_CAPTURE_CNT, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_pps_error_cnt_R", PPS_ERROR_CNT, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_monitor_pps_offset_time_R", MONITOR_PPS_OFFSET_TIME, nFpgas, 1, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_time_since_last_pps_R", TIME_SINCE_LAST_PPS, nFpgas, 1, "RO", REG_FORMAT_DOUBLE);
pointMap->add_register("FPGA_boot_image_R", BOOT_IMAGE, nFpgas, 1, "RO", REG_FORMAT_INT32);
pointMap->add_register("FPGA_boot_image_RW", BOOT_IMAGE, nFpgas, 1, "RW", REG_FORMAT_INT32);
pointMap->add_register("FPGA_flash_addr_R", FLASH_ADDR, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_flash_addr_RW", FLASH_ADDR, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_flash_protect_R", FLASH_PROTECT, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_flash_protect_RW", FLASH_PROTECT, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_flash_erase_R", FLASH_ERASE_SECTOR, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_flash_erase_RW", FLASH_ERASE_SECTOR, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_flash_pages_R", FLASH_PAGES, nFpgas, 16384, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_flash_pages_RW", FLASH_PAGES, nFpgas, 16384, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_ring_node_offset_R", RING_NODE_OFFSET, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_ring_node_offset_RW", RING_NODE_OFFSET, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_ring_nof_nodes_R", RING_NOF_NODES, nFpgas, 1, "RO", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_ring_nof_nodes_RW", RING_NOF_NODES, nFpgas, 1, "RW", REG_FORMAT_UINT32);
pointMap->add_register("FPGA_ring_use_cable_to_next_rn_R", RING_USE_CABLE_TO_NEXT_RN, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_ring_use_cable_to_next_rn_RW", RING_USE_CABLE_TO_NEXT_RN, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_ring_use_cable_to_previous_rn_R", RING_USE_CABLE_TO_PREVIOUS_RN, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_ring_use_cable_to_previous_rn_RW", RING_USE_CABLE_TO_PREVIOUS_RN, nFpgas, 1, "RW", REG_FORMAT_BOOLEAN);
}
FpgaMap::~FpgaMap()
{
if (pointMap != NULL) { delete pointMap; pointMap = NULL; }
for (auto node : FPGA) { delete node; node = NULL; }
}
void FpgaMap::add_nodes(void)
{
for (auto nc : SD.node_config) {
Node *node = new Node(nc.ipaddr, nc.udp_port, nc.board_nr, nc.fpga_nr, nFilterbanks, nBeamsets);
FPGA.push_back(node);
// add global node nr to nodes
nodes.push_back(nc.gn);
}
}
Node * FpgaMap::select_node(const int nr)
{
for (auto node : FPGA) {
if (node->GetGlobalNr() == (uint)nr) {
return node;
}
}
throw runtime_error("select_node: not found");
}
vector<bool> FpgaMap::get_all_masked_nodes(void)
{
vector<bool> masked;
for (auto node : FPGA) {
masked.push_back(node->isMasked());
}
return masked;
}
vector<bool> FpgaMap::get_all_offline_nodes(void)
{
vector<bool> online;
for (auto node : FPGA) {
online.push_back(!node->isOnline());
}
return online;
}
void FpgaMap::set_all_masked_nodes(std::vector<bool> masked)
{
for (uint idx = 0; idx<nFpgas; idx++) {
auto node = select_node(nodes[idx]);
node->setMasked(masked[idx]);
}
}
vector<double> FpgaMap::get_all_monitor_pps_offset_times(void)
{
vector<double> monitor_pps_offset_times;
for (auto node : FPGA) {
monitor_pps_offset_times.push_back(node->monitorPpsOffsetTime());
}
return monitor_pps_offset_times;
}
vector<struct timespec> FpgaMap::get_all_monitor_start_times(void)
{
vector<struct timespec> monitor_start_time;
for (auto node : FPGA) {
monitor_start_time.push_back(node->monitorStartTime());
}
return monitor_start_time;
}
CPointMap * FpgaMap::get_pointMap(void)
{
return pointMap;
}
bool FpgaMap::monitor(void)
{
for (uint idx=0; idx<nFpgas; idx++) {
auto node = select_node(nodes[idx]);
node->monitor();
}
return true;
}
/* read and write are called by the ua_server */
bool FpgaMap::read(char *data, const string& pointname)
{
return point(data, 'R', pointname);
}
bool FpgaMap::write(char *data, const string& pointname)
{
return point(data, 'W', pointname);
}
/* point() is only called by read() and write() and is used send/receive the single opc-ua request to/from all the nodes.
data: char buffer for send/receive data, buffer size is calculated in ua_server.cpp
cmd: ['R' | 'W'] read or write action.
pointname: opcua pointname
1) Check if read/write can be done on the requested pointname.
2) convert pointname to a cmd_id, cmd_id is a numeric id for the pointname without the access part.
3) The start pointer in the single data buffer for each node is calculated.
4) cmd is executed on all online nodes or all nodes if it is an intern point.
5) wait for status response from all nodes and return
*/
bool FpgaMap::point(char *data, const char cmd, const string& pointname)
{
char _cmd = cmd;
// check if pointname exists and can be read or writen
if (_cmd == 'R' && !pointMap->canRead(pointname)) { return false; }
else if (_cmd == 'W' && !pointMap->canWrite(pointname)) { return false; }
if (_cmd == 'R' && pointname.rfind("_RW") != string::npos) {
LOG_F(DEBUG, "Read from cache");
_cmd = 'r';
}
uint32_t cmd_id = pointMap->getCommandId(pointname);
uint32_t format = pointMap->getFormat(pointname);
size_t n_values = pointMap->getDataSize(pointname);
size_t n_nodes = pointMap->getNodesSize(pointname);
size_t data_size_bytes = n_values * reg_format_size_in_bytes(format);
// map with node status
// 1 = send request
// -1 = not online
// 2 = received response
map <int, int> node_status;
// loop over all nodes and execute requested command
for (uint idx = 0; idx<n_nodes; idx++) {
node_status.insert(node_status.end(), pair<int, int>(idx, 0));
auto node = select_node(nodes[idx]);
// if node online or an intern point exec_cmd.
if (node->isOnline() || cmd_id < MAX_ID_INTERN_POINT) {
uint32_t didx = 0;
didx = idx * data_size_bytes;
node->exec_cmd(_cmd, cmd_id, &(data[didx]), n_values, format);
node_status[idx] = 1;
} else {
node_status[idx] = -1;
}
}
// try to get all reply data, delete fpga from map if done
bool done = false;
while (!done) {
done = true;
for (uint idx = 0; idx<n_nodes; idx++) {
int state = node_status[idx];
if (state == 1) {
done = false;
auto node = select_node(nodes[idx]);
int stat = node->exec_reply(cmd_id);
// if stat = 0, still waiting for response
if (stat == 1) { // valid data
node_status[idx] = 2;
}
else if (stat == -1) { // no valid data
node_status[idx] = -1;
}
}
}
// to avoid 100% load while looping (waiting for reply)
this_thread::sleep_for(chrono::microseconds(2));
}
// make no response string
string no_response = "";
for (uint idx = 0; idx<n_nodes; idx++) {
auto node = select_node(nodes[idx]);
int state = node_status[idx];
if (state == -1) {
// If no response from the fpga (-1) add fpga number to the string
if (no_response == "") {
no_response = "No response from node(s): " + to_string(node->GetGlobalNr());
} else {
no_response += ", " + to_string(node->GetGlobalNr());
}
}
}
// if no_response string is not empty log string
if (no_response != "") { LOG_F(INFO, "%s", no_response.c_str()); }
return true;
}