Manually applied diff from older HamLib version.

pull/974/head
OK1CTR 2022-02-23 22:36:57 +01:00
rodzic d04f4b6b3b
commit 83e5b14cf6
9 zmienionych plików z 1029 dodań i 1 usunięć

1
.gitignore vendored
Wyświetl plik

@ -63,3 +63,4 @@ src/hamlibdatetime.h
build/ build/
libs/ libs/
obj/ obj/
.project

Wyświetl plik

@ -47,7 +47,7 @@ dnl added to AC_CONFIG_FILES near the end of this file. See README.developer
dnl Beware of duplication should a backend directory include both rig and dnl Beware of duplication should a backend directory include both rig and
dnl rotor definitions, e.g. "dummy". Optional backends will not be listed dnl rotor definitions, e.g. "dummy". Optional backends will not be listed
dnl here but will be added later, e.g. "winradio". dnl here but will be added later, e.g. "winradio".
RIG_BACKEND_LIST="rigs/adat rigs/alinco rigs/aor rigs/barrett rigs/codan rigs/dorji rigs/drake rigs/dummy rigs/elad rigs/flexradio rigs/icom rigs/icmarine rigs/jrc rigs/kachina rigs/kenwood rigs/kit rigs/lowe rigs/pcr rigs/prm80 rigs/racal rigs/rft rigs/rs rigs/skanti rigs/tapr rigs/tentec rigs/tuner rigs/uniden rigs/winradio rigs/wj rigs/yaesu" RIG_BACKEND_LIST="rigs/adat rigs/alinco rigs/aor rigs/barrett rigs/codan rigs/dorji rigs/drake rigs/dummy rigs/elad rigs/flexradio rigs/icom rigs/icmarine rigs/jrc rigs/kachina rigs/kenwood rigs/kit rigs/lowe rigs/pcr rigs/prm80 rigs/racal rigs/rft rigs/rs rigs/skanti rigs/tapr rigs/tentec rigs/tuner rigs/uniden rigs/winradio rigs/wj rigs/yaesu rigs/gomspace"
ROT_BACKEND_LIST="rotators/amsat rotators/ars rotators/celestron rotators/cnctrk rotators/easycomm rotators/ether6 rotators/fodtrack rotators/gs232a rotators/heathkit rotators/m2 rotators/meade rotators/rotorez rotators/sartek rotators/spid rotators/ts7400 rotators/prosistel rotators/ioptron rotators/satel rotators/radant" ROT_BACKEND_LIST="rotators/amsat rotators/ars rotators/celestron rotators/cnctrk rotators/easycomm rotators/ether6 rotators/fodtrack rotators/gs232a rotators/heathkit rotators/m2 rotators/meade rotators/rotorez rotators/sartek rotators/spid rotators/ts7400 rotators/prosistel rotators/ioptron rotators/satel rotators/radant"
# Amplifiers are all in the amplifiers directory # Amplifiers are all in the amplifiers directory
AMP_BACKEND_LIST="amplifiers/elecraft" AMP_BACKEND_LIST="amplifiers/elecraft"
@ -80,6 +80,7 @@ AM_CPPFLAGS="${AM_CPPFLAGS} -I\$(top_srcdir)/include -I\$(top_srcdir)/src -I\$(t
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CC AC_PROG_CC
AC_PROG_CC_STDC
AC_PROG_CXX AC_PROG_CXX
AC_PROG_CPP AC_PROG_CPP
AC_PROG_AWK AC_PROG_AWK
@ -868,6 +869,7 @@ rigs/uniden/Makefile
rigs/winradio/Makefile rigs/winradio/Makefile
rigs/wj/Makefile rigs/wj/Makefile
rigs/yaesu/Makefile rigs/yaesu/Makefile
rigs/gomspace/Makefile
tests/Makefile tests/Makefile
scripts/Makefile scripts/Makefile
android/Makefile android/Makefile

Wyświetl plik

