From 4dc4f0a7e3ea002dfa68571fe1be778f39fd5684 Mon Sep 17 00:00:00 2001 From: "Travis F. Collins" Date: Fri, 27 Oct 2023 17:33:29 -0600 Subject: [PATCH] Simplify ADC classes This is an try at simplifying the common code between any ADC (and likely DAC) classes. It also provide a visible class for all support component skews to make picking the right class easier. Signed-off-by: Travis F. Collins --- adi/__init__.py | 2 +- adi/ad7124.py | 45 ----------- adi/ad7606.py | 124 ------------------------------ adi/ad760x.py | 89 +++++++++++++++++++++ adi/dma_helpers.py | 36 +++++++++ adi/rx_tx.py | 12 +++ doc/source/devices/adi.ad7606.rst | 7 -- doc/source/devices/adi.ad760x.rst | 56 ++++++++++++++ 8 files changed, 194 insertions(+), 177 deletions(-) delete mode 100644 adi/ad7606.py create mode 100644 adi/ad760x.py create mode 100644 adi/dma_helpers.py delete mode 100644 doc/source/devices/adi.ad7606.rst create mode 100644 doc/source/devices/adi.ad760x.rst diff --git a/adi/__init__.py b/adi/__init__.py index dd8372a0a..fc2b30af1 100644 --- a/adi/__init__.py +++ b/adi/__init__.py @@ -7,6 +7,7 @@ from adi.ad578x import ad578x from adi.ad717x import ad717x from adi.ad719x import ad719x +from adi.ad760x import ad7605_4, ad7606, ad7606_4, ad7606_6, ad7606_8 from adi.ad777x import ad777x from adi.ad936x import Pluto, ad9361, ad9363, ad9364 from adi.ad4020 import ad4020 @@ -21,7 +22,6 @@ from adi.ad6676 import ad6676 from adi.ad7124 import ad7124 from adi.ad7291 import ad7291 -from adi.ad7606 import ad7606 from adi.ad7689 import ad7689 from adi.ad7746 import ad7746 from adi.ad7768 import ad7768, ad7768_4 diff --git a/adi/ad7124.py b/adi/ad7124.py index 9eda4a0c0..62b82799d 100644 --- a/adi/ad7124.py +++ b/adi/ad7124.py @@ -76,48 +76,3 @@ def sample_rate(self, value): def scale_available(self): """Provides all available scale(gain) settings for the AD7124 channels""" return self._get_iio_attr(self.channel[0].name, "scale_available", False) - - class _channel(attribute): - """AD7124 channel""" - - def __init__(self, ctrl, channel_name): - self.name = channel_name - self._ctrl = ctrl - - @property - def raw(self): - """AD7124 channel raw value""" - return self._get_iio_attr(self.name, "raw", False) - - @property - def scale(self): - """AD7124 channel scale(gain)""" - return float(self._get_iio_attr_str(self.name, "scale", False)) - - @scale.setter - def scale(self, value): - self._set_iio_attr(self.name, "scale", False, str(Decimal(value).real)) - - @property - def offset(self): - """AD7124 channel offset""" - return self._get_iio_attr(self.name, "offset", False) - - @offset.setter - def offset(self, value): - self._get_iio_attr(self.name, "offset", False, value) - - def to_volts(self, index, val): - """Converts raw value to SI""" - _scale = self.channel[index].scale - _offset = self.channel[index].offset - - ret = None - - if isinstance(val, np.int16): - ret = val * _scale + _offset - - if isinstance(val, np.ndarray): - ret = [x * _scale + _offset for x in val] - - return ret diff --git a/adi/ad7606.py b/adi/ad7606.py deleted file mode 100644 index e3f1cb7ce..000000000 --- a/adi/ad7606.py +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (C) 2021-2023 Analog Devices, Inc. -# -# SPDX short identifier: ADIBSD - - -from decimal import Decimal - -import numpy as np -from adi.attribute import attribute -from adi.context_manager import context_manager -from adi.rx_tx import rx - - -class ad7606(rx, context_manager): - """ AD7606 ADC """ - - _complex_data = False - channel = [] # type: ignore - _device_name = "" - - def __init__(self, uri="", device_name=""): - - context_manager.__init__(self, uri, self._device_name) - - compatible_parts = [ - "ad7605-4", - "ad7606-4", - "ad7606-6", - "ad7606-8", - "ad7606b", - "ad7606c-16", - "ad7606c-18", - "ad7616", - ] - - self._ctrl = None - - if not device_name: - device_name = compatible_parts[0] - else: - if device_name not in compatible_parts: - raise Exception("Not a compatible device: " + device_name) - - # Select the device matching device_name as working device - for device in self._ctx.devices: - if device.name == device_name: - self._ctrl = device - self._rxadc = device - break - - for ch in self._ctrl.channels: - name = ch._id - self._rx_channel_names.append(name) - self.channel.append(self._channel(self._ctrl, name)) - - rx.__init__(self) - - @property - def scale_available(self): - """Provides all available scale settings for the AD7606 channels""" - return self._get_iio_attr(self.channel[0].name, "scale_available", False) - - @property - def range_available(self): - """Provides all available range settings for the AD7606 channels""" - return self._get_iio_attr(self.channel[0].name, "range_available", False) - - @property - def oversampling_ratio(self): - """AD7606 oversampling_ratio""" - return self._get_iio_attr(self.name, "oversampling_ratio", False) - - @oversampling_ratio.setter - def oversampling_ratio(self, value): - self._get_iio_attr(self.name, "oversampling_ratio", False, value) - - @property - def oversampling_ratio_available(self): - """AD7606 channel oversampling_ratio_available""" - return self._get_iio_attr(self.name, "oversampling_ratio_available", False) - - class _channel(attribute): - """AD7606 channel""" - - def __init__(self, ctrl, channel_name): - self.name = channel_name - self._ctrl = ctrl - - @property - def raw(self): - """AD7606 channel raw value""" - return self._get_iio_attr(self.name, "raw", False) - - @property - def scale(self): - """AD7606 channel scale""" - return float(self._get_iio_attr_str(self.name, "scale", False)) - - @scale.setter - def scale(self, value): - self._set_iio_attr(self.name, "scale", False, str(Decimal(value).real)) - - @property - def range(self): - """AD7606 channel range""" - return self._get_iio_attr(self.name, "range", False) - - @range.setter - def range(self, value): - self._set_iio_attr(self.name, "range", False, str(Decimal(value).real)) - - def to_volts(self, index, val): - """Converts raw value to SI""" - _scale = self.channel[index].scale - - ret = None - - if isinstance(val, np.int16): - ret = val * _scale - - if isinstance(val, np.ndarray): - ret = [x * _scale for x in val] - - return ret diff --git a/adi/ad760x.py b/adi/ad760x.py new file mode 100644 index 000000000..32a5e9d27 --- /dev/null +++ b/adi/ad760x.py @@ -0,0 +1,89 @@ +# Copyright (C) 2021-2023 Analog Devices, Inc. +# +# SPDX short identifier: ADIBSD + + +from decimal import Decimal + +from adi.context_manager import context_manager +from adi.dma_helpers import _channel +from adi.rx_tx import rx_def + + +class ad760x(rx_def, context_manager): + """Common class for the AD760x ADCs""" + _complex_data = False + _device_name = "" + _enabled_channel_components = True + + @property + def scale_available(self): + """Provides all available scale settings for the ADC channels""" + return self._get_iio_attr(self.channel[0].name, "scale_available", False) + + @property + def range_available(self): + """Provides all available range settings for the ADC channels""" + return self._get_iio_attr(self.channel[0].name, "range_available", False) + + @property + def oversampling_ratio(self): + """Oversampling_ratio""" + return self._get_iio_attr(self.name, "oversampling_ratio", False) + + @oversampling_ratio.setter + def oversampling_ratio(self, value): + self._get_iio_attr(self.name, "oversampling_ratio", False, value) + + @property + def oversampling_ratio_available(self): + """Channel oversampling_ratio_available""" + return self._get_iio_attr(self.name, "oversampling_ratio_available", False) + + +class ad7605_4(ad760x): + """ AD7605-4 ADC """ + _control_device_name = "ad7605-4" + _rx_data_device_name = "ad7605-4" + _rx_channel_names = [f"voltage{i}" for i in range(4)] + + +class ad7606_4(ad7605_4): + """ AD7606-4 ADC """ + _control_device_name = "ad7606-4" + _rx_data_device_name = "ad7606-4" + + +class ad7606_6(ad760x): + """ AD7606-6 ADC """ + _control_device_name = "ad7606-6" + _rx_data_device_name = "ad7606-6" + _rx_channel_names = [f"voltage{i}" for i in range(6)] + + +class ad7606_8(ad760x): + """ AD7606-8 ADC """ + _control_device_name = "ad7606-8" + _rx_data_device_name = "ad7606-8" + _rx_channel_names = [f"voltage{i}" for i in range(6)] + + +class ad7606b(ad760x): + """ AD7606B ADC """ + _control_device_name = "ad7606b" + _rx_data_device_name = "ad7606b" + _rx_channel_names = [f"voltage{i}" for i in range(6)] + + +class ad7606c_16(ad760x): + """ AD7606C-16 ADC """ + _control_device_name = "ad7606c-16" + _rx_data_device_name = "ad7606c-16" + _rx_channel_names = [f"voltage{i}" for i in range(8)] + + +class ad7606c_18(ad760x): + """ AD7606C-18 ADC """ + _control_device_name = "ad7606c-18" + _rx_data_device_name = "ad7606c-18" + _rx_channel_names = [f"voltage{i}" for i in range(8)] diff --git a/adi/dma_helpers.py b/adi/dma_helpers.py new file mode 100644 index 000000000..273d6acbe --- /dev/null +++ b/adi/dma_helpers.py @@ -0,0 +1,36 @@ +"""Common methods for DMA channels.""" +from .attribute import attribute + +from decimal import Decimal +from iio import Device + + +class dma_channel(attribute): + """ADC channel""" + + def __init__(self, ctrl: Device, channel_name: str): + self.name = channel_name + self._ctrl = ctrl + + @property + def raw(self): + """Channel raw value""" + return self._get_iio_attr(self.name, "raw", False) + + @property + def scale(self): + """Channel scale (gain)""" + return float(self._get_iio_attr_str(self.name, "scale", False)) + + @scale.setter + def scale(self, value): + self._set_iio_attr(self.name, "scale", False, str(Decimal(value).real)) + + @property + def offset(self): + """Channel offset (bias)""" + return self._get_iio_attr(self.name, "offset", False) + + @offset.setter + def offset(self, value): + self._get_iio_attr(self.name, "offset", False, value) \ No newline at end of file diff --git a/adi/rx_tx.py b/adi/rx_tx.py index e9e1b23b0..4b50bec2b 100644 --- a/adi/rx_tx.py +++ b/adi/rx_tx.py @@ -11,6 +11,7 @@ from adi.attribute import attribute from adi.context_manager import context_manager from adi.dds import dds +from adi.dma_helpers import dma_channel class phy(attribute): @@ -619,6 +620,7 @@ class rx_def(shared_def, rx, context_manager, metaclass=ABCMeta): be populated as available channels. """ _rx_channel_names = None + _rx_enabled_channel_components = False @property @abstractmethod @@ -652,11 +654,21 @@ def __init__( if not self._rx_channel_names: raise Exception(f"No scan elements found for device {self._rxadc.name}") + # Add DMA control and sample read properties + if self._rx_enabled_channel_components: + self.__add_component_channels() + rx.__init__(self) if self.__run_rx_post_init__: self.__post_init__() + def __add_component_channels(self): + """Dynamically add component channels to access DMA channels individually""" + self.channel = [ + dma_channel(self._ctrl, cname) for cname in self._rx_channel_names + ] + class tx_def(shared_def, tx, context_manager, metaclass=ABCMeta): """Template metaclass for rx only device specific interfaces.""" diff --git a/doc/source/devices/adi.ad7606.rst b/doc/source/devices/adi.ad7606.rst deleted file mode 100644 index c41c55779..000000000 --- a/doc/source/devices/adi.ad7606.rst +++ /dev/null @@ -1,7 +0,0 @@ -ad7606 -================= - -.. automodule:: adi.ad7606 - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/devices/adi.ad760x.rst b/doc/source/devices/adi.ad760x.rst new file mode 100644 index 000000000..0a1f530c3 --- /dev/null +++ b/doc/source/devices/adi.ad760x.rst @@ -0,0 +1,56 @@ +ad7605-4 +================= + +.. automodule:: adi.ad7605_4 + :members: + :undoc-members: + :show-inheritance: + + +ad7606-4 +================= + +.. automodule:: adi.ad7606_4 + :members: + :undoc-members: + :show-inheritance: + +ad7606-6 +================= + +.. automodule:: adi.ad7606_6 + :members: + :undoc-members: + :show-inheritance: + +ad7606-8 +================= + +.. automodule:: adi.ad7606_8 + :members: + :undoc-members: + :show-inheritance: + +ad7606b +================= + +.. automodule:: adi.ad7606b + :members: + :undoc-members: + :show-inheritance: + +ad7606c_16 +================= + +.. automodule:: adi.ad7606c_16 + :members: + :undoc-members: + :show-inheritance: + +ad7606c_18 +================= + +.. automodule:: adi.ad7606c_18 + :members: + :undoc-members: + :show-inheritance: