## ## This file is part of the libsigrokdecode project. ## ## Copyright (C) 2018 Steve R ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## import sigrokdecode as srd bitvals = ('0', '1', 'f', 'U') def decode_bit(edges, pulses_per_bit): if pulses_per_bit == 2: # Datasheet says long pulse is 3 times short pulse. lmin = 1.5 # long min multiplier lmax = 5 # long max multiplier if (edges[1] >= edges[0] * lmin and edges[1] <= edges[0] * lmax): # 0 -___ return '0' elif (edges[0] >= edges[1] * lmin and edges[0] <= edges[1] * lmax): # 1 ---_ return '1' # No float type for this line encoding else: return 'U' if pulses_per_bit == 4: # Datasheet says long pulse is 3 times short pulse. lmin = 2 # long min multiplier lmax = 5 # long max multiplier eqmin = 0.5 # equal min multiplier eqmax = 1.5 # equal max multiplier if ( # 0 -___-___ (edges[1] >= edges[0] * lmin and edges[1] <= edges[0] * lmax) and (edges[2] >= edges[0] * eqmin and edges[2] <= edges[0] * eqmax) and (edges[3] >= edges[0] * lmin and edges[3] <= edges[0] * lmax)): return '0' elif ( # 1 ---_---_ (edges[0] >= edges[1] * lmin and edges[0] <= edges[1] * lmax) and (edges[0] >= edges[2] * eqmin and edges[0] <= edges[2] * eqmax) and (edges[0] >= edges[3] * lmin and edges[0] <= edges[3] * lmax)): return '1' elif ( # float ---_-___ (edges[1] >= edges[0] * lmin and edges[1] <= edges[0] * lmax) and (edges[2] >= edges[0] * lmin and edges[2] <= edges[0]* lmax) and (edges[3] >= edges[0] * eqmin and edges[3] <= edges[0] * eqmax)): return 'f' else: return 'U' def pinlabels(bit_count, packet_bit_count): if packet_bit_count == 12: if bit_count <= 6: return 'A%i' % (bit_count - 1) else: return 'A%i/D%i' % (bit_count - 1, 12 - bit_count) if packet_bit_count == 24: if bit_count <= 20: return 'A%i' % (bit_count - 1) else: return 'D%i' % (bit_count - 21) def decode_model(model, bits): if model == 'maplin_l95ar': address = 'Addr' # Address bits A0 to A5 for i in range(0, 6): address += ' %i:' % (i + 1) + ('on' if bits[i][0] == '0' else 'off') button = 'Button' # Button bits A6/D5 to A11/D0 if bits[6][0] == '0' and bits[11][0] == '0': button += ' A ON/OFF' elif bits[7][0] == '0' and bits[11][0] == '0': button += ' B ON/OFF' elif bits[9][0] == '0' and bits[11][0] == '0': button += ' C ON/OFF' elif bits[8][0] == '0' and bits[11][0] == '0': button += ' D ON/OFF' else: button += ' Unknown' return [address, bits[0][1], bits[5][2], \ button, bits[6][1], bits[11][2]] if model == 'xx1527': addr = 0 addr_valid = 1 for i in range(0, 20): if bits[i][0] != 'U': addr += int(bits[i][0]) * 2 ** i else: addr_valid = 0 if addr_valid == 1: address = 'Address 0x%X %X %X' % (addr & 0xFF, (addr >> 8) & 0xFF, addr >> 16) else: address = 'Invalid address as not all bits are 0 or 1' output = ' K0 = ' + bits[20][0] + ',' output += ' K1 = ' + bits[21][0] + ',' output += ' K2 = ' + bits[22][0] + ',' output += ' K3 = ' + bits[23][0] return [address, bits[0][1], bits[19][2], \ output, bits[20][1], bits[23][2]] class Decoder(srd.Decoder): api_version = 3 id = 'rc_encode' name = 'RC encode' longname = 'Remote control encoder' desc = 'PT22x2/HX22x2/SC52x2 and xx1527 remote control encoder protocol.' license = 'gplv2+' inputs = ['logic'] outputs = [] tags = ['IC', 'IR'] channels = ( {'id': 'data', 'name': 'Data', 'desc': 'Data line'}, ) annotations = ( ('bit-0', 'Bit 0'), ('bit-1', 'Bit 1'), ('bit-f', 'Bit f'), ('bit-U', 'Bit U'), ('bit-sync', 'Bit sync'), ('pin', 'Pin'), ('code-word-addr', 'Code word address'), ('code-word-data', 'Code word data'), ) annotation_rows = ( ('bits', 'Bits', (0, 1, 2, 3, 4)), ('pins', 'Pins', (5,)), ('code-words', 'Code words', (6, 7)), ) options = ( {'id': 'linecoding', 'desc': 'Encoding', 'default': 'SC52x2/HX22x2', 'values': ('SC52x2/HX22x2', 'xx1527')}, {'id': 'remote', 'desc': 'Remote', 'default': 'none', 'values': ('none', 'maplin_l95ar')}, ) def __init__(self): self.reset() def reset(self): self.samplenumber_last = None self.pulses = [] self.bits = [] self.labels = [] self.bit_count = 0 self.ss = None self.es = None self.state = 'IDLE' def start(self): self.out_ann = self.register(srd.OUTPUT_ANN) self.model = self.options['remote'] if self.options['linecoding'] == 'xx1527': self.pulses_per_bit = 2 self.packet_bits = 24 self.model = 'xx1527' else: self.pulses_per_bit = 4 # Each bit is repeated self.packet_bits = 12 def putx(self, data): self.put(self.ss, self.es, self.out_ann, data) def decode(self): while True: pin = self.wait({0: 'e'}) self.state = 'DECODING' if not self.samplenumber_last: # Set counters to start of signal. self.samplenumber_last = self.samplenum self.ss = self.samplenum continue if self.bit_count < self.packet_bits: # Decode A0 to A11 / A23. self.bit_count += 1 for i in range(0, self.pulses_per_bit): if i > 0: pin = self.wait({0: 'e'}) # Get next edges if we need more. samples = self.samplenum - self.samplenumber_last self.pulses.append(samples) # Save the pulse width. self.samplenumber_last = self.samplenum self.es = self.samplenum self.bits.append([decode_bit(self.pulses, self.pulses_per_bit), self.ss, self.es]) # Save states and times. idx = bitvals.index(decode_bit(self.pulses, self.pulses_per_bit)) self.putx([idx, [decode_bit(self.pulses, self.pulses_per_bit)]]) # Write decoded bit. self.putx([5, [pinlabels(self.bit_count, self.packet_bits)]]) # Write pin labels. self.pulses = [] self.ss = self.samplenum else: if self.model != 'none': self.labels = decode_model(self.model, self.bits) self.put(self.labels[1], self.labels[2], self.out_ann, [6, [self.labels[0]]]) # Write model decode. self.put(self.labels[4], self.labels[5], self.out_ann, [7, [self.labels[3]]]) # Write model decode. samples = self.samplenum - self.samplenumber_last pin = self.wait({'skip': 8 * samples}) # Wait for end of sync bit. self.es = self.samplenum self.putx([4, ['Sync']]) # Write sync label. self.reset() # Reset and wait for next set of pulses. self.state = 'DECODE_TIMEOUT' if not self.state == 'DECODE_TIMEOUT': self.samplenumber_last = self.samplenum