-
Notifications
You must be signed in to change notification settings - Fork 0
/
ad7476.py
116 lines (85 loc) · 3.24 KB
/
ad7476.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from adi.attribute import attribute
from adi.context_manager import context_manager
from adi.rx_tx import rx
import numpy as np
from pyfdt.pyfdt import *
import re
import ad7476_helper
from hrtimer import hrtimer as hrt
class ad7476a(rx, context_manager):
"""AD7476a 12-Bit, 1Msps Serial Sampling ADC
parameters:
uri: type=string
URI of IIO context with AD7476a
"""
_complex_data = False
_rx_channel_names = ["voltage0"]
_rx_data_si_type = float
_device_name = ""
def __init__(self, uri="", device_name="", trigger=""):
self.max_sample_rate = 0
self.spi_max_frequency = 0
self.hrtimer = None
if trigger != "":
self.spi_max_frequency, self.max_sample_rate = self.spi_max_f()
if ad7476_helper.chips[device_name] < self.spi_max_frequency:
raise Exception(
f"{device_name} does not support SPI frequency higher than {ad7476_helper.chips[device_name]}."
)
self.hrtimer = hrt(trigger)
context_manager.__init__(self, uri, self._device_name)
self._ctrl = None
if device_name not in ad7476_helper.chips.keys():
raise Exception(f"Not a compatible device: {device_name}")
# Find the main and trigger devices
self._ctrl = self._ctx.find_device(device_name)
self._rxadc = self._ctx.find_device(device_name)
if not self._ctrl:
raise Exception(f"Cannot find IIO device {device_name}")
if not self._rxadc:
raise Exception(f"Cannot find IIO device {device_name}")
rx.__init__(self)
def spi_max_f(self):
"""find maximum SPI frequency in Devicetree"""
Devicetree = "/sys/firmware/devicetree/base"
pat = re.compile(r".*ad7476.*spi-max-frequency")
pat_value = re.compile(r"[0-9a-fA-F]{8}")
fdt = FdtFsParse(Devicetree)
for path, node in fdt.resolve_path("/").walk():
if pat.match(path):
spi_f = float.fromhex("".join(
pat_value.findall(node.dts_represent())))
max_sr = spi_f / 16.0
return spi_f, max_sr
@property
def lsb_mv(self):
"""Get the LSB in millivolts"""
return self._get_iio_attr("voltage0", "scale", False, self._ctrl)
@property
def voltage(self):
"""Get the voltage reading from the ADC"""
code = self._get_iio_attr("voltage0", "raw", False, self._ctrl)
return code * self.lsb_mv / 1000
@property
def raw(self):
"""AD7476 channel raw value"""
return self._get_iio_attr("voltage0", "raw", False)
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
if __name__ == "__main__":
import ad7476
data = []
target_device = "ad7476a"
ADC = ad7476.ad7476a("local:", target_device)
for k in range(10):
data.append(ADC.voltage)
print(data)