]> sigrok.org Git - libsigrokdecode.git/blob - decoders/rc_encode/pd.py
56b60caed3c1067fa8bdbca294620a5709e2c92f
[libsigrokdecode.git] / decoders / rc_encode / pd.py
1 ##
2 ## This file is part of the libsigrokdecode project.
3 ##
4 ## Copyright (C) 2018 Steve R <steversig@virginmedia.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 bitvals = ('0', '1', 'f', 'U')
23
24 def decode_bit(edges):
25     # Datasheet says long pulse is 3 times short pulse.
26     lmin = 2 # long min multiplier
27     lmax = 5 # long max multiplier
28     eqmin = 0.5 # equal min multiplier
29     eqmax = 1.5 # equal max multiplier
30     if ( # 0 -___-___
31         (edges[1] >= edges[0] * lmin and edges[1] <= edges[0] * lmax) and
32         (edges[2] >= edges[0] * eqmin and edges[2] <= edges[0] * eqmax) and
33         (edges[3] >= edges[0] * lmin and edges[3] <= edges[0] * lmax)):
34         return '0'
35     elif ( # 1 ---_---_
36         (edges[0] >= edges[1] * lmin and edges[0] <= edges[1] * lmax) and
37         (edges[0] >= edges[2] * eqmin and edges[0] <= edges[2] * eqmax) and
38         (edges[0] >= edges[3] * lmin and edges[0] <= edges[3] * lmax)):
39         return '1'
40     elif ( # float ---_-___
41         (edges[1] >= edges[0] * lmin and edges[1] <= edges[0] * lmax) and
42         (edges[2] >= edges[0] * lmin and edges[2] <= edges[0]* lmax) and
43         (edges[3] >= edges[0] * eqmin and edges[3] <= edges[0] * eqmax)):
44         return 'f'
45     else:
46         return 'U'
47
48 def pinlabels(bit_count):
49     if bit_count <= 6:
50         return 'A%i' % (bit_count - 1)
51     else:
52         return 'A%i/D%i' % (bit_count - 1, 12 - bit_count)
53
54 def decode_model(model, bits):
55     if model == 'maplin_l95ar':
56         address = 'Addr' # Address pins A0 to A5
57         for i in range(0, 6):
58             address += ' %i:' % (i + 1) + ('on' if bits[i][0] == '0' else 'off')
59         button = 'Button'
60         # Button pins A6/D5 to A11/D0
61         if bits[6][0] == '0' and bits[11][0] == '0':
62             button += ' A ON/OFF'
63         elif bits[7][0] == '0' and bits[11][0] == '0':
64             button += ' B ON/OFF'
65         elif bits[9][0] == '0' and bits[11][0] == '0':
66             button += ' C ON/OFF'
67         elif bits[8][0] == '0' and bits[11][0] == '0':
68             button += ' D ON/OFF'
69         else:
70             button += ' Unknown'
71         return ['%s' % address, bits[0][1], bits[5][2], \
72                 '%s' % button, bits[6][1], bits[11][2]]
73
74 class Decoder(srd.Decoder):
75     api_version = 3
76     id = 'rc_encode'
77     name = 'RC encode'
78     longname = 'Remote control encoder'
79     desc = 'PT2262/HX2262/SC5262 remote control encoder protocol.'
80     license = 'gplv2+'
81     inputs = ['logic']
82     outputs = []
83     channels = (
84         {'id': 'data', 'name': 'Data', 'desc': 'Data line'},
85     )
86     annotations = (
87         ('bit-0', 'Bit 0'),
88         ('bit-1', 'Bit 1'),
89         ('bit-f', 'Bit f'),
90         ('bit-U', 'Bit U'),
91         ('bit-sync', 'Bit sync'),
92         ('pin', 'Pin'),
93         ('code-word-addr', 'Code word address'),
94         ('code-word-data', 'Code word data'),
95     )
96     annotation_rows = (
97         ('bits', 'Bits', (0, 1, 2, 3, 4)),
98         ('pins', 'Pins', (5,)),
99         ('code-words', 'Code words', (6, 7)),
100     )
101     options = (
102         {'id': 'remote', 'desc': 'Remote', 'default': 'none', 
103             'values': ('none', 'maplin_l95ar')},
104     )
105
106     def __init__(self):
107         self.reset()
108
109     def reset(self):
110         self.samplenumber_last = None
111         self.pulses = []
112         self.bits = []
113         self.labels = []
114         self.bit_count = 0
115         self.ss = None
116         self.es = None
117         self.state = 'IDLE'
118
119     def start(self):
120         self.out_ann = self.register(srd.OUTPUT_ANN)
121         self.model = self.options['remote']
122
123     def putx(self, data):
124         self.put(self.ss, self.es, self.out_ann, data)
125
126     def decode(self):
127         while True:
128             pin = self.wait({0: 'e'})
129             self.state = 'DECODING'
130
131             if not self.samplenumber_last: # Set counters to start of signal.
132                 self.samplenumber_last = self.samplenum
133                 self.ss = self.samplenum
134                 continue
135
136             if self.bit_count < 12: # Decode A0 to A11.
137                 self.bit_count += 1
138                 for i in range(0, 4): # Get four pulses for each bit.
139                     if i > 0:
140                         pin = self.wait({0: 'e'}) # Get next 3 edges.
141                     samples = self.samplenum - self.samplenumber_last
142                     self.pulses.append(samples) # Save the pulse width.
143                     self.samplenumber_last = self.samplenum
144                 self.es = self.samplenum
145                 self.bits.append([decode_bit(self.pulses), self.ss,
146                                   self.es]) # Save states and times.
147                 idx = bitvals.index(decode_bit(self.pulses))
148                 self.putx([idx, [decode_bit(self.pulses)]]) # Write decoded bit.
149                 self.putx([5, [pinlabels(self.bit_count)]]) # Write pin labels.
150                 self.pulses = []
151                 self.ss = self.samplenum
152             else:
153                 if self.model != 'none':
154                     self.labels = decode_model(self.model, self.bits)
155                     self.put(self.labels[1], self.labels[2], self.out_ann,
156                              [6, [self.labels[0]]]) # Write model decode.
157                     self.put(self.labels[4], self.labels[5], self.out_ann,
158                              [7, [self.labels[3]]]) # Write model decode.
159                 samples = self.samplenum - self.samplenumber_last
160                 pin = self.wait({'skip': 8 * samples}) # Wait for end of sync bit.
161                 self.es = self.samplenum
162                 self.putx([4, ['Sync']]) # Write sync label.
163                 self.reset() # Reset and wait for next set of pulses.
164                 self.state = 'DECODE_TIMEOUT'
165             if not self.state == 'DECODE_TIMEOUT':
166                 self.samplenumber_last = self.samplenum