2022-11-26 00:04:36 +00:00
|
|
|
/*
|
2022-11-30 11:20:25 +00:00
|
|
|
* Hamlib FLIR PTU rotor backend - main file
|
|
|
|
* Copyright (c) 2022 by Andreas Mueller (DC1MIL)
|
2022-11-26 00:04:36 +00:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* 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 <hamlib/config.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h> /* String function definitions */
|
|
|
|
#include <math.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
#include "hamlib/rotator.h"
|
|
|
|
#include "register.h"
|
|
|
|
#include "idx_builtin.h"
|
2022-11-30 12:55:00 +00:00
|
|
|
#include "serial.h"
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
#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)
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
char info[256];
|
|
|
|
|
2022-11-26 00:04:36 +00:00
|
|
|
struct ext_list *ext_funcs;
|
|
|
|
struct ext_list *ext_levels;
|
|
|
|
struct ext_list *ext_parms;
|
|
|
|
|
|
|
|
char *magic_conf;
|
|
|
|
|
2022-12-09 04:37:22 +00:00
|
|
|
float_t resolution_pp;
|
|
|
|
float_t resolution_tp;
|
2022-11-26 00:04:36 +00:00
|
|
|
};
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
static int flir_request(ROT *rot, char *request, char *response,
|
2022-12-09 04:37:22 +00:00
|
|
|
int resp_size)
|
2022-11-26 00:04:36 +00:00
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
int return_value = -RIG_EINVAL;
|
|
|
|
int retry_read = 0;
|
2022-11-30 14:00:29 +00:00
|
|
|
int read_char = 0;
|
2022-11-30 11:20:25 +00:00
|
|
|
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
|
|
|
|
rig_flush(&rot->state.rotport);
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-12-09 04:37:22 +00:00
|
|
|
if (request)
|
|
|
|
{
|
|
|
|
return_value = write_block(&rot->state.rotport, (unsigned char *)request,
|
|
|
|
strlen(request));
|
|
|
|
|
|
|
|
if (return_value != RIG_OK)
|
2022-11-30 11:20:25 +00:00
|
|
|
{
|
2022-12-09 04:37:22 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s request not OK\n", __func__);
|
|
|
|
return return_value;
|
2022-11-30 11:20:25 +00:00
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Is a direct response expected?
|
|
|
|
if (response != NULL)
|
|
|
|
{
|
|
|
|
while (retry_read < rot->state.rotport.retry)
|
2022-11-30 11:20:25 +00:00
|
|
|
{
|
2022-12-09 04:37:22 +00:00
|
|
|
memset(response, 0, (size_t)resp_size);
|
|
|
|
read_char = read_string(&rot->state.rotport, (unsigned char *)response,
|
|
|
|
resp_size,
|
|
|
|
"\r\n", sizeof("\r\n"), 0, 1);
|
|
|
|
|
|
|
|
if (read_char > 0)
|
2022-11-30 11:20:25 +00:00
|
|
|
{
|
2022-12-09 04:37:22 +00:00
|
|
|
if (response[0] == '*')
|
|
|
|
{
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "accepted command %s\n", request);
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
else
|
2022-11-30 11:20:25 +00:00
|
|
|
{
|
2022-12-09 04:37:22 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "NOT accepted command %s\n", request);
|
|
|
|
return -RIG_ERJCTED;
|
2022-11-30 11:20:25 +00:00
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
|
|
|
|
retry_read++;
|
2022-11-30 11:20:25 +00:00
|
|
|
}
|
|
|
|
|
2022-12-09 04:37:22 +00:00
|
|
|
response = "";
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "timeout for command %s\n", request);
|
|
|
|
return -RIG_ETIMEOUT;
|
|
|
|
}
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
return return_value;
|
|
|
|
};
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
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->az = priv->el = 0;
|
|
|
|
|
|
|
|
priv->target_az = priv->target_el = 0;
|
|
|
|
|
|
|
|
priv->magic_conf = strdup("ROTATOR");
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
priv->resolution_pp = 92.5714;
|
|
|
|
priv->resolution_tp = 46.2857;
|
|
|
|
|
2022-11-26 00:04:36 +00:00
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int flir_cleanup(ROT *rot)
|
|
|
|
{
|
|
|
|
struct flir_priv_data *priv = (struct flir_priv_data *)
|
2022-12-09 04:37:22 +00:00
|
|
|
rot->state.priv;
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
struct flir_priv_data *priv;
|
|
|
|
char return_str[MAXBUF];
|
|
|
|
float_t resolution_pp, resolution_tp;
|
|
|
|
int return_value = RIG_OK;
|
|
|
|
|
2022-11-26 00:04:36 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
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
|
2022-12-09 04:37:22 +00:00
|
|
|
if (flir_request(rot, "PR\n", return_str, MAXBUF) == RIG_OK)
|
2022-11-30 11:20:25 +00:00
|
|
|
{
|
|
|
|
sscanf(return_str, "* %f", &resolution_pp);
|
2022-12-09 04:37:22 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "PAN resolution: %f arcsecs per position\n",
|
|
|
|
resolution_pp);
|
2022-11-30 11:20:25 +00:00
|
|
|
priv->resolution_pp = resolution_pp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return_value = -RIG_EPROTO;
|
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
// Get TILT resolution in arcsecs
|
2022-12-09 04:37:22 +00:00
|
|
|
if (flir_request(rot, "TR\n", return_str, MAXBUF) == RIG_OK)
|
2022-11-26 00:04:36 +00:00
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
sscanf(return_str, "* %f", &resolution_tp);
|
2022-12-09 04:37:22 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "TILT resolution: %f arcsecs per position\n",
|
|
|
|
resolution_tp);
|
2022-11-30 11:20:25 +00:00
|
|
|
priv->resolution_tp = resolution_tp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return_value = -RIG_EPROTO;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
return return_value;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int flir_close(ROT *rot)
|
|
|
|
{
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_set_conf(ROT *rot, token_t token, const char *val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_get_conf(ROT *rot, token_t token, char *val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
static int flir_set_position(ROT *rot, azimuth_t az, elevation_t el)
|
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
int32_t t_pan_positions, t_tilt_positions;
|
|
|
|
char return_str[MAXBUF];
|
|
|
|
char cmd_str[MAXBUF];
|
2022-11-26 00:04:36 +00:00
|
|
|
struct flir_priv_data *priv = (struct flir_priv_data *)
|
2022-12-09 04:37:22 +00:00
|
|
|
rot->state.priv;
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__,
|
|
|
|
az, el);
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
priv->target_az = az;
|
|
|
|
priv->target_el = el;
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
t_pan_positions = (az * 3600) / priv->resolution_pp;
|
|
|
|
t_tilt_positions = - ((90.0 - el) * 3600) / priv->resolution_tp;
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
sprintf(cmd_str, "PP%d TP%d\n", t_pan_positions, t_tilt_positions);
|
|
|
|
|
|
|
|
return flir_request(rot, cmd_str, return_str, MAXBUF);
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
/*
|
|
|
|
* Get position of rotor
|
|
|
|
*/
|
|
|
|
static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el)
|
2022-11-26 00:04:36 +00:00
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
int return_value = RIG_OK;
|
|
|
|
char return_str[MAXBUF];
|
|
|
|
int32_t pan_positions, tilt_positions;
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-26 00:04:36 +00:00
|
|
|
struct flir_priv_data *priv = (struct flir_priv_data *)
|
2022-12-09 04:37:22 +00:00
|
|
|
rot->state.priv;
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
|
2022-12-09 04:37:22 +00:00
|
|
|
if (flir_request(rot, "PP\n", return_str, MAXBUF) == RIG_OK)
|
2022-11-26 00:04:36 +00:00
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
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;
|
2022-11-30 12:55:00 +00:00
|
|
|
*az = priv->az;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-11-30 14:00:29 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "PP Wrong Return String: %s\n", return_str);
|
2022-11-30 11:20:25 +00:00
|
|
|
return_value = -RIG_EPROTO;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
|
|
|
|
if (flir_request(rot, "TP\n", return_str, MAXBUF) == RIG_OK)
|
2022-11-26 00:04:36 +00:00
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
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);
|
2022-11-30 12:55:00 +00:00
|
|
|
*el = priv->el;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-11-30 14:00:29 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "PP Wrong Return String: %s\n", return_str);
|
2022-11-30 11:20:25 +00:00
|
|
|
return_value = -RIG_EPROTO;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
return return_value;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int flir_stop(ROT *rot)
|
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
int return_value = RIG_OK;
|
|
|
|
|
2022-11-26 00:04:36 +00:00
|
|
|
struct flir_priv_data *priv = (struct flir_priv_data *)
|
2022-12-09 04:37:22 +00:00
|
|
|
rot->state.priv;
|
2022-11-26 00:04:36 +00:00
|
|
|
azimuth_t az;
|
|
|
|
elevation_t el;
|
|
|
|
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
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);
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
priv->target_az = priv->az = az;
|
|
|
|
priv->target_el = priv->el = el;
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
return return_value;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int flir_park(ROT *rot)
|
|
|
|
{
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
/* Assume park Position is 0,90 */
|
|
|
|
flir_set_position(rot, 0, 90);
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int flir_reset(ROT *rot, rot_reset_t reset)
|
|
|
|
{
|
2022-11-30 11:20:25 +00:00
|
|
|
int return_value = RIG_OK;
|
2022-11-26 00:04:36 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
if (reset != 0)
|
|
|
|
{
|
2022-11-30 12:55:00 +00:00
|
|
|
return_value = flir_request(rot, "r\n", NULL, 0);
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
// After Reset: Disable Hard Limits
|
2022-12-09 04:37:22 +00:00
|
|
|
if (return_value == RIG_OK)
|
2022-11-30 11:20:25 +00:00
|
|
|
{
|
|
|
|
return_value = flir_request(rot, "LD\n", NULL, MAXBUF);
|
|
|
|
}
|
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-30 11:20:25 +00:00
|
|
|
return return_value;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int flir_move(ROT *rot, int direction, int speed)
|
|
|
|
{
|
|
|
|
struct flir_priv_data *priv = (struct flir_priv_data *)
|
2022-12-09 04:37:22 +00:00
|
|
|
rot->state.priv;
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2022-11-30 14:33:55 +00:00
|
|
|
char firmware_str[121];
|
|
|
|
char info_str[101];
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
struct flir_priv_data *priv = (struct flir_priv_data *)
|
2022-12-09 04:37:22 +00:00
|
|
|
rot->state.priv;
|
2022-11-30 11:20:25 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
sprintf(priv->info, "No Info");
|
2022-11-30 11:20:25 +00:00
|
|
|
|
2022-11-26 00:04:36 +00:00
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
2022-12-09 04:37:22 +00:00
|
|
|
|
|
|
|
if (flir_request(rot, "V\n", firmware_str, 120) != RIG_OK)
|
2022-11-30 11:20:25 +00:00
|
|
|
{
|
2022-11-30 14:33:55 +00:00
|
|
|
return "No Info available";
|
2022-11-30 11:20:25 +00:00
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-30 14:33:55 +00:00
|
|
|
hl_usleep(500000);
|
2022-12-09 04:37:22 +00:00
|
|
|
|
|
|
|
if (flir_request(rot, "O\n", info_str, 100) != RIG_OK)
|
2022-11-30 14:33:55 +00:00
|
|
|
{
|
|
|
|
return "No Info available";
|
|
|
|
}
|
2022-12-09 04:37:22 +00:00
|
|
|
|
2022-11-30 14:33:55 +00:00
|
|
|
sprintf(priv->info, "Firmware: %s\nPower: %s", firmware_str, info_str);
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
return priv->info;
|
2022-11-26 00:04:36 +00:00
|
|
|
}
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_set_func(ROT *rot, setting_t func, int status)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_get_func(ROT *rot, setting_t func, int *status)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_set_level(ROT *rot, setting_t level, value_t val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_get_level(ROT *rot, setting_t level, value_t *val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_set_ext_level(ROT *rot, token_t token, value_t val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_get_ext_level(ROT *rot, token_t token, value_t *val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_set_ext_func(ROT *rot, token_t token, int status)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_get_ext_func(ROT *rot, token_t token, int *status)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_set_parm(ROT *rot, setting_t parm, value_t val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_get_parm(ROT *rot, setting_t parm, value_t *val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_set_ext_parm(ROT *rot, token_t token, value_t val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
static int flir_get_ext_parm(ROT *rot, token_t token, value_t *val)
|
|
|
|
{
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
}
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
static int flir_get_status(ROT *rot, rot_status_t *status)
|
|
|
|
{
|
|
|
|
struct flir_priv_data *priv = (struct flir_priv_data *)
|
2022-12-09 04:37:22 +00:00
|
|
|
rot->state.priv;
|
2022-11-26 00:04:36 +00:00
|
|
|
*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",
|
2022-11-30 11:20:25 +00:00
|
|
|
.status = RIG_STATUS_ALPHA,
|
2022-11-26 00:04:36 +00:00
|
|
|
.rot_type = ROT_TYPE_AZEL,
|
2022-11-30 11:20:25 +00:00
|
|
|
.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,
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
.min_az = -180.,
|
2022-11-30 11:20:25 +00:00
|
|
|
.max_az = 180.,
|
2022-11-26 00:04:36 +00:00
|
|
|
.min_el = 0.,
|
|
|
|
.max_el = 90.,
|
|
|
|
|
|
|
|
.priv = NULL, /* priv */
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
.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),
|
2022-11-26 00:04:36 +00:00
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
.level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } },
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
.has_status = FLIR_STATUS,
|
|
|
|
|
|
|
|
.rot_init = flir_init,
|
|
|
|
.rot_cleanup = flir_cleanup,
|
|
|
|
.rot_open = flir_open,
|
|
|
|
.rot_close = flir_close,
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
.set_conf = flir_set_conf,
|
|
|
|
.get_conf = flir_get_conf,
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
.set_position = flir_set_position,
|
|
|
|
.get_position = flir_get_position,
|
|
|
|
.park = flir_park,
|
|
|
|
.stop = flir_stop,
|
|
|
|
.reset = flir_reset,
|
|
|
|
.move = flir_move,
|
|
|
|
|
2022-11-30 12:55:00 +00:00
|
|
|
.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,
|
2022-11-26 00:04:36 +00:00
|
|
|
|
|
|
|
.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;
|
|
|
|
}
|