Select Git revision
fpga_map.cpp
Forked from
LOFAR2.0 / sdptr
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
fpga_map.cpp 42.99 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_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_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_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_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_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_subband_spectral_inversion_R", SUBBAND_SPECTRAL_INVERSION, nFpgas, 1, "RO", REG_FORMAT_BOOLEAN);
pointMap->add_register("FPGA_subband_spectral_inversion_RW", SUBBAND_SPECTRAL_INVERSION, nFpgas, 1, "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_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;
}