From: ian Date: Sun, 9 Jan 2005 18:30:15 +0000 (+0000) Subject: decodes packets X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=150462588db978bc325a981def557adef90ed78b;p=trains.git decodes packets --- diff --git a/parport/nmra-decode.pl b/parport/nmra-decode.pl index c68b1d8..b94b281 100755 --- a/parport/nmra-decode.pl +++ b/parport/nmra-decode.pl @@ -16,12 +16,58 @@ sub usec_from_to ($$) { #---------- bit stream (packet) decoder ---------- -sub found_bit ($) { - my ($bit) = @_; -} +our ($idle_counter, $bitnum, @bytes); sub reset_packet_decoder () { - printf "-- restarting decoder --\n"; + $idle_counter= 0; +} + +sub packet_decoder_error ($) { + printf "EP (%s)\n", $_[0]; + reset_packet_decoder(); +} + +sub found_bit ($) { + my ($bit) = @_; + if (defined $idle_counter) { + if ($bit) { + $idle_counter++; + printf "I%-4d\n", $idle_counter; + return; + } + if ($idle_counter < 10) { + packet_decoder_error("I only $idle_counter"); + return; + } + undef $idle_counter; + $bitnum= -1; + @bytes= (); + } + if ($bitnum<0) { + if ($bit) { + my ($checksum,$byte); + $checksum= 0; + foreach $byte (@bytes) { + $checksum ^= hex $byte; + } + if ($checksum) { + packet_decoder_error("csum $checksum, @bytes"); + return; + } + print "P @bytes\n"; + $idle_counter= 0; + return; + } + $bitnum= 7; + push @bytes, 0; + print "F @bytes...\n"; + return; + } + $b= hex $bytes[$#bytes]; + $b |= ($bit << $bitnum); + $bytes[$#bytes]= sprintf "%02x", $b; + print "B @bytes($bitnum)\n"; + $bitnum--; } #---------- interval -> bit decoder ---------- @@ -52,6 +98,7 @@ sub interval_mapchar ($$@) { } sub reset_bit_decoder () { + printf "-- restarting bit decoder --\n"; undef @valuefor; undef $in_bit; $bit_phase_determined= 0; @@ -118,19 +165,19 @@ sub found_interval ($$$) { } if ($bit_half) { + undef $in_bit; if ($class eq 'U') { - printf " E UU\n"; + printf " E UU"; reset_packet_decoder(); - } else { - $bit_value= !!($class eq 'S'); - printf " %d ", $bit_value; - found_bit($bit_value); + return; } - undef $in_bit; + $bit_value= !!($class eq 'S'); + printf " %d ", $bit_value; + found_bit($bit_value); } else { $in_bit= $class; + printf "\n"; } - printf "\n"; } #---------- interval scanner ----------