]> sigrok.org Git - libsigrokdecode.git/commitdiff
timing: optional terse format for timing annoations
authorGerhard Sittig <redacted>
Fri, 3 Jul 2020 10:12:40 +0000 (12:12 +0200)
committerGerhard Sittig <redacted>
Tue, 7 Jul 2020 20:50:46 +0000 (22:50 +0200)
In some situations (inspecting a dense run of pulses in a burst of data
communication) it takes a lot of zooming before the 'timing' decoder's
'time' annotations start revealing numbers. Which limits the number of
pulses which can fit in the visible trace area.

This is a stab at improving the usability of the timing decoder for
similar "crowded pulses" scenarios. Try to come up with an annotation
text that is shorter yet communicates the very details which the user
needs in this situation. Drop the frequency, avoid umlauts in the unit
text, don't use decimal places (use all integers within a scale). Even
offer to drop the unit text, assuming that a dense run of pulses results
in all times sharing their scale.

Make the terse presentation optional and off by default, and use a
separate annotation class for maximum backwards compatibility.

decoders/timing/pd.py

index f14b64f4853abe3ada07cfbb4edd958faadb81ba..071c99057f2bdf15c8a760e7229605840fbde8d5 100644 (file)
@@ -45,11 +45,26 @@ def normalize_time(t):
     else:
         return '%f' % t
 
+def terse_times(t):
+    if abs(t) >= 1e0:
+        t *= 1e0
+        return ['{:.0f}s'.format(t), '{:.0f}'.format(t)]
+    if abs(t) >= 1e-3:
+        t *= 1e3
+        return ['{:.0f}ms'.format(t), '{:.0f}'.format(t)]
+    if abs(t) >= 1e-6:
+        t *= 1e6
+        return ['{:.0f}us'.format(t), '{:.0f}'.format(t)]
+    if abs(t) >= 1e-9:
+        t *= 1e9
+        return ['{:.0f}ns'.format(t), '{:.0f}'.format(t)]
+    return ['{:f}'.format(t = t)]
+
 class Pin:
     (DATA,) = range(1)
 
 class Ann:
-    (TIME, AVG, DELTA,) = range(3)
+    (TIME, TERSE, AVG, DELTA,) = range(4)
 
 class Decoder(srd.Decoder):
     api_version = 3
@@ -66,11 +81,12 @@ class Decoder(srd.Decoder):
     )
     annotations = (
         ('time', 'Time'),
+        ('terse', 'Terse'),
         ('average', 'Average'),
         ('delta', 'Delta'),
     )
     annotation_rows = (
-        ('times', 'Times', (Ann.TIME,)),
+        ('times', 'Times', (Ann.TIME, Ann.TERSE,)),
         ('averages', 'Averages', (Ann.AVG,)),
         ('deltas', 'Deltas', (Ann.DELTA,)),
     )
@@ -78,6 +94,7 @@ class Decoder(srd.Decoder):
         { 'id': 'avg_period', 'desc': 'Averaging period', 'default': 100 },
         { 'id': 'edge', 'desc': 'Edges to check', 'default': 'any', 'values': ('any', 'rising', 'falling') },
         { 'id': 'delta', 'desc': 'Show delta from last', 'default': 'no', 'values': ('yes', 'no') },
+        { 'id': 'terse', 'desc': 'Show periods in terse format', 'default': 'no', 'values': ('yes', 'no') },
     )
 
     def __init__(self):
@@ -98,6 +115,7 @@ class Decoder(srd.Decoder):
             raise SamplerateError('Cannot decode without samplerate.')
         edge = self.options['edge']
         avg_period = self.options['avg_period']
+        terse = self.options['terse'] == 'yes'
         ss = None
         last_n = deque()
         last_t = None
@@ -121,8 +139,10 @@ class Decoder(srd.Decoder):
             if len(last_n) > avg_period:
                 last_n.popleft()
 
-            self.put(ss, es, self.out_ann,
-                     [Ann.TIME, [normalize_time(t)]])
+            if terse:
+                self.put(ss, es, self.out_ann, [Ann.TERSE, terse_times(t)])
+            else:
+                self.put(ss, es, self.out_ann, [Ann.TIME, [normalize_time(t)]])
             if avg_period > 0:
                 self.put(ss, es, self.out_ann,
                          [Ann.AVG, [normalize_time(sum(last_n) / len(last_n))]])