I am currently working on configuring a sampler and Urukul in a suservo setup for laser intensity stabilization. My primary goal at the moment is to obtain a signal from the Urukul module with feedback disabled.

Current Status:
Despite the apparent correctness of the code, I am unable to obtain a signal from the Urukul module. Notably, the RF Switch (green LED) is lit, and the DDS (red LED) is correctly set up. I have also taken some steps to validate the configuration. I ensured that the PLL is configured properly by removing the MMCX cable and observing that the red LED starts glowing. Additionally, I confirmed that channel settings are being written correctly by enabling and disabling channels through code and observing the behavior of the RF LED.

However, I am not entirely certain about the configurations for the iir and dds.

Code Reference:
To guide my work, I have been following the code example provided in the 'GitHub Example'
[https://github.com/m-labs/artiq/blob/master/artiq/examples/kasli_suservo/repository/suservo.py#L82]

I have attached my code and device database files for your perusal.

Hardware Configuration:

  1. One Urukul and a sampler
  2. MMCX clock
  3. Currently, there is no input provided to the sampler.

I would greatly appreciate any insights or assistance that forum members can offer. Your expertise and guidance will be instrumental in resolving this matter. Thank you in advance for your support.

Code
`

from artiq.experiment import *
class SuServo_Minimal(EnvExperiment):

def build(self):
    self.setattr_device("core")
    self.setattr_device("suservo0")

    for i in range(4):
        self.setattr_device("suservo0_ch{}".format(i))


@kernel
def run(self):
    self.core.break_realtime()

    self.core.reset()
    self.suservo0.init()       #Initialize the servo


    #set the attenuation on the DDS channels
    self.suservo0.cplds[0].set_att(0, 10.)


    #Set the sampler gain on channel 0
    self.suservo0.set_pgia_mu(0, 0)


    #Validate survo is done and disabled
    assert self.suservo0.get_status() & 0xff == 2


    #Enable output on suservo0_ch0 to generate 70 * MHz frequency
    for channel in [self.suservo0_ch0]:
        delay(100 * us)
        channel.set(en_out=0)  #Start by disabling channel
        delay(100 * us)
        #Take the input from channel 0
        channel.set_iir(profile=0, adc=0, kp=-0.1, ki=-300./s, g=0.,delay=0.)
        delay(100 * us)
        channel.set_dds(profile=0,offset=-0.5, frequency=71*MHz, phase=0.)
        delay(100 * us)
        channel.set(en_out=1, en_iir=0, profile=0)  # Enable channel, but keep the PID loop disabled`

Relevant portion of device db file
`

    device_db["suservo0_ch0"] = {
        "type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x000008, "servo_device": "suservo0"}
 }
device_db["suservo0_ch1"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x000009, "servo_device": "suservo0"}
}

device_db["suservo0_ch2"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x00000a, "servo_device": "suservo0"}
}

device_db["suservo0_ch3"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x00000b, "servo_device": "suservo0"}
}

device_db["suservo0_ch4"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x00000c, "servo_device": "suservo0"}
}

device_db["suservo0_ch5"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x00000d, "servo_device": "suservo0"}
}

device_db["suservo0_ch6"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x00000e, "servo_device": "suservo0"}
}

device_db["suservo0_ch7"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "Channel",
	"arguments": {"channel": 0x00000f, "servo_device": "suservo0"}
}

device_db["suservo0"] = {
	"type": "local",
	"module": "artiq.coredevice.suservo",
	"class": "SUServo",
	"arguments": {
		"channel": 0x000010,
		"pgia_device": "spi_sampler0_pgia",
		"cpld_devices": ['urukul0_cpld', 'urukul1_cpld'],
		"dds_devices": ['urukul0_dds', 'urukul1_dds']
	}
}

device_db["spi_sampler0_pgia"] = {
	"type": "local",
	"module": "artiq.coredevice.spi2",
	"class": "SPIMaster",
	"arguments": {"channel": 0x000011}
}

device_db["spi_urukul0"] = {
	"type": "local",
	"module": "artiq.coredevice.spi2",
	"class": "SPIMaster",
	"arguments": {"channel": 0x000012}
}
device_db["urukul0_cpld"] = {
	"type": "local",
	"module": "artiq.coredevice.urukul",
	"class": "CPLD",
	"arguments": {
		"spi_device": "spi_urukul0",
		"refclk": 125e6,
		"clk_sel": 2
	}
}
device_db["urukul0_dds"] = {
	"type": "local",
	"module": "artiq.coredevice.ad9910",
	"class": "AD9910",
	"arguments": {
		"pll_n": 32,
		"pll_en": 1,
		"chip_select": 3,
		"cpld_device": "urukul0_cpld"
	}
}

device_db["spi_urukul1"] = {
	"type": "local",
	"module": "artiq.coredevice.spi2",
	"class": "SPIMaster",
	"arguments": {"channel": 0x000013}
}
device_db["urukul1_cpld"] = {
	"type": "local",
	"module": "artiq.coredevice.urukul",
	"class": "CPLD",
	"arguments": {
		"spi_device": "spi_urukul1",
		"refclk": 125e6,
		"clk_sel": 2
	}
}
device_db["urukul1_dds"] = {
	"type": "local",
	"module": "artiq.coredevice.ad9910",
	"class": "AD9910",
	"arguments": {
		"pll_n": 32,
		"chip_select": 3,
		"cpld_device": "urukul1_cpld"
	}
}`

Which Bitstream/kasli Variant Name?
What's connected to the sampler input channel in question?
Note that with the iir filter disabled the output will remain at zero.
See the example.you reference. And also artiq_sinara_tester.

  • mkc replied to this.

    I'm a bit confused because in an earlier discussion thread [https://forum.m-labs.hk/d/264-suservo-pid-loop], it was claimed that DDS output could be obtained with the PID loop disabled with ' iir=0'. Has something changed since then?

    To address your questions:

    I am currently using the Kasli EEM controller version 2.0 with artiq-7.
    Up to this point, I haven't provided a proper analog signal to the sampler.

    Currently, both the artiq_sinara_tester and my code run fine with 'iir=1' set. However, I do not see the DDS output. I assume that with a proper analog signal applied to the sampler, I should be able to observe the DDS output.

    rjo Any further thougts?
    Thanks for looking!

    Seem to me that you are missing self.suservo0.set_config(enable=1) in your code, which activate the whole suservo device.

    @mkc I meant the kasli json variant name in AFWS and the supplier that you bought it from. They will support your configuration and ensure your crate is built correctly and has valid device-db and gateware.

    • mkc replied to this.

      rjo
      We are building the gateware locally. I am pasting the information from the sdf.json file over here if that helps.

      {
      "target": "kasli",
      "min_artiq_version": "6.0",
      "variant": "nqcc-staging",
      "hw_rev": "v2.0",
      "base": "master",
      "core_addr": "172.18.0.31",
      "peripherals": [
      {
      "type": "dio",
      "board": "DIO_BNC",
      "hw_rev": "v1.6",
      "ports": [1],
      "bank_direction_low": "input",
      "bank_direction_high": "input"
      },
      {
      "type": "suservo",
      "sampler_ports": [3, 4],
      "urukul0_ports": [5, 6],
      "clk_sel": 2
      }
      ]
      }

      The coremgmt log shows the version as 7.8112.de6f444, and I use the revision 21c6f57ce18cdd0c41f467434d58c0b9193da374 while building the gateware.

      Although I understand that one should reach out to the vendor who supplied the hardware, your response also seems to suggest that the configuration can be vendor-dependent. This is disconcerting to me given that Sinara and ARTIQ are open standards.

        The custom configuration is what we as vendors design, supply, and maintain for you based on your specification and requirements. It's what makes this flexible. If you defer to M-Labs or QUARTIQ to do that work for you it enables support, this forum, and some of the development and maintenance on ARTIQ and Sinara. If you prefer to do it yourself, you will need to develop the know-how and the experience yourself. I'm uncertain what "open standard" exactly means in practice, whether or not ARTIQ/Sinara are one, or who claims and decides that. But luckily it also appears irrelevant here.
        Looking at the technical aspects, again, please first make sure your hardware and configuration are fine using artiq_sinara_tester. Help with the code from others (the code you reference) is best provided by those who posted it.

        7 days later

        mkc Although I understand that one should reach out to the vendor who supplied the hardware, your response also seems to suggest that the configuration can be vendor-dependent. This is disconcerting to me given that Sinara and ARTIQ are open standards.

        Not sure what you mean by "vendor-dependent". ARTIQ/Sinara systems, including SU-Servo, are built with the published open source code and hardware schematics, there is no secret sauce. As @rjo points out there is some learning curve if you want to do it yourself.