Hello sigrok developers, debugging a WS281x driver I was very confused to see #000000 values in sigrok when my LEDs lit up. Please pull from [1] or see below.
As I'm currently facing unrelated problems ([2] and somethign more) with my Hantek oscilloscope, I'd appreciate if this were tested on known-good data before merging. Best regards, and thanks for maintaining sigrok and pulseview! chrysn [1]: https://codeberg.org/chrysn-pull-requests/libsigrokdecode.git -b ws281x_is_time_based [2]: https://sigrok.org/bug/1884 --- From d22372bfaf1810c53003159e56ab68d57796fd2c Mon Sep 17 00:00:00 2001 From: chrysn <chr...@fsfe.org> Date: Wed, 16 Aug 2023 22:00:11 +0200 Subject: [PATCH] rgb_led_ws281x: Evaluate timing rather than duty cycle The duty cycle criterion is precise only if the source adheres to both the high and the low time -- but what the recipients actually evaluate is the high time, as long as the low time doesn't fall on the reset side of things. Thus, the criterion for recognizing a bit is changed from duty cycle to time. This also allows doing away with the workaround of using a previous period length for the last bit that ends at the reset condition and thus has no period of its own. Sources: Experimentation on SK6812 and "Timing" section of https://blog.kubovy.eu/2019/02/17/ws281x-using-pic/ --- decoders/rgb_led_ws281x/pd.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/decoders/rgb_led_ws281x/pd.py b/decoders/rgb_led_ws281x/pd.py index 099a2ce..486834e 100644 --- a/decoders/rgb_led_ws281x/pd.py +++ b/decoders/rgb_led_ws281x/pd.py @@ -107,6 +107,8 @@ def start(self): def metadata(self, key, value): if key == srd.SRD_CONF_SAMPLERATE: self.samplerate = value + # Number of ticks that represent 480ns, which is a value between the T0H upper bound (380ns) and the T1H lower bound (580ns) + self.t1h_threshold = 480e-9 * self.samplerate def putg(self, ss, es, cls, text): self.put(ss, es, self.out_ann, [cls, text]) @@ -202,7 +204,6 @@ def decode(self): # adjacent to that bit time. cond_bit_starts = {0: 'r'} cond_inbit_edge = {0: 'f'} - samples_625ns = int(self.samplerate * 625e-9) samples_50us = round(self.samplerate * 50e-6) cond_reset_pulse = {'skip': samples_50us + 1} conds = [cond_bit_starts, cond_inbit_edge, cond_reset_pulse] @@ -227,17 +228,8 @@ def decode(self): ss_rst, es_rst = inv_bit, self.samplenum if ss_bit and inv_bit and es_bit: - # Decode last bit value. Use the last processed bit's - # width for comparison when available. Fallback to an - # arbitrary threshold otherwise (which can result in - # false detection of value 1 for those captures where - # high and low pulses are of similar width). duty = inv_bit - ss_bit - thres = samples_625ns - if self.bits: - period = self.bits[-1][2] - self.bits[-1][1] - thres = period * 0.5 - bit_value = 1 if duty >= thres else 0 + bit_value = 1 if duty > self.t1h_threshold else 0 self.handle_bit(ss_bit, inv_bit, bit_value, True) if ss_rst and es_rst: @@ -258,8 +250,9 @@ def decode(self): es_bit = self.samplenum period = es_bit - ss_bit duty = inv_bit - ss_bit - # Ideal duty for T0H: 33%, T1H: 66%. - bit_value = 1 if (duty / period) > 0.5 else 0 + # The period cycle is not used; the controllers evaluate the + # high time and not the duty cycle. + bit_value = 1 if duty > self.t1h_threshold else 0 self.handle_bit(ss_bit, es_bit, bit_value) ss_bit, inv_bit, es_bit = self.samplenum, None, None if self.matched[1]: # and not pin: -- 2.40.1
signature.asc
Description: PGP signature
_______________________________________________ sigrok-devel mailing list sigrok-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sigrok-devel