Skip to content

Commit

Permalink
Merge pull request #481 from analogdevicesinc/dlech/ad2s1210
Browse files Browse the repository at this point in the history
adi/ad2s1210: add AD2S1210 Resolver-to-Digital Converter
  • Loading branch information
tfcollins authored Oct 26, 2023
2 parents 24b753e + a09c520 commit 339a77a
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 0 deletions.
1 change: 1 addition & 0 deletions adi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# SPDX short identifier: ADIBSD

from adi.ad2s1210 import ad2s1210
from adi.ad469x import ad469x
from adi.ad717x import ad717x
from adi.ad719x import ad719x
Expand Down
99 changes: 99 additions & 0 deletions adi/ad2s1210.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Copyright (C) 2023 Analog Devices, Inc.
#
# SPDX short identifier: ADIBSD

from adi.attribute import attribute
from adi.context_manager import context_manager
from adi.rx_tx import rx

# TODO: add support for events when libiio gains support for it


class ad2s1210(rx, context_manager):
"""
AD2S1210 resolver to digital converter.
"""

_device_name = "ad2s1210"

def __init__(self, uri=""):
context_manager.__init__(self, uri, self._device_name)

self._rxadc = self._ctrl = self._ctx.find_device(self._device_name)
self._rx_channel_names = []

for ch in self._ctrl.channels:
name = ch.id

if name == "angl0":
self._rx_channel_names.append(name)
self.position = self._position_channel(self._ctrl, name)
elif name == "anglvel0":
self._rx_channel_names.append(name)
self.velocity = self._velocity_channel(self._ctrl, name)

rx.__init__(self)

@property
def excitation_frequency(self) -> int:
"""
Gets and sets the excitation frequency in Hz.
Setting the value also does a soft reset of the device so that the
physical output is updated for the change.
"""
return self._get_iio_attr("altvoltage0", "frequency", True)

@excitation_frequency.setter
def excitation_frequency(self, value: int) -> None:
self._set_iio_attr("altvoltage0", "frequency", True, value)

@property
def hysteresis_enable(self) -> bool:
"""
Gets and sets the hysteresis bit in the Control register.
"""
return bool(self._get_iio_attr("angl0", "hysteresis", False))

@hysteresis_enable.setter
def hysteresis_enable(self, value: bool) -> None:
# This is just a boolean bit flag in the Control register but the
# IIO ABI requires us to use raw angle units so we have to look up
# the available values to find out what the raw value is for True.
# `avail` will be a list of two int values.
avail = self._get_iio_attr("angl0", "hysteresis_available", False)
self._set_iio_attr("angl0", "hysteresis", False, avail[bool(value)])

class _position_channel(attribute):
"""AD2S1210 channel"""

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

@property
def raw(self) -> int:
"""AD2S1210 position channel raw value"""
return self._get_iio_attr(self.name, "raw", False)

@property
def scale(self) -> float:
"""AD2S1210 position channel scale"""
return float(self._get_iio_attr(self.name, "scale", False))

class _velocity_channel(attribute):
"""AD2S1210 channel"""

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

@property
def raw(self) -> int:
"""AD2S1210 velocity channel raw value"""
return self._get_iio_attr(self.name, "raw", False)

@property
def scale(self) -> float:
"""AD2S1210 velocity channel scale"""
return float(self._get_iio_attr(self.name, "scale", False))
7 changes: 7 additions & 0 deletions doc/source/devices/adi.ad2s1210.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ad2s1210
=================

.. automodule:: adi.ad2s1210
: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 @@ -8,6 +8,7 @@ Supported Devices
:maxdepth: 4

