]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/rc_encode/pd.py
rc_encode: Add support for EV1527, RT1527, FP1527 and HS1527
[libsigrokdecode.git] / decoders / rc_encode / pd.py
index 902594c80da09d2cabe9e2aaed26cda4c022ba1c..31727bdb1aac4abd6d985e2b5a4ff50cbc1c641e 100644 (file)
 
 import sigrokdecode as srd
 
-def decode_bit(edges):
-    # 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):
-    if bit_count <= 6:
-        return 'A%i' % (bit_count - 1)
-    else:
-        return 'A%i/D%i' % (bit_count - 1, 12 - bit_count)
+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 pins A0 to A5
+        address = 'Addr' # Address bits A0 to A5
         for i in range(0, 6):
-            address = address + ' %i:' % (i + 1) + \
-                      ('on' if bits[i][0] == '0' else 'off')
+            address += ' %i:' % (i + 1) + ('on' if bits[i][0] == '0' else 'off')
         button = 'Button'
-        # Button pins A6/D5 to A11/D0
+        # Button bits A6/D5 to A11/D0
         if bits[6][0] == '0' and bits[11][0] == '0':
-            button = button + ' A ON/OFF'
+            button += ' A ON/OFF'
         elif bits[7][0] == '0' and bits[11][0] == '0':
-            button = button + ' B ON/OFF'
+            button += ' B ON/OFF'
         elif bits[9][0] == '0' and bits[11][0] == '0':
-            button = button + ' C ON/OFF'
+            button += ' C ON/OFF'
         elif bits[8][0] == '0' and bits[11][0] == '0':
-            button = button + ' D ON/OFF'
+            button += ' D ON/OFF'
         else:
-            button = button + ' Unknown'
-        return ['%s' % address, bits[0][1], bits[5][2], \
-                '%s' % button, bits[6][1], bits[11][2]]
+            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 = 'PT2262/HX2262/SC5262 remote control encoder protocol.'
+    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 = (
-        ('bits', 'Bits'),
-        ('pins', 'Pins'),
-        ('remote', 'Remote'),
+        ('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,)),
-        ('pins', 'Pins', (1,)),
-        ('remote', 'Remote', (2,)),
+        ('bits', 'Bits', (0, 1, 2, 3, 4)),
+        ('pins', 'Pins', (5,)),
+        ('code-words', 'Code words', (6, 7)),
     )
     options = (
-        {'id': 'remote', 'desc': 'Remote', 'default': 'none', 
-            'values': ('none', 'maplin_l95ar')},
+        {'id': 'linecoding', 'desc': 'Encoding', 'default': 'SC52x2/HX22x2', 'values': ('SC52x2/HX22x2', 'xx1527')},
+        {'id': 'remote', 'desc': 'Remote', 'default': 'none', 'values': ('none', 'maplin_l95ar')},
     )
 
     def __init__(self):
@@ -106,13 +154,23 @@ class Decoder(srd.Decoder):
         self.bits = []
         self.labels = []
         self.bit_count = 0
-        self.bit_first = None
-        self.bit_last = None
+        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:
@@ -121,38 +179,36 @@ class Decoder(srd.Decoder):
 
             if not self.samplenumber_last: # Set counters to start of signal.
                 self.samplenumber_last = self.samplenum
-                self.bit_first = self.samplenum
+                self.ss = self.samplenum
                 continue
 
-            if self.bit_count < 12: # Decode A0 to A11.
+            if self.bit_count < self.packet_bits: # Decode A0 to A11 / A23.
                 self.bit_count += 1
-                for i in range(0, 4): # Get four pulses for each bit.
+                for i in range(0, self.pulses_per_bit):
                     if i > 0:
-                        pin = self.wait({0: 'e'}) # Get next 3 edges.
+                        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.bit_last = self.samplenum
-                self.bits.append([decode_bit(self.pulses), self.bit_first,
-                                  self.bit_last]) # Save states and times.
-                self.put(self.bit_first, self.bit_last, self.out_ann,
-                         [0, [decode_bit(self.pulses)]]) # Write decoded bit.
-                self.put(self.bit_first, self.bit_last, self.out_ann,
-                         [1, [pinlabels(self.bit_count)]]) # Write pin labels.
+                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.bit_first = self.samplenum
+                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,
-                             [2, [self.labels[0]]]) # Write model decode.
+                             [6, [self.labels[0]]]) # Write model decode.
                     self.put(self.labels[4], self.labels[5], self.out_ann,
-                             [2, [self.labels[3]]]) # Write model decode.
+                             [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.bit_last = self.samplenum
-                self.put(self.bit_first, self.bit_last, self.out_ann,
-                         [0, ['Sync']]) # Write sync label.
+                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':