Skip to content

Commit

Permalink
Adding Support for CN0579 (#450)
Browse files Browse the repository at this point in the history
* Add support to cn0579

Signed-off-by: Nathaniel Acut <[email protected]>

* Add docstring to current source controller

Also, reused sin_params from ad4639 folder.

Signed-off-by: Nathaniel Acut <[email protected]>

* Was rearranged by pre-commit

Signed-off-by: Nathaniel Acut <[email protected]>

* Removed var 'dac_scale' is assigned to but never used

Signed-off-by: Nathaniel Acut <[email protected]>

* Fix remaining linting issues

Signed-off-by: Nathaniel Acut <[email protected]>

* Fix Codacy Static Code Analysis Issues

Signed-off-by: Nathaniel Acut <[email protected]>

* Remove unused import

Signed-off-by: Nathaniel Acut <[email protected]>

---------

Signed-off-by: Nathaniel Acut <[email protected]>
  • Loading branch information
nsacut authored Jul 20, 2023
1 parent d9b05aa commit ff613be
Show file tree
Hide file tree
Showing 10 changed files with 360 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 @@ -74,6 +74,7 @@
from adi.cn0554 import cn0554
from adi.cn0566 import CN0566
from adi.cn0575 import cn0575
from adi.cn0579 import cn0579
from adi.daq2 import DAQ2
from adi.daq3 import DAQ3
from adi.fmc_vna import fmcvna
Expand Down
107 changes: 107 additions & 0 deletions adi/cn0579.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright (C) 2023 Analog Devices, Inc.
#
# SPDX short identifier: ADIBSD

from adi.ad7768 import ad7768_4


class cn0579(ad7768_4):

""" CN0579 - Multichannel IEPE DAQ for CbM """

def __init__(
self, uri="ip:analog.local",
):

ad7768_4.__init__(self, uri)

self._gpio = self._ctx.find_device("cn0579_control")
self._ad5696 = self._ctx.find_device("ad5696")

@property
def shift_voltage0(self):
"""shift_voltage: Shift voltage in mV from AD5696 to bias sensor data"""
dac_chan = self._ad5696
raw = self._get_iio_attr("voltage0", "raw", True, dac_chan)
return raw # * dac_scale * 1.22

@shift_voltage0.setter
def shift_voltage0(self, value):
dac_chan = self._ad5696
self._set_iio_attr_int("voltage0", "raw", True, int(value), dac_chan)

@property
def shift_voltage1(self):
"""shift_voltage: Shift voltage in mV from AD5696 to bias sensor data"""
dac_chan = self._ad5696
raw = self._get_iio_attr("voltage1", "raw", True, dac_chan)
return raw # * dac_scale * 1.22

@shift_voltage1.setter
def shift_voltage1(self, value):
dac_chan = self._ad5696
self._set_iio_attr_int("voltage1", "raw", True, int(value), dac_chan)

@property
def shift_voltage2(self):
"""shift_voltage: Shift voltage in mV from AD5696 to bias sensor data"""
dac_chan = self._ad5696
raw = self._get_iio_attr("voltage2", "raw", True, dac_chan)
return raw # * dac_scale * 1.22

@shift_voltage2.setter
def shift_voltage2(self, value):
dac_chan = self._ad5696
self._set_iio_attr_int("voltage2", "raw", True, int(value), dac_chan)

@property
def shift_voltage3(self):
"""shift_voltage: Shift voltage in mV from AD5696 to bias sensor data"""
dac_chan = self._ad5696
raw = self._get_iio_attr("voltage3", "raw", True, dac_chan)
return raw # * dac_scale * 1.22

@shift_voltage3.setter
def shift_voltage3(self, value):
dac_chan = self._ad5696
self._set_iio_attr_int("voltage3", "raw", True, int(value), dac_chan)

@property
def CC_CH0(self):
"""Get Channel 0 Current Source Control"""
return self._get_iio_attr("voltage0", "raw", True, self._gpio)

@CC_CH0.setter
def CC_CH0(self, value):
"""Set Channel 0 Current Source Control"""
self._set_iio_attr_int("voltage0", "raw", True, value, self._gpio)

@property
def CC_CH1(self):
"""Get Channel 1 Current Source Control"""
return self._get_iio_attr("voltage1", "raw", True, self._gpio)

@CC_CH1.setter
def CC_CH1(self, value):
"""Set Channel 1 Current Source Control"""
self._set_iio_attr_int("voltage1", "raw", True, value, self._gpio)

@property
def CC_CH2(self):
"""Get Channel 2 Current Source Control"""
return self._get_iio_attr("voltage2", "raw", True, self._gpio)

@CC_CH2.setter
def CC_CH2(self, value):
"""Set Channel 2 Current Source Control"""
self._set_iio_attr_int("voltage2", "raw", True, value, self._gpio)

@property
def CC_CH3(self):
"""Get Channel 3 Current Source Control"""
return self._get_iio_attr("voltage3", "raw", True, self._gpio)

@CC_CH3.setter
def CC_CH3(self, value):
"""Set Channel 3 Current Source Control"""
self._set_iio_attr_int("voltage3", "raw", True, value, self._gpio)
7 changes: 7 additions & 0 deletions doc/source/devices/adi.cn0579.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cn0579
=================

.. automodule:: adi.cn0579
: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 @@ -83,6 +83,7 @@ Supported Devices
adi.cn0554
adi.cn0566
adi.cn0575
adi.cn0579
adi.daq2
adi.daq3
adi.fmc_vna
Expand Down
108 changes: 108 additions & 0 deletions examples/cn0579/cn0579_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copyright (C) 2023 Analog Devices, Inc.
#
# SPDX short identifier: ADIBSD

import inspect
import os
import sys

import matplotlib.pyplot as plt
import numpy as np
from adi import cn0579

# Lets try to reuse the ./examples/ad4630/sin_params.py file instead of having
# our own copy. Add path prior to importing sin_params
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
ad4630_dir = os.path.join(parentdir, "ad4630")
sys.path.insert(0, ad4630_dir)

import sin_params # isort:skip

# from save_for_pscope import save_for_pscope

# 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 = cn0579(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 = 256000

# Choose a power mode:
# my_adc.power_mode_avail = 'LOW_POWER_MODE MEDIAN_MODE FAST_MODE'
my_adc.power_mode = "FAST_MODE"

# Choose a filter type:
# my_adc.filter_type_avail = 'WIDEBAND SINC5'
my_adc.filter_type = "WIDEBAND"

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

# Set Shift Voltage:
vshift = 43355
my_adc.shift_voltage0 = vshift
my_adc.shift_voltage1 = vshift
my_adc.shift_voltage2 = vshift
my_adc.shift_voltage3 = vshift

# Current Source for each channel:
my_adc.CC_CH0 = 1
my_adc.CC_CH1 = 1
my_adc.CC_CH2 = 0
my_adc.CC_CH3 = 0

# Verify settings:
print("Power Mode: ", my_adc.power_mode)
print("Sampling Frequency: ", my_adc.sampling_frequency)
print("Filter Type: ", my_adc.filter_type)
print("Enabled Channels: ", my_adc.rx_enabled_channels)
print("Ch0 Shift Voltage: ", my_adc.shift_voltage0)
print("Ch1 Shift Voltage: ", my_adc.shift_voltage1)
print("Ch2 Shift Voltage: ", my_adc.shift_voltage2)
print("Ch3 Shift Voltage: ", my_adc.shift_voltage3)


plt.clf()
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,
)

