]> sigrok.org Git - libsigrokdecode.git/blame - decoders/adxl345/pd.py
Add AD5626 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
7b0f3c78 21from common.srdhelper import SrdIntEnum
f47d3a2d
TP
22from .lists import *
23
24WORD_SIZE = 8
25
26class Channel():
88098c75 27 MISO, MOSI = range(2)
f47d3a2d
TP
28
29class Operation():
88098c75 30 READ, WRITE = range(2)
f47d3a2d
TP
31
32class 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
40class 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
7b0f3c78
UH
61Ann = SrdIntEnum.from_str('Ann', 'READ WRITE MB REG_ADDRESS REG_DATA WARNING')
62
93ddf98b
UH
63St = SrdIntEnum.from_str('St', 'IDLE ADDRESS_BYTE DATA')
64
f47d3a2d
TP
65class 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 = (
7b0f3c78
UH
84 ('reg', 'Registers', (Ann.READ, Ann.WRITE, Ann.MB, Ann.REG_ADDRESS)),
85 ('data', 'Data', (Ann.REG_DATA, Ann.WARNING)),
f47d3a2d
TP
86 )
87
88 def __init__(self):
89 self.reset()
90
91 def reset(self):
88098c75 92 self.mosi, self.miso = [], []
f47d3a2d
TP
93 self.reg = []
94 self.operation = None
95 self.address = 0
96 self.data = -1
93ddf98b 97 self.state = St.IDLE
88098c75 98 self.ss, self.es = -1, -1
f47d3a2d
TP
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):
4b0d57fc
UH
112 start_index = self.reverse_bit_index(start_index, WORD_SIZE)
113 stop_index = self.reverse_bit_index(stop_index, WORD_SIZE)
f47d3a2d
TP
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:
7b0f3c78 120 self.putx([Ann.WARNING, error_msg])
f47d3a2d
TP
121 else:
122 result = (data * factor) / 1000
7b0f3c78 123 self.putx([Ann.REG_DATA, ['%s: %f %s' % (name, result, unit), '%f %s' % (result, unit)]])
f47d3a2d
TP
124
125 def handle_reg_bit_msg(self, bit, index, en_msg, dis_msg):
7b0f3c78 126 self.putb([Ann.REG_DATA, [en_msg if bit else dis_msg]], index)
f47d3a2d
TP
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])
7b0f3c78 138 self.putb([Ann.REG_DATA, bit.get_bit_annotation()], index)
f47d3a2d
TP
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,
7b0f3c78 158 [Ann.REG_DATA, ['%s: 0x%04X' % (axis, self.data), str(data)]])
f47d3a2d
TP
159 self.data = -1
160 else:
7b0f3c78 161 self.putx([Ann.REG_DATA, [str(data)]])
f47d3a2d 162
2833e43d 163 def handle_reg_0x1d(self, data):
f47d3a2d
TP
164 self.handle_reg_with_scaling_factor(data, 62.5, 'Threshold', 'g',
165 error_messages['undesirable'])
166
2833e43d 167 def handle_reg_0x1e(self, data):
f47d3a2d
TP
168 self.handle_reg_with_scaling_factor(data, 15.6, 'OFSX', 'g', None)
169
2833e43d 170 def handle_reg_0x1f(self, data):
f47d3a2d
TP
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):
81bf080f 181 self.handle_reg_with_scaling_factor(data, 1.25, 'Latent', 's',
f47d3a2d
TP
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):
2833e43d 193 self.handle_reg_0x1d(data)
f47d3a2d
TP
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):
2833e43d 211 self.handle_reg_0x1d(data)
f47d3a2d
TP
212
213 def handle_reg_0x29(self, data):
214 self.handle_reg_with_scaling_factor(data, 5, 'Time', 's',
215 error_messages['undesirable'])
216
2833e43d 217 def handle_reg_0x2a(self, data):
f47d3a2d
TP
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
2833e43d 229 def handle_reg_0x2b(self, data):
f47d3a2d
TP
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
2833e43d 241 def handle_reg_0x2c(self, data):
f47d3a2d
TP
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
88098c75 248 start_index, stop_index = 0, 3
327a281f 249 rate = self.get_decimal_number(bits_values, start_index, stop_index)
7b0f3c78 250 self.putbs([Ann.REG_DATA, ['%f' % rate_code[rate]]], stop_index, start_index)
f47d3a2d 251
2833e43d 252 def handle_reg_0x2d(self, data):
f47d3a2d
TP
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
88098c75 261 start_index, stop_index = 0, 1
f47d3a2d
TP
262 wakeup = self.get_decimal_number(bits_values, start_index, stop_index)
263 frequency = 2 ** (~wakeup & 0x03)
7b0f3c78 264 self.putbs([Ann.REG_DATA, ['%d Hz' % frequency]], stop_index, start_index)
f47d3a2d 265
2833e43d 266 def handle_reg_0x2e(self, data):
f47d3a2d
TP
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
2833e43d 277 def handle_reg_0x2f(self, data):
f47d3a2d
TP
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
88098c75 308 start_index, stop_index = 0, 1
f47d3a2d
TP
309 range_g = self.get_decimal_number(bits_values, start_index, stop_index)
310 result = 2 ** (range_g + 1)
7b0f3c78 311 self.putbs([Ann.REG_DATA, ['+/-%d g' % result]], stop_index, start_index)
f47d3a2d
TP
312
313 def handle_reg_0x32(self, data):
314 self.data = data
7b0f3c78 315 self.putx([Ann.REG_DATA, [str(data)]])
f47d3a2d
TP
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
88098c75 338 start_index, stop_index = 6, 7
f47d3a2d 339 fifo = self.get_decimal_number(bits_values, start_index, stop_index)
7b0f3c78 340 self.putbs([Ann.REG_DATA, [fifo_modes[fifo]]], stop_index, start_index)
f47d3a2d 341
88098c75 342 start_index, stop_index = 0, 4
f47d3a2d 343 samples = self.get_decimal_number(bits_values, start_index, stop_index)
7b0f3c78 344 self.putbs([Ann.REG_DATA, ['Samples: %d' % samples, '%d' % samples]], stop_index, start_index)
f47d3a2d
TP
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
88098c75 351 start_index, stop_index = 0, 5
f47d3a2d 352 entries = self.get_decimal_number(bits_values, start_index, stop_index)
7b0f3c78 353 self.putbs([Ann.REG_DATA, ['Entries: %d' % entries, '%d' % entries]], stop_index, start_index)
f47d3a2d
TP
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:
88098c75 380 self.ss, self.es = ss, es
93ddf98b 381 self.state = St.ADDRESS_BYTE
f47d3a2d 382 else:
93ddf98b 383 self.state = St.IDLE
f47d3a2d
TP
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
93ddf98b 394 if self.state == St.ADDRESS_BYTE:
f47d3a2d
TP
395 # OPERATION BIT
396 op_bit = self.get_bit(Channel.MOSI)
88098c75 397 self.put(op_bit[1], op_bit[2], self.out_ann,
7b0f3c78 398 [Ann.READ if op_bit[0] else Ann.WRITE, operations[op_bit[0]]])
88098c75 399 self.operation = Operation.READ if op_bit[0] else Operation.WRITE
f47d3a2d
TP
400 # MULTIPLE-BYTE BIT
401 mb_bit = self.get_bit(Channel.MOSI)
7b0f3c78 402 self.put(mb_bit[1], mb_bit[2], self.out_ann, [Ann.MB, number_bytes[mb_bit[0]]])
f47d3a2d
TP
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,
7b0f3c78 414 [Ann.REG_ADDRESS, ['ADDRESS: 0x%02X' % self.address, 'ADDR: 0x%02X'
f47d3a2d
TP
415 % self.address, '0x%02X' % self.address]])
416 self.ss = -1
93ddf98b 417 self.state = St.DATA
f47d3a2d 418
93ddf98b 419 elif self.state == St.DATA:
88098c75 420 self.reg.extend(self.mosi if self.operation == Operation.WRITE else self.miso)
f47d3a2d 421
88098c75 422 self.mosi, self.miso = [], []
f47d3a2d 423 if self.ss == -1:
88098c75 424 self.ss, self.es = self.reg[0][1], es
f47d3a2d
TP
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:
7b0f3c78
UH
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)]])
f47d3a2d 447 else:
7b0f3c78 448 self.put(self.ss, reg_bit[2], self.out_ann, [Ann.REG_ADDRESS, registers[self.address]])
2833e43d 449 handle_reg = getattr(self, 'handle_reg_0x%02x' % self.address)
f47d3a2d
TP
450 handle_reg(reg_value)
451
452 self.reg = []
453 self.address += 1
454 self.ss = -1