From: ian Date: Sun, 9 Jan 2005 18:06:41 +0000 (+0000) Subject: decoder takes account of slop in input measurements X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=a9847747e849d28fb12da7866fb7ceb741e4a339;p=trains.git decoder takes account of slop in input measurements --- diff --git a/parport/nmra-decode.pl b/parport/nmra-decode.pl index 3f7c520..c68b1d8 100755 --- a/parport/nmra-decode.pl +++ b/parport/nmra-decode.pl @@ -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 () { @@ -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;