From ae3fb34e4223a8ef0667989e170bc259812653c2 Mon Sep 17 00:00:00 2001 From: "Nate Bargmann, N0NB" Date: Fri, 16 Jan 2009 04:21:11 +0000 Subject: [PATCH] Fix to flush buffer if RotorEZ should receive an invalid command in which case it puts a long string into the buffer. git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2587 7ae35d74-ebe9-4afe-98af-79ac388436b8 --- rotorez/rotorez.c | 55 ++++++++++++++++++++++++++++++++++++++++++--- rotorez/rotorez.txt | 28 +++++++++++------------ 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/rotorez/rotorez.c b/rotorez/rotorez.c index 3cd63e773..c01e8ef92 100644 --- a/rotorez/rotorez.c +++ b/rotorez/rotorez.c @@ -12,7 +12,7 @@ * Hy-Gain is a trademark of MFJ Enterprises * * - * $Id: rotorez.c,v 1.10 2008-10-26 13:50:30 y32kn Exp $ + * $Id: rotorez.c,v 1.11 2009-01-16 04:21:11 n0nb Exp $ * * * This library is free software; you can redistribute it and/or @@ -44,6 +44,7 @@ #include "serial.h" #include "misc.h" #include "register.h" +#include "iofunc.h" #include "rotorez.h" @@ -60,6 +61,7 @@ struct rotorez_rot_priv_data { */ static int rotorez_send_priv_cmd(ROT *rot, const char *cmd); +static int rotorez_flush_buffer(ROT *rot); /* ************************************* * @@ -296,15 +298,27 @@ static int rotorez_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *e if (!rot) return -RIG_EINVAL; +get_az: err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) return err; rs = &rot->state; + err = read_block(&rs->rotport, az, AZ_READ_LEN); if (err != AZ_READ_LEN) return -RIG_ETRUNC; + /* The azimuth string should be ';xxx' beginning at offset 0. If the + * ';' is not there, it's likely the RotorEZ has received an invalid + * command and the buffer needs to be flushed. See rotorez_flush_buffer() + * definition below for a complete description. + */ + if (az[0] != ';') { + rotorez_flush_buffer(rot); + goto get_az; + } + /* * Rotor-EZ returns a four octet string consisting of a ';' followed * by three octets containing the rotor's position in degrees. The @@ -320,7 +334,7 @@ static int rotorez_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *e return -RIG_EINVAL; *azimuth = tmp; - *elevation = 0; /* assume aiming at the horizon */ + *elevation = 0; /* RotorEZ does not support elevation */ rig_debug(RIG_DEBUG_TRACE, "%s: azimuth = %.1f deg; elevation = %.1f deg\n", __func__, *azimuth, *elevation); @@ -408,6 +422,42 @@ static int rotorez_send_priv_cmd(ROT *rot, const char *cmdstr) { } +/* + * Flush the serial input buffer + * + * If the RotorEZ should receive an invalid command, such as an the ';' + * character while the rotor is not in motion, as sent by the rotorez_rot_stop + * function or the 'S' command from `rotctl', it will output the following + * string, "C2000 IDIOM V1.4S " into the input buffer. This function flushes + * the buffer by reading it until a timeout occurs. Once the timeout occurs, + * this function returns and the buffer is presumed to be empty. + */ + +static int rotorez_flush_buffer(ROT *rot) { + struct rot_state *rs; + char garbage[32]; /* read buffer */ + int err = 0; + size_t MAX = 31; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rot) + return -RIG_EINVAL; + + rs = &rot->state; + do { + err = read_block(&rs->rotport, garbage, MAX); + + /* Oops! An IO error was encountered. Bail out! */ + if (err == -RIG_EIO) + return -RIG_EIO; + } + while (err != -RIG_ETIMEOUT); + + return RIG_OK; +} + + /* * Initialize backend */ @@ -423,4 +473,3 @@ DECLARE_INITROT_BACKEND(rotorez) return RIG_OK; } - diff --git a/rotorez/rotorez.txt b/rotorez/rotorez.txt index ca86018d2..0b2c3312d 100644 --- a/rotorez/rotorez.txt +++ b/rotorez/rotorez.txt @@ -6,7 +6,7 @@ The Hy-Gain DCU-1/DCU-1X Digital Control Unit supports a subset of these commands--AP1XXX; and AM1; The DCU-1/DCU-1X is manufactured and sold by Hy-Gain, http://www.hy-gain.com -$Id: rotorez.txt,v 1.1 2003-01-12 14:29:15 n0nb Exp $ +$Id: rotorez.txt,v 1.2 2009-01-16 04:21:11 n0nb Exp $ From: "sales@idiompress.com" To: "Nate Bargmann" @@ -30,19 +30,19 @@ between 000 and 360, and executes. A typical command to rotate to 080 degrees would be AP1080 Note that the is often labeled on many keyboards. -"AP1xxx;" sets the target bearing but does not execute. -"AM1;" executes rotation to the bearing set by the "AP1xxx;" command -"AI1;" inquires current bearing; and responds with (000-359) degrees -";" terminates rotation -"E" enable endpoint option - effective immediately -"e" disable endpoint option - effective immediately -"O" enable overshoot option - effective immediately -"o" disable overshoot option - effective immediately -"S" enable unstick option - effective immediately -"s" disable unstick option - effective immediately -"V" reports version number -"J" enable jam protection - effective immediately -"j" disable jam protection - effective immediately - NOT recommended! +"AP1xxx;" sets the target bearing but does not execute. +"AM1;" executes rotation to the bearing set by the "AP1xxx;" command +"AI1;" inquires current bearing; and responds with (000-359) degrees +";" terminates rotation +"E" enable endpoint option - effective immediately +"e" disable endpoint option - effective immediately +"O" enable overshoot option - effective immediately +"o" disable overshoot option - effective immediately +"S" enable unstick option - effective immediately +"s" disable unstick option - effective immediately +"V" reports version number +"J" enable jam protection - effective immediately +"j" disable jam protection - effective immediately - NOT recommended! Note that during any rotation initiated by an RS232 command, the rotation can be halted and further rotation cancelled by a momentary press of the