From 4d21a72407bf7b2ef56d0c8f0acb7b2bcf2e8000 Mon Sep 17 00:00:00 2001 From: SingularitySurfer Date: Wed, 18 Aug 2021 15:01:11 +0000 Subject: [PATCH 1/3] Implement SUServo tester. --- artiq/frontend/artiq_sinara_tester.py | 99 ++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/artiq/frontend/artiq_sinara_tester.py b/artiq/frontend/artiq_sinara_tester.py index 5c88d5917..9ca1cb932 100755 --- a/artiq/frontend/artiq_sinara_tester.py +++ b/artiq/frontend/artiq_sinara_tester.py @@ -55,6 +55,8 @@ class SinaraTester(EnvExperiment): self.grabbers = dict() self.mirny_cplds = dict() self.mirnies = dict() + self.suservos = dict() + self.suschannels = dict() ddb = self.get_device_db() for name, desc in ddb.items(): @@ -88,9 +90,13 @@ class SinaraTester(EnvExperiment): self.mirny_cplds[name] = self.get_device(name) elif (module, cls) == ("artiq.coredevice.adf5356", "ADF5356"): self.mirnies[name] = self.get_device(name) + elif (module, cls) == ("artiq.coredevice.suservo", "SUServo"): + self.suservos[name] = self.get_device(name) + elif (module, cls) == ("artiq.coredevice.suservo", "Channel"): + self.suschannels[name] = self.get_device(name) # Remove Urukul, Sampler, Zotino and Mirny control signals - # from TTL outs (tested separately) + # from TTL outs (tested separately) and remove SUServo Urukuls ddb = self.get_device_db() for name, desc in ddb.items(): if isinstance(desc, dict) and desc["type"] == "local": @@ -101,8 +107,17 @@ class SinaraTester(EnvExperiment): sw_device = desc["arguments"]["sw_device"] del self.ttl_outs[sw_device] elif (module, cls) == ("artiq.coredevice.urukul", "CPLD"): - io_update_device = desc["arguments"]["io_update_device"] - del self.ttl_outs[io_update_device] + if "io_update_device" in desc["arguments"]: + io_update_device = desc["arguments"]["io_update_device"] + del self.ttl_outs[io_update_device] + # check for suservos and delete respective urukuls + elif (module, cls) == ("artiq.coredevice.suservo", "SUServo"): + del self.urukuls[desc["arguments"]["dds0_device"]] + del self.urukul_cplds[desc["arguments"]["cpld0_device"]] + if "dds1_device" in desc["arguments"]: + del self.urukuls[desc["arguments"]["dds1_device"]] + if "cpld1_device" in desc["arguments"]: + del self.urukul_cplds[desc["arguments"]["cpld1_device"]] elif (module, cls) == ("artiq.coredevice.sampler", "Sampler"): cnv_device = desc["arguments"]["cnv_device"] del self.ttl_outs[cnv_device] @@ -126,6 +141,8 @@ class SinaraTester(EnvExperiment): self.phasers = sorted(self.phasers.items(), key=lambda x: x[1].channel_base) self.grabbers = sorted(self.grabbers.items(), key=lambda x: x[1].channel_base) self.mirnies = sorted(self.mirnies.items(), key=lambda x: (x[1].cpld.bus.channel, x[1].channel)) + self.suservos = sorted(self.suservos.items(), key=lambda x: x[1].channel) + self.suschannels = sorted(self.suschannels.items(), key=lambda x: x[1].channel) @kernel def test_led(self, led): @@ -555,6 +572,80 @@ class SinaraTester(EnvExperiment): print(card_name) self.grabber_capture(card_dev, rois) + @kernel + def setup_suservo(self, channel): + self.core.break_realtime() + channel.init() + delay(1*us) + # ADC PGIA gain 0 + for i in range(8): + channel.set_pgia_mu(i, 0) + delay(10*us) + # DDS attenuator 10dB + for i in range(4): + channel.cpld0.set_att(i, 10.) + channel.cpld1.set_att(i, 10.) + delay(1*us) + # Servo is done and disabled + assert channel.get_status() & 0xff == 2 + delay(10*us) + + @kernel + def setup_suservo_loop(self, channel, loop_nr): + self.core.break_realtime() + channel.set_y( + profile=loop_nr, + y=0. # clear integrator + ) + channel.set_iir( + profile=loop_nr, + adc=loop_nr, # take data from Sampler channel + kp=-.1, # -0.1 P gain + ki=0./s, # low integrator gain + g=0., # no integrator gain limit + delay=0. # no IIR update delay after enabling + ) + # setpoint 0.5 (5 V with above PGIA gain setting) + # 0 phase + delay(100*us) + channel.set_dds( + profile=loop_nr, + offset=-.3, # 3 V with above PGIA settings + frequency=10*MHz, + phase=0.) + # enable RF, IIR updates and profile 0 + delay(10*us) + channel.set(en_out=1, en_iir=1, profile=loop_nr) + + @kernel + def setup_start_suservo(self, channel): + self.core.break_realtime() + channel.set_config(enable=1) + delay(10*us) + + # check servo enabled + assert channel.get_status() & 0x01 == 1 + delay(10*us) + + def test_suservos(self): + print("*** Testing SUServos.") + print("Initializing...") + for card_n, (card_name, card_dev) in enumerate(self.suservos): + print(card_name + "...") + self.setup_suservo(card_dev) + print("Setup SUServo loops.") + print("Urukul0 channels corresponds to Sampler channels 0-3 and Urukul1 channels correspont to Sampler channels 4-7.") + print("Only proportional gain and offset such that 1.5V on the input gives 6dB less output power than at 0V input. (open loop)") + print("Frequency: 10MHz. Output power at 0V input: ~-29dBm") + for card_n, channels in enumerate(chunker(self.suschannels, 8)): + for channel_n, (channel_name, channel_dev) in enumerate(channels): + self.setup_suservo_loop(channel_dev, channel_n) + print("Enabling...") + for card_n, (card_name, card_dev) in enumerate(self.suservos): + self.setup_start_suservo(card_dev) + print("Press ENTER when done.") + input() + def run(self): print("****** Sinara system tester ******") print("") @@ -579,6 +670,8 @@ class SinaraTester(EnvExperiment): self.test_phasers() if self.grabbers: self.test_grabbers() + if self.suservos: + self.test_suservos() def main(): From a53162d01dd3c952181f7d35b291430629248081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Thu, 19 Aug 2021 09:17:14 +0200 Subject: [PATCH 2/3] tester: tweak suservo * p gain 1 to get reasonable power * refine testing instructions and comments --- artiq/frontend/artiq_sinara_tester.py | 45 +++++++++++++++------------ 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/artiq/frontend/artiq_sinara_tester.py b/artiq/frontend/artiq_sinara_tester.py index 9ca1cb932..ec9f504ee 100755 --- a/artiq/frontend/artiq_sinara_tester.py +++ b/artiq/frontend/artiq_sinara_tester.py @@ -96,7 +96,8 @@ class SinaraTester(EnvExperiment): self.suschannels[name] = self.get_device(name) # Remove Urukul, Sampler, Zotino and Mirny control signals - # from TTL outs (tested separately) and remove SUServo Urukuls + # from TTL outs (tested separately) and remove Urukuls covered by + # SUServo ddb = self.get_device_db() for name, desc in ddb.items(): if isinstance(desc, dict) and desc["type"] == "local": @@ -116,7 +117,6 @@ class SinaraTester(EnvExperiment): del self.urukul_cplds[desc["arguments"]["cpld0_device"]] if "dds1_device" in desc["arguments"]: del self.urukuls[desc["arguments"]["dds1_device"]] - if "cpld1_device" in desc["arguments"]: del self.urukul_cplds[desc["arguments"]["cpld1_device"]] elif (module, cls) == ("artiq.coredevice.sampler", "Sampler"): cnv_device = desc["arguments"]["cnv_device"] @@ -600,20 +600,19 @@ class SinaraTester(EnvExperiment): channel.set_iir( profile=loop_nr, adc=loop_nr, # take data from Sampler channel - kp=-.1, # -0.1 P gain - ki=0./s, # low integrator gain - g=0., # no integrator gain limit - delay=0. # no IIR update delay after enabling + kp=-1., # -1 P gain + ki=0./s, # no integrator gain + g=0., # no integrator gain limit + delay=0. # no IIR update delay after enabling ) # setpoint 0.5 (5 V with above PGIA gain setting) - # 0 phase delay(100*us) channel.set_dds( profile=loop_nr, offset=-.3, # 3 V with above PGIA settings frequency=10*MHz, phase=0.) - # enable RF, IIR updates and profile 0 + # enable RF, IIR updates and set profile delay(10*us) channel.set(en_out=1, en_iir=1, profile=loop_nr) @@ -622,27 +621,33 @@ class SinaraTester(EnvExperiment): self.core.break_realtime() channel.set_config(enable=1) delay(10*us) - # check servo enabled assert channel.get_status() & 0x01 == 1 delay(10*us) def test_suservos(self): print("*** Testing SUServos.") - print("Initializing...") - for card_n, (card_name, card_dev) in enumerate(self.suservos): - print(card_name + "...") + print("Initializing modules...") + for card_name, card_dev in self.suservos: + print(card_name) self.setup_suservo(card_dev) - print("Setup SUServo loops.") - print("Urukul0 channels corresponds to Sampler channels 0-3 and Urukul1 channels correspont to Sampler channels 4-7.") - print("Only proportional gain and offset such that 1.5V on the input gives 6dB less output power than at 0V input. (open loop)") - print("Frequency: 10MHz. Output power at 0V input: ~-29dBm") - for card_n, channels in enumerate(chunker(self.suschannels, 8)): - for channel_n, (channel_name, channel_dev) in enumerate(channels): - self.setup_suservo_loop(channel_dev, channel_n) + print("...done") + print("Setting up SUServo channels...") + for channels in chunker(self.suschannels, 8): + for i, (channel_name, channel_dev) in enumerate(channels): + print(channel_name) + self.setup_suservo_loop(channel_dev, i) + print("...done") print("Enabling...") - for card_n, (card_name, card_dev) in enumerate(self.suservos): + for card_name, card_dev in enumerate(self.suservos): + print(card_name) self.setup_start_suservo(card_dev) + print("...done") + print("Each Sampler channel applies proportional amplitude control") + print("on the respective Urukul0 (ADC 0-3) and Urukul1 (ADC 4-7, if") + print("present) channels.") + print("Frequency: 10 MHz, output power: about -9 dBm at 0 V and about -15 dBm at 1.5 V") + print("Verify frequency and power behavior.") print("Press ENTER when done.") input() From 65f63e6927a6d636e6a67738312c30ac47e9ea30 Mon Sep 17 00:00:00 2001 From: SingularitySurfer Date: Thu, 19 Aug 2021 07:38:48 +0000 Subject: [PATCH 3/3] fix suservo start --- artiq/frontend/artiq_sinara_tester.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artiq/frontend/artiq_sinara_tester.py b/artiq/frontend/artiq_sinara_tester.py index ec9f504ee..078d7db5e 100755 --- a/artiq/frontend/artiq_sinara_tester.py +++ b/artiq/frontend/artiq_sinara_tester.py @@ -639,7 +639,7 @@ class SinaraTester(EnvExperiment): self.setup_suservo_loop(channel_dev, i) print("...done") print("Enabling...") - for card_name, card_dev in enumerate(self.suservos): + for card_name, card_dev in self.suservos: print(card_name) self.setup_start_suservo(card_dev) print("...done")