X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=dialog.pl;h=6e3445efb987fa003f06934b25f28c3883dbe369;hb=3963b022e8ede3147104660c3d77404301b6ac74;hp=b0e630d5a7b6e8ab072d8858469caaeccf7dfda8;hpb=350a28bc648f4b3e194eebb7a29b18b2d8253919;p=vrDialog diff --git a/dialog.pl b/dialog.pl index b0e630d..6e3445e 100755 --- a/dialog.pl +++ b/dialog.pl @@ -5,7 +5,10 @@ use strict; use Data::Dump qw(dump); use Device::SerialPort qw(:STAT); +my $debug = $ENV{DEBUG} || 0; + my $port = Device::SerialPort->new('/dev/ttyUSB0'); +die "can't open serial port" unless $port; $port->baudrate(9600); $port->databits(8); $port->parity('none'); @@ -15,6 +18,19 @@ $port->handshake('none'); $port->read_char_time(500); $port->read_const_time(1000); +sub read_serial { + my $len = shift; + return $port->read( $len ); +} + +sub write_serial { + my $bytes = shift; + return $port->write( $bytes ); +} + +# TODO: implement remote serial port +# remserial -x 2 -p 23000 -s "9600 raw" /dev/ttyUSB0 + sub as_hex { my @out; foreach my $str ( @_ ) { @@ -32,24 +48,82 @@ sub hex2bytes { return $bytes; } -sub v { - my ($hex,$expect,$desc) = @_; - my $bytes = hex2bytes( $hex ); +sub crc { + my $data = shift; + my $crc = 0; + for my $i ( 0 .. length($data) - 2 ) { + if ( $crc & 0x80 ) { + $crc = ( $crc << 1 ) ^ 25; + } else { + $crc = $crc << 1; + } + $crc = $crc & 0xff; + my $byte = ord(substr($data,$i,1)); + $crc = $crc ^ $byte; +# warn "## ", as_hex(chr($byte)), " crc = ", $crc, " ", as_hex(chr($crc)); + } + # ignore checksum errors for FF, we will calulate them! + if ( chr($crc) ne substr($data,-1,1) && substr($data,-1,1) ne "\xFF" ) { + warn "CRC error for ",as_hex($data), " calulated ", as_hex(chr($crc)); + } + + return substr($data,0,-1) . chr($crc); +} + +sub v_bytes { + my ($bytes,$desc) = @_; warn "# $desc\n"; +retry: warn ">> ",as_hex( $bytes ); - $port->write( $bytes ); + crc( $bytes ); + write_serial( $bytes ); + + my $data = read_serial(1); + warn "<< len: ",ord($data) if $debug; - my $data = $port->read(1); - warn "<< len: ",ord($data); - $data .= $port->read(ord($data) - 1); + goto retry if ord($data) == 0; + + $data .= read_serial(ord($data) - 1); + crc($data); warn "<< ",as_hex($data); - warn "?? $expect\n" if $expect; + my $o = 2; + while ( $o < length($data) - 2 ) { + my $n = unpack('n', substr($data,$o,2)); + $n = -( 0xffff - $n ) if $n & 0x8000; + warn "## $o = ",$n, "\t",$n / 16,"\n"; + $o += 2; + } + + while ( $o < length($data) - 1 ) { + my $n = unpack('c', substr($data,$o,1)); + warn "## $o = ", $n, "\n"; + $o += 1; + } + + return $data; +} + +sub v { + my ($hex,$desc) = @_; + v_bytes( hex2bytes( $hex ), $desc ); } -#v '07 02 00 00 00 04 C4', "hardware version"; +if ( ! @ARGV ) { + v '07 02 00 00 00 04 C4', "hardware version"; + + v '07 0A 00 00 00 04 44', 'software version'; -#v '07 0A 00 00 00 04 44', 'software version'; + v '07 00 01 00 06 0E EA', 'temperatures'; -v '07 00 01 00 06 0E EA', 'temperatures'; + v '07 00 00 00 26 0A A6', 'last errros'; +} + +#v '07 00 00 00 26 00 AC', 'last errros (with invalid length)'; +foreach my $reg ( @ARGV ) { + warn "# send user $reg\n"; + v_bytes( + crc( hex2bytes( "07 00 00 00 $reg 01 FF" ) ) + ,"user: $reg"); +}