for ch in my_adc.rx_enabled_channels:
parameters = sin_params.sin_params(data[ch])
snr = parameters[1]
thd = parameters[2]
sinad = parameters[3]
enob = parameters[4]
sfdr = parameters[5]
floor = parameters[6]
print("\nChannel " + str(ch))
print("SNR = " + str(snr))
print("THD = " + str(thd))
print("SINAD = " + str(sinad))
print("ENOB = " + str(enob))
print("SFDR = " + str(sfdr))
print("FLOOR = " + str(floor))

plt.show()

# save_for_pscope("Vshift=" + str(my_adc.shift_voltage2) + "_" + str(my_adc.sampling_frequency) + "_cn0579_data.adc" , 24, True, len(data), "DC0000", "LTC1111", data, data, )
61 changes: 61 additions & 0 deletions examples/cn0579/save_for_scope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright (C) 2023 Analog Devices, Inc.
#
# SPDX short identifier: ADIBSD

import math as m


def save_for_pscope(
out_path, num_bits, is_bipolar, num_samples, dc_num, ltc_num, *data
):
num_channels = len(data)
if num_channels < 0 or num_channels > 16:
raise ValueError("pass in a list for each channel (between 1 and 16)")

full_scale = 1 << num_bits
if is_bipolar:
min_val = -full_scale // 2
max_val = full_scale // 2
else:
min_val = 0
max_val = full_scale

