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')
예제 #3
0
 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)
예제 #4
0
 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')
예제 #5
0
 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)
예제 #6
0
 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)
예제 #8
0
    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)