From 61c2bd366eba64b50009c604c382c547f6cfdd88 Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Tue, 31 Jan 2012 18:05:11 +0100 Subject: [PATCH] srd: add generic I2C filter PD --- configure.ac | 1 + decoders/Makefile.am | 1 + decoders/i2cfilter/Makefile.am | 25 +++++++++++ decoders/i2cfilter/__init__.py | 36 ++++++++++++++++ decoders/i2cfilter/i2cfilter.py | 76 +++++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+) create mode 100644 decoders/i2cfilter/Makefile.am create mode 100644 decoders/i2cfilter/__init__.py create mode 100644 decoders/i2cfilter/i2cfilter.py diff --git a/configure.ac b/configure.ac index a3a6896..f59f392 100644 --- a/configure.ac +++ b/configure.ac @@ -158,6 +158,7 @@ AC_CONFIG_FILES([Makefile decoders/edid/Makefile decoders/i2c/Makefile decoders/i2cdemux/Makefile + decoders/i2cfilter/Makefile decoders/mlx90614/Makefile decoders/mx25lxx05d/Makefile decoders/nunchuk/Makefile diff --git a/decoders/Makefile.am b/decoders/Makefile.am index aee4e2b..7e40b2f 100644 --- a/decoders/Makefile.am +++ b/decoders/Makefile.am @@ -26,6 +26,7 @@ SUBDIRS = \ edid \ i2c \ i2cdemux \ + i2cfilter \ mlx90614 \ mx25lxx05d \ nunchuk \ diff --git a/decoders/i2cfilter/Makefile.am b/decoders/i2cfilter/Makefile.am new file mode 100644 index 0000000..5b90489 --- /dev/null +++ b/decoders/i2cfilter/Makefile.am @@ -0,0 +1,25 @@ +## +## This file is part of the sigrok project. +## +## Copyright (C) 2012 Bert Vermeulen +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +pkgdatadir = $(DECODERS_DIR)/i2cfilter + +dist_pkgdata_DATA = __init__.py i2cfilter.py + +CLEANFILES = *.pyc + diff --git a/decoders/i2cfilter/__init__.py b/decoders/i2cfilter/__init__.py new file mode 100644 index 0000000..6c5f1ec --- /dev/null +++ b/decoders/i2cfilter/__init__.py @@ -0,0 +1,36 @@ +## +## This file is part of the sigrok project. +## +## Copyright (C) 2012 Bert Vermeulen +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +''' +Takes input from the I2C protocol decoder and filters out traffic from/to +a single address on the I2C bus. + +It then outputs the filtered data one byte at a time as OUTPUT_PROTO up the +protocol decoder stack. No annotations are output. + +The I2C address to filter out should be passed in as an option 'address', as +an integer. A specific read or write operation can be selected with the +'direction' option, which should be 'read' or 'write'. + +Both of these are optional; if no options are specified the entire payload +of the I2C session will be output. +''' + +from .i2cfilter import * + diff --git a/decoders/i2cfilter/i2cfilter.py b/decoders/i2cfilter/i2cfilter.py new file mode 100644 index 0000000..4b88bef --- /dev/null +++ b/decoders/i2cfilter/i2cfilter.py @@ -0,0 +1,76 @@ +## +## This file is part of the sigrok project. +## +## Copyright (C) 2012 Bert Vermeulen +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sigrokdecode as srd + + +class Decoder(srd.Decoder): + api_version = 1 + id = 'i2cfilter' + name = 'I2C filter' + longname = 'I2C filter' + desc = 'Filter out specific addresses/directions in an I2C stream.' + license = 'gplv3+' + inputs = ['i2c'] + outputs = [] + options = { + 'address': ['Address to filter out of the I2C stream', 0], + 'direction': ['Direction to filter (read/write)', ''] + } + + def __init__(self, **kwargs): + self.state = None + + def start(self, metadata): + self.out_proto = self.add(srd.OUTPUT_PROTO, 'i2cdata') + if self.options['direction'] not in ('', 'read', 'write'): + raise Exception("Invalid direction: expected 'read' or 'write'") + + def decode(self, ss, es, data): + try: + cmd, data, ack_bit = data + except Exception as e: + raise Exception('Malformed I2C input: %s' % str(e)) from e + + # Whichever state we're in, these always reset the state machine. + # This should make it easier to deal with corrupt data etc. + if cmd in ('START', 'START REPEAT'): + self.state = 'start' + return + if cmd == 'STOP': + self.state = None + return + + if self.state == 'start': + # Start of a transfer, see if we want this one. + if cmd == 'ADDRESS READ' and self.options['direction'] == 'write': + return + elif cmd == 'ADDRESS WRITE' and self.options['direction'] == 'read': + return + elif cmd in ('ADDRESS READ', 'ADDRESS WRITE'): + if self.options['address'] in (0, data): + # We want this tranfer. + self.state = 'transfer' + elif self.state == 'transfer': + if cmd in ('DATA READ', 'DATA WRITE'): + self.put(ss, es, self.out_proto, data) + else: + raise Exception('Invalid state: %s' % self.state) + + -- 2.30.2