chiark / gitweb /
decoder takes account of slop in input measurements
authorian <ian>
Sun, 9 Jan 2005 18:06:41 +0000 (18:06 +0000)
committerian <ian>
Sun, 9 Jan 2005 18:06:41 +0000 (18:06 +0000)
parport/nmra-decode.pl

index 3f7c520cd8cdec19fc8a8453edeb4c65a3b27972..c68b1d8d244a6acf572352fc192f393dc8ed4acc 100755 (executable)
@@ -5,12 +5,25 @@
 use strict qw(vars refs);
 use IO::Handle;
 
-#---------- bit stream decoder ----------
+sub usec_from_to ($$) {
+    my ($from,$to) = @_; # uses $from->{S}, $from->{U}, $to->{S}, $to->{U}
+    my ($s,$u);
+    $s= $to->{S} - $from->{S};
+    $u= $to->{U} - $from->{U};
+    die "interval $s.$u secs too big" if $s < -100 or $s > 100;
+    return $s * 1000000 + $u;
+}
+
+#---------- bit stream (packet) decoder ----------
 
 sub found_bit ($) {
     my ($bit) = @_;
 }
 
+sub reset_packet_decoder () {
+    printf "-- restarting decoder --\n";
+}
+
 #---------- interval -> bit decoder ----------
 
 our (@valuefor);
@@ -39,10 +52,10 @@ sub interval_mapchar ($$@) {
 }
 
 sub reset_bit_decoder () {
-    printf "-- restarting bit decoder --\n";
     undef @valuefor;
     undef $in_bit;
     $bit_phase_determined= 0;
+    reset_packet_decoder();
 }
 
 sub found_interval ($$$) {
@@ -105,9 +118,14 @@ sub found_interval ($$$) {
     }
 
     if ($bit_half) {
-       $bit_value= !!($class eq 'S');
-       printf "  %d  ", $bit_value;
-       found_bit($bit_value);
+       if ($class eq 'U') {
+           printf " E UU\n";
+           reset_packet_decoder();
+       } else {
+           $bit_value= !!($class eq 'S');
+           printf "  %d  ", $bit_value;
+           found_bit($bit_value);
+       }
        undef $in_bit;
     } else {
        $in_bit= $class;
@@ -115,31 +133,55 @@ sub found_interval ($$$) {
     printf "\n";
 }
 
-sub usec_from_to ($$) {
-    my ($from,$to) = @_;
-    my ($s,$u);
-    $s= $to->{S} - $from->{S};
-    $u= $to->{U} - $from->{U};
-    die "interval $s.$u secs too big" if $s < -100 or $s > 100;
-    return $s * 1000000 + $u;
+#---------- interval scanner ----------
+
+our (%interval,%last);
+# $now{V}           value at this instant
+# $now{S}           seconds
+# $now{U}           microseconds
+# $now{Slop}        slop in current transition; undef = no transition here
+# $last{V}          value at last instant               } undef =
+# $last{S}          time of last instant (seconds)      }    before first
+# $last{U}          time of last instant (microseconds) }    instant
+# $last{Slop}       irrelevant
+# $interval{V}      value in the current interval; undef = before first val
+# $interval{S}      } start of current interval
+# $interval{U}      }  undef = no transition found yet
+# $interval{Slop}   }
+
+sub found_datapoint ($$$$) {
+    # found_datapoint($s,$u,$value,$inacc) is called
+    #  when we find that $value was measured at between $s.$u and $s.$u+$inacc
+    my (%now) = (S => $_[0], U => $_[1], V => $_[2]);
+    my ($inacc) = $_[3];
+    my ($minlen,$maxlen);
+    
+    if (exists $interval{V} and $now{V} ne $interval{V}) {
+       # found a transition
+       $now{Slop}= usec_from_to(\%last,\%now) + $inacc;
+    }
+    if (defined $now{Slop} and defined $interval{S}) {
+       # found an interval
+       $minlen= usec_from_to(\%interval,\%now) - $now{Slop};
+       $maxlen= $minlen + $interval{Slop};
+       printf("\@<%10d.%06d %6d..%-6d %s ",
+              $now{S},$now{U}, $minlen,$maxlen, $interval{V});
+       found_interval($interval{V}, $minlen, $maxlen);
+    }
+    if (defined $now{Slop}) { # found a transition ? mark it as last one
+       %interval= %now;
+    }
+    if (!defined $interval{V}) { # if right at start, simply not current V
+       $interval{V}= $now{V};
+    }
+    %last= %now;
 }
 
-sub scan_for_intervals() {
-    my (%interval,%now,%last);
-    # $now{V}           value at this instant
-    # $now{S}           seconds
-    # $now{U}           microseconds
-    # $now{Slop}        slop in current transition; undef = no transition here
-    # $last{V}          value at last instant               } undef =
-    # $last{S}          time of last instant (seconds)      }    before first
-    # $last{U}          time of last instant (microseconds) }    instant
-    # $last{Slop}       irrelevant
-    # $interval{V}      value in the current interval; undef = before first val
-    # $interval{S}      } start of current interval
-    # $interval{U}      }  undef = no transition found yet
-    # $interval{Slop}   }
-    my ($minlen,$maxlen);
+#---------- datapoint reader ----------
 
+sub read_input_file() {
+    my (%now,%last);
+    
     reset_bit_decoder();
 
     while (<STDIN>) {
@@ -148,30 +190,15 @@ sub scan_for_intervals() {
 
        %now= (S => $1,
               U => $2,
-              V => hex $3);
-
-       if (exists $interval{V} and $now{V} ne $interval{V}) {
-           # found a transition
-           $now{Slop}= usec_from_to(\%last,\%now);
-       }
-       if (defined $now{Slop} and defined $interval{S}) {
-           # found an interval
-           $minlen= usec_from_to(\%interval,\%now);
-           $maxlen= $minlen + $interval{Slop} + $now{Slop};
-           printf("\@<%10d.%06d %6d..%-6d %s ",
-                  $now{S},$now{U}, $minlen,$maxlen, $interval{V});
-           found_interval($interval{V}, $minlen, $maxlen);
-       }
-       if (defined $now{Slop}) { # found a transition ? mark it as last one
-           %interval= %now;
-       }
-       if (!defined $interval{V}) { # if right at start, simply not current V
-           $interval{V}= $now{V};
+              V => $3);
+       if (defined $last{V}) {
+           found_datapoint($last{S}, $last{U}, $last{V},
+                           usec_from_to(\%last, \%now));
        }
        %last= %now;
     }
+    die $! if STDIN->error;
 }
 
-scan_for_intervals();
-die $! if STDIN->error;
+read_input_file();
 die $! if STDOUT->error;