]>
Commit | Line | Data |
---|---|---|
979d5dd0 PLE |
1 | ## |
2 | ## This file is part of the libsigrokdecode project. | |
3 | ## | |
4 | ## Copyright (C) 2015 Paul Evans <leonerd@leonerd.org.uk> | |
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 2 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 | |
4539e9ca | 17 | ## along with this program; if not, see <http://www.gnu.org/licenses/>. |
979d5dd0 PLE |
18 | ## |
19 | ||
20 | import re | |
21 | import sigrokdecode as srd | |
22 | ||
23 | def _decode_intensity(val): | |
24 | intensity = val & 0x0f | |
25 | if intensity == 0: | |
26 | return 'min' | |
27 | elif intensity == 15: | |
28 | return 'max' | |
29 | else: | |
30 | return intensity | |
31 | ||
32 | registers = { | |
33 | 0x00: ['No-op', lambda _: ''], | |
34 | 0x09: ['Decode', lambda v: '0b{:08b}'.format(v)], | |
35 | 0x0A: ['Intensity', _decode_intensity], | |
36 | 0x0B: ['Scan limit', lambda v: 1 + v], | |
37 | 0x0C: ['Shutdown', lambda v: 'off' if v else 'on'], | |
38 | 0x0F: ['Display test', lambda v: 'on' if v else 'off'] | |
39 | } | |
40 | ||
41 | ann_reg, ann_digit, ann_warning = range(3) | |
42 | ||
43 | class Decoder(srd.Decoder): | |
b197383c | 44 | api_version = 3 |
979d5dd0 PLE |
45 | id = 'max7219' |
46 | name = 'MAX7219' | |
47 | longname = 'Maxim MAX7219/MAX7221' | |
2787cf2a | 48 | desc = 'Maxim MAX72xx series 8-digit LED display driver.' |
979d5dd0 PLE |
49 | license = 'gplv2+' |
50 | inputs = ['spi'] | |
6cbba91f | 51 | outputs = [] |
d6d8a8a4 | 52 | tags = ['Display'] |
979d5dd0 PLE |
53 | annotations = ( |
54 | ('register', 'Registers written to the device'), | |
55 | ('digit', 'Digits displayed on the device'), | |
56 | ('warnings', 'Human-readable warnings'), | |
57 | ) | |
58 | annotation_rows = ( | |
59 | ('commands', 'Commands', (ann_reg, ann_digit)), | |
60 | ('warnings', 'Warnings', (ann_warning,)), | |
61 | ) | |
62 | ||
34f18d2f GS |
63 | def __init__(self): |
64 | self.reset() | |
65 | ||
66 | def reset(self): | |
67 | pass | |
68 | ||
979d5dd0 PLE |
69 | def start(self): |
70 | self.out_ann = self.register(srd.OUTPUT_ANN) | |
71 | self.pos = 0 | |
72 | self.cs_start = 0 | |
73 | ||
74 | def putreg(self, ss, es, reg, value): | |
75 | self.put(ss, es, self.out_ann, [ann_reg, ['%s: %s' % (reg, value)]]) | |
76 | ||
77 | def putdigit(self, ss, es, digit, value): | |
78 | self.put(ss, es, self.out_ann, [ann_digit, ['Digit %d: %02X' % (digit, value)]]) | |
79 | ||
80 | def putwarn(self, ss, es, message): | |
81 | self.put(ss, es, self.out_ann, [ann_warning, [message]]) | |
82 | ||
83 | def decode(self, ss, es, data): | |
84 | ptype, mosi, _ = data | |
85 | ||
86 | if ptype == 'DATA': | |
87 | if not self.cs_asserted: | |
88 | return | |
89 | ||
90 | if self.pos == 0: | |
91 | self.addr = mosi | |
92 | self.addr_start = ss | |
93 | elif self.pos == 1: | |
94 | if self.addr >= 1 and self.addr <= 8: | |
95 | self.putdigit(self.addr_start, es, self.addr, mosi) | |
96 | elif self.addr in registers: | |
97 | name, decoder = registers[self.addr] | |
98 | self.putreg(self.addr_start, es, name, decoder(mosi)) | |
99 | else: | |
100 | self.putwarn(self.addr_start, es, | |
101 | 'Unknown register %02X' % (self.addr)) | |
102 | ||
103 | self.pos += 1 | |
104 | elif ptype == 'CS-CHANGE': | |
105 | self.cs_asserted = mosi | |
106 | if self.cs_asserted: | |
107 | self.pos = 0 | |
108 | self.cs_start = ss | |
109 | else: | |
110 | if self.pos == 1: | |
111 | # Don't warn if pos=0 so that CS# glitches don't appear | |
112 | # as spurious warnings. | |
113 | self.putwarn(self.cs_start, es, 'Short write') | |
114 | elif self.pos > 2: | |
115 | self.putwarn(self.cs_start, es, 'Overlong write') |