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)