--- a/bbabble Thu Nov 21 14:01:21 2013 +0000
+++ b/bbabble Fri Jul 03 10:25:08 2020 -0400
@@ -2,12 +2,12 @@
#======================================================================
# B B A B B L E
# doc: Thu Mar 11 01:00:51 2004
-# dlm: Wed Dec 1 14:31:14 2010
+# dlm: Fri Jul 3 10:12:51 2020
# (c) 2004 A.M. Thurnherr
-# uE-Info: 49 73 NIL 0 0 72 10 2 8 NIL ofnI
+# uE-Info: 58 0 NIL 0 0 72 10 2 8 NIL ofnI
#======================================================================
-# Broad Band Babble --- talk to 1--2 RDI ADCPs
+# Broad Band Babble --- talk to 1--2 RDI ADCPs or other serial instruments
# HISTORY:
# Mar 5, 2004: - written first, one-page-long proof-of-concept version
@@ -47,6 +47,14 @@
# Aug 26, 2010: - added -y)modem receive
# Oct 18, 2010: - added -u option to default ymodem receive call
# Dec 1, 2010: - BUG: -y with empty-string option argument did not work
+# Jun 18, 2018: - explicitly implemented code to disable download on -y ""
+# - BUG: one debug message had -s wrong way round
+# - added state-change test required when Arduino closes USB connection
+# - BUG: non-existing ttys had stupid error messages
+# - made -s default and added -a to show async output, which is for debugging only
+# - changed default to use -m unless 2 devices are chosen
+# - begin implementing non-R)DI mode (currently, upload only)
+# Jul 3, 2020: - expunged master/slave terminology
#----------------------------------------------------------------------
# USAGE
@@ -54,33 +62,25 @@
use Getopt::Std;
-$USAGE = "Usage: $0 [-m)onochrome] [-s)uppress async output] " .
- "[-y)modem receive <cmd>] " .
+$USAGE = "Usage: $0 [-m)onochrome] [-s)uppress async output(default)] [produce -a)sync ouput]" .
+ "[-y)modem receive <cmd[\"\" for none]>] [non-R)DI mode]" .
"<tty0_device> [tty1_device]\n";
-die($USAGE) unless (getopts("msy:"));
+die($USAGE) unless (getopts("amRsy:"));
+$opt_s = 1 unless ($opt_a);
+$opt_m = 1 unless (@ARGV > 1);
+
+#============================== USER MANUAL ==============================
# bbabble is started with 1 or 2 arguments, which are tty special files.
# On LINUX, /dev/ttyS0 is com1: /dev/ttyS1 is com2: /dev/ttyUSB0 is the
# first USB tty port, /dev/ttyUSB1 is the 2nd, &c. If two ttys are
# specified bbabble can talk to two instruments in parallel. Communication
# with The first (second) port is shown in red (blue). For consistency
-# with the color scheme used by the LDEO expect scripts, the master
-# (downlooker) should be connected to the first tty given on the command
-# line.
-
-# On some (especially BSD-based) systems there are separate tty
-# device files for dialin and dialout operations. Only the latter work
-# with bbabble. They traditionally have names matching /dev/cu* (e.g.
-# /dev/cuad0 for the first serial # port in FreeBSD).
-
-# In order to have read/write access to the device files, the user
-# that is to run bbabble should be added to the group that owns
-# the tty device files (e.g. dialer on FreeBSD).
-
-# The -m option suppresses color ouput and -s suppresses the asynchronous
-# messages generated by bbabble and printed in curly braces. Both
-# options should be used if bbabble is run within expect(1).
+# with the color scheme used by the LDEO expect scripts, the instrument
+# sending the sync pulses (downlooker) should be connected to the first
+# tty given on the command line. When only one port is specified, the
+# -m)onochrome option is assumed.
# Upon startup, bbabble prints a help message showing the current
# "foreground" instrument as well as a list of legal keyboard commands.
@@ -115,6 +115,17 @@
# instrument. The command file may contain any valid RDI command, empty
# lines, as well as comments beginning with a semicolon (;).
+#====================== USAGE NOTES ==============================
+
+# On some (especially BSD-based) systems there are separate tty
+# device files for dialin and dialout operations. Only the latter work
+# with bbabble. They traditionally have names matching /dev/cu* (e.g.
+# /dev/cuad0 for the first serial # port in FreeBSD).
+
+# In order to have read/write access to the device files, the user
+# that is to run bbabble should be added to the group that owns
+# the tty device files (e.g. dialer on FreeBSD).
+
# Upon startup, bbabble expects to communicate with the ADCPs at 9600bps
# (baud). If the user sends a BREAK (^C) and garbage is produced the
# instrument's default baud rate is probably set to a different value.
@@ -247,15 +258,17 @@
# If -y is not given, bbabble trys to find one of the standard ymodem
# executables. Using -y allows options to be set.
-if (length($opt_y) > 0) {
- $receive_ymodem = $opt_y;
+if (defined($opt_y)) {
+ if (length($opt_y) > 0) {
+ $receive_ymodem = $opt_y;
+ }
} else {
- chomp($receive_ymodem = `which lrb 2>/dev/null`);
- chomp($receive_ymodem = `which rb 2>/dev/null`)
- if ($receive_ymodem eq '');
- die("$0: cannot find rb or lrb\n")
- if ($receive_ymodem eq '');
- $receive_ymodem .= ' -u'; # keep upper-case filenames
+ chomp($receive_ymodem = `which lrb 2>/dev/null`);
+ chomp($receive_ymodem = `which rb 2>/dev/null`)
+ if ($receive_ymodem eq '');
+ die("$0: cannot find rb or lrb\n")
+ if ($receive_ymodem eq '');
+ $receive_ymodem .= ' -u'; # keep upper-case filenames
}
# When uploading command files, each command is sent after a prompt
@@ -330,10 +343,12 @@
}
my(@sfd); # TTYs
+-c $TTY0 || die("$TTY0: no such file or directory\n");
open(TTY0,'+>',$TTY0) || die("$TTY0: $!\n");
$sfd[0] = fileno(TTY0);
if (defined($TTY1)) {
select(undef,undef,undef,$naptime); # KEYSPAN 49W requires this
+ -c $TTY1 || die("$TTY1: no such file or directory\n");
open(TTY1,'+>',$TTY1) || die("$TTY1: $!\n");
$sfd[1] = fileno(TTY1);
}
@@ -386,7 +401,7 @@
| POSIX::CS8());
$t->setcc(POSIX::VMIN,1); $t->setcc(POSIX::VTIME,0);
set_speed($t,$id,$DEFAULT_SPEED[$id]);
- if ($opt_s) {
+ unless ($opt_s) {
print($COLOR[$id]) unless ($opt_m);
print("{TTY $id READY}");
}
@@ -402,7 +417,9 @@
$rcv_state[$id] == $BUFFER);
vec($rin,$sfd[$id],1) = 1;
}
-
+ last unless ($rcv_state[$id] == $ECHO || # needed when Arduino USB interface is closed at other end
+ $rcv_state[$id] == $BUFFER);
+
#------------------------------
# DOWNLOAD DATA FROM INSTRUMENT
#------------------------------
@@ -807,7 +824,9 @@
if ($rcv_state[$cid]&$DOWNLOAD){
print(STDERR "$COLOR[$cid]\{DOWNLOAD IN PROGRESS --- ^C TO ABORT}\n");
} else {
- $tmp = $rcv_state[$cid]&~$ECHO; $rcv_state[$cid] = $tmp|$BUFFER;
+ unless ($opt_R) {
+ $tmp = $rcv_state[$cid]&~$ECHO; $rcv_state[$cid] = $tmp|$BUFFER;
+ }
print($RESET);
cookedmode();
do {
@@ -815,8 +834,10 @@
if ($_ eq '') { # no file name given
print("{upload canceled}\n");
rawmode();
- $tmp = $rcv_state[$cid]&~$BUFFER; $rcv_state[$cid] = $tmp|$FLUSH;
- wait_for_bit_cleared($cid,$FLUSH);
+ unless ($opt_R) {
+ $tmp = $rcv_state[$cid]&~$BUFFER; $rcv_state[$cid] = $tmp|$FLUSH;
+ wait_for_bit_cleared($cid,$FLUSH);
+ }
next KEYSTROKE;
}
unless (open(CF,$_)) {
@@ -825,28 +846,33 @@
}
} while (0);
rawmode();
- $tmp = $rcv_state[$cid]&~$BUFFER; $rcv_state[$cid] = $tmp|$FLUSH;
- wait_for_bit_cleared($cid,$FLUSH);
- my($cmd) = next_cmd(CF); # read ahead (last cmd may ...
- my($next_cmd); # ... not generate prompt)
- while (defined($next_cmd = next_cmd(CF))) {
- $rcv_state[$cid] = $UPLOAD;
- if ($cmd eq '<BREAK>') {
- send_BREAK($cid);
- } else {
- POSIX::write($sfd[$cid],"$cmd\r",length($cmd)+1);
+ if ($opt_R) { # non-RDI mode: dump entire file contents raw
+ my($buf,$nread);
+ while (($nread = read(CF,$buf,1)) > 0) { # nice small chunks
+ POSIX::write($sfd[$cid],$buf,$nread);
+ }
+ } else { # RDI mode: parse command file and send command by command
+ $tmp = $rcv_state[$cid]&~$BUFFER; $rcv_state[$cid] = $tmp|$FLUSH;
+ wait_for_bit_cleared($cid,$FLUSH);
+ my($cmd) = next_cmd(CF); # read ahead (last cmd may ...
+ my($next_cmd); # ... not generate prompt)
+ while (defined($next_cmd = next_cmd(CF))) {
+ $rcv_state[$cid] = $UPLOAD;
+ if ($cmd eq '<BREAK>') {
+ send_BREAK($cid);
+ } else {
+ POSIX::write($sfd[$cid],"$cmd\r",length($cmd)+1);
+ }
+ $cmd = $next_cmd;
+ wait_for_bit_set($cid,$ECHO); # NOT SURE!!!
+ $tmp = $rcv_state[$cid]&~$ECHO; $rcv_state[$cid] = $tmp|$BUFFER;
+ print("\n${RESET}{upload finished}\n");
+ $tmp = $rcv_state[$cid]&~$BUFFER; $rcv_state[$cid] = $tmp|$FLUSH;
+ wait_for_bit_cleared($cid,$FLUSH);
}
- $cmd = $next_cmd;
- wait_for_bit_set($cid,$ECHO); # NOT SURE!!!
}
close(CF);
- POSIX::write($sfd[$cid],"$cmd\r",length($cmd)+1); # last cmd
-
- $tmp = $rcv_state[$cid]&~$ECHO; $rcv_state[$cid] = $tmp|$BUFFER;
- print("\n${RESET}{upload finished}\n");
- $tmp = $rcv_state[$cid]&~$BUFFER; $rcv_state[$cid] = $tmp|$FLUSH;
- wait_for_bit_cleared($cid,$FLUSH);
}
}
@@ -855,15 +881,19 @@
#--------------------------
elsif ($char == 24) {
- if ($rcv_state[$cid]&$DOWNLOAD){
- print(STDERR "$COLOR[$cid]\{DOWNLOAD IN PROGRESS --- ^C TO ABORT}\n");
+ if (defined($receive_ymodem)) {
+ if ($rcv_state[$cid]&$DOWNLOAD){
+ print(STDERR "$COLOR[$cid]\{DOWNLOAD IN PROGRESS --- ^C TO ABORT}\n");
+ } else {
+ $rcv_state[$cid] = $SET_DOWNLOAD_SPEED;
+ wait_for_bit_set($cid,$ECHO);
+ $rcv_state[$cid] = $DOWNLOAD; # start waiting for instr. ready
+ POSIX::write($sfd[$cid],"$START_DOWNLOAD_RDI_COMMAND\r",
+ length($START_DOWNLOAD_RDI_COMMAND)+1);
+ wait_for_bit_set($cid,$ECHO);
+ }
} else {
- $rcv_state[$cid] = $SET_DOWNLOAD_SPEED;
- wait_for_bit_set($cid,$ECHO);
- $rcv_state[$cid] = $DOWNLOAD; # start waiting for instr. ready
- POSIX::write($sfd[$cid],"$START_DOWNLOAD_RDI_COMMAND\r",
- length($START_DOWNLOAD_RDI_COMMAND)+1);
- wait_for_bit_set($cid,$ECHO);
+ print(STDERR "$COLOR[$cid]\{NO YMODEM RECEIVER PROGRAM SPECIFIED}\n");
}
}