]> sigrok.org Git - libsigrokdecode.git/blame - decoders/adxl345/pd.py
adxl345: Shorten/simplify self.putbs() invocations.
[libsigrokdecode.git] / decoders / adxl345 / pd.py
CommitLineData
f47d3a2d
TP
1##
2## This file is part of the libsigrokdecode project.
3##
4## Copyright (C) 2020 Analog Devices Inc.
5##
6## This program is free software; you can redistribute it and/or modify
7## it under the terms of the GNU General Public License as published by
8## the Free Software Foundation; either version 3 of the License, or
9## (at your option) any later version.
10##
11## This program is distributed in the hope that it will be useful,
12## but WITHOUT ANY WARRANTY; without even the implied warranty of
13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14## GNU General Public License for more details.
15##
16## You should have received a copy of the GNU General Public License
17## along with this program; if not, see <http://www.gnu.org/licenses/>.
18##
19
20import sigrokdecode as srd
21from .lists import *
22
23WORD_SIZE = 8
24
25class Channel():
88098c75 26 MISO, MOSI = range(2)
f47d3a2d
TP
27
28class Operation():
88098c75 29 READ, WRITE = range(2)
f47d3a2d
TP
30
31class BitType():
32 ENABLE = {1: ['Enable %s', 'En %s', '%s '], 0: ['Disable %s', 'Dis %s', '!%s '],}
33 SOURCE = {1: ['Involve %s', 'Inv %s', '%s'], 0: ['Not involve %s', 'Not inv %s', '!%s'],}
34 INTERRUPT = {1: ['INT2 %s', 'I2: %s '], 0: ['INT1 %s', 'I1:%s '],}
35 AC_DC = {1: ['%s ac', 'ac'], 0: ['%s dc', 'dc'],}
36 UNUSED = {1: ['N/A'], 0: ['N/A'],}
37 OTHER = 0
38
39class Bit():
40 def __init__(self, name, type, values=None):
41 self.value = 0
42 self.name = name
43 self.type = type
44 self.values = values
45
46 def set_value(self, value):
47 self.value = value
48
49 def get_bit_annotation(self):
50 if self.type == BitType.OTHER:
51 annotation = self.values[self.value].copy()
52 else:
53 annotation = self.type[self.value].copy()
54
55 for index in range(len(annotation)):
56 if '%s' in annotation[index]:
57 annotation[index] = str(annotation[index] % self.name)
58 return annotation
59
60class Decoder(srd.Decoder):
61 api_version = 3
62 id = 'adxl345'
63 name = 'ADXL345'
64 longname = 'Analog Devices ADXL345'
65 desc = 'Analog Devices ADXL345 3-axis accelerometer.'
66 license = 'gplv2+'
67 inputs = ['spi']
68 outputs = []
69 tags = ['IC', 'Sensor']
70 annotations = (
71 ('read', 'Read'),
72 ('write', 'Write'),
73 ('mb', 'Multiple bytes'),
74 ('reg-address', 'Register address'),
75 ('reg-data', 'Register data'),
76 ('warning', 'Warning'),
77 )
78 annotation_rows = (
79 ('reg', 'Registers', (0, 1, 2, 3)),
80 ('data', 'Data', (4, 5)),
81 )
82
83 def __init__(self):
84 self.reset()
85
86 def reset(self):
88098c75 87 self.mosi, self.miso = [], []
f47d3a2d
TP
88 self.reg = []
89 self.operation = None
90 self.address = 0
91 self.data = -1
92 self.state = 'IDLE'
88098c75 93 self.ss, self.es = -1, -1
f47d3a2d
TP
94 self.samples_per_bit = 0
95
96 def start(self):
97 self.out_ann = self.register(srd.OUTPUT_ANN)
98
99 def putx(self, data):
100 self.put(self.ss, self.es, self.out_ann, data)
101
102 def putb(self, data, index):
103 start = self.ss + (self.samples_per_bit * index)
104 self.put(start, start + self.samples_per_bit, self.out_ann, data)
105
106 def putbs(self, data, start_index, stop_index):
4b0d57fc
UH
107 start_index = self.reverse_bit_index(start_index, WORD_SIZE)
108 stop_index = self.reverse_bit_index(stop_index, WORD_SIZE)
f47d3a2d
TP
109 start = self.ss + (self.samples_per_bit * start_index)
110 stop = start + (self.samples_per_bit * (stop_index - start_index + 1))
111 self.put(start, stop, self.out_ann, data)
112
113 def handle_reg_with_scaling_factor(self, data, factor, name, unit, error_msg):
114 if data == 0 and error_msg is not None:
115 self.putx([5, error_msg])
116 else:
117 result = (data * factor) / 1000
88098c75 118 self.putx([4, ['%s: %f %s' % (name, result, unit), '%f %s' % (result, unit)]])
f47d3a2d
TP
119
120 def handle_reg_bit_msg(self, bit, index, en_msg, dis_msg):
88098c75 121 self.putb([4, [en_msg if bit else dis_msg]], index)
f47d3a2d
TP
122
123 def interpret_bits(self, data, bits):
124 bits_values = []
125 for offset in range(8):
126 bits_values.insert(0, (data & (1 << offset)) >> offset)
127
128 for index in range(len(bits)):
129 if bits[index] is None:
130 continue
131 bit = bits[index]
132 bit.set_value(bits_values[index])
88098c75 133 self.putb([4, bit.get_bit_annotation()], index)
f47d3a2d
TP
134
135 return list(reversed(bits_values))
136
137 def reverse_bit_index(self, index, word_size):
138 return word_size - index - 1
139
140 def get_decimal_number(self, bits, start_index, stop_index):
141 number = 0
142 interval = range(start_index, stop_index + 1, 1)
143 for index, offset in zip(interval, range(len(interval))):
144 bit = bits[index]
145 number = number | (bit << offset)
146 return number
147
148 def get_axis_value(self, data, axis):
149 if self.data != - 1:
150 data <<= 8
151 self.data |= data
152 self.put(self.start_index, self.es, self.out_ann,
153 [4, ['%s: 0x%04X' % (axis, self.data), str(data)]])
154 self.data = -1
155 else:
156 self.putx([4, [str(data)]])
157
158 def handle_reg_0x1D(self, data):
159 self.handle_reg_with_scaling_factor(data, 62.5, 'Threshold', 'g',
160 error_messages['undesirable'])
161
162 def handle_reg_0x1E(self, data):
163 self.handle_reg_with_scaling_factor(data, 15.6, 'OFSX', 'g', None)
164
165 def handle_reg_0x1F(self, data):
166 self.handle_reg_with_scaling_factor(data, 15.6, 'OFSY', 'g', None)
167
168 def handle_reg_0x20(self, data):
169 self.handle_reg_with_scaling_factor(data, 15.6, 'OFSZ', 'g', None)
170
171 def handle_reg_0x21(self, data):
172 self.handle_reg_with_scaling_factor(data, 0.625, 'Time', 's',
173 error_messages['dis_single_double'])
174
175 def handle_reg_0x22(self, data):
176 self.handle_reg_with_scaling_factor(data, 62.5, 'Latent', 's',
177 error_messages['dis_double'])
178
179 def handle_reg_0x23(self, data):
180 self.handle_reg_with_scaling_factor(data, 1.25, 'Latent', 's',
181 error_messages['dis_double'])
182
183 def handle_reg_0x24(self, data):
184 self.handle_reg_with_scaling_factor(data, 62.5, 'Latent', 's',
185 error_messages['undesirable'])
186
187 def handle_reg_0x25(self, data):
188 self.handle_reg_0x1D(data)
189
190 def handle_reg_0x26(self, data):
191 self.handle_reg_with_scaling_factor(data, 1000, 'Time', 's',
192 error_messages['interrupt'])
193
194 def handle_reg_0x27(self, data):
195 bits = [Bit('ACT', BitType.AC_DC),
196 Bit('ACT_X', BitType.ENABLE),
197 Bit('ACT_Y', BitType.ENABLE),
198 Bit('ACT_Z', BitType.ENABLE),
199 Bit('INACT', BitType.AC_DC),
200 Bit('INACT_X', BitType.ENABLE),
201 Bit('INACT_Y', BitType.ENABLE),
202 Bit('INACT_Z', BitType.ENABLE)]
203 self.interpret_bits(data, bits)
204
205 def handle_reg_0x28(self, data):
206 self.handle_reg_0x1D(data)
207
208 def handle_reg_0x29(self, data):
209 self.handle_reg_with_scaling_factor(data, 5, 'Time', 's',
210 error_messages['undesirable'])
211
212 def handle_reg_0x2A(self, data):
213 bits = [Bit('', BitType.UNUSED),
214 Bit('', BitType.UNUSED),
215 Bit('', BitType.UNUSED),
216 Bit('', BitType.UNUSED),
217 Bit('', BitType.OTHER, {1: ['Suppressed', 'Suppr', 'S'],
218 0: ['Unsuppressed', 'Unsuppr', 'Uns'],}),
219 Bit('TAP_X', BitType.ENABLE),
220 Bit('TAP_Y', BitType.ENABLE),
221 Bit('TAP_Z', BitType.ENABLE)]
222 self.interpret_bits(data, bits)
223
224 def handle_reg_0x2B(self, data):
225 bits = [Bit('', BitType.UNUSED),
226 Bit('ACT_X', BitType.SOURCE),
227 Bit('ACT_Y', BitType.SOURCE),
228 Bit('ACT_Z', BitType.SOURCE),
229 Bit('', BitType.OTHER, {1: ['Asleep', 'Asl'],
230 0: ['Not asleep', 'Not asl', '!Asl'],}),
231 Bit('TAP_X', BitType.SOURCE),
232 Bit('TAP_Y', BitType.SOURCE),
233 Bit('TAP_Z', BitType.SOURCE)]
234 self.interpret_bits(data, bits)
235
236 def handle_reg_0x2C(self, data):
237 bits = [Bit('', BitType.UNUSED),
238 Bit('', BitType.UNUSED),
239 Bit('', BitType.UNUSED),
240 Bit('', BitType.OTHER, {1: ['Reduce power', 'Reduce pw', 'Red pw'], 0: ['Normal operation', 'Normal op', 'Norm op'],})]
241 bits_values = self.interpret_bits(data, bits)
242
88098c75 243 start_index, stop_index = 0, 3
f47d3a2d 244 rate = self.get_decimal_number(bits_values, start_index, start_index)
4b0d57fc 245 self.putbs([4, ['%f' % rate_code[rate]]], stop_index, start_index)
f47d3a2d
TP
246
247 def handle_reg_0x2D(self, data):
248 bits = [Bit('', BitType.UNUSED),
249 Bit('', BitType.UNUSED),
250 Bit('', BitType.OTHER, {1: ['Link'], 0: ['Unlink'], }),
251 Bit('AUTO_SLEEP', BitType.ENABLE),
252 Bit('', BitType.OTHER, {1: ['Measurement mode', 'Measurement', 'Meas'], 0: ['Standby mode', 'Standby'], }),
253 Bit('', BitType.OTHER, {1: ['Sleep mode', 'Sleep', 'Slp'], 0: ['Normal mode', 'Normal', 'Nrm'],})]
254 bits_values = self.interpret_bits(data, bits)
255
88098c75 256 start_index, stop_index = 0, 1
f47d3a2d
TP
257 wakeup = self.get_decimal_number(bits_values, start_index, stop_index)
258 frequency = 2 ** (~wakeup & 0x03)
4b0d57fc 259 self.putbs([4, ['%d Hz' % frequency]], stop_index, start_index)
f47d3a2d
TP
260
261 def handle_reg_0x2E(self, data):
262 bits = [Bit('DATA_READY', BitType.ENABLE),
263 Bit('SINGLE_TAP', BitType.ENABLE),
264 Bit('DOUBLE_TAP', BitType.ENABLE),
265 Bit('Activity', BitType.ENABLE),
266 Bit('Inactivity', BitType.ENABLE),
267 Bit('FREE_FALL', BitType.ENABLE),
268 Bit('Watermark', BitType.ENABLE),
269 Bit('Overrun', BitType.ENABLE)]
270 self.interpret_bits(data, bits)
271
272 def handle_reg_0x2F(self, data):
273 bits = [Bit('DATA_READY', BitType.INTERRUPT),
274 Bit('SINGLE_TAP', BitType.INTERRUPT),
275 Bit('DOUBLE_TAP', BitType.INTERRUPT),
276 Bit('Activity', BitType.INTERRUPT),
277 Bit('Inactivity', BitType.INTERRUPT),
278 Bit('FREE_FALL', BitType.INTERRUPT),
279 Bit('Watermark', BitType.INTERRUPT),
280 Bit('Overrun', BitType.INTERRUPT)]
281 self.interpret_bits(data, bits)
282
283 def handle_reg_0x30(self, data):
284 bits = [Bit('DATA_READY', BitType.SOURCE),
285 Bit('SINGLE_TAP', BitType.SOURCE),
286 Bit('DOUBLE_TAP', BitType.SOURCE),
287 Bit('Activity', BitType.SOURCE),
288 Bit('Inactivity', BitType.SOURCE),
289 Bit('FREE_FALL', BitType.SOURCE),
290 Bit('Watermark', BitType.SOURCE),
291 Bit('Overrun', BitType.SOURCE)]
292 self.interpret_bits(data, bits)
293
294 def handle_reg_0x31(self, data):
295 bits = [Bit('SELF_TEST', BitType.ENABLE),
296 Bit('', BitType.OTHER, {1: ['3-wire SPI', '3-SPI'], 0: ['4-wire SPI', '4-SPI'],}),
297 Bit('', BitType.OTHER, {1: ['INT ACT LOW', 'INT LOW'], 0: ['INT ACT HIGH', 'INT HIGH'],}),
298 Bit('', BitType.UNUSED),
299 Bit('', BitType.OTHER, {1: ['Full resolution', 'Full res'], 0: ['10-bit mode', '10-bit'],}),
300 Bit('', BitType.OTHER, {1: ['MSB mode', 'MSB'], 0: ['LSB mode', 'LSB'],})]
301 bits_values = self.interpret_bits(data, bits)
302
88098c75 303 start_index, stop_index = 0, 1
f47d3a2d
TP
304 range_g = self.get_decimal_number(bits_values, start_index, stop_index)
305 result = 2 ** (range_g + 1)
4b0d57fc 306 self.putbs([4, ['+/-%d g' % result]], stop_index, start_index)
f47d3a2d
TP
307
308 def handle_reg_0x32(self, data):
309 self.data = data
310 self.putx([4, [str(data)]])
311
312 def handle_reg_0x33(self, data):
313 self.get_axis_value(data, 'X')
314
315 def handle_reg_0x34(self, data):
316 self.handle_reg_0x32(data)
317
318 def handle_reg_0x35(self, data):
319 self.get_axis_value(data, 'Y')
320
321 def handle_reg_0x36(self, data):
322 self.handle_reg_0x32(data)
323
324 def handle_reg_0x37(self, data):
325 self.get_axis_value(data, 'Z')
326
327 def handle_reg_0x38(self, data):
328 bits = [None,
329 None,
330 Bit('', BitType.OTHER, {1: ['Trig-INT2', 'INT2'], 0: ['Trig-INT1', 'INT1'], })]
331 bits_values = self.interpret_bits(data, bits)
332
88098c75 333 start_index, stop_index = 6, 7
f47d3a2d 334 fifo = self.get_decimal_number(bits_values, start_index, stop_index)
4b0d57fc 335 self.putbs([4, [fifo_modes[fifo]]], stop_index, start_index)
f47d3a2d 336
88098c75 337 start_index, stop_index = 0, 4
f47d3a2d 338 samples = self.get_decimal_number(bits_values, start_index, stop_index)
4b0d57fc 339 self.putbs([4, ['Samples: %d' % samples, '%d' % samples]], stop_index, start_index)
f47d3a2d
TP
340
341 def handle_reg_0x39(self, data):
342 bits = [Bit('', BitType.OTHER, {1: ['Triggered', 'Trigg'], 0: ['Not triggered', 'Not trigg'],}),
343 Bit('', BitType.UNUSED)]
344 bits_values = self.interpret_bits(data, bits)
345
88098c75 346 start_index, stop_index = 0, 5
f47d3a2d 347 entries = self.get_decimal_number(bits_values, start_index, stop_index)
4b0d57fc 348 self.putbs([4, ['Entries: %d' % entries, '%d' % entries]], stop_index, start_index)
f47d3a2d
TP
349
350 def get_bit(self, channel):
351 if (channel == Channel.MOSI and self.mosi is None) or \
352 (channel == Channel.MISO and self.miso is None):
353 raise Exception('No available data')
354
355 mosi_bit, miso_bit = 0, 0
356 if self.miso is not None:
357 if len(self.mosi) < 0:
358 raise Exception('No available data')
359 miso_bit = self.miso.pop(0)
360 if self.miso is not None:
361 if len(self.miso) < 0:
362 raise Exception('No available data')
363 mosi_bit = self.mosi.pop(0)
364
365 if channel == Channel.MOSI:
366 return mosi_bit
367 return miso_bit
368
369 def decode(self, ss, es, data):
370 ptype = data[0]
371
372 if ptype == 'CS-CHANGE':
373 cs_old, cs_new = data[1:]
374 if cs_old is not None and cs_old == 1 and cs_new == 0:
88098c75 375 self.ss, self.es = ss, es
f47d3a2d
TP
376 self.state = 'ADDRESS-BYTE'
377 else:
378 self.state = 'IDLE'
379
380 elif ptype == 'BITS':
381 if data[1] is not None:
382 self.mosi = list(reversed(data[1]))
383 if data[2] is not None:
384 self.miso = list(reversed(data[2]))
385
386 if self.mosi is None and self.miso is None:
387 return
388
389 if self.state == 'ADDRESS-BYTE':
390 # OPERATION BIT
391 op_bit = self.get_bit(Channel.MOSI)
88098c75
UH
392 self.put(op_bit[1], op_bit[2], self.out_ann,
393 [0 if op_bit[0] else 1, operations[op_bit[0]]])
394 self.operation = Operation.READ if op_bit[0] else Operation.WRITE
f47d3a2d
TP
395 # MULTIPLE-BYTE BIT
396 mb_bit = self.get_bit(Channel.MOSI)
397 self.put(mb_bit[1], mb_bit[2], self.out_ann, [2, number_bytes[mb_bit[0]]])
398
399 # REGISTER 6-BIT ADDRESS
400 self.address = 0
401 start_sample = self.mosi[0][1]
402 addr_bit = []
403 for i in range(6):
404 addr_bit = self.get_bit(Channel.MOSI)
405 self.address |= addr_bit[0]
406 self.address <<= 1
407 self.address >>= 1
408 self.put(start_sample, addr_bit[2], self.out_ann,
409 [3, ['ADDRESS: 0x%02X' % self.address, 'ADDR: 0x%02X'
410 % self.address, '0x%02X' % self.address]])
411 self.ss = -1
412 self.state = 'DATA'
413
414 elif self.state == 'DATA':
88098c75 415 self.reg.extend(self.mosi if self.operation == Operation.WRITE else self.miso)
f47d3a2d 416
88098c75 417 self.mosi, self.miso = [], []
f47d3a2d 418 if self.ss == -1:
88098c75 419 self.ss, self.es = self.reg[0][1], es
f47d3a2d
TP
420 self.samples_per_bit = self.reg[0][2] - self.ss
421
422 if len(self.reg) < 8:
423 return
424 else:
425 reg_value = 0
426 reg_bit = []
427 for offset in range(7, -1, -1):
428 reg_bit = self.reg.pop(0)
429
430 mask = reg_bit[0] << offset
431 reg_value |= mask
432
433 if self.address < 0x00 or self.address > 0x39:
434 return
435
436 if self.address in [0x32, 0x34, 0x36]:
437 self.start_index = self.ss
438
439 if 0x1D > self.address >= 0x00:
440 self.put(self.ss, reg_bit[2], self.out_ann, [3, [str(self.address)]])
441 self.put(self.ss, reg_bit[2], self.out_ann, [4, [str(reg_value)]])
442 else:
443 self.put(self.ss, reg_bit[2], self.out_ann, [3, registers[self.address]])
444 handle_reg = getattr(self, 'handle_reg_0x%02X' % self.address)
445 handle_reg(reg_value)
446
447 self.reg = []
448 self.address += 1
449 self.ss = -1