Source code for larpix.chip

from .key import Key
from .configuration import Configuration_v1, Configuration_v2, Configuration_v2b, Configuration_Lightpix_v1
from .packet import Packet_v1, Packet_v2

[docs]class Chip(object): ''' Represents one LArPix chip and helps with configuration and packet generation. ''' def __init__(self, chip_key, version=2): ''' Create a new Chip object with the given ``chip_key``. See the ``Key`` class for the key specification. Key can be specified by a valid keystring or a ``Key`` object. ''' self.asic_version = version if self.asic_version == 1: self.config = Configuration_v1() elif self.asic_version == 2: self.config = Configuration_v2() elif self.asic_version == 'lightpix-v1.0': self.config = Configuration_Lightpix_v1() elif self.asic_version == '2b': self.config = Configuration_v2b() else: raise RuntimeError('chip asic version is invalid') chip_key = Key(chip_key) self.io_group = chip_key.io_group self.io_channel = chip_key.io_channel self.chip_id = chip_key.chip_id self.reads = [] self.new_reads_index = 0 def __str__(self): return 'Chip (key: {}, version: {})'.format(str(self.chip_key), self.asic_version) def __repr__(self): return 'Chip(chip_key={}, version={})'.format(str(self.chip_key), self.asic_version) @property def chip_key(self): return Key(self.io_group, self.io_channel, self.chip_id) @chip_key.setter def chip_key(self, val): val = Key(val) self.io_group = val.io_group self.io_channel = val.io_channel self.chip_id = val.chip_id
[docs] def is_chip_id_set(self): ''' Check if chip id (as specified by unique key) matches the chip id stored in the configuration. Only valid for v2 asics, if v1 asic, will always return ``True`` Note: Even if this function returns True, it's possible the chip ID has not been sent from the larpix-control software onto the ASIC hardware ''' if self.asic_version == 1: return True elif self.asic_version in (2, 'lightpix-v1.0'): return self.config.chip_id == self.chip_id
[docs] def get_configuration_packets(self, packet_type, registers=None): ''' Return a list of Packet objects to read or write (depending on ``packet_type``) the specified configuration registers (or all registers by default). ''' conf = self.config if registers is None: registers = range(conf.num_registers) packets = [] if self.asic_version == 1: packet_register_data = enumerate(conf.all_data()) elif self.asic_version in (2, 'lightpix-v1.0', '2b'): packet_register_data = zip(*conf.some_data(registers)) for i, data in packet_register_data: if i not in registers: continue if self.asic_version == 1: packet = Packet_v1() else: packet = Packet_v2() packet.packet_type = packet_type packet.chip_id = self.chip_id packet.chip_key = self.chip_key packet.register_address = i if packet_type == packet.CONFIG_WRITE_PACKET: packet.register_data = data elif packet_type == packet.CONFIG_READ_PACKET: packet.register_data = 0 else: raise ValueError('incorrect packet_type for configuration packets') packet.assign_parity() packets.append(packet) return packets
[docs] def get_configuration_write_packets(self, registers=None): ''' Return a list of Packet objects to write corresponding to the specified configuration registers (all by default) ''' if self.asic_version == 1: return self.get_configuration_packets(Packet_v1.CONFIG_WRITE_PACKET, registers) return self.get_configuration_packets(Packet_v2.CONFIG_WRITE_PACKET, registers)
[docs] def get_configuration_read_packets(self, registers=None): ''' Return a list of Packet objects to write corresponding to the specified configuration registers (all by default) ''' if self.asic_version == 1: return self.get_configuration_packets(Packet_v1.CONFIG_READ_PACKET, registers) return self.get_configuration_packets(Packet_v2.CONFIG_READ_PACKET, registers)
[docs] def sync_configuration(self, index=-1): ''' Adjust self.config to match whatever config read packets are in self.reads[index]. Defaults to the most recently read PacketCollection. Later packets in the list will overwrite earlier packets. The ``index`` parameter could be a slice. ''' updates = {} if isinstance(index, slice): for collection in self.reads[index]: for packet in collection: if packet.packet_type == packet.CONFIG_READ_PACKET: updates[packet.register_address] = packet.register_data else: for packet in self.reads[index]: if packet.packet_type == packet.CONFIG_READ_PACKET: updates[packet.register_address] = packet.register_data if self.asic_version == 1: self.config.from_dict_registers(updates) else: self.config.from_dict_registers(updates, endian=Packet_v2.endian)
[docs] def export_reads(self, only_new_reads=True): ''' Return a dict of the packets this Chip has received. If ``only_new_reads`` is ``True`` (default), then only the packets since the last time this method was called will be in the dict. Otherwise, all of the packets stored in ``self.reads`` will be in the dict. ''' data = {} data['chip_key'] = self.chip_key data['chip_id'] = self.chip_id if only_new_reads: packets = self.reads[self.new_reads_index:] else: packets = self.reads data['packets'] = list(map(lambda x:x.export(), packets)) self.new_reads_index = len(self.reads) return data