diff --git a/src/fpga.cpp b/src/fpga.cpp index 7b36d9c4cfc1afcdbe8296f0f9678e82df25bdb9..e447b5ba84b4e66a84e2ff5d1dadbbdd0b842f1e 100644 --- a/src/fpga.cpp +++ b/src/fpga.cpp @@ -54,9 +54,6 @@ Fpga::Fpga(list<class Node*>& nodelist) // Add points: vector<int> nodes = get_all_nodes(); - pointMap->add_register("FPGA_mask_R", "fpga/enable_mask", nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN); - pointMap->add_register("FPGA_mask_RW", "fpga/enable_mask", nodes.size(), 1, "RW", REG_FORMAT_BOOLEAN); - pointMap->add_register("FPGA_status_R", "fpga/status", nodes.size(), 1, "RO", REG_FORMAT_BOOLEAN); pointMap->add_register("FPGA_temp_R", "fpga/temp", nodes.size(), 1, "RO", REG_FORMAT_DOUBLE); pointMap->add_register("FPGA_firmware_version_R", "fpga/firmware_version", nodes.size(), 1, "RO", REG_FORMAT_STRING); pointMap->add_register("FPGA_hardware_version_R", "fpga/hardware_version", nodes.size(), 1, "RO", REG_FORMAT_STRING); @@ -173,11 +170,48 @@ vector<bool> Fpga::get_all_enabled_nodes(void) { vector<bool> enabled; for (auto node : FPGA) { - enabled.push_back(node->GetEnabled()); + enabled.push_back(node->isEnabled()); } return enabled; } +vector<bool> Fpga::get_all_masked_nodes(void) +{ + vector<bool> masked; + for (auto node : FPGA) { + masked.push_back(node->isMasked()); + } + return masked; +} + +vector<bool> Fpga::get_all_offline_nodes(void) +{ + vector<bool> online; + for (auto node : FPGA) { + online.push_back(!node->isOnline()); + } + return online; +} + +void Fpga::set_all_masked_nodes(std::vector<bool> masked) +{ + vector<int> nodes = get_all_nodes(); + for (uint idx = 0; idx<nodes.size(); idx++) { + auto node = select_node(nodes[idx]); + node->setMasked(masked[idx]); + } +} + +vector<uint32_t> Fpga::get_all_pps_offset_cnt(void) +{ + vector<uint32_t> pps_offset_cnt; + for (auto node : FPGA) { + pps_offset_cnt.push_back(node->ppsOffsetCnt()); + } + return pps_offset_cnt; +} + + uint Fpga::node_number(Node *node) { return (node->GetUniboardNr() * 4) + node->GetLocalNr(); diff --git a/src/fpga.h b/src/fpga.h index cfa1ca83854e199b808d271100ba2e7b397b2c20..14f62ec1d3a79dc84cdcfaf38e264d6f10b14ba5 100644 --- a/src/fpga.h +++ b/src/fpga.h @@ -54,6 +54,11 @@ public: Node * select_node(const int nr); std::vector<int> get_all_nodes(void); std::vector<bool> get_all_enabled_nodes(void); + std::vector<bool> get_all_masked_nodes(void); + std::vector<bool> get_all_offline_nodes(void); + void set_all_masked_nodes(std::vector<bool> masked); + std::vector<uint32_t> get_all_pps_offset_cnt(void); + CPointMap * get_pointMap(void); uint node_number(Node *node); bool is_fpga(const std::string addr); diff --git a/src/map.cpp b/src/map.cpp index eb605595025d9d4078909d2516c43027cbae2659..d584a8111c5feb41cb2abb7e2b36a51165a0b053 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -64,7 +64,6 @@ bool UniboardMap::read(TermOutput& termout, return retval; } - bool UniboardMap::write(TermOutput& termout, const string addr, const unsigned int *data, diff --git a/src/node.cpp b/src/node.cpp index 270a87d483f4cfcfcdee8de50c5479372267267f..64cbe881e456f63fc982798ac02ed1c29832bb3a 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -161,13 +161,13 @@ Node::Node(const string ipaddr, const uint unb, const uint localnr, const string const string firmware, const uint firmware_version, const bool enabled) { // int ret; - myIPaddr = ipaddr; - - periph_fpga = new Periph_fpga(ipaddr, firmware, firmware_version, enabled); - UniboardNr = unb; LocalNr = localnr; GlobalNr = localnr + 4 * unb; + + myIPaddr = ipaddr; + periph_fpga = new Periph_fpga(GlobalNr, ipaddr, firmware, firmware_version, enabled); + if (type != "pn") { throw runtime_error("invalid node type: \"" + type + "\""); @@ -233,11 +233,31 @@ CMMap * Node::get_MMap(void) return periph_fpga->getMMap(); } -bool Node::GetEnabled(void) +bool Node::isEnabled(void) { - return periph_fpga->getEnabled(); + return periph_fpga->isEnabled(); } +bool Node::isOnline(void) +{ + return periph_fpga->isOnline(); +} + +bool Node::isMasked() +{ + return periph_fpga->isMasked(); +} + +void Node::setMasked(bool mask) +{ + periph_fpga->setMasked(mask); +} + +uint32_t Node::ppsOffsetCnt(void) { + return periph_fpga->ppsOffsetCnt(); +} + + bool Node::exec_cmd(const char cmd, const string relative_addr, const string type, const string instance, const unsigned int *data, const int nvalues, const int format) @@ -280,7 +300,7 @@ bool Node::exec_reply(TermOutput& termout) // cout << "received " << r->nof_vals << " bytes from worker node=" << GlobalNr // << " retval=" << r->retval << " datatype=" << r->datatype << endl; - if (GetEnabled() && !r->retval) { + if (isEnabled() && !r->retval) { //cout << "no retval" << endl; throw runtime_error("no retval"); } diff --git a/src/node.h b/src/node.h index 52ce52b8b364a2bf0bff15f8a5fce39ffc4bc678..4006e2924fa4eb044d7c24013f3a68adf862a0d7 100644 --- a/src/node.h +++ b/src/node.h @@ -91,7 +91,11 @@ class Node { const uint GetGlobalNr() { return GlobalNr; } const uint GetNr() { return LocalNr; } const std::string GetType() { return Type; } - bool GetEnabled(void); + bool isEnabled(void); + bool isOnline(void); + bool isMasked(); + void setMasked(bool mask); + uint32_t ppsOffsetCnt(void); bool monitor(TermOutput& t); diff --git a/src/opcua/ua_server.cpp b/src/opcua/ua_server.cpp index 8a9faecebf84098aecfabb55359bf07083e4dea2..961c22b8b7cfd567b656da487b3ac1df6b1c1b1b 100644 --- a/src/opcua/ua_server.cpp +++ b/src/opcua/ua_server.cpp @@ -90,7 +90,7 @@ static UA_StatusCode ua_read_DataSource(UA_Server *server, regname[nodeId->identifier.string.length] = 0; // add end of string char UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "ua_read_DataSource: from node %s",regname); + "ua_read_DataSource: reading from %s",regname); UA_NodeId currentNodeId = UA_NODEID_STRING(mUaLofarNameSpace, (char *)regname); UA_NodeId ntype; @@ -109,24 +109,25 @@ static UA_StatusCode ua_read_DataSource(UA_Server *server, // weird... must do -1 // see: https://open62541.org/doc/current/types.html - // Translator regnames start with "TR_" others "FPGA_" - bool regname_is_for_translator = false; - if (strncmp(regname,"TR_", 3) == 0) { - regname_is_for_translator = true; - UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,"ua_read_DataSource: for translator class"); - } - TermOutput termout; - if (regname_is_for_translator) { - try { + // read values for point + try { + // Translator regnames start with "TR_" others "FPGA_" + if (strncmp(regname,"TR_", 3) == 0) { + // UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,"ua_read_DataSource: for translator class"); SD.tr->read(termout, regname, -1); - } catch (runtime_error& e) { - cerr << "ua_read_DataSource error: " << e.what() << endl; } + else { + // UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,"ua_read_DataSource: for fpga class"); + SD.unb->read(termout, regname, -1); + } + } catch (runtime_error& e) { + cerr << "ua_read_DataSource error: " << e.what() << endl; + } - - // TR_* has only scalars + // if scalar + if (termout.nof_vals == 1) { switch (ntype.identifier.numeric - 1) { case UA_TYPES_STRING: { char *ptr = (char *)termout.val; @@ -194,13 +195,6 @@ static UA_StatusCode ua_read_DataSource(UA_Server *server, } } else { - try { - SD.unb->read(termout, regname, -1); - } catch (runtime_error& e) { - cerr << "ua_read_DataSource: error: " << e.what() << endl; - } - - // FPGA_* has only arrays switch (ntype.identifier.numeric - 1) { case UA_TYPES_STRING: { UA_String *values = (UA_String *) UA_Array_new(termout.nof_vals, &UA_TYPES[UA_TYPES_STRING]); @@ -314,201 +308,106 @@ static UA_StatusCode ua_write_DataSource(UA_Server *server, UA_NodeId ntype; UA_Server_readDataType(server, currentNodeId, &ntype); + // UA_Variant nv_dims; + // https://open62541.org/doc/0.2/server.html + // UA_Server_readArrayDimensions(server, currentNodeId, &nv_dims); + + if (data->hasValue && data->value.arrayLength > 0) { + //data.value is a UA_Variant + uint type = ntype.identifier.numeric - 1; + uint32_t *data_sdp; + uint32_t sz; + if ((type == UA_TYPES_DOUBLE) || (type == UA_TYPES_INT64) || (type == UA_TYPES_UINT64)) { + sz = data->value.arrayLength * 2; + } else if (type == UA_TYPES_STRING) { + sz = data->value.arrayLength * (SIZE1STRING / 4); + } else { + sz = data->value.arrayLength; + } + data_sdp = new uint32_t[sz]; + memset((void *)data_sdp, 0, sizeof(uint32_t)*sz); - // Translator regnames start with "TR_" others "FPGA_" - bool regname_is_for_translator = false; - if (strncmp(regname,"TR_",3) == 0) { - regname_is_for_translator = true; - UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,"ua_write_DataSource: for translator class"); - } - - if (regname_is_for_translator) { - // TR_* has only scalars - if (data->hasValue) { - unsigned int array_length = 1; - uint32_t *data_sdp = new uint32_t[array_length]; - - switch (ntype.identifier.numeric - 1) { - case UA_TYPES_STRING: { - retval = false; - } break; - case UA_TYPES_FLOAT: { - retval = false; - } break; - case UA_TYPES_DOUBLE: { - retval = false; - } break; - case UA_TYPES_INT16: { - retval = true; - int16_t *dptr = (int16_t *)data->value.data; - for (uint i=0; i<array_length; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_UINT16: { - retval = true; - uint16_t *dptr = (uint16_t *)data->value.data; - for (uint i=0; i<array_length; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_INT32: { - retval = true; - int32_t *dptr = (int32_t *)data->value.data; - for (uint i=0; i<array_length; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_UINT32: { - retval = true; - uint32_t *dptr = (uint32_t *)data->value.data; - for (uint i=0; i<array_length; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_INT64: { - retval = true; - int64_t *dptr = (int64_t *)data->value.data; - for (uint i=0; i<array_length; i++) { - data_sdp[i] = (uint64_t)dptr[i]; - } - } break; - case UA_TYPES_UINT64: { - retval = true; - uint64_t *dptr = (uint64_t *)data->value.data; - for (uint i=0; i<array_length; i++) { - data_sdp[i] = (uint64_t)dptr[i]; - } - } break; - case UA_TYPES_BOOLEAN: { - retval = true; - bool *dptr = (bool *)data->value.data; - for (unsigned int i=0; i<array_length; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - default: { - retval = false; - } break; - } - if (retval) { - TermOutput termout; - - try { - SD.tr->write(termout, regname, data_sdp, array_length); - } catch (runtime_error& e) { - cerr << "write_TR_DataSource error: " << e.what() << endl; - retval = false; + retval = true; + switch (ntype.identifier.numeric - 1) { + case UA_TYPES_STRING: { + UA_String *dptr = (UA_String *)data->value.data; + UA_String str_data; + for (int i=0; i<(int)data->value.arrayLength; i++){ + str_data = dptr[i]; + memcpy((void *)&(data_sdp[i*(SIZE1STRING/4)]), (void *)str_data.data, str_data.length); } - } - delete[] data_sdp; + } break; + case UA_TYPES_FLOAT: { + memcpy(data_sdp, data->value.data, data->value.arrayLength*sizeof(UA_Float)); + } break; + case UA_TYPES_DOUBLE: { + memcpy(data_sdp, data->value.data, data->value.arrayLength*sizeof(UA_Double)); + } break; + case UA_TYPES_INT16: { + int16_t *dptr = (int16_t *)data->value.data; + for (uint i=0; i<data->value.arrayLength; i++) { + data_sdp[i] = (uint32_t)dptr[i]; + } + } break; + case UA_TYPES_UINT16: { + uint16_t *dptr = (uint16_t *)data->value.data; + for (uint i=0; i<data->value.arrayLength; i++) { + data_sdp[i] = (uint32_t)dptr[i]; + } + } break; + case UA_TYPES_INT32: { + int32_t *dptr = (int32_t *)data->value.data; + for (uint i=0; i<data->value.arrayLength; i++) { + data_sdp[i] = (uint32_t)dptr[i]; + } + } break; + case UA_TYPES_UINT32: { + uint32_t *dptr = (uint32_t *)data->value.data; + for (uint i=0; i<data->value.arrayLength; i++) { + data_sdp[i] = (uint32_t)dptr[i]; + } + } break; + case UA_TYPES_INT64: { // TODO: 64b -> 32b, not used yet but should give an error + int64_t *dptr = (int64_t *)data->value.data; + for (uint i=0; i<data->value.arrayLength; i++) { + data_sdp[i] = (uint64_t)dptr[i]; + } + } break; + case UA_TYPES_UINT64: { // TODO: 64b -> 32b, not used yet but should give an error + uint64_t *dptr = (uint64_t *)data->value.data; + for (uint i=0; i<data->value.arrayLength; i++) { + data_sdp[i] = (uint64_t)dptr[i]; + } + } break; + case UA_TYPES_BOOLEAN: { + bool *dptr = (bool *)data->value.data; + for (unsigned int i=0; i<data->value.arrayLength; i++) { + data_sdp[i] = (uint32_t)dptr[i]; + } + } break; + default: { + cout << "UA_TYPES_?: not implemented yet" << endl; + retval = false; + } break; } - } - else { - // FPGA_* has only arrays - UA_Variant nv_dims; - /*https://open62541.org/doc/0.2/server.html */ - UA_Server_readArrayDimensions(server, currentNodeId, &nv_dims); - - if (data->hasValue && data->value.arrayLength > 0) { - //data.value is a UA_Variant - uint type = ntype.identifier.numeric - 1; - uint32_t *data_sdp; - uint32_t sz; - if ((type == UA_TYPES_DOUBLE) || (type == UA_TYPES_INT64) || (type == UA_TYPES_UINT64)) { - sz = data->value.arrayLength * 2; - } else if (type == UA_TYPES_STRING) { - sz = data->value.arrayLength * (SIZE1STRING / 4); - } else { - sz = data->value.arrayLength; - } - data_sdp = new uint32_t[sz]; - memset((void *)data_sdp, 0, sizeof(uint32_t)*sz); - - switch (ntype.identifier.numeric - 1) { - case UA_TYPES_STRING: { - UA_String *dptr = (UA_String *)data->value.data; - UA_String str_data; - for (int i=0; i<(int)data->value.arrayLength; i++){ - str_data = dptr[i]; - memcpy((void *)&(data_sdp[i*(SIZE1STRING/4)]), (void *)str_data.data, str_data.length); - } - retval = true; - } break; - case UA_TYPES_FLOAT: { - retval = true; - memcpy(data_sdp, data->value.data, data->value.arrayLength*sizeof(UA_Float)); - } break; - case UA_TYPES_DOUBLE: { - retval = true; - memcpy(data_sdp, data->value.data, data->value.arrayLength*sizeof(UA_Double)); - } break; - case UA_TYPES_INT16: { - retval = true; - int16_t *dptr = (int16_t *)data->value.data; - for (uint i=0; i<data->value.arrayLength; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_UINT16: { - retval = true; - uint16_t *dptr = (uint16_t *)data->value.data; - for (uint i=0; i<data->value.arrayLength; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_INT32: { - retval = true; - int32_t *dptr = (int32_t *)data->value.data; - for (uint i=0; i<data->value.arrayLength; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_UINT32: { - retval = true; - uint32_t *dptr = (uint32_t *)data->value.data; - for (uint i=0; i<data->value.arrayLength; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - case UA_TYPES_INT64: { - retval = true; - int64_t *dptr = (int64_t *)data->value.data; - for (uint i=0; i<data->value.arrayLength; i++) { - data_sdp[i] = (uint64_t)dptr[i]; - } - } break; - case UA_TYPES_UINT64: { - retval = true; - uint64_t *dptr = (uint64_t *)data->value.data; - for (uint i=0; i<data->value.arrayLength; i++) { - data_sdp[i] = (uint64_t)dptr[i]; - } - } break; - case UA_TYPES_BOOLEAN: { - retval = true; - bool *dptr = (bool *)data->value.data; - for (unsigned int i=0; i<data->value.arrayLength; i++) { - data_sdp[i] = (uint32_t)dptr[i]; - } - } break; - default: { - cout << "UA_TYPES_?: not implemented yet" << endl; - retval = false; - } break; - } - if (retval) { - TermOutput termout; - try { + if (retval) { + TermOutput termout; + try { + if (strncmp(regname,"TR_",3) == 0) { + // UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,"ua_write_DataSource: for translator class"); + SD.tr->write(termout, regname, data_sdp, data->value.arrayLength); + } + else { + // UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,"ua_write_DataSource: for fpga class"); SD.unb->write(termout, regname, data_sdp, data->value.arrayLength); - } catch (runtime_error& e) { - cerr << "ua_write_DataSource error: " << e.what() << endl; - retval = false; } + } catch (runtime_error& e) { + cerr << "ua_write_DataSource error: " << e.what() << endl; + retval = false; } - delete[] data_sdp; } + delete[] data_sdp; } delete[] regname; diff --git a/src/periph/fpga.cpp b/src/periph/fpga.cpp index e49bed6b40e68204c6a78da092ec0d31bdae98fb..ff3769e784227eacd0d6b7442707ebb597e6d88b 100644 --- a/src/periph/fpga.cpp +++ b/src/periph/fpga.cpp @@ -58,12 +58,14 @@ extern int debug; #define R_MEM 0 // read mem value #define R_UCP 1 // read value from hardware -Periph_fpga::Periph_fpga(string ipaddr, string expected_design_name, uint expected_firmware_version, bool enabled): +Periph_fpga::Periph_fpga(uint global_nr, string ipaddr, string expected_design_name, uint expected_firmware_version, bool enabled): + GlobalNr(global_nr), Enabled(enabled), + Masked(true), + Online(true), my_expected_design_name(expected_design_name), my_expected_firmware_version(expected_firmware_version), my_current_design_name("-"), - my_current_status("offline"), my_current_hw_version(0), my_current_fw_version("-.-"), my_bsn_input_sync_timeout(false), @@ -75,15 +77,19 @@ Periph_fpga::Periph_fpga(string ipaddr, string expected_design_name, uint expect my_jesd_csr_dev_syncn {0}, my_jesd_rx_err0 {0}, my_jesd_rx_err1 {0}, - my_xst_processing_enable(false) + my_xst_processing_enable(false), + my_pps_offset_cnt(0) { ucp = new UCP(ipaddr); if (Enabled) { mmap = new CMMap(read_reg_map()); + cout << "mmap for node " << GlobalNr << endl; + mmap->print_screen(); } else { mmap = new CMMap(); + cout << "empty mmap for node " << GlobalNr << endl; } // Test FPGA by reading system info: @@ -124,11 +130,13 @@ Periph_fpga::~Periph_fpga() bool Periph_fpga::Read(const string addr_str, uint32_t *data_ptr, bool use_mask_shift=true) { bool ret; - if (!Enabled) { + if ((!Enabled) || (!Masked)) { + cout << "not Enabled or not Masked" << endl; return false; // throw runtime_error("disabled: " + addr_str); } if (!mmap->find_register(addr_str)) { + cout << addr_str << " not found" << endl; return false; } @@ -150,7 +158,7 @@ bool Periph_fpga::Read(const string addr_str, uint32_t *data_ptr, bool use_mask_ bool Periph_fpga::Write(const string addr_str, uint32_t *data_ptr, bool use_shift_mask=true) { - if (!Enabled) { + if ((!Enabled) || (!Masked)) { return false; // throw runtime_error("disabled " + addr_str); } @@ -199,34 +207,6 @@ uint32_t Periph_fpga::shift_mask(const string addr_str, uint32_t data) return _data; } - -bool Periph_fpga::read_fpga_status(TermOutput& termout, int format) -{ - if (my_current_status == "online") { - termout.val[0] = 1; - } - else { - termout.val[0] = 0; - } - termout.nof_vals = 1; - termout.datatype = format; - return true; -} - -bool Periph_fpga::write_fpga_enable_mask(const char *data) -{ - Enabled = (bool)*data; - return true; -} - -bool Periph_fpga::read_fpga_enable_mask(TermOutput& termout, int format) -{ - termout.val[0] = Enabled; - termout.nof_vals = 1; - termout.datatype = format; - return true; -} - /* """Peripheral system_info Register map: @@ -245,13 +225,18 @@ bool Periph_fpga::read_fpga_enable_mask(TermOutput& termout, int format) */ bool Periph_fpga::read_system_info(TermOutput& termout) { - // cout << "read system info" << endl; + cout << "node " << GlobalNr << " read system info" << endl; uint32_t data; - bool retval = Read("mm/0/PIO_SYSTEM_INFO/info", &data); - if (retval == false) { return false; } + bool retval = Read("mm/0/PIO_SYSTEM_INFO/0/info", &data); + if (retval == false) { + cout << "node " << GlobalNr << " no response" << endl; + Online = false; + return false; + } // string design_name = read_design_name(); my_current_design_name = read_design_name(); + cout << "node " << GlobalNr << " design_name=" << my_current_design_name << endl; // FIXME: get rid of magic constants in masks, should be in CCFG: uint firmware_version = (data & 0x00F00000) >> 20; @@ -261,7 +246,7 @@ bool Periph_fpga::read_system_info(TermOutput& termout) my_current_hw_version = (data & 0x0000300) >> 8; if (my_current_design_name == my_expected_design_name && firmware_version >= my_expected_firmware_version) { - my_current_status = "online"; + Online = true; retval = true; } else { @@ -273,7 +258,7 @@ bool Periph_fpga::read_system_info(TermOutput& termout) // my_current_design_name.c_str(), firmware_version, // my_expected_design_name.c_str(), my_expected_firmware_version); - my_current_status = "offline"; + Online = false; // registerMap->setAllPermission_NA(); } return retval; @@ -283,17 +268,13 @@ bool Periph_fpga::read(TermOutput& termout, const string addr, const string type, char *data, const uint nvalues, const int format) { + // cout << "node " << GlobalNr << " read: Enabled=" << Enabled << ", Online=" << Online << ", Masked=" << Masked << endl; bool retval = false; termout.datatype = format; termout.nof_vals = 0; - if (addr == "fpga/enable_mask") { - retval = read_fpga_enable_mask(termout, format); - return retval; - } - - if (!Enabled) { return false; } + if ((!Enabled) || (!Online) || (!Masked)) { return false; } if (type == "mm") { uint32_t *data_ptr = (uint32_t *)data; @@ -331,12 +312,6 @@ bool Periph_fpga::read(TermOutput& termout, const string addr, else if (addr == "fpga/epcs_wait_busy") { retval = wait_while_epcs_busy(1000); } - else if (addr == "fpga/status") { - retval = read_fpga_status(termout, format); - } - else if (addr == "fpga/enable_mask") { - retval = read_fpga_enable_mask(termout, format); - } else if (addr == "fpga/scrap") { retval = read_fpga_scrap(termout, format); } @@ -471,14 +446,10 @@ bool Periph_fpga::read(TermOutput& termout, const string addr, bool Periph_fpga::write(TermOutput& termout, const string addr, const string type, char *data, const uint nvalues, const int format) { + // cout << "node " << GlobalNr << " write: Enabled=" << Enabled << ", Online=" << Online << ", Masked=" << Masked << endl; bool retval = false; - if (addr == "fpga/enable_mask") { - retval = write_fpga_enable_mask(data); - return retval; - } - - if (!Enabled) { return false; } + if ((!Enabled) || (!Online) || (!Masked)) { return false; } uint32_t *data_ptr = (uint32_t *)data; @@ -515,7 +486,7 @@ bool Periph_fpga::write(TermOutput& termout, const string addr, const string typ } else if (addr == "fpga/epcs_mmdp_data") { // write to FIFO - retval = Write("mm/0/REG_MMDP_DATA/data", data_ptr); + retval = Write("mm/0/REG_MMDP_DATA/0/data", data_ptr); } else if (addr == "fpga/scrap") { retval = write_fpga_scrap(data_ptr); @@ -618,16 +589,18 @@ bool Periph_fpga::monitor(TermOutput& termout) // first 9 read functions on 4 nodes will take 6 msec. tictoc.tic("periph.fpga.monitor"); read_system_info(termout); - read_bsn_monitor_input_sync_timeout(termout, REG_FORMAT_INT64, R_UCP); - read_bsn_monitor_input_bsn(termout, REG_FORMAT_INT64, R_UCP); - read_bsn_monitor_input_nof_packets(termout, REG_FORMAT_INT32, R_UCP); - read_bsn_monitor_input_nof_valid(termout, REG_FORMAT_INT32, R_UCP); - read_bsn_monitor_input_nof_err(termout, REG_FORMAT_INT32, R_UCP); - read_jesd204b_csr_rbd_count(termout, REG_FORMAT_UINT32, R_UCP); - read_jesd204b_csr_dev_syncn(termout, REG_FORMAT_UINT32, R_UCP); - read_jesd204b_rx_err0(termout, REG_FORMAT_UINT32, R_UCP); - read_jesd204b_rx_err1(termout, REG_FORMAT_UINT32, R_UCP); - + if (Online) { + read_time_since_last_pps(termout, REG_FORMAT_INT64, R_UCP); + read_bsn_monitor_input_sync_timeout(termout, REG_FORMAT_INT64, R_UCP); + read_bsn_monitor_input_bsn(termout, REG_FORMAT_INT64, R_UCP); + read_bsn_monitor_input_nof_packets(termout, REG_FORMAT_INT32, R_UCP); + read_bsn_monitor_input_nof_valid(termout, REG_FORMAT_INT32, R_UCP); + read_bsn_monitor_input_nof_err(termout, REG_FORMAT_INT32, R_UCP); + read_jesd204b_csr_rbd_count(termout, REG_FORMAT_UINT32, R_UCP); + read_jesd204b_csr_dev_syncn(termout, REG_FORMAT_UINT32, R_UCP); + read_jesd204b_rx_err0(termout, REG_FORMAT_UINT32, R_UCP); + read_jesd204b_rx_err1(termout, REG_FORMAT_UINT32, R_UCP); + } termout.clear(); tictoc.toc(); return true; @@ -640,10 +613,10 @@ bool Periph_fpga::flash_prot(uint32_t *data) uint32_t passphrase_unprotect = 0xBEDA221E; if (*data == 0) { // unprotect - retval = Write("mm/0/REG_EPCS/unprotect", &passphrase_unprotect); + retval = Write("mm/0/REG_EPCS/0/unprotect", &passphrase_unprotect); } else { // protect - retval = Write("mm/0/REG_EPCS/unprotect", &passphrase_protect); + retval = Write("mm/0/REG_EPCS/0/unprotect", &passphrase_protect); } return retval; } @@ -655,14 +628,14 @@ bool Periph_fpga::flash_page(uint32_t *data) wait_while_epcs_busy(1); // write address uint32_t addr = Flash_page_start * Flash_page_size_bytes; - retval = Write("mm/0/REG_EPCS/addr", &addr); + retval = Write("mm/0/REG_EPCS/0/addr", &addr); // write to FIFO - retval = Write("mm/0/REG_MMDP_DATA/data", data); + retval = Write("mm/0/REG_MMDP_DATA/0/data", data); // write_write uint32_t d = 1; - retval = Write("mm/0/REG_EPCS/write", &d); + retval = Write("mm/0/REG_EPCS/0/write", &d); return retval; } @@ -688,7 +661,7 @@ bool Periph_fpga::wait_while_epcs_busy(uint sleeptime) bool retval; //cout << "wait_while_epcs_busy:"; for (int i=0; i<100; i++) { - retval = Read("mm/0/REG_EPCS/busy", &data); + retval = Read("mm/0/REG_EPCS/0/busy", &data); if (!retval) break; if (data == 0) break; usleep(sleeptime); @@ -715,10 +688,10 @@ bool Periph_fpga::flash_erase_sector(uint32_t sector) for (uint i=0; i<s_list.size(); i++) { s = sector * 0x40000 + s_list[i]; // write address - retval = Write("mm/0/REG_EPCS/addr", &s); + retval = Write("mm/0/REG_EPCS/0/addr", &s); // sector erase d = 1; - retval = Write("mm/0/REG_EPCS/sector_erase", &d); + retval = Write("mm/0/REG_EPCS/0/sector_erase", &d); wait_while_epcs_busy(50000); } return retval; @@ -2280,6 +2253,23 @@ bool Periph_fpga::read_subband_weights(TermOutput& termout, int format) { return retval; } +bool Periph_fpga::read_time_since_last_pps(TermOutput& termout, int format, int mode) { + bool retval = true; + if (mode == R_UCP) { + uint32_t data[20]; + memset((void *)data, 0, sizeof(data)); + retval = Read("mm/0/PIO_PPS/0/offset_cnt", data); + my_pps_offset_cnt = (uint32_t)data[0]; + } + + uint32_t *_ptr = (uint32_t *)termout.val; + *_ptr = my_pps_offset_cnt; + termout.nof_vals = 1; + termout.datatype = format; + return retval; +} + + bool Periph_fpga::write_wdi_override(TermOutput& termout) { uint32_t data = 0xB007FAC7; @@ -2319,7 +2309,7 @@ CMMap Periph_fpga::read_reg_map() char *str_ptr = (char *)data; string reg_map_str(str_ptr); - cout << "Periph_fpga::read_reg_map:\n" << reg_map_str << endl; + // cout << "Periph_fpga::read_reg_map:\n" << reg_map_str << endl; if (data != NULL) { delete[] data; } diff --git a/src/periph/fpga.h b/src/periph/fpga.h index b66d47d27acfbb8a7a2d15a32968330ecc21c762..eea3a2415f2c30c97388334cdfcaaa2c35d89466 100644 --- a/src/periph/fpga.h +++ b/src/periph/fpga.h @@ -46,12 +46,14 @@ private: Tictoc tictoc; // used to get some timing information UCP *ucp; CMMap *mmap; - + uint32_t GlobalNr; bool Enabled; + bool Masked; + bool Online; + std::string my_expected_design_name; uint my_expected_firmware_version; std::string my_current_design_name; - std::string my_current_status; uint my_current_hw_version; std::string my_current_fw_version; @@ -66,6 +68,7 @@ private: uint32_t my_jesd_rx_err0[C_S_pn]; uint32_t my_jesd_rx_err1[C_S_pn]; bool my_xst_processing_enable; + uint32_t my_pps_offset_cnt; std::ofstream rbf_wf; uint32_t Flash_page_start, Flash_page_size_bytes, Flash_user_sector_start, @@ -85,10 +88,6 @@ private: bool wait_while_epcs_busy(uint sleeptime); std::string read_design_name(); std::string read_design_note(); - bool read_fpga_status(TermOutput& termout, int format); - - bool read_fpga_enable_mask(TermOutput& termout, int format); - bool write_fpga_enable_mask(const char *data); bool read_system_info(TermOutput& termout); bool read_hardware_version(TermOutput& termout, int format); @@ -181,12 +180,13 @@ private: 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); CMMap read_reg_map(); public: - Periph_fpga(std::string ipaddr, std::string expected_design_name, uint expected_firmware_version, bool enabled); + Periph_fpga(uint global_nr, std::string ipaddr, std::string expected_design_name, uint expected_firmware_version, bool enabled); ~Periph_fpga(); @@ -197,7 +197,11 @@ public: bool monitor(TermOutput& termout); CMMap* getMMap(void) { return mmap; }; - bool getEnabled(void) { return Enabled; } + bool isEnabled(void) { return Enabled; } + bool isOnline(void) { return Online; } + bool isMasked(void) { return Masked; } + void setMasked(bool mask) { Masked = mask; } + uint32_t ppsOffsetCnt(void) { return my_pps_offset_cnt; } }; #endif // __PERIPH_FPGA_H__ diff --git a/src/registers.cpp b/src/registers.cpp index 124b3501950f586b65dfcbfd0a669724d4b5a6df..1639254c44243ee5e5189b33aa9d18ef636f67b5 100644 --- a/src/registers.cpp +++ b/src/registers.cpp @@ -99,7 +99,7 @@ bool CMMap::add_register(const string name, const uint32_t base, const uint32_t const uint32_t shift, const string access, const string type, const uint32_t peripheral_span, const uint32_t mm_port_span) { - cout << "CMMap::add_register: " << name << endl; + // cout << "CMMap::add_register: " << name << endl; if (find_register(name)) { cerr << "CMMap::add_register: " << name << " already exist!" << endl; return false; @@ -114,7 +114,7 @@ bool CMMap::update_register(const string name, const uint32_t base, const uint32 const uint32_t shift, const string access, const string type, const uint32_t peripheral_span, const uint32_t mm_port_span) { - cout << "CMMap::update_register: " << name << endl; + // cout << "CMMap::update_register: " << name << endl; if (!find_register(name)) { cerr << "CMMap::update_register: " << name << " not exist!" << endl; return false; diff --git a/src/sdptr.cpp b/src/sdptr.cpp index 80353e041c3fd22b90b785ccef91b39287004921..7fffbe4e8dad998d487f4b21ee751b11922dcabb 100644 --- a/src/sdptr.cpp +++ b/src/sdptr.cpp @@ -62,6 +62,7 @@ void monitor() string line; string cmdname = ""; TermOutput termout; + struct timeval current_time; SD.timetick = SECONDS_PER_TICK; clock_gettime(CLOCK_REALTIME, (struct timespec *)&SD.t0); @@ -69,21 +70,23 @@ void monitor() pthread_cond_init(&SD.newpoint_cond, NULL); SD.uptime = 0; + + gettimeofday(¤t_time, NULL); + SD.start_time = current_time.tv_sec; - while (ServerRunning) { - struct timeval current_time; + while (ServerRunning) { SD.t0.tv_sec = SD.t0.tv_sec + SD.timetick; // specify next position in time SD.t0.tv_nsec = 10000000L; // 0..999999999 // offset 10ms in a new second pthread_mutex_lock(&SD.newpoint_lock); pthread_cond_timedwait(&SD.newpoint_cond, &SD.newpoint_lock, (const struct timespec *)&SD.t0); pthread_mutex_unlock(&SD.newpoint_lock); - SD.uptime++; gettimeofday(¤t_time, NULL); + SD.tod = current_time.tv_sec; cout << "MONITOR THREAD. now=" << current_time.tv_sec << "." << current_time.tv_usec << " uptime=" << SD.uptime << " seconds" << endl; - SD.tod = current_time.tv_sec; + SD.uptime++; if (SD.unb != NULL) { // cout << "sdptr_monitor start" << endl; @@ -229,7 +232,6 @@ int main (int argc, char* argv[]) //openlog(basename(argv[0]), 0, LOG_LOCAL0); //syslog(LOG_INFO,"Starting server %s\n", SDPTR_VERSION); - if (!nodaemon) { if (daemon(1, 0) < 0) cerr << "Error fork as daemon: " << strerror(errno) << endl; } diff --git a/src/sdptr.h b/src/sdptr.h index b112ea7be397b63987a9845d46cbbacefb36e6b4..ebfc4c3329de2567171f509e573c5cb2b7400963 100644 --- a/src/sdptr.h +++ b/src/sdptr.h @@ -56,6 +56,7 @@ public: pthread_mutex_t newpoint_lock; std::atomic<uint32_t> uptime; + std::atomic<uint32_t> start_time; std::atomic<uint32_t> tod; std::atomic<bool> busy; }; diff --git a/src/tools/mmap.cpp b/src/tools/mmap.cpp index eed1055d5ecc9a67a0625edfa30f1b1d44483749..a14315eb00451ea62076cffa30885e2056ab7b2c 100644 --- a/src/tools/mmap.cpp +++ b/src/tools/mmap.cpp @@ -255,8 +255,8 @@ CMMap mmap_to_regmap(istringstream& iss) } } - cout << "regmap:" << endl; - regmap.print_screen(); + // cout << "regmap:" << endl; + // regmap.print_screen(); return regmap; } diff --git a/src/tr.cpp b/src/tr.cpp index 9938d86b5650853bda298391d1ecfb20d31ffb77..e5d031102742c4d3fbe7bf29f188cc74323fc874 100644 --- a/src/tr.cpp +++ b/src/tr.cpp @@ -36,6 +36,7 @@ #include "tr.h" #include "sdptr.h" +#include "constants.h" using namespace std; @@ -48,11 +49,18 @@ TranslatorMap::TranslatorMap() { translatorMap = new CPointMap(); - translatorMap->add_register("TR_reload_RW", "-", 1, 1, "RW", REG_FORMAT_BOOLEAN); - translatorMap->add_register("TR_software_version_R", "-", 1, 1, "RO", REG_FORMAT_STRING); - translatorMap->add_register("TR_busy_R", "-", 1, 1, "RO", REG_FORMAT_BOOLEAN); - translatorMap->add_register("TR_tod_R", "-", 1, 1, "RO", REG_FORMAT_UINT32); - translatorMap->add_register("TR_uptime_R", "-", 1, 1, "RO", REG_FORMAT_UINT32); + translatorMap->add_register("TR_fpga_mask_R", "-", C_N_pn, 1, "RO", REG_FORMAT_BOOLEAN); + translatorMap->add_register("TR_fpga_mask_RW", "-", C_N_pn, 1, "RW", REG_FORMAT_BOOLEAN); + 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_UINT32); + // translatorMap->add_register("TR_tod_client_status_R", "-", 1, 1, "RO", REG_FORMAT_BOOLEAN); + translatorMap->add_register("TR_tod_R", "-", 1, 1, "RO", REG_FORMAT_UINT32); + translatorMap->add_register("TR_tod_pps_delta_R", "-", 1, 1, "RO", REG_FORMAT_DOUBLE); + translatorMap->add_register("TR_fpga_communication_error_R", "-", C_N_pn, 1, "RO", REG_FORMAT_BOOLEAN); + + // translatorMap->add_register("TR_uptime_R", "-", 1, 1, "RO", REG_FORMAT_UINT32); + // translatorMap->add_register("TR_busy_R", "-", 1, 1, "RO", REG_FORMAT_BOOLEAN); + // translatorMap->add_register("TR_reload_RW", "-", 1, 1, "RW", REG_FORMAT_BOOLEAN); } @@ -79,7 +87,9 @@ bool TranslatorMap::translator(TermOutput& termout, const char cmd, const string } int format = (int)translatorMap->getFormat(addr); - termout.nof_vals = translatorMap->getDataSize(addr); + uint32_t n_nodes = translatorMap->getNodesSize(addr); + uint32_t n_values = translatorMap->getDataSize(addr); + termout.nof_vals = n_nodes * n_values; termout.datatype = format; retval = true; @@ -90,17 +100,63 @@ bool TranslatorMap::translator(TermOutput& termout, const char cmd, const string raise(SIGHUP); } } + else if (addr == "TR_fpga_mask_R") { + bool *ptr_out = (bool *)termout.val; + vector<bool> masked = SD.unb->get_all_masked_nodes(); + for (auto val : masked) { + *ptr_out = val; + ptr_out++; + } + } + else if (addr == "TR_fpga_mask_RW") { + if (cmd == 'W') { + bool *ptr_in = (bool *)data; + vector<bool> masked; + for (uint i=0; i<n_nodes; i++) { + masked.push_back(*ptr_in); + ptr_in++; + } + SD.unb->set_all_masked_nodes(masked); + } + else { + bool *ptr_out = (bool *)termout.val; + vector<bool> masked = SD.unb->get_all_masked_nodes(); + for (auto val : masked) { + *ptr_out = val; + ptr_out++; + } + } + } else if (addr == "TR_software_version_R") { strcpy(termout.val, SDPTR_VERSION); } - else if (addr == "TR_busy_R") { - bool *ptr_out = (bool *)termout.val; - *ptr_out = (bool)SD.busy; - } else if (addr == "TR_tod_R") { uint32_t *ptr_out = (uint32_t *)termout.val; *ptr_out = (uint32_t)SD.tod; } + else if (addr == "TR_tod_pps_delta_R") { + double *ptr_out = (double *)termout.val; + vector<uint32_t> pps_offset_cnt = SD.unb->get_all_pps_offset_cnt(); + cout << "pps_offset_cnt=" << pps_offset_cnt[0] << endl; + double pps_delta = (double)(pps_offset_cnt[0] * 5); // TODO: make constant of 5(nS) + *ptr_out = pps_delta; + } + else if (addr == "TR_start_time_R") { + uint32_t *ptr_out = (uint32_t *)termout.val; + *ptr_out = (uint32_t)SD.start_time; + } + else if (addr == "TR_fpga_communication_error_R") { + bool *ptr_out = (bool *)termout.val; + vector<bool> offline = SD.unb->get_all_offline_nodes(); + for (auto val : offline) { + *ptr_out = val; + ptr_out++; + } + } + else if (addr == "TR_busy_R") { + bool *ptr_out = (bool *)termout.val; + *ptr_out = (bool)SD.busy; + } else if (addr == "TR_uptime_R") { uint32_t *ptr_out = (uint32_t *)termout.val; *ptr_out = (uint32_t)SD.uptime; @@ -115,6 +171,7 @@ bool TranslatorMap::translator(TermOutput& termout, const char cmd, const string bool TranslatorMap::read(TermOutput& termout, const string addr, const int nvalues) { + cout << "TR:read" << endl; return translator(termout, 'R', addr, NULL, nvalues); } @@ -122,5 +179,6 @@ bool TranslatorMap::write(TermOutput& termout, const string addr, const unsigned int *data, const int nvalues) { + cout << "TR:write" << endl; return translator(termout, 'W', addr, data, nvalues); } diff --git a/test/py/Client.py b/test/py/Client.py index aa4e99d2fc65d7038bb8c1e53619614828397708..79ca01749fe7f86b54adede2f0a012b8de5a2994 100644 --- a/test/py/Client.py +++ b/test/py/Client.py @@ -23,18 +23,6 @@ # Purpose: # . script to test (control/monitor) opc-ua server # Description: -# Client.py is used to connect (TCP/IP) to an opc-ua server and test (read/write) -# opc-ua points (registers on a fpga). -# For LTS the server is running on DOP36 port 4840, this client can not run -# on DOP36 itself (too old system). -# -# In this version the following is working: -# . --info, read info from server, list all available points on the server. -# . --all, read all *_R point and print needed time. -# . --wg, turn off WG or setup for XST (to generate crosslets plot). -# . --setup, setup SST, BST and XST stream. -# . --stream, turn off or on SST, BST or XST stream. -# # . run ./Client.py -h for help # ########################################################################## @@ -143,7 +131,6 @@ def check_get_all_R_time(obj): info.append(str(obj.get_child("2:FPGA_jesd204b_csr_rbd_count_R").get_value())) info.append(str(obj.get_child("2:FPGA_jesd204b_rx_err0_R").get_value())) info.append(str(obj.get_child("2:FPGA_jesd204b_rx_err1_R").get_value())) - info.append(str(obj.get_child("2:FPGA_mask_R").get_value())) info.append(str(obj.get_child("2:FPGA_processing_enable_R").get_value())) info.append(str(obj.get_child("2:FPGA_sdp_info_antenna_band_index_R").get_value())) info.append(str(obj.get_child("2:FPGA_sdp_info_block_period_R").get_value())) @@ -170,7 +157,6 @@ def check_get_all_R_time(obj): info.append(str(obj.get_child("2:FPGA_xst_offload_hdr_eth_destination_mac_R").get_value())) info.append(str(obj.get_child("2:FPGA_xst_offload_hdr_ip_destination_address_R").get_value())) info.append(str(obj.get_child("2:FPGA_xst_offload_hdr_udp_destination_port_R").get_value())) - info.append(str(obj.get_child("2:FPGA_status_R").get_value())) info.append(str(obj.get_child("2:FPGA_subband_weights_R").get_value())) info.append(str(obj.get_child("2:FPGA_temp_R").get_value())) info.append(str(obj.get_child("2:FPGA_weights_R").get_value())) @@ -178,10 +164,12 @@ def check_get_all_R_time(obj): info.append(str(obj.get_child("2:FPGA_wg_enable_R").get_value())) info.append(str(obj.get_child("2:FPGA_wg_frequency_R").get_value())) info.append(str(obj.get_child("2:FPGA_wg_phase_R").get_value())) - info.append(str(obj.get_child("2:TR_busy_R").get_value())) + info.append(str(obj.get_child("2:TR_fpga_mask_R").get_value())) info.append(str(obj.get_child("2:TR_software_version_R").get_value())) + info.append(str(obj.get_child("2:TR_start_time_R").get_value())) info.append(str(obj.get_child("2:TR_tod_R").get_value())) - info.append(str(obj.get_child("2:TR_uptime_R").get_value())) + info.append(str(obj.get_child("2:TR_tod_pps_delta_R").get_value())) + #info.append(str(obj.get_child("2:TR_uptime_R").get_value())) print(f"checked {len(info)} FPGA_*_R points") # print('\n'.join(info)) @@ -194,12 +182,12 @@ def write_fpga_mask(obj, nodes=None, mask=None): for node in list(nodes): enable_mask[node] = True #print(enable_mask) - var = obj.get_child("2:FPGA_mask_RW") + var = obj.get_child("2:TR_fpga_mask_RW") var.set_value(ua.Variant(value=list(enable_mask), varianttype=ua.VariantType.Boolean)) def get_fpga_mask(obj): - var = obj.get_child("2:FPGA_mask_R") + var = obj.get_child("2:TR_fpga_mask_R") enable_mask = var.get_value() #print(enable_mask) return enable_mask @@ -411,7 +399,7 @@ if __name__ == "__main__": if args.wg_mode is not None: if args.wg_mode == 'OFF': - turn_wg_off(obj) + turn_wg_off(Object) elif args.wg_mode == 'XST': setup_wg_xst_mode(Object)