From 82ef0a39bfb9ff5be56cd28c212b1954e8f39ba0 Mon Sep 17 00:00:00 2001 From: andz Date: Sat, 26 Nov 2022 01:04:36 +0100 Subject: [PATCH 1/8] Initial adding FLIR PTU rotator --- configure.ac | 3 +- include/hamlib/rotlist.h | 15 + rotators/flir/Makefile.am | 6 + rotators/flir/README | 1 + rotators/flir/flir.c | 1002 +++++++++++++++++++++++++++++++++++++ rotators/flir/flir.h | 42 ++ src/rot_reg.c | 2 + 7 files changed, 1070 insertions(+), 1 deletion(-) create mode 100644 rotators/flir/Makefile.am create mode 100644 rotators/flir/README create mode 100644 rotators/flir/flir.c create mode 100644 rotators/flir/flir.h diff --git a/configure.ac b/configure.ac index 866ebff41..6014b3911 100644 --- a/configure.ac +++ b/configure.ac @@ -48,7 +48,7 @@ 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 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 rigs/gomspace rigs/mds" -ROT_BACKEND_LIST="rotators/amsat rotators/ars rotators/celestron rotators/cnctrk rotators/grbltrk 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/grbltrk rotators/easycomm rotators/ether6 rotators/flir 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 AMP_BACKEND_LIST="amplifiers/elecraft amplifiers/gemini" @@ -834,6 +834,7 @@ rotators/cnctrk/Makefile rotators/grbltrk/Makefile rotators/easycomm/Makefile rotators/ether6/Makefile +rotators/flir/Makefile rotators/fodtrack/Makefile rotators/gs232a/Makefile rotators/heathkit/Makefile diff --git a/include/hamlib/rotlist.h b/include/hamlib/rotlist.h index 45d4e01a1..0dbd16f4d 100644 --- a/include/hamlib/rotlist.h +++ b/include/hamlib/rotlist.h @@ -648,6 +648,21 @@ #define ROT_MODEL_GRBLTRK_SER ROT_MAKE_MODEL(ROT_GRBLTRK, 1) #define ROT_MODEL_GRBLTRK_NET ROT_MAKE_MODEL(ROT_GRBLTRK, 2) +/** + * \brief A macro that returns the model number of the FLIR backend. + * + * \def ROT_MODEL_FLIR + * + * The FLIR backend can be used with FLIR and DirectedPercepition + * rotators using the PTU protocol (e.g. PTU-D48). Currently only + * the serial interaface is supported and no ethernet. + */ +//! @cond Doxygen_Suppress +#define ROT_FLIR 25 +#define ROT_BACKEND_FLIR "flir" +//! @endcond +#define ROT_MODEL_FLIR ROT_MAKE_MODEL(ROT_FLIR, 1) + /** * \brief Convenience type definition for a rotator model. * diff --git a/rotators/flir/Makefile.am b/rotators/flir/Makefile.am new file mode 100644 index 000000000..f43281d5b --- /dev/null +++ b/rotators/flir/Makefile.am @@ -0,0 +1,6 @@ +FLIRSRC = flir.c flir.h + +noinst_LTLIBRARIES = libhamlib-flir.la +libhamlib_flir_la_SOURCES = $(FLIRSRC) + +EXTRA_DIST = README.md Android.mk \ No newline at end of file diff --git a/rotators/flir/README b/rotators/flir/README new file mode 100644 index 000000000..0601a099b --- /dev/null +++ b/rotators/flir/README @@ -0,0 +1 @@ +tbd diff --git a/rotators/flir/flir.c b/rotators/flir/flir.c new file mode 100644 index 000000000..04f648afa --- /dev/null +++ b/rotators/flir/flir.c @@ -0,0 +1,1002 @@ +/* + * Hamlib Dummy backend - main file + * Copyright (c) 2001-2009 by Stephane Fillod + * + * + * 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 + * + */ + +#include + +#include +#include /* String function definitions */ +#include +#include + +#include "hamlib/rotator.h" +//#include "dummy_common.h" +#include "register.h" +#include "idx_builtin.h" + +#include "flir.h" + +#define FLIR_FUNC 0 +#define FLIR_LEVEL ROT_LEVEL_SPEED +#define FLIR_PARM 0 + +#define FLIR_STATUS (ROT_STATUS_MOVING | ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT | \ + ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN | \ + ROT_STATUS_LIMIT_UP | ROT_STATUS_LIMIT_DOWN | ROT_STATUS_LIMIT_LEFT | ROT_STATUS_LIMIT_RIGHT) + +static int simulating = 0; // do we need rotator emulation for debug? + +struct flir_priv_data +{ + azimuth_t az; + elevation_t el; + + struct timeval tv; /* time last az/el update */ + azimuth_t target_az; + elevation_t target_el; + rot_status_t status; + + setting_t funcs; + value_t levels[RIG_SETTING_MAX]; + value_t parms[RIG_SETTING_MAX]; + + struct ext_list *ext_funcs; + struct ext_list *ext_levels; + struct ext_list *ext_parms; + + char *magic_conf; +}; + +static const struct confparams flir_ext_levels[] = +{ + { + TOK_EL_ROT_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } + }, + { + TOK_EL_ROT_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", + NULL, RIG_CONF_CHECKBUTTON + }, + { + TOK_EL_ROT_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", + NULL, RIG_CONF_BUTTON + }, + { + TOK_EL_ROT_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", + "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } + }, + { RIG_CONF_END, NULL, } +}; + +static const struct confparams flir_ext_funcs[] = +{ + { + TOK_EL_ROT_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", + NULL, RIG_CONF_CHECKBUTTON + }, + { RIG_CONF_END, NULL, } +}; + +static const struct confparams flir_ext_parms[] = +{ + { + TOK_EP_ROT_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } + }, + { RIG_CONF_END, NULL, } +}; + +/* cfgparams are configuration item generally used by the backend's open() method */ +static const struct confparams flir_cfg_params[] = +{ + { + TOK_CFG_ROT_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", + "ROTATOR", RIG_CONF_STRING, { } + }, + { RIG_CONF_END, NULL, } +}; + + +static int flir_init(ROT *rot) +{ + struct flir_priv_data *priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + rot->state.priv = (struct flir_priv_data *) + calloc(1, sizeof(struct flir_priv_data)); + + if (!rot->state.priv) + { + return -RIG_ENOMEM; + } + + priv = rot->state.priv; + + priv->ext_funcs = alloc_init_ext(flir_ext_funcs); + + if (!priv->ext_funcs) + { + return -RIG_ENOMEM; + } + + priv->ext_levels = alloc_init_ext(flir_ext_levels); + + if (!priv->ext_levels) + { + return -RIG_ENOMEM; + } + + priv->ext_parms = alloc_init_ext(flir_ext_parms); + + if (!priv->ext_parms) + { + return -RIG_ENOMEM; + } + + rot->state.rotport.type.rig = RIG_PORT_NONE; + + priv->az = priv->el = 0; + + priv->target_az = priv->target_el = 0; + + priv->magic_conf = strdup("ROTATOR"); + + return RIG_OK; +} + +static int flir_cleanup(ROT *rot) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + free(priv->ext_funcs); + free(priv->ext_levels); + free(priv->ext_parms); + free(priv->magic_conf); + + if (rot->state.priv) + { + free(rot->state.priv); + } + + rot->state.priv = NULL; + + return RIG_OK; +} + +static int flir_open(ROT *rot) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (rot->caps->rot_model == ROT_MODEL_FLIR) + { + simulating = 1; + rig_debug(RIG_DEBUG_VERBOSE, "%s: flir rotator so simulating speed\n", + __func__); + } + + return RIG_OK; +} + +static int flir_close(ROT *rot) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + return RIG_OK; +} + +static int flir_set_conf(ROT *rot, token_t token, const char *val) +{ + struct flir_priv_data *priv; + + priv = (struct flir_priv_data *)rot->state.priv; + + switch (token) + { + case TOK_CFG_ROT_MAGICCONF: + if (val) + { + free(priv->magic_conf); + priv->magic_conf = strdup(val); + } + + break; + + default: + return -RIG_EINVAL; + } + + return RIG_OK; +} + + +static int flir_get_conf2(ROT *rot, token_t token, char *val, int val_len) +{ + struct flir_priv_data *priv; + + priv = (struct flir_priv_data *)rot->state.priv; + + switch (token) + { + case TOK_CFG_ROT_MAGICCONF: + SNPRINTF(val, val_len, "%s", priv->magic_conf); + break; + + default: + return -RIG_EINVAL; + } + + return RIG_OK; +} + +static int flir_get_conf(ROT *rot, token_t token, char *val) +{ + return flir_get_conf2(rot, token, val, 128); +} + + + +static int flir_set_position(ROT *rot, azimuth_t az, elevation_t el) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, + az, el); + + if (simulating) + { + priv->target_az = az; + priv->target_el = el; + gettimeofday(&priv->tv, NULL); + } + else + { + priv->az = priv->target_az = az; + priv->el = priv->target_az = el; + } + + + return RIG_OK; +} + +static void flir_simulate_rotation(ROT *rot) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + struct timeval tv; + unsigned elapsed; /* ms */ + + gettimeofday(&tv, NULL); + + elapsed = (tv.tv_sec - priv->tv.tv_sec) * 1000 + + (tv.tv_usec - priv->tv.tv_usec) / 1000; + + /* + * Simulate rotation speed of 360 deg per minute + */ +#define DEG_PER_MS (360./60/1000) + + if (fabs(priv->target_az - priv->az) / DEG_PER_MS <= elapsed) + { + /* target reached */ + priv->az = priv->target_az; + priv->status &= ~(ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | + ROT_STATUS_MOVING_RIGHT); + } + else + { + if (priv->az < priv->target_az) + { + priv->az += (azimuth_t)elapsed * DEG_PER_MS; + priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_RIGHT; + } + else + { + priv->az -= (azimuth_t)elapsed * DEG_PER_MS; + priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT; + } + } + + if (fabs(priv->target_el - priv->el) / DEG_PER_MS <= elapsed) + { + /* target reached */ + priv->el = priv->target_el; + priv->status &= ~(ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | + ROT_STATUS_MOVING_DOWN); + } + else + { + if (priv->el < priv->target_el) + { + priv->el += (elevation_t)elapsed * DEG_PER_MS; + priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP; + } + else + { + priv->el -= (elevation_t)elapsed * DEG_PER_MS; + priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_DOWN; + } + } + + if (priv->status & (ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_EL)) + { + priv->status |= ROT_STATUS_MOVING; + } + else + { + priv->status &= ~(ROT_STATUS_MOVING); + } + + priv->tv = tv; +} + + +/* + * Get position of rotor, simulating slow rotation + */ +static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (simulating && priv->az == priv->target_az && + priv->el == priv->target_el) + { + *az = priv->az; + *el = priv->el; + return RIG_OK; + } + + if (simulating) + { + flir_simulate_rotation(rot); + } + + *az = priv->az; + *el = priv->el; + + return RIG_OK; +} + + +static int flir_stop(ROT *rot) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + azimuth_t az; + elevation_t el; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + flir_get_position(rot, &az, &el); + + priv->target_az = priv->az = az; + priv->target_el = priv->el = el; + + return RIG_OK; +} + + +static int flir_park(ROT *rot) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + /* Assume home is 0,0 */ + flir_set_position(rot, 0, 0); + + return RIG_OK; +} + +static int flir_reset(ROT *rot, rot_reset_t reset) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + return RIG_OK; +} + +static int flir_move(ROT *rot, int direction, int speed) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_TRACE, "%s: Direction = %d, Speed = %d\n", __func__, + direction, speed); + + switch (direction) + { + case ROT_MOVE_UP: + return flir_set_position(rot, priv->target_az, 90); + + case ROT_MOVE_DOWN: + return flir_set_position(rot, priv->target_az, 0); + + case ROT_MOVE_CCW: + return flir_set_position(rot, -180, priv->target_el); + + case ROT_MOVE_CW: + return flir_set_position(rot, 180, priv->target_el); + + default: + return -RIG_EINVAL; + } + + return RIG_OK; +} + +static const char *flir_get_info(ROT *rot) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + return "flir rotator"; +} + +static int flir_set_func(ROT *rot, setting_t func, int status) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, + rot_strfunc(func), status); + + if (status) + { + priv->funcs |= func; + } + else + { + priv->funcs &= ~func; + } + + return RIG_OK; +} + + +static int flir_get_func(ROT *rot, setting_t func, int *status) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + + *status = (priv->funcs & func) ? 1 : 0; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, + rot_strfunc(func)); + + return RIG_OK; +} + + +static int flir_set_level(ROT *rot, setting_t level, value_t val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + int idx; + char lstr[32]; + + idx = rig_setting2idx(level); + + if (idx >= RIG_SETTING_MAX) + { + return -RIG_EINVAL; + } + + priv->levels[idx] = val; + + if (ROT_LEVEL_IS_FLOAT(level)) + { + SNPRINTF(lstr, sizeof(lstr), "%f", val.f); + } + else + { + SNPRINTF(lstr, sizeof(lstr), "%d", val.i); + } + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, + rot_strlevel(level), lstr); + + return RIG_OK; +} + + +static int flir_get_level(ROT *rot, setting_t level, value_t *val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + int idx; + + idx = rig_setting2idx(level); + + if (idx >= RIG_SETTING_MAX) + { + return -RIG_EINVAL; + } + + *val = priv->levels[idx]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, + rot_strlevel(level)); + + return RIG_OK; +} + +static int flir_set_ext_level(ROT *rot, token_t token, value_t val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + char lstr[64]; + const struct confparams *cfp; + struct ext_list *elp; + + cfp = rot_ext_lookup_tok(rot, token); + + if (!cfp) + { + return -RIG_EINVAL; + } + + switch (token) + { + case TOK_EL_ROT_MAGICLEVEL: + case TOK_EL_ROT_MAGICFUNC: + case TOK_EL_ROT_MAGICOP: + case TOK_EL_ROT_MAGICCOMBO: + break; + + default: + return -RIG_EINVAL; + } + + switch (cfp->type) + { + case RIG_CONF_STRING: + strcpy(lstr, val.s); + break; + + case RIG_CONF_COMBO: + SNPRINTF(lstr, sizeof(lstr), "%d", val.i); + break; + + case RIG_CONF_NUMERIC: + SNPRINTF(lstr, sizeof(lstr), "%f", val.f); + break; + + case RIG_CONF_CHECKBUTTON: + SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); + break; + + case RIG_CONF_BUTTON: + lstr[0] = '\0'; + break; + + default: + return -RIG_EINTERNAL; + } + + elp = find_ext(priv->ext_levels, token); + + if (!elp) + { + return -RIG_EINTERNAL; + } + + /* store value */ + elp->val = val; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, + cfp->name, lstr); + + return RIG_OK; +} + +static int flir_get_ext_level(ROT *rot, token_t token, value_t *val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + const struct confparams *cfp; + struct ext_list *elp; + + cfp = rot_ext_lookup_tok(rot, token); + + if (!cfp) + { + return -RIG_EINVAL; + } + + switch (token) + { + case TOK_EL_ROT_MAGICLEVEL: + case TOK_EL_ROT_MAGICFUNC: + case TOK_EL_ROT_MAGICOP: + case TOK_EL_ROT_MAGICCOMBO: + break; + + default: + return -RIG_EINVAL; + } + + elp = find_ext(priv->ext_levels, token); + + if (!elp) + { + return -RIG_EINTERNAL; + } + + /* load value */ + *val = elp->val; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, + cfp->name); + + return RIG_OK; +} + + +static int flir_set_ext_func(ROT *rot, token_t token, int status) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + const struct confparams *cfp; + struct ext_list *elp; + + cfp = rot_ext_lookup_tok(rot, token); + + if (!cfp) + { + return -RIG_EINVAL; + } + + switch (token) + { + case TOK_EL_ROT_MAGICEXTFUNC: + break; + + default: + return -RIG_EINVAL; + } + + switch (cfp->type) + { + case RIG_CONF_CHECKBUTTON: + break; + + case RIG_CONF_BUTTON: + break; + + default: + return -RIG_EINTERNAL; + } + + elp = find_ext(priv->ext_funcs, token); + + if (!elp) + { + return -RIG_EINTERNAL; + } + + /* store value */ + elp->val.i = status; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, + cfp->name, status); + + return RIG_OK; +} + + +static int flir_get_ext_func(ROT *rot, token_t token, int *status) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + const struct confparams *cfp; + struct ext_list *elp; + + cfp = rot_ext_lookup_tok(rot, token); + + if (!cfp) + { + return -RIG_EINVAL; + } + + switch (token) + { + case TOK_EL_ROT_MAGICEXTFUNC: + break; + + default: + return -RIG_EINVAL; + } + + elp = find_ext(priv->ext_funcs, token); + + if (!elp) + { + return -RIG_EINTERNAL; + } + + /* load value */ + *status = elp->val.i; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, + cfp->name); + + return RIG_OK; +} + + +static int flir_set_parm(ROT *rot, setting_t parm, value_t val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + int idx; + char pstr[32]; + + idx = rig_setting2idx(parm); + + if (idx >= RIG_SETTING_MAX) + { + return -RIG_EINVAL; + } + + if (ROT_PARM_IS_FLOAT(parm)) + { + SNPRINTF(pstr, sizeof(pstr), "%f", val.f); + } + else + { + SNPRINTF(pstr, sizeof(pstr), "%d", val.i); + } + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, + rig_strparm(parm), pstr); + + priv->parms[idx] = val; + + return RIG_OK; +} + + +static int flir_get_parm(ROT *rot, setting_t parm, value_t *val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + int idx; + + idx = rig_setting2idx(parm); + + if (idx >= RIG_SETTING_MAX) + { + return -RIG_EINVAL; + } + + *val = priv->parms[idx]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, + rig_strparm(parm)); + + return RIG_OK; +} + +static int flir_set_ext_parm(ROT *rot, token_t token, value_t val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + char lstr[64]; + const struct confparams *cfp; + struct ext_list *epp; + + cfp = rot_ext_lookup_tok(rot, token); + + if (!cfp) + { + return -RIG_EINVAL; + } + + switch (token) + { + case TOK_EP_ROT_MAGICPARM: + break; + + default: + return -RIG_EINVAL; + } + + switch (cfp->type) + { + case RIG_CONF_STRING: + strcpy(lstr, val.s); + break; + + case RIG_CONF_COMBO: + SNPRINTF(lstr, sizeof(lstr), "%d", val.i); + break; + + case RIG_CONF_NUMERIC: + SNPRINTF(lstr, sizeof(lstr), "%f", val.f); + break; + + case RIG_CONF_CHECKBUTTON: + SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); + break; + + case RIG_CONF_BUTTON: + lstr[0] = '\0'; + break; + + default: + return -RIG_EINTERNAL; + } + + epp = find_ext(priv->ext_parms, token); + + if (!epp) + { + return -RIG_EINTERNAL; + } + + /* store value */ + epp->val = val; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, + cfp->name, lstr); + + return RIG_OK; +} + +static int flir_get_ext_parm(ROT *rot, token_t token, value_t *val) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + const struct confparams *cfp; + struct ext_list *epp; + + cfp = rot_ext_lookup_tok(rot, token); + + if (!cfp) + { + return -RIG_EINVAL; + } + + switch (token) + { + case TOK_EP_ROT_MAGICPARM: + break; + + default: + return -RIG_EINVAL; + } + + epp = find_ext(priv->ext_parms, token); + + if (!epp) + { + return -RIG_EINTERNAL; + } + + /* load value */ + *val = epp->val; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, + cfp->name); + + return RIG_OK; +} + + +static int flir_get_status(ROT *rot, rot_status_t *status) +{ + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; + + if (simulating) + { + flir_simulate_rotation(rot); + } + + *status = priv->status; + + return RIG_OK; +} + + +/* + * flir rotator capabilities. + */ +struct rot_caps flir_caps = +{ + ROT_MODEL(ROT_MODEL_FLIR), + .model_name = "PTU Serial", + .mfg_name = "FLIR", + .version = "20221126.0", + .copyright = "LGPL", + .status = RIG_STATUS_STABLE, + .rot_type = ROT_TYPE_AZEL, + .port_type = RIG_PORT_NONE, + + .min_az = -180., + .max_az = 450., + .min_el = 0., + .max_el = 90., + + .priv = NULL, /* priv */ + + .has_get_func = FLIR_FUNC, + .has_set_func = FLIR_FUNC, + .has_get_level = FLIR_LEVEL, + .has_set_level = ROT_LEVEL_SET(FLIR_LEVEL), + .has_get_parm = FLIR_PARM, + .has_set_parm = ROT_PARM_SET(FLIR_PARM), + + .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, + + .extlevels = flir_ext_levels, + .extfuncs = flir_ext_funcs, + .extparms = flir_ext_parms, + .cfgparams = flir_cfg_params, + + .has_status = FLIR_STATUS, + + .rot_init = flir_init, + .rot_cleanup = flir_cleanup, + .rot_open = flir_open, + .rot_close = flir_close, + + .set_conf = flir_set_conf, + .get_conf = flir_get_conf, + + .set_position = flir_set_position, + .get_position = flir_get_position, + .park = flir_park, + .stop = flir_stop, + .reset = flir_reset, + .move = flir_move, + + .set_func = flir_set_func, + .get_func = flir_get_func, + .set_level = flir_set_level, + .get_level = flir_get_level, + .set_parm = flir_set_parm, + .get_parm = flir_get_parm, + + .set_ext_func = flir_set_ext_func, + .get_ext_func = flir_get_ext_func, + .set_ext_level = flir_set_ext_level, + .get_ext_level = flir_get_ext_level, + .set_ext_parm = flir_set_ext_parm, + .get_ext_parm = flir_get_ext_parm, + + .get_info = flir_get_info, + .get_status = flir_get_status, +}; + +DECLARE_INITROT_BACKEND(flir) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); + + rot_register(&flir_caps); + rot_register(&netrotctl_caps); + + return RIG_OK; +} diff --git a/rotators/flir/flir.h b/rotators/flir/flir.h new file mode 100644 index 000000000..4d86eea0b --- /dev/null +++ b/rotators/flir/flir.h @@ -0,0 +1,42 @@ +/* + * Hamlib Dummy backend - main header + * Copyright (c) 2001-2008 by Stephane Fillod + * + * + * 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 _ROT_FLIR_H +#define _ROT_FLIR_H 1 + +#include "token.h" + +/* backend conf */ +#define TOK_CFG_ROT_MAGICCONF TOKEN_BACKEND(1) +#define TOK_CFG_ROT_STATIC_DATA TOKEN_BACKEND(2) + +/* ext_level's and ext_parm's tokens */ +#define TOK_EL_ROT_MAGICLEVEL TOKEN_BACKEND(1) +#define TOK_EL_ROT_MAGICFUNC TOKEN_BACKEND(2) +#define TOK_EL_ROT_MAGICOP TOKEN_BACKEND(3) +#define TOK_EP_ROT_MAGICPARM TOKEN_BACKEND(4) +#define TOK_EL_ROT_MAGICCOMBO TOKEN_BACKEND(5) +#define TOK_EL_ROT_MAGICEXTFUNC TOKEN_BACKEND(6) + +extern struct rot_caps flir_caps; +extern struct rot_caps netrotctl_caps; + +#endif /* _ROT_FLIR_H */ diff --git a/src/rot_reg.c b/src/rot_reg.c index 13e152c59..5e2fff59c 100644 --- a/src/rot_reg.c +++ b/src/rot_reg.c @@ -83,6 +83,7 @@ DEFINE_INITROT_BACKEND(meade); DEFINE_INITROT_BACKEND(ioptron); DEFINE_INITROT_BACKEND(satel); DEFINE_INITROT_BACKEND(radant); +DEFINE_INITROT_BACKEND(flir); #if HAVE_LIBINDI DEFINE_INITROT_BACKEND(indi); #endif @@ -131,6 +132,7 @@ static struct { ROT_IOPTRON, ROT_BACKEND_IOPTRON, ROT_FUNCNAMA(ioptron) }, { ROT_SATEL, ROT_BACKEND_SATEL, ROT_FUNCNAMA(satel) }, { ROT_RADANT, ROT_BACKEND_RADANT, ROT_FUNCNAMA(radant)}, + { ROT_FLIR, ROT_BACKEND_FLIR, ROT_FUNCNAMA(flir) }, #if HAVE_LIBINDI { ROT_INDI, ROT_BACKEND_INDI, ROT_FUNCNAMA(indi) }, #endif From 0bdb6827dabab3321fb10d835810c180f77fde99 Mon Sep 17 00:00:00 2001 From: andz Date: Wed, 30 Nov 2022 12:20:25 +0100 Subject: [PATCH 2/8] Implemented FLIR basic funktions: * flir_init * flir_cleanup * flir_open * flir_close * flir_set_position * flir_get_position * flir_park * flir_stop * flir_reset * flir_move --- rotators/flir/flir.c | 1221 ++++++++++++++++++++++-------------------- rotators/flir/flir.h | 4 + src/rot_reg.c | 4 +- 3 files changed, 649 insertions(+), 580 deletions(-) diff --git a/rotators/flir/flir.c b/rotators/flir/flir.c index 04f648afa..0e1b839c1 100644 --- a/rotators/flir/flir.c +++ b/rotators/flir/flir.c @@ -1,6 +1,6 @@ /* - * Hamlib Dummy backend - main file - * Copyright (c) 2001-2009 by Stephane Fillod + * Hamlib FLIR PTU rotor backend - main file + * Copyright (c) 2022 by Andreas Mueller (DC1MIL) * * * This library is free software; you can redistribute it and/or @@ -27,7 +27,6 @@ #include #include "hamlib/rotator.h" -//#include "dummy_common.h" #include "register.h" #include "idx_builtin.h" @@ -41,7 +40,7 @@ ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN | \ ROT_STATUS_LIMIT_UP | ROT_STATUS_LIMIT_DOWN | ROT_STATUS_LIMIT_LEFT | ROT_STATUS_LIMIT_RIGHT) -static int simulating = 0; // do we need rotator emulation for debug? +//static int simulating = 0; // do we need rotator emulation for debug? struct flir_priv_data { @@ -62,57 +61,110 @@ struct flir_priv_data struct ext_list *ext_parms; char *magic_conf; + + float_t resolution_pp; + float_t resolution_tp; }; -static const struct confparams flir_ext_levels[] = -{ - { - TOK_EL_ROT_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", - NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } - }, - { - TOK_EL_ROT_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", - NULL, RIG_CONF_CHECKBUTTON - }, - { - TOK_EL_ROT_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", - NULL, RIG_CONF_BUTTON - }, - { - TOK_EL_ROT_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", - "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } - }, - { RIG_CONF_END, NULL, } -}; +// static const struct confparams flir_ext_levels[] = +// { +// { +// TOK_EL_ROT_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", +// NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } +// }, +// { +// TOK_EL_ROT_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", +// NULL, RIG_CONF_CHECKBUTTON +// }, +// { +// TOK_EL_ROT_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", +// NULL, RIG_CONF_BUTTON +// }, +// { +// TOK_EL_ROT_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", +// "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } +// }, +// { RIG_CONF_END, NULL, } +// }; -static const struct confparams flir_ext_funcs[] = -{ - { - TOK_EL_ROT_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", - NULL, RIG_CONF_CHECKBUTTON - }, - { RIG_CONF_END, NULL, } -}; +// static const struct confparams flir_ext_funcs[] = +// { +// { +// TOK_EL_ROT_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", +// NULL, RIG_CONF_CHECKBUTTON +// }, +// { RIG_CONF_END, NULL, } +// }; -static const struct confparams flir_ext_parms[] = -{ - { - TOK_EP_ROT_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", - NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } - }, - { RIG_CONF_END, NULL, } -}; +// static const struct confparams flir_ext_parms[] = +// { +// { +// TOK_EP_ROT_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", +// NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } +// }, +// { RIG_CONF_END, NULL, } +// }; /* cfgparams are configuration item generally used by the backend's open() method */ -static const struct confparams flir_cfg_params[] = -{ - { - TOK_CFG_ROT_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", - "ROTATOR", RIG_CONF_STRING, { } - }, - { RIG_CONF_END, NULL, } -}; +// static const struct confparams flir_cfg_params[] = +// { +// { +// TOK_CFG_ROT_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", +// "ROTATOR", RIG_CONF_STRING, { } +// }, +// { RIG_CONF_END, NULL, } +// }; +static int flir_request(ROT *rot, char *request, char *response, + uint32_t *resp_size) +{ + int return_value = -RIG_EINVAL; + int retry_read = 0; + unsigned char cmd_ok; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + rig_flush(&rot->state.rotport); + + if (request) + { + return_value = write_block(&rot->state.rotport, (unsigned char *) request, + strlen(request)); + if (return_value != RIG_OK) + { + return return_value; + } + } + //Is a direct request expected? + if (response != NULL) + { + while(retry_read < rot->state.rotport.retry) + { + memset(response, 0, resp_size); + resp_size = read_string(&rot->state.rotport, response, resp_size, + "\r\n", sizeof("\r\n"), 0, 1); + if(resp_size > 0) + { + if(response[0] == '*') + { + rig_debug(RIG_DEBUG_VERBOSE, "accepted command %s\n", request); + return RIG_OK; + } + else + { + rig_debug(RIG_DEBUG_VERBOSE, "NOT accepted command %s\n", request); + return -RIG_ERJCTED; + } + + } + retry_read++; + } + rig_debug(RIG_DEBUG_VERBOSE, "timeout for command %s\n", request); + return -RIG_ETIMEOUT; + } + + return return_value; +}; static int flir_init(ROT *rot) { @@ -130,28 +182,29 @@ static int flir_init(ROT *rot) priv = rot->state.priv; - priv->ext_funcs = alloc_init_ext(flir_ext_funcs); + // priv->ext_funcs = alloc_init_ext(flir_ext_funcs); - if (!priv->ext_funcs) - { - return -RIG_ENOMEM; - } + // if (!priv->ext_funcs) + // { + // return -RIG_ENOMEM; + // } - priv->ext_levels = alloc_init_ext(flir_ext_levels); + // priv->ext_levels = alloc_init_ext(flir_ext_levels); - if (!priv->ext_levels) - { - return -RIG_ENOMEM; - } + // if (!priv->ext_levels) + // { + // return -RIG_ENOMEM; + // } - priv->ext_parms = alloc_init_ext(flir_ext_parms); + // priv->ext_parms = alloc_init_ext(flir_ext_parms); - if (!priv->ext_parms) - { - return -RIG_ENOMEM; - } + // if (!priv->ext_parms) + // { + // return -RIG_ENOMEM; + // } - rot->state.rotport.type.rig = RIG_PORT_NONE; + //rot->state.rotport.type.rig = RIG_PORT_SERIAL; + //flir_request(rot, "r\n", sizeof("r\n"), NULL, NULL); priv->az = priv->el = 0; @@ -159,6 +212,9 @@ static int flir_init(ROT *rot) priv->magic_conf = strdup("ROTATOR"); + priv->resolution_pp = 92.5714; + priv->resolution_tp = 46.2857; + return RIG_OK; } @@ -186,16 +242,45 @@ static int flir_cleanup(ROT *rot) static int flir_open(ROT *rot) { + struct flir_priv_data *priv; + char return_str[MAXBUF]; + float_t resolution_pp, resolution_tp; + int return_value = RIG_OK; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (rot->caps->rot_model == ROT_MODEL_FLIR) + priv = rot->state.priv; + + // Disable ECHO + return_value = flir_request(rot, "ED\n", NULL, MAXBUF); + + // Disable Verbose Mode + return_value = flir_request(rot, "FT\n", return_str, MAXBUF); + + // Get PAN resolution in arcsecs + if(flir_request(rot, "PR\n", return_str, MAXBUF) == RIG_OK) { - simulating = 1; - rig_debug(RIG_DEBUG_VERBOSE, "%s: flir rotator so simulating speed\n", - __func__); + sscanf(return_str, "* %f", &resolution_pp); + rig_debug(RIG_DEBUG_VERBOSE, "PAN resolution: %f arcsecs per position\n", resolution_pp); + priv->resolution_pp = resolution_pp; + } + else + { + return_value = -RIG_EPROTO; + } + // Get TILT resolution in arcsecs + if(flir_request(rot, "TR\n", return_str, MAXBUF) == RIG_OK) + { + sscanf(return_str, "* %f", &resolution_tp); + rig_debug(RIG_DEBUG_VERBOSE, "TILT resolution: %f arcsecs per position\n", resolution_tp); + priv->resolution_tp = resolution_tp; + } + else + { + return_value = -RIG_EPROTO; } - return RIG_OK; + return return_value; } static int flir_close(ROT *rot) @@ -205,185 +290,128 @@ static int flir_close(ROT *rot) return RIG_OK; } -static int flir_set_conf(ROT *rot, token_t token, const char *val) -{ - struct flir_priv_data *priv; +// static int flir_set_conf(ROT *rot, token_t token, const char *val) +// { +// struct flir_priv_data *priv; - priv = (struct flir_priv_data *)rot->state.priv; +// priv = (struct flir_priv_data *)rot->state.priv; - switch (token) - { - case TOK_CFG_ROT_MAGICCONF: - if (val) - { - free(priv->magic_conf); - priv->magic_conf = strdup(val); - } +// switch (token) +// { +// case TOK_CFG_ROT_MAGICCONF: +// if (val) +// { +// free(priv->magic_conf); +// priv->magic_conf = strdup(val); +// } - break; +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_get_conf2(ROT *rot, token_t token, char *val, int val_len) -{ - struct flir_priv_data *priv; +// static int flir_get_conf2(ROT *rot, token_t token, char *val, int val_len) +// { +// struct flir_priv_data *priv; - priv = (struct flir_priv_data *)rot->state.priv; +// priv = (struct flir_priv_data *)rot->state.priv; - switch (token) - { - case TOK_CFG_ROT_MAGICCONF: - SNPRINTF(val, val_len, "%s", priv->magic_conf); - break; +// switch (token) +// { +// case TOK_CFG_ROT_MAGICCONF: +// SNPRINTF(val, val_len, "%s", priv->magic_conf); +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_get_conf(ROT *rot, token_t token, char *val) -{ - return flir_get_conf2(rot, token, val, 128); -} +// static int flir_get_conf(ROT *rot, token_t token, char *val) +// { +// return flir_get_conf2(rot, token, val, 128); +// } static int flir_set_position(ROT *rot, azimuth_t az, elevation_t el) { + int32_t t_pan_positions, t_tilt_positions; + char return_str[MAXBUF]; + char cmd_str[MAXBUF]; struct flir_priv_data *priv = (struct flir_priv_data *) rot->state.priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); - if (simulating) - { - priv->target_az = az; - priv->target_el = el; - gettimeofday(&priv->tv, NULL); - } - else - { - priv->az = priv->target_az = az; - priv->el = priv->target_az = el; - } + priv->target_az = az; + priv->target_el = el; + t_pan_positions = (az * 3600) / priv->resolution_pp; + t_tilt_positions = - ((90.0 - el) * 3600) / priv->resolution_tp; - return RIG_OK; + sprintf(cmd_str, "PP%d TP%d\n", t_pan_positions, t_tilt_positions); + + return flir_request(rot, cmd_str, return_str, MAXBUF); } -static void flir_simulate_rotation(ROT *rot) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - struct timeval tv; - unsigned elapsed; /* ms */ - - gettimeofday(&tv, NULL); - - elapsed = (tv.tv_sec - priv->tv.tv_sec) * 1000 + - (tv.tv_usec - priv->tv.tv_usec) / 1000; - - /* - * Simulate rotation speed of 360 deg per minute - */ -#define DEG_PER_MS (360./60/1000) - - if (fabs(priv->target_az - priv->az) / DEG_PER_MS <= elapsed) - { - /* target reached */ - priv->az = priv->target_az; - priv->status &= ~(ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | - ROT_STATUS_MOVING_RIGHT); - } - else - { - if (priv->az < priv->target_az) - { - priv->az += (azimuth_t)elapsed * DEG_PER_MS; - priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_RIGHT; - } - else - { - priv->az -= (azimuth_t)elapsed * DEG_PER_MS; - priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT; - } - } - - if (fabs(priv->target_el - priv->el) / DEG_PER_MS <= elapsed) - { - /* target reached */ - priv->el = priv->target_el; - priv->status &= ~(ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | - ROT_STATUS_MOVING_DOWN); - } - else - { - if (priv->el < priv->target_el) - { - priv->el += (elevation_t)elapsed * DEG_PER_MS; - priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP; - } - else - { - priv->el -= (elevation_t)elapsed * DEG_PER_MS; - priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_DOWN; - } - } - - if (priv->status & (ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_EL)) - { - priv->status |= ROT_STATUS_MOVING; - } - else - { - priv->status &= ~(ROT_STATUS_MOVING); - } - - priv->tv = tv; -} - - /* - * Get position of rotor, simulating slow rotation + * Get position of rotor */ static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { + int return_value = RIG_OK; + char return_str[MAXBUF]; + int32_t pan_positions, tilt_positions; + struct flir_priv_data *priv = (struct flir_priv_data *) rot->state.priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (simulating && priv->az == priv->target_az && - priv->el == priv->target_el) - { - *az = priv->az; - *el = priv->el; - return RIG_OK; - } - if (simulating) + if(flir_request(rot, "PP\n", return_str, MAXBUF) == RIG_OK) { - flir_simulate_rotation(rot); + rig_debug(RIG_DEBUG_VERBOSE, "PP Return String: %s\n", return_str); + sscanf(return_str, "* %d", &pan_positions); + priv->az = (pan_positions * priv->resolution_pp) / 3600; + } + else + { + return_value = -RIG_EPROTO; + } + + if(flir_request(rot, "TP\n", return_str, MAXBUF) == RIG_OK) + { + rig_debug(RIG_DEBUG_VERBOSE, "TP Return String: %s\n", return_str); + sscanf(return_str, "* %d", &tilt_positions); + priv->el = 90.0 + ((tilt_positions * priv->resolution_tp) / 3600); + } + else + { + return_value = -RIG_EPROTO; } *az = priv->az; *el = priv->el; - return RIG_OK; + return return_value; } static int flir_stop(ROT *rot) { + int return_value = RIG_OK; + char return_str[MAXBUF]; + struct flir_priv_data *priv = (struct flir_priv_data *) rot->state.priv; azimuth_t az; @@ -391,12 +419,16 @@ static int flir_stop(ROT *rot) rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - flir_get_position(rot, &az, &el); + return_value = flir_request(rot, "H\n", NULL, MAXBUF); + // Wait 2s until rotor has stopped (Needs to be refactored) + hl_usleep(2000000); + + return_value = flir_get_position(rot, &az, &el); priv->target_az = priv->az = az; priv->target_el = priv->el = el; - return RIG_OK; + return return_value; } @@ -404,17 +436,26 @@ static int flir_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - /* Assume home is 0,0 */ - flir_set_position(rot, 0, 0); + /* Assume park Position is 0,90 */ + flir_set_position(rot, 0, 90); return RIG_OK; } static int flir_reset(ROT *rot, rot_reset_t reset) { + int return_value = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - - return RIG_OK; + if (reset != 0) + { + return_value = flir_request(rot, "r\n", NULL, NULL); + // After Reset: Disable Hard Limits + if(return_value == RIG_OK) + { + return_value = flir_request(rot, "LD\n", NULL, MAXBUF); + } + } + return return_value; } static int flir_move(ROT *rot, int direction, int speed) @@ -449,460 +490,472 @@ static int flir_move(ROT *rot, int direction, int speed) static const char *flir_get_info(ROT *rot) { + const char* firmware_str[120]; + const char* info_str[120]; + const char* return_str[256]; + + sprintf(return_str, "No Info"); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - return "flir rotator"; + if(flir_request(rot, "V\n", firmware_str, 120) == RIG_OK && + flir_request(rot, "O\n", info_str, 120) == RIG_OK) + { + sprintf(return_str, "Firmware: %s Info: %s", firmware_str, info_str); + } + //rig_debug(RIG_DEBUG_VERBOSE, "Return String: %s", return_str); + return *return_str; } -static int flir_set_func(ROT *rot, setting_t func, int status) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; +// static int flir_set_func(ROT *rot, setting_t func, int status) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, - rot_strfunc(func), status); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, +// rot_strfunc(func), status); - if (status) - { - priv->funcs |= func; - } - else - { - priv->funcs &= ~func; - } - - return RIG_OK; -} +// if (status) +// { +// priv->funcs |= func; +// } +// else +// { +// priv->funcs &= ~func; +// } + +// return RIG_OK; +// } -static int flir_get_func(ROT *rot, setting_t func, int *status) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; +// static int flir_get_func(ROT *rot, setting_t func, int *status) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; - *status = (priv->funcs & func) ? 1 : 0; - - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, - rot_strfunc(func)); +// *status = (priv->funcs & func) ? 1 : 0; + +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, +// rot_strfunc(func)); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_set_level(ROT *rot, setting_t level, value_t val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - int idx; - char lstr[32]; +// static int flir_set_level(ROT *rot, setting_t level, value_t val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// int idx; +// char lstr[32]; - idx = rig_setting2idx(level); +// idx = rig_setting2idx(level); - if (idx >= RIG_SETTING_MAX) - { - return -RIG_EINVAL; - } +// if (idx >= RIG_SETTING_MAX) +// { +// return -RIG_EINVAL; +// } - priv->levels[idx] = val; +// priv->levels[idx] = val; - if (ROT_LEVEL_IS_FLOAT(level)) - { - SNPRINTF(lstr, sizeof(lstr), "%f", val.f); - } - else - { - SNPRINTF(lstr, sizeof(lstr), "%d", val.i); - } +// if (ROT_LEVEL_IS_FLOAT(level)) +// { +// SNPRINTF(lstr, sizeof(lstr), "%f", val.f); +// } +// else +// { +// SNPRINTF(lstr, sizeof(lstr), "%d", val.i); +// } - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, - rot_strlevel(level), lstr); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, +// rot_strlevel(level), lstr); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_get_level(ROT *rot, setting_t level, value_t *val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - int idx; +// static int flir_get_level(ROT *rot, setting_t level, value_t *val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// int idx; - idx = rig_setting2idx(level); +// idx = rig_setting2idx(level); - if (idx >= RIG_SETTING_MAX) - { - return -RIG_EINVAL; - } - - *val = priv->levels[idx]; - - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, - rot_strlevel(level)); +// if (idx >= RIG_SETTING_MAX) +// { +// return -RIG_EINVAL; +// } + +// *val = priv->levels[idx]; + +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, +// rot_strlevel(level)); - return RIG_OK; -} - -static int flir_set_ext_level(ROT *rot, token_t token, value_t val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - char lstr[64]; - const struct confparams *cfp; - struct ext_list *elp; +// return RIG_OK; +// } + +// static int flir_set_ext_level(ROT *rot, token_t token, value_t val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// char lstr[64]; +// const struct confparams *cfp; +// struct ext_list *elp; - cfp = rot_ext_lookup_tok(rot, token); +// cfp = rot_ext_lookup_tok(rot, token); - if (!cfp) - { - return -RIG_EINVAL; - } +// if (!cfp) +// { +// return -RIG_EINVAL; +// } - switch (token) - { - case TOK_EL_ROT_MAGICLEVEL: - case TOK_EL_ROT_MAGICFUNC: - case TOK_EL_ROT_MAGICOP: - case TOK_EL_ROT_MAGICCOMBO: - break; +// switch (token) +// { +// case TOK_EL_ROT_MAGICLEVEL: +// case TOK_EL_ROT_MAGICFUNC: +// case TOK_EL_ROT_MAGICOP: +// case TOK_EL_ROT_MAGICCOMBO: +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - switch (cfp->type) - { - case RIG_CONF_STRING: - strcpy(lstr, val.s); - break; +// switch (cfp->type) +// { +// case RIG_CONF_STRING: +// strcpy(lstr, val.s); +// break; - case RIG_CONF_COMBO: - SNPRINTF(lstr, sizeof(lstr), "%d", val.i); - break; +// case RIG_CONF_COMBO: +// SNPRINTF(lstr, sizeof(lstr), "%d", val.i); +// break; - case RIG_CONF_NUMERIC: - SNPRINTF(lstr, sizeof(lstr), "%f", val.f); - break; +// case RIG_CONF_NUMERIC: +// SNPRINTF(lstr, sizeof(lstr), "%f", val.f); +// break; - case RIG_CONF_CHECKBUTTON: - SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); - break; +// case RIG_CONF_CHECKBUTTON: +// SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); +// break; - case RIG_CONF_BUTTON: - lstr[0] = '\0'; - break; +// case RIG_CONF_BUTTON: +// lstr[0] = '\0'; +// break; - default: - return -RIG_EINTERNAL; - } +// default: +// return -RIG_EINTERNAL; +// } - elp = find_ext(priv->ext_levels, token); +// elp = find_ext(priv->ext_levels, token); - if (!elp) - { - return -RIG_EINTERNAL; - } +// if (!elp) +// { +// return -RIG_EINTERNAL; +// } - /* store value */ - elp->val = val; +// /* store value */ +// elp->val = val; - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, - cfp->name, lstr); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, +// cfp->name, lstr); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_get_ext_level(ROT *rot, token_t token, value_t *val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - const struct confparams *cfp; - struct ext_list *elp; +// static int flir_get_ext_level(ROT *rot, token_t token, value_t *val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// const struct confparams *cfp; +// struct ext_list *elp; - cfp = rot_ext_lookup_tok(rot, token); +// cfp = rot_ext_lookup_tok(rot, token); - if (!cfp) - { - return -RIG_EINVAL; - } +// if (!cfp) +// { +// return -RIG_EINVAL; +// } - switch (token) - { - case TOK_EL_ROT_MAGICLEVEL: - case TOK_EL_ROT_MAGICFUNC: - case TOK_EL_ROT_MAGICOP: - case TOK_EL_ROT_MAGICCOMBO: - break; +// switch (token) +// { +// case TOK_EL_ROT_MAGICLEVEL: +// case TOK_EL_ROT_MAGICFUNC: +// case TOK_EL_ROT_MAGICOP: +// case TOK_EL_ROT_MAGICCOMBO: +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - elp = find_ext(priv->ext_levels, token); +// elp = find_ext(priv->ext_levels, token); - if (!elp) - { - return -RIG_EINTERNAL; - } +// if (!elp) +// { +// return -RIG_EINTERNAL; +// } - /* load value */ - *val = elp->val; +// /* load value */ +// *val = elp->val; - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, - cfp->name); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, +// cfp->name); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_set_ext_func(ROT *rot, token_t token, int status) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - const struct confparams *cfp; - struct ext_list *elp; +// static int flir_set_ext_func(ROT *rot, token_t token, int status) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// const struct confparams *cfp; +// struct ext_list *elp; - cfp = rot_ext_lookup_tok(rot, token); +// cfp = rot_ext_lookup_tok(rot, token); - if (!cfp) - { - return -RIG_EINVAL; - } +// if (!cfp) +// { +// return -RIG_EINVAL; +// } - switch (token) - { - case TOK_EL_ROT_MAGICEXTFUNC: - break; +// switch (token) +// { +// case TOK_EL_ROT_MAGICEXTFUNC: +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - switch (cfp->type) - { - case RIG_CONF_CHECKBUTTON: - break; +// switch (cfp->type) +// { +// case RIG_CONF_CHECKBUTTON: +// break; - case RIG_CONF_BUTTON: - break; +// case RIG_CONF_BUTTON: +// break; - default: - return -RIG_EINTERNAL; - } +// default: +// return -RIG_EINTERNAL; +// } - elp = find_ext(priv->ext_funcs, token); +// elp = find_ext(priv->ext_funcs, token); - if (!elp) - { - return -RIG_EINTERNAL; - } +// if (!elp) +// { +// return -RIG_EINTERNAL; +// } - /* store value */ - elp->val.i = status; +// /* store value */ +// elp->val.i = status; - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, - cfp->name, status); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, +// cfp->name, status); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_get_ext_func(ROT *rot, token_t token, int *status) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - const struct confparams *cfp; - struct ext_list *elp; +// static int flir_get_ext_func(ROT *rot, token_t token, int *status) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// const struct confparams *cfp; +// struct ext_list *elp; - cfp = rot_ext_lookup_tok(rot, token); +// cfp = rot_ext_lookup_tok(rot, token); - if (!cfp) - { - return -RIG_EINVAL; - } +// if (!cfp) +// { +// return -RIG_EINVAL; +// } - switch (token) - { - case TOK_EL_ROT_MAGICEXTFUNC: - break; +// switch (token) +// { +// case TOK_EL_ROT_MAGICEXTFUNC: +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - elp = find_ext(priv->ext_funcs, token); +// elp = find_ext(priv->ext_funcs, token); - if (!elp) - { - return -RIG_EINTERNAL; - } +// if (!elp) +// { +// return -RIG_EINTERNAL; +// } - /* load value */ - *status = elp->val.i; +// /* load value */ +// *status = elp->val.i; - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, - cfp->name); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, +// cfp->name); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_set_parm(ROT *rot, setting_t parm, value_t val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - int idx; - char pstr[32]; +// static int flir_set_parm(ROT *rot, setting_t parm, value_t val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// int idx; +// char pstr[32]; - idx = rig_setting2idx(parm); +// idx = rig_setting2idx(parm); - if (idx >= RIG_SETTING_MAX) - { - return -RIG_EINVAL; - } +// if (idx >= RIG_SETTING_MAX) +// { +// return -RIG_EINVAL; +// } - if (ROT_PARM_IS_FLOAT(parm)) - { - SNPRINTF(pstr, sizeof(pstr), "%f", val.f); - } - else - { - SNPRINTF(pstr, sizeof(pstr), "%d", val.i); - } +// if (ROT_PARM_IS_FLOAT(parm)) +// { +// SNPRINTF(pstr, sizeof(pstr), "%f", val.f); +// } +// else +// { +// SNPRINTF(pstr, sizeof(pstr), "%d", val.i); +// } - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, - rig_strparm(parm), pstr); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, +// rig_strparm(parm), pstr); - priv->parms[idx] = val; +// priv->parms[idx] = val; - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_get_parm(ROT *rot, setting_t parm, value_t *val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - int idx; +// static int flir_get_parm(ROT *rot, setting_t parm, value_t *val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// int idx; - idx = rig_setting2idx(parm); +// idx = rig_setting2idx(parm); - if (idx >= RIG_SETTING_MAX) - { - return -RIG_EINVAL; - } +// if (idx >= RIG_SETTING_MAX) +// { +// return -RIG_EINVAL; +// } - *val = priv->parms[idx]; +// *val = priv->parms[idx]; - rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, - rig_strparm(parm)); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, +// rig_strparm(parm)); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_set_ext_parm(ROT *rot, token_t token, value_t val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - char lstr[64]; - const struct confparams *cfp; - struct ext_list *epp; +// static int flir_set_ext_parm(ROT *rot, token_t token, value_t val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// char lstr[64]; +// const struct confparams *cfp; +// struct ext_list *epp; - cfp = rot_ext_lookup_tok(rot, token); +// cfp = rot_ext_lookup_tok(rot, token); - if (!cfp) - { - return -RIG_EINVAL; - } +// if (!cfp) +// { +// return -RIG_EINVAL; +// } - switch (token) - { - case TOK_EP_ROT_MAGICPARM: - break; +// switch (token) +// { +// case TOK_EP_ROT_MAGICPARM: +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - switch (cfp->type) - { - case RIG_CONF_STRING: - strcpy(lstr, val.s); - break; +// switch (cfp->type) +// { +// case RIG_CONF_STRING: +// strcpy(lstr, val.s); +// break; - case RIG_CONF_COMBO: - SNPRINTF(lstr, sizeof(lstr), "%d", val.i); - break; +// case RIG_CONF_COMBO: +// SNPRINTF(lstr, sizeof(lstr), "%d", val.i); +// break; - case RIG_CONF_NUMERIC: - SNPRINTF(lstr, sizeof(lstr), "%f", val.f); - break; +// case RIG_CONF_NUMERIC: +// SNPRINTF(lstr, sizeof(lstr), "%f", val.f); +// break; - case RIG_CONF_CHECKBUTTON: - SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); - break; +// case RIG_CONF_CHECKBUTTON: +// SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); +// break; - case RIG_CONF_BUTTON: - lstr[0] = '\0'; - break; +// case RIG_CONF_BUTTON: +// lstr[0] = '\0'; +// break; - default: - return -RIG_EINTERNAL; - } +// default: +// return -RIG_EINTERNAL; +// } - epp = find_ext(priv->ext_parms, token); +// epp = find_ext(priv->ext_parms, token); - if (!epp) - { - return -RIG_EINTERNAL; - } +// if (!epp) +// { +// return -RIG_EINTERNAL; +// } - /* store value */ - epp->val = val; +// /* store value */ +// epp->val = val; - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, - cfp->name, lstr); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, +// cfp->name, lstr); - return RIG_OK; -} +// return RIG_OK; +// } -static int flir_get_ext_parm(ROT *rot, token_t token, value_t *val) -{ - struct flir_priv_data *priv = (struct flir_priv_data *) - rot->state.priv; - const struct confparams *cfp; - struct ext_list *epp; +// static int flir_get_ext_parm(ROT *rot, token_t token, value_t *val) +// { +// struct flir_priv_data *priv = (struct flir_priv_data *) +// rot->state.priv; +// const struct confparams *cfp; +// struct ext_list *epp; - cfp = rot_ext_lookup_tok(rot, token); +// cfp = rot_ext_lookup_tok(rot, token); - if (!cfp) - { - return -RIG_EINVAL; - } +// if (!cfp) +// { +// return -RIG_EINVAL; +// } - switch (token) - { - case TOK_EP_ROT_MAGICPARM: - break; +// switch (token) +// { +// case TOK_EP_ROT_MAGICPARM: +// break; - default: - return -RIG_EINVAL; - } +// default: +// return -RIG_EINVAL; +// } - epp = find_ext(priv->ext_parms, token); +// epp = find_ext(priv->ext_parms, token); - if (!epp) - { - return -RIG_EINTERNAL; - } +// if (!epp) +// { +// return -RIG_EINTERNAL; +// } - /* load value */ - *val = epp->val; +// /* load value */ +// *val = epp->val; - rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, - cfp->name); +// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, +// cfp->name); - return RIG_OK; -} +// return RIG_OK; +// } static int flir_get_status(ROT *rot, rot_status_t *status) @@ -910,10 +963,10 @@ static int flir_get_status(ROT *rot, rot_status_t *status) struct flir_priv_data *priv = (struct flir_priv_data *) rot->state.priv; - if (simulating) - { - flir_simulate_rotation(rot); - } + // if (simulating) + // { + // flir_simulate_rotation(rot); + // } *status = priv->status; @@ -931,30 +984,42 @@ struct rot_caps flir_caps = .mfg_name = "FLIR", .version = "20221126.0", .copyright = "LGPL", - .status = RIG_STATUS_STABLE, + .status = RIG_STATUS_ALPHA, .rot_type = ROT_TYPE_AZEL, - .port_type = RIG_PORT_NONE, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 9600, + .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 = 300, + .timeout = 400, + .retry = 3, .min_az = -180., - .max_az = 450., + .max_az = 180., .min_el = 0., .max_el = 90., + + .priv = NULL, /* priv */ - .has_get_func = FLIR_FUNC, - .has_set_func = FLIR_FUNC, - .has_get_level = FLIR_LEVEL, - .has_set_level = ROT_LEVEL_SET(FLIR_LEVEL), - .has_get_parm = FLIR_PARM, - .has_set_parm = ROT_PARM_SET(FLIR_PARM), + // .has_get_func = FLIR_FUNC, + // .has_set_func = FLIR_FUNC, + // .has_get_level = FLIR_LEVEL, + // .has_set_level = ROT_LEVEL_SET(FLIR_LEVEL), + // .has_get_parm = FLIR_PARM, + // .has_set_parm = ROT_PARM_SET(FLIR_PARM), - .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, + // .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, - .extlevels = flir_ext_levels, - .extfuncs = flir_ext_funcs, - .extparms = flir_ext_parms, - .cfgparams = flir_cfg_params, + // .extlevels = flir_ext_levels, + // .extfuncs = flir_ext_funcs, + // .extparms = flir_ext_parms, + // .cfgparams = flir_cfg_params, .has_status = FLIR_STATUS, @@ -963,8 +1028,8 @@ struct rot_caps flir_caps = .rot_open = flir_open, .rot_close = flir_close, - .set_conf = flir_set_conf, - .get_conf = flir_get_conf, + // .set_conf = flir_set_conf, + // .get_conf = flir_get_conf, .set_position = flir_set_position, .get_position = flir_get_position, @@ -973,19 +1038,19 @@ struct rot_caps flir_caps = .reset = flir_reset, .move = flir_move, - .set_func = flir_set_func, - .get_func = flir_get_func, - .set_level = flir_set_level, - .get_level = flir_get_level, - .set_parm = flir_set_parm, - .get_parm = flir_get_parm, + // .set_func = flir_set_func, + // .get_func = flir_get_func, + // .set_level = flir_set_level, + // .get_level = flir_get_level, + // .set_parm = flir_set_parm, + // .get_parm = flir_get_parm, - .set_ext_func = flir_set_ext_func, - .get_ext_func = flir_get_ext_func, - .set_ext_level = flir_set_ext_level, - .get_ext_level = flir_get_ext_level, - .set_ext_parm = flir_set_ext_parm, - .get_ext_parm = flir_get_ext_parm, + // .set_ext_func = flir_set_ext_func, + // .get_ext_func = flir_get_ext_func, + // .set_ext_level = flir_set_ext_level, + // .get_ext_level = flir_get_ext_level, + // .set_ext_parm = flir_set_ext_parm, + // .get_ext_parm = flir_get_ext_parm, .get_info = flir_get_info, .get_status = flir_get_status, diff --git a/rotators/flir/flir.h b/rotators/flir/flir.h index 4d86eea0b..5b32e1c30 100644 --- a/rotators/flir/flir.h +++ b/rotators/flir/flir.h @@ -36,6 +36,10 @@ #define TOK_EL_ROT_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_ROT_MAGICEXTFUNC TOKEN_BACKEND(6) +#define MAXBUF 64 + + + extern struct rot_caps flir_caps; extern struct rot_caps netrotctl_caps; diff --git a/src/rot_reg.c b/src/rot_reg.c index 5e2fff59c..b476dd4c2 100644 --- a/src/rot_reg.c +++ b/src/rot_reg.c @@ -83,7 +83,6 @@ DEFINE_INITROT_BACKEND(meade); DEFINE_INITROT_BACKEND(ioptron); DEFINE_INITROT_BACKEND(satel); DEFINE_INITROT_BACKEND(radant); -DEFINE_INITROT_BACKEND(flir); #if HAVE_LIBINDI DEFINE_INITROT_BACKEND(indi); #endif @@ -91,6 +90,7 @@ DEFINE_INITROT_BACKEND(indi); DEFINE_INITROT_BACKEND(androidsensor); #endif DEFINE_INITROT_BACKEND(grbltrk); +DEFINE_INITROT_BACKEND(flir); //! @endcond /** @@ -132,7 +132,6 @@ static struct { ROT_IOPTRON, ROT_BACKEND_IOPTRON, ROT_FUNCNAMA(ioptron) }, { ROT_SATEL, ROT_BACKEND_SATEL, ROT_FUNCNAMA(satel) }, { ROT_RADANT, ROT_BACKEND_RADANT, ROT_FUNCNAMA(radant)}, - { ROT_FLIR, ROT_BACKEND_FLIR, ROT_FUNCNAMA(flir) }, #if HAVE_LIBINDI { ROT_INDI, ROT_BACKEND_INDI, ROT_FUNCNAMA(indi) }, #endif @@ -140,6 +139,7 @@ static struct { ROT_ANDROIDSENSOR, ROT_BACKEND_ANDROIDSENSOR, ROT_FUNCNAMA(androidsensor) }, #endif { ROT_GRBLTRK, ROT_BACKEND_GRBLTRK, ROT_FUNCNAMA(grbltrk) }, + { ROT_FLIR, ROT_BACKEND_FLIR, ROT_FUNCNAMA(flir) }, { 0, NULL }, /* end */ }; From db690f37ff31fc303edf87c41358bcdc0d9ad9fc Mon Sep 17 00:00:00 2001 From: andz Date: Wed, 30 Nov 2022 13:55:00 +0100 Subject: [PATCH 3/8] Cleaned up * removed all warnings * retrun -RIG_ENIMPL for all not yet implemented functions --- rotators/flir/flir.c | 734 +++++++------------------------------------ 1 file changed, 106 insertions(+), 628 deletions(-) diff --git a/rotators/flir/flir.c b/rotators/flir/flir.c index 0e1b839c1..ee3d317cf 100644 --- a/rotators/flir/flir.c +++ b/rotators/flir/flir.c @@ -29,6 +29,7 @@ #include "hamlib/rotator.h" #include "register.h" #include "idx_builtin.h" +#include "serial.h" #include "flir.h" @@ -40,8 +41,6 @@ ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN | \ ROT_STATUS_LIMIT_UP | ROT_STATUS_LIMIT_DOWN | ROT_STATUS_LIMIT_LEFT | ROT_STATUS_LIMIT_RIGHT) -//static int simulating = 0; // do we need rotator emulation for debug? - struct flir_priv_data { azimuth_t az; @@ -56,6 +55,8 @@ struct flir_priv_data value_t levels[RIG_SETTING_MAX]; value_t parms[RIG_SETTING_MAX]; + char info[256]; + struct ext_list *ext_funcs; struct ext_list *ext_levels; struct ext_list *ext_parms; @@ -66,61 +67,11 @@ struct flir_priv_data float_t resolution_tp; }; -// static const struct confparams flir_ext_levels[] = -// { -// { -// TOK_EL_ROT_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", -// NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } -// }, -// { -// TOK_EL_ROT_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", -// NULL, RIG_CONF_CHECKBUTTON -// }, -// { -// TOK_EL_ROT_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", -// NULL, RIG_CONF_BUTTON -// }, -// { -// TOK_EL_ROT_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", -// "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } -// }, -// { RIG_CONF_END, NULL, } -// }; - -// static const struct confparams flir_ext_funcs[] = -// { -// { -// TOK_EL_ROT_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", -// NULL, RIG_CONF_CHECKBUTTON -// }, -// { RIG_CONF_END, NULL, } -// }; - -// static const struct confparams flir_ext_parms[] = -// { -// { -// TOK_EP_ROT_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", -// NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } -// }, -// { RIG_CONF_END, NULL, } -// }; - -/* cfgparams are configuration item generally used by the backend's open() method */ -// static const struct confparams flir_cfg_params[] = -// { -// { -// TOK_CFG_ROT_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", -// "ROTATOR", RIG_CONF_STRING, { } -// }, -// { RIG_CONF_END, NULL, } -// }; - static int flir_request(ROT *rot, char *request, char *response, - uint32_t *resp_size) + int resp_size) { int return_value = -RIG_EINVAL; int retry_read = 0; - unsigned char cmd_ok; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -128,20 +79,20 @@ static int flir_request(ROT *rot, char *request, char *response, if (request) { - return_value = write_block(&rot->state.rotport, (unsigned char *) request, + return_value = write_block(&rot->state.rotport, (unsigned char *)request, strlen(request)); if (return_value != RIG_OK) { return return_value; } } - //Is a direct request expected? + //Is a direct response expected? if (response != NULL) { while(retry_read < rot->state.rotport.retry) { - memset(response, 0, resp_size); - resp_size = read_string(&rot->state.rotport, response, resp_size, + memset(response, 0, (size_t)resp_size); + resp_size = read_string(&rot->state.rotport, (unsigned char *)response, resp_size, "\r\n", sizeof("\r\n"), 0, 1); if(resp_size > 0) { @@ -182,30 +133,6 @@ static int flir_init(ROT *rot) priv = rot->state.priv; - // priv->ext_funcs = alloc_init_ext(flir_ext_funcs); - - // if (!priv->ext_funcs) - // { - // return -RIG_ENOMEM; - // } - - // priv->ext_levels = alloc_init_ext(flir_ext_levels); - - // if (!priv->ext_levels) - // { - // return -RIG_ENOMEM; - // } - - // priv->ext_parms = alloc_init_ext(flir_ext_parms); - - // if (!priv->ext_parms) - // { - // return -RIG_ENOMEM; - // } - - //rot->state.rotport.type.rig = RIG_PORT_SERIAL; - //flir_request(rot, "r\n", sizeof("r\n"), NULL, NULL); - priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; @@ -290,56 +217,15 @@ static int flir_close(ROT *rot) return RIG_OK; } -// static int flir_set_conf(ROT *rot, token_t token, const char *val) -// { -// struct flir_priv_data *priv; - -// priv = (struct flir_priv_data *)rot->state.priv; - -// switch (token) -// { -// case TOK_CFG_ROT_MAGICCONF: -// if (val) -// { -// free(priv->magic_conf); -// priv->magic_conf = strdup(val); -// } - -// break; - -// default: -// return -RIG_EINVAL; -// } - -// return RIG_OK; -// } - - -// static int flir_get_conf2(ROT *rot, token_t token, char *val, int val_len) -// { -// struct flir_priv_data *priv; - -// priv = (struct flir_priv_data *)rot->state.priv; - -// switch (token) -// { -// case TOK_CFG_ROT_MAGICCONF: -// SNPRINTF(val, val_len, "%s", priv->magic_conf); -// break; - -// default: -// return -RIG_EINVAL; -// } - -// return RIG_OK; -// } - -// static int flir_get_conf(ROT *rot, token_t token, char *val) -// { -// return flir_get_conf2(rot, token, val, 128); -// } - +static int flir_set_conf(ROT *rot, token_t token, const char *val) +{ + return -RIG_ENIMPL; +} +static int flir_get_conf(ROT *rot, token_t token, char *val) +{ + return -RIG_ENIMPL; +} static int flir_set_position(ROT *rot, azimuth_t az, elevation_t el) { @@ -383,6 +269,7 @@ static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el) rig_debug(RIG_DEBUG_VERBOSE, "PP Return String: %s\n", return_str); sscanf(return_str, "* %d", &pan_positions); priv->az = (pan_positions * priv->resolution_pp) / 3600; + *az = priv->az; } else { @@ -394,23 +281,19 @@ static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el) rig_debug(RIG_DEBUG_VERBOSE, "TP Return String: %s\n", return_str); sscanf(return_str, "* %d", &tilt_positions); priv->el = 90.0 + ((tilt_positions * priv->resolution_tp) / 3600); + *el = priv->el; } else { return_value = -RIG_EPROTO; } - *az = priv->az; - *el = priv->el; - return return_value; } - static int flir_stop(ROT *rot) { int return_value = RIG_OK; - char return_str[MAXBUF]; struct flir_priv_data *priv = (struct flir_priv_data *) rot->state.priv; @@ -431,7 +314,6 @@ static int flir_stop(ROT *rot) return return_value; } - static int flir_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -448,7 +330,7 @@ static int flir_reset(ROT *rot, rot_reset_t reset) rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (reset != 0) { - return_value = flir_request(rot, "r\n", NULL, NULL); + return_value = flir_request(rot, "r\n", NULL, 0); // After Reset: Disable Hard Limits if(return_value == RIG_OK) { @@ -490,490 +372,93 @@ static int flir_move(ROT *rot, int direction, int speed) static const char *flir_get_info(ROT *rot) { - const char* firmware_str[120]; - const char* info_str[120]; - const char* return_str[256]; + char firmware_str[120]; + char info_str[120]; + struct flir_priv_data *priv = (struct flir_priv_data *) + rot->state.priv; - sprintf(return_str, "No Info"); + sprintf(priv->info, "No Info"); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if(flir_request(rot, "V\n", firmware_str, 120) == RIG_OK && flir_request(rot, "O\n", info_str, 120) == RIG_OK) { - sprintf(return_str, "Firmware: %s Info: %s", firmware_str, info_str); + sprintf(priv->info, "Firmware: %s Info: %s", firmware_str, info_str); } //rig_debug(RIG_DEBUG_VERBOSE, "Return String: %s", return_str); - return *return_str; + return priv->info; } -// static int flir_set_func(ROT *rot, setting_t func, int status) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, -// rot_strfunc(func), status); - -// if (status) -// { -// priv->funcs |= func; -// } -// else -// { -// priv->funcs &= ~func; -// } - -// return RIG_OK; -// } - - -// static int flir_get_func(ROT *rot, setting_t func, int *status) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; - -// *status = (priv->funcs & func) ? 1 : 0; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, -// rot_strfunc(func)); - -// return RIG_OK; -// } - - -// static int flir_set_level(ROT *rot, setting_t level, value_t val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// int idx; -// char lstr[32]; - -// idx = rig_setting2idx(level); - -// if (idx >= RIG_SETTING_MAX) -// { -// return -RIG_EINVAL; -// } - -// priv->levels[idx] = val; - -// if (ROT_LEVEL_IS_FLOAT(level)) -// { -// SNPRINTF(lstr, sizeof(lstr), "%f", val.f); -// } -// else -// { -// SNPRINTF(lstr, sizeof(lstr), "%d", val.i); -// } - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, -// rot_strlevel(level), lstr); - -// return RIG_OK; -// } - - -// static int flir_get_level(ROT *rot, setting_t level, value_t *val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// int idx; - -// idx = rig_setting2idx(level); - -// if (idx >= RIG_SETTING_MAX) -// { -// return -RIG_EINVAL; -// } - -// *val = priv->levels[idx]; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, -// rot_strlevel(level)); - -// return RIG_OK; -// } - -// static int flir_set_ext_level(ROT *rot, token_t token, value_t val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// char lstr[64]; -// const struct confparams *cfp; -// struct ext_list *elp; - -// cfp = rot_ext_lookup_tok(rot, token); - -// if (!cfp) -// { -// return -RIG_EINVAL; -// } - -// switch (token) -// { -// case TOK_EL_ROT_MAGICLEVEL: -// case TOK_EL_ROT_MAGICFUNC: -// case TOK_EL_ROT_MAGICOP: -// case TOK_EL_ROT_MAGICCOMBO: -// break; - -// default: -// return -RIG_EINVAL; -// } - -// switch (cfp->type) -// { -// case RIG_CONF_STRING: -// strcpy(lstr, val.s); -// break; - -// case RIG_CONF_COMBO: -// SNPRINTF(lstr, sizeof(lstr), "%d", val.i); -// break; - -// case RIG_CONF_NUMERIC: -// SNPRINTF(lstr, sizeof(lstr), "%f", val.f); -// break; - -// case RIG_CONF_CHECKBUTTON: -// SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); -// break; - -// case RIG_CONF_BUTTON: -// lstr[0] = '\0'; -// break; - -// default: -// return -RIG_EINTERNAL; -// } - -// elp = find_ext(priv->ext_levels, token); - -// if (!elp) -// { -// return -RIG_EINTERNAL; -// } - -// /* store value */ -// elp->val = val; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, -// cfp->name, lstr); - -// return RIG_OK; -// } - -// static int flir_get_ext_level(ROT *rot, token_t token, value_t *val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// const struct confparams *cfp; -// struct ext_list *elp; - -// cfp = rot_ext_lookup_tok(rot, token); - -// if (!cfp) -// { -// return -RIG_EINVAL; -// } - -// switch (token) -// { -// case TOK_EL_ROT_MAGICLEVEL: -// case TOK_EL_ROT_MAGICFUNC: -// case TOK_EL_ROT_MAGICOP: -// case TOK_EL_ROT_MAGICCOMBO: -// break; - -// default: -// return -RIG_EINVAL; -// } - -// elp = find_ext(priv->ext_levels, token); - -// if (!elp) -// { -// return -RIG_EINTERNAL; -// } - -// /* load value */ -// *val = elp->val; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, -// cfp->name); - -// return RIG_OK; -// } - - -// static int flir_set_ext_func(ROT *rot, token_t token, int status) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// const struct confparams *cfp; -// struct ext_list *elp; - -// cfp = rot_ext_lookup_tok(rot, token); - -// if (!cfp) -// { -// return -RIG_EINVAL; -// } - -// switch (token) -// { -// case TOK_EL_ROT_MAGICEXTFUNC: -// break; - -// default: -// return -RIG_EINVAL; -// } - -// switch (cfp->type) -// { -// case RIG_CONF_CHECKBUTTON: -// break; - -// case RIG_CONF_BUTTON: -// break; - -// default: -// return -RIG_EINTERNAL; -// } - -// elp = find_ext(priv->ext_funcs, token); - -// if (!elp) -// { -// return -RIG_EINTERNAL; -// } - -// /* store value */ -// elp->val.i = status; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, -// cfp->name, status); - -// return RIG_OK; -// } - - -// static int flir_get_ext_func(ROT *rot, token_t token, int *status) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// const struct confparams *cfp; -// struct ext_list *elp; - -// cfp = rot_ext_lookup_tok(rot, token); - -// if (!cfp) -// { -// return -RIG_EINVAL; -// } - -// switch (token) -// { -// case TOK_EL_ROT_MAGICEXTFUNC: -// break; - -// default: -// return -RIG_EINVAL; -// } - -// elp = find_ext(priv->ext_funcs, token); - -// if (!elp) -// { -// return -RIG_EINTERNAL; -// } - -// /* load value */ -// *status = elp->val.i; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, -// cfp->name); - -// return RIG_OK; -// } - - -// static int flir_set_parm(ROT *rot, setting_t parm, value_t val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// int idx; -// char pstr[32]; - -// idx = rig_setting2idx(parm); - -// if (idx >= RIG_SETTING_MAX) -// { -// return -RIG_EINVAL; -// } - -// if (ROT_PARM_IS_FLOAT(parm)) -// { -// SNPRINTF(pstr, sizeof(pstr), "%f", val.f); -// } -// else -// { -// SNPRINTF(pstr, sizeof(pstr), "%d", val.i); -// } - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, -// rig_strparm(parm), pstr); - -// priv->parms[idx] = val; - -// return RIG_OK; -// } - - -// static int flir_get_parm(ROT *rot, setting_t parm, value_t *val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// int idx; - -// idx = rig_setting2idx(parm); - -// if (idx >= RIG_SETTING_MAX) -// { -// return -RIG_EINVAL; -// } - -// *val = priv->parms[idx]; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, -// rig_strparm(parm)); - -// return RIG_OK; -// } - -// static int flir_set_ext_parm(ROT *rot, token_t token, value_t val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// char lstr[64]; -// const struct confparams *cfp; -// struct ext_list *epp; - -// cfp = rot_ext_lookup_tok(rot, token); - -// if (!cfp) -// { -// return -RIG_EINVAL; -// } - -// switch (token) -// { -// case TOK_EP_ROT_MAGICPARM: -// break; - -// default: -// return -RIG_EINVAL; -// } - -// switch (cfp->type) -// { -// case RIG_CONF_STRING: -// strcpy(lstr, val.s); -// break; - -// case RIG_CONF_COMBO: -// SNPRINTF(lstr, sizeof(lstr), "%d", val.i); -// break; - -// case RIG_CONF_NUMERIC: -// SNPRINTF(lstr, sizeof(lstr), "%f", val.f); -// break; - -// case RIG_CONF_CHECKBUTTON: -// SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); -// break; - -// case RIG_CONF_BUTTON: -// lstr[0] = '\0'; -// break; - -// default: -// return -RIG_EINTERNAL; -// } - -// epp = find_ext(priv->ext_parms, token); - -// if (!epp) -// { -// return -RIG_EINTERNAL; -// } - -// /* store value */ -// epp->val = val; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, -// cfp->name, lstr); - -// return RIG_OK; -// } - -// static int flir_get_ext_parm(ROT *rot, token_t token, value_t *val) -// { -// struct flir_priv_data *priv = (struct flir_priv_data *) -// rot->state.priv; -// const struct confparams *cfp; -// struct ext_list *epp; - -// cfp = rot_ext_lookup_tok(rot, token); - -// if (!cfp) -// { -// return -RIG_EINVAL; -// } - -// switch (token) -// { -// case TOK_EP_ROT_MAGICPARM: -// break; - -// default: -// return -RIG_EINVAL; -// } - -// epp = find_ext(priv->ext_parms, token); - -// if (!epp) -// { -// return -RIG_EINTERNAL; -// } - -// /* load value */ -// *val = epp->val; - -// rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, -// cfp->name); - -// return RIG_OK; -// } - +static int flir_set_func(ROT *rot, setting_t func, int status) +{ + return -RIG_ENIMPL; +} + +static int flir_get_func(ROT *rot, setting_t func, int *status) +{ + return -RIG_ENIMPL; +} + +static int flir_set_level(ROT *rot, setting_t level, value_t val) +{ + return -RIG_ENIMPL; +} + +static int flir_get_level(ROT *rot, setting_t level, value_t *val) +{ + return -RIG_ENIMPL; +} + +static int flir_set_ext_level(ROT *rot, token_t token, value_t val) +{ + return -RIG_ENIMPL; +} + +static int flir_get_ext_level(ROT *rot, token_t token, value_t *val) +{ + return -RIG_ENIMPL; +} + +static int flir_set_ext_func(ROT *rot, token_t token, int status) +{ + return -RIG_ENIMPL; +} + +static int flir_get_ext_func(ROT *rot, token_t token, int *status) +{ + return -RIG_ENIMPL; +} + +static int flir_set_parm(ROT *rot, setting_t parm, value_t val) +{ + return -RIG_ENIMPL; +} + +static int flir_get_parm(ROT *rot, setting_t parm, value_t *val) +{ + return -RIG_ENIMPL; +} + +static int flir_set_ext_parm(ROT *rot, token_t token, value_t val) +{ + return -RIG_ENIMPL; +} + +static int flir_get_ext_parm(ROT *rot, token_t token, value_t *val) +{ + return -RIG_ENIMPL; +} static int flir_get_status(ROT *rot, rot_status_t *status) { struct flir_priv_data *priv = (struct flir_priv_data *) rot->state.priv; - - // if (simulating) - // { - // flir_simulate_rotation(rot); - // } - *status = priv->status; return RIG_OK; } - /* * flir rotator capabilities. */ @@ -1003,23 +488,16 @@ struct rot_caps flir_caps = .min_el = 0., .max_el = 90., - - .priv = NULL, /* priv */ - // .has_get_func = FLIR_FUNC, - // .has_set_func = FLIR_FUNC, - // .has_get_level = FLIR_LEVEL, - // .has_set_level = ROT_LEVEL_SET(FLIR_LEVEL), - // .has_get_parm = FLIR_PARM, - // .has_set_parm = ROT_PARM_SET(FLIR_PARM), + .has_get_func = FLIR_FUNC, + .has_set_func = FLIR_FUNC, + .has_get_level = FLIR_LEVEL, + .has_set_level = ROT_LEVEL_SET(FLIR_LEVEL), + .has_get_parm = FLIR_PARM, + .has_set_parm = ROT_PARM_SET(FLIR_PARM), - // .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, - - // .extlevels = flir_ext_levels, - // .extfuncs = flir_ext_funcs, - // .extparms = flir_ext_parms, - // .cfgparams = flir_cfg_params, + .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .has_status = FLIR_STATUS, @@ -1028,8 +506,8 @@ struct rot_caps flir_caps = .rot_open = flir_open, .rot_close = flir_close, - // .set_conf = flir_set_conf, - // .get_conf = flir_get_conf, + .set_conf = flir_set_conf, + .get_conf = flir_get_conf, .set_position = flir_set_position, .get_position = flir_get_position, @@ -1038,19 +516,19 @@ struct rot_caps flir_caps = .reset = flir_reset, .move = flir_move, - // .set_func = flir_set_func, - // .get_func = flir_get_func, - // .set_level = flir_set_level, - // .get_level = flir_get_level, - // .set_parm = flir_set_parm, - // .get_parm = flir_get_parm, + .set_func = flir_set_func, + .get_func = flir_get_func, + .set_level = flir_set_level, + .get_level = flir_get_level, + .set_parm = flir_set_parm, + .get_parm = flir_get_parm, - // .set_ext_func = flir_set_ext_func, - // .get_ext_func = flir_get_ext_func, - // .set_ext_level = flir_set_ext_level, - // .get_ext_level = flir_get_ext_level, - // .set_ext_parm = flir_set_ext_parm, - // .get_ext_parm = flir_get_ext_parm, + .set_ext_func = flir_set_ext_func, + .get_ext_func = flir_get_ext_func, + .set_ext_level = flir_set_ext_level, + .get_ext_level = flir_get_ext_level, + .set_ext_parm = flir_set_ext_parm, + .get_ext_parm = flir_get_ext_parm, .get_info = flir_get_info, .get_status = flir_get_status, From b2d6a856a432aa7394d6b7887660d4dca504d842 Mon Sep 17 00:00:00 2001 From: andz Date: Wed, 30 Nov 2022 15:00:29 +0100 Subject: [PATCH 4/8] Fixed segfault when read_string failed --- rotators/flir/flir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rotators/flir/flir.c b/rotators/flir/flir.c index ee3d317cf..8adaa8929 100644 --- a/rotators/flir/flir.c +++ b/rotators/flir/flir.c @@ -72,6 +72,7 @@ static int flir_request(ROT *rot, char *request, char *response, { int return_value = -RIG_EINVAL; int retry_read = 0; + int read_char = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -83,6 +84,7 @@ static int flir_request(ROT *rot, char *request, char *response, strlen(request)); if (return_value != RIG_OK) { + rig_debug(RIG_DEBUG_VERBOSE, "%s request not OK\n", __func__); return return_value; } } @@ -92,9 +94,9 @@ static int flir_request(ROT *rot, char *request, char *response, while(retry_read < rot->state.rotport.retry) { memset(response, 0, (size_t)resp_size); - resp_size = read_string(&rot->state.rotport, (unsigned char *)response, resp_size, + read_char = read_string(&rot->state.rotport, (unsigned char *)response, resp_size, "\r\n", sizeof("\r\n"), 0, 1); - if(resp_size > 0) + if(read_char > 0) { if(response[0] == '*') { @@ -110,6 +112,7 @@ static int flir_request(ROT *rot, char *request, char *response, } retry_read++; } + response = ""; rig_debug(RIG_DEBUG_VERBOSE, "timeout for command %s\n", request); return -RIG_ETIMEOUT; } @@ -273,6 +276,7 @@ static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el) } else { + rig_debug(RIG_DEBUG_VERBOSE, "PP Wrong Return String: %s\n", return_str); return_value = -RIG_EPROTO; } @@ -285,6 +289,7 @@ static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el) } else { + rig_debug(RIG_DEBUG_VERBOSE, "PP Wrong Return String: %s\n", return_str); return_value = -RIG_EPROTO; } From c7d0004b36e60691f5f2e87acf538f505d6e5175 Mon Sep 17 00:00:00 2001 From: andz Date: Wed, 30 Nov 2022 15:33:55 +0100 Subject: [PATCH 5/8] Fixed Info command --- rotators/flir/flir.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/rotators/flir/flir.c b/rotators/flir/flir.c index 8adaa8929..7ae3ffc02 100644 --- a/rotators/flir/flir.c +++ b/rotators/flir/flir.c @@ -377,21 +377,26 @@ static int flir_move(ROT *rot, int direction, int speed) static const char *flir_get_info(ROT *rot) { - char firmware_str[120]; - char info_str[120]; + char firmware_str[121]; + char info_str[101]; + struct flir_priv_data *priv = (struct flir_priv_data *) rot->state.priv; sprintf(priv->info, "No Info"); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - - if(flir_request(rot, "V\n", firmware_str, 120) == RIG_OK && - flir_request(rot, "O\n", info_str, 120) == RIG_OK) + if(flir_request(rot, "V\n", firmware_str, 120) != RIG_OK) { - sprintf(priv->info, "Firmware: %s Info: %s", firmware_str, info_str); + return "No Info available"; } - //rig_debug(RIG_DEBUG_VERBOSE, "Return String: %s", return_str); + hl_usleep(500000); + if(flir_request(rot, "O\n", info_str, 100) != RIG_OK) + { + return "No Info available"; + } + sprintf(priv->info, "Firmware: %s\nPower: %s", firmware_str, info_str); + return priv->info; } From a522e6f6e7e0cdca8e0cbb8204a29d584431cc41 Mon Sep 17 00:00:00 2001 From: andz Date: Wed, 30 Nov 2022 15:41:41 +0100 Subject: [PATCH 6/8] Added README.md --- rotators/flir/README | 1 - rotators/flir/README.md | 75 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) delete mode 100644 rotators/flir/README create mode 100644 rotators/flir/README.md diff --git a/rotators/flir/README b/rotators/flir/README deleted file mode 100644 index 0601a099b..000000000 --- a/rotators/flir/README +++ /dev/null @@ -1 +0,0 @@ -tbd diff --git a/rotators/flir/README.md b/rotators/flir/README.md new file mode 100644 index 000000000..11d3b9bc2 --- /dev/null +++ b/rotators/flir/README.md @@ -0,0 +1,75 @@ +# FLIR/DirectedPerception PTU Rotor Module + +This module interfaces FLIR and DirectedPerception +rotor using the PTU protocol via serial. + +This includes: + +* PTU-D48(E) +* PTU-E46 +* PTU-D100(E) +* PTU-D300(E) + +Tested only with PTU-D48 yet and with one rotor per chain only. + +## Usage + +1. Connect the rotor via serial (RS232 or RS485) +2. Power up the rotor +3. The rotor must be calibrated after each power up. This can be accived +either using the rotctl `Reset` command (R) or manually via serial terminal +sending the `R\n` command. +4. To enable the rotor to fully turn +/- 180°, the softlock must be disabled. +This is included in the rotctl `Reset` commnad or manually via serial terminal +seinden the command `LD\n`. **WARNING:** Send this command only after the rotor is +calibrated, or you risk damage running into the hard endstops (at about +/-190°) +5. Start `rotctl` or `rotctld` with the arguments `-m 2501 -r ` + +Have Fun. + +### Hints + +1. Setup the max. velocity, power and acceleration according to your antenna load. +This must be done via serial terminal, as the functions are not implemented yet. +2. Never use the maximum hold power, only use the low or off. If you use max or regular, +the rotor may easily overheat! + +## PTU Protocol + +* [Protocol Version 3.02 (2011)](https://flir.netx.net/file/asset/11556/original/attachment) + +## Current Status + +The current status is **ALPHA**. It is tested with DirectedPercepiton PTU-D48 (Firmware v2.13.4r0(D48-C14/E)) +Linux with `rotctl` and `gpredict`. + +### Implemented so far: + +* init +* cleanup +* open +* close +* set_position +* get_position +* park +* stop +* reset +* move +* info + +### Needs to be implemented: + +#### Parameters + +* velocity +* acceleration +* velocity profile +* user soft-limits +* power commands (move and hold) +* step mode +* reset on startup + +#### Functions + +* usage of chained rotors via RS485 From 0860bda83214382d1d0c887573d553cd0d9a4e86 Mon Sep 17 00:00:00 2001 From: andz Date: Wed, 30 Nov 2022 15:55:27 +0100 Subject: [PATCH 7/8] Changed header description --- rotators/flir/flir.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rotators/flir/flir.h b/rotators/flir/flir.h index 5b32e1c30..e20c05c79 100644 --- a/rotators/flir/flir.h +++ b/rotators/flir/flir.h @@ -1,6 +1,6 @@ /* - * Hamlib Dummy backend - main header - * Copyright (c) 2001-2008 by Stephane Fillod + * Hamlib FLIR PTU rotor backend - main header + * Copyright (c) 2022 by Andreas Mueller (DC1MIL) * * * This library is free software; you can redistribute it and/or From 07cc887432be93b191aa7b67c68a5b2962c4f06e Mon Sep 17 00:00:00 2001 From: andz Date: Wed, 30 Nov 2022 16:06:27 +0100 Subject: [PATCH 8/8] Added Android.mk --- rotators/flir/Android.mk | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 rotators/flir/Android.mk diff --git a/rotators/flir/Android.mk b/rotators/flir/Android.mk new file mode 100644 index 000000000..3fa35ec03 --- /dev/null +++ b/rotators/flir/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := flir.c +LOCAL_MODULE := flir + +LOCAL_CFLAGS := +LOCAL_C_INCLUDES := android include src +LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) + +include $(BUILD_STATIC_LIBRARY)