]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/ir_irmp/pd.py
avr_isp: Extend decoder, add locks, eeprom, program memory commands.
[libsigrokdecode.git] / decoders / ir_irmp / pd.py
index ef3da4dd3ac80f0fedfed0477dd84b3df6a31c6f..979c1e0129b63e7b43f94f6f8458f16a961d11cb 100644 (file)
@@ -24,6 +24,9 @@ import sigrokdecode as srd
 class SamplerateError(Exception):
     pass
 
+class LibraryError(Exception):
+    pass
+
 class Decoder(srd.Decoder):
     api_version = 3
     id = 'ir_irmp'
@@ -49,29 +52,52 @@ class Decoder(srd.Decoder):
     )
 
     def putframe(self, data):
+        '''Emit annotation for an IR frame.'''
+
+        # Cache result data fields in local variables. Get the ss/es
+        # timestamps, scaled to sample numbers.
         nr = data['proto_nr']
         name = data['proto_name']
         addr = data['address']
         cmd = data['command']
         repeat = data['repeat']
-        rep = ['repeat', 'rep', 'r'] if repeat else ['', '', '']
+        release = data['release']
         ss = data['start'] * self.rate_factor
         es = data['end'] * self.rate_factor
-        self.put(ss, es, self.out_ann, [0, [
-            'Protocol: {nr} ({name}), Address 0x{addr:04x}, Command: 0x{cmd:04x} {rep[0]}'.format(**locals()),
-            'P: {name} ({nr}), Addr: 0x{addr:x}, Cmd: 0x{cmd:x} {rep[1]}'.format(**locals()),
-            'P: {nr} A: 0x{addr:x} C: 0x{cmd:x} {rep[1]}'.format(**locals()),
-            'C:{cmd:x} A:{addr:x} {rep[2]}'.format(**locals()),
+
+        # Prepare display texts for several zoom levels.
+        # Implementor's note: Keep list lengths for flags aligned during
+        # maintenance. Make sure there are as many flags text variants
+        # as are referenced by annotation text variants. Differing list
+        # lengths or dynamic refs will severely complicate the logic.
+        rep_txts = ['repeat', 'rep', 'r']
+        rel_txts = ['release', 'rel', 'R']
+        flag_txts = [None,] * len(rep_txts)
+        for zoom in range(len(flag_txts)):
+            flag_txts[zoom] = []
+            if repeat:
+                flag_txts[zoom].append(rep_txts[zoom])
+            if release:
+                flag_txts[zoom].append(rel_txts[zoom])
+        flag_txts = [' '.join(t) or '-' for t in flag_txts]
+        flg = flag_txts # Short name for .format() references.
+        txts = [
+            'Protocol: {name} ({nr}), Address 0x{addr:04x}, Command: 0x{cmd:04x}, Flags: {flg[0]}'.format(**locals()),
+            'P: {name} ({nr}), Addr: 0x{addr:x}, Cmd: 0x{cmd:x}, Flg: {flg[1]}'.format(**locals()),
+            'P: {nr} A: 0x{addr:x} C: 0x{cmd:x} F: {flg[1]}'.format(**locals()),
+            'C:{cmd:x} A:{addr:x} {flg[2]}'.format(**locals()),
             'C:{cmd:x}'.format(**locals()),
-        ]])
+        ]
+
+        # Emit the annotation from details which were constructed above.
+        self.put(ss, es, self.out_ann, [0, txts])
 
     def __init__(self):
-        self.irmp = irmp_library.IrmpLibrary()
-        self.lib_rate = self.irmp.get_sample_rate()
+        self.irmp = None
         self.reset()
 
     def reset(self):
-        self.irmp.reset_state()
+        self.want_reset = True
 
     def start(self):
         self.out_ann = self.register(srd.OUTPUT_ANN)
@@ -81,11 +107,24 @@ class Decoder(srd.Decoder):
             self.samplerate = value
 
     def decode(self):
+        if not self.irmp:
+            try:
+                self.irmp = irmp_library.IrmpLibrary()
+            except Exception as e:
+                txt = e.args[0]
+                raise LibraryError(txt)
+        if self.irmp:
+            self.lib_rate = self.irmp.get_sample_rate()
+        if not self.irmp or not self.lib_rate:
+            raise LibraryError('Cannot access IRMP library. One instance limit exceeded?')
         if not self.samplerate:
             raise SamplerateError('Cannot decode without samplerate.')
         if self.samplerate % self.lib_rate:
-            raise SamplerateError('capture samplerate must be multiple of library samplerate ({})'.format(self.lib_rate))
+            raise SamplerateError('Capture samplerate must be multiple of library samplerate ({})'.format(self.lib_rate))
         self.rate_factor = int(self.samplerate / self.lib_rate)
+        if self.want_reset:
+            self.irmp.reset_state()
+            self.want_reset = False
 
         self.active = 0 if self.options['polarity'] == 'active-low' else 1
         ir, = self.wait()