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:
Robert Jördens 2019-01-09 17:08:11 +00:00
parent 51239ebdb6
commit 41a816fd16

View File

@ -285,8 +285,9 @@ class AD9910:
"""
if phase_mode == _PHASE_MODE_DEFAULT:
phase_mode = self.phase_mode
# Align to coarse RTIO which aligns SYNC_CLK
at_mu(now_mu() & ~0xf)
# Align to coarse RTIO which aligns SYNC_CLK. I.e. clear fine TSC
# This will not cause a collision or sequence error.
at_mu(now_mu() & ~7)
if phase_mode != PHASE_MODE_CONTINUOUS:
# Auto-clear phase accumulator on 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
self.write64(_AD9910_REG_PROFILE0 + profile, (asf << 16) | pow, ftw)
delay_mu(int64(self.io_update_delay))
self.cpld.io_update.pulse_mu(8) # assumes 8 mu > t_SYSCLK
at_mu(now_mu() & ~0xf)
self.cpld.io_update.pulse_mu(8) # assumes 8 mu > t_SYN_CCLK
at_mu(now_mu() & ~7) # clear fine TSC again
if phase_mode != PHASE_MODE_CONTINUOUS:
self.write32(_AD9910_REG_CFR1, 0x00000002)
# future IO_UPDATE will activate
@ -496,16 +497,17 @@ class AD9910:
self.write32(_AD9910_REG_RAMP_RATE, 0x00010000)
# dFTW = 1, (work around negative slope)
self.write64(_AD9910_REG_RAMP_STEP, -1, 0)
# delay io_update after RTIO/2 edge
t = now_mu() + 0x10 & ~0xf
# delay io_update after RTIO edge
t = now_mu() + 8 & ~7
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
self.write32(_AD9910_REG_CFR1, 0x00000002)
# stop DRG
self.write64(_AD9910_REG_RAMP_STEP, 0, 0)
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
delay(100*us) # slack
# disable DRG