Hi, I have got a bit of a weird issue which I don't understand. Let's look at the following script (or the four scripts I packed into one for debugging-purposes):

from artiq.experiment import *

class test_script(EnvExperiment):
    def build(self):
        self.setattr_device("core")
        self.setattr_device("urukul2_cpld")
        self.setattr_device("urukul2_ch1")
        self.setattr_device("urukul2_ch2")

        self.cpld=self.urukul2_cpld
        self.dds1=self.urukul2_ch1
        self.dds2=self.urukul2_ch2

        self.setattr_argument("init", BooleanValue(False))
        self.setattr_argument("first", BooleanValue(False))
        self.setattr_argument("second", BooleanValue(False))

    @kernel
    def run(self):

        self.core.reset()

        if self.init:
            self.cpld.init()
            self.dds1.init()
            self.dds2.init()
            self.core.break_realtime()

        if self.first:
            self.dds1.cfg_sw(True)
        
        if self.second:
            self.dds2.cfg_sw(True)

Let's now look at two situations, where I run this "experiment" multiple tiimes:

Situation 1:

  • I run with init=True
  • I run with first=True and second=True

Situation 2:

  • I run with init=True
  • I run with first=True
  • I run with second=True

In both situations, I would expect both of my urukul-channels to be turned on in the end. In the situation 1, this is the case. In situation two, only dds2 is active in the end. dds1 seems to be deactivated again by the second call to 'cfg_sw()'. Why is that and how do I set a dds in an experiment without re-setting all the other channels?

Do a sta_read() or set the "expected" state in the device db.

    rjo Do a sta_read() or set the "expected" state in the device db.

    Hi, thanks for the answer, I tried it (see below), but it doesn't change anything in the behaviour. Can you explain how the sta_read() should change anything or what it does? Or why cfg_sw() behaves so weirdly at all? My code now looks like this:

            if self.first:
                self.dds1.cpld.sta_read()
                self.core.break_realtime()
                self.dds1.cfg_sw(True)
            
            if self.second:
                self.dds2.cpld.sta_read()
                self.core.break_realtime()
                self.dds2.cfg_sw(True)

    OK, I have now figured it out myself. As you can find deeply hidden inside the code (Definition of the CPLD-class), the setting of the RF-switch register is not kept between experiments:

    :param rf_sw: Initial CPLD RF switch register setting (default: 0x0). Knowledge of this state is not transferred between experiments.

    Therefore, my code now looks as follows and it seems to work:

        @kernel
        def run(self):
            self.core.reset()
    
            if self.init:
                self.cpld.init()
                self.dds1.init()
                self.dds2.init()
                self.core.break_realtime()
    
    
            sta=self.cpld.sta_read()
            sw_sta=urukul.urukul_sta_rf_sw(sta)
            self.core.break_realtime()
    
            self.cpld.cfg_write(urukul.urukul_cfg(rf_sw=sw_sta, led=0, 
                                                  profile=urukul.DEFAULT_PROFILE,
                                                  io_update=0, mask_nu=0, clk_sel=0,
                                                  sync_sel=0, rst=0, io_rst=0, clk_div=0))
            self.core.break_realtime()
    
    
            if self.first:
                self.dds1.cfg_sw(True)
            
            if self.second:
                self.dds2.cfg_sw(True)