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) diff --git a/plugins/DaphneController.cpp b/plugins/DaphneController.cpp index ba8b08b..ed861f2 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, conf_as_cpp.daphne_address); + } else { + m_slot = (decltype(m_slot)) 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/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/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, diff --git a/scripts/daphne_example_config.json b/scripts/daphne_example_config.json index 5aac67b..367d59f 100644 --- a/scripts/daphne_example_config.json +++ b/scripts/daphne_example_config.json @@ -6,6 +6,13 @@ "ers_impl": "local" }, "daphne": { - "slots": [13] + "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"} + ] } } diff --git a/scripts/daphne_gen b/scripts/daphne_gen index a123359..e48d9c8 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 #################################################################### @@ -96,7 +111,8 @@ def cli(config, 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) + 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}")