def __init__(self, hostname, dsoc_desc=None, boffile=None): """ Initialize an ArtooDaq object. Parameters ---------- hostname : string Address of the roach2 on the 1GbE (control) network. dsoc_desc : tuple A tuple with the first element the IP address / hostname and the second element the port where data is to be received. This argument, if not None, is passed directly to socket.bind(); see the documentation of that class for details. In this case a socket is opened and bound to the given address. If None, then the data socket is not opened. Default is None. boffile : string Program the device with this bitcode if not None. The special filename 'latest-build' uses the current build of the bit-code. Default is None. """ # connect to roach and store local copy of FpgaClient r2 = FpgaClient(hostname) if not r2.wait_connected(self._TIMEOUT): raise RuntimeError( "Unable to connect to ROACH2 named '{0}'".format(hostname)) self._roach2 = r2 # program bitcode if not boffile is None: self._start(boffile) # if requested, open data socket if not dsoc_desc is None: self.open_dsoc(dsoc_desc)
def __init__(self, roach=None, roachip='roach', adc_valon=None, host_ip=None, nfs_root='/srv/roach_boot/etch', lo_valon=None): """ Abstract class to represent readout system roach: an FpgaClient instance for communicating with the ROACH. If not specified, will try to instantiate one connected to *roachip* roachip: (optional). Network address of the ROACH if you don't want to provide an FpgaClient adc_valon: a Valon class, a string, or None Provide access to the Valon class which controls the Valon synthesizer which provides the ADC and DAC sampling clock. The default None value will use the valon.find_valon function to locate a synthesizer and create a Valon class for you. You can alternatively pass a string such as '/dev/ttyUSB0' to specify the port for the synthesizer, which will then be used for creating a Valon class. Finally, for test suites, you can directly pass a Valon class or a class with the same interface. host_ip: Override IP address to which the ROACH should send it's data. If left as None, the host_ip will be set appropriately based on the HOSTNAME. """ self.is_roach2 = False self._using_mock_roach = False if roach: self.r = roach # Check if we're using a fake ROACH for testing. If so, disable additional externalities # This logic could be made more general if desired (i.e. has attribute mock # or type name matches regex including 'mock' if type(roach) is MockRoach: self._using_mock_roach = True else: # pragma: no cover from corr.katcp_wrapper import FpgaClient logger.debug("Creating FpgaClient") self.r = FpgaClient(roachip) t1 = time.time() timeout = 10 logger.debug("Waiting for connection to ROACH") while not self.r.is_connected(): if (time.time() - t1) > timeout: raise Exception("Connection timeout to roach") time.sleep(0.1) logger.debug("ROACH is connected") if adc_valon is None: # pragma: no cover from kid_readout.roach import valon ports = valon.find_valons() if len(ports) == 0: self.adc_valon_port = None self.adc_valon = None logger.warn( "Warning: No valon found! You will not be able to change or verify the sampling frequency" ) else: for port in ports: try: self.adc_valon_port = port self.adc_valon = valon.Synthesizer(port) f = self.adc_valon.get_frequency_a() break except: pass elif type(adc_valon) is str: # pragma: no cover from kid_readout.roach import valon self.adc_valon_port = adc_valon self.adc_valon = valon.Synthesizer(self.adc_valon_port) else: self.adc_valon = adc_valon if type(lo_valon) is str: # pragma: no cover from kid_readout.roach import valon self.lo_valon_port = lo_valon self.lo_valon = valon.Synthesizer(self.lo_valon_port) else: self.lo_valon = lo_valon if host_ip is None: # pragma: no cover hostname = socket.gethostname() if hostname == 'detectors': host_ip = '192.168.1.1' else: host_ip = '192.168.1.1' self.host_ip = host_ip self.roachip = roachip self.nfs_root = nfs_root self._config_file_name = CONFIG_FILE_NAME_TEMPLATE % self.roachip self.adc_atten = 31.5 self.dac_atten = -1 self.fft_gain = 0 self.fft_bins = None self.tone_nsamp = None self.tone_bins = None self.phases = None self.amps = None self.readout_selection = None self.modulation_output = 0 self.modulation_rate = 0 self.wavenorm = None self.phase0 = None self.loopback = None self.debug_register = None # Things to be configured by subclasses self.lo_frequency = 0.0 self.iq_delay = 0 self.heterodyne = False self.bof_pid = None self.boffile = None self.wafer = None self.raw_adc_ns = 2**12 # number of samples in the raw ADC buffer self.nfft = None # Boffile specific register names self._fpga_output_buffer = None