Skip to content

Glitch Filter for 1:I2C decoder #853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions libsigrokdecode4DSL/decoders/1-i2c/pd.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class Decoder(srd.Decoder):
options = (
{'id': 'address_format', 'desc': 'Displayed slave address format',
'default': 'unshifted', 'values': ('shifted', 'unshifted'), 'idn':'dec_1i2c_opt_addr'},
{'id': 'glitch_filter', 'desc': 'Glitch Filter (ns)',
'default': 0, 'idn':'dec_1i2c_opt_gf'},
)
annotations = (
('7', 'start', 'Start condition'),
Expand Down Expand Up @@ -123,12 +125,17 @@ def reset(self):
self.pdu_start = None
self.pdu_bits = 0
self.bits = []
self.glitch_ns_per_sample = 0
self.glitch_threshold = 0
self.glitch_scl_ss = 0

def metadata(self, key, value):
if key == srd.SRD_CONF_SAMPLERATE:
self.samplerate = value
self.glitch_ns_per_sample = 1000000000 / value

def start(self):
self.glitch_threshold = self.options['glitch_filter']
self.out_python = self.register(srd.OUTPUT_PYTHON)
self.out_ann = self.register(srd.OUTPUT_ANN)
self.out_binary = self.register(srd.OUTPUT_BINARY)
Expand Down Expand Up @@ -157,6 +164,18 @@ def handle_start(self):
self.wr = -1
self.bits = []

def check_glitch_filter(self):
ret = True
if self.glitch_threshold != 0:
glitch_scl_sdiff = self.samplenum - self.glitch_scl_ss
glitch_scl_sdiff_ns = self.glitch_ns_per_sample * glitch_scl_sdiff

if glitch_scl_sdiff_ns <= self.glitch_threshold:
ret = False

self.glitch_scl_ss = self.samplenum
return ret

# Gather 8 bits of data plus the ACK/NACK bit.
def handle_address_or_data(self, scl, sda):
self.pdu_bits += 1
Expand Down Expand Up @@ -257,14 +276,22 @@ def decode(self):
# State machine.
if self.state == 'FIND START':
# Wait for a START condition (S): SCL = high, SDA = falling.
self.wait({0: 'h', 1: 'f'})
self.handle_start()
(scl, sda) = self.wait([{0: 'h', 1: 'f'}, {0: 'r'}, {0: 'f'}])

if self.check_glitch_filter() == False:
continue

if (self.matched & (0b1 << 0)):
self.handle_start()
elif self.state == 'FIND ADDRESS':
# Wait for any of the following conditions (or combinations):
# a) Data sampling of receiver: SCL = rising, and/or
# b) START condition (S): SCL = high, SDA = falling, and/or
# c) STOP condition (P): SCL = high, SDA = rising
(scl, sda) = self.wait([{0: 'r'}, {0: 'h', 1: 'f'}, {0: 'h', 1: 'r'}])
(scl, sda) = self.wait([{0: 'r'}, {0: 'h', 1: 'f'}, {0: 'h', 1: 'r'}, {0: 'f'}])

if self.check_glitch_filter() == False:
continue

# Check which of the condition(s) matched and handle them.
if (self.matched & (0b1 << 0)):
Expand All @@ -278,7 +305,10 @@ def decode(self):
# a) Data sampling of receiver: SCL = rising, and/or
# b) START condition (S): SCL = high, SDA = falling, and/or
# c) STOP condition (P): SCL = high, SDA = rising
(scl, sda) = self.wait([{0: 'r'}, {0: 'h', 1: 'f'}, {0: 'h', 1: 'r'}])
(scl, sda) = self.wait([{0: 'r'}, {0: 'h', 1: 'f'}, {0: 'h', 1: 'r'}, {0: 'f'}])

if self.check_glitch_filter() == False:
continue

# Check which of the condition(s) matched and handle them.
if (self.matched & (0b1 << 0)):
Expand All @@ -291,7 +321,11 @@ def decode(self):
# Wait for any of the following conditions (or combinations):
# a) a data/ack bit: SCL = rising.
# b) STOP condition (P): SCL = high, SDA = rising
(scl, sda) = self.wait([{0: 'r'}, {0: 'h', 1: 'r'}])
(scl, sda) = self.wait([{0: 'r'}, {0: 'h', 1: 'r'}, {0: 'f'}])

if self.check_glitch_filter() == False:
continue

if (self.matched & (0b1 << 0)):
self.get_ack(scl, sda)
elif (self.matched & (0b1 << 1)):
Expand Down