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