def __init__(self, name, trigger_device=None, trigger_connection=None, serial='', reference_clock='internal', clock_frequency=100e6, use_wait_monitor=False, trigger_debounce_clock_ticks=10): # set device properties based on clock frequency self.clock_limit = clock_frequency / 2 self.clock_resolution = 1 / clock_frequency # We'll set this to be 2x the debounce count self.trigger_minimum_duration = 2 * trigger_debounce_clock_ticks / clock_frequency # Todo: confirm this. # It should only be 5 clock cycles + the debounce_clock_ticks # as I think it takes 3 clock cycles to propagate to the state # machine of the FPGA code (due to the three uses of the non-blocking <= verilog operator # in the debounce code) and then another 2 cycles before the output goes high # (one to move out of the wait for retrigger code and then one because the update of the # output state is non-blocking)\ # self.trigger_delay = (5 + trigger_debounce_clock_ticks) / clock_frequency # Todo: confirm this # I believe it is 1 clock cycle self.wait_delay = self.clock_resolution PseudoclockDevice.__init__(self, name, trigger_device, trigger_connection) self.BLACS_connection = serial if trigger_debounce_clock_ticks >= 2**16: raise LabscriptError( 'The %s %s trigger_debounce_clock_ticks parameter must be between 0 and 65535' % (self.description, self.name)) # create Pseudoclock and clockline self._pseudoclock = CiceroOpalKellyXEM3001Pseudoclock( '%s_pseudoclock' % name, self, 'clock') # possibly a better connection name than 'clock'? # Create the internal direct output clock_line self._clock_line = ClockLine('%s_clock_line' % name, self.pseudoclock, 'Clock Out') # Create internal devices for connecting to a wait monitor self.__wait_monitor_dummy_pseudoclock = CiceroOpalKellyXEM3001DummyPseudoclock( '%s__dummy_wait_pseudoclock' % name, self, '_') self.__wait_monitor_dummy_clock_line = CiceroOpalKellyXEM3001DummyClockLine( '%s__dummy_wait_clock_line' % name, self.__wait_monitor_dummy_pseudoclock, '_') self.__wait_monitor_intermediate_device = CiceroOpalKellyXEM3001DummyIntermediateDevice( '%s_internal_wait_monitor_outputs' % name, self.__wait_monitor_dummy_clock_line) if use_wait_monitor: WaitMonitor('%s__wait_monitor' % name, self.internal_wait_monitor_outputs, 'internal', self.internal_wait_monitor_outputs, 'internal', self.internal_wait_monitor_outputs, 'internal')
def __init__(self, name, trigger_device=None, trigger_connection=None, usbport='COM1'): PseudoclockDevice.__init__(self, name, trigger_device, trigger_connection) self.BLACS_connection = usbport # create Pseudoclock and clockline self._pseudoclock = PineBlasterPseudoclock('%s_pseudoclock'%name, self, 'clock') # possibly a better connection name than 'clock'? # Create the internal direct output clock_line self._clock_line = ClockLine('%s_clock_line'%name, self.pseudoclock, 'internal')
def __init__(self, name, ip_address, trigger_device=None, trigger_connection=None): PseudoclockDevice.__init__(self, name, trigger_device, trigger_connection) self.BLACS_connection = ip_address # create Pseudoclock and clockline self._pseudoclock = RFBlasterPseudoclock('%s_pseudoclock'%name, self, 'clock') # possibly a better connection name than 'clock'? # Create the internal direct output clock_line self._clock_line = ClockLine('%s_clock_line'%name, self.pseudoclock, 'internal') # Create the internal intermediate device connected to the above clock line # This will have the DDSs of the RFBlaster connected to it self._direct_output_device = RFBlasterDirectOutputs('%s_direct_output_device'%name, self._clock_line)
def __init__(self, name='dummy_pseudoclock', BLACS_connection='dummy_connection', **kwargs): self.BLACS_connection = BLACS_connection PseudoclockDevice.__init__(self, name, None, None, **kwargs) self.pseudoclock = Pseudoclock(self.name + '_pseudoclock', self, 'pseudoclock') self.clockline = ClockLine(name='clockline', pseudoclock=self.pseudoclock, connection='dummy')
def __init__(self, name='dummy_pseudoclock', BLACS_connection='dummy_connection', **kwargs): self.BLACS_connection = BLACS_connection PseudoclockDevice.__init__(self, name, None, None, **kwargs) self._pseudoclock = _DummyPseudoclock( name=f'{name}_pseudoclock', pseudoclock_device=self, connection='pseudoclock', ) self._clock_line = ClockLine( name=f'{name}_clock_line', pseudoclock=self.pseudoclock, connection='internal', )
def __init__(self, name='narwhal_pulsegen', usbport='autodetect', **kwargs): self.BLACS_connection = usbport PseudoclockDevice.__init__(self, name, None, None, **kwargs) # Create the internal pseudoclock self._pseudoclock = NarwhalPulseGenPseudoclock( name=f'{name}_pseudoclock', pseudoclock_device=self, connection='pseudoclock', ) # Create the internal direct output clock_line self._direct_output_clock_line = ClockLine( name=f'{name}_direct_output_clock_line', pseudoclock=self.pseudoclock, connection='internal', ramping_allowed=False, ) # Create the internal intermediate device connected to the above clock line # This will have the direct DigitalOuts of the NarwhalPulseGen connected to it self._direct_output_device = NarwhalPulseGenDirectOutputs( name=f'{name}_direct_output_device', parent_device=self._direct_output_clock_line)
def __init__( self, name, trigger_device=None, trigger_connection=None, com_port="COM1", num_pseudoclocks=1, out_pins=None, in_pins=None, clock_frequency=100e6, external_clock_pin=None, use_wait_monitor=True, ): """PrawnBlaster Pseudoclock labscript device. This labscript device creates Pseudoclocks based on the PrawnBlaster, a Raspberry Pi Pico with custom firmware. Args: name (str): python variable name to assign to the PrawnBlaster com_port (str): COM port assigned to the PrawnBlaster by the OS. Takes the form of `'COMd'`, where `d` is an integer. num_pseudoclocks (int): Number of pseudoclocks to create. Ranges from 1-4. trigger_device (:class:`~labscript.IntermediateDevice`, optional): Device that will send the hardware start trigger when using the PrawnBlaster as a secondary Pseudoclock. trigger_connection (str, optional): Which output of the `trigger_device` is connected to the PrawnBlaster hardware trigger input. out_pins (list, optional): What outpins to use for the pseudoclock outputs. Must have length of at least `num_pseudoclocks`. Defaults to `[9,11,13,15]` in_pins (list, optional): What inpins to use for the pseudoclock hardware triggering. Must have length of at least `num_pseudoclocks`. Defaults to `[0,0,0,0]` clock_frequency (float, optional): Frequency of clock. Standard range accepts up to 133 MHz. An experimental overclocked firmware is available that allows higher frequencies. external_clock_pin (int, optional): If not `None` (the default), the PrawnBlaster uses an external clock on the provided pin. Valid options are `20` and `22`. The external frequency must be defined using `clock_frequency`. use_wait_monitor (bool, optional): Configure the PrawnBlaster to perform its own wait monitoring. """ # Check number of pseudoclocks is within range if num_pseudoclocks < 1 or num_pseudoclocks > 4: raise LabscriptError( f"The PrawnBlaster {name} only supports between 1 and 4 pseudoclocks" ) # Update the specs based on the number of pseudoclocks self.max_instructions = self.max_instructions // num_pseudoclocks # Update the specs based on the clock frequency if self.clock_resolution != 2 / clock_frequency: factor = (2 / clock_frequency) / self.clock_resolution self.clock_limit *= factor self.clock_resolution *= factor self.input_response_time *= factor self.trigger_delay *= factor self.trigger_minimum_duration *= factor self.wait_delay *= factor # Instantiate the base class PseudoclockDevice.__init__(self, name, trigger_device, trigger_connection) self.num_pseudoclocks = num_pseudoclocks # Wait monitor can only be used if this is the master pseudoclock self.use_wait_monitor = use_wait_monitor and self.is_master_pseudoclock # Set the BLACS connections self.BLACS_connection = com_port # Check in/out pins if out_pins is None: out_pins = [9, 11, 13, 15] if in_pins is None: in_pins = [0, 0, 0, 0] if len(out_pins) < num_pseudoclocks: raise LabscriptError( f"The PrawnBlaster {self.name} is configured with {num_pseudoclocks} but only has pin numbers specified for {len(out_pins)}." ) else: self.out_pins = out_pins[:num_pseudoclocks] if len(in_pins) < num_pseudoclocks: raise LabscriptError( f"The PrawnBlaster {self.name} is configured with {num_pseudoclocks} but only has pin numbers specified for {len(in_pins)}." ) else: self.in_pins = in_pins[:num_pseudoclocks] self._pseudoclocks = [] self._clocklines = [] for i in range(num_pseudoclocks): self._pseudoclocks.append( _PrawnBlasterPseudoclock( i, name=f"{name}_pseudoclock_{i}", pseudoclock_device=self, connection=f"pseudoclock {i}", )) self._clocklines.append( ClockLine( name=f"{name}_clock_line_{i}", pseudoclock=self._pseudoclocks[i], connection=f"GPIO {self.out_pins[i]}", )) if self.use_wait_monitor: # Create internal devices for connecting to a wait monitor self.__wait_monitor_dummy_pseudoclock = _PrawnBlasterDummyPseudoclock( "%s__dummy_wait_pseudoclock" % name, self, "_") self.__wait_monitor_dummy_clock_line = _PrawnBlasterDummyClockLine( "%s__dummy_wait_clock_line" % name, self.__wait_monitor_dummy_pseudoclock, "_", ) self.__wait_monitor_intermediate_device = ( _PrawnBlasterDummyIntermediateDevice( "%s_internal_wait_monitor_outputs" % name, self.__wait_monitor_dummy_clock_line, )) # Create the wait monitor WaitMonitor( "%s__wait_monitor" % name, self.internal_wait_monitor_outputs, "internal", self.internal_wait_monitor_outputs, "internal", self.internal_wait_monitor_outputs, "internal", )
def __init__(self, name='dummy_pseudoclock', BLACS_connection='dummy_connection', **kwargs): self.BLACS_connection = BLACS_connection PseudoclockDevice.__init__(self, name, None, None, **kwargs)