]> sigrok.org Git - libsigrokdecode.git/blob - decoders/adxl345/pd.py
c0b9a48444b91a35c3ac9abfc5f2d38ebe4e6f29
[libsigrokdecode.git] / decoders / adxl345 / pd.py
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
20 import sigrokdecode as srd
21 from .lists import *
22
23 WORD_SIZE = 8
24
25 class Channel():
26     MISO, MOSI = range(2)
27
28 class Operation():
29     READ, WRITE = range(2)
30
31 class 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
39 class 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
60 class 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):
87         self.mosi, self.miso = [], []
88         self.reg = []
89         self.operation = None
90         self.address = 0
91         self.data = -1
92         self.state = 'IDLE'
93         self.ss, self.es = -1, -1
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):
107         start = self.ss + (self.samples_per_bit * start_index)
108         stop = start + (self.samples_per_bit * (stop_index - start_index + 1))
109         self.put(start, stop, self.out_ann, data)
110
111     def handle_reg_with_scaling_factor(self, data, factor, name, unit, error_msg):
112         if data == 0 and error_msg is not None:
113             self.putx([5, error_msg])
114         else:
115             result = (data * factor) / 1000
116             self.putx([4, ['%s: %f %s' % (name, result, unit), '%f %s' % (result, unit)]])
117
118     def handle_reg_bit_msg(self, bit, index, en_msg, dis_msg):
119         self.putb([4, [en_msg if bit else dis_msg]], index)
120
121     def interpret_bits(self, data, bits):
122         bits_values = []
123         for offset in range(8):
124             bits_values.insert(0, (data & (1 << offset)) >> offset)
125
126         for index in range(len(bits)):
127             if bits[index] is None:
128                 continue
129             bit = bits[index]
130             bit.set_value(bits_values[index])
131             self.putb([4, bit.get_bit_annotation()], index)
132
133         return list(reversed(bits_values))
134
135     def reverse_bit_index(self, index, word_size):
136         return word_size - index - 1
137
138     def get_decimal_number(self, bits, start_index, stop_index):
139         number = 0
140         interval = range(start_index, stop_index + 1, 1)
141         for index, offset in zip(interval, range(len(interval))):
142             bit = bits[index]
143             number = number | (bit << offset)
144         return number
145
146     def get_axis_value(self, data, axis):
147         if self.data != - 1:
148             data <<= 8
149             self.data |= data
150             self.put(self.start_index, self.es, self.out_ann,
151                 [4, ['%s: 0x%04X' % (axis, self.data), str(data)]])
152             self.data = -1
153         else:
154             self.putx([4, [str(data)]])
155
156     def handle_reg_0x1D(self, data):
157         self.handle_reg_with_scaling_factor(data, 62.5, 'Threshold', 'g',
158             error_messages['undesirable'])
159
160     def handle_reg_0x1E(self, data):
161         self.handle_reg_with_scaling_factor(data, 15.6, 'OFSX', 'g', None)
162
163     def handle_reg_0x1F(self, data):
164         self.handle_reg_with_scaling_factor(data, 15.6, 'OFSY', 'g', None)
165
166     def handle_reg_0x20(self, data):
167         self.handle_reg_with_scaling_factor(data, 15.6, 'OFSZ', 'g', None)
168
169     def handle_reg_0x21(self, data):
170         self.handle_reg_with_scaling_factor(data, 0.625, 'Time', 's',
171             error_messages['dis_single_double'])
172
173     def handle_reg_0x22(self, data):
174         self.handle_reg_with_scaling_factor(data, 62.5, 'Latent', 's',
175             error_messages['dis_double'])
176
177     def handle_reg_0x23(self, data):
178         self.handle_reg_with_scaling_factor(data, 1.25, 'Latent', 's',
179             error_messages['dis_double'])
180
181     def handle_reg_0x24(self, data):
182         self.handle_reg_with_scaling_factor(data, 62.5, 'Latent', 's',
183             error_messages['undesirable'])
184
185     def handle_reg_0x25(self, data):
186         self.handle_reg_0x1D(data)
187
188     def handle_reg_0x26(self, data):
189         self.handle_reg_with_scaling_factor(data, 1000, 'Time', 's',
190             error_messages['interrupt'])
191
192     def handle_reg_0x27(self, data):
193         bits = [Bit('ACT', BitType.AC_DC),
194                 Bit('ACT_X', BitType.ENABLE),
195                 Bit('ACT_Y', BitType.ENABLE),
196                 Bit('ACT_Z', BitType.ENABLE),
197                 Bit('INACT', BitType.AC_DC),
198                 Bit('INACT_X', BitType.ENABLE),
199                 Bit('INACT_Y', BitType.ENABLE),
200                 Bit('INACT_Z', BitType.ENABLE)]
201         self.interpret_bits(data, bits)
202
203     def handle_reg_0x28(self, data):
204         self.handle_reg_0x1D(data)
205
206     def handle_reg_0x29(self, data):
207         self.handle_reg_with_scaling_factor(data, 5, 'Time', 's',
208             error_messages['undesirable'])
209
210     def handle_reg_0x2A(self, data):
211         bits = [Bit('', BitType.UNUSED),
212                 Bit('', BitType.UNUSED),
213                 Bit('', BitType.UNUSED),
214                 Bit('', BitType.UNUSED),
215                 Bit('', BitType.OTHER, {1: ['Suppressed', 'Suppr', 'S'],
216                     0: ['Unsuppressed', 'Unsuppr', 'Uns'],}),
217                 Bit('TAP_X', BitType.ENABLE),
218                 Bit('TAP_Y', BitType.ENABLE),
219                 Bit('TAP_Z', BitType.ENABLE)]
220         self.interpret_bits(data, bits)
221
222     def handle_reg_0x2B(self, data):
223         bits = [Bit('', BitType.UNUSED),
224                 Bit('ACT_X', BitType.SOURCE),
225                 Bit('ACT_Y', BitType.SOURCE),
226                 Bit('ACT_Z', BitType.SOURCE),
227                 Bit('', BitType.OTHER, {1: ['Asleep', 'Asl'],
228                     0: ['Not asleep', 'Not asl', '!Asl'],}),
229                 Bit('TAP_X', BitType.SOURCE),
230                 Bit('TAP_Y', BitType.SOURCE),
231                 Bit('TAP_Z', BitType.SOURCE)]
232         self.interpret_bits(data, bits)
233
234     def handle_reg_0x2C(self, data):
235         bits = [Bit('', BitType.UNUSED),
236                 Bit('', BitType.UNUSED),
237                 Bit('', BitType.UNUSED),
238                 Bit('', BitType.OTHER, {1: ['Reduce power', 'Reduce pw', 'Red pw'], 0: ['Normal operation', 'Normal op', 'Norm op'],})]
239         bits_values = self.interpret_bits(data, bits)
240
241         start_index, stop_index = 0, 3
242         rate = self.get_decimal_number(bits_values, start_index, start_index)
243         self.putbs([4, ['%f' % rate_code[rate]]],
244             self.reverse_bit_index(stop_index, WORD_SIZE),
245             self.reverse_bit_index(start_index, WORD_SIZE))
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
256         start_index, stop_index = 0, 1
257         wakeup = self.get_decimal_number(bits_values, start_index, stop_index)
258         frequency = 2 ** (~wakeup & 0x03)
259         self.putbs([4, ['%d Hz' % frequency]],
260             self.reverse_bit_index(stop_index, WORD_SIZE),
261             self.reverse_bit_index(start_index, WORD_SIZE))
262
263     def handle_reg_0x2E(self, data):
264         bits = [Bit('DATA_READY', BitType.ENABLE),
265                 Bit('SINGLE_TAP', BitType.ENABLE),
266                 Bit('DOUBLE_TAP', BitType.ENABLE),
267                 Bit('Activity', BitType.ENABLE),
268                 Bit('Inactivity', BitType.ENABLE),
269                 Bit('FREE_FALL', BitType.ENABLE),
270                 Bit('Watermark', BitType.ENABLE),
271                 Bit('Overrun', BitType.ENABLE)]
272         self.interpret_bits(data, bits)
273
274     def handle_reg_0x2F(self, data):
275         bits = [Bit('DATA_READY', BitType.INTERRUPT),
276                 Bit('SINGLE_TAP', BitType.INTERRUPT),
277                 Bit('DOUBLE_TAP', BitType.INTERRUPT),
278                 Bit('Activity', BitType.INTERRUPT),
279                 Bit('Inactivity', BitType.INTERRUPT),
280                 Bit('FREE_FALL', BitType.INTERRUPT),
281                 Bit('Watermark', BitType.INTERRUPT),
282                 Bit('Overrun', BitType.INTERRUPT)]
283         self.interpret_bits(data, bits)
284
285     def handle_reg_0x30(self, data):
286         bits = [Bit('DATA_READY', BitType.SOURCE),
287                 Bit('SINGLE_TAP', BitType.SOURCE),
288                 Bit('DOUBLE_TAP', BitType.SOURCE),
289                 Bit('Activity', BitType.SOURCE),
290                 Bit('Inactivity', BitType.SOURCE),
291                 Bit('FREE_FALL', BitType.SOURCE),
292                 Bit('Watermark', BitType.SOURCE),
293                 Bit('Overrun', BitType.SOURCE)]
294         self.interpret_bits(data, bits)
295
296     def handle_reg_0x31(self, data):
297         bits = [Bit('SELF_TEST', BitType.ENABLE),
298                 Bit('', BitType.OTHER, {1: ['3-wire SPI', '3-SPI'], 0: ['4-wire SPI', '4-SPI'],}),
299                 Bit('', BitType.OTHER, {1: ['INT ACT LOW', 'INT LOW'], 0: ['INT ACT HIGH', 'INT HIGH'],}),
300                 Bit('', BitType.UNUSED),
301                 Bit('', BitType.OTHER, {1: ['Full resolution', 'Full res'], 0: ['10-bit mode', '10-bit'],}),
302                 Bit('', BitType.OTHER, {1: ['MSB mode', 'MSB'], 0: ['LSB mode', 'LSB'],})]
303         bits_values = self.interpret_bits(data, bits)
304
305         start_index, stop_index = 0, 1
306         range_g = self.get_decimal_number(bits_values, start_index, stop_index)
307         result = 2 ** (range_g + 1)
308         self.putbs([4, ['+/-%d g' % result]],
309             self.reverse_bit_index(stop_index, WORD_SIZE),
310             self.reverse_bit_index(start_index, WORD_SIZE))
311
312     def handle_reg_0x32(self, data):
313         self.data = data
314         self.putx([4, [str(data)]])
315
316     def handle_reg_0x33(self, data):
317         self.get_axis_value(data, 'X')
318
319     def handle_reg_0x34(self, data):
320         self.handle_reg_0x32(data)
321
322     def handle_reg_0x35(self, data):
323         self.get_axis_value(data, 'Y')
324
325     def handle_reg_0x36(self, data):
326         self.handle_reg_0x32(data)
327
328     def handle_reg_0x37(self, data):
329         self.get_axis_value(data, 'Z')
330
331     def handle_reg_0x38(self, data):
332         bits = [None,
333                 None,
334                 Bit('', BitType.OTHER, {1: ['Trig-INT2', 'INT2'], 0: ['Trig-INT1', 'INT1'], })]
335         bits_values = self.interpret_bits(data, bits)
336
337         start_index, stop_index = 6, 7
338         fifo = self.get_decimal_number(bits_values, start_index, stop_index)
339         self.putbs([4, [fifo_modes[fifo]]],
340             self.reverse_bit_index(stop_index, WORD_SIZE),
341             self.reverse_bit_index(start_index, WORD_SIZE))
342
343         start_index, stop_index = 0, 4
344         samples = self.get_decimal_number(bits_values, start_index, stop_index)
345         self.putbs([4, ['Samples: %d' % samples, '%d' % samples]],
346             self.reverse_bit_index(stop_index, WORD_SIZE),
347             self.reverse_bit_index(start_index, WORD_SIZE))
348
349     def handle_reg_0x39(self, data):
350         bits = [Bit('', BitType.OTHER, {1: ['Triggered', 'Trigg'], 0: ['Not triggered', 'Not trigg'],}),
351                 Bit('', BitType.UNUSED)]
352         bits_values = self.interpret_bits(data, bits)
353
354         start_index, stop_index = 0, 5
355         entries = self.get_decimal_number(bits_values, start_index, stop_index)
356         self.putbs([4, ['Entries: %d' % entries, '%d' % entries]],
357             self.reverse_bit_index(stop_index, WORD_SIZE),
358             self.reverse_bit_index(start_index, WORD_SIZE))
359
360     def get_bit(self, channel):
361         if (channel == Channel.MOSI and self.mosi is None) or \
362                 (channel == Channel.MISO and self.miso is None):
363             raise Exception('No available data')
364
365         mosi_bit, miso_bit = 0, 0
366         if self.miso is not None:
367             if len(self.mosi) < 0:
368                 raise Exception('No available data')
369             miso_bit = self.miso.pop(0)
370         if self.miso is not None:
371             if len(self.miso) < 0:
372                 raise Exception('No available data')
373             mosi_bit = self.mosi.pop(0)
374
375         if channel == Channel.MOSI:
376             return mosi_bit
377         return miso_bit
378
379     def decode(self, ss, es, data):
380         ptype = data[0]
381
382         if ptype == 'CS-CHANGE':
383             cs_old, cs_new = data[1:]
384             if cs_old is not None and cs_old == 1 and cs_new == 0:
385                 self.ss, self.es = ss, es
386                 self.state = 'ADDRESS-BYTE'
387             else:
388                 self.state = 'IDLE'
389
390         elif ptype == 'BITS':
391             if data[1] is not None:
392                 self.mosi = list(reversed(data[1]))
393             if data[2] is not None:
394                 self.miso = list(reversed(data[2]))
395
396             if self.mosi is None and self.miso is None:
397                 return
398
399             if self.state == 'ADDRESS-BYTE':
400                 # OPERATION BIT
401                 op_bit = self.get_bit(Channel.MOSI)
402                 self.put(op_bit[1], op_bit[2], self.out_ann,
403                     [0 if op_bit[0] else 1, operations[op_bit[0]]])
404                 self.operation = Operation.READ if op_bit[0] else Operation.WRITE
405                 # MULTIPLE-BYTE BIT
406                 mb_bit = self.get_bit(Channel.MOSI)
407                 self.put(mb_bit[1], mb_bit[2], self.out_ann, [2, number_bytes[mb_bit[0]]])
408
409                 # REGISTER 6-BIT ADDRESS
410                 self.address = 0
411                 start_sample = self.mosi[0][1]
412                 addr_bit = []
413                 for i in range(6):
414                     addr_bit = self.get_bit(Channel.MOSI)
415                     self.address |= addr_bit[0]
416                     self.address <<= 1
417                 self.address >>= 1
418                 self.put(start_sample, addr_bit[2], self.out_ann,
419                     [3, ['ADDRESS: 0x%02X' % self.address, 'ADDR: 0x%02X'
420                     % self.address, '0x%02X' % self.address]])
421                 self.ss = -1
422                 self.state = 'DATA'
423
424             elif self.state == 'DATA':
425                 self.reg.extend(self.mosi if self.operation == Operation.WRITE else self.miso)
426
427                 self.mosi, self.miso = [], []
428                 if self.ss == -1:
429                     self.ss, self.es = self.reg[0][1], es
430                     self.samples_per_bit = self.reg[0][2] - self.ss
431
432                 if len(self.reg) < 8:
433                     return
434                 else:
435                     reg_value = 0
436                     reg_bit = []
437                     for offset in range(7, -1, -1):
438                         reg_bit = self.reg.pop(0)
439
440                         mask = reg_bit[0] << offset
441                         reg_value |= mask
442
443                     if self.address < 0x00 or self.address > 0x39:
444                         return
445
446                     if self.address in [0x32, 0x34, 0x36]:
447                         self.start_index = self.ss
448
449                     if 0x1D > self.address >= 0x00:
450                         self.put(self.ss, reg_bit[2], self.out_ann, [3, [str(self.address)]])
451                         self.put(self.ss, reg_bit[2], self.out_ann, [4, [str(reg_value)]])
452                     else:
453                         self.put(self.ss, reg_bit[2], self.out_ann, [3, registers[self.address]])
454                         handle_reg = getattr(self, 'handle_reg_0x%02X' % self.address)
455                         handle_reg(reg_value)
456
457                     self.reg = []
458                     self.address += 1
459                     self.ss = -1