forked from M-Labs/artiq
ad9910: profile support
Signed-off-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
parent
d0cadfeb4b
commit
c3178c2cab
|
@ -256,7 +256,7 @@ class AD9910:
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_mu(self, ftw, pow=0, asf=0x3fff, phase_mode=_PHASE_MODE_DEFAULT,
|
def set_mu(self, ftw, pow=0, asf=0x3fff, phase_mode=_PHASE_MODE_DEFAULT,
|
||||||
ref_time=-1):
|
ref_time=-1, profile=0):
|
||||||
"""Set profile 0 data in machine units.
|
"""Set profile 0 data in machine units.
|
||||||
|
|
||||||
This uses machine units (FTW, POW, ASF). The frequency tuning word
|
This uses machine units (FTW, POW, ASF). The frequency tuning word
|
||||||
|
@ -276,6 +276,7 @@ class AD9910:
|
||||||
by :meth:`set_phase_mode` for this call.
|
by :meth:`set_phase_mode` for this call.
|
||||||
:param ref_time: Fiducial time used to compute absolute or tracking
|
:param ref_time: Fiducial time used to compute absolute or tracking
|
||||||
phase updates. In machine units as obtained by `now_mu()`.
|
phase updates. In machine units as obtained by `now_mu()`.
|
||||||
|
:param profile: Profile number to set (0-7, default: 0).
|
||||||
:return: Resulting phase offset word after application of phase
|
:return: Resulting phase offset word after application of phase
|
||||||
tracking offset. When using :const:`PHASE_MODE_CONTINUOUS` in
|
tracking offset. When using :const:`PHASE_MODE_CONTINUOUS` in
|
||||||
subsequent calls, use this value as the "current" phase.
|
subsequent calls, use this value as the "current" phase.
|
||||||
|
@ -297,7 +298,7 @@ class AD9910:
|
||||||
# is equivalent to an output pipeline latency.
|
# is equivalent to an output pipeline latency.
|
||||||
dt = int32(now_mu()) - int32(ref_time)
|
dt = int32(now_mu()) - int32(ref_time)
|
||||||
pow += dt*ftw*self.sysclk_per_mu >> 16
|
pow += dt*ftw*self.sysclk_per_mu >> 16
|
||||||
self.write64(_AD9910_REG_PROFILE0, (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_SYSCLK
|
||||||
at_mu(now_mu() & ~0xf)
|
at_mu(now_mu() & ~0xf)
|
||||||
|
@ -332,7 +333,7 @@ class AD9910:
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set(self, frequency, phase=0.0, amplitude=1.0,
|
def set(self, frequency, phase=0.0, amplitude=1.0,
|
||||||
phase_mode=_PHASE_MODE_DEFAULT, ref_time=-1):
|
phase_mode=_PHASE_MODE_DEFAULT, ref_time=-1, profile=0):
|
||||||
"""Set profile 0 data in SI units.
|
"""Set profile 0 data in SI units.
|
||||||
|
|
||||||
.. seealso:: :meth:`set_mu`
|
.. seealso:: :meth:`set_mu`
|
||||||
|
@ -342,11 +343,12 @@ class AD9910:
|
||||||
:param asf: Amplitude in units of full scale
|
:param asf: Amplitude in units of full scale
|
||||||
:param phase_mode: Phase mode constant
|
:param phase_mode: Phase mode constant
|
||||||
:param ref_time: Fiducial time stamp in machine units
|
:param ref_time: Fiducial time stamp in machine units
|
||||||
|
:param profile: Profile to affect
|
||||||
:return: Resulting phase offset in turns
|
:return: Resulting phase offset in turns
|
||||||
"""
|
"""
|
||||||
return self.pow_to_turns(self.set_mu(
|
return self.pow_to_turns(self.set_mu(
|
||||||
self.frequency_to_ftw(frequency), self.turns_to_pow(phase),
|
self.frequency_to_ftw(frequency), self.turns_to_pow(phase),
|
||||||
self.amplitude_to_asf(amplitude), phase_mode, ref_time))
|
self.amplitude_to_asf(amplitude), phase_mode, ref_time, profile))
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_att_mu(self, att):
|
def set_att_mu(self, att):
|
||||||
|
|
|
@ -134,6 +134,20 @@ class AD9910Exp(EnvExperiment):
|
||||||
sw_off = (self.dev.cpld.sta_read() >> (self.dev.chip_select - 4)) & 1
|
sw_off = (self.dev.cpld.sta_read() >> (self.dev.chip_select - 4)) & 1
|
||||||
self.set_dataset("sw", (sw_on, sw_off))
|
self.set_dataset("sw", (sw_on, sw_off))
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def profile_readback(self):
|
||||||
|
self.core.break_realtime()
|
||||||
|
self.dev.cpld.init()
|
||||||
|
self.dev.init()
|
||||||
|
for i in range(8):
|
||||||
|
self.dev.set_mu(ftw=i, profile=i)
|
||||||
|
ftw = [0] * 8
|
||||||
|
for i in range(8):
|
||||||
|
self.dev.cpld.set_profile(i)
|
||||||
|
ftw[i] = self.dev.read32(_AD9910_REG_FTW)
|
||||||
|
delay(100*us)
|
||||||
|
self.set_dataset("ftw", ftw)
|
||||||
|
|
||||||
|
|
||||||
class AD9910Test(ExperimentCase):
|
class AD9910Test(ExperimentCase):
|
||||||
def test_instantiate(self):
|
def test_instantiate(self):
|
||||||
|
@ -189,3 +203,7 @@ class AD9910Test(ExperimentCase):
|
||||||
def test_sw_readback(self):
|
def test_sw_readback(self):
|
||||||
self.execute(AD9910Exp, "sw_readback")
|
self.execute(AD9910Exp, "sw_readback")
|
||||||
self.assertEqual(self.dataset_mgr.get("sw"), (1, 0))
|
self.assertEqual(self.dataset_mgr.get("sw"), (1, 0))
|
||||||
|
|
||||||
|
def test_profile_readback(self):
|
||||||
|
self.execute(AD9910Exp, "profile_readback")
|
||||||
|
self.assertEqual(self.dataset_mgr.get("ftw"), list(range(8)))
|
||||||
|
|
Loading…
Reference in New Issue