From ac73654079ad1d5547910f81c0cbe4bb6bccd7c7 Mon Sep 17 00:00:00 2001 From: Trisha De Vera Date: Tue, 19 Nov 2024 11:10:01 +0800 Subject: [PATCH] Add adrv9008-1/2 support Signed-off-by: Trisha De Vera --- adi/__init__.py | 2 +- adi/adrv9009.py | 365 +++++++++++++++++++++++++++++++- examples/adrv9008_1.py | 33 +++ examples/adrv9008_2.py | 31 +++ supported_parts.md | 3 +- test/emu/devices/adrv9008-1.xml | 1 + test/emu/devices/adrv9008-2.xml | 1 + test/emu/hardware_map.yml | 22 ++ test/test_adrv9008_1.py | 142 +++++++++++++ test/test_adrv9008_2.py | 169 +++++++++++++++ 10 files changed, 766 insertions(+), 3 deletions(-) create mode 100644 examples/adrv9008_1.py create mode 100644 examples/adrv9008_2.py create mode 100644 test/emu/devices/adrv9008-1.xml create mode 100644 test/emu/devices/adrv9008-2.xml create mode 100644 test/test_adrv9008_1.py create mode 100644 test/test_adrv9008_2.py diff --git a/adi/__init__.py b/adi/__init__.py index 8b36a295a..ce619455b 100644 --- a/adi/__init__.py +++ b/adi/__init__.py @@ -82,7 +82,7 @@ from adi.adpd1080 import adpd1080 from adi.adrf5720 import adrf5720 from adi.adrv9002 import adrv9002 -from adi.adrv9009 import adrv9009 +from adi.adrv9009 import adrv9008_1, adrv9008_2, adrv9009 from adi.adrv9009_zu11eg import adrv9009_zu11eg from adi.adrv9009_zu11eg_fmcomms8 import adrv9009_zu11eg_fmcomms8 from adi.adrv9009_zu11eg_multi import adrv9009_zu11eg_multi diff --git a/adi/adrv9009.py b/adi/adrv9009.py index 7744ee7ce..dfd038514 100644 --- a/adi/adrv9009.py +++ b/adi/adrv9009.py @@ -5,7 +5,7 @@ from adi.context_manager import context_manager from adi.jesd import jesd as jesdadi from adi.obs import obs -from adi.rx_tx import rx_tx +from adi.rx_tx import rx, rx_tx, tx from adi.sync_start import sync_start @@ -356,3 +356,366 @@ def jesd204_fsm_paused(self): def jesd204_fsm_error(self): """jesd204_fsm_error: jesd204-fsm error""" return self._get_iio_dev_attr("jesd204_fsm_error") + + +class adrv9008_1(rx, context_manager, sync_start): + """ADRV9008-1 Receiver""" + + def __init__(self, uri="", jesd_monitor=False, jesd=None): + self.adrv9009 = adrv9009(uri, jesd_monitor, jesd) + + self._rx_channel_names = self.adrv9009._rx_channel_names + self._device_name = self.adrv9009._device_name + self._ctrl = self.adrv9009._ctx.find_device("adrv9009-phy") + self._rxadc = self.adrv9009._ctx.find_device("axi-adrv9009-rx-hpc") + self.adrv9009._ctx.set_timeout(30000) # Needed for loading profiles + if jesdadi and jesd_monitor: + self._jesd = jesd if jesd else jesdadi(uri=uri) + rx.__init__(self) + + @property + def ensm_mode(self): + """ensm_mode: Enable State Machine State Allows real time control over + the current state of the device. Options are: radio_on, radio_off""" + return self.adrv9009.ensm_mode + + @ensm_mode.setter + def ensm_mode(self, value): + self.adrv9009.ensm_mode = value + + @property + def profile(self): + """Load profile file. Provide path to profile file to attribute""" + return self.adrv9009.profile + + @profile.setter + def profile(self, value): + self.adrv9009.profile = value + + @property + def frequency_hopping_mode(self): + """frequency_hopping_mode: Set Frequency Hopping Mode""" + return self._get_iio_attr("RX_LO", "frequency_hopping_mode", True) + + @frequency_hopping_mode.setter + def frequency_hopping_mode(self, value): + self._set_iio_attr("RX_LO", "frequency_hopping_mode", True, value) + + @property + def frequency_hopping_mode_en(self): + """frequency_hopping_mode_en: Enable Frequency Hopping Mode""" + return self._get_iio_attr("RX_LO", "frequency_hopping_mode_enable", True) + + @frequency_hopping_mode_en.setter + def frequency_hopping_mode_en(self, value): + self._set_iio_attr("RX_LO", "frequency_hopping_mode_enable", True, value) + + @property + def calibrate_rx_phase_correction_en(self): + """calibrate_rx_phase_correction_en: Enable RX Phase Correction Calibration""" + return self.adrv9009.calibrate_rx_phase_correction_en + + @calibrate_rx_phase_correction_en.setter + def calibrate_rx_phase_correction_en(self, value): + self.adrv9009.calibrate_rx_phase_correction_en = value + + @property + def calibrate_rx_qec_en(self): + """calibrate_rx_qec_en: Enable RX QEC Calibration""" + return self.adrv9009.calibrate_rx_qec_en + + @calibrate_rx_qec_en.setter + def calibrate_rx_qec_en(self, value): + self.adrv9009.calibrate_rx_qec_en = value + + @property + def calibrate(self): + """calibrate: Trigger Calibration""" + return self.adrv9009.calibrate + + @calibrate.setter + def calibrate(self, value): + self.adrv9009.calibrate = value + + @property + def gain_control_mode_chan0(self): + """gain_control_mode_chan0: Mode of receive path AGC. Options are: + slow_attack, manual""" + return self.adrv9009.gain_control_mode_chan0 + + @gain_control_mode_chan0.setter + def gain_control_mode_chan0(self, value): + self.adrv9009.gain_control_mode_chan0 = value + + @property + def gain_control_mode_chan1(self): + """gain_control_mode_chan1: Mode of receive path AGC. Options are: + slow_attack, manual""" + return self.adrv9009.gain_control_mode_chan1 + + @gain_control_mode_chan1.setter + def gain_control_mode_chan1(self, value): + self.adrv9009.gain_control_mode_chan1 = value + + @property + def rx_quadrature_tracking_en_chan0(self): + """Enable Quadrature tracking calibration for RX1""" + return self.adrv9009.rx_quadrature_tracking_en_chan0 + + @rx_quadrature_tracking_en_chan0.setter + def rx_quadrature_tracking_en_chan0(self, value): + self.adrv9009.rx_quadrature_tracking_en_chan0 = value + + @property + def rx_quadrature_tracking_en_chan1(self): + """Enable Quadrature tracking calibration for RX2""" + return self.adrv9009.rx_quadrature_tracking_en_chan1 + + @rx_quadrature_tracking_en_chan1.setter + def rx_quadrature_tracking_en_chan1(self, value): + self.adrv9009.rx_quadrature_tracking_en_chan1 = value + + @property + def rx_powerdown_en_chan0(self): + """rx_powerdown_en_chan0: Enables/disables the RX1 signal paths + while in the ENSM radio_on state""" + return self.adrv9009.rx_powerdown_en_chan0 + + @rx_powerdown_en_chan0.setter + def rx_powerdown_en_chan0(self, value): + self.adrv9009.rx_powerdown_en_chan0 = value + + @property + def rx_powerdown_en_chan1(self): + """rx_powerdown_en_chan1: Enables/disables the RX2 signal paths + while in the ENSM radio_on state""" + return self.adrv9009.rx_powerdown_en_chan1 + + @rx_powerdown_en_chan1.setter + def rx_powerdown_en_chan1(self, value): + self.adrv9009.rx_powerdown_en_chan1 = value + + @property + def rx_hardwaregain_chan0(self): + """rx_hardwaregain: Gain applied to RX path channel 0. Only applicable when + gain_control_mode is set to 'manual'""" + return self.adrv9009.rx_hardwaregain_chan0 + + @rx_hardwaregain_chan0.setter + def rx_hardwaregain_chan0(self, value): + if self.adrv9009.gain_control_mode_chan0 == "manual": + self.adrv9009.rx_hardwaregain_chan0 = value + + @property + def rx_hardwaregain_chan1(self): + """rx_hardwaregain: Gain applied to RX path channel 1. Only applicable when + gain_control_mode is set to 'manual'""" + return self.adrv9009.rx_hardwaregain_chan1 + + @rx_hardwaregain_chan1.setter + def rx_hardwaregain_chan1(self, value): + if self.adrv9009.gain_control_mode_chan1 == "manual": + self.adrv9009.rx_hardwaregain_chan1 = value + + @property + def rx_rf_bandwidth(self): + """rx_rf_bandwidth: Bandwidth of front-end analog filter of RX path""" + return self.adrv9009.rx_rf_bandwidth + + @property + def rx_sample_rate(self): + """rx_sample_rate: Sample rate RX path in samples per second""" + return self.adrv9009.rx_sample_rate + + @property + def trx_lo(self): + """trx_lo: Carrier frequency of TX and RX path""" + return self.adrv9009.trx_lo + + @trx_lo.setter + def trx_lo(self, value): + self.adrv9009.trx_lo = value + + +class adrv9008_2(tx, context_manager, sync_start): + """ADRV9008-2 Transmitter""" + + def __init__(self, uri="", jesd_monitor=False, jesd=None): + self.adrv9009 = adrv9009(uri, jesd_monitor, jesd) + + self._tx_channel_names = self.adrv9009._tx_channel_names + self._device_name = self.adrv9009._device_name + self._ctrl = self.adrv9009._ctx.find_device("adrv9009-phy") + self._txdac = self.adrv9009._ctx.find_device("axi-adrv9009-tx-hpc") + self.adrv9009._ctx.set_timeout(30000) # Needed for loading profiles + if jesdadi and jesd_monitor: + self._jesd = jesd if jesd else jesdadi(uri=uri) + tx.__init__(self) + + @property + def ensm_mode(self): + """ensm_mode: Enable State Machine State Allows real time control over + the current state of the device. Options are: radio_on, radio_off""" + return self.adrv9009.ensm_mode + + @ensm_mode.setter + def ensm_mode(self, value): + self.adrv9009.ensm_mode = value + + @property + def profile(self): + """Load profile file. Provide path to profile file to attribute""" + return self.adrv9009.profile + + @profile.setter + def profile(self, value): + self.adrv9009.profile = value + + @property + def frequency_hopping_mode(self): + """frequency_hopping_mode: Set Frequency Hopping Mode""" + return self._get_iio_attr("TX_LO", "frequency_hopping_mode", True) + + @frequency_hopping_mode.setter + def frequency_hopping_mode(self, value): + self._set_iio_attr("TX_LO", "frequency_hopping_mode", True, value) + + @property + def frequency_hopping_mode_en(self): + """frequency_hopping_mode_en: Enable Frequency Hopping Mode""" + return self._get_iio_attr("TX_LO", "frequency_hopping_mode_enable", True) + + @frequency_hopping_mode_en.setter + def frequency_hopping_mode_en(self, value): + self._set_iio_attr("TX_LO", "frequency_hopping_mode_enable", True, value) + + @property + def calibrate_tx_qec_en(self): + """calibrate_tx_qec_en: Enable TX QEC Calibration""" + return self.adrv9009.calibrate_tx_qec_en + + @calibrate_tx_qec_en.setter + def calibrate_tx_qec_en(self, value): + self.adrv9009.calibrate_tx_qec_en = value + + @property + def calibrate(self): + """calibrate: Trigger Calibration""" + return self.adrv9009.calibrate + + @calibrate.setter + def calibrate(self, value): + self.adrv9009.calibrate = value + + @property + def tx_quadrature_tracking_en_chan0(self): + """Enable Quadrature tracking calibration for TX1""" + return self.adrv9009.tx_quadrature_tracking_en_chan0 + + @tx_quadrature_tracking_en_chan0.setter + def tx_quadrature_tracking_en_chan0(self, value): + self.adrv9009.tx_quadrature_tracking_en_chan0 = value + + @property + def tx_quadrature_tracking_en_chan1(self): + """Enable Quadrature tracking calibration for TX2""" + return self.adrv9009.tx_quadrature_tracking_en_chan1 + + @tx_quadrature_tracking_en_chan1.setter + def tx_quadrature_tracking_en_chan1(self, value): + self.adrv9009.tx_quadrature_tracking_en_chan1 = value + + @property + def tx_hardwaregain_chan0(self): + """tx_hardwaregain: Attenuation applied to TX path channel 0""" + return self.adrv9009.tx_hardwaregain_chan0 + + @tx_hardwaregain_chan0.setter + def tx_hardwaregain_chan0(self, value): + self.adrv9009.tx_hardwaregain_chan0 = value + + @property + def tx_hardwaregain_chan1(self): + """tx_hardwaregain: Attenuation applied to TX path channel 1""" + return self.adrv9009.tx_hardwaregain_chan1 + + @tx_hardwaregain_chan1.setter + def tx_hardwaregain_chan1(self, value): + self.adrv9009.tx_hardwaregain_chan1 = value + + @property + def tx_rf_bandwidth(self): + """tx_rf_bandwidth: Bandwidth of front-end analog filter of TX path""" + return self.adrv9009.tx_rf_bandwidth + + @property + def tx_sample_rate(self): + """tx_sample_rate: Sample rate TX path in samples per second""" + return self.adrv9009.tx_sample_rate + + @property + def trx_lo(self): + """trx_lo: Carrier frequency of TX and RX path""" + return self.adrv9009.trx_lo + + @trx_lo.setter + def trx_lo(self, value): + self.adrv9009.trx_lo = value + + @property + def obs_powerdown_en(self): + """obs_powerdown_en: Enables/disables the ORX signal paths + while in the ENSM radio_on state""" + return self.adrv9009.obs_powerdown_en + + @obs_powerdown_en.setter + def obs_powerdown_en(self, value): + self.adrv9009.obs_powerdown_en = value + + @property + def aux_obs_lo(self): + """aux_obs_lo: Carrier frequency of ORx path""" + return self.adrv9009.aux_obs_lo + + @aux_obs_lo.setter + def aux_obs_lo(self, value): + self.adrv9009.aux_obs_lo = value + + @property + def obs_quadrature_tracking_en(self): + """Enable Quadrature tracking calibration for ORX""" + return self.adrv9009.obs_quadrature_tracking_en + + @obs_quadrature_tracking_en.setter + def obs_quadrature_tracking_en(self, value): + self.adrv9009.obs_quadrature_tracking_en = value + + @property + def obs_rf_port_select(self): + """obs_rf_port_select: Observation path source for ORX. Options are: + + - OBS_TX_LO - + - OBS_AUX_LO - + + """ + return self.adrv9009.obs_rf_port_select + + @obs_rf_port_select.setter + def obs_rf_port_select(self, value): + self.adrv9009.obs_rf_port_select = value + + @property + def obs_hardwaregain(self): + """obs_hardwaregain: Gain applied to Obs/Sniffer receive path ORX1.""" + return self.adrv9009.obs_hardwaregain + + @obs_hardwaregain.setter + def obs_hardwaregain(self, value): + self.adrv9009.obs_hardwaregain = value + + @property + def orx_sample_rate(self): + """orx_sample_rate: Sample rate ORX path in samples per second + This value will reflect the correct value when 8x decimator is enabled + """ + return self.adrv9009.orx_sample_rate diff --git a/examples/adrv9008_1.py b/examples/adrv9008_1.py new file mode 100644 index 000000000..3e4aa3d08 --- /dev/null +++ b/examples/adrv9008_1.py @@ -0,0 +1,33 @@ +# Copyright (C) 2019-2025 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD + +import adi + +sdr = adi.adrv9008_1(uri="ip:localhost") + +sdr.ensm_mode = "radio_on" +print("ensm_mode: " + sdr.ensm_mode) +sdr.rx_powerdown_en_chan0 = 0 +print("rx_powerdown_chan0: " + str(sdr.rx_powerdown_en_chan0)) +sdr.rx_powerdown_en_chan1 = 0 +print("rx_powerdown_chan1: " + str(sdr.rx_powerdown_en_chan1)) +sdr.gain_control_mode_chan0 = "slow_attack" +print("gain_control_mode_chan0: " + sdr.gain_control_mode_chan0) +sdr.gain_control_mode_chan0 = "manual" +print("gain_control_mode_chan0: " + sdr.gain_control_mode_chan0) +sdr.gain_control_mode_chan1 = "slow_attack" +print("gain_control_mode_chan1: " + sdr.gain_control_mode_chan1) +sdr.gain_control_mode_chan0 = "manual" +print("gain_control_mode_chan1: " + sdr.gain_control_mode_chan1) +print("rx_hardwaregain_chan0: " + str(sdr.rx_hardwaregain_chan0)) +sdr.rx_hardwaregain_chan0 = -20 +print("rx_hardwaregain_chan0: " + str(sdr.rx_hardwaregain_chan0)) +print("rx_hardwaregain_chan1: " + str(sdr.rx_hardwaregain_chan1)) +sdr.rx_hardwaregain_chan1 = -20 +print("rx_hardwaregain_chan1: " + str(sdr.rx_hardwaregain_chan1)) +print("rx_rf_bandwidth: " + str(sdr.rx_rf_bandwidth)) +print("rx_sample_rate: " + str(sdr.rx_sample_rate)) +print("trx_lo: " + str(sdr.trx_lo)) +sdr.trx_lo = 6000000000 +print("trx_lo: " + str(sdr.trx_lo)) diff --git a/examples/adrv9008_2.py b/examples/adrv9008_2.py new file mode 100644 index 000000000..82da492ed --- /dev/null +++ b/examples/adrv9008_2.py @@ -0,0 +1,31 @@ +# Copyright (C) 2019-2025 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD + +import adi + +sdr = adi.adrv9008_2(uri="ip:localhost") + +sdr.ensm_mode = "radio_on" +print("ensm_mode: " + sdr.ensm_mode) +print("tx_hardwaregain_chan0: " + str(sdr.tx_hardwaregain_chan0)) +sdr.tx_hardwaregain_chan0 = -20 +print("tx_hardwaregain_chan0: " + str(sdr.tx_hardwaregain_chan0)) +print("tx_hardwaregain_chan1: " + str(sdr.tx_hardwaregain_chan1)) +sdr.tx_hardwaregain_chan1 = -20 +print("tx_hardwaregain_chan1: " + str(sdr.tx_hardwaregain_chan1)) +print("tx_rf_bandwidth: " + str(sdr.tx_rf_bandwidth)) +print("tx_sample_rate: " + str(sdr.tx_sample_rate)) +print("trx_lo: " + str(sdr.trx_lo)) +sdr.trx_lo = 6000000000 +print("trx_lo: " + str(sdr.trx_lo)) +print("aux_obs_lo: " + str(sdr.aux_obs_lo)) +sdr.aux_obs_lo = 2500000000 +print("aux_obs_lo: " + str(sdr.aux_obs_lo)) +print("obs_powerdown_en: " + str(sdr.obs_powerdown_en)) +sdr.obs_powerdown_en = 0 +print("obs_powerdown_en: " + str(sdr.obs_powerdown_en)) +print("obs_hardwaregain: " + str(sdr.obs_hardwaregain)) +sdr.obs_hardwaregain = 3.5 +print("obs_hardwaregain: " + str(sdr.obs_hardwaregain)) +print("orx_sample_rate: " + str(sdr.orx_sample_rate)) diff --git a/supported_parts.md b/supported_parts.md index 14a8abce8..890868815 100644 --- a/supported_parts.md +++ b/supported_parts.md @@ -152,7 +152,8 @@ - ADPD410x - ADRF5720 - ADRV9002 -- ADRV9008-1/2 +- ADRV9008-1 +- ADRV9008-2 - ADRV9009 - ADRV9009-ZU11EG - ADT7420 diff --git a/test/emu/devices/adrv9008-1.xml b/test/emu/devices/adrv9008-1.xml new file mode 100644 index 000000000..41cf9fe74 --- /dev/null +++ b/test/emu/devices/adrv9008-1.xml @@ -0,0 +1 @@ +]> \ No newline at end of file diff --git a/test/emu/devices/adrv9008-2.xml b/test/emu/devices/adrv9008-2.xml new file mode 100644 index 000000000..a18aed032 --- /dev/null +++ b/test/emu/devices/adrv9008-2.xml @@ -0,0 +1 @@ +]> \ No newline at end of file diff --git a/test/emu/hardware_map.yml b/test/emu/hardware_map.yml index e4b0a5b3a..2e48e7e5f 100644 --- a/test/emu/hardware_map.yml +++ b/test/emu/hardware_map.yml @@ -318,6 +318,28 @@ adrv9009-dual: - adrv9009-phy-b - pyadi_iio_class_support: - adrv9009_zu11eg +adrv9008-1: + - adrv9009-phy + - axi-adrv9009-rx-hpc + - pyadi_iio_class_support: + - adrv9008_1 + - emulate: + - filename: adrv9008-1.xml + - data_devices: + - iio:device3 + - iio:device4 +adrv9008-2: + - adrv9009-phy + - axi-adrv9009-tx-hpc + - axi-adrv9009-rx-obs-hpc + - pyadi_iio_class_support: + - adrv9008_2 + - emulate: + - filename: adrv9008-2.xml + - data_devices: + - iio:device3 + - iio:device4 + - iio:device5 adrv9371: - ad9371-phy - emulate: diff --git a/test/test_adrv9008_1.py b/test/test_adrv9008_1.py new file mode 100644 index 000000000..95c28feb5 --- /dev/null +++ b/test/test_adrv9008_1.py @@ -0,0 +1,142 @@ +from os import listdir +from os.path import dirname, join, realpath + +import pytest + +hardware = "adrv9008-1" +classname = "adi.adrv9008_1" + +profile_path = dirname(realpath(__file__)) + "/adrv9009_profiles/" +test_profiles = [join(profile_path, f) for f in listdir(profile_path)] + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, value", + [ + ("ensm_mode", "radio_off"), + ("ensm_mode", "radio_on"), + ("calibrate_rx_phase_correction_en", 1), + ("calibrate_rx_phase_correction_en", 0), + ("calibrate_rx_qec_en", 1), + ("calibrate_rx_qec_en", 0), + ("rx_quadrature_tracking_en_chan0", 1), + ("rx_quadrature_tracking_en_chan0", 0), + ("rx_quadrature_tracking_en_chan1", 1), + ("rx_quadrature_tracking_en_chan1", 0), + ("rx_powerdown_en_chan0", 1), + ("rx_powerdown_en_chan0", 0), + ("rx_powerdown_en_chan1", 1), + ("rx_powerdown_en_chan1", 0), + ("gain_control_mode_chan0", "manual"), + ("gain_control_mode_chan0", "slow_attack"), + ("gain_control_mode_chan1", "manual"), + ("gain_control_mode_chan1", "slow_attack"), + ], +) +def test_adrv9008_1_attr_boolean( + test_attribute_single_value_boolean, iio_uri, classname, attr, value +): + test_attribute_single_value_boolean(iio_uri, classname, attr, value) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr", [("rx_rf_bandwidth"), ("rx_sample_rate"),], +) +def test_adrv9008_1_attr_boolean_readonly( + test_attribute_single_value_boolean_readonly, iio_uri, classname, attr +): + test_attribute_single_value_boolean_readonly(iio_uri, classname, attr) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, value", [("calibrate", 1),], +) +def test_adrv9008_1_attribute_write_only_str( + test_attribute_write_only_str, iio_uri, classname, attr, value +): + test_attribute_write_only_str(iio_uri, classname, attr, value) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, start, stop, step, tol", [("trx_lo", 70000000, 6000000000, 1000, 0),], +) +def test_adrv9008_1_attr( + test_attribute_single_value, iio_uri, classname, attr, start, stop, step, tol +): + test_attribute_single_value(iio_uri, classname, attr, start, stop, step, tol) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, depends, start, stop, step, tol, repeats", + [ + ( + "rx_hardwaregain_chan0", + dict( + frequency_hopping_mode_en=0, + ensm_mode="radio_on", + gain_control_mode_chan0="manual", + rx_powerdown_en_chan0=0, + ), + 0.0, + 30.0, + 0.5, + 0.05, + 2, + ), + ( + "rx_hardwaregain_chan1", + dict( + ensm_mode="radio_on", + gain_control_mode_chan1="manual", + rx_powerdown_en_chan1=0, + ), + 0.0, + 30.0, + 0.5, + 0.05, + 2, + ), + ], +) +def test_adrv9008_1_attr_singleval_depends( + test_attribute_check_range_singleval_with_depends, + iio_uri, + classname, + attr, + depends, + start, + stop, + step, + tol, + repeats, +): + test_attribute_check_range_singleval_with_depends( + iio_uri, classname, attr, depends, start, stop, step, tol, repeats + ) + + +######################################### +@pytest.mark.iio_hardware(hardware, True) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize("attr", ["profile"]) +@pytest.mark.parametrize( + "files", test_profiles, +) +def test_adrv9008_1_profile_write( + test_attribute_write_only_str, iio_uri, classname, attr, files +): + test_attribute_write_only_str(iio_uri, classname, attr, files) diff --git a/test/test_adrv9008_2.py b/test/test_adrv9008_2.py new file mode 100644 index 000000000..5492a49cb --- /dev/null +++ b/test/test_adrv9008_2.py @@ -0,0 +1,169 @@ +from os import listdir +from os.path import dirname, join, realpath + +import pytest + +hardware = "adrv9009" +classname = "adi.adrv9008_2" + +profile_path = dirname(realpath(__file__)) + "/adrv9009_profiles/" +test_profiles = [join(profile_path, f) for f in listdir(profile_path)] + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, value", + [ + ("ensm_mode", "radio_off"), + ("ensm_mode", "radio_on"), + ("calibrate_tx_qec_en", 1), + ("calibrate_tx_qec_en", 0), + ("tx_quadrature_tracking_en_chan0", 1), + ("tx_quadrature_tracking_en_chan0", 0), + ("tx_quadrature_tracking_en_chan1", 1), + ("tx_quadrature_tracking_en_chan1", 0), + ("obs_quadrature_tracking_en", 1), + ("obs_quadrature_tracking_en", 0), + ("obs_rf_port_select", "OBS_AUX_LO"), + ("obs_rf_port_select", "OBS_TX_LO"), + ("obs_powerdown_en", 1), + ("obs_powerdown_en", 0), + ], +) +def test_adrv9008_2_attr_boolean( + test_attribute_single_value_boolean, iio_uri, classname, attr, value +): + test_attribute_single_value_boolean(iio_uri, classname, attr, value) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr", [("tx_rf_bandwidth"), ("tx_sample_rate"), ("orx_sample_rate"),], +) +def test_adrv9008_2_attr_boolean_readonly( + test_attribute_single_value_boolean_readonly, iio_uri, classname, attr +): + test_attribute_single_value_boolean_readonly(iio_uri, classname, attr) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, value", [("calibrate", 1),], +) +def test_adrv9008_2_attribute_write_only_str( + test_attribute_write_only_str, iio_uri, classname, attr, value +): + test_attribute_write_only_str(iio_uri, classname, attr, value) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, start, stop, step, tol", + [ + ("trx_lo", 70000000, 6000000000, 1000, 0), + ("aux_obs_lo", 70000000, 6000000000, 1000, 0), + ], +) +def test_adrv9008_2_attr( + test_attribute_single_value, iio_uri, classname, attr, start, stop, step, tol +): + test_attribute_single_value(iio_uri, classname, attr, start, stop, step, tol) + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, depends, start, stop, step, tol, repeats", + [ + ( + "tx_hardwaregain_chan0", + dict(frequency_hopping_mode_en=0, ensm_mode="radio_on",), + -41.95, + 0.0, + 0.05, + 0.05, + 2, + ), + ( + "tx_hardwaregain_chan1", + dict(frequency_hopping_mode_en=0, ensm_mode="radio_on",), + -41.95, + 0.0, + 0.05, + 0.05, + 2, + ), + ], +) +def test_adrv9008_2_attr_singleval_depends( + test_attribute_check_range_singleval_with_depends, + iio_uri, + classname, + attr, + depends, + start, + stop, + step, + tol, + repeats, +): + test_attribute_check_range_singleval_with_depends( + iio_uri, classname, attr, depends, start, stop, step, tol, repeats + ) + + +######################################### +@pytest.mark.iio_hardware(hardware, True) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, depends, start, stop, step, tol, repeats", + [ + ( + "obs_hardwaregain", + dict( + frequency_hopping_mode_en=0, ensm_mode="radio_on", obs_powerdown_en=0, + ), + 0.0, + 30.0, + 0.5, + 0.05, + 2, + ), + ], +) +def test_adrv9008_2_attr_singleval_depends_2( + test_attribute_check_range_singleval_with_depends, + iio_uri, + classname, + attr, + depends, + start, + stop, + step, + tol, + repeats, +): + test_attribute_check_range_singleval_with_depends( + iio_uri, classname, attr, depends, start, stop, step, tol, repeats + ) + + +######################################### +@pytest.mark.iio_hardware(hardware, True) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize("attr", ["profile"]) +@pytest.mark.parametrize( + "files", test_profiles, +) +def test_adrv9008_2_profile_write( + test_attribute_write_only_str, iio_uri, classname, attr, files +): + test_attribute_write_only_str(iio_uri, classname, attr, files)