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