6d1a29a3833b6861a8977fb8fccdc6e09d633b0a
[vrDialog] / dialog.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use Data::Dump qw(dump);
6 use Device::SerialPort qw(:STAT);
7
8 my $debug = $ENV{DEBUG} || 0;
9
10 my $port = Device::SerialPort->new('/dev/ttyUSB0');
11 $port->baudrate(9600);
12 $port->databits(8);
13 $port->parity('none');
14 $port->stopbits(1);
15 $port->handshake('none');
16
17 $port->read_char_time(500);
18 $port->read_const_time(1000);
19
20 sub as_hex {
21         my @out;
22         foreach my $str ( @_ ) {
23                 my $hex = uc unpack( 'H*', $str );
24                 $hex =~ s/(..)/$1 /g if length( $str ) > 2;
25                 $hex =~ s/\s+$//;
26                 push @out, $hex;
27         }
28         return join(' | ', @out);
29 }
30
31 sub hex2bytes {
32         my $bytes;
33         $bytes .= pack('C', hex('0x' . $_)) foreach split(/\s+/,join(' ',@_));
34         return $bytes;
35 }
36
37 sub crc {
38         my $data = shift;
39         my $crc = 0;
40         for my $i ( 0 .. length($data) - 2 ) {
41                 if ( $crc & 0x80 ) {
42                         $crc = ( $crc << 1 ) ^ 25;
43                 } else {
44                         $crc = $crc << 1;
45                 }
46                 $crc = $crc & 0xff;
47                 my $byte = ord(substr($data,$i,1));
48                 $crc = $crc ^ $byte;
49 #               warn "## ", as_hex(chr($byte)), " crc = ", $crc, " ", as_hex(chr($crc));
50         }
51         # ignore checksum errors for FF, we will calulate them!
52         if ( chr($crc) ne substr($data,-1,1) && substr($data,-1,1) ne "\xFF" ) {
53                 warn "CRC error for ",as_hex($data), " calulated ", as_hex(chr($crc));
54         }
55
56         return substr($data,0,-1) . chr($crc);
57 }
58
59 sub v_bytes {
60         my ($bytes,$desc) = @_;
61         warn "# $desc\n";
62 retry:
63         warn ">> ",as_hex( $bytes );
64         crc( $bytes );
65         $port->write( $bytes );
66
67         my $data = $port->read(1);
68         warn "<< len: ",ord($data) if $debug;
69
70         goto retry if ord($data) == 0;
71
72         $data .= $port->read(ord($data) - 1);
73         crc($data);
74         warn "<< ",as_hex($data);
75
76         my $o = 2;
77         while ( $o < length($data) - 2 ) {
78                 my $n = unpack('n', substr($data,$o,2));
79                 $n = -( 0xffff - $n ) if $n & 0x8000;
80                 warn "## $o = ",$n, "\t",$n / 16,"\n";
81                 $o += 2;
82         }
83
84         while ( $o < length($data) - 1 ) {
85                 my $n = unpack('c', substr($data,$o,1));
86                 warn "## $o = ", $n, "\n";
87                 $o += 1;
88         }
89
90         return $data;
91 }
92
93 sub v {
94         my ($hex,$desc) = @_;
95         v_bytes( hex2bytes( $hex ), $desc );
96 }
97
98 if ( ! @ARGV ) {
99         v '07 02 00 00 00 04 C4', "hardware version";
100
101         v '07 0A 00 00 00 04 44', 'software version';
102
103         v '07 00 01 00 06 0E EA', 'temperatures';
104
105         v '07 00 00 00 26 0A A6', 'last errros';
106 }
107
108 #v '07 00 00 00 26 00 AC', 'last errros (with invalid length)';
109
110 foreach my $reg ( @ARGV ) {
111         warn "# send user $reg\n";
112         v_bytes(
113                 crc( hex2bytes( "07 00 00 00 $reg 01 FF" ) )
114         ,"user: $reg");
115 }