Attachment 'pd.py'

Download

   1 ##
   2 ## This file is part of the libsigrokdecode project.
   3 ##
   4 ## Copyright (C) 2014 Gump Yang <gump.yang@gmail.com>
   5 ##
   6 ## This program is free software; you can redistribute it and/or modify
   7 ## it under the terms of the GNU General Public License as published by
   8 ## the Free Software Foundation; either version 2 of the License, or
   9 ## (at your option) any later version.
  10 ##
  11 ## This program is distributed in the hope that it will be useful,
  12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 ## GNU General Public License for more details.
  15 ##
  16 ## You should have received a copy of the GNU General Public License
  17 ## along with this program; if not, write to the Free Software
  18 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  19 ##
  20 
  21 import sigrokdecode as srd
  22 from .lists import *
  23 
  24 class SamplerateError(Exception):
  25     pass
  26 
  27 class Decoder(srd.Decoder):
  28     api_version = 2
  29     id = 'ir_nec2'
  30     name = 'IR NEC2'
  31     longname = 'IR NEC debug'
  32     desc = 'NEC infrared remote control protocol.'
  33     license = 'gplv2+'
  34     inputs = ['logic']
  35     outputs = ['ir_nec']
  36     channels = (
  37         {'id': 'ir', 'name': 'IR', 'desc': 'Data line'},
  38     )
  39     options = (
  40         {'id': 'polarity', 'desc': 'Polarity', 'default': 'active-low',
  41             'values': ('active-low', 'active-high')},
  42     )
  43     annotations = (
  44         ('bit', 'Bit'),
  45         ('agc-pulse', 'AGC pulse'),
  46         ('longpause', 'Long pause'),
  47         ('shortpause', 'Short pause'),
  48         ('stop-bit', 'Stop bit'),
  49         ('leader-code', 'Leader code'),
  50         ('addr', 'Address'),
  51         ('addr-inv', 'Address#'),
  52         ('cmd', 'Command'),
  53         ('cmd-inv', 'Command#'),
  54         ('repeat-code', 'Repeat code'),
  55         ('remote', 'Remote'),
  56         ('warnings', 'Warnings'),
  57     )
  58     annotation_rows = (
  59         ('bits', 'Bits', (0, 1, 2, 3, 4)),
  60         ('fields', 'Fields', (5, 6, 7, 8, 9, 10)),
  61         ('remote', 'Remote', (11,)),
  62         ('warnings', 'Warnings', (12,)),
  63     )
  64 
  65     def putx(self, data):
  66         self.put(self.ss_start, self.samplenum, self.out_ann, data)
  67 
  68     def putb(self, data):
  69         self.put(self.ss_bit, self.samplenum, self.out_ann, data)
  70 
  71     def putd(self, data):
  72         name = self.state.title()
  73         d = {'ADDRESS': 6, 'ADDRESS#': 7, 'COMMAND': 8, 'COMMAND#': 9}
  74         s = {'ADDRESS': ['ADDR', 'A'], 'ADDRESS#': ['ADDR#', 'A#'],
  75              'COMMAND': ['CMD', 'C'], 'COMMAND#': ['CMD#', 'C#']}
  76         self.putx([d[self.state], ['%s: 0x%02X' % (name, data),
  77                   '%s: 0x%02X' % (s[self.state][0], data),
  78                   '%s: 0x%02X' % (s[self.state][1], data), s[self.state][1]]])
  79 
  80     def putstop(self, ss):
  81         self.put(ss, ss + self.stop, self.out_ann,
  82                  [4, ['Stop bit', 'Stop', 'St', 'S']])
  83 
  84     def putpause(self, p):
  85         self.put(self.ss_start, self.ss_other_edge, self.out_ann,
  86                  [1, ['AGC pulse', 'AGC', 'A']])
  87         idx = 2 if p == 'Long' else 3
  88         self.put(self.ss_other_edge, self.samplenum, self.out_ann,
  89                  [idx, [p + ' pause', '%s-pause' % p[0], '%sP' % p[0], 'P']])
  90 
  91     def putremote(self):
  92         dev = address.get(self.addr, 'Unknown device')
  93         buttons = command.get(self.addr, None)
  94         if buttons is None:
  95             btn = ['Unknown', 'Unk']
  96         else:
  97             btn = buttons.get(self.cmd, ['Unknown', 'Unk'])
  98         self.put(self.ss_remote, self.ss_bit + self.stop, self.out_ann,
  99                  [11, ['%s: %s' % (dev, btn[0]), '%s: %s' % (dev, btn[1]),
 100                  '%s' % btn[1]]])
 101 
 102     def __init__(self, **kwargs):
 103         self.state = 'IDLE'
 104         self.ss_bit = self.ss_start = self.ss_other_edge = self.ss_remote = 0
 105         self.data = self.count = self.active = self.old_ir = None
 106         self.addr = self.cmd = None
 107 
 108     def start(self):
 109         self.out_ann = self.register(srd.OUTPUT_ANN)
 110         self.active = 0 if self.options['polarity'] == 'active-low' else 1
 111         self.old_ir = 1 if self.active == 0 else 0
 112 
 113     def metadata(self, key, value):
 114         if key == srd.SRD_CONF_SAMPLERATE:
 115             self.samplerate = value
 116         self.margin = int(self.samplerate * 0.0001) - 1 # 0.1ms
 117         self.lc = int(self.samplerate * 0.0135) - 1 # 13.5ms
 118         self.rc = int(self.samplerate * 0.01125) - 1 # 11.25ms
 119         self.dazero = int(self.samplerate * 0.001125) - 1 # 1.125ms
 120         self.daone = int(self.samplerate * 0.00225) - 1 # 2.25ms
 121         self.stop = int(self.samplerate * 0.000652) - 1 # 0.652ms
 122 
 123     def handle_bit(self, tick):
 124         ret = None
 125         if tick in range(self.dazero - self.margin, self.dazero + self.margin):
 126             ret = 0
 127         elif tick in range(self.daone - self.margin, self.daone + self.margin):
 128             ret = 1
 129         if ret in (0, 1):
 130             self.putb([0, ['%d' % ret]])
 131             self.data |= (ret << self.count) # LSB-first
 132             self.count = self.count + 1
 133         self.ss_bit = self.samplenum
 134 
 135     def data_ok(self):
 136         ret, name = (self.data >> 8) & (self.data & 0xff), self.state.title()
 137         if self.count == 8:
 138             if self.state == 'ADDRESS':
 139                 self.addr = self.data
 140             if self.state == 'COMMAND':
 141                 self.cmd = self.data
 142             self.putd(self.data)
 143             self.ss_start = self.samplenum
 144             return True
 145         if ret == 0:
 146             self.putd(self.data >> 8)
 147         else:
 148             self.putx([12, ['%s error: 0x%04X' % (name, self.data)]])
 149         self.data = self.count = 0
 150         self.ss_bit = self.ss_start = self.samplenum
 151         return ret == 0
 152 
 153     def decode(self, ss, es, data):
 154         import rpdb2; rpdb2.start_embedded_debugger('1', fAllowRemote=True)
 155         if not self.samplerate:
 156             raise SamplerateError('Cannot decode without samplerate.')
 157         for (self.samplenum, pins) in data:
 158             self.ir = pins[0]
 159 
 160             # Wait for an "interesting" edge, but also record the other ones.
 161             if self.old_ir == self.ir:
 162                 continue
 163             if self.ir != self.active:
 164                 self.ss_other_edge = self.samplenum
 165                 self.old_ir = self.ir
 166                 continue
 167 
 168             b = self.samplenum - self.ss_bit
 169 
 170             # State machine.
 171             if self.state == 'IDLE':
 172                 if b in range(self.lc - self.margin, self.lc + self.margin):
 173                     self.putpause('Long')
 174                     self.putx([5, ['Leader code', 'Leader', 'LC', 'L']])
 175                     self.ss_remote = self.ss_start
 176                     self.data = self.count = 0
 177                     self.state = 'ADDRESS'
 178                 elif b in range(self.rc - self.margin, self.rc + self.margin):
 179                     self.putpause('Short')
 180                     self.putstop(self.samplenum)
 181                     self.samplenum += self.stop
 182                     self.putx([10, ['Repeat code', 'Repeat', 'RC', 'R']])
 183                     self.data = self.count = 0
 184                 self.ss_bit = self.ss_start = self.samplenum
 185             elif self.state == 'ADDRESS':
 186                 self.handle_bit(b)
 187                 if self.count == 8:
 188                     self.state = 'ADDRESS#' if self.data_ok() else 'IDLE'
 189             elif self.state == 'ADDRESS#':
 190                 self.handle_bit(b)
 191                 if self.count == 16:
 192                     self.state = 'COMMAND' if self.data_ok() else 'IDLE'
 193             elif self.state == 'COMMAND':
 194                 self.handle_bit(b)
 195                 if self.count == 8:
 196                     self.state = 'COMMAND#' if self.data_ok() else 'IDLE'
 197             elif self.state == 'COMMAND#':
 198                 self.handle_bit(b)
 199                 if self.count == 16:
 200                     self.state = 'STOP' if self.data_ok() else 'IDLE'
 201             elif self.state == 'STOP':
 202                 self.putstop(self.ss_bit)
 203                 self.putremote()
 204                 self.ss_bit = self.ss_start = self.samplenum
 205                 self.state = 'IDLE'
 206 
 207             self.old_ir = self.ir

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2016-09-07 18:06:00, 6.2 KB) [[attachment:ir_nec_tv_matsui_av_hold.sr]]
  • [get | view] (2016-09-07 18:08:00, 7.9 KB) [[attachment:pd.py]]
  • [get | view] (2016-09-13 15:57:00, 33.9 KB) [[attachment:sigrok_Ubuntu1604-32_git-test.txt]]
  • [get | view] (2016-09-07 17:33:00, 67.2 KB) [[attachment:sigrok_decoder_ir_nec2.png]]
  • [get | view] (2016-09-07 19:14:00, 44.4 KB) [[attachment:sigrok_decoder_ir_nec_options.png]]
  • [get | view] (2016-09-07 17:33:00, 21.2 KB) [[attachment:winpdb_attach.PNG]]
  • [get | view] (2016-09-07 17:33:00, 126.6 KB) [[attachment:winpdb_decoder_ir_nec2.PNG]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.