spirack 0.2.9__tar.gz → 0.2.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {spirack-0.2.9 → spirack-0.2.12}/PKG-INFO +1 -1
- spirack-0.2.12/spirack/D4a_module.py +1155 -0
- spirack-0.2.12/spirack/version.py +1 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack.egg-info/PKG-INFO +1 -1
- {spirack-0.2.9 → spirack-0.2.12}/spirack.egg-info/SOURCES.txt +1 -0
- spirack-0.2.9/spirack/version.py +0 -1
- {spirack-0.2.9 → spirack-0.2.12}/LICENSE +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/README.md +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/setup.cfg +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/setup.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/B1b_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/B2b_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/D4_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/D4b_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/D5a_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/D5b_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/F1d_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/M2j_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/M2p_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/P2d_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/S4g_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/S5i_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/S5k_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/S5l_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/U1c_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/U2_module.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/__init__.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/chip_mode.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack/spi_rack.py +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack.egg-info/dependency_links.txt +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack.egg-info/requires.txt +0 -0
- {spirack-0.2.9 → spirack-0.2.12}/spirack.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,1155 @@
|
|
|
1
|
+
"""ADC module D4a interface
|
|
2
|
+
|
|
3
|
+
SPI Rack interface code for the D4 module.
|
|
4
|
+
|
|
5
|
+
Example:
|
|
6
|
+
Example use: ::
|
|
7
|
+
D4a = spirack.D4a_modules(SPI_Rack1, 5)
|
|
8
|
+
|
|
9
|
+
Code version: 10
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .chip_mode import AD7175_MODE, AD7175_SPEED # for ADC
|
|
13
|
+
from .chip_mode import HCT595_MODE, HCT595_SPEED # for SR (shift register)
|
|
14
|
+
from .chip_mode import BICPINS_SPEED # for GPIO
|
|
15
|
+
import time
|
|
16
|
+
|
|
17
|
+
class D4a_module(object):
|
|
18
|
+
"""D4a module interface class
|
|
19
|
+
|
|
20
|
+
This class does the low level interfacing with the D4a module. When creating
|
|
21
|
+
an instance, it requires a SPI_rack class passed as a parameter.
|
|
22
|
+
|
|
23
|
+
The module contains two independent 24-bit analog to digital converters. They
|
|
24
|
+
can be individually configured and triggered. The filter settings determine
|
|
25
|
+
the data rate and resolution. For an overview of settings, see the website.
|
|
26
|
+
|
|
27
|
+
Attributes:
|
|
28
|
+
module (int): module number set by the user (must coincide with hardware)
|
|
29
|
+
filter_setting (int): current filter setting
|
|
30
|
+
filter_type (string): filter type, either sinc3 or sinc5
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, spi_rack, module, switch_delay = 0.1, initialize = 1):
|
|
34
|
+
"""Inits D4a module class
|
|
35
|
+
|
|
36
|
+
The D4a_module class needs an SPI_rack object at initiation. All
|
|
37
|
+
communication will run via that class. At initialization the ADC filters
|
|
38
|
+
will be set to 'sinc3' at 16.67 SPS.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
spi_rack (SPI_rack object): SPI_rack class object via which the communication runs
|
|
42
|
+
module (int): module number set on the hardware
|
|
43
|
+
"""
|
|
44
|
+
self.file = os.path.abspath(__file__)
|
|
45
|
+
print("D4a initialized.\nPath to D4a file is", self.file,"\n") # debug only
|
|
46
|
+
|
|
47
|
+
self.module = module
|
|
48
|
+
self.spi_rack = spi_rack
|
|
49
|
+
|
|
50
|
+
self.reg = AD7175_registers
|
|
51
|
+
|
|
52
|
+
self.filter_setting = None
|
|
53
|
+
self.filter_type = None
|
|
54
|
+
|
|
55
|
+
# remote_settings is a byte containing settings
|
|
56
|
+
# for overload (OL), feedback (FB) and the muxes (1P4T switches).
|
|
57
|
+
# The bit order corresponds to the connectivity of the Shift-Regsiter outputs
|
|
58
|
+
# Bits are:
|
|
59
|
+
#
|
|
60
|
+
# 7 (msb) 6 5 4 3 2 1 0 (lsb)
|
|
61
|
+
#
|
|
62
|
+
# SWB_A0 SWB_A1_0 B_OL SWB_A1_1 SWT_A1_1 SWT_A0 SWT_A1_0 T_OL
|
|
63
|
+
# "Bottom" "Bottom" "Bottom" "Bottom" "Top" "Top" "Top" "Top"
|
|
64
|
+
# 1 0 0 0 0 1 0 0
|
|
65
|
+
#
|
|
66
|
+
self.remote_settings = 0x42 # 0b 0100 0010
|
|
67
|
+
self.spi_rack.write_data(self.module, 2, HCT595_MODE, HCT595_SPEED, bytearray([self.remote_settings]))
|
|
68
|
+
|
|
69
|
+
self.bic_sync_value = 0 # initializing to no sync given
|
|
70
|
+
|
|
71
|
+
self._default_setup() # cont. mode, single cycle, chnn 0 and set-up 0, AIN3-vs-AIN2
|
|
72
|
+
|
|
73
|
+
for adc in range(0, 2):
|
|
74
|
+
|
|
75
|
+
# Check communication with the ADC
|
|
76
|
+
print("\nChecking communication with ADC",adc,":")
|
|
77
|
+
Received_ID = self.get_ADC_ID(adc)
|
|
78
|
+
print(" ADC ID is",Received_ID,
|
|
79
|
+
",",hex(Received_ID),".\n",
|
|
80
|
+
" The expected value is 3294 , 0xCDX.")
|
|
81
|
+
|
|
82
|
+
# Set filter to sinc3 and 20
|
|
83
|
+
self.set_filter(adc, 'sinc3', 20)
|
|
84
|
+
|
|
85
|
+
# Disable sync mode
|
|
86
|
+
self.configure_sync_mode(adc, 0)
|
|
87
|
+
|
|
88
|
+
# Turn off over-load indicators
|
|
89
|
+
self.config_led(adc, 0)
|
|
90
|
+
|
|
91
|
+
self.SR_OEb = 0 # initializing the SR output_enable\ to 'enabled'
|
|
92
|
+
self.set_output_enable(self.SR_OEb)
|
|
93
|
+
|
|
94
|
+
def continuous_conversion_trig_and_read(self, adc):
|
|
95
|
+
"""Perform a conversion
|
|
96
|
+
|
|
97
|
+
Performs a conversion on the given ADC. It will both trigger the ADC and
|
|
98
|
+
wait for the result. Because of this it will block all other operations.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
adc (int:0-1): ADC to perform the conversion
|
|
102
|
+
"""
|
|
103
|
+
self.launch_continuous_conversion(adc)
|
|
104
|
+
return self.get_finalized_result(adc)
|
|
105
|
+
|
|
106
|
+
def single_conversion_trig_and_read(self, adc):
|
|
107
|
+
"""Perform a true-single conversion
|
|
108
|
+
|
|
109
|
+
Performs a conversion on the given ADC. It will both trigger the ADC for one
|
|
110
|
+
conversion only (single- vs. continuous-mode ) and wait for its result.
|
|
111
|
+
Because of this it will block all other operations.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
adc (int:0-1): ADC to perform the conversion
|
|
115
|
+
"""
|
|
116
|
+
self.launch_one_conversion(adc)
|
|
117
|
+
return self.get_finalized_result(adc)
|
|
118
|
+
|
|
119
|
+
def launch_continuous_conversion(self, adc):
|
|
120
|
+
"""Triggers a continuous conversion
|
|
121
|
+
|
|
122
|
+
Triggers a conversion on the given ADC. Does not wait for the result. This
|
|
123
|
+
should be used if multiple devices/adcs need to convert in parallel. After the conversion
|
|
124
|
+
is done it will immediately continue doing conversions and updating the
|
|
125
|
+
output.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
adc (int:0-1): ADC to perform the conversion
|
|
129
|
+
"""
|
|
130
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
131
|
+
(0<<self.reg.MODE) |
|
|
132
|
+
(1<<self.reg.SING_CYC))
|
|
133
|
+
|
|
134
|
+
def launch_one_conversion(self, adc):
|
|
135
|
+
"""Triggers a single conversion
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
adc (int:0-1): ADC to perform the conversion
|
|
139
|
+
"""
|
|
140
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
141
|
+
(1<<self.reg.MODE) |
|
|
142
|
+
(1<<self.reg.SING_CYC))
|
|
143
|
+
|
|
144
|
+
def get_finalized_result(self, adc):
|
|
145
|
+
"""Returns the result of a conversion
|
|
146
|
+
|
|
147
|
+
Returns the result from an executed conversion. The function will wait until the
|
|
148
|
+
result is present, therefore it will block all other operations.
|
|
149
|
+
|
|
150
|
+
It will return the last conversion result. If the time between the launching the conversion
|
|
151
|
+
and reading the result is too long, the result may be of a second/third conversion. (in
|
|
152
|
+
continuous mode, where the ADC keeps converting and updating the data output)
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
adc (int:0-1): ADC to readout
|
|
156
|
+
Returns:
|
|
157
|
+
ADC measured voltage (float)
|
|
158
|
+
"""
|
|
159
|
+
self.wait_for_data(adc)
|
|
160
|
+
raw_res = self.force_immediate_read_out(adc)
|
|
161
|
+
checked_res = self.overload_check(adc, raw_res)
|
|
162
|
+
return checked_res
|
|
163
|
+
|
|
164
|
+
def wait_for_data(self, adc):
|
|
165
|
+
"""Pauses further execution until current conversion is completed
|
|
166
|
+
"""
|
|
167
|
+
running = True
|
|
168
|
+
while running:
|
|
169
|
+
status = self._read_RDYb_bit(adc)
|
|
170
|
+
# if new data available:
|
|
171
|
+
if status == 0:
|
|
172
|
+
running = False
|
|
173
|
+
return
|
|
174
|
+
|
|
175
|
+
def _read_RDYb_bit(self, adc):
|
|
176
|
+
"""reads out the RDYb bit from the specified ADC
|
|
177
|
+
"""
|
|
178
|
+
status = self._read_data(adc, self.reg.STATUS_REG, 1)
|
|
179
|
+
RDYb = status[0]&0x80
|
|
180
|
+
return RDYb
|
|
181
|
+
|
|
182
|
+
def force_immediate_read_out(self, adc):
|
|
183
|
+
"""Reads the ADC data output register, regardless of its RDY/complete status
|
|
184
|
+
|
|
185
|
+
Get raw data, shift it to correct place, and convert to voltage
|
|
186
|
+
Args:
|
|
187
|
+
adc (int:0-1): ADC to readout
|
|
188
|
+
Returns:
|
|
189
|
+
ADC measured voltage (float)
|
|
190
|
+
force_read_out = force_get_results
|
|
191
|
+
"""
|
|
192
|
+
raw_data = self._read_data(adc, self.reg.DATA_REG, 3)
|
|
193
|
+
raw_data = raw_data[1:]
|
|
194
|
+
raw_data_val = raw_data[0] << 16 | raw_data[1] << 8 | raw_data[2]
|
|
195
|
+
return self.calculate_ADC_voltage_from_ADC_binary(raw_data_val)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def calculate_ADC_voltage_from_ADC_binary(self, bin_data):
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
"""
|
|
202
|
+
return (bin_data * 2 * 0.875 / 2**22) - 3.5 # D4a v2-1 using a 3.5V reference
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def overload_check(self, adc, raw_res):
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
"""
|
|
209
|
+
if (raw_res > 3.999999 or raw_res < -3.994):
|
|
210
|
+
# Indicate overload condition to user:
|
|
211
|
+
# print warning, turn on LED until reset by user, and replace result
|
|
212
|
+
print(" Warning: result", raw_res,"is outside the supported range.\n Data will be replaced by '999'")
|
|
213
|
+
self.config_led(adc, 1)
|
|
214
|
+
return 999
|
|
215
|
+
else:
|
|
216
|
+
return raw_res
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def config_led(self, led, on_off):
|
|
220
|
+
"""
|
|
221
|
+
"""
|
|
222
|
+
if led not in range(2):
|
|
223
|
+
raise ValueError('LED number {} does not exist. Possible values are 0 and 1.'.format(adc))
|
|
224
|
+
if on_off not in range(2):
|
|
225
|
+
raise ValueError('Value {} is not legal for LED setting. Requiring a Bool value.'.format(on_off))
|
|
226
|
+
|
|
227
|
+
if (led==0):
|
|
228
|
+
# Setting the 'Top' mux
|
|
229
|
+
self.remote_settings &= 0xfe # reset SR bit 0 (T_OL)
|
|
230
|
+
mux_new_settings = on_off<<0 # shift new val to bit 0
|
|
231
|
+
elif (led==1):
|
|
232
|
+
# Setting the 'Bottom' mux
|
|
233
|
+
self.remote_settings &= 0xDf # reset SR bit 5 (B_OL)
|
|
234
|
+
mux_new_settings = on_off<<5 # shift new val to bit 5
|
|
235
|
+
self.remote_settings |= mux_new_settings
|
|
236
|
+
self.spi_rack.write_data(self.module, 2, HCT595_MODE, HCT595_SPEED, bytearray([self.remote_settings]))
|
|
237
|
+
|
|
238
|
+
def select_measurement_type(self, adc, measurement_type):
|
|
239
|
+
"""Sets the D4a input-path mux
|
|
240
|
+
(connects the selected signal to the selected ADC)
|
|
241
|
+
and updates the 'remote_settings' byte
|
|
242
|
+
|
|
243
|
+
Options are 0 - GND, 1 - cal ref level , 2 - internal header pin, 3 - front-panel connector
|
|
244
|
+
|
|
245
|
+
Formerly called 'config_mux' (a.k.a. 'connect_signals_to_adc')
|
|
246
|
+
"""
|
|
247
|
+
# input checks
|
|
248
|
+
if adc not in range(2):
|
|
249
|
+
raise ValueError('ADC number {} does not exist. Possible values are 0 and 1.'.format(adc))
|
|
250
|
+
|
|
251
|
+
self.measurement_types = ['single-ended calibration','differential calibration',
|
|
252
|
+
'single-ended measurement','grounding',
|
|
253
|
+
'back-panel single-ended measurement','back-panel complementary single-ended measurement',
|
|
254
|
+
'back-panel differential measurement',
|
|
255
|
+
'test_msb_is_1','test_lsb_is_1']
|
|
256
|
+
if measurement_type not in self.measurement_types:
|
|
257
|
+
raise ValueError('Measurement type \'{}\' does not exist. \nPossible values are {}.'.format(measurement_type,self.measurement_types))
|
|
258
|
+
|
|
259
|
+
print("select_measurement_type:",
|
|
260
|
+
"\n Instruction was given for ADC",adc,
|
|
261
|
+
"\n Initial SR remote_settings is",self.remote_settings,
|
|
262
|
+
"\n (as bits:",bin(self.remote_settings),")") # debug
|
|
263
|
+
|
|
264
|
+
if (adc==0):
|
|
265
|
+
# Setting the 'Top' mux
|
|
266
|
+
if (measurement_type=='test_lsb_is_1'):
|
|
267
|
+
self.remote_settings = 0x01 # testing only (used for debug)
|
|
268
|
+
if (measurement_type=='test_msb_is_1'):
|
|
269
|
+
self.remote_settings = 0x08 # testing only (used for debug)
|
|
270
|
+
if (measurement_type=='single-ended calibration'):
|
|
271
|
+
#SWT_A0,A1_0,A1_1: 0 0 0
|
|
272
|
+
self.remote_settings &= 0xfb # config SWT_A0 (bit 2)
|
|
273
|
+
self.remote_settings &= 0xfd # config SWT_A1_0 (bit 1)
|
|
274
|
+
self.remote_settings &= 0xf7 # config SWT_A1_1 (bit 3)
|
|
275
|
+
if (measurement_type=='differential calibration'):
|
|
276
|
+
#SWT_A0,A1_0,A1_1: 0 0 1
|
|
277
|
+
self.remote_settings &= 0xfb # config SWT_A0 (bit 2)
|
|
278
|
+
self.remote_settings &= 0xfd # config SWT_A1_0 (bit 1)
|
|
279
|
+
self.remote_settings |= 0x08 # config SWT_A1_1 (bit 3)
|
|
280
|
+
if (measurement_type=='single-ended measurement'):
|
|
281
|
+
#SWT_A0,A1_0,A1_1: 0 1 0
|
|
282
|
+
self.remote_settings &= 0xfb # config SWT_A0 (bit 2)
|
|
283
|
+
self.remote_settings |= 0x02 # config SWT_A1_0 (bit 1)
|
|
284
|
+
self.remote_settings &= 0xf7 # config SWT_A1_1 (bit 3)
|
|
285
|
+
if (measurement_type=='grounding'):
|
|
286
|
+
#SWT_A0,A1_0,A1_1: 1 0 0
|
|
287
|
+
self.remote_settings |= 0x04 # config SWT_A0 (bit 2)
|
|
288
|
+
self.remote_settings &= 0xfd # config SWT_A1_0 (bit 1)
|
|
289
|
+
self.remote_settings &= 0xf7 # config SWT_A1_1 (bit 3)
|
|
290
|
+
if (measurement_type=='back-panel single-ended measurement'):
|
|
291
|
+
#SWT_A0,A1_0,A1_1: 1 1 0
|
|
292
|
+
self.remote_settings |= 0x04 # config SWT_A0 (bit 2)
|
|
293
|
+
self.remote_settings |= 0x02 # config SWT_A1_0 (bit 1)
|
|
294
|
+
self.remote_settings &= 0xf7 # config SWT_A1_1 (bit 3)
|
|
295
|
+
if (measurement_type=='back-panel complementary single-ended measurement'):
|
|
296
|
+
#SWT_A0,A1_0,A1_1: 1 0 1
|
|
297
|
+
self.remote_settings |= 0x04 # config SWT_A0 (bit 2)
|
|
298
|
+
self.remote_settings &= 0xfd # config SWT_A1_0 (bit 1)
|
|
299
|
+
self.remote_settings |= 0x08 # config SWT_A1_1 (bit 3)
|
|
300
|
+
if (measurement_type=='back-panel differential measurement'):
|
|
301
|
+
#SWT_A0,A1_0,A1_1: 1 1 1
|
|
302
|
+
self.remote_settings |= 0x04 # config SWT_A0 (bit 2)
|
|
303
|
+
self.remote_settings |= 0x02 # config SWT_A1_0 (bit 1)
|
|
304
|
+
self.remote_settings |= 0x08 # config SWT_A1_1 (bit 3)
|
|
305
|
+
if (adc==1):
|
|
306
|
+
# Setting the 'Bottom' mux
|
|
307
|
+
if (measurement_type=='test_lsb_is_1'):
|
|
308
|
+
self.remote_settings = 0x10 # testing only (used for debug)
|
|
309
|
+
if (measurement_type=='test_msb_is_1'):
|
|
310
|
+
self.remote_settings = 0x80 # testing only (used for debug)
|
|
311
|
+
if (measurement_type=='single-ended calibration'):
|
|
312
|
+
#SWB_A0,A1_0,A1_1: 0 0 0
|
|
313
|
+
self.remote_settings &= 0x7f # config SWB_A0 (bit 7)
|
|
314
|
+
self.remote_settings &= 0xbf # config SWB_A1_0 (bit 6)
|
|
315
|
+
self.remote_settings &= 0xef # config SWB_A1_1 (bit 4)
|
|
316
|
+
if (measurement_type=='differential calibration'):
|
|
317
|
+
#SWB_A0,A1_0,A1_1: 0 0 1
|
|
318
|
+
self.remote_settings &= 0x7f # config SWB_A0 (bit 7)
|
|
319
|
+
self.remote_settings &= 0xbf # config SWB_A1_0 (bit 6)
|
|
320
|
+
self.remote_settings |= 0x10 # config SWB_A1_1 (bit 4)
|
|
321
|
+
if (measurement_type=='single-ended measurement'):
|
|
322
|
+
#SWB_A0,A1_0,A1_1: 0 1 0
|
|
323
|
+
self.remote_settings &= 0x7f # config SWB_A0 (bit 7)
|
|
324
|
+
self.remote_settings |= 0x40 # config SWB_A1_0 (bit 6)
|
|
325
|
+
self.remote_settings &= 0xef # config SWB_A1_1 (bit 4)
|
|
326
|
+
if (measurement_type=='grounding'):
|
|
327
|
+
#SWB_A0,A1_0,A1_1: 1 0 0
|
|
328
|
+
self.remote_settings |= 0x80 # config SWB_A0 (bit 7)
|
|
329
|
+
self.remote_settings &= 0xbf # config SWB_A1_0 (bit 6)
|
|
330
|
+
self.remote_settings &= 0xef # config SWB_A1_1 (bit 4)
|
|
331
|
+
if (measurement_type=='back-panel single-ended measurement'):
|
|
332
|
+
#SWB_A0,A1_0,A1_1: 1 1 0
|
|
333
|
+
self.remote_settings |= 0x80 # config SWB_A0 (bit 7)
|
|
334
|
+
self.remote_settings |= 0x40 # config SWB_A1_0 (bit 6)
|
|
335
|
+
self.remote_settings &= 0xef # config SWB_A1_1 (bit 4)
|
|
336
|
+
if (measurement_type=='back-panel complementary single-ended measurement'):
|
|
337
|
+
#SWB_A0,A1_0,A1_1: 1 0 1
|
|
338
|
+
self.remote_settings |= 0x80 # config SWB_A0 (bit 7)
|
|
339
|
+
self.remote_settings &= 0xbf # config SWB_A1_0 (bit 6)
|
|
340
|
+
self.remote_settings |= 0x10 # config SWB_A1_1 (bit 4)
|
|
341
|
+
if (measurement_type=='back-panel differential measurement'):
|
|
342
|
+
#SWB_A0,A1_0,A1_1: 1 1 1
|
|
343
|
+
self.remote_settings |= 0x8f # config SWB_A0 (bit 7)
|
|
344
|
+
self.remote_settings |= 0x4f # config SWB_A1_0 (bit 6)
|
|
345
|
+
self.remote_settings |= 0x1f # config SWB_A1_1 (bit 4)
|
|
346
|
+
|
|
347
|
+
# finaly, write the data
|
|
348
|
+
self.spi_rack.write_data(self.module, 2, HCT595_MODE, HCT595_SPEED, bytearray([self.remote_settings]))
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def select_ADC_inputs(self, adc, pos_input_name, neg_input_name):
|
|
352
|
+
"""Set the ADCs to read from desired line
|
|
353
|
+
|
|
354
|
+
This updates the config resgisters on the ADC chip itself.
|
|
355
|
+
|
|
356
|
+
Args:
|
|
357
|
+
adc (int:0-1): ADC which receives the signal to sample
|
|
358
|
+
pos_input_name: the D4a internal signal used as the non-inverting signal
|
|
359
|
+
neg_input_name: the D4a internal signal used as the inverting signal
|
|
360
|
+
(see numbering of connectors on front-panel)
|
|
361
|
+
"""
|
|
362
|
+
# input checks
|
|
363
|
+
if (pos_input_name == neg_input_name):
|
|
364
|
+
raise ValueError('Cannot set both phases to the same value. Requested set for pos_input_line and neg_input_line was {}'.format(pos_input_name))
|
|
365
|
+
accepted_names = ['REF-', 'REF+', 'POS', 'NEG', 'gnd']
|
|
366
|
+
if pos_input_name not in accepted_names:
|
|
367
|
+
raise ValueError('pos_input_line {} does not exist.'.format(pos_input_name))
|
|
368
|
+
if neg_input_name not in accepted_names:
|
|
369
|
+
raise ValueError('neg_input_line {} does not exist.'.format(neg_input_name))
|
|
370
|
+
|
|
371
|
+
# choosing the non-inverting ("positive") signal
|
|
372
|
+
if (pos_input_name=='REF-'):
|
|
373
|
+
# Set the ADC positive to read REF-
|
|
374
|
+
self.read_modify_write_CH0_AINPOS0(adc, 22)
|
|
375
|
+
elif (pos_input_name=='REF+'):
|
|
376
|
+
# Set the ADC positive to read REF+
|
|
377
|
+
self.read_modify_write_CH0_AINPOS0(adc, 21)
|
|
378
|
+
elif (pos_input_name=='NEG'):
|
|
379
|
+
# Set the ADC positive to read from AIN2
|
|
380
|
+
self.read_modify_write_CH0_AINPOS0(adc, 2)
|
|
381
|
+
elif (pos_input_name=='POS'):
|
|
382
|
+
# Set the ADC positive to read from AIN3
|
|
383
|
+
self.read_modify_write_CH0_AINPOS0(adc, 3)
|
|
384
|
+
elif (pos_input_name=='gnd'):
|
|
385
|
+
# Set the ADC positive to read from AIN4
|
|
386
|
+
self.read_modify_write_CH0_AINPOS0(adc, 4)
|
|
387
|
+
|
|
388
|
+
# choosing the inverting ("negative") signal
|
|
389
|
+
if (neg_input_name=='REF-'):
|
|
390
|
+
# Set the ADC negative to read REF-
|
|
391
|
+
self.read_modify_write_CH0_AINNEG0(adc, 22)
|
|
392
|
+
elif (neg_input_name=='REF+'):
|
|
393
|
+
# Set the ADC negative to read REF+
|
|
394
|
+
self.read_modify_write_CH0_AINNEG0(adc, 21)
|
|
395
|
+
elif (neg_input_name=='NEG'):
|
|
396
|
+
# Set the ADC negative to read from AIN2
|
|
397
|
+
self.read_modify_write_CH0_AINNEG0(adc, 2)
|
|
398
|
+
elif (neg_input_name=='POS'):
|
|
399
|
+
# Set the ADC negative to read from AIN3
|
|
400
|
+
self.read_modify_write_CH0_AINNEG0(adc, 3)
|
|
401
|
+
elif (neg_input_name=='gnd'):
|
|
402
|
+
# Set the ADC negative to read from AIN4
|
|
403
|
+
self.read_modify_write_CH0_AINNEG0(adc, 4)
|
|
404
|
+
|
|
405
|
+
return
|
|
406
|
+
|
|
407
|
+
def read_modify_write_CH0_AINPOS0(self, adc, adc_ain_pin):
|
|
408
|
+
"""
|
|
409
|
+
"""
|
|
410
|
+
CH0_REG_data = self._read_data(adc, self.reg.CH0_REG, 2)
|
|
411
|
+
CH0_REG_data = CH0_REG_data[1:]
|
|
412
|
+
|
|
413
|
+
# AINPOS0 - update
|
|
414
|
+
byte0 = CH0_REG_data[0]&0xfc # clear 2 lsbs
|
|
415
|
+
byte0_new_2msbs = ((adc_ain_pin&0x18)>>3) # calculate new 2 lsbs
|
|
416
|
+
byte0 |= byte0_new_2msbs # place new lsbs into the 2 lsb positions
|
|
417
|
+
byte1 = CH0_REG_data[1]&0x1f # clear 3 msbs
|
|
418
|
+
byte1_new_3lsbs = (adc_ain_pin&0x07)<<5 # calculate new 3 msbs
|
|
419
|
+
byte1 |= byte1_new_3lsbs # place new msbs into the 3 msb positions
|
|
420
|
+
|
|
421
|
+
wr_data = byte0<<8 | byte1
|
|
422
|
+
self._write_data_16(adc, self.reg.CH0_REG, wr_data)
|
|
423
|
+
|
|
424
|
+
def read_modify_write_CH0_AINNEG0(self, adc, adc_ain_pin):
|
|
425
|
+
"""
|
|
426
|
+
"""
|
|
427
|
+
CH0_REG_data = self._read_data(adc, self.reg.CH0_REG, 2)
|
|
428
|
+
CH0_REG_data = CH0_REG_data[1:]
|
|
429
|
+
|
|
430
|
+
# AINNEG0 - update
|
|
431
|
+
byte0 = CH0_REG_data[0]
|
|
432
|
+
byte1 = CH0_REG_data[1]&0xe0 # clear 5 lsbs
|
|
433
|
+
byte1_new_5lsbs = (adc_ain_pin&0x1f) # calculate new 5 lsbs
|
|
434
|
+
byte1 |= byte1_new_5lsbs # place new lsbs into the 5 lsb positions
|
|
435
|
+
|
|
436
|
+
wr_data = byte0<<8 | byte1
|
|
437
|
+
self._write_data_16(adc, self.reg.CH0_REG, wr_data)
|
|
438
|
+
|
|
439
|
+
def set_single_cycle(self, adc, sing_cyc):
|
|
440
|
+
"""
|
|
441
|
+
"""
|
|
442
|
+
# input checks
|
|
443
|
+
if adc not in range(2):
|
|
444
|
+
raise ValueError('ADC number {} does not exist. Possible values are 0 and 1.'.format(adc))
|
|
445
|
+
if sing_cyc not in [0,1]:
|
|
446
|
+
raise ValueError('The bit value {} does not exist. Possible values are 0 or 1'.format(sing_cyc))
|
|
447
|
+
|
|
448
|
+
ADCMODE_data = self._read_data(adc, self.reg.adcMODE_REG, 2)
|
|
449
|
+
ADCMODE_data = ADCMODE_data[1:]
|
|
450
|
+
|
|
451
|
+
byte0 = ADCMODE_data[0] & 0xdf # clear existing ref buffer setting
|
|
452
|
+
buf_bit = (sing_cyc & 0xff) << 5 # calculate new bit
|
|
453
|
+
byte0 |= buf_bit # place new bits into position
|
|
454
|
+
byte1 = ADCMODE_data[1]
|
|
455
|
+
|
|
456
|
+
wr_data = byte0<<8 | byte1
|
|
457
|
+
self._write_data_16(adc, self.reg.adcMODE_REG, wr_data)
|
|
458
|
+
|
|
459
|
+
def set_ref_input_buffers(self, adc, buf_setting):
|
|
460
|
+
"""
|
|
461
|
+
"""
|
|
462
|
+
# input checks
|
|
463
|
+
if adc not in range(2):
|
|
464
|
+
raise ValueError('ADC number {} does not exist. Possible values are 0 and 1.'.format(adc))
|
|
465
|
+
if buf_setting not in ['enabled','disabled']:
|
|
466
|
+
raise ValueError("ADC number {} does not exist. Possible values are 'enabled','disabled'".format(buf_setting[0],buf_setting[1]))
|
|
467
|
+
|
|
468
|
+
SETUPCON0_data = self._read_data(adc, self.reg.SETUPCON0_REG, 2)
|
|
469
|
+
SETUPCON0_data = SETUPCON0_data[1:]
|
|
470
|
+
|
|
471
|
+
if (buf_setting=='enabled'):
|
|
472
|
+
wr_bit = 1
|
|
473
|
+
elif (buf_setting=='disabled'):
|
|
474
|
+
wr_bit = 0
|
|
475
|
+
else:
|
|
476
|
+
print("Error")
|
|
477
|
+
|
|
478
|
+
byte0 = SETUPCON0_data[0] & 0xf3 # clear existing ref buffer setting
|
|
479
|
+
buf_bits = ((wr_bit*3) & 0xff) << 2 # calculate 2 new bits
|
|
480
|
+
byte0 |= buf_bits # place new bits into position
|
|
481
|
+
byte1 = SETUPCON0_data[1]
|
|
482
|
+
|
|
483
|
+
wr_data = byte0<<8 | byte1
|
|
484
|
+
self._write_data_16(adc, self.reg.SETUPCON0_REG, wr_data)
|
|
485
|
+
|
|
486
|
+
def set_anlg_input_buffers(self, adc, buf_setting):
|
|
487
|
+
"""
|
|
488
|
+
"""
|
|
489
|
+
# input checks
|
|
490
|
+
if adc not in range(2):
|
|
491
|
+
raise ValueError('ADC number {} does not exist. Possible values are 0 and 1.'.format(adc))
|
|
492
|
+
if buf_setting not in ['enabled','disabled']:
|
|
493
|
+
raise ValueError('ADC number {} does not exist. Possible values are {} and {}.'.format(buf_setting[0],buf_setting[1]))
|
|
494
|
+
|
|
495
|
+
SETUPCON0_data = self._read_data(adc, self.reg.SETUPCON0_REG, 2)
|
|
496
|
+
SETUPCON0_data = SETUPCON0_data[1:]
|
|
497
|
+
|
|
498
|
+
if (buf_setting=='enabled'):
|
|
499
|
+
wr_bit = 1
|
|
500
|
+
elif (buf_setting=='disabled'):
|
|
501
|
+
wr_bit = 0
|
|
502
|
+
else:
|
|
503
|
+
print("Error")
|
|
504
|
+
|
|
505
|
+
byte0 = SETUPCON0_data[0] & 0xfc # clear existing ref buffer setting
|
|
506
|
+
buf_bits = ((wr_bit*3) & 0xff) # calculate 2 new bits
|
|
507
|
+
byte0 |= buf_bits # place new bits into position
|
|
508
|
+
byte1 = SETUPCON0_data[1]
|
|
509
|
+
|
|
510
|
+
wr_data = byte0<<8 | byte1
|
|
511
|
+
self._write_data_16(adc, self.reg.SETUPCON0_REG, wr_data)
|
|
512
|
+
|
|
513
|
+
def save_remote_settings(self):
|
|
514
|
+
"""
|
|
515
|
+
"""
|
|
516
|
+
initial_settings = self.remote_settings
|
|
517
|
+
filter_setting = self.filter_setting
|
|
518
|
+
filter_type = self.filter_type
|
|
519
|
+
return([initial_settings, filter_setting, filter_type])
|
|
520
|
+
|
|
521
|
+
def restore_remote_settings(self, adc, initial_conditions):
|
|
522
|
+
"""
|
|
523
|
+
"""
|
|
524
|
+
|
|
525
|
+
# Restore remote settings
|
|
526
|
+
initial_settings = initial_conditions[0]
|
|
527
|
+
self.remote_settings = initial_settings
|
|
528
|
+
self.spi_rack.write_data(self.module, 2, HCT595_MODE, HCT595_SPEED, bytearray([self.remote_settings]))
|
|
529
|
+
|
|
530
|
+
# Restore filter settings
|
|
531
|
+
filter_setting = initial_conditions[1]
|
|
532
|
+
filter_type = initial_conditions[2]
|
|
533
|
+
self.set_filter(adc, filter_type, filter_setting)
|
|
534
|
+
|
|
535
|
+
def offset_calibration_with_module_reference(self, adc):
|
|
536
|
+
"""Offset voltage calibration routine
|
|
537
|
+
|
|
538
|
+
Calibrates the offset of the given ADC input.
|
|
539
|
+
This uses the internal GND, so no need to short on front-panel.
|
|
540
|
+
|
|
541
|
+
Args:
|
|
542
|
+
adc (int:0-1): ADC to calibrate
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
# Save initial remote settings
|
|
546
|
+
initial_settings = self.remote_settings
|
|
547
|
+
# Save filter settings
|
|
548
|
+
filter_setting = self.filter_setting
|
|
549
|
+
filter_type = self.filter_type
|
|
550
|
+
|
|
551
|
+
# Set calibration conditions
|
|
552
|
+
# Setting input to GND
|
|
553
|
+
self.select_measurement_type(0, 'grounding')
|
|
554
|
+
# Set to best performance for offset calibration
|
|
555
|
+
self.set_filter(adc, 'sinc3', 20)
|
|
556
|
+
|
|
557
|
+
# Calibrate
|
|
558
|
+
# 6 is 'System offset calibration' - valid for the present channel and configuration
|
|
559
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
560
|
+
(6<<self.reg.MODE) |
|
|
561
|
+
(1<<self.reg.SING_CYC))
|
|
562
|
+
self.wait_for_data(adc)
|
|
563
|
+
# 0 is 'Continuous conversion mode'
|
|
564
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
565
|
+
(0<<self.reg.MODE) |
|
|
566
|
+
(1<<self.reg.SING_CYC))
|
|
567
|
+
|
|
568
|
+
# Restore filter settings
|
|
569
|
+
self.set_filter(adc, filter_type, filter_setting)
|
|
570
|
+
# Restore remote settings
|
|
571
|
+
self.remote_settings = initial_settings
|
|
572
|
+
self.spi_rack.write_data(self.module, 2, HCT595_MODE, HCT595_SPEED, bytearray([self.remote_settings]))
|
|
573
|
+
|
|
574
|
+
def offset_calibration_with_external_reference(self, adc):
|
|
575
|
+
"""Offset voltage calibration routine
|
|
576
|
+
|
|
577
|
+
Calibrates the offset of the given ADC input. To run this routine, put
|
|
578
|
+
a short or 50 Ohm short on the input of the given ADC.
|
|
579
|
+
|
|
580
|
+
Args:
|
|
581
|
+
adc (int:0-1): ADC to calibrate
|
|
582
|
+
"""
|
|
583
|
+
print('Make sure that ADC{} inputs are terminated with a short or 50 Ohm to GND'
|
|
584
|
+
'while running this calibration!'.format(adc+1))
|
|
585
|
+
|
|
586
|
+
# Save initial conditions
|
|
587
|
+
initial_conditions = self.save_remote_settings()
|
|
588
|
+
|
|
589
|
+
# Set calibration conditions
|
|
590
|
+
# Setting input to 'single-ended measurement'
|
|
591
|
+
self.select_measurement_type(adc, 'single-ended measurement')
|
|
592
|
+
# set to best performance for offset calibration
|
|
593
|
+
self.set_filter(adc, 'sinc3', 20)
|
|
594
|
+
|
|
595
|
+
# Calibrate
|
|
596
|
+
# 6 is 'System offset calibration' - valid for the present channel and configuration
|
|
597
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
598
|
+
(6<<self.reg.MODE) |
|
|
599
|
+
(1<<self.reg.SING_CYC))
|
|
600
|
+
self.wait_for_data(adc)
|
|
601
|
+
# 0 is 'Continuous conversion mode'
|
|
602
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
603
|
+
(0<<self.reg.MODE) |
|
|
604
|
+
(1<<self.reg.SING_CYC))
|
|
605
|
+
|
|
606
|
+
# Restore initial conditions
|
|
607
|
+
self.restore_remote_settings(adc, initial_conditions)
|
|
608
|
+
|
|
609
|
+
def gain_calibration_with_module_reference(self, adc):
|
|
610
|
+
"""Gain calibration routine
|
|
611
|
+
|
|
612
|
+
Calibrates the gain of the given ADC input.
|
|
613
|
+
This uses the in-module CAL_REF, so no need for connection on front-panel.
|
|
614
|
+
Sets the input-path mux to the 'CAL_REF' position,
|
|
615
|
+
and then restores its initial connection.
|
|
616
|
+
|
|
617
|
+
Args:
|
|
618
|
+
adc (int:0-1): ADC to calibrate
|
|
619
|
+
"""
|
|
620
|
+
# Save initial remote settings
|
|
621
|
+
initial_settings = self.remote_settings
|
|
622
|
+
# Save filter settings
|
|
623
|
+
filter_setting = self.filter_setting
|
|
624
|
+
filter_type = self.filter_type
|
|
625
|
+
|
|
626
|
+
# Set calibration conditions
|
|
627
|
+
# Setting input to CAL_REF
|
|
628
|
+
self.select_measurement_type(0, 'single-ended calibration')
|
|
629
|
+
|
|
630
|
+
# set to best performance for offset calibration
|
|
631
|
+
self.set_filter(adc, 'sinc3', 20)
|
|
632
|
+
|
|
633
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
634
|
+
(7<<self.reg.MODE) |
|
|
635
|
+
(1<<self.reg.SING_CYC))
|
|
636
|
+
self.wait_for_data(adc)
|
|
637
|
+
|
|
638
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
639
|
+
(0<<self.reg.MODE) |
|
|
640
|
+
(1<<self.reg.SING_CYC))
|
|
641
|
+
#self.add_to_GAIN0(adc, -3700) # was -10900 in D4 TEMP COMMENTED
|
|
642
|
+
|
|
643
|
+
# Restore filter settings
|
|
644
|
+
self.set_filter(adc, filter_type, filter_setting)
|
|
645
|
+
# Restore remote settings
|
|
646
|
+
self.remote_settings = initial_settings
|
|
647
|
+
self.spi_rack.write_data(self.module, 2, HCT595_MODE, HCT595_SPEED, bytearray([self.remote_settings]))
|
|
648
|
+
|
|
649
|
+
def gain_calibration_with_external_reference(self, adc):
|
|
650
|
+
"""Gain calibration routine
|
|
651
|
+
|
|
652
|
+
Calibrates the gain of the given ADC input. To run this routine, apply
|
|
653
|
+
4V on the input of the given ADC using a D5a.
|
|
654
|
+
|
|
655
|
+
Args:
|
|
656
|
+
adc (int:0-1): ADC to calibrate
|
|
657
|
+
"""
|
|
658
|
+
print('Make sure that ADC {} input is set to the experiment full-scale (using a precise voltage source)!\n',
|
|
659
|
+
'For the general case use the D4a maximum scale of 3.5V.'.format(adc)) # prev. we printed 'adc' without adc+1
|
|
660
|
+
|
|
661
|
+
# Save initial conditions
|
|
662
|
+
initial_conditions = self.save_remote_settings()
|
|
663
|
+
|
|
664
|
+
# Set calibration conditions
|
|
665
|
+
# Setting input to 'single-ended measurement'
|
|
666
|
+
self.select_measurement_type(adc, 'single-ended measurement')
|
|
667
|
+
|
|
668
|
+
# set to best performance for offset calibration
|
|
669
|
+
self.set_filter(adc, 'sinc3', 20)
|
|
670
|
+
|
|
671
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
672
|
+
(7<<self.reg.MODE) |
|
|
673
|
+
(1<<self.reg.SING_CYC))
|
|
674
|
+
self.wait_for_data(adc)
|
|
675
|
+
|
|
676
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
677
|
+
(0<<self.reg.MODE) |
|
|
678
|
+
(1<<self.reg.SING_CYC))
|
|
679
|
+
#self.add_to_GAIN0(adc, -3700) # was -10900 in D4 TEMP COMMENTED
|
|
680
|
+
|
|
681
|
+
# Restore initial conditions
|
|
682
|
+
self.restore_remote_settings(adc, initial_conditions)
|
|
683
|
+
|
|
684
|
+
def set_GAIN0(self, adc, gain_setting):
|
|
685
|
+
"""Set the GAIN resgiter for set-up 0
|
|
686
|
+
"""
|
|
687
|
+
self._write_data_24(adc, self.reg.GAIN0_REG, gain_setting)
|
|
688
|
+
return
|
|
689
|
+
|
|
690
|
+
def add_to_GAIN0(self, adc, gain_incr):
|
|
691
|
+
"""Add to the GAIN resgiter of set-up 0
|
|
692
|
+
"""
|
|
693
|
+
value = self.read_GAIN0(adc)
|
|
694
|
+
self._write_data_24(adc, self.reg.GAIN0_REG, value+gain_incr)
|
|
695
|
+
return
|
|
696
|
+
|
|
697
|
+
def read_GAIN0(self, adc):
|
|
698
|
+
"""Read the GAIN resgiter for set-up 0
|
|
699
|
+
"""
|
|
700
|
+
if adc not in range(2):
|
|
701
|
+
raise ValueError('ADC number {} does not exist. Possible values are 0 and 1.'.format(adc))
|
|
702
|
+
rdata = self._read_data(adc, self.reg.GAIN0_REG, 3) # DEBUG
|
|
703
|
+
print(" rdata is",rdata) # DEBUG
|
|
704
|
+
rdata = self._read_data(adc, self.reg.GAIN0_REG, 3)[1:]
|
|
705
|
+
print(" The final rdata is",rdata[0], rdata[1], rdata[2], rdata) # DEBUG
|
|
706
|
+
value = rdata[0]<<16 | rdata[1]<<8 | rdata[2]
|
|
707
|
+
return value
|
|
708
|
+
|
|
709
|
+
def set_OFFSET0(self, adc, gain_setting):
|
|
710
|
+
"""Set the OFFSET resgiter for set-up 0
|
|
711
|
+
"""
|
|
712
|
+
self._write_data_24(adc, self.reg.OFFSET0_REG, gain_setting)
|
|
713
|
+
return
|
|
714
|
+
|
|
715
|
+
def read_OFFSET0(self, adc):
|
|
716
|
+
"""Read the OFFSET resgiter for set-up 0
|
|
717
|
+
"""
|
|
718
|
+
if adc not in range(2):
|
|
719
|
+
raise ValueError('ADC number {} does not exist. Possible values are 0 and 1.'.format(adc))
|
|
720
|
+
rdata = self._read_data(adc, self.reg.OFFSET0_REG, 3)[1:]
|
|
721
|
+
value = rdata[0]<<16 | rdata[1]<<8 | rdata[2]
|
|
722
|
+
return value
|
|
723
|
+
|
|
724
|
+
def _default_setup(self):
|
|
725
|
+
# Basic configuration
|
|
726
|
+
for adc in range(0, 2):
|
|
727
|
+
|
|
728
|
+
# adcMODE_REG:
|
|
729
|
+
# Mode - set continuous conversion mode
|
|
730
|
+
# Single cycle - only output data at filter settling rate
|
|
731
|
+
# Also implcitly disabling internal ref and setting the clock source to internal
|
|
732
|
+
self._write_data_16(adc, self.reg.adcMODE_REG,
|
|
733
|
+
(0<<self.reg.MODE) |
|
|
734
|
+
(1<<self.reg.SING_CYC))
|
|
735
|
+
|
|
736
|
+
# IFMODE_REG:
|
|
737
|
+
self._write_data_16(adc, self.reg.IFMODE_REG, (1<<self.reg.DOUT_RESET))
|
|
738
|
+
|
|
739
|
+
# GPIOCON_REG:
|
|
740
|
+
# Disable ext_synch
|
|
741
|
+
self._write_data_16(adc, self.reg.GPIOCON_REG,
|
|
742
|
+
(0<<self.reg.SYNC_EN) |
|
|
743
|
+
(0<<self.reg.IP_EN1) |
|
|
744
|
+
(0<<self.reg.IP_EN0) |
|
|
745
|
+
(0<<self.reg.OP_EN1) |
|
|
746
|
+
(0<<self.reg.OP_EN0))
|
|
747
|
+
|
|
748
|
+
# CH0_REG:
|
|
749
|
+
self._write_data_16(adc, self.reg.CH0_REG,
|
|
750
|
+
(1<<self.reg.CH_EN) |
|
|
751
|
+
(0<<self.reg.SETUP_SEL) |
|
|
752
|
+
(self.reg.AIN3<<self.reg.AINPOS) |
|
|
753
|
+
(self.reg.AIN2<<self.reg.AINNEG))
|
|
754
|
+
|
|
755
|
+
# CH1,2,3_REG:
|
|
756
|
+
self._write_data_16(adc, self.reg.CH1_REG,
|
|
757
|
+
(0<<self.reg.CH_EN) |
|
|
758
|
+
(0<<self.reg.SETUP_SEL) |
|
|
759
|
+
(self.reg.AIN1<<self.reg.AINPOS) |
|
|
760
|
+
(self.reg.AIN4<<self.reg.AINNEG))
|
|
761
|
+
|
|
762
|
+
self._write_data_16(adc, self.reg.CH2_REG,
|
|
763
|
+
(0<<self.reg.CH_EN) |
|
|
764
|
+
(0<<self.reg.SETUP_SEL) |
|
|
765
|
+
(self.reg.AIN2<<self.reg.AINPOS) |
|
|
766
|
+
(self.reg.AIN4<<self.reg.AINNEG))
|
|
767
|
+
|
|
768
|
+
self._write_data_16(adc, self.reg.CH3_REG,
|
|
769
|
+
(0<<self.reg.CH_EN) |
|
|
770
|
+
(0<<self.reg.SETUP_SEL) |
|
|
771
|
+
(self.reg.AIN3<<self.reg.AINPOS) |
|
|
772
|
+
(self.reg.AIN4<<self.reg.AINNEG))
|
|
773
|
+
|
|
774
|
+
# SETUPCON0_REG:
|
|
775
|
+
self._write_data_16(adc, self.reg.SETUPCON0_REG,
|
|
776
|
+
(1<<self.reg.BI_UNIPOLAR) |
|
|
777
|
+
(1<<self.reg.REFBUF0P) |
|
|
778
|
+
(1<<self.reg.REFBUF0M) |
|
|
779
|
+
(0<<self.reg.AINBUF0P) |
|
|
780
|
+
(0<<self.reg.AINBUF0M))
|
|
781
|
+
|
|
782
|
+
# OFFSET 0,1,2,3_REG:
|
|
783
|
+
self._write_data_24(adc, self.reg.OFFSET0_REG, 8388150)
|
|
784
|
+
self._write_data_24(adc, self.reg.OFFSET1_REG, 8388150)
|
|
785
|
+
self._write_data_24(adc, self.reg.OFFSET2_REG, 8388150)
|
|
786
|
+
self._write_data_24(adc, self.reg.OFFSET3_REG, 8388150)
|
|
787
|
+
|
|
788
|
+
# GAIN 0,1,2,3_REG:
|
|
789
|
+
# Set the gain such that +-3.5V is full scale. Can be overwritten by user's calibration
|
|
790
|
+
self._write_data_24(adc, self.reg.GAIN0_REG, 5699250)
|
|
791
|
+
self._write_data_24(adc, self.reg.GAIN1_REG, 5699250)
|
|
792
|
+
self._write_data_24(adc, self.reg.GAIN2_REG, 5699250)
|
|
793
|
+
self._write_data_24(adc, self.reg.GAIN3_REG, 5699250)
|
|
794
|
+
|
|
795
|
+
def set_clock_mode(self, adc, clockmode):
|
|
796
|
+
"""Selects the Clock Mode for the ADC
|
|
797
|
+
|
|
798
|
+
"""
|
|
799
|
+
d_clock_modes = {'IntOsc':0b00, 'IntOscToOut':0b01, 'ExtClk':0b10, 'ExtOsc':0b11}
|
|
800
|
+
if clockmode not in d_clock_modes:
|
|
801
|
+
raise ValueError('Value {} does not exist. Possible values are: {}'.format(clockmode, d_clock_modes.keys()))
|
|
802
|
+
self._write_data_16(self, adc, self.reg.adcMODE_REG,
|
|
803
|
+
(d_clock_modes[clockmode]<<self.reg.CLOCKSEL))
|
|
804
|
+
|
|
805
|
+
def set_filter(self, adc, filter_type, filter_setting):
|
|
806
|
+
"""Sets the ADC filter
|
|
807
|
+
|
|
808
|
+
The two filter parameters determine the filter response (cutoff frequency),
|
|
809
|
+
the 50 Hz rejection and the resolution. See the filter table on the website
|
|
810
|
+
to determine which setting is correct for your application.
|
|
811
|
+
|
|
812
|
+
Args:
|
|
813
|
+
adc (int:0-1): ADC inside the module which needs to be set
|
|
814
|
+
filter_type (string): set to sinc3 or sinc5
|
|
815
|
+
filter_setting (int:0-20): the desired filter setting
|
|
816
|
+
"""
|
|
817
|
+
filter_values = {'sinc3': 3, 'sinc5': 0}
|
|
818
|
+
if filter_type not in filter_values:
|
|
819
|
+
raise ValueError('Value {} does not exist. Possible values are: {}'.format(filter_type, filter_values))
|
|
820
|
+
if filter_setting not in range(21):
|
|
821
|
+
raise ValueError('Value {} not allowed. Possible values are from 0 to 20.'.format(filter_setting))
|
|
822
|
+
|
|
823
|
+
self._write_data_16(adc, self.reg.FILTCON0_REG,
|
|
824
|
+
(filter_values[filter_type]<<self.reg.ORDER0) |
|
|
825
|
+
(filter_setting<<self.reg.ODR))
|
|
826
|
+
|
|
827
|
+
self.filter_setting = filter_setting
|
|
828
|
+
self.filter_type = filter_type
|
|
829
|
+
|
|
830
|
+
def get_ADC_ID(self, adc):
|
|
831
|
+
|
|
832
|
+
# From register ID REGISTER:
|
|
833
|
+
# extract ID
|
|
834
|
+
ADC_ID_raw = self._read_data(adc, self.reg.ID_REG, 2)
|
|
835
|
+
ADC_ID_chopped = ADC_ID_raw[1:]
|
|
836
|
+
ADC_ID = (ADC_ID_chopped[0]<<8)|(ADC_ID_chopped[1])
|
|
837
|
+
return ADC_ID
|
|
838
|
+
|
|
839
|
+
def get_ADC_status(self, adc):
|
|
840
|
+
AdcState = {}
|
|
841
|
+
|
|
842
|
+
# From register ID_REG:
|
|
843
|
+
# extract ID
|
|
844
|
+
ID_REG_data = self.get_ADC_ID(adc)
|
|
845
|
+
print("Reading ID_REG:")
|
|
846
|
+
print(" ID is ", ID_REG_data)
|
|
847
|
+
AdcState['ID_REG']= ID_REG_data
|
|
848
|
+
|
|
849
|
+
# From register CH0_REG:
|
|
850
|
+
# extract CH_EN0
|
|
851
|
+
CH0_REG_data = self._read_data(adc, self.reg.CH0_REG, 2)
|
|
852
|
+
CH0_REG_data = CH0_REG_data[1:]
|
|
853
|
+
CH_EN0 = (CH0_REG_data[0]>>7)&0x01
|
|
854
|
+
AINPOS0 = ((CH0_REG_data[1]&0xe0)>>5)|((CH0_REG_data[0]&0x03)<<3)
|
|
855
|
+
AINNEG0 = (CH0_REG_data[1]&0x1f)
|
|
856
|
+
# prints for debug
|
|
857
|
+
print("Reading ADC{} CH0_REG:".format(adc))
|
|
858
|
+
print(" CH0_REG data is ", CH0_REG_data, " (or integer value of ", int.from_bytes(CH0_REG_data, byteorder='big', signed=False),")")
|
|
859
|
+
print(" CH0_REG's CH_EN0 is:", CH_EN0, ", AINPOS0 is:", AINPOS0, ", AINNEG0 is:", AINNEG0)
|
|
860
|
+
AdcState['CH_EN0']=CH_EN0
|
|
861
|
+
AdcState['AINPOS0']=AINPOS0
|
|
862
|
+
AdcState['AINNEG0']=AINNEG0
|
|
863
|
+
|
|
864
|
+
# From register adcMODE (p. 53):
|
|
865
|
+
# extract REF_EN, SING_CYC, MODE, CLOCKSEL
|
|
866
|
+
adcMODE_REG_data = self._read_data(adc, self.reg.adcMODE_REG, 2)
|
|
867
|
+
adcMODE_REG_data = adcMODE_REG_data[1:]
|
|
868
|
+
REF_EN = (adcMODE_REG_data[0]>>7)&0x01
|
|
869
|
+
SING_CYC = (adcMODE_REG_data[0]>>5)&0x01
|
|
870
|
+
MODE = (adcMODE_REG_data[1]>>4)&0x07
|
|
871
|
+
CLOCKSEL = adcMODE_REG_data[1]&0x0c
|
|
872
|
+
# prints for debug
|
|
873
|
+
print("Reading ADC{} MODE_REG:".format(adc))
|
|
874
|
+
print(" MODE_REG data is ", adcMODE_REG_data, " (or integer value of ", int.from_bytes(adcMODE_REG_data, byteorder='big', signed=False),")")
|
|
875
|
+
print(" adcMODE_REG's Internal_REF is:",REF_EN," SING_CYC is:", SING_CYC, ", MODE is:",MODE, ", CLOCKSEL is:",CLOCKSEL)
|
|
876
|
+
AdcState['Internal_REF EN']=REF_EN
|
|
877
|
+
AdcState['SING_CYC']=SING_CYC
|
|
878
|
+
AdcState['MODE']=MODE
|
|
879
|
+
AdcState['CLOCKSEL']=CLOCKSEL
|
|
880
|
+
|
|
881
|
+
# From register FILTCON0:
|
|
882
|
+
# extract ODR, Sync_Filter
|
|
883
|
+
FILTCON0_REG_data = self._read_data(adc, self.reg.FILTCON0_REG, 2)
|
|
884
|
+
FILTCON0_REG_data = FILTCON0_REG_data[1:]
|
|
885
|
+
Sync_Filter = FILTCON0_REG_data[1]>>5&0x03 # Order (type) of digital filter used
|
|
886
|
+
ODR = FILTCON0_REG_data[1]&0x1f # 'ODR' is Output Data Rate
|
|
887
|
+
# prints for debug
|
|
888
|
+
print("Reading ADC{} FILTCON0_REG:".format(adc))
|
|
889
|
+
print(" FILTCON0_REG data is ", FILTCON0_REG_data, " (or integer value of ", int.from_bytes(FILTCON0_REG_data, byteorder='big', signed=False),")")
|
|
890
|
+
print(" FILTCON0_REG's Sync_Filter is:", Sync_Filter, ", ODR code is:",ODR)
|
|
891
|
+
AdcState['Output Data Rate']=ODR
|
|
892
|
+
AdcState['Sync_Filter']=Sync_Filter
|
|
893
|
+
|
|
894
|
+
# From register GPIOCON:
|
|
895
|
+
# extract EXT_ENABLE, OP1_EN, GP_DATA1
|
|
896
|
+
GPIO_data = self._read_data(adc, self.reg.GPIOCON_REG, 2)
|
|
897
|
+
GPIO_data = GPIO_data[1:]
|
|
898
|
+
EXT_ENABLE = (GPIO_data[0]>>3)&0x01
|
|
899
|
+
OP_EN1 = (GPIO_data[1]>>3)&0x01
|
|
900
|
+
GP_DATA1 = (GPIO_data[1]>>1)&0x01
|
|
901
|
+
# prints for debug
|
|
902
|
+
print("Reading ADC{} GPIOCON:".format(adc))
|
|
903
|
+
print(" GPIOCON is ", GPIO_data, " (or integer value of ", int.from_bytes(GPIO_data, byteorder='big', signed=False),")")
|
|
904
|
+
print(" GPIOCON_REG's EXT_ENABLE is:", EXT_ENABLE, ", OP_EN1 is:", OP_EN1, ", GP_DATA1 is:",GP_DATA1)
|
|
905
|
+
AdcState['EXT_ENABLE']=EXT_ENABLE
|
|
906
|
+
AdcState['OP_EN1']=OP_EN1
|
|
907
|
+
AdcState['GP_DATA1']=GP_DATA1
|
|
908
|
+
|
|
909
|
+
# From register SETUPCON0 (p. 59):
|
|
910
|
+
# extract REFBUF0+, REFBUF0-, REF_SEL0
|
|
911
|
+
GPIO_data = self._read_data(adc, self.reg.SETUPCON0_REG, 2)
|
|
912
|
+
GPIO_data = GPIO_data[1:]
|
|
913
|
+
REFBUF0plus = (GPIO_data[0]>>3)&0x01
|
|
914
|
+
REFBUF0minus = (GPIO_data[0]>>2)&0x01
|
|
915
|
+
ANLGBUF0plus = (GPIO_data[0]>>1)&0x01
|
|
916
|
+
ANLGBUF0minus = GPIO_data[0]&0x01
|
|
917
|
+
REF_SEL0 = (GPIO_data[1]>>4)&0x03
|
|
918
|
+
# prints for debug
|
|
919
|
+
print("Reading ADC{} SETUPCON0:".format(adc))
|
|
920
|
+
print(" SETUPCON0 is ", GPIO_data, " (or integer value of ", int.from_bytes(GPIO_data, byteorder='big', signed=False),")")
|
|
921
|
+
print(" SETUPCON0_REG's REFBUF0+ is:", REFBUF0plus, ", REFBUF0- is:", REFBUF0minus, ", REF_SEL0 is:" ,REF_SEL0 , "ANLGBUF0+ is:", ANLGBUF0plus, ", ANLGBUF0- is:", ANLGBUF0minus)
|
|
922
|
+
AdcState['REFBUF0+']=REFBUF0plus
|
|
923
|
+
AdcState['REFBUF0-']=REFBUF0minus
|
|
924
|
+
AdcState['ANLGBUF0+']=ANLGBUF0plus
|
|
925
|
+
AdcState['ANLGBUF0-']=ANLGBUF0minus
|
|
926
|
+
AdcState['REF_SEL0']=REF_SEL0
|
|
927
|
+
|
|
928
|
+
# From register OFFSET0:
|
|
929
|
+
# prints for debug
|
|
930
|
+
print("Reading ADC{} OFFSET0:".format(adc))
|
|
931
|
+
OFFSET0 = self.read_OFFSET0(adc)
|
|
932
|
+
print(" OFFSET0 is:", OFFSET0)
|
|
933
|
+
AdcState['OFFSET0']=OFFSET0
|
|
934
|
+
|
|
935
|
+
# From register GAIN0:
|
|
936
|
+
# prints for debug
|
|
937
|
+
print("Reading ADC{} GAIN0:".format(adc))
|
|
938
|
+
GAIN0 = self.read_GAIN0(adc)
|
|
939
|
+
print(" GAIN0 is:", GAIN0)
|
|
940
|
+
AdcState['GAIN0']=GAIN0
|
|
941
|
+
|
|
942
|
+
return AdcState
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
def set_output_enable(self, SR_OEb):
|
|
946
|
+
"""
|
|
947
|
+
Sets the output_enable\ signal into the SR.
|
|
948
|
+
Args:
|
|
949
|
+
|
|
950
|
+
"""
|
|
951
|
+
if SR_OEb not in range(0, 2):
|
|
952
|
+
raise ValueError('The output_enable given {} is not a legal value. Possible values are in {}'.format(SR_OEb, range(0, 2)))
|
|
953
|
+
|
|
954
|
+
# The output byte holds two bits:
|
|
955
|
+
# The 'SR_OEb' - given hereby explicitly by the user
|
|
956
|
+
# The trig/sync - the existing bic_sync_value kept in memory
|
|
957
|
+
output_byte = SR_OEb<<7|self.bic_sync_value
|
|
958
|
+
print("The output_byte from BIC to module is",output_byte)
|
|
959
|
+
|
|
960
|
+
self.spi_rack.write_data(self.module, 5, 0, BICPINS_SPEED, bytearray([output_byte]))
|
|
961
|
+
self.SR_OEb = SR_OEb # need to keep this value for sync_signal setting
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
def set_sync_signal(self, user_sync_value):
|
|
965
|
+
"""
|
|
966
|
+
Sets the sync signal from the BIC to the ADCs
|
|
967
|
+
to 0 or 1, as configured.
|
|
968
|
+
Note 1: one sync signal serves both ADC0, ADC1.
|
|
969
|
+
Note 2: sync\ low freezes operation. Operation resumes at sync\ rising edge,
|
|
970
|
+
and continues while high value maintained.
|
|
971
|
+
Note 3: the BIC_TRIG is OR'ed with the front-panel wired TRIG. Therefore
|
|
972
|
+
a 'high' setting from a front-panel TRIG is enough to keep the sync at 'high'
|
|
973
|
+
even with the BIC_TRIG low.
|
|
974
|
+
|
|
975
|
+
Args:
|
|
976
|
+
|
|
977
|
+
"""
|
|
978
|
+
if user_sync_value not in range(0, 2):
|
|
979
|
+
raise ValueError('The sync_value given {} is not a legal value. Possible values are in {}'.format(user_sync_value, range(0, 2)))
|
|
980
|
+
|
|
981
|
+
print("set_sync_signal:\n sync_signal from user is ",bytearray([user_sync_value]))
|
|
982
|
+
|
|
983
|
+
# The output byte holds two bits:
|
|
984
|
+
# The 'SR_OEb' - the existing SR_OEb kept in memory
|
|
985
|
+
# The trig/sync - the new user_sync_value given here explicitly by the user
|
|
986
|
+
output_byte = self.SR_OEb<<7|user_sync_value
|
|
987
|
+
print(" The output_byte from BIC to module is",output_byte)
|
|
988
|
+
|
|
989
|
+
# Write to SPI addr 5 - the GPIO output direction
|
|
990
|
+
self.spi_rack.write_data(self.module, 5, 0, BICPINS_SPEED, bytearray([output_byte]))
|
|
991
|
+
|
|
992
|
+
self.bic_sync_value = user_sync_value # need to keep this value for SR_OEb setting
|
|
993
|
+
|
|
994
|
+
def read_unified_sync_signal(self):
|
|
995
|
+
"""
|
|
996
|
+
Note: there is only one sync signal in the module, not per ADC
|
|
997
|
+
|
|
998
|
+
Args:
|
|
999
|
+
|
|
1000
|
+
"""
|
|
1001
|
+
s_data = bytearray([0])
|
|
1002
|
+
r_data = self.spi_rack.read_data(self.module, 4, 0, BICPINS_SPEED, s_data)
|
|
1003
|
+
lsb_value = int.from_bytes(r_data, byteorder='little', signed=False)&0x1
|
|
1004
|
+
return lsb_value
|
|
1005
|
+
|
|
1006
|
+
def configure_sync_mode(self, adc, ext_enable):
|
|
1007
|
+
"""Wait for external trigger to perform a conversion
|
|
1008
|
+
|
|
1009
|
+
Configures the given ADC to depend on external 'enable' (a.k.a. synch or mask) to perform a new convertion.
|
|
1010
|
+
A call to get the result needs to follow to access the data.
|
|
1011
|
+
|
|
1012
|
+
Args:
|
|
1013
|
+
adc (int:0-1): ADC to perform the conversion
|
|
1014
|
+
ext_enable (int:0-1): 1 - external trigger mode; 0 - regular operation (SW)
|
|
1015
|
+
"""
|
|
1016
|
+
# input checks
|
|
1017
|
+
if adc not in range(0, 2):
|
|
1018
|
+
raise ValueError('ADC {} does not exist. Possible values are: {}'.format(adc, range(0, 2)))
|
|
1019
|
+
if ext_enable not in range(0, 2):
|
|
1020
|
+
raise ValueError('ext_enable {} is not a legal value. Possible values are in {}'.format(ext_enable, range(0, 2)))
|
|
1021
|
+
|
|
1022
|
+
gpio_desired = (ext_enable<<self.reg.SYNC_EN)|(ext_enable<<self.reg.OP_EN1)|(ext_enable<<self.reg.GP_DATA1)
|
|
1023
|
+
self._write_data_16(adc, self.reg.GPIOCON_REG, gpio_desired)
|
|
1024
|
+
gpio_actual = self._read_data(adc, self.reg.GPIOCON_REG, 2)
|
|
1025
|
+
gpio_actual = gpio_actual[1]<<8|gpio_actual[2]
|
|
1026
|
+
if (gpio_actual != gpio_desired):
|
|
1027
|
+
raise ValueError('D4a set_ext_trigger error: failed to configure desired trigger mode {} to ADC{}'.format(ext_enable, adc))
|
|
1028
|
+
|
|
1029
|
+
def _read_data(self, adc, reg, num_bytes):
|
|
1030
|
+
"""
|
|
1031
|
+
Read a given number of bytes (num_bytes) from given adc register
|
|
1032
|
+
"""
|
|
1033
|
+
s_data = bytearray([reg | (1<<6)] + num_bytes*[0])
|
|
1034
|
+
r_i_data = self.spi_rack.read_data(self.module, adc, AD7175_MODE, AD7175_SPEED, s_data)
|
|
1035
|
+
|
|
1036
|
+
return r_i_data
|
|
1037
|
+
|
|
1038
|
+
def _write_data_8(self, adc, reg, data):
|
|
1039
|
+
s_data = bytearray([reg, data])
|
|
1040
|
+
self.spi_rack.write_data(self.module, adc, AD7175_MODE, AD7175_SPEED, s_data)
|
|
1041
|
+
|
|
1042
|
+
def _write_data_16(self, adc, reg, data):
|
|
1043
|
+
s_data = bytearray([reg, data>>8, data&0xFF])
|
|
1044
|
+
self.spi_rack.write_data(self.module, adc, AD7175_MODE, AD7175_SPEED, s_data)
|
|
1045
|
+
|
|
1046
|
+
def _write_data_24(self, adc, reg, data):
|
|
1047
|
+
s_data = bytearray([reg, data>>16, (data>>8)&0xFF, data&0xFF])
|
|
1048
|
+
self.spi_rack.write_data(self.module, adc, AD7175_MODE, AD7175_SPEED, s_data)
|
|
1049
|
+
|
|
1050
|
+
def _reset_ADC(self, adc):
|
|
1051
|
+
s_data = bytearray([self.reg.GAIN0_REG, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
|
|
1052
|
+
self.spi_rack.write_data(self.module, adc, AD7175_MODE, AD7175_SPEED, s_data)
|
|
1053
|
+
|
|
1054
|
+
|
|
1055
|
+
class AD7175_registers:
|
|
1056
|
+
"""AD7175 register class
|
|
1057
|
+
|
|
1058
|
+
A list of all the register names with values and all bits with corresponding
|
|
1059
|
+
locations in the registers.
|
|
1060
|
+
"""
|
|
1061
|
+
# adc register locations
|
|
1062
|
+
STATUS_REG = 0x00
|
|
1063
|
+
adcMODE_REG = 0x01
|
|
1064
|
+
IFMODE_REG = 0x02
|
|
1065
|
+
REGCHECK_REG = 0x03
|
|
1066
|
+
DATA_REG = 0x04
|
|
1067
|
+
GPIOCON_REG = 0x06
|
|
1068
|
+
ID_REG = 0x07
|
|
1069
|
+
CH0_REG = 0x10
|
|
1070
|
+
CH1_REG = 0x11
|
|
1071
|
+
CH2_REG = 0x12
|
|
1072
|
+
CH3_REG = 0x13
|
|
1073
|
+
SETUPCON0_REG = 0x20
|
|
1074
|
+
SETUPCON1_REG = 0x21
|
|
1075
|
+
SETUPCON2_REG = 0x22
|
|
1076
|
+
SETUPCON3_REG = 0x23
|
|
1077
|
+
FILTCON0_REG = 0x28
|
|
1078
|
+
FILTCON1_REG = 0x29
|
|
1079
|
+
FILTCON2_REG = 0x2A
|
|
1080
|
+
FILTCON3_REG = 0x2B
|
|
1081
|
+
OFFSET0_REG = 0x30
|
|
1082
|
+
OFFSET1_REG = 0x31
|
|
1083
|
+
OFFSET2_REG = 0x32
|
|
1084
|
+
OFFSET3_REG = 0x33
|
|
1085
|
+
GAIN0_REG = 0x38
|
|
1086
|
+
GAIN1_REG = 0x39
|
|
1087
|
+
GAIN2_REG = 0x3A
|
|
1088
|
+
GAIN3_REG = 0x3B
|
|
1089
|
+
|
|
1090
|
+
# Status Register bits
|
|
1091
|
+
nRDY = 7
|
|
1092
|
+
adc_ERROR = 6
|
|
1093
|
+
CRC_ERROR = 5
|
|
1094
|
+
REG_ERROR = 4
|
|
1095
|
+
CHANNEL = 0
|
|
1096
|
+
|
|
1097
|
+
# adc Mode Register bits
|
|
1098
|
+
REF_EN = 15
|
|
1099
|
+
HIDE_DELAY = 14
|
|
1100
|
+
SING_CYC = 13
|
|
1101
|
+
DELAY = 8
|
|
1102
|
+
MODE = 4
|
|
1103
|
+
CLOCKSEL = 2
|
|
1104
|
+
|
|
1105
|
+
# IFMODE Register bits
|
|
1106
|
+
ALT_SYNC = 12
|
|
1107
|
+
IOSTRENGTH = 11
|
|
1108
|
+
DOUT_RESET = 8
|
|
1109
|
+
CONTREAD = 7
|
|
1110
|
+
DATA_STAT = 6
|
|
1111
|
+
REG_CHECK = 5
|
|
1112
|
+
CRC_EN = 2
|
|
1113
|
+
WL16 = 0
|
|
1114
|
+
|
|
1115
|
+
# GPIOCON Register bits
|
|
1116
|
+
MUX_IO = 12
|
|
1117
|
+
SYNC_EN = 11
|
|
1118
|
+
ERR_EN = 9
|
|
1119
|
+
ERR_DAT = 8
|
|
1120
|
+
IP_EN1 = 5
|
|
1121
|
+
IP_EN0 = 4
|
|
1122
|
+
OP_EN1 = 3
|
|
1123
|
+
OP_EN0 = 2
|
|
1124
|
+
GP_DATA1 = 1
|
|
1125
|
+
GP_DATA0 = 0
|
|
1126
|
+
|
|
1127
|
+
# Channel Registers bits
|
|
1128
|
+
CH_EN = 15
|
|
1129
|
+
SETUP_SEL = 12
|
|
1130
|
+
AINPOS = 5
|
|
1131
|
+
AINNEG = 0
|
|
1132
|
+
|
|
1133
|
+
# Setup Configuration Register bits
|
|
1134
|
+
BI_UNIPOLAR = 12
|
|
1135
|
+
REFBUF0P = 11
|
|
1136
|
+
REFBUF0M = 10
|
|
1137
|
+
AINBUF0P = 9
|
|
1138
|
+
AINBUF0M = 8
|
|
1139
|
+
REF_SEL = 4
|
|
1140
|
+
|
|
1141
|
+
# Filter Configuration Register bits
|
|
1142
|
+
SINC3_MAP0 = 15
|
|
1143
|
+
ENHFILTEN = 11
|
|
1144
|
+
ENHFILT = 8
|
|
1145
|
+
ORDER0 = 5
|
|
1146
|
+
ODR = 0
|
|
1147
|
+
|
|
1148
|
+
# adc register values
|
|
1149
|
+
AIN0 = 0
|
|
1150
|
+
AIN1 = 1
|
|
1151
|
+
AIN2 = 2
|
|
1152
|
+
AIN3 = 3
|
|
1153
|
+
AIN4 = 4
|
|
1154
|
+
REFP = 21
|
|
1155
|
+
REFN = 22
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.2.12'
|
spirack-0.2.9/spirack/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.2.9'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|