From 165260020e247a0259fde07bc9422f8e43e3189f Mon Sep 17 00:00:00 2001 From: Marco Roda Date: Wed, 17 Jul 2024 11:11:48 +0200 Subject: [PATCH 1/6] Bump version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b082a5..d686520 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.12) -project(daphnemodules VERSION 1.4.0) +project(daphnemodules VERSION 1.5.0) find_package(daq-cmake REQUIRED) From 031656ea94f14c3341e0ce53aec0f0eadcb17358 Mon Sep 17 00:00:00 2001 From: Marco Roda Date: Wed, 17 Jul 2024 11:31:37 +0200 Subject: [PATCH 2/6] Dedicated slot configuration --- plugins/DaphneController.cpp | 16 ++++++++-------- schema/daphnemodules/daphnecontroller.jsonnet | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/plugins/DaphneController.cpp b/plugins/DaphneController.cpp index ba8b08b..beb1d10 100644 --- a/plugins/DaphneController.cpp +++ b/plugins/DaphneController.cpp @@ -186,6 +186,14 @@ DaphneController::do_conf(const data_t& conf_as_json) auto conf_as_cpp = conf_as_json.get(); + auto slot = conf_as_cpp.slot; + if ( slot >= 16 ) { + // the slot used laster in the code is a 4 bit register, so we need to check we are not overflowing + throw InvalidSlot(ERS_HERE, slot, ip); + } else { + m_slot = (decltype) slot; + } + // during configuration no other operations are allowed const std::lock_guard lock(m_mutex); @@ -265,14 +273,6 @@ DaphneController::create_interface(const std::string & ip) { throw InvalidIPAddress(ERS_HERE, ip); } - auto last = std::stoi(matches[1]); - m_slot = last % 100; - if ( m_slot >= 16 ) { - // Set the slot to the last part of the IP addreess (from 104 to 113) - // the slot used laster in the code is a 4 bit register, so we need to check we are not overflowing - throw InvalidSlot(ERS_HERE, m_slot, ip); - } - TLOG() << get_name() << ": using daphne at " << ip << " with slot " << (int)m_slot; m_interface.reset( new DaphneInterface( ip.c_str(), 2001) ); diff --git a/schema/daphnemodules/daphnecontroller.jsonnet b/schema/daphnemodules/daphnecontroller.jsonnet index 38e828c..aee7a36 100644 --- a/schema/daphnemodules/daphnecontroller.jsonnet +++ b/schema/daphnemodules/daphnecontroller.jsonnet @@ -77,6 +77,8 @@ local types = { conf: s.record("Conf", [ s.field("daphne_address", self.ipaddress, doc="addresses of the daphne connection point"), + s.field("slot", self.uint4, + doc="Slot of the board, also used to identify the board"), s.field("biasctrl", self.uint4, doc="V Bias Control"), s.field("channels", self.channels, From 1ca91962e07088bdc5e842c917009cff671c2980 Mon Sep 17 00:00:00 2001 From: Marco Roda Date: Wed, 17 Jul 2024 11:35:33 +0200 Subject: [PATCH 3/6] Fix compilation errors --- plugins/DaphneController.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/DaphneController.cpp b/plugins/DaphneController.cpp index beb1d10..ed861f2 100644 --- a/plugins/DaphneController.cpp +++ b/plugins/DaphneController.cpp @@ -189,9 +189,9 @@ DaphneController::do_conf(const data_t& conf_as_json) auto slot = conf_as_cpp.slot; if ( slot >= 16 ) { // the slot used laster in the code is a 4 bit register, so we need to check we are not overflowing - throw InvalidSlot(ERS_HERE, slot, ip); + throw InvalidSlot(ERS_HERE, slot, conf_as_cpp.daphne_address); } else { - m_slot = (decltype) slot; + m_slot = (decltype(m_slot)) slot; } // during configuration no other operations are allowed From 143267fc2ce452e125dc1bc450553953ab776ae8 Mon Sep 17 00:00:00 2001 From: Marco Roda Date: Wed, 17 Jul 2024 14:23:59 +0200 Subject: [PATCH 4/6] Configuration with independent slot and ip; separate applications for each controller --- python/daphnemodules/daphnemodulesapp_gen.py | 138 +++++++++---------- schema/daphnemodules/confgen.jsonnet | 9 +- scripts/daphne_example_config.json | 2 +- scripts/daphne_gen | 55 +++++--- 4 files changed, 111 insertions(+), 93 deletions(-) diff --git a/python/daphnemodules/daphnemodulesapp_gen.py b/python/daphnemodules/daphnemodulesapp_gen.py index f6b1656..ac93a5f 100644 --- a/python/daphnemodules/daphnemodulesapp_gen.py +++ b/python/daphnemodules/daphnemodulesapp_gen.py @@ -53,8 +53,10 @@ def to_lna( j : dict ) -> daphnecontroller.LNAConf : gain = j['gain'] ) return ret + def get_daphnemodules_app( - slots : tuple, + slot : int, + ip : str, biasctrl : int, afe_gain : int, channel_gain : int, @@ -62,7 +64,7 @@ def get_daphnemodules_app( adc : daphnecontroller.ADCConf, pga : daphnecontroller.PGAConf, lna : daphnecontroller.LNAConf, - map_file, + details, nickname="daphne", host="localhost"): """ @@ -71,78 +73,74 @@ def get_daphnemodules_app( The map file, will profvide details to override whatever comes from the inputs """ - daphnes = {} - if map_file : - file = open(map_file) - data = json.load(file) - daphnes = unpack(data, 'details') + ext_conf = details - modules = [] - - for s in slots: - - ext_conf = None - if s in daphnes : ext_conf = daphnes[s] - - ip = ip_base + str(100+s) - - afes = [] - if ext_conf : - afe_block = ext_conf['afes'] - ext_afe_gains = unpack(afe_block, 'v_gains') - ext_biases = unpack(afe_block, 'v_biases') - ext_adcs = unpack(afe_block, 'adcs') - ext_pgas = unpack(afe_block, 'pgas') - ext_lnas = unpack(afe_block, 'lnas') + afes = [] + ext_afe_gains = [] + ext_biases = [] + ext_adcs = [] + ext_pgas = [] + ext_lnas = [] + + if ext_conf : + afe_block = ext_conf['afes'] + ext_afe_gains = unpack(afe_block, 'v_gains') + ext_biases = unpack(afe_block, 'v_biases') + ext_adcs = unpack(afe_block, 'adcs') + ext_pgas = unpack(afe_block, 'pgas') + ext_lnas = unpack(afe_block, 'lnas') - for afe in range(n_afe) : - afes.append( daphnecontroller.AFE( - id=afe, - v_gain=afe_gain if afe not in ext_afe_gains else ext_afe_gains[afe], - v_bias = 0 if afe not in ext_biases else ext_biases[afe], - adc = adc if afe not in ext_adcs else to_adc(ext_adcs[afe]), - pga = pga if afe not in ext_pgas else to_pga(ext_pgas[afe]), - lna = lna if afe not in ext_lnas else to_lna(ext_lnas[afe]) - ) ) - - channels=[] - if ext_conf : - channel_block = ext_conf['channels'] - ext_gains = unpack(channel_block, 'gains') - ext_offsets = unpack(channel_block, 'offsets') - ext_trims = unpack(channel_block, 'trims') + for afe in range(n_afe) : + afes.append( daphnecontroller.AFE( + id=afe, + v_gain=afe_gain if afe not in ext_afe_gains else ext_afe_gains[afe], + v_bias = 0 if afe not in ext_biases else ext_biases[afe], + adc = adc if afe not in ext_adcs else to_adc(ext_adcs[afe]), + pga = pga if afe not in ext_pgas else to_pga(ext_pgas[afe]), + lna = lna if afe not in ext_lnas else to_lna(ext_lnas[afe]) + ) ) + + channels=[] + ext_gains = [] + ext_offsets = [] + ext_trims = [] + if ext_conf : + channel_block = ext_conf['channels'] + ext_gains = unpack(channel_block, 'gains') + ext_offsets = unpack(channel_block, 'offsets') + ext_trims = unpack(channel_block, 'trims') - for ch in range(n_channels) : - conf = None - - gain = channel_gain if ch not in ext_gains else ext_gains[ch] - offset = channel_offset if ch not in ext_offsets else ext_offsets[ch] - if ch in ext_trims : - conf = daphnecontroller.ChannelConf( - gain = gain, - offset = offset, - trim = ext_trims[ch] ) - else : - conf = daphnecontroller.ChannelConf( - gain = gain, - offset = offset ) - - channels.append( daphnecontroller.Channel( id = ch, conf = conf ) ) + for ch in range(n_channels) : + conf = None + + gain = channel_gain if ch not in ext_gains else ext_gains[ch] + offset = channel_offset if ch not in ext_offsets else ext_offsets[ch] + if ch in ext_trims : + conf = daphnecontroller.ChannelConf( + gain = gain, + offset = offset, + trim = ext_trims[ch] ) + else : + conf = daphnecontroller.ChannelConf( + gain = gain, + offset = offset ) + + channels.append( daphnecontroller.Channel( id = ch, conf = conf ) ) - conf = daphnecontroller.Conf( - daphne_address=ip, - biasctrl=biasctrl, - afes = afes, - channels = channels, - self_trigger_threshold = 0 if not ext_conf else ext_conf['self_trigger_threshold'], - full_stream_channels = [] if not ext_conf else ext_conf['full_stream_channels'] - ) - - modules += [DAQModule(name = f"controller_{s}", - plugin = "DaphneController", - conf = conf - ) - ] + conf = daphnecontroller.Conf( + daphne_address=ip, + slot=slot, + biasctrl=biasctrl, + afes = afes, + channels = channels, + self_trigger_threshold = 0 if not ext_conf else ext_conf['self_trigger_threshold'], + full_stream_channels = [] if not ext_conf else ext_conf['full_stream_channels'] + ) + + modules = [DAQModule(name = "controller", + plugin = "DaphneController", + conf = conf + )] mgraph = ModuleGraph(modules) daphnemodules_app = App(modulegraph = mgraph, host = host, name = nickname) diff --git a/schema/daphnemodules/confgen.jsonnet b/schema/daphnemodules/confgen.jsonnet index 7cd653d..b17a0c3 100644 --- a/schema/daphnemodules/confgen.jsonnet +++ b/schema/daphnemodules/confgen.jsonnet @@ -27,10 +27,15 @@ local cs = { string: s.string( "String", doc="A string"), monitoring_dest: s.enum( "MonitoringDest", ["local", "cern", "pocket"]), - slotlist : s.sequence( "SlotList", self.uint4, doc="list of slots" ), + daphne_id : s.record( "DaphneId", [ + s.field("slot", self.uint4, doc="Slot of the board"), + s.field("ip", self.string, doc="IP of the board") + ], doc="Entry for a map to slot map"), + + daphne_list : s.sequence( "DaphneList", self.daphne_id, doc="Map of slots and IPs" ), daphne_input: s.record("DaphneInput", [ - s.field( "slots", self.slotlist, default=[4,5,7,9,11,12,13], + s.field( "daphnes", self.daphne_list, default=[], doc="List of the daphne to use, identified by slot"), s.field( "biasctrl", self.uint4, default = 4095, doc = "Biasctr to be used for all boards"), diff --git a/scripts/daphne_example_config.json b/scripts/daphne_example_config.json index 5aac67b..f9e2bf6 100644 --- a/scripts/daphne_example_config.json +++ b/scripts/daphne_example_config.json @@ -6,6 +6,6 @@ "ers_impl": "local" }, "daphne": { - "slots": [13] + "daphnes": [{"slot": 13, "ip": "10.73.137.113"}] } } diff --git a/scripts/daphne_gen b/scripts/daphne_gen index a123359..03475f2 100755 --- a/scripts/daphne_gen +++ b/scripts/daphne_gen @@ -60,21 +60,36 @@ def cli(config, from daphnemodules import daphnemodulesapp_gen the_system = System() - - the_system.apps["daphneapp"] = daphnemodulesapp_gen.get_daphnemodules_app( - host=host, - nickname = "controller", - slots = daphne_block.slots, - biasctrl = daphne_block.biasctrl, - afe_gain = daphne_block.afe_gain, - channel_gain = daphne_block.channel_gain, - channel_offset = daphne_block.channel_offset, - adc = daphne_block.adc, - pga = daphne_block.pga, - lna = daphne_block.lna, - map_file = daphne_file - ) - + + daphnes = {} + if daphne_file : + file = open(daphne_file) + data = json.load(file) + daphnes = daphnemodulesapp_gen.unpack(data, 'details') + + for entry in daphne_block.daphnes : + slot = entry["slot"] + ip = entry["ip"] + app_name = f"daphne-{slot}" + detail_block = None + if slot in daphnes : detail_block = daphnes[slot] + + the_system.apps[app_name] = daphnemodulesapp_gen.get_daphnemodules_app( + host=host, + nickname = f"controller_{slot}", + slot = slot, + ip = ip, + biasctrl = daphne_block.biasctrl, + afe_gain = daphne_block.afe_gain, + channel_gain = daphne_block.channel_gain, + channel_offset = daphne_block.channel_offset, + adc = daphne_block.adc, + pga = daphne_block.pga, + lna = daphne_block.lna, + details = detail_block + ) + + #################################################################### # Application command data generation #################################################################### @@ -92,11 +107,11 @@ def cli(config, write_json_files(app_command_datas, system_command_datas, json_dir, verbose=True) - from daphnemodules.dump_buffer_command_gen import generate_daphne_rc_cmds - directory = daphne_block.dump_buffers_directory - n_samples = daphne_block.dump_buffers_n_samples - console.log(f"dump_buffer command generated and will dump in the {directory} directory, dumping {n_samples} n_samples") - generate_daphne_rc_cmds(directory, n_samples, "daphneapp", json_dir) +# from daphnemodules.dump_buffer_command_gen import generate_daphne_rc_cmds +# directory = daphne_block.dump_buffers_directory +# n_samples = daphne_block.dump_buffers_n_samples +# console.log(f"dump_buffer command generated and will dump in the {directory} directory, dumping {n_samples} n_samples") +# generate_daphne_rc_cmds(directory, n_samples, "daphneapp", json_dir) console.log(f"daphnemodules app config generated in {json_dir}") From ef40690a45d9e77756b5b2ff779ef40e7e51d4f4 Mon Sep 17 00:00:00 2001 From: Marco Roda Date: Wed, 17 Jul 2024 14:25:42 +0200 Subject: [PATCH 5/6] Complete example --- scripts/daphne_example_config.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/daphne_example_config.json b/scripts/daphne_example_config.json index f9e2bf6..33ebc8f 100644 --- a/scripts/daphne_example_config.json +++ b/scripts/daphne_example_config.json @@ -6,6 +6,13 @@ "ers_impl": "local" }, "daphne": { - "daphnes": [{"slot": 13, "ip": "10.73.137.113"}] + "daphnes": [ {"slot": 4, "ip": "10.73.137.104"}, + {"slot": 5, "ip": "10.73.137.105"}, + {"slot": 7, "ip": "10.73.137.110"}, + {"slot": 9, "ip": "10.73.137.109"}, + {"slot": 11, "ip": "10.73.137.111"}, + {"slot": 12, "ip": "10.73.137.112"}, + {"slot": 13, "ip": "10.73.137.113"}, + ] } } From c09c606378f7fd868ed68d288da23a6738487f7d Mon Sep 17 00:00:00 2001 From: Marco Roda Date: Wed, 17 Jul 2024 14:49:39 +0200 Subject: [PATCH 6/6] Restore spy buffer commands --- scripts/daphne_example_config.json | 2 +- scripts/daphne_gen | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/daphne_example_config.json b/scripts/daphne_example_config.json index 33ebc8f..367d59f 100644 --- a/scripts/daphne_example_config.json +++ b/scripts/daphne_example_config.json @@ -12,7 +12,7 @@ {"slot": 9, "ip": "10.73.137.109"}, {"slot": 11, "ip": "10.73.137.111"}, {"slot": 12, "ip": "10.73.137.112"}, - {"slot": 13, "ip": "10.73.137.113"}, + {"slot": 13, "ip": "10.73.137.113"} ] } } diff --git a/scripts/daphne_gen b/scripts/daphne_gen index 03475f2..e48d9c8 100755 --- a/scripts/daphne_gen +++ b/scripts/daphne_gen @@ -107,11 +107,12 @@ def cli(config, write_json_files(app_command_datas, system_command_datas, json_dir, verbose=True) -# from daphnemodules.dump_buffer_command_gen import generate_daphne_rc_cmds -# directory = daphne_block.dump_buffers_directory -# n_samples = daphne_block.dump_buffers_n_samples -# console.log(f"dump_buffer command generated and will dump in the {directory} directory, dumping {n_samples} n_samples") -# generate_daphne_rc_cmds(directory, n_samples, "daphneapp", json_dir) + from daphnemodules.dump_buffer_command_gen import generate_daphne_rc_cmds + directory = daphne_block.dump_buffers_directory + n_samples = daphne_block.dump_buffers_n_samples + console.log(f"dump_buffer command generated and will dump in the {directory} directory, dumping {n_samples} n_samples") + for name in the_system.apps : + generate_daphne_rc_cmds(directory, n_samples, name, json_dir) console.log(f"daphnemodules app config generated in {json_dir}")