 #!/usr/bin/perl -w
 
use strict;

BEGIN {

    if( index($^O, 'Win') >= 0 ) {   # MSWin32 (and not darwin, cygwin, ...)
        eval("require Win32::SerialPort") or die "Error: Failed dependencies!\nPlease install Win32::SerialPort via ppm or CPAN!\n";
        import  Win32::SerialPort;
    } else {
        eval("require Device::SerialPort") or die "Error: Failed dependencies!\nPlease install Device::SerialPort via CPAN!\n";
        import  Device::SerialPort;
    }
}

$|++; # disable buffering

print <<WARR_END;

*** No Warranty
***
*** This program is distributed in the hope that it will be useful,
*** but is provided AS IS with ABSOLUTELY NO WARRANTY;
*** The entire risk as to the quality and performance
*** of the program is with you. Should the program prove defective,
*** you assume the cost of all necessary servicing, repair or correction.
*** In no event will any of the developers, or any other party,
*** be liable to anyone for damages arising out of the use or inability
*** to use the program.

WARR_END

my ($serial, $count, $filehnd, $cur, $test, $line);
my ($dev, $filename) = @ARGV;

die "Error: not enough parameters! $0 <serial port> <flash file>\n" unless $dev and $filename;

my $ostype = $^O;
if (index($ostype, 'Win') >= 0) {
	$serial = Win32::SerialPort->new($dev);
} else {
	$serial = Device::SerialPort->new($dev);
}
die ("Error: can't open serial port. Typo? (e.g. COM1, /dev/ttyUSB0)\n") unless ref $serial;

$serial->baudrate(115200);
$serial->databits(8);
$serial->parity('none');
$serial->stopbits(1);
$serial->purge_all();
$serial->rts_active(0);
$serial->dtr_active(0);
$serial->read_const_time(1000);
if (index($ostype, 'Win') >= 0) {
	$serial->read_interval(100);
	$serial->read_char_time(5);
}
$serial->write_settings or die ("Error: can't init serial port.\n");

open($filehnd, $filename) or die "Error: File '$filename' not found.\n";
my @temp = <$filehnd>;
close($filehnd);

$count = @temp;

LINE: for $line (@temp) {

	$cur++;

	$line =~ s/[\r\n]//g; # get rid of any CR and LF
	print "$cur/$count: '", substr($line, 0, 39), length($line) > 40 ? '...' : '', "' ";
	if ($line =~ /^#.*/) {
		print "Comment not transferred.\n";
		next;
	}

	my $writecount = 0;
SERWRT:	while (1) {
		$serial->write("$line\r"); # append a CR 
		
		if ($line =~ /S8/) {
			print "Start command end of GERMS.\n";
			exit;
		}

		# waiting for response
		my ($readcount, $buffer) = (0, '');
		while ($buffer !~ /\+/) {
			my (undef, $str) = $serial->read(length($line) + 2); # $line + "\r" + "+"
			$buffer = "$buffer$str";
			print '.';
			if ($readcount++ > 10) {
				die <<TOEND;
\nError: Timeout while reading response from DSO!
Firmware update was NOT successful!
Please fix the connection issue and retry!
TOEND
			}
		}

		if ($buffer =~ /^$line\r\+$/) {
			print " OK\n";
			last SERWRT;
		} else {
			print "X";
			if ($writecount++ > 10) {
				die <<WEEND;
\nError: Unknown transmission error.
Firmware update was NOT successful!
Please fix the issue and retry!
WEEND
			}
		}
	}
	if ($cur == $count){ 
		print "READY!\n";
		exit;
	}
}

