diff --git a/adi/__init__.py b/adi/__init__.py index 8188c8b35..7549e1615 100644 --- a/adi/__init__.py +++ b/adi/__init__.py @@ -95,6 +95,7 @@ from adi.ltc2314_14 import ltc2314_14 from adi.ltc2387 import ltc2387 from adi.ltc2499 import ltc2499 +from adi.ltc2664 import ltc2664 from adi.ltc2688 import ltc2688 from adi.ltc2983 import ltc2983 from adi.max9611 import max9611 diff --git a/adi/ltc2664.py b/adi/ltc2664.py new file mode 100644 index 000000000..95a51847b --- /dev/null +++ b/adi/ltc2664.py @@ -0,0 +1,166 @@ +# Copyright (C) 2024 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD + +from adi.attribute import attribute +from adi.context_manager import context_manager + + +class ltc2664(context_manager, attribute): + """ LTC2664 DAC """ + + _complex_data = False + _device_name = "LTC2664" + channel_names = [] + + def __init__(self, uri="ip:analog.local", device_index=0): + context_manager.__init__(self, uri, self._device_name) + + self._ctrl = self._ctx.find_device("ltc2664") + + for ch in self._ctrl.channels: + name = ch.id + self.channel_names.append(name) + if "toggle_en" in ch.attrs: + setattr(self, name, self._channel_toggle(self._ctrl, name)) + else: + setattr(self, name, self._channel_standard(self._ctrl, name)) + + class _channel_base(attribute): + """ LTC2664 base channel class """ + + def __init__(self, ctrl, channel_name): + self.name = channel_name + self._ctrl = ctrl + + @property + def scale(self): + """ LTC2664 channel gain """ + return self._get_iio_attr(self.name, "scale", True, self._ctrl) + + @property + def offset(self): + """ LTC2664 channel offset """ + return self._get_iio_attr(self.name, "offset", True, self._ctrl) + + @property + def volt_available(self): + """ LTC2664 voltage min/max [min, max] in mV """ + return [ + round((0 + self.offset) * self.scale, 2), + round((65535 + self.offset) * self.scale, 2), + ] + + @property + def raw_available(self): + """ LTC2664 raw value range [min, increment, max] """ + return list( + map( + int, + (self._get_iio_attr(self.name, "raw_available", True, self._ctrl)), + ) + ) + + @property + def powerdown(self): + """ LTC2664 channel powerdown """ + return self._get_iio_attr(self.name, "powerdown", True, self._ctrl) + + @powerdown.setter + def powerdown(self, val): + """ LTC2664 channel powerdown """ + self._set_iio_attr(self.name, "powerdown", True, val, self._ctrl) + + class _channel_standard(_channel_base): + def __init__(self, ctrl, channel_name): + super().__init__(ctrl, channel_name) + + @property + def raw(self): + """ LTC2664 channel raw value property """ + return self._get_iio_attr(self.name, "raw", True, self._ctrl) + + @raw.setter + def raw(self, val): + """ LTC2664 channel raw value setter """ + raw_span = self._get_iio_attr(self.name, "raw_available", True, self._ctrl) + if val >= raw_span[0] and val <= raw_span[2] and val % raw_span[1] == 0: + self._set_iio_attr(self.name, "raw", True, str(int(val))) + + @property + def volt(self): + """ LTC2664 channel volt property (in mV)""" + return (self.raw + self.offset) * self.scale + + @volt.setter + def volt(self, val): + """ LTC2664 channel volt setter (in mV)""" + self.raw = int((val / self.scale) - self.offset) + + class _channel_toggle(_channel_base): + def __init__(self, ctrl, channel_name): + super().__init__(ctrl, channel_name) + + @property + def toggle_en(self): + """ LTC2664 channel toggle enable flag """ + return self._get_iio_attr(self.name, "toggle_en", True, self._ctrl) + + @toggle_en.setter + def toggle_en(self, val): + """ LTC2664 channel toggle enable flag setter """ + self._set_iio_attr(self.name, "toggle_en", True, val) + + @property + def toggle_state(self): + """ LTC2664 SW toggle enable flag """ + return self._get_iio_attr(self.name, "symbol", True, self._ctrl) + + @toggle_state.setter + def toggle_state(self, val): + """ LTC2664 SW toggle enable flag setter """ + self._set_iio_attr(self.name, "symbol", True, str(int(val))) + + @property + def raw0(self): + """ LTC2664 channel toggle state 0 raw value """ + return self._get_iio_attr(self.name, "raw0", True, self._ctrl) + + @raw0.setter + def raw0(self, val): + """ LTC2664 channel toggle state 0 raw value setter """ + raw_span = self._get_iio_attr(self.name, "raw_available", True, self._ctrl) + if val >= raw_span[0] and val <= raw_span[2] and val % raw_span[1] == 0: + self._set_iio_attr(self.name, "raw0", True, str(int(val))) + + @property + def raw1(self): + """ LTC2664 channel toggle state 1 raw value """ + return self._get_iio_attr(self.name, "raw1", True, self._ctrl) + + @raw1.setter + def raw1(self, val): + """ LTC2664 channel toggle state 1 raw value setter """ + raw_span = self._get_iio_attr(self.name, "raw_available", True, self._ctrl) + if val >= raw_span[0] and val <= raw_span[2] and val % raw_span[1] == 0: + self._set_iio_attr(self.name, "raw1", True, str(int(val))) + + @property + def volt0(self): + """ LTC2664 channel toggle state 0 voltage value (in mV)""" + return (self.raw0 + self.offset) * self.scale + + @volt0.setter + def volt0(self, val): + """ LTC2664 channel toggle state 0 voltage value setter (in mV)""" + self.raw0 = int(((val / self.scale) - self.offset)) + + @property + def volt1(self): + """ LTC2664 channel toggle state 1 voltage value (in mV)""" + return (self.raw1 + self.offset) * self.scale + + @volt1.setter + def volt1(self, val): + """ LTC2664 channel toggle state 1 voltage value setter (in mV)""" + self.raw1 = int(((val / self.scale) - self.offset)) diff --git a/doc/source/devices/adi.ltc2664.rst b/doc/source/devices/adi.ltc2664.rst new file mode 100644 index 000000000..c3fca06ba --- /dev/null +++ b/doc/source/devices/adi.ltc2664.rst @@ -0,0 +1,7 @@ +ltc2664 +================== + +.. automodule:: adi.ltc2664 + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/devices/index.rst b/doc/source/devices/index.rst index 0a8973b6b..62d7396b9 100644 --- a/doc/source/devices/index.rst +++ b/doc/source/devices/index.rst @@ -105,6 +105,7 @@ Supported Devices adi.ltc2314_14 adi.ltc2387 adi.ltc2499 + adi.ltc2664 adi.ltc2688 adi.ltc2983 adi.max11205 diff --git a/examples/ltc2664_example.py b/examples/ltc2664_example.py new file mode 100644 index 000000000..845a0066e --- /dev/null +++ b/examples/ltc2664_example.py @@ -0,0 +1,40 @@ +# Copyright (C) 2023 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD + +import sys +import time + +import adi + +# Device initialization +try: + myDAC = adi.ltc2664(uri="ip:analog.local") + + for ch in myDAC.channel_names: + ch_object = eval("myDAC." + str(ch)) + voltage_range = ch_object.volt_available + raw_value_range = ch_object.raw_available + print( + "LTC2644 channel " + + ch + + " configured output range " + + str(voltage_range) + + " mV: RAW value range " + + str(raw_value_range) + ) + +except Exception as e: + print(str(e)) + print("Failed to open LTC2664 device") + sys.exit(0) + +# sweep entire output range in 100mV steps +voltage_range = myDAC.voltage0.volt_available + +for v in range(int(voltage_range[0]), int(voltage_range[1]), 100): + print("setting voltage0 = " + str(v / 1000) + " Volt") + myDAC.voltage0.volt = v + time.sleep(0.05) + +myDAC.voltage0.powerdown = 1 diff --git a/supported_parts.md b/supported_parts.md index e52795d8e..b509c5512 100644 --- a/supported_parts.md +++ b/supported_parts.md @@ -161,6 +161,7 @@ - LTC2314-14 - LTC2387-18 - LTC2499 +- LTC2664 - LTC2688 - LTC2983 - AD7606 diff --git a/test/emu/devices/ltc2664.xml b/test/emu/devices/ltc2664.xml new file mode 100644 index 000000000..e2bd4cd11 --- /dev/null +++ b/test/emu/devices/ltc2664.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 8e73b720d..8d31e0874 100644 --- a/test/emu/hardware_map.yml +++ b/test/emu/hardware_map.yml @@ -403,6 +403,15 @@ ltc2387: - filename: ltc2387.xml - data_devices: - iio:device0 +ltc2664: + - ltc2664 + - pyadi_iio_class_support: + - ltc2664 + - emulate: + - filename: ltc2664.xml + - data_devices: + - iio:device0 + ltc2688: - ltc2688 - pyadi_iio_class_support: diff --git a/test/test_ltc2664.py b/test/test_ltc2664.py new file mode 100644 index 000000000..38f2a0d76 --- /dev/null +++ b/test/test_ltc2664.py @@ -0,0 +1,34 @@ +import pytest + +hardware = "ltc2664" +classname = "adi.ltc2664" + + +######################################### +@pytest.mark.iio_hardware(hardware) +@pytest.mark.parametrize("classname", [(classname)]) +@pytest.mark.parametrize( + "attr, start, stop, step, tol, repeats, sub_channel", + [ + ("raw", 0, 65000, 1000, 1, 3, "voltage0"), # Standard Channel + ("raw0", 0, 65000, 1000, 1, 3, "voltage1"), # Toggle Channel + ("raw1", 0, 65000, 1000, 1, 3, "voltage1"), # Toggle Channel + ("raw", 0, 65000, 1000, 1, 3, "voltage2"), # Standard Channel + ("raw", 0, 65000, 1000, 1, 3, "voltage3"), # Standard Channel + ], +) +def test_ltc2688_raw_attr( + test_attribute_single_value, + iio_uri, + classname, + attr, + start, + stop, + step, + tol, + repeats, + sub_channel, +): + test_attribute_single_value( + iio_uri, classname, attr, start, stop, step, tol, repeats, sub_channel + )