adi.QuadMxFE_multi
adi.ad2s1210
adi.ad4020
adi.ad4110
adi.ad4130
Expand Down
1 change: 1 addition & 0 deletions supported_parts.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
[[Wiki](https://wiki.analog.com/resources/tools-software/linux-software/pyadi-iio)]

### Currently supported hardware
- AD2S1210
- AD4020
- AD4130
- AD4110
Expand Down
154 changes: 154 additions & 0 deletions test/emu/devices/ad2s1210.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE context [
<!ELEMENT context (device | context-attribute)*>
<!ELEMENT context-attribute EMPTY>
<!ELEMENT device (channel | attribute | debug-attribute | buffer-attribute)*>
<!ELEMENT channel (scan-element?, attribute*)>
<!ELEMENT attribute EMPTY>
<!ELEMENT scan-element EMPTY>
<!ELEMENT debug-attribute EMPTY>
<!ELEMENT buffer-attribute EMPTY>
<!ATTLIST context
name CDATA #REQUIRED
description CDATA #IMPLIED>
<!ATTLIST context-attribute
name CDATA #REQUIRED
value CDATA #REQUIRED>
<!ATTLIST device
id CDATA #REQUIRED
name CDATA #IMPLIED>
<!ATTLIST channel
id CDATA #REQUIRED
type (input|output) #REQUIRED
name CDATA #IMPLIED>
<!ATTLIST scan-element
index CDATA #REQUIRED
format CDATA #REQUIRED
scale CDATA #IMPLIED>
<!ATTLIST attribute
name CDATA #REQUIRED
filename CDATA #IMPLIED
value CDATA #IMPLIED>
<!ATTLIST debug-attribute
name CDATA #REQUIRED
value CDATA #IMPLIED>
<!ATTLIST buffer-attribute
name CDATA #REQUIRED
value CDATA #IMPLIED>
]>
<context name="network"
description="10.2.5.203 Linux setup-2-zed 6.6.0-rc1-00159-gc9e4b991d8c1 #1 SMP PREEMPT Tue Sep 26 10:20:33 CDT 2023 armv7l">
<context-attribute name="hw_carrier" value="Xilinx Zynq ZED" />
<context-attribute name="local,kernel" value="6.6.0-rc1-00159-gc9e4b991d8c1" />
<context-attribute name="uri" value="ip:10.2.5.203" />
<context-attribute name="ip,ip-addr" value="10.2.5.203" />
<device id="hwmon0" name="e000b000ethernetffffffff00">
<channel id="temp1" type="input">
<attribute name="crit" filename="temp1_crit" value="100000" />
<attribute name="input" filename="temp1_input" value="43000" />
<attribute name="max_alarm" filename="temp1_max_alarm" value="0" />
</channel>
</device>
<device id="iio:device0" name="xadc">
<channel id="voltage5" name="vccoddr" type="input">
<attribute name="label" filename="in_voltage5_vccoddr_label" value="vccoddr" />
<attribute name="raw" filename="in_voltage5_vccoddr_raw" value="2051" />
<attribute name="scale" filename="in_voltage5_vccoddr_scale" value="0.732421875" />
</channel>
<channel id="voltage0" name="vccint" type="input">
<attribute name="label" filename="in_voltage0_vccint_label" value="vccint" />
<attribute name="raw" filename="in_voltage0_vccint_raw" value="1394" />
<attribute name="scale" filename="in_voltage0_vccint_scale" value="0.732421875" />
</channel>
<channel id="voltage4" name="vccpaux" type="input">
<attribute name="label" filename="in_voltage4_vccpaux_label" value="vccpaux" />
<attribute name="raw" filename="in_voltage4_vccpaux_raw" value="2464" />
<attribute name="scale" filename="in_voltage4_vccpaux_scale" value="0.732421875" />
</channel>
<channel id="temp0" type="input">
<attribute name="offset" filename="in_temp0_offset" value="-2219" />
<attribute name="raw" filename="in_temp0_raw" value="2624" />
<attribute name="scale" filename="in_temp0_scale" value="123.040771484" />
</channel>
<channel id="voltage7" name="vrefn" type="input">
<attribute name="label" filename="in_voltage7_vrefn_label" value="vrefn" />
<attribute name="raw" filename="in_voltage7_vrefn_raw" value="11" />
<attribute name="scale" filename="in_voltage7_vrefn_scale" value="0.732421875" />
</channel>
<channel id="voltage1" name="vccaux" type="input">
<attribute name="label" filename="in_voltage1_vccaux_label" value="vccaux" />
<attribute name="raw" filename="in_voltage1_vccaux_raw" value="2459" />
<attribute name="scale" filename="in_voltage1_vccaux_scale" value="0.732421875" />
</channel>
<channel id="voltage2" name="vccbram" type="input">
<attribute name="label" filename="in_voltage2_vccbram_label" value="vccbram" />
<attribute name="raw" filename="in_voltage2_vccbram_raw" value="1397" />
<attribute name="scale" filename="in_voltage2_vccbram_scale" value="0.732421875" />
</channel>
<channel id="voltage3" name="vccpint" type="input">
<attribute name="label" filename="in_voltage3_vccpint_label" value="vccpint" />
<attribute name="raw" filename="in_voltage3_vccpint_raw" value="1393" />
<attribute name="scale" filename="in_voltage3_vccpint_scale" value="0.732421875" />
</channel>
<channel id="voltage6" name="vrefp" type="input">
<attribute name="label" filename="in_voltage6_vrefp_label" value="vrefp" />
<attribute name="raw" filename="in_voltage6_vrefp_raw" value="1715" />
<attribute name="scale" filename="in_voltage6_vrefp_scale" value="0.732421875" />
</channel>
<attribute name="sampling_frequency" value="961538" />
<attribute name="waiting_for_supplier" value="0" />
</device>
<device id="iio:device1" name="ad2s1210">
<channel id="angl0" type="input">
<scan-element index="0" format="be:U16/16&gt;&gt;0" scale="0.000096" />
<attribute name="hysteresis" filename="in_angl0_hysteresis" value="64" />
<attribute name="hysteresis_available" filename="in_angl0_hysteresis_available"
value="0 64" />
<attribute name="label" filename="in_angl0_label" value="position" />
<attribute name="raw" filename="in_angl0_raw" value="12577" />
<attribute name="scale" filename="in_angl0_scale" value="0.000095874" />
</channel>
<channel id="anglvel0" type="input">
<scan-element index="1" format="be:S16/16&gt;&gt;0" scale="0.023968" />
<attribute name="label" filename="in_anglvel0_label" value="velocity" />
<attribute name="raw" filename="in_anglvel0_raw" value="3" />
<attribute name="scale" filename="in_anglvel0_scale" value="0.023968449" />
</channel>
<channel id="timestamp" type="input">
<scan-element index="2" format="le:S64/64&gt;&gt;0" />
</channel>
<channel id="phase0" type="input">
<attribute name="label" filename="in_phase0_label" value="synthetic reference" />
</channel>
<channel id="altvoltage0" type="output">
<attribute name="frequency" filename="out_altvoltage0_frequency" value="10000" />
<attribute name="frequency_available" filename="out_altvoltage0_frequency_available"
value="[2000 250 20000]" />
<attribute name="label" filename="out_altvoltage0_label" value="excitation" />
</channel>
<channel id="altvoltage2" type="input">
<attribute name="label" filename="in_altvoltage2_label" value="sine" />
</channel>
<channel id="angl1" type="input">
<attribute name="label" filename="in_angl1_label" value="tracking error" />
</channel>
<channel id="altvoltage0" type="input">
<attribute name="label" filename="in_altvoltage0_label" value="monitor signal" />
</channel>
<channel id="altvoltage1" type="input">
<attribute name="label" filename="in_altvoltage1_label" value="cosine" />
</channel>
<attribute name="current_timestamp_clock" value="realtime" />
<attribute name="waiting_for_supplier" value="0" />
<buffer-attribute name="data_available" value="0" />
<buffer-attribute name="direction" value="in" />
<debug-attribute name="direct_reg_access" value="ERROR" />
</device>
<device id="iio_sysfs_trigger">
<attribute name="add_trigger" value="ERROR" />
<attribute name="remove_trigger" value="ERROR" />
</device>
<device id="trigger0" name="test">
<attribute name="sampling_frequency" value="100.000000" />
</device>
</context>
10 changes: 10 additions & 0 deletions test/emu/hardware_map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ daq3:
- data_devices:
- iio:device3
- iio:device4

ad2s1210:
- ad2s1210
- pyadi_iio_class_support:
- ad2s1210
- emulate:
- filename: ad2s1210.xml
- data_devices:
- iio:device1

ad9081:
- axi-ad9081-tx-hpc
- axi-ad9081-rx-hpc
Expand Down
47 changes: 47 additions & 0 deletions test/test_ad2s1210.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import pytest

hardware = "ad2s1210"
classname = "adi.ad2s1210"


#########################################
@pytest.mark.iio_hardware(hardware, True)
@pytest.mark.parametrize("classname", [classname])
@pytest.mark.parametrize("channel", ["angl0", "anglvel0", ["angl0", "anglvel0"]])
def test_ad2s1210_rx_data(test_dma_rx, iio_uri, classname, channel):
test_dma_rx(iio_uri, classname, channel, buffer_size=1024)


#########################################
@pytest.mark.iio_hardware(hardware)
@pytest.mark.parametrize("classname", [classname])
@pytest.mark.parametrize(
"attr, start, stop, step, tol, repeats",
[("excitation_frequency", 2000, 20000, 250, 1, 10),],
)
def test_ad2s1210_attr(
test_attribute_single_value,
iio_uri,
classname,
attr,
start,
stop,
step,
tol,
repeats,
):
test_attribute_single_value(
iio_uri, classname, attr, start, stop, step, tol, repeats
)


#########################################
@pytest.mark.iio_hardware(hardware)
@pytest.mark.parametrize("classname", [classname])
@pytest.mark.parametrize(
"attr, value", [("hysteresis_enable", True), ("hysteresis_enable", False),],
)
def test_ad2s1210_attr_boolean(
test_attribute_single_value_boolean, iio_uri, classname, attr, value
):
test_attribute_single_value_boolean(iio_uri, classname, attr, value)

0 comments on commit 339a77a

Please sign in to comment.