with open(out_path, "w") as out_file:
out_file.write("Version,115\n")
out_file.write(
"Retainers,0,{0:d},{1:d},1024,0,{2:0.15f},1,1\n".format(
num_channels, num_samples, 0.0
)
)
out_file.write("Placement,44,0,1,-1,-1,-1,-1,10,10,1031,734\n")
out_file.write("DemoID," + dc_num + "," + ltc_num + ",0\n")
for i in range(num_channels):
out_file.write(
"RawData,{0:d},{1:d},{2:d},{3:d},{4:d},{5:0.15f},{3:e},{4:e}\n".format(
i + 1, int(num_samples), int(num_bits), min_val, max_val, 1.0
)
)
for samp in range(num_samples):
out_file.write(str(data[0][samp]))
for ch in range(1, num_channels):
out_file.write(", ," + str(data[ch][samp]))
out_file.write("\n")
out_file.write("End\n")


if __name__ == "__main__":
num_bits = 16
num_samples = 65536
channel_1 = [int(8192 * m.cos(0.12 * d)) for d in range(num_samples)]
channel_2 = [int(8192 * m.cos(0.034 * d)) for d in range(num_samples)]

save_for_pscope(
"test.adc",
num_bits,
True,
num_samples,
"DC9876A-A",
"LTC9999",
channel_1,
channel_2,
)
1 change: 1 addition & 0 deletions supported_parts.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
- CN0549
- CN0566
- CN0575
- CN0579
- DAQ2
- DAQ3
- FMCADC3
Expand Down
1 change: 1 addition & 0 deletions test/emu/devices/cn0579.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?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="169.254.92.202 Linux analog 5.10.0-98748-gbbbac949ef39 #11 SMP PREEMPT Fri May 12 07:19:20 EEST 2023 armv7l" ><context-attribute name="hw_carrier" value="Zynq Cora Z7 Development Board" /><context-attribute name="hdl_system_id" value="[cn0579] [sys rom custom string placeholder] on [coraz7s] git branch [cn0579_dev] git [d696cc11d626051df59bd8a216d106a36a2139ba] clean [2023-01-11 07:59:59] UTC" /><context-attribute name="local,kernel" value="5.10.0-98748-gbbbac949ef39" /><context-attribute name="uri" value="ip:169.254.92.202" /><context-attribute name="ip,ip-addr" value="169.254.92.202" /><device id="iio:device1" name="cf_axi_adc" ><channel id="voltage0" type="input" ><scan-element index="0" format="le:s24/32&gt;&gt;0" scale="0.000488" /><attribute name="label" filename="in_voltage0_label" value="ERROR" /><attribute name="scale" filename="in_voltage_scale" value="0.000488281" /></channel><channel id="voltage1" type="input" ><scan-element index="1" format="le:s24/32&gt;&gt;0" scale="0.000488" /><attribute name="label" filename="in_voltage1_label" value="ERROR" /><attribute name="scale" filename="in_voltage_scale" value="0.000488281" /></channel><channel id="voltage2" type="input" ><scan-element index="2" format="le:s24/32&gt;&gt;0" scale="0.000488" /><attribute name="label" filename="in_voltage2_label" value="ERROR" /><attribute name="scale" filename="in_voltage_scale" value="0.000488281" /></channel><channel id="voltage3" type="input" ><scan-element index="3" format="le:s24/32&gt;&gt;0" scale="0.000488" /><attribute name="label" filename="in_voltage3_label" value="ERROR" /><attribute name="scale" filename="in_voltage_scale" value="0.000488281" /></channel><attribute name="filter_type" value="SINC5" /><attribute name="filter_type_available" value="WIDEBAND SINC5" /><attribute name="power_mode" value="FAST_MODE" /><attribute name="power_mode_available" value="LOW_POWER_MODE MEDIAN_MODE FAST_MODE" /><attribute name="sampling_frequency" value="256000" /><attribute name="sampling_frequency_available" value="1000 2000 4000 8000 16000 32000 64000 128000 256000" /><attribute name="sync_start_enable" value="arm" /><attribute name="sync_start_enable_available" value="arm" /><buffer-attribute name="data_available" value="0" /><buffer-attribute name="length_align_bytes" value="16" /><debug-attribute name="pseudorandom_err_check" value="ERROR" /><debug-attribute name="direct_reg_access" value="0x0" /></device><device id="iio:device2" name="xadc" ><channel id="voltage5" name="vccoddr" type="input" ><attribute name="raw" filename="in_voltage5_vccoddr_raw" value="1842" /><attribute name="scale" filename="in_voltage5_vccoddr_scale" value="0.732421875" /></channel><channel id="voltage0" name="vccint" type="input" ><attribute name="raw" filename="in_voltage0_vccint_raw" value="1367" /><attribute name="scale" filename="in_voltage0_vccint_scale" value="0.732421875" /></channel><channel id="voltage4" name="vccpaux" type="input" ><attribute name="raw" filename="in_voltage4_vccpaux_raw" value="2463" /><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="2656" /><attribute name="scale" filename="in_temp0_scale" value="123.040771484" /></channel><channel id="voltage7" name="vrefn" type="input" ><attribute name="raw" filename="in_voltage7_vrefn_raw" value="5" /><attribute name="scale" filename="in_voltage7_vrefn_scale" value="0.732421875" /></channel><channel id="voltage1" name="vccaux" type="input" ><attribute name="raw" filename="in_voltage1_vccaux_raw" value="2465" /><attribute name="scale" filename="in_voltage1_vccaux_scale" value="0.732421875" /></channel><channel id="voltage2" name="vccbram" type="input" ><attribute name="raw" filename="in_voltage2_vccbram_raw" value="1367" /><attribute name="scale" filename="in_voltage2_vccbram_scale" value="0.732421875" /></channel><channel id="voltage3" name="vccpint" type="input" ><attribute name="raw" filename="in_voltage3_vccpint_raw" value="1362" /><attribute name="scale" filename="in_voltage3_vccpint_scale" value="0.732421875" /></channel><channel id="voltage6" name="vrefp" type="input" ><attribute name="raw" filename="in_voltage6_vrefp_raw" value="1710" /><attribute name="scale" filename="in_voltage6_vrefp_scale" value="0.732421875" /></channel><attribute name="sampling_frequency" value="961538" /></device><device id="iio:device3" name="cn0579_control" ><channel id="voltage1" type="output" ><attribute name="label" filename="out_voltage1_label" value="CC_CH1" /><attribute name="raw" filename="out_voltage1_raw" value="0" /></channel><channel id="voltage0" type="output" ><attribute name="label" filename="out_voltage0_label" value="CC_CH0" /><attribute name="raw" filename="out_voltage0_raw" value="0" /></channel><channel id="voltage3" type="output" ><attribute name="label" filename="out_voltage3_label" value="CC_CH3" /><attribute name="raw" filename="out_voltage3_raw" value="0" /></channel><channel id="voltage2" type="output" ><attribute name="label" filename="out_voltage2_label" value="CC_CH2" /><attribute name="raw" filename="out_voltage2_raw" value="0" /></channel></device><device id="iio:device4" name="ad5696" ><channel id="voltage0" type="output" ><scan-element index="0" format="le:U16/16&gt;&gt;0" scale="0.000000" /><attribute name="powerdown" filename="out_voltage0_powerdown" value="0" /><attribute name="powerdown_mode" filename="out_voltage0_powerdown_mode" value="1kohm_to_gnd" /><attribute name="powerdown_mode_available" filename="out_voltage_powerdown_mode_available" value="1kohm_to_gnd 100kohm_to_gnd three_state" /><attribute name="raw" filename="out_voltage0_raw" value="0" /><attribute name="sampling_frequency" filename="out_voltage_sampling_frequency" value="ERROR" /><attribute name="scale" filename="out_voltage_scale" value="0.000000000" /></channel><channel id="voltage1" type="output" ><scan-element index="1" format="le:U16/16&gt;&gt;0" scale="0.000000" /><attribute name="powerdown" filename="out_voltage1_powerdown" value="0" /><attribute name="powerdown_mode" filename="out_voltage1_powerdown_mode" value="1kohm_to_gnd" /><attribute name="powerdown_mode_available" filename="out_voltage_powerdown_mode_available" value="1kohm_to_gnd 100kohm_to_gnd three_state" /><attribute name="raw" filename="out_voltage1_raw" value="0" /><attribute name="sampling_frequency" filename="out_voltage_sampling_frequency" value="ERROR" /><attribute name="scale" filename="out_voltage_scale" value="0.000000000" /></channel><channel id="voltage2" type="output" ><scan-element index="2" format="le:U16/16&gt;&gt;0" scale="0.000000" /><attribute name="powerdown" filename="out_voltage2_powerdown" value="0" /><attribute name="powerdown_mode" filename="out_voltage2_powerdown_mode" value="1kohm_to_gnd" /><attribute name="powerdown_mode_available" filename="out_voltage_powerdown_mode_available" value="1kohm_to_gnd 100kohm_to_gnd three_state" /><attribute name="raw" filename="out_voltage2_raw" value="0" /><attribute name="sampling_frequency" filename="out_voltage_sampling_frequency" value="ERROR" /><attribute name="scale" filename="out_voltage_scale" value="0.000000000" /></channel><channel id="voltage3" type="output" ><scan-element index="3" format="le:U16/16&gt;&gt;0" scale="0.000000" /><attribute name="powerdown" filename="out_voltage3_powerdown" value="0" /><attribute name="powerdown_mode" filename="out_voltage3_powerdown_mode" value="1kohm_to_gnd" /><attribute name="powerdown_mode_available" filename="out_voltage_powerdown_mode_available" value="1kohm_to_gnd 100kohm_to_gnd three_state" /><attribute name="raw" filename="out_voltage3_raw" value="0" /><attribute name="sampling_frequency" filename="out_voltage_sampling_frequency" value="ERROR" /><attribute name="scale" filename="out_voltage_scale" value="0.000000000" /></channel><buffer-attribute name="data_available" value="0" /></device><device id="iio_sysfs_trigger" ><attribute name="add_trigger" value="ERROR" /><attribute name="remove_trigger" value="ERROR" /></device><device id="trigger0" name="ad5696-dev4" ></device></context>
13 changes: 12 additions & 1 deletion test/emu/hardware_map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,18 @@ cn0575:
- filename: cn0575.xml
- data_devices:
- hwmon2
- iio:device0
- iio:device0

cn0579:
- cf_axi_adc
- cn0579_control
- ad5696
- pyadi_iio_class_support:
- cn0579
- emulate:
- filename: cn0579.xml
- data_devices:
- iio:device1

# SOMS
adrv9361:
Expand Down
Loading

0 comments on commit ff613be

Please sign in to comment.