From 3844123c1381ef293f278a6f90ec2874f9fa1b39 Mon Sep 17 00:00:00 2001 From: Etienne Wodey Date: Mon, 9 Nov 2020 19:19:16 +0100 Subject: [PATCH] coredevice: adf5356: add enable/disable and power setting for outA Signed-off-by: Etienne Wodey --- artiq/coredevice/adf5356.py | 37 ++++++++++++++++++++ artiq/test/coredevice/test_adf5356.py | 50 +++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/artiq/coredevice/adf5356.py b/artiq/coredevice/adf5356.py index 19ed29a60..2c4da1751 100644 --- a/artiq/coredevice/adf5356.py +++ b/artiq/coredevice/adf5356.py @@ -116,6 +116,43 @@ class ADF5356: def read_muxout(self): return bool(self.cpld.read_reg(0) & (1 << (self.channel + 8))) + @kernel + def set_output_power_mu(self, n): + """ + Set the power level at output A of the PLL chip in machine units. + + This driver defaults to `n = 3` at init. + + :param n: output power setting, 0, 1, 2, or 3 (see ADF5356 datasheet, fig. 44). + """ + if n not in [0, 1, 2, 3]: + raise ValueError("invalid power setting") + self.regs[6] = ADF5356_REG6_RF_OUTPUT_A_POWER_UPDATE(self.regs[6], n) + self.sync() + + @portable + def output_power_mu(self): + """ + Return the power level at output A of the PLL chip in machine units. + """ + return ADF5356_REG6_RF_OUTPUT_A_POWER_GET(self.regs[6]) + + @kernel + def enable_output(self): + """ + Enable output A of the PLL chip. This is the default after init. + """ + self.regs[6] |= ADF5356_REG6_RF_OUTPUT_A_ENABLE(1) + self.sync() + + @kernel + def disable_output(self): + """ + Disable output A of the PLL chip. + """ + self.regs[6] &= ~ADF5356_REG6_RF_OUTPUT_A_ENABLE(1) + self.sync() + @kernel def set_frequency(self, f): """ diff --git a/artiq/test/coredevice/test_adf5356.py b/artiq/test/coredevice/test_adf5356.py index 61637dbb8..56f8c95a9 100644 --- a/artiq/test/coredevice/test_adf5356.py +++ b/artiq/test/coredevice/test_adf5356.py @@ -1,4 +1,6 @@ import unittest +import numpy as np + from artiq.experiment import * from artiq.test.hardware_testbench import ExperimentCase from artiq.coredevice.adf5356 import ( @@ -29,7 +31,7 @@ class ADF5356Exp(EnvExperiment): self.dev.init() @kernel - def set_get_simple(self): + def set_get_freq(self): self.core.break_realtime() self.dev.cpld.init() self.dev.init() @@ -60,6 +62,35 @@ class ADF5356Exp(EnvExperiment): delay(5 * ms) self.set_dataset("muxout", self.dev.read_muxout()) + @kernel + def set_get_output_power(self): + self.core.break_realtime() + self.dev.cpld.init() + self.dev.init() + self.dev.set_att_mu(0) + self.dev.set_frequency(100 * MHz) + self.set_dataset("get_power", np.full(4, np.nan)) + for n in range(4): + delay(10 * ms) + self.dev.set_output_power_mu(n) + m = self.dev.output_power_mu() + self.mutate_dataset("get_power", n, m) + + @kernel + def invalid_output_power_setting(self): + self.dev.set_output_power_mu(42) + + @kernel + def enable_disable_output(self): + self.core.break_realtime() + self.dev.cpld.init() + self.dev.init() + self.dev.set_att_mu(0) + self.dev.set_frequency(100 * MHz) + self.dev.disable_output() + delay(100 * us) + self.dev.enable_output() + class TestCalculateParameters(unittest.TestCase): def setUp(self): @@ -126,8 +157,8 @@ class ADF5356Test(ExperimentCase): def test_init(self): self.execute(ADF5356Exp, "init") - def test_set_get_simple(self): - self.execute(ADF5356Exp, "set_get_simple") + def test_set_get_freq(self): + self.execute(ADF5356Exp, "set_get_freq") f_set = self.dataset_mgr.get("freq_set") f_get = self.dataset_mgr.get("freq_get") self.assertEqual(f_set, f_get) @@ -144,3 +175,16 @@ class ADF5356Test(ExperimentCase): def test_set_too_low_frequency(self): with self.assertRaises(ValueError): self.execute(ADF5356Exp, "set_too_low_frequency") + + def test_set_get_output_power(self): + self.execute(ADF5356Exp, "set_get_output_power") + get_power = self.dataset_mgr.get("get_power") + for n in range(4): + self.assertEqual(n, get_power[n]) + + def test_invalid_output_power_setting(self): + with self.assertRaises(ValueError): + self.execute(ADF5356Exp, "invalid_output_power_setting") + + def test_enable_disable_output(self): + self.execute(ADF5356Exp, "enable_disable_output")