@ -643,6 +643,13 @@
#define RIG_BACKEND_CODAN "codan" #define RIG_BACKEND_CODAN "codan"
#define RIG_MODEL_CODAN_ENVOY RIG_MAKE_MODEL(RIG_CODAN, 1) #define RIG_MODEL_CODAN_ENVOY RIG_MAKE_MODEL(RIG_CODAN, 1)
#define RIG_MODEL_CODAN_NGT RIG_MAKE_MODEL(RIG_CODAN, 2) #define RIG_MODEL_CODAN_NGT RIG_MAKE_MODEL(RIG_CODAN, 2)
/*
* Gomspace
*/
#define RIG_GOMSPACE 34
#define RIG_BACKEND_GOMSPACE "gomspace"
#define RIG_MODEL_GS100 RIG_MAKE_MODEL(RIG_GOMSPACE, 1)
//! @endcond //! @endcond
/* /*

Wyświetl plik

@ -0,0 +1,6 @@
GOMSPACESRC = gs100.c gs100.h
noinst_LTLIBRARIES = libhamlib-gomspace.la
libhamlib_gomspace_la_SOURCES = $(GOMSPACESRC)
EXTRA_DIST = Android.mk

Wyświetl plik

@ -0,0 +1,548 @@
/*
* GomSpace backend and the GS100 radio control module
*
* Created in 2022 by Richard Linhart OK1CTR OK1CTR@gmail.com
* and used during VZLUSAT-2 satellite mission.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#include "hamlib/rig.h"
#include "serial.h"
#include "parallel.h"
#include "cm108.h"
#include "gpio.h"
#include "misc.h"
#include "tones.h"
#include "idx_builtin.h"
#include "register.h"
#include "gs100.h"
/* Private Defines -----------------------------------------------------------*/
// If defined, commands are software simulated only
#undef _LOCAL_SIMULATION_
// If true, configuration table switching is minimized
#define PARAM_MEM_MINIMAL 1
// Buffer size for serial transfers
#define BUFSZ 256
// Last character on each line received from RIG
#define GOM_STOPSET "\n"
// Exact character sequence on the RIG's command prompt
#define GOM_PROMPT "\x1B[1;32mnanocom-ax\x1B[1;30m # \x1B[0m\x1B[0m"
// Maximum number of lines parsed from GS100 response
#define GOM_MAXLINES 20
// RIG's parametric table number for receive
#define GOM_CONFIG_TAB_RX 1
// RIG's parametric table number for transmit
#define GOM_CONFIG_TAB_TX 5
/* Private Typedefs ----------------------------------------------------------*/
/**
* GS100 rig private data structure
*/
struct gs100_priv_data
{
freq_t freq_rx; ///< currently just for backup and TRX emulation
freq_t freq_tx; ///< currently just for backup and TRX emulation
int param_mem; ///< last value of configuration table selection
};
/* Imported Functions --------------------------------------------------------*/
struct ext_list *alloc_init_ext(const struct confparams *cfp);
struct ext_list *find_ext(struct ext_list *elp, token_t token);
/* Private function prototypes -----------------------------------------------*/
/**
* Set variable in the GS100 configuration table
*/
static int gomx_set(RIG *rig, int table, char *varname, char *varvalue);
/**
* Get variable from the GS100 configuration table
*/
static int gomx_get(RIG *rig, int table, char *varname, char *varvalue);
/**
* Sends a message to the GS100 and parses response lines
*/
static int gomx_transaction(RIG *rig, char *message, char *response);
/* Functions -----------------------------------------------------------------*/
/* GS100 transceiver control init */
static int gs100_init(RIG *rig)
{
struct gs100_priv_data *priv;
ENTERFUNC;
if (!rig || !rig->caps)
{
RETURNFUNC(-RIG_EINVAL);
}
priv = (struct gs100_priv_data *)malloc(sizeof(struct gs100_priv_data));
if (!priv)
{
RETURNFUNC(-RIG_ENOMEM);
}
rig->state.priv = (void *)priv;
#ifdef _LOCAL_SIMULATION_
rig->state.rigport.type.rig = RIG_PORT_NONE; // just simulation
priv->freq_rx = rig->caps->rx_range_list1->startf;
priv->freq_tx = rig->caps->tx_range_list1->startf;
#endif
priv->param_mem = -1; // means undefined last selection
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver control deinit */
static int gs100_cleanup(RIG *rig)
{
struct gs100_priv_data *priv = (struct gs100_priv_data *)rig->state.priv;
ENTERFUNC;
if (rig->state.priv)
{
free(rig->state.priv);
}
rig->state.priv = NULL;
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver open */
static int gs100_open(RIG *rig)
{
ENTERFUNC;
if (rig->caps->rig_model == RIG_MODEL_GS100)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s: OPENING'\n", __func__);
}
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver close */
static int gs100_close(RIG *rig)
{
ENTERFUNC;
if (rig->caps->rig_model == RIG_MODEL_GS100)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s: CLOSING'\n", __func__);
}
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver set configuration */
static int gs100_set_conf(RIG *rig, token_t token, const char *val)
{
struct gs100_priv_data *priv;
ENTERFUNC;
priv = (struct gs100_priv_data *)rig->state.priv;
switch (token)
{
case 0:
break;
case 1:
break;
default:
RETURNFUNC(-RIG_EINVAL);
}
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver get configuration */
static int gs100_get_conf(RIG *rig, token_t token, char *val)
{
struct gs100_priv_data *priv;
ENTERFUNC;
priv = (struct gs100_priv_data *)rig->state.priv;
switch (token)
{
case 0:
break;
default:
RETURNFUNC(-RIG_EINVAL);
}
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver set receiver frequency */
static int gs100_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
struct gs100_priv_data *priv = (struct gs100_priv_data *)rig->state.priv;
char fstr[20], value[20];
int retval;
ENTERFUNC;
// reporting
sprintf_freq(fstr, sizeof(fstr), freq);
rig_debug(RIG_DEBUG_VERBOSE, "%s: fstr = '%s'\n", __func__, fstr);
#ifdef _LOCAL_SIMULATION_
priv->freq_rx = freq;
#endif
// range check - GS100 don't do it!
if (freq < rig->caps->rx_range_list1->startf || freq > rig->caps->rx_range_list1->endf) RETURNFUNC(-RIG_EDOM);
// perform set command
sprintf(value, "%1.0lf", freq);
retval = gomx_set(rig, GOM_CONFIG_TAB_RX, "freq", value);
if (retval != RIG_OK) RETURNFUNC(retval);
RETURNFUNC(retval);
}
/* GS100 transceiver get receiver frequency */
static int gs100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
struct gs100_priv_data *priv = (struct gs100_priv_data *)rig->state.priv;
char fstr[20], resp[20];
int retval;
freq_t f;
ENTERFUNC;
// perform the get command
retval = gomx_get(rig, GOM_CONFIG_TAB_RX, "freq", resp);
if (retval != RIG_OK) RETURNFUNC(retval);
#ifdef _LOCAL_SIMULATION_
*freq = priv->freq_rx;
#else
retval = sscanf(resp, "%lf", &f);
#endif
// relevance check
if (retval != 1) RETURNFUNC(-RIG_EPROTO);
if (f < rig->caps->rx_range_list1->startf || f > rig->caps->rx_range_list1->endf) RETURNFUNC(-RIG_EDOM);
*freq = f;
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver set transmitter frequency */
static int gs100_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
struct gs100_priv_data *priv = (struct gs100_priv_data *)rig->state.priv;
char fstr[20], value[20];
int retval;
ENTERFUNC;
// reporting
sprintf_freq(fstr, sizeof(fstr), freq);
rig_debug(RIG_DEBUG_VERBOSE, "%s: fstr = '%s'\n", __func__, fstr);
#ifdef _LOCAL_SIMULATION_
priv->freq_tx = freq;
#endif
// range check - GS100 don't do it!
if (freq < rig->caps->tx_range_list1->startf || freq > rig->caps->tx_range_list1->endf) RETURNFUNC(-RIG_EDOM);
// perform set command
sprintf(value, "%1.0lf", freq);
retval = gomx_set(rig, GOM_CONFIG_TAB_TX, "freq", value);
if (retval != RIG_OK) RETURNFUNC(retval);
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver get transmitter frequency */
static int gs100_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
struct gs100_priv_data *priv = (struct gs100_priv_data *)rig->state.priv;
char fstr[20], resp[20];
int retval;
freq_t f;
ENTERFUNC;
// perform the get command
retval = gomx_get(rig, GOM_CONFIG_TAB_TX, "freq", resp);
if (retval != RIG_OK) RETURNFUNC(retval);
#ifdef _LOCAL_SIMULATION_
*freq = priv->freq_tx;
#else
retval = sscanf(resp, "%lf", &f);
#endif
// relevance check
if (retval != 1) RETURNFUNC(-RIG_EPROTO);
if (f < rig->caps->tx_range_list1->startf || f > rig->caps->tx_range_list1->endf) RETURNFUNC(-RIG_EDOM);
*freq = f;
RETURNFUNC(RIG_OK);
}
/* GS100 transceiver get info */
static const char *gs100_get_info(RIG *rig)
{
return("Gomspace Ground Station Transceiver GS100");
}
/* The HAMLIB RIG Capabilities Structure Definition --------------------------*/
#define GS100_FUNC (0)
#define GS100_LEVEL (0)
#define GS100_PARM (0)
#define GS100_VFO_OPS RIG_OP_TUNE
#define GS100_VFOS (RIG_VFO_A)
#define GS100_MODES (RIG_MODE_PKTFM)
struct rig_caps GS100_caps =
{
RIG_MODEL(RIG_MODEL_GS100),
.model_name = "GS100",
.mfg_name = "GOMSPACE",
.version = "20211117.0",
.copyright = "LGPL",
.status = RIG_STATUS_ALPHA,
.rig_type = RIG_TYPE_TRANSCEIVER,
.targetable_vfo = 0,
.ptt_type = RIG_PTT_NONE,
.dcd_type = RIG_DCD_NONE,
.port_type = RIG_PORT_SERIAL,
.serial_rate_min = 115200,
.serial_rate_max = 500000,
.serial_data_bits = 8,
.serial_stop_bits = 1,
.serial_parity = RIG_PARITY_NONE,
.serial_handshake = RIG_HANDSHAKE_NONE,
.write_delay = 1,
.post_write_delay = 1,
.timeout = 250,
.retry = 0,
.has_get_func = GS100_FUNC,
.has_set_func = GS100_FUNC,
.has_get_level = GS100_LEVEL,
.has_set_level = GS100_LEVEL,
.has_get_parm = GS100_PARM,
.has_set_parm = GS100_PARM,
.vfo_ops = GS100_VFO_OPS,
.rx_range_list1 = { {
.startf = MHz(430), .endf = MHz(440), .modes = GS100_MODES,
.low_power = -1, .high_power = -1, GS100_VFOS,
.label = "GS100#1"
}, RIG_FRNG_END, },
.tx_range_list1 = { {
.startf = MHz(430), .endf = MHz(440), .modes = GS100_MODES,
.low_power = -1, .high_power = -1, GS100_VFOS,
.label = "GS100#1"
}, RIG_FRNG_END, },
.tuning_steps = { {GS100_MODES, Hz(10)}, RIG_TS_END, },
.priv = NULL,
.rig_init = gs100_init,
.rig_cleanup = gs100_cleanup,
.rig_open = gs100_open,
.rig_close = gs100_close,
.set_conf = gs100_set_conf,
.get_conf = gs100_get_conf,
.set_freq = gs100_set_freq,
.get_freq = gs100_get_freq,
.set_split_freq = gs100_set_tx_freq,
.get_split_freq = gs100_get_tx_freq,
.get_info = gs100_get_info,
};
/* Private functions ---------------------------------------------------------*/
/* Set variable in the GS100 configuration table */
static int gomx_set(RIG *rig, int table, char *varname, char *varvalue)
{
struct gs100_priv_data *priv = (struct gs100_priv_data *)rig->state.priv;
int retval;
char msg[BUFSZ], resp[BUFSZ];
assert(rig != NULL);
assert(varname != NULL);
assert(varvalue != NULL);
rig_debug(RIG_DEBUG_TRACE, "%s: table=%d, '%s' = '%s'\n", __func__, table, varname, varvalue);
if (!PARAM_MEM_MINIMAL || table != priv->param_mem)
{
// select the configuration table
priv->param_mem = table;
sprintf(msg, "param mem %d\n", table);
retval = gomx_transaction(rig, msg, resp);
if (retval != RIG_OK) return(retval);
}
// set the variable
sprintf(msg, "param set %s %s\n", varname, varvalue);
retval = gomx_transaction(rig, msg, resp);
if (retval != RIG_OK) return(retval);
// check response
if (strlen(resp) > 0) return(-RIG_EPROTO);
return(RIG_OK);
}
/* Get variable from the GS100 configuration table */
static int gomx_get(RIG *rig, int table, char *varname, char *varvalue)
{
struct gs100_priv_data *priv = (struct gs100_priv_data *)rig->state.priv;
int retval;
char msg[BUFSZ], resp[BUFSZ], *c;
assert(rig != NULL);
assert(varname != NULL);
assert(varvalue != NULL);
rig_debug(RIG_DEBUG_TRACE, "%s: table=%d, '%s'\n", __func__, table, varname);
if (!PARAM_MEM_MINIMAL || table != priv->param_mem)
{
// select the configuration table
priv->param_mem = table;
sprintf(msg, "param mem %d\n", table);
retval = gomx_transaction(rig, msg, resp);
if (retval != RIG_OK) return(retval);
}
// get the variable
sprintf(msg, "param get %s\n", varname);
retval = gomx_transaction(rig, msg, resp);
if (retval != RIG_OK) return(retval);
// check response and extract the value
if ((c = strchr(resp, '=')) == NULL) return(-RIG_EPROTO);
if (sscanf(c + 1, "%s", varvalue) != 1) return(-RIG_EPROTO);
return(RIG_OK);
}
/* Sends a message to the GS100 and parses response lines */
static int gomx_transaction(RIG *rig, char *message, char *response)
{
struct gs100_priv_data *priv;
struct rig_state *rs;
int retval, n = 0;
char buf[BUFSZ];
assert(rig != NULL);
assert(message != NULL);
assert(response != NULL);
rig_debug(RIG_DEBUG_TRACE, "%s: msg='%s'\n", __func__, message == NULL ? "NULL" : message);
// access to private variables
rs = &rig->state;
priv = (struct gs100_priv_data *)rs->priv;
// send message to the transceiver
rig_flush(&rs->rigport);
retval = write_block(&rs->rigport, message, strlen(message));
if (retval != RIG_OK) return(retval);
while (1)
{
// read the response line
retval = read_string(&rs->rigport, buf, BUFSZ, GOM_STOPSET, strlen(GOM_STOPSET), 0);
if (retval < 0) return(retval);
if (retval == 0) return(-RIG_ETIMEOUT);
n++;
// prompt is always the last line
if (strcmp(buf, GOM_PROMPT) == 0) break;
// before last line would be the response
if (n > 1) strcpy(response, buf);
else *response = '\0'; // don't return command echo
if (n > GOM_MAXLINES) return(-RIG_EPROTO);
}
// report the response
rig_debug(RIG_DEBUG_VERBOSE, "%s: returning response='%s'\n", __func__, response == NULL ? "NULL" : response);
return(RIG_OK);
}
/* System Integration Functions ----------------------------------------------*/
/* Init RIG backend function */
DECLARE_INITRIG_BACKEND(gomspace)
{
ENTERFUNC;
rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__);
rig_register(&GS100_caps);
RETURNFUNC(RIG_OK);
}
/* Probe RIG backend function */
DECLARE_PROBERIG_BACKEND(gomspace)
{
return(RIG_MODEL_GS100);
}
/*----------------------------------------------------------------------------*/

Wyświetl plik

@ -0,0 +1,55 @@
/*
* GomSpace backend and the GS100 radio control module
*
* Created in 2022 by Richard Linhart OK1CTR OK1CTR@gmail.com
* and used during VZLUSAT-2 satellite mission.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef _GS100_H
#define _GS100_H 1
/* Includes ------------------------------------------------------------------*/
#include "hamlib/rig.h"
#include "token.h"
/* Definitions ---------------------------------------------------------------*/
/* backend conf */
#define TOK_CFG_MAGICCONF TOKEN_BACKEND(1)
#define TOK_CFG_STATIC_DATA TOKEN_BACKEND(2)
/* ext_level's and ext_parm's tokens */
#define TOK_EL_MAGICLEVEL TOKEN_BACKEND(1)
#define TOK_EL_MAGICFUNC TOKEN_BACKEND(2)
#define TOK_EL_MAGICOP TOKEN_BACKEND(3)
#define TOK_EP_MAGICPARM TOKEN_BACKEND(4)
#define TOK_EL_MAGICCOMBO TOKEN_BACKEND(5)
#define TOK_EL_MAGICEXTFUNC TOKEN_BACKEND(6)
/* Public variables ----------------------------------------------------------*/
/* RIG capabilities descriptions */
extern struct rig_caps gs100_caps;
extern struct rig_caps netrigctl_caps;
extern const struct rig_caps flrig_caps;
extern const struct rig_caps trxmanager_caps;
/*----------------------------------------------------------------------------*/
#endif /* _GS100_H */

Wyświetl plik

@ -0,0 +1,400 @@
/*
* Simple fundamental function simulator of GOMSPACE GS100 satellite
* radio transceiver
*
* Created in 2022 by Richard Linhart OK1CTR OK1CTR@gmail.com
* and used during VZLUSAT-2 satellite mission.
*
* This sorce code is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
/* Private defines -----------------------------------------------------------*/
//! If defined, also silent commands print their result
#undef _DBG_SILENT_
//! If defined, value range bounds are checked (originally not)
#undef _CHECK_BOUNDS_
//! Function finished with success
#define STATUS_OK 0
//! Function finished with error
#define STATUS_ERROR -1
//! Serial baud rate - cannot use 500000 as the GS100 have
#define BAUD_RATE 115200
//! Incomming serial buffer length
#define BUF_LENGTH 32
//! New line character on receive
#define NLRX '\n'
//! New line character on transmit
#define NLTX "\r\r\n"
//! Displayed prompt
#define PROMPT "\x1B[1;32mnanocom-ax\x1B[1;30m # \x1B[0m\x1B[0m"
/* Private macros ------------------------------------------------------------*/
//! Checks leading substring as command
#define LEADINGSTR(a,b) (strncmp((a), (b), strlen(b)) == 0)
//! Find the first alphabet character in string
#define FIRSTALPHA(a) while(*(a) != '\0' && !isalpha(*(a))) { (a)++; }
//! Find the first alphabet character or number in string
#define FIRSTALNUM(a) while(*(a) != '\0' && !isalnum(*(a))) { (a)++; }
//! Find the first space in string
#define FIRSTSPACE(a) while(*(a) != '\0' && *(a) != ' ') { (a)++; }
/* Private typedefs ----------------------------------------------------------*/
//! Types of hint outputs
typedef enum {
hint_param1,
hint_param2,
hint_mem,
hint_get1,
hint_get2,
hint_set
} hint_t;
/* Private constants ---------------------------------------------------------*/
//! Low frequency limit, both for receive and transmit
static const unsigned long f_min = 430000000;
//! High frequency limit, both for receive and transmit
static const unsigned long f_max = 440000000;
/* Private variables ---------------------------------------------------------*/
//! Selected configuration table memory
static uint8_t mem = 0;
//! Radio receive frequency
static unsigned long rx_freq;
//! Radio transmit frequency
static unsigned long tx_freq;
/* Private function prototypes -----------------------------------------------*/
/**
* @brief Store incomming serial characters unitl line end
* @return The line if received successfully or NULL
*/
static char *serReadLine(void);
/**
* @brief Process the command PARAM
* @param The input command string
* @return 0 in case of success
*/
static int cmdParam(char *cmd);
/**
* @brief Process the command MEM
* @param The input command string
* @return 0 in case of success
*/
static int cmdMem(char *cmd);
/**
* @brief Process the command GET
* @param The input command string
* @return 0 in case of success
*/
static int cmdGet(char *cmd);
/**
* @brief Process the command SET
* @param The input command string
* @return 0 in case of success
*/
static int cmdSet(char *cmd);
/**
* @brief Displays command prompt
*/
static void prnPrompt(void);
/**
* @brief Displays hint output for commands
* @param hint_type Type or command
* @oaram cmd Part of commend to comment
*/
static void prnHint(hint_t hint_type, char *cmd);
/* Functions -----------------------------------------------------------------*/
/**
* @brief Arduino SETUP function
*/
void setup(void)
{
Serial.begin(BAUD_RATE);
rx_freq = f_min;
tx_freq = f_min;
return;
}
/**
* @brief Arduino LOOP function
*/
void loop(void)
{
char *c;
// reading command line from serial
if ((c = serReadLine()) != NULL)
{
FIRSTALPHA(c);
if (LEADINGSTR(c, "param"))
{
cmdParam(c);
} else {
if (strlen(c) > 0)
{
Serial.print("Unknown command '");
Serial.print(c);
Serial.print("'");
Serial.print(NLTX);
}
}
prnPrompt();
}
return;
}
/* Private functions ---------------------------------------------------------*/
/* Store incomming serial characters unitl line end */
static char *serReadLine(void)
{
int inchar;
static char buf[BUF_LENGTH] = "\0", *p = buf;
if (Serial.available())
{
inchar = Serial.read();
// is it end of line?
if (inchar > 0)
{
if (inchar == NLRX)
{
Serial.print(NLTX); // enf of line repeated strange
*p = '\0'; // terminate the string
p = buf; // reset the buffer
return(buf);
}
// repeat received character
Serial.write(inchar & 0xFF);
// insert new character into the buffer
*p = inchar & 0xFF;
if (p - buf < BUF_LENGTH - 1)
{
p++;
} else {
p = buf; // reset the buffer
}
}
}
return(NULL);
}
/* Process the command PARAM */
static int cmdParam(char *cmd)
{
FIRSTSPACE(cmd);
FIRSTALPHA(cmd);
if (strlen(cmd) > 0)
{
if (LEADINGSTR(cmd, "mem")) return(cmdMem(cmd));
if (LEADINGSTR(cmd, "get")) return(cmdGet(cmd));
if (LEADINGSTR(cmd, "set")) return(cmdSet(cmd));
prnHint(hint_param1, cmd);
return(STATUS_ERROR);
} else {
prnHint(hint_param2, NULL);
return(STATUS_ERROR);
}
}
/* Process the command MEM */
static int cmdMem(char *cmd)
{
FIRSTSPACE(cmd);
FIRSTALNUM(cmd);
if (strlen(cmd) > 0)
{
mem = strtol(cmd, &cmd, 10) & 0xFF;
#ifdef _DBG_SILENT_
Serial.print(mem);
Serial.print(NLTX);
#endif
return(STATUS_OK);
} else {
prnHint(hint_mem, NULL);
return(STATUS_ERROR);
}
}
/* Process the command GET */
static int cmdGet(char *cmd)
{
unsigned long f;
FIRSTSPACE(cmd);
FIRSTALPHA(cmd);
if (strlen(cmd) > 0)
{
if (LEADINGSTR(cmd, "freq"))
{
switch (mem)
{
case 1: f = rx_freq; break;
case 5: f = tx_freq; break;
default: return(STATUS_ERROR);
}
Serial.print(" GET freq = ");
Serial.print(f);
Serial.print(NLTX);
return(STATUS_OK);
} else {
prnHint(hint_get1, cmd);
return(STATUS_ERROR);
}
} else {
prnHint(hint_get2, NULL);
return(STATUS_ERROR);
}
}
/* Process the command SET */
static int cmdSet(char *cmd)
{
unsigned long f;
FIRSTSPACE(cmd);
FIRSTALPHA(cmd);
if (strlen(cmd) > 0)
{
if (LEADINGSTR(cmd, "freq"))
{
FIRSTSPACE(cmd);
FIRSTALNUM(cmd);
if (strlen(cmd) == 0)
{
prnHint(hint_set, NULL);
return(STATUS_ERROR);
}
f = strtol(cmd, &cmd, 10);
#ifdef _DBG_SILENT_
Serial.print(f);
Serial.print(NLTX);
#endif
#ifdef _CHECK_BOUNDS_
if (f < f_min) f = f_min;
if (f > f_max) f = f_max;
#endif
switch (mem)
{
case 1: rx_freq = f; break;
case 5: tx_freq = f; break;
default: return(STATUS_ERROR);
}
return(STATUS_OK);
} else {
// different behavior than at GET
prnHint(hint_set, NULL);
return(STATUS_ERROR);
}
} else {
prnHint(hint_set, NULL);
return(STATUS_ERROR);
}
}
/* Displays command prompt */
static void prnPrompt(void)
{
Serial.print(PROMPT);
return;
}
/* Displays hint output for commands */
static void prnHint(hint_t hint_type, char *cmd)
{
switch (hint_type)
{
case hint_param1:
Serial.print("Unknown command 'param ");
Serial.print(cmd);
Serial.print("'");
Serial.print(NLTX);
return;
case hint_param2:
// reduced on simulated commads only!
Serial.print("'param' contains sub-commands:");
Serial.print(NLTX);
Serial.print(" mem Set cmds working mem");
Serial.print(NLTX);
Serial.print(" set Set parameter");
Serial.print(NLTX);
Serial.print(" get Get parameter");
Serial.print(NLTX);
break;
case hint_mem:
Serial.print("usage: mem <mem>");
Serial.print(NLTX);
Serial.print("Could not execute command 'param mem', error -2");
Serial.print(NLTX);
break;
case hint_get1:
Serial.print("Unknown parameter ");
Serial.print(cmd);
Serial.print(NLTX);
Serial.print("Could not execute command 'param get shit', error -1");
Serial.print(NLTX);
break;
case hint_get2:
Serial.print("usage: get <name|addr>");
Serial.print(NLTX);
Serial.print("Could not execute command 'param get', error -2");
Serial.print(NLTX);
break;
case hint_set:
Serial.print("usage: set <name|addr> <value> [quiet]");
Serial.print(NLTX);
Serial.print("Could not execute command 'param set', error -2");
Serial.print(NLTX);
break;
}
return;
}
/*----------------------------------------------------------------------------*/

Wyświetl plik

@ -89,6 +89,7 @@ DEFINE_INITRIG_BACKEND(dorji);
DEFINE_INITRIG_BACKEND(barrett); DEFINE_INITRIG_BACKEND(barrett);
DEFINE_INITRIG_BACKEND(elad); DEFINE_INITRIG_BACKEND(elad);
DEFINE_INITRIG_BACKEND(codan); DEFINE_INITRIG_BACKEND(codan);
DEFINE_INITRIG_BACKEND(gomspace);
//! @endcond //! @endcond
#ifdef HAVE_WINRADIO #ifdef HAVE_WINRADIO
@ -146,6 +147,7 @@ static struct
{ RIG_BARRETT, RIG_BACKEND_BARRETT, RIG_FUNCNAMA(barrett) }, { RIG_BARRETT, RIG_BACKEND_BARRETT, RIG_FUNCNAMA(barrett) },
{ RIG_ELAD, RIG_BACKEND_ELAD, RIG_FUNCNAMA(elad) }, { RIG_ELAD, RIG_BACKEND_ELAD, RIG_FUNCNAMA(elad) },
{ RIG_CODAN, RIG_BACKEND_CODAN, RIG_FUNCNAMA(codan) }, { RIG_CODAN, RIG_BACKEND_CODAN, RIG_FUNCNAMA(codan) },
{ RIG_GOMSPACE, RIG_BACKEND_GOMSPACE, RIG_FUNCNAM(gomspace) },
{ 0, NULL }, /* end */ { 0, NULL }, /* end */
}; };

Wyświetl plik

@ -370,6 +370,13 @@ int HAMLIB_API serial_setup(hamlib_port_t *rp)
break; break;
#endif #endif
#ifdef B500000
case 500000:
speed = B500000; /* extra super awesome! */
break;
#endif
default: default:
rig_debug(RIG_DEBUG_ERR, rig_debug(RIG_DEBUG_ERR,
"%s: unsupported rate specified: %d\n", "%s: unsupported rate specified: %d\n",