|
@@ -578,8 +578,32 @@ sub tty_write($$$) {
|
|
|
}
|
|
|
|
|
|
sub upload_fpgadata($$) {
|
|
|
+ use bytes;
|
|
|
+
|
|
|
my($port, $fpgadata) = @_;
|
|
|
|
|
|
+ my $SOH = 001;
|
|
|
+ my $STX = 002;
|
|
|
+ my $ETX = 003;
|
|
|
+ my $EOT = 004;
|
|
|
+ my $ENQ = 005;
|
|
|
+ my $ACK = 006;
|
|
|
+ my $XON = 021; # A.k.a. DC1
|
|
|
+ my $WRST = 022; # DC2: window = 0
|
|
|
+ my $XOFF = 023; # A.k.a. DC3
|
|
|
+ my $WGO = 024; # DC4: window += 256 bytes
|
|
|
+ my $NAK = 025;
|
|
|
+ my $SYM = 026;
|
|
|
+ my $ETB = 027;
|
|
|
+ my $CAN = 030;
|
|
|
+ my $EM = 031; # Packet offset too high
|
|
|
+ my $FS = 034;
|
|
|
+ my $GS = 035;
|
|
|
+ my $RS = 036;
|
|
|
+ my $US = 037;
|
|
|
+
|
|
|
+ my $WGO_CHUNK = 256; # Each WGO = 256 bytes
|
|
|
+
|
|
|
my $SerialPort = eval {
|
|
|
require Device::SerialPort;
|
|
|
Device::SerialPort->import(qw(:PARAM));
|
|
@@ -644,9 +668,9 @@ sub upload_fpgadata($$) {
|
|
|
while (($tt = time()) - $start_enq < 30) {
|
|
|
my $d = tty_read($tty, \$ttybuf, 1000);
|
|
|
if ($d eq '') {
|
|
|
- tty_write($tty, \$ttybuf, "\005"); # ENQ
|
|
|
+ tty_write($tty, \$ttybuf, chr($ENQ));
|
|
|
} else {
|
|
|
- my $ix = index("\026\004\027", $d);
|
|
|
+ my $ix = index("\026\004\027", $d); # SYN EOT ETB
|
|
|
if ($ix < 0) {
|
|
|
print STDERR $d;
|
|
|
next;
|
|
@@ -669,6 +693,7 @@ sub upload_fpgadata($$) {
|
|
|
die "$0: $port: failed to start FPGA firmware upload\n";
|
|
|
}
|
|
|
if ($tt != $last_req) {
|
|
|
+ # FS SOH <string> GS
|
|
|
tty_write($tty, \$ttybuf,
|
|
|
"\034\001: /// MAX80 FW UPLOAD \~\@\~ \$\r\n\035");
|
|
|
$last_req = $tt;
|
|
@@ -679,7 +704,7 @@ sub upload_fpgadata($$) {
|
|
|
last if ($d eq '');
|
|
|
my $dc = unpack('C', $d);
|
|
|
print STDERR $a[$dc];
|
|
|
- if ($dc == 036) {
|
|
|
+ if ($dc == $RS) {
|
|
|
$winspc = 0;
|
|
|
last;
|
|
|
}
|
|
@@ -715,13 +740,13 @@ sub upload_fpgadata($$) {
|
|
|
last if ($d eq '');
|
|
|
|
|
|
my $dc = unpack('C', $d);
|
|
|
- if ($dc == 022) {
|
|
|
+ if ($dc == $WRST) {
|
|
|
$winspc = 0;
|
|
|
- } elsif ($dc == 024) {
|
|
|
+ } elsif ($dc == $WGO) {
|
|
|
if (defined($winspc)) {
|
|
|
- $winspc += 256;
|
|
|
+ $winspc += $WGO_CHUNK;
|
|
|
}
|
|
|
- } elsif ($dc == 006) {
|
|
|
+ } elsif ($dc == $ACK) {
|
|
|
$last_ack = shift(@pktends) || $last_ack;
|
|
|
if ($now != $last_ack_time) {
|
|
|
printf STDERR "%s: %s: %d/%d (%d%%) uploaded\n",
|
|
@@ -730,11 +755,11 @@ sub upload_fpgadata($$) {
|
|
|
}
|
|
|
} else {
|
|
|
print STDERR $a[$dc];
|
|
|
- if ($dc == 025 || $dc == 031 || $dc == 037) {
|
|
|
+ if ($dc == $NAK || $dc == $EM || $dc == $US) {
|
|
|
$offset = $last_ack;
|
|
|
@pktends = ();
|
|
|
undef $winspc; # Wait for WRST before resuming
|
|
|
- } elsif ($dc == 030) {
|
|
|
+ } elsif ($dc == $CAN) {
|
|
|
print STDERR "\n";
|
|
|
die "$0: $port: upload aborted by target system\n";
|
|
|
}
|
|
@@ -745,7 +770,7 @@ sub upload_fpgadata($$) {
|
|
|
if ($bytes > $offset) {
|
|
|
if ($now != $last_enq) {
|
|
|
# SYN: request window resync
|
|
|
- tty_write($tty, \$ttybuf, "\026");
|
|
|
+ tty_write($tty, \$ttybuf, chr($SYN));
|
|
|
$last_enq = $now;
|
|
|
}
|
|
|
}
|
|
@@ -755,14 +780,14 @@ sub upload_fpgadata($$) {
|
|
|
my $data = substr($fpgadata, $offset, $chunk);
|
|
|
my $hdr = pack("CvVV", $chunk-1, 0, $offset, crc32($data));
|
|
|
|
|
|
- tty_write($tty, \$ttybuf, "\002".mybaseencode($hdr, $data));
|
|
|
+ tty_write($tty, \$ttybuf, chr($STX).mybaseencode($hdr, $data));
|
|
|
|
|
|
push(@pktends, $offset + $chunk);
|
|
|
$offset += $chunk;
|
|
|
$winspc -= $chunk;
|
|
|
}
|
|
|
|
|
|
- tty_write($tty, \$ttybuf, "\004"); # EOT
|
|
|
+ tty_write($tty, \$ttybuf, chr($EOT));
|
|
|
|
|
|
# Final messages out
|
|
|
while (1) {
|
|
@@ -781,6 +806,7 @@ my $fpgaonly = 0;
|
|
|
my $file;
|
|
|
my $target_board = undef;
|
|
|
my $setver = 0;
|
|
|
+my $getver = 0;
|
|
|
my $port = undef;
|
|
|
my $which = 0;
|
|
|
|
|
@@ -797,6 +823,8 @@ while (1) {
|
|
|
} elsif ($file eq '--setver') {
|
|
|
$target_board = shift(@args);
|
|
|
$setver = defined($target_board);
|
|
|
+ } elsif ($file eq '--getver') {
|
|
|
+ $getver = 1;
|
|
|
} elsif ($file eq '--port') {
|
|
|
$port = shift(@args);
|
|
|
} elsif ($file eq '--') {
|
|
@@ -859,8 +887,14 @@ if ($which) {
|
|
|
print STDERR "esptool ${espver} found\n\n";
|
|
|
|
|
|
if (!defined($port)) {
|
|
|
- die "Usage: $0 [--which][--esponly][--setver version][--port port]\n".
|
|
|
- " [file.fw] [--esptool esptool_options...]\n";
|
|
|
+ die "Usage: $0 [options] [file.fw] [--esptool esptool_options...]\n".
|
|
|
+ " Options:\n".
|
|
|
+ " --which print the esptool command discovered, if any\n".
|
|
|
+ " --setver <version> set the board version string\n".
|
|
|
+ " --getver get the board version string, then exit\n".
|
|
|
+ " --esponly flash ESP32 only\n".
|
|
|
+ " --fpgaonly flash the FPGA only\n".
|
|
|
+ " --port serial port to use\n";
|
|
|
}
|
|
|
|
|
|
if (! -c $port && !File::Spec->file_name_is_absolute($port)) {
|
|
@@ -874,7 +908,7 @@ if (! -c $port && !File::Spec->file_name_is_absolute($port)) {
|
|
|
die "$0: no such serial port: $port\n";
|
|
|
}
|
|
|
}
|
|
|
-print STDERR "Using serial port device $port\n";
|
|
|
+print STDERR "$0: using serial port device $port\n";
|
|
|
|
|
|
my @espfiles = ();
|
|
|
|
|
@@ -901,6 +935,11 @@ if (defined($target_board)) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+if ($getver) {
|
|
|
+ print "$0: $port: board version: $target_board\n";
|
|
|
+ exit 0;
|
|
|
+}
|
|
|
+
|
|
|
my $fpgadata;
|
|
|
if (defined($file)) {
|
|
|
my $fwfiles;
|