aquinn one other suggestion: try using the get_y method and other get_ methods to read back the parameters that have been set and check everything is updating correctly

    hartytp Using the get_ methods, it looks like the Kasli is able to update the Urukul's parameters properly, but from the LEDs, it looks like the DDS are not getting initialized. This gives a possible lead! We'll continue looking into it.

    Okay. So calling the servo init isn’t initialising your urukul correctly. Probably one of:clocking issue, dip switches incorrect for servo (you need to switch one to enable servo mode) or a gateware/device_db mismatch. One thing you can try is probing the urukul eem cable and check you get spi transactions when you call the init code. Also try probing the clock chip and check the right clock gets to the ddss

    Thanks for the help @hartytp. Our best guess right now is that it's a gateware/device_db mismatch. Therefore we are going to wait until we get a new Artiq 5 gateware/device_db combo built using the new M-Labs build system before debugging further.

    20 days later
    5 days later

    @sb10q, the kasli-oregon configuration seems to be working just fine! There's something about SU servo though that I wasn't entirely clear on. Is there any way of directly controlling the set point for the Sampler? The closest I could find was the offset parameter in Channel.set_dds(), and it seems like the y-value is being set to this offset parameter regardless of what kind of signal is being fed into the Sampler. It doesn't look like the Urukul signal is being modulated.

    I just wanted to clarify whether or not the offset parameter is used to control the set point before continuing to debug our current code/hardware setup.

    Yes. E.g. set_dds(offset=-.5) controls the offset of the ADC inputs and thus the setpoint of the servo.

    And make sure you have the P/I profile coefficients and all parameters (ADC channel, channel enable, IIR enable, delay etc), set up as well, then select profile and enable the channel.

      rjo Thank you very much for the confirmation! That's very helpful to know. We were also wondering though if there's any way of converting between volts (which the ADC measures in) and the full scale units of the set point, or if we find this relationship through measurement.

      rjo We were able to get our servo system up and running. Thank you very much for your help!

      Edit: In case someone else comes along who might benefit from it, here's an example of some minimal code that gets a servo loop running. This loop will target the input voltage v_t for the Sampler channel adc_ch. The target voltage is set using the offset parameter in set_dds. This offset should be minus the target voltage scaled by the gain.

      from artiq.experiment import *
      
      
      class SUServoMinimal(EnvExperiment):
          def build(self):
              self.setattr_device("core")
              self.setattr_device("urukul0_cpld")
              self.setattr_device("suservo0")
              self.setattr_device("suservo0_ch0")
          
          @kernel
          def run(self):
              # Prepare core
              self.core.reset()
      
              #Initialize and activate SUServo
              self.suservo0.init()
              self.suservo0.set_config(enable=1)
              
              # Set Sampler gain and Urukul attenuation
              g = 0
              A = 0.0
              self.suservo0.set_pgia_mu(0, g)         # set gain on Sampler channel 0 to 10^g
              self.suservo0.cpld0.set_att(0, A)       # set attenuation on Urukul channel 0 to 0
              
              
              # Set physical parameters
              v_t = 0.07                              # target input voltage (V) for Sampler channel
              f = 100000000.0                         # frequency (Hz) of Urukul output
              o = -v_t*(10.0**(g-1))                  # offset to assign to servo to reach target voltage
      
              # Set PI loop parameters 
              kp = 0.005                              # proportional gain in loop
              ki = -10.0                              # integrator gain
              gl = 0.0                                # integrator gain limit
              adc_ch = 0                              # Sampler channel to read from
              
              # Input parameters, activate Urukul output (en_out=1),
              # activate PI loop (en_iir=1)
              self.suservo0_ch0.set_iir(profile=0, adc=adc_ch, kp=kp, ki=ki, g=gl)
              self.suservo0_ch0.set_dds(profile=0, frequency=f, offset=o)
              self.suservo0_ch0.set(en_out=1, en_iir=1, profile=0)