2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2014 Gump Yang <gump.yang@gmail.com>
5 ## Copyright (C) 2019 Rene Staffen
6 ## Copyright (C) 2020-2021 Gerhard Sittig <gerhard.sittig@gmx.net>
8 ## This program is free software; you can redistribute it and/or modify
9 ## it under the terms of the GNU General Public License as published by
10 ## the Free Software Foundation; either version 2 of the License, or
11 ## (at your option) any later version.
13 ## This program is distributed in the hope that it will be useful,
14 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ## GNU General Public License for more details.
18 ## You should have received a copy of the GNU General Public License
19 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
22 from . import irmp_library
23 import sigrokdecode
as srd
25 class SamplerateError(Exception):
28 class LibraryError(Exception):
31 class Decoder(srd
.Decoder
):
36 desc
= 'IRMP infrared remote control multi protocol.'
42 {'id': 'ir', 'name': 'IR', 'desc': 'Data line'},
45 {'id': 'polarity', 'desc': 'Polarity', 'default': 'active-low',
46 'values': ('active-low', 'active-high')},
52 ('packets', 'IR Packets', (0,)),
55 def putframe(self
, data
):
56 '''Emit annotation for an IR frame.'''
58 # Cache result data fields in local variables. Get the ss/es
59 # timestamps, scaled to sample numbers.
61 name
= data
['proto_name']
62 addr
= data
['address']
64 repeat
= data
['repeat']
65 release
= data
['release']
66 ss
= data
['start'] * self
.rate_factor
67 es
= data
['end'] * self
.rate_factor
69 # Prepare display texts for several zoom levels.
70 # Implementor's note: Keep list lengths for flags aligned during
71 # maintenance. Make sure there are as many flags text variants
72 # as are referenced by annotation text variants. Differing list
73 # lengths or dynamic refs will severely complicate the logic.
74 rep_txts
= ['repeat', 'rep', 'r']
75 rel_txts
= ['release', 'rel', 'R']
76 flag_txts
= [None,] * len(rep_txts
)
77 for zoom
in range(len(flag_txts
)):
80 flag_txts
[zoom
].append(rep_txts
[zoom
])
82 flag_txts
[zoom
].append(rel_txts
[zoom
])
83 flag_txts
= [' '.join(t
) or '-' for t
in flag_txts
]
84 flg
= flag_txts
# Short name for .format() references.
86 'Protocol: {name} ({nr}), Address 0x{addr:04x}, Command: 0x{cmd:04x}, Flags: {flg[0]}'.format(**locals()),
87 'P: {name} ({nr}), Addr: 0x{addr:x}, Cmd: 0x{cmd:x}, Flg: {flg[1]}'.format(**locals()),
88 'P: {nr} A: 0x{addr:x} C: 0x{cmd:x} F: {flg[1]}'.format(**locals()),
89 'C:{cmd:x} A:{addr:x} {flg[2]}'.format(**locals()),
90 'C:{cmd:x}'.format(**locals()),
93 # Emit the annotation from details which were constructed above.
94 self
.put(ss
, es
, self
.out_ann
, [0, txts
])
104 self
.out_ann
= self
.register(srd
.OUTPUT_ANN
)
106 def metadata(self
, key
, value
):
107 if key
== srd
.SRD_CONF_SAMPLERATE
:
108 self
.samplerate
= value
113 self
.irmp
= irmp_library
.IrmpLibrary()
114 except Exception as e
:
116 raise LibraryError(txt
)
118 raise LibraryError('Cannot access IRMP library.')
119 if not self
.samplerate
:
120 raise SamplerateError('Cannot decode without samplerate.')
121 lib_rate
= self
.irmp
.get_sample_rate()
123 raise LibraryError('Cannot determine IRMP library\'s samplerate.')
124 if self
.samplerate
% lib_rate
:
125 raise SamplerateError('Capture samplerate must be multiple of library samplerate ({})'.format(lib_rate
))
127 self
.rate_factor
= int(self
.samplerate
/ lib_rate
)
128 active
= 0 if self
.options
['polarity'] == 'active-low' else 1
132 self
.irmp
.reset_state()
136 if self
.irmp
.add_one_sample(ir
):
137 data
= self
.irmp
.get_result_data()
139 ir
, = self
.wait([{'skip': self
.rate_factor
}])