From f055bf88f6b5137f1caca22b81a0af65e8d64559 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Wed, 9 May 2018 07:16:15 +0000 Subject: [PATCH] suservo: add clip flags (#992) --- artiq/coredevice/suservo.py | 4 +++- .../kasli_suservo/repository/suservo.py | 20 +++++++++++++------ artiq/gateware/rtio/phy/servo.py | 7 ++++++- artiq/gateware/suservo/iir.py | 8 ++++++-- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/artiq/coredevice/suservo.py b/artiq/coredevice/suservo.py index 8dfff8af1..c5aa6f2d1 100644 --- a/artiq/coredevice/suservo.py +++ b/artiq/coredevice/suservo.py @@ -109,8 +109,10 @@ class SUServo: """Get current SU Servo status. This method does not advance the timeline but consumes all slack. + This method returns and clears the clip indicator for all channels. - :return: Status. Bit 0: enabled, bit 1: done + :return: Status. Bit 0: enabled, bit 1: done, + bits 8-15: channel clip indicators. """ return self.read(CONFIG_ADDR) diff --git a/artiq/examples/kasli_suservo/repository/suservo.py b/artiq/examples/kasli_suservo/repository/suservo.py index 61ad9f47f..cf49a77fb 100644 --- a/artiq/examples/kasli_suservo/repository/suservo.py +++ b/artiq/examples/kasli_suservo/repository/suservo.py @@ -29,7 +29,8 @@ class SUServo(EnvExperiment): # DDS attenuator self.suservo0.cpld0.set_att_mu(0, 64) delay(1*us) - assert self.suservo0.get_status() == 2 + # Servo is done + assert self.suservo0.get_status() & 0xff == 2 delay(10*us) # set up profile 0 on channel 0 @@ -51,16 +52,19 @@ class SUServo(EnvExperiment): delay(10*ms) # check servo status - assert self.suservo0.get_status() == 1 + assert self.suservo0.get_status() & 0xff == 1 delay(10*us) # reach back ADC data - print(self.suservo0.get_adc_mu(0)) - delay(10*ms) + assert self.suservo0.get_adc_mu(0) == 0 + delay(10*us) # read out IIR data - print(self.suservo0_ch0.get_y_mu(0)) - delay(10*ms) + assert self.suservo0_ch0.get_y_mu(0) == 0x1ffff + delay(10*us) + + assert self.suservo0.get_status() & 0xff00 == 0x0100 + delay(10*us) # repeatedly clear the IIR state/integrator # with the ADC yielding 0's and given the profile configuration, @@ -69,6 +73,10 @@ class SUServo(EnvExperiment): while True: self.suservo0_ch0.set(1, 0, 0) delay(1*us) + assert self.suservo0.get_status() & 0xff00 == 0x0100 + delay(10*us) + assert self.suservo0.get_status() & 0xff00 == 0x0000 + delay(10*us) self.suservo0_ch0.set_y_mu(0, 0) delay(1*us) self.suservo0_ch0.set(1, 1, 0) diff --git a/artiq/gateware/rtio/phy/servo.py b/artiq/gateware/rtio/phy/servo.py index eb1f8495f..a4ef729a4 100644 --- a/artiq/gateware/rtio/phy/servo.py +++ b/artiq/gateware/rtio/phy/servo.py @@ -58,9 +58,11 @@ class RTServoMem(Module): config = Signal(w.coeff, reset=0) status = Signal(w.coeff) + pad = Signal(6) self.comb += [ Cat(servo.start).eq(config), - status.eq(Cat(servo.start, servo.done)) + status.eq(Cat(servo.start, servo.done, pad, + [_.clip for _ in servo.iir.ctrl])) ] assert len(self.rtlink.o.address) == ( @@ -108,6 +110,9 @@ class RTServoMem(Module): self.sync.rio_phy += [ If(self.rtlink.o.stb & we & state_sel & config_sel, config.eq(self.rtlink.o.data) + ), + If(read & read_config & read_state, + [_.clip.eq(0) for _ in servo.iir.ctrl] ) ] self.comb += [ diff --git a/artiq/gateware/suservo/iir.py b/artiq/gateware/suservo/iir.py index bd4c7dda2..c8b31da6e 100644 --- a/artiq/gateware/suservo/iir.py +++ b/artiq/gateware/suservo/iir.py @@ -238,6 +238,7 @@ class IIR(Module): ("profile", w.profile), ("en_out", 1), ("en_iir", 1), + ("clip", 1), ("stb", 1)]) for i in range(1 << w.channel)] # only update during ~loading @@ -266,6 +267,7 @@ class IIR(Module): profiles = Array([ch.profile for ch in self.ctrl]) en_outs = Array([ch.en_out for ch in self.ctrl]) en_iirs = Array([ch.en_iir for ch in self.ctrl]) + clips = Array([ch.clip for ch in self.ctrl]) # state counter state = Signal(w.channel + 2) @@ -443,8 +445,10 @@ class IIR(Module): en_out.eq(en_outs[channel[0]]), en_iir.eq(en_iirs[channel[0]]), If(stage[1], - ddss[channel[1]][:w.word].eq( - m_coeff.dat_r), + ddss[channel[1]][:w.word].eq(m_coeff.dat_r) + ), + If(stage[2] & en[1] & dsp.clip, + clips[channel[2]].eq(1) ) ], 1: [