]>
Commit | Line | Data |
---|---|---|
23a8a383 JS |
1 | ## |
2 | ## This file is part of the libsigrokdecode project. | |
3 | ## | |
4 | ## Copyright (C) 2015 Jeremy Swanson <jeremy@rakocontrols.com> | |
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 | |
17 | ## along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | ## | |
19 | ||
20 | import sigrokdecode as srd | |
21 | ||
22 | class SamplerateError(Exception): | |
23 | pass | |
24 | ||
25 | class Decoder(srd.Decoder): | |
26 | api_version = 2 | |
27 | id = 'dsi' | |
28 | name = 'DSI' | |
92c117d6 | 29 | longname = 'Digital Serial Interface' |
23a8a383 JS |
30 | desc = 'DSI lighting control protocol.' |
31 | license = 'gplv2+' | |
32 | inputs = ['logic'] | |
33 | outputs = ['dsi'] | |
34 | channels = ( | |
35 | {'id': 'dsi', 'name': 'DSI', 'desc': 'DSI data line'}, | |
36 | ) | |
37 | options = ( | |
38 | {'id': 'polarity', 'desc': 'Polarity', 'default': 'active-high', | |
39 | 'values': ('active-low', 'active-high')}, | |
40 | ) | |
41 | annotations = ( | |
42 | ('bit', 'Bit'), | |
43 | ('startbit', 'Startbit'), | |
44 | ('Level', 'Dimmer level'), | |
45 | ('raw', 'Raw data'), | |
46 | ) | |
47 | annotation_rows = ( | |
48 | ('bits', 'Bits', (0,)), | |
49 | ('raw', 'Raw Data',(3,)), | |
50 | ('fields', 'Fields', (1, 2,)), | |
51 | ) | |
52 | ||
53 | def __init__(self): | |
54 | self.samplerate = None | |
55 | self.samplenum = None | |
56 | self.edges, self.bits, self.ss_es_bits = [], [], [] | |
57 | self.state = 'IDLE' | |
58 | self.nextSamplePoint = None | |
59 | self.nextSample = None | |
60 | ||
61 | def start(self): | |
62 | self.out_ann = self.register(srd.OUTPUT_ANN) | |
41b37321 | 63 | self.old_dsi = 1 if self.options['polarity'] == 'active-low' else 0 |
23a8a383 JS |
64 | |
65 | def metadata(self, key, value): | |
66 | if key == srd.SRD_CONF_SAMPLERATE: | |
67 | self.samplerate = value | |
68 | # One bit: 1666.7us (one half low, one half high). | |
69 | # This is how many samples are in 1TE. | |
70 | self.halfbit = int((self.samplerate * 0.0016667) / 2.0) | |
71 | ||
72 | def putb(self, bit1, bit2, data): | |
73 | ss, es = self.ss_es_bits[bit1][0], self.ss_es_bits[bit2][1] | |
74 | self.put(ss, es, self.out_ann, data) | |
75 | ||
76 | def handle_bits(self, length): | |
77 | a, c, f, g, b = 0, 0, 0, 0, self.bits | |
78 | # Individual raw bits. | |
79 | for i in range(length): | |
80 | if i == 0: | |
81 | ss = max(0, self.bits[0][0]) | |
82 | else: | |
83 | ss = self.ss_es_bits[i - 1][1] | |
84 | es = self.bits[i][0] + (self.halfbit * 2) | |
85 | self.ss_es_bits.append([ss, es]) | |
86 | self.putb(i, i, [0, ['%d' % self.bits[i][1]]]) | |
87 | # Bits[0:0]: Startbit | |
88 | s = ['Startbit: %d' % b[0][1], 'ST: %d' % b[0][1], 'ST', 'S', 'S'] | |
89 | self.putb(0, 0, [1, s]) | |
90 | self.putb(0, 0, [3, s]) | |
91 | # Bits[1:8] | |
92 | for i in range(8): | |
93 | f |= (b[1 + i][1] << (7 - i)) | |
94 | g = f / 2.55 | |
95 | if length == 9: # BACKWARD Frame | |
96 | s = ['Data: %02X' % f, 'Dat: %02X' % f, | |
97 | 'Dat: %02X' % f, 'D: %02X' % f, 'D'] | |
98 | self.putb(1, 8, [3, s]) | |
99 | s = ['Level: %d%%' % g, 'Lev: %d%%' % g, | |
100 | 'Lev: %d%%' % g, 'L: %d' % g, 'D'] | |
101 | self.putb(1, 8, [2, s]) | |
102 | return | |
103 | ||
104 | def reset_decoder_state(self): | |
105 | self.edges, self.bits, self.ss_es_bits = [], [], [] | |
106 | self.state = 'IDLE' | |
107 | ||
108 | def decode(self, ss, es, data): | |
109 | if not self.samplerate: | |
110 | raise SamplerateError('Cannot decode without samplerate.') | |
111 | bit = 0; | |
112 | for (self.samplenum, pins) in data: | |
41b37321 | 113 | self.dsi = pins[0] |
23a8a383 JS |
114 | # data.itercnt += 1 |
115 | if self.options['polarity'] == 'active-high': | |
41b37321 | 116 | self.dsi ^= 1 # Invert. |
23a8a383 JS |
117 | |
118 | # State machine. | |
119 | if self.state == 'IDLE': | |
120 | # Wait for any edge (rising or falling). | |
41b37321 | 121 | if self.old_dsi == self.dsi: |
23a8a383 JS |
122 | continue |
123 | # Add in the first half of the start bit. | |
124 | self.edges.append(self.samplenum - int(self.halfbit)) | |
125 | self.edges.append(self.samplenum) | |
126 | # Start bit is 0->1. | |
41b37321 | 127 | self.phase0 = self.dsi ^ 1 |
23a8a383 | 128 | self.state = 'PHASE1' |
41b37321 | 129 | self.old_dsi = self.dsi |
23a8a383 JS |
130 | # Get the next sample point. |
131 | # self.nextSamplePoint = self.samplenum + int(self.halfbit / 2) | |
41b37321 UH |
132 | self.old_dsi = self.dsi |
133 | # bit = self.dsi | |
23a8a383 JS |
134 | continue |
135 | ||
136 | # if(self.samplenum == self.nextSamplePoint): | |
41b37321 | 137 | # bit = self.dsi |
23a8a383 JS |
138 | # continue |
139 | ||
41b37321 | 140 | if self.old_dsi != self.dsi: |
23a8a383 JS |
141 | self.edges.append(self.samplenum) |
142 | elif self.samplenum == (self.edges[-1] + int(self.halfbit * 1.5)): | |
143 | self.edges.append(self.samplenum - int(self.halfbit * 0.5)) | |
144 | else: | |
145 | continue | |
146 | ||
41b37321 | 147 | bit = self.old_dsi |
23a8a383 JS |
148 | if self.state == 'PHASE0': |
149 | self.phase0 = bit | |
150 | self.state = 'PHASE1' | |
151 | elif self.state == 'PHASE1': | |
152 | if (bit == 1) and (self.phase0 == 1): # Stop bit | |
153 | if len(self.bits) == 17 or len(self.bits) == 9: | |
154 | # Forward or Backward | |
155 | self.handle_bits(len(self.bits)) | |
156 | self.reset_decoder_state() # Reset upon errors. | |
157 | continue | |
158 | else: | |
159 | self.bits.append([self.edges[-3], bit]) | |
160 | self.state = 'PHASE0' | |
161 | ||
162 | # self.nextSamplePoint = self.edges[-1] + int(self.halfbit / 2) | |
163 | ||
41b37321 | 164 | self.old_dsi = self.dsi |