From f6a7e6628c223f01ff0d5982fb21fd84945d89bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Fillod=2C=20F8CFE?= Date: Fri, 23 May 2008 14:14:17 +0000 Subject: [PATCH] added GS-232A rotator controller git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2361 7ae35d74-ebe9-4afe-98af-79ac388436b8 --- bindings/ignore.swg | 2 + configure.ac | 3 +- gs232a/Makefile.am | 7 + gs232a/gs232a.c | 281 +++++++++++++++++++++++++++++++++++++++ gs232a/gs232a.h | 28 ++++ include/hamlib/rotlist.h | 15 ++- 6 files changed, 333 insertions(+), 3 deletions(-) create mode 100644 gs232a/Makefile.am create mode 100644 gs232a/gs232a.c create mode 100644 gs232a/gs232a.h diff --git a/bindings/ignore.swg b/bindings/ignore.swg index 23718df32..b12e3aacc 100644 --- a/bindings/ignore.swg +++ b/bindings/ignore.swg @@ -73,6 +73,8 @@ %ignore ROT_BACKEND_ROTOREZ; %ignore ROT_SARTEK; %ignore ROT_BACKEND_SARTEK; +%ignore ROT_GS232A; +%ignore ROT_BACKEND_GS232A; %ignore PRIfreq; %ignore SCNfreq; diff --git a/configure.ac b/configure.ac index 6bd9e0991..2e1d372ce 100644 --- a/configure.ac +++ b/configure.ac @@ -223,7 +223,7 @@ AC_SUBST(RIGMATRIX) BACKEND_LIST="icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc drake lowe rft kit skanti tapr flexradio wj racal tuner" -ROT_BACKEND_LIST="dummy easycomm rotorez sartek fodtrack" +ROT_BACKEND_LIST="dummy easycomm fodtrack gs232a rotorez sartek" BINDINGS="" BINDING_ALL="" BINDING_CHECK="" @@ -499,6 +499,7 @@ tuner/Makefile gnuradio/Makefile easycomm/Makefile fodtrack/Makefile +gs232a/Makefile sartek/Makefile rpcrig/Makefile rpcrot/Makefile diff --git a/gs232a/Makefile.am b/gs232a/Makefile.am new file mode 100644 index 000000000..700833346 --- /dev/null +++ b/gs232a/Makefile.am @@ -0,0 +1,7 @@ + +lib_LTLIBRARIES = hamlib-gs232a.la +hamlib_gs232a_la_SOURCES = gs232a.c +hamlib_gs232a_la_LDFLAGS = -no-undefined -module -avoid-version +hamlib_gs232a_la_LIBADD = $(top_builddir)/src/libhamlib.la + +noinst_HEADERS = gs232a.h diff --git a/gs232a/gs232a.c b/gs232a/gs232a.c new file mode 100644 index 000000000..093868b75 --- /dev/null +++ b/gs232a/gs232a.c @@ -0,0 +1,281 @@ +/* + * Hamlib Rotator backend - GS-232A + * Copyright (c) 2001-2008 by Stephane Fillod + * + * $Id: gs232a.c,v 1.1 2008-05-23 14:14:17 fillods Exp $ + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include /* String function definitions */ +#include /* UNIX standard function definitions */ +#include + +#include "hamlib/rotator.h" +#include "serial.h" +#include "misc.h" +#include "register.h" + +#include "gs232a.h" + +#define EOM "\r\n" +#define REPLY_EOM "\r" + +#define BUFSZ 64 + +/** + * gs232a_transaction + * + * cmdstr - Command to be sent to the rig. + * data - Buffer for reply string. Can be NULL, indicating that no reply is + * is needed, but answer will still be read. + * data_len - in: Size of buffer. It is the caller's responsibily to provide + * a large enough buffer for all possible replies for a command. + * + * returns: + * RIG_OK - if no error occured. + * RIG_EIO - if an I/O error occured while sending/receiving data. + * RIG_ETIMEOUT - if timeout expires without any characters received. + * RIG_REJECTED - if a negative acknowledge was received or command not + * recognized by rig. + */ +int +gs232a_transaction (ROT *rot, const char *cmdstr, + char *data, size_t data_len) +{ + struct rot_state *rs; + int retval; + int retry_read = 0; + char replybuf[BUFSZ]; + + rs = &rot->state; + +transaction_write: + + serial_flush(&rs->rotport); + + if (cmdstr) { + retval = write_block(&rs->rotport, cmdstr, strlen(cmdstr)); + if (retval != RIG_OK) + goto transaction_quit; + } + + /* Always read the reply to know whether the cmd went OK */ + if (!data) + data = replybuf; + if (!data_len) + data_len = BUFSZ; + + memset(data,0,data_len); + retval = read_string(&rs->rotport, data, data_len, REPLY_EOM, strlen(REPLY_EOM)); + if (retval < 0) { + if (retry_read++ < rot->state.rotport.retry) + goto transaction_write; + goto transaction_quit; + } + +#if 0 + /* Check that command termination is correct */ + if (strchr(REPLY_EOM, data[strlen(data)-1])==NULL) { + rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __FUNCTION__, data); + if (retry_read++ < rig->state.rotport.retry) + goto transaction_write; + retval = -RIG_EPROTO; + goto transaction_quit; + } +#endif + + if (data[0] == '?') { + /* Invalid command */ + rig_debug(RIG_DEBUG_VERBOSE, "%s: Error for '%s': '%s'\n", + __FUNCTION__, cmdstr, data); + retval = -RIG_EPROTO; + goto transaction_quit; + } + + retval = RIG_OK; +transaction_quit: + return retval; +} + + +static int +gs232a_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) +{ + char cmdstr[64]; + int retval; + unsigned u_az, u_el; + + rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __FUNCTION__, az, el); + + u_az = (unsigned)rint(az); + u_el = (unsigned)rint(el); + + sprintf(cmdstr, "W %03u %03u" EOM, u_az, u_el); + retval = gs232a_transaction(rot, cmdstr, NULL, 0); + + if (retval != RIG_OK) { + return retval; + } + + return RIG_OK; +} + +static int +gs232a_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) +{ + char posbuf[32]; + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s called\n", __FUNCTION__); + + retval = gs232a_transaction(rot, "C2" EOM, posbuf, sizeof(posbuf)); + if (retval != RIG_OK || strlen(posbuf) < 10) { + return retval; + } + + /* parse */ + if (sscanf(posbuf+2, "%f", az) != 1) { + rig_debug(RIG_DEBUG_ERR, "%s: wrong reply '%s'\n", __FUNCTION__, posbuf); + return -RIG_EPROTO; + } + if (sscanf(posbuf+7, "%f", el) != 1) { + rig_debug(RIG_DEBUG_ERR, "%s: wrong reply '%s'\n", __FUNCTION__, posbuf); + return -RIG_EPROTO; + } + + rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", + __FUNCTION__, *az, *el); + + return RIG_OK; +} + +static int +gs232a_rot_stop(ROT *rot) +{ + int retval; + + rig_debug(RIG_DEBUG_TRACE, "%s called\n", __FUNCTION__); + + /* All Stop */ + retval = gs232a_transaction(rot, "S" EOM, NULL, 0); + if (retval != RIG_OK) + return retval; + + return RIG_OK; +} + + +static int +gs232a_rot_move(ROT *rot, int direction, int speed) +{ + char cmdstr[24]; + int retval; + unsigned x_speed; + + rig_debug(RIG_DEBUG_TRACE, "%s called %d %d\n", __FUNCTION__, + direction, speed); + + x_speed = (3*speed)/100 + 1; + + /* between 1 (slowest) and 4 (fastest) */ + sprintf(cmdstr, "X%u" EOM, x_speed); + retval = gs232a_transaction(rot, cmdstr, NULL, 0); + if (retval != RIG_OK) + return retval; + + switch (direction) { + case ROT_MOVE_UP: /* Elevation increase */ + sprintf(cmdstr, "U" EOM); + break; + case ROT_MOVE_DOWN: /* Elevation decrease */ + sprintf(cmdstr, "D" EOM); + break; + case ROT_MOVE_LEFT: /* Azimuth decrease */ + sprintf(cmdstr, "L" EOM); + break; + case ROT_MOVE_RIGHT: /* Azimuth increase */ + sprintf(cmdstr, "R" EOM); + break; + default: + rig_debug(RIG_DEBUG_ERR,"%s: Invalid direction value! (%d)\n", + __FUNCTION__, direction); + return -RIG_EINVAL; + } + + retval = gs232a_transaction(rot, cmdstr, NULL, 0); + if (retval != RIG_OK) + return retval; + + return RIG_OK; +} + +/* ************************************************************************* */ +/* + * Generic GS232A rotator capabilities. + */ + +const struct rot_caps gs232a_rot_caps = { + .rot_model = ROT_MODEL_GS232A, + .model_name = "GS-232A", + .mfg_name = "Yaesu", + .version = "0.1", + .copyright = "LGPL", + .status = RIG_STATUS_NEW, + .rot_type = ROT_TYPE_OTHER, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 150, + .serial_rate_max = 9600, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_NONE, + .write_delay = 0, + .post_write_delay = 0, + .timeout = 400, + .retry = 3, + + .min_az = 0.0, + .max_az = 450.0, /* vary according to rotator type */ + .min_el = 0.0, + .max_el = 180.0, /* requires G-5400B, G-5600B, G-5500, or G-500/G-550 */ + + .get_position = gs232a_rot_get_position, + .set_position = gs232a_rot_set_position, + .stop = gs232a_rot_stop, + .move = gs232a_rot_move, +}; + +/* ************************************************************************* */ + +DECLARE_INITROT_BACKEND(gs232a) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__); + + rot_register(&gs232a_rot_caps); + + return RIG_OK; +} + +/* ************************************************************************* */ +/* end of file */ + diff --git a/gs232a/gs232a.h b/gs232a/gs232a.h new file mode 100644 index 000000000..208c4365b --- /dev/null +++ b/gs232a/gs232a.h @@ -0,0 +1,28 @@ +/* + * Hamlib Rotator backend - GS-232A interface protocol + * Copyright (c) 2001-2008 by Stephane Fillod + * + * $Id: gs232a.h,v 1.1 2008-05-23 14:14:17 fillods Exp $ + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _ROT_GS232A_H +#define _ROT_GS232A_H 1 + +extern const struct rot_caps gs232a_rot_caps; + +#endif /* _ROT_GS232A_H */ diff --git a/include/hamlib/rotlist.h b/include/hamlib/rotlist.h index 5106a2b2a..46b328dcf 100644 --- a/include/hamlib/rotlist.h +++ b/include/hamlib/rotlist.h @@ -1,8 +1,8 @@ /* * Hamlib Interface - list of known rotators - * Copyright (c) 2000-2002 by Stephane Fillod and Frank Singleton + * Copyright (c) 2000-2008 by Stephane Fillod and Frank Singleton * - * $Id: rotlist.h,v 1.10 2006-10-15 00:26:47 aa6e Exp $ + * $Id: rotlist.h,v 1.11 2008-05-23 14:09:11 fillods Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -138,6 +138,16 @@ #define ROT_BACKEND_SARTEK "sartek" #define ROT_MODEL_SARTEK1 ROT_MAKE_MODEL(ROT_SARTEK, 1) +/*! \def ROT_MODEL_GS232A + * \brief A macro that returns the model number of the GS-232A backend. + * + * The GS-232A backend can be used with rotators that support the + * GS-232A protocol. + */ +#define ROT_GS232A 6 +#define ROT_BACKEND_GS232A "gs232a" +#define ROT_MODEL_GS232A ROT_MAKE_MODEL(ROT_GS232A, 1) + /*! \typedef typedef int rot_model_t \brief Convenience type definition for rotator model. */ @@ -157,6 +167,7 @@ typedef int rot_model_t; { ROT_FODTRACK, ROT_BACKEND_FODTRACK }, \ { ROT_ROTOREZ, ROT_BACKEND_ROTOREZ }, \ { ROT_SARTEK, ROT_BACKEND_SARTEK }, \ + { ROT_GS232A, ROT_BACKEND_GS232A }, \ { 0, NULL }, /* end */ \ }