Skip to content

Commit

Permalink
ad77681 pyadi-iio support
Browse files Browse the repository at this point in the history
Implemented ad7768-1 pyadi-iio device driver class and example script

Signed-off-by: MPhalke <[email protected]>
  • Loading branch information
mphalke committed May 18, 2023
1 parent 4f8ef1c commit 1edc997
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 1 deletion.
1 change: 1 addition & 0 deletions adi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
from adi.ad7689 import ad7689
from adi.ad7746 import ad7746
from adi.ad7768 import ad7768
from adi.ad7768_1 import ad7768_1
from adi.ad7799 import ad7799
from adi.ad9081 import ad9081
from adi.ad9081_mc import QuadMxFE, ad9081_mc
Expand Down
166 changes: 166 additions & 0 deletions adi/ad7768_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Copyright (C) 2023 Analog Devices, Inc.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# - Neither the name of Analog Devices, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
# - The use of this software may or may not infringe the patent rights
# of one or more patent holders. This license does not release you
# from the requirement that you obtain separate licenses from these
# patent holders to use this software.
# - Use of the software either in source or binary form, must be run
# on or directly connected to an Analog Devices Inc. component.
#
# THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED.
#
# IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
# RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


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 ad7768_1(rx, context_manager):

""" AD7768-1 ADC """

_complex_data = False
channel = [] # type: ignore
_device_name = ""

def __init__(self, uri="", device_name=""):
"""Constructor for ad7768_1 class."""
context_manager.__init__(self, uri, self._device_name)

compatible_parts = ["ad7768-1"]

self._ctrl = None

if not device_name:
device_name = compatible_parts[0]
else:
if device_name not in compatible_parts:
raise Exception(f"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

if not self._ctrl:
raise Exception("Error in selecting matching device")

if not self._rxadc:
raise Exception("Error in selecting matching device")

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 sampling_frequency(self):
"""Get sampling frequency."""
return self._get_iio_dev_attr("sampling_frequency")

@sampling_frequency.setter
def sampling_frequency(self, rate):
"""Set sampling frequency."""
self._set_iio_dev_attr("sampling_frequency", rate)


class _channel(attribute):

""" ad7768-1 channel """

def __init__(self, ctrl, channel_name):
self.name = channel_name
self._ctrl = ctrl

@property
def raw(self):
"""Get channel raw value."""
return self._get_iio_attr(self.name, "raw", False)

@property
def scale(self):
"""Get channel scale."""
return self._get_iio_attr(self.name, "scale", False)

@scale.setter
def scale(self, value):
"""Set channel scale."""
self._set_iio_attr(self.name, "scale", False, Decimal(value).real)

@property
def offset(self):
"""Get channel offset."""
return self._get_iio_attr(self.name, "offset", False)

@offset.setter
def offset(self, value):
"""Set channel offset."""
self._set_iio_attr(self.name, "offset", False, value)

@property
def filter_low_pass_3db_frequency_avail(self):
"""Get available low pass filter 3db frequencies."""
return self._get_iio_attr_str(self.name, "filter_low_pass_3db_frequency_available", False)

@property
def filter_low_pass_3db_frequency(self):
"""Get low pass filter 3db frequency."""
return self._get_iio_attr_str(self.name, "filter_low_pass_3db_frequency", False)

@filter_low_pass_3db_frequency.setter
def filter_low_pass_3db_frequency(self, freq):
"""Set low pass filter 3db frequency."""
if freq in self.filter_low_pass_3db_frequency_avail:
self._set_iio_attr(self.name, "filter_low_pass_3db_frequency", False, freq)
else:
raise ValueError(
"Error: Low pass filter 3db frequency not supported \nUse one of: "
+ str(self.filter_low_pass_3db_frequency_avail)
)

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]

if ret is None:
raise Exception("Error in converting to actual voltage")

return ret
7 changes: 7 additions & 0 deletions doc/source/devices/adi.ad7768_1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ad7768_1
=================

.. automodule:: adi.ad7768_1
:members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions doc/source/devices/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Supported Devices
adi.ad7689
adi.ad7746
adi.ad7768
adi.ad7768_1
adi.ad777x
adi.ad7799
adi.ad9081
Expand Down
81 changes: 81 additions & 0 deletions examples/ad7768_1_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright (C) 2023 Analog Devices, Inc.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# - Neither the name of Analog Devices, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
# - The use of this software may or may not infringe the patent rights
# of one or more patent holders. This license does not release you
# from the requirement that you obtain separate licenses from these
# patent holders to use this software.
# - Use of the software either in source or binary form, must be run
# on or directly connected to an Analog Devices Inc. component.
#
# THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED.
#
# IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
# RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys
from time import sleep

import matplotlib.pyplot as plt
from adi import ad7768_1

# Optionally pass URI as command line argument,
# else use default ip:analog.local
my_uri = sys.argv[1] if len(sys.argv) >= 2 else "ip:analog.local"
print("uri: " + str(my_uri))

my_adc = ad7768_1(uri=my_uri)
my_adc.rx_buffer_size = 1024

# Set Sample Rate. Options are 1ksps to 256ksps, 1k* power of 2.
# Note that sample rate and power mode are not orthogonal - refer
# to datasheet.
my_adc.sampling_frequency = 8000

# Choose output format:
# my_adc.rx_output_type = "raw"
my_adc.rx_output_type = "SI"

# Verify settings:
print("Sampling Frequency: ", my_adc.sampling_frequency)
print("Enabled Channels: ", my_adc.rx_enabled_channels)


plt.clf()
sleep(0.5)
data = my_adc.rx()
for ch in my_adc.rx_enabled_channels:
plt.plot(range(0, len(data[0])), data[ch], label="voltage" + str(ch))
plt.xlabel("Data Point")
if my_adc.rx_output_type == "SI":
plt.ylabel("Millivolts")
else:
plt.ylabel("ADC counts")
plt.legend(
bbox_to_anchor=(0.0, 1.02, 1.0, 0.102),
loc="lower left",
ncol=4,
mode="expand",
borderaxespad=0.0,
)
plt.pause(0.01)

del my_adc
1 change: 1 addition & 0 deletions supported_parts.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
- AD7193
- AD7195
- AD7768
- AD7768-1
- AD7770
- AD7771
- AD7779
Expand Down
11 changes: 10 additions & 1 deletion test/emu/hardware_map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,16 @@ ad7768:
- filename: ad7768.xml
- data_devices:
- iio:device0


ad7768_1:
- ad7768-1
- pyadi_iio_class_support:
- ad7768_1
- emulate:
- filename: ad7768_1.xml
- data_devices:
- iio:device0

ad5592r:
- ad5592r
- pyadi_iio_class_support:
Expand Down
11 changes: 11 additions & 0 deletions test/test_ad7768_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import pytest

hardware = "ad7768-1"
classname = "adi.ad7768_1"


#########################################
@pytest.mark.iio_hardware(hardware)
@pytest.mark.parametrize("classname", [(classname)])
def test_ad7768_1_rx_data(test_dma_rx, iio_uri, classname, channel):
test_dma_rx(iio_uri, classname, channel)

0 comments on commit 1edc997

Please sign in to comment.