X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=decoders%2Fir_irmp%2Fpd.py;h=979c1e0129b63e7b43f94f6f8458f16a961d11cb;hb=8838d01886f056b20da458fe55ad977997739b0c;hp=ef3da4dd3ac80f0fedfed0477dd84b3df6a31c6f;hpb=e8e8bec61ce9b855c078e2ca1de55f648af5204a;p=libsigrokdecode.git diff --git a/decoders/ir_irmp/pd.py b/decoders/ir_irmp/pd.py index ef3da4d..979c1e0 100644 --- a/decoders/ir_irmp/pd.py +++ b/decoders/ir_irmp/pd.py @@ -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()