mirror of https://github.com/m-labs/artiq.git
ad9910: fix RTIO fine timestamp nudging
Previously the TSC was truncated to an even coarse RTIO periods before doing the setting SPI xfer. Afterwards the the IO update pulse would introduce at least one but less than two RTIO cycles. Ultimately the RTIO TSC was truncated again to even. If the SPI xfer takes an odd number of RTIO periods, then a subsequent xfer would collide. close #1229 Signed-off-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
parent
51239ebdb6
commit
41a816fd16
|
@ -285,8 +285,9 @@ class AD9910:
|
||||||
"""
|
"""
|
||||||
if phase_mode == _PHASE_MODE_DEFAULT:
|
if phase_mode == _PHASE_MODE_DEFAULT:
|
||||||
phase_mode = self.phase_mode
|
phase_mode = self.phase_mode
|
||||||
# Align to coarse RTIO which aligns SYNC_CLK
|
# Align to coarse RTIO which aligns SYNC_CLK. I.e. clear fine TSC
|
||||||
at_mu(now_mu() & ~0xf)
|
# This will not cause a collision or sequence error.
|
||||||
|
at_mu(now_mu() & ~7)
|
||||||
if phase_mode != PHASE_MODE_CONTINUOUS:
|
if phase_mode != PHASE_MODE_CONTINUOUS:
|
||||||
# Auto-clear phase accumulator on IO_UPDATE.
|
# Auto-clear phase accumulator on IO_UPDATE.
|
||||||
# This is active already for the next IO_UPDATE
|
# This is active already for the next IO_UPDATE
|
||||||
|
@ -302,8 +303,8 @@ class AD9910:
|
||||||
pow += dt*ftw*self.sysclk_per_mu >> 16
|
pow += dt*ftw*self.sysclk_per_mu >> 16
|
||||||
self.write64(_AD9910_REG_PROFILE0 + profile, (asf << 16) | pow, ftw)
|
self.write64(_AD9910_REG_PROFILE0 + profile, (asf << 16) | pow, ftw)
|
||||||
delay_mu(int64(self.io_update_delay))
|
delay_mu(int64(self.io_update_delay))
|
||||||
self.cpld.io_update.pulse_mu(8) # assumes 8 mu > t_SYSCLK
|
self.cpld.io_update.pulse_mu(8) # assumes 8 mu > t_SYN_CCLK
|
||||||
at_mu(now_mu() & ~0xf)
|
at_mu(now_mu() & ~7) # clear fine TSC again
|
||||||
if phase_mode != PHASE_MODE_CONTINUOUS:
|
if phase_mode != PHASE_MODE_CONTINUOUS:
|
||||||
self.write32(_AD9910_REG_CFR1, 0x00000002)
|
self.write32(_AD9910_REG_CFR1, 0x00000002)
|
||||||
# future IO_UPDATE will activate
|
# future IO_UPDATE will activate
|
||||||
|
@ -496,16 +497,17 @@ class AD9910:
|
||||||
self.write32(_AD9910_REG_RAMP_RATE, 0x00010000)
|
self.write32(_AD9910_REG_RAMP_RATE, 0x00010000)
|
||||||
# dFTW = 1, (work around negative slope)
|
# dFTW = 1, (work around negative slope)
|
||||||
self.write64(_AD9910_REG_RAMP_STEP, -1, 0)
|
self.write64(_AD9910_REG_RAMP_STEP, -1, 0)
|
||||||
# delay io_update after RTIO/2 edge
|
# delay io_update after RTIO edge
|
||||||
t = now_mu() + 0x10 & ~0xf
|
t = now_mu() + 8 & ~7
|
||||||
at_mu(t + delay_start)
|
at_mu(t + delay_start)
|
||||||
self.cpld.io_update.pulse_mu(32 - delay_start) # realign
|
# assumes a maximum t_SYNC_CLK period
|
||||||
|
self.cpld.io_update.pulse_mu(16 - delay_start) # realign
|
||||||
# disable DRG autoclear and LRR on io_update
|
# disable DRG autoclear and LRR on io_update
|
||||||
self.write32(_AD9910_REG_CFR1, 0x00000002)
|
self.write32(_AD9910_REG_CFR1, 0x00000002)
|
||||||
# stop DRG
|
# stop DRG
|
||||||
self.write64(_AD9910_REG_RAMP_STEP, 0, 0)
|
self.write64(_AD9910_REG_RAMP_STEP, 0, 0)
|
||||||
at_mu(t + 0x1000 + delay_stop)
|
at_mu(t + 0x1000 + delay_stop)
|
||||||
self.cpld.io_update.pulse_mu(32 - delay_stop) # realign
|
self.cpld.io_update.pulse_mu(16 - delay_stop) # realign
|
||||||
ftw = self.read32(_AD9910_REG_FTW) # read out effective FTW
|
ftw = self.read32(_AD9910_REG_FTW) # read out effective FTW
|
||||||
delay(100*us) # slack
|
delay(100*us) # slack
|
||||||
# disable DRG
|
# disable DRG
|
||||||
|
|
Loading…
Reference in New Issue