From aee896589777f7327c9ce51d09fed06e50519c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Thu, 21 Feb 2019 15:59:52 +0000 Subject: [PATCH] ad9910: add ram conversion tooling and unittests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Robert Jördens --- artiq/coredevice/ad9910.py | 58 ++++++++++++++++++++++++++- artiq/test/coredevice/test_ad9910.py | 59 +++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 4 deletions(-) diff --git a/artiq/coredevice/ad9910.py b/artiq/coredevice/ad9910.py index 29ee86460..8da06b275 100644 --- a/artiq/coredevice/ad9910.py +++ b/artiq/coredevice/ad9910.py @@ -310,8 +310,8 @@ class AD9910: :param drg_autoclear: Autoclear digital ramp generator. :param internal_profile: Internal profile control. :param ram_destination: RAM destination - (:const:`_AD9910_RAM_DEST_FTW`, :const:`_AD9910_RAM_DEST_POW`, - :const:`_AD9910_RAM_DEST_ASF`, :const:`_AD9910_RAM_DEST_POWASF`). + (:const:`RAM_DEST_FTW`, :const:`RAM_DEST_POW`, + :const:`RAM_DEST_ASF`, :const:`RAM_DEST_POWASF`). :param ram_enable: RAM mode enable. """ self.write32(_AD9910_REG_CFR1, @@ -516,6 +516,60 @@ class AD9910: amplitude scale factor.""" return asf / float(0x3ffe) + @portable(flags={"fast-math"}) + def frequency_to_ram(self, frequency, ram): + """Convert frequency values to RAM profile data. + + To be used with :const:`RAM_DEST_FTW`. + + :param frequency: List of frequency values in Hz. + :param ram: List to write RAM data into. + Suitable for :meth:`write_ram`. + """ + for i in range(len(ram)): + ram[i] = self.frequency_to_ftw(frequency[i]) + + @portable(flags={"fast-math"}) + def turns_to_ram(self, turns, ram): + """Convert phase values to RAM profile data. + + To be used with :const:`RAM_DEST_POW`. + + :param turns: List of phase values in turns. + :param ram: List to write RAM data into. + Suitable for :meth:`write_ram`. + """ + for i in range(len(ram)): + ram[i] = self.turns_to_pow(turns[i]) << 16 + + @portable(flags={"fast-math"}) + def amplitude_to_ram(self, amplitude, ram): + """Convert amplitude values to RAM profile data. + + To be used with :const:`RAM_DEST_ASF`. + + :param amplitude: List of amplitude values in units of full scale. + :param ram: List to write RAM data into. + Suitable for :meth:`write_ram`. + """ + for i in range(len(ram)): + ram[i] = self.amplitude_to_asf(amplitude[i]) << 16 + + @portable(flags={"fast-math"}) + def turns_amplitude_to_ram(self, turns, amplitude, ram): + """Convert phase and amplitude values to RAM profile data. + + To be used with :const:`RAM_DEST_POWASF`. + + :param turns: List of phase values in turns. + :param amplitude: List of amplitude values in units of full scale. + :param ram: List to write RAM data into. + Suitable for :meth:`write_ram`. + """ + for i in range(len(ram)): + ram[i] = ((self.turns_to_pow(turns[i]) << 16) | + self.amplitude_to_asf(amplitude[i])) + @kernel def set_frequency(self, frequency): return self.set_ftw(self.frequency_to_ftw(frequency)) diff --git a/artiq/test/coredevice/test_ad9910.py b/artiq/test/coredevice/test_ad9910.py index 417ac9c25..4af554784 100644 --- a/artiq/test/coredevice/test_ad9910.py +++ b/artiq/test/coredevice/test_ad9910.py @@ -231,8 +231,8 @@ class AD9910Exp(EnvExperiment): @kernel def ram_exec(self): - ftw0 = [0x12345678]*10 - ftw1 = [0x55aaaa55]*10 + ftw0 = [0x12345678]*2 + ftw1 = [0x55aaaa55]*2 self.core.break_realtime() self.dev.cpld.init() self.dev.init() @@ -268,6 +268,40 @@ class AD9910Exp(EnvExperiment): self.set_dataset("ftw", [ftw0[0], ftw0r, ftw1[0], ftw1r]) + @kernel + def ram_convert_frequency(self): + freq = [33*MHz]*2 + ram = [0]*len(freq) + self.dev.frequency_to_ram(freq, ram) + + self.core.break_realtime() + self.dev.cpld.init() + self.dev.init() + self.dev.set_cfr1(ram_enable=0) + self.dev.cpld.io_update.pulse_mu(8) + self.dev.set_profile_ram( + start=100, end=100 + len(ram) - 1, step=1, + profile=6, mode=RAM_MODE_RAMPUP) + self.dev.cpld.set_profile(6) + self.dev.cpld.io_update.pulse_mu(8) + self.dev.write_ram(ram) + self.dev.set_cfr1(ram_enable=1, ram_destination=RAM_DEST_FTW) + self.dev.cpld.io_update.pulse_mu(8) + ftw_read = self.dev.read32(_AD9910_REG_FTW) + self.set_dataset("ram", ram) + self.set_dataset("ftw_read", ftw_read) + self.set_dataset("freq", freq) + + @kernel + def ram_convert_powasf(self): + amplitude = [.1, .9] + turns = [.3, .5] + ram = [0]*2 + self.dev.turns_amplitude_to_ram(turns, amplitude, ram) + self.set_dataset("amplitude", amplitude) + self.set_dataset("turns", turns) + self.set_dataset("ram", ram) + class AD9910Test(ExperimentCase): def test_instantiate(self): @@ -353,3 +387,24 @@ class AD9910Test(ExperimentCase): ftw = self.dataset_mgr.get("ftw") self.assertEqual(ftw[0], ftw[1]) self.assertEqual(ftw[2], ftw[3]) + + def test_ram_convert_frequency(self): + exp = self.execute(AD9910Exp, "ram_convert_frequency") + ram = self.dataset_mgr.get("ram") + ftw_read = self.dataset_mgr.get("ftw_read") + self.assertEqual(ftw_read, ram[0]) + freq = self.dataset_mgr.get("freq") + self.assertEqual(ftw_read, exp.dev.frequency_to_ftw(freq[0])) + self.assertAlmostEqual(freq[0], exp.dev.ftw_to_frequency(ftw_read), + delta=.25) + + def test_ram_convert_powasf(self): + exp = self.execute(AD9910Exp, "ram_convert_powasf") + ram = self.dataset_mgr.get("ram") + amplitude = self.dataset_mgr.get("amplitude") + turns = self.dataset_mgr.get("turns") + for i in range(len(ram)): + self.assertEqual((ram[i] >> 16) & 0xffff, + exp.dev.turns_to_pow(turns[i])) + self.assertEqual(ram[i] & 0xffff, + exp.dev.amplitude_to_asf(amplitude[i]))