kopia lustrzana https://github.com/Hamlib/Hamlib
rodzic
403ec07b6b
commit
bbda209fc0
|
@ -0,0 +1,12 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := expert.c
|
||||
LOCAL_MODULE := expoert
|
||||
|
||||
LOCAL_CFLAGS :=
|
||||
LOCAL_C_INCLUDES := android include src
|
||||
LOCAL_LDLIBS := -lhamlib
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
|
@ -0,0 +1,8 @@
|
|||
SRC = expert.c
|
||||
|
||||
EXPERTSRC = expert.h
|
||||
|
||||
noinst_LTLIBRARIES = libhamlib-expert.la
|
||||
libhamlib_expert_la_SOURCES = $(SRC) $(EXPERTSRC)
|
||||
|
||||
EXTRA_DIST = README.expert Android.mk
|
|
@ -0,0 +1,7 @@
|
|||
hamlib - Copyright (C) 2023 The Hamlib Group
|
||||
|
||||
File: README.expert
|
||||
|
||||
Notes on Expert backends
|
||||
|
||||
2023-03-20 Initial prototype for Expert amplifiers
|
|
@ -0,0 +1,734 @@
|
|||
/*
|
||||
* Hamlib Expert amplifier backend - low level communication routines
|
||||
* Copyright (c) 2023 by Michael Black W9MDB
|
||||
*
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "expert.h"
|
||||
#include "register.h"
|
||||
|
||||
struct fault_list
|
||||
{
|
||||
int code;
|
||||
char *errmsg;
|
||||
};
|
||||
const struct fault_list expert_fault_list [] =
|
||||
{
|
||||
{0, "No fault condition"},
|
||||
{0x10, "Watchdog Timer was reset"},
|
||||
{0x20, "PA Current is too high"},
|
||||
{0x40, "Temperature is too high"},
|
||||
{0x60, "Input power is too high"},
|
||||
{0x61, "Gain is too low"},
|
||||
{0x70, "Invalid frequency"},
|
||||
{0x80, "50V supply voltage too low or too high"},
|
||||
{0x81, "5V supply voltage too low or too high"},
|
||||
{0x82, "10V supply voltage too low or too high"},
|
||||
{0x83, "12V supply voltage too low or too high"},
|
||||
{0x84, "-12V supply voltage too low or too high"},
|
||||
{0x85, "5V or 400V LPF board supply voltages not detected"},
|
||||
{0x90, "Reflected power is too high"},
|
||||
{0x91, "SWR very high"},
|
||||
{0x92, "ATU no match"},
|
||||
{0xB0, "Dissipated power too high"},
|
||||
{0xC0, "Forward power too high"},
|
||||
{0xE0, "Forward power too high for current setting"},
|
||||
{0xF0, "Gain is too high"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize data structures
|
||||
*/
|
||||
|
||||
int expert_init(AMP *amp)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
amp->state.priv = (struct expert_priv_data *)
|
||||
calloc(1, sizeof(struct expert_priv_data));
|
||||
|
||||
if (!amp->state.priv)
|
||||
{
|
||||
return -RIG_ENOMEM;
|
||||
}
|
||||
|
||||
amp->state.ampport.type.rig = RIG_PORT_SERIAL;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int expert_close(AMP *amp)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (amp->state.priv) { free(amp->state.priv); }
|
||||
|
||||
amp->state.priv = NULL;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int expert_flushbuffer(AMP *amp)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
rs = &->state;
|
||||
|
||||
return rig_flush(&rs->ampport);
|
||||
}
|
||||
|
||||
int expert_transaction(AMP *amp, const char *cmd, char *response, int response_len)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
int err;
|
||||
int len = 0;
|
||||
int loop;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%s\n", __func__, cmd);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
expert_flushbuffer(amp);
|
||||
|
||||
rs = &->state;
|
||||
|
||||
loop = 3;
|
||||
|
||||
do // wake up the amp by sending ; until we receive ;
|
||||
{
|
||||
char c = ';';
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s waiting for ;\n", __func__);
|
||||
err = write_block(&rs->ampport, (unsigned char *) &c, 1);
|
||||
|
||||
if (err != RIG_OK) { return err; }
|
||||
|
||||
len = read_string(&rs->ampport, (unsigned char *) response, response_len, ";",
|
||||
1, 0, 1);
|
||||
|
||||
if (len < 0) { return len; }
|
||||
}
|
||||
while (--loop > 0 && (len != 1 || response[0] != ';'));
|
||||
|
||||
// Now send our command
|
||||
err = write_block(&rs->ampport, (unsigned char *) cmd, strlen(cmd));
|
||||
|
||||
if (err != RIG_OK) { return err; }
|
||||
|
||||
if (response) // if response expected get it
|
||||
{
|
||||
response[0] = 0;
|
||||
len = read_string(&rs->ampport, (unsigned char *) response, response_len, ";",
|
||||
1, 0, 1);
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, error=%s\n", __func__,
|
||||
rigerror(len));
|
||||
return len;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, response='%s'\n", __func__,
|
||||
response);
|
||||
}
|
||||
else // if no response expected try to get one
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
responsebuf[0] = 0;
|
||||
loop = 3;
|
||||
|
||||
do
|
||||
{
|
||||
char c = ';';
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s waiting for ;\n", __func__);
|
||||
err = write_block(&rs->ampport, (unsigned char *) &c, 1);
|
||||
|
||||
if (err != RIG_OK) { return err; }
|
||||
|
||||
len = read_string(&rs->ampport, (unsigned char *) responsebuf, KPABUFSZ, ";", 1,
|
||||
0, 1);
|
||||
|
||||
if (len < 0) { return len; }
|
||||
}
|
||||
while (--loop > 0 && (len != 1 || responsebuf[0] != ';'));
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Info
|
||||
* returns the model name string
|
||||
*/
|
||||
const char *expert_get_info(AMP *amp)
|
||||
{
|
||||
const struct amp_caps *rc;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp) { return (const char *) - RIG_EINVAL; }
|
||||
|
||||
rc = amp->caps;
|
||||
|
||||
return rc->model_name;
|
||||
}
|
||||
|
||||
int expert_get_freq(AMP *amp, freq_t *freq)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
int retval;
|
||||
unsigned long tfreq;
|
||||
int nargs;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
retval = expert_transaction(amp, "^FR;", responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
nargs = sscanf(responsebuf, "^FR%lu", &tfreq);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^FR response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
*freq = tfreq * 1000;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int expert_set_freq(AMP *amp, freq_t freq)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
int retval;
|
||||
unsigned long tfreq;
|
||||
int nargs;
|
||||
char cmd[KPABUFSZ];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, freq=%"PRIfreq"\n", __func__, freq);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
SNPRINTF(cmd, sizeof(cmd), "^FR%05ld;", (long)freq / 1000);
|
||||
retval = expert_transaction(amp, cmd, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
nargs = sscanf(responsebuf, "^FR%lu", &tfreq);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s Error: ^FR response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
if (tfreq * 1000 != freq)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s Error setting freq: ^FR freq!=freq2, %f=%lu '%s'\n", __func__,
|
||||
freq, tfreq * 1000, responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int expert_get_level(AMP *amp, setting_t level, value_t *val)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
char *cmd;
|
||||
int retval;
|
||||
int fault;
|
||||
int i;
|
||||
int nargs;
|
||||
int antenna;
|
||||
int pwrpeak;
|
||||
int pwrref;
|
||||
int pwrfwd;
|
||||
int pwrinput;
|
||||
float float_value = 0;
|
||||
int int_value = 0, int_value2 = 0;
|
||||
struct amp_state *rs = &->state;
|
||||
struct expert_priv_data *priv = amp->state.priv;
|
||||
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
// get the current antenna selected
|
||||
cmd = "^AE;";
|
||||
retval = expert_transaction(amp, cmd, responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
antenna = 0;
|
||||
nargs = sscanf(responsebuf, "^AE%d", &antenna);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, antenna=%d\n", __func__, cmd,
|
||||
antenna);
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case AMP_LEVEL_SWR:
|
||||
cmd = "^SW;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_NH:
|
||||
cmd = "^DF;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PF:
|
||||
cmd = "^DF;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_INPUT:
|
||||
cmd = "^PWI;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_FWD:
|
||||
cmd = "^PWF;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_REFLECTED:
|
||||
cmd = "^PWR;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_PEAK:
|
||||
cmd = "^PWK;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_FAULT:
|
||||
cmd = "^SF;";
|
||||
break;
|
||||
}
|
||||
|
||||
retval = expert_transaction(amp, cmd, responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case AMP_LEVEL_SWR:
|
||||
nargs = sscanf(responsebuf, "^SW%f", &float_value);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->f = float_value / 10.0f;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_NH:
|
||||
case AMP_LEVEL_PF:
|
||||
nargs = sscanf(responsebuf, "^DF%d,%d", &int_value, &int_value2);
|
||||
|
||||
if (nargs != 2)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s freq range=%dKHz,%dKHz\n", __func__,
|
||||
int_value, int_value2);
|
||||
|
||||
//
|
||||
do
|
||||
{
|
||||
retval = read_string(&rs->ampport, (unsigned char *) responsebuf,
|
||||
sizeof(responsebuf), ";", 1, 0,
|
||||
1);
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
if (strstr(responsebuf, "BYPASS") != 0)
|
||||
{
|
||||
int antenna2 = 0;
|
||||
nargs = sscanf(responsebuf, "AN%d Side TX %d %*s %*s %d", &antenna2, &int_value,
|
||||
&int_value2);
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s response='%s'\n", __func__, responsebuf);
|
||||
|
||||
if (nargs != 3)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s antenna=%d,nH=%d\n", __func__, antenna2,
|
||||
int_value);
|
||||
|
||||
val->i = level == AMP_LEVEL_NH ? int_value : int_value2;
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
while (strstr(responsebuf, "BYPASS"));
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case AMP_LEVEL_PWR_INPUT:
|
||||
cmd = "^PWI;";
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrinput);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrinput;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_FWD:
|
||||
cmd = "^PWF;";
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrfwd);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrfwd;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_REFLECTED:
|
||||
cmd = "^PWR;";
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrref);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrref;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_PEAK:
|
||||
cmd = "^PWK;";
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrpeak);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrpeak;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_FAULT:
|
||||
cmd = "^SF;";
|
||||
nargs = sscanf(responsebuf, "^SW%d", &fault);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
for (i = 0; expert_fault_list[i].errmsg != NULL; ++i)
|
||||
{
|
||||
if (expert_fault_list[i].code == fault)
|
||||
{
|
||||
val->s = expert_fault_list[i].errmsg;
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_ERR, "%s unknown fault from %s\n", __func__, responsebuf);
|
||||
SNPRINTF(priv->tmpbuf, sizeof(priv->tmpbuf), "Unknown fault code=0x%02x",
|
||||
fault);
|
||||
val->s = priv->tmpbuf;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s unknown level=%s\n", __func__,
|
||||
rig_strlevel(level));
|
||||
|
||||
}
|
||||
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
int expert_get_powerstat(AMP *amp, powerstat_t *status)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
int retval;
|
||||
int operate;
|
||||
int ampon;
|
||||
int nargs;
|
||||
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
*status = RIG_POWER_UNKNOWN;
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
retval = expert_transaction(amp, "^ON;", responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
nargs = sscanf(responsebuf, "^ON%d", &on);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
switch (ampon)
|
||||
{
|
||||
case 0: *status = RIG_POWER_OFF; return RIG_OK;
|
||||
|
||||
case 1: *status = RIG_POWER_ON; break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON unknown response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
retval = expert_transaction(amp, "^OP;", responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
nargs = sscanf(responsebuf, "^ON%d", &operate);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
*status = operate == 1 ? RIG_POWER_OPERATE : RIG_POWER_STANDBY;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int expert_set_powerstat(AMP *amp, powerstat_t status)
|
||||
{
|
||||
int retval;
|
||||
char *cmd = NULL;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case RIG_POWER_UNKNOWN: break;
|
||||
|
||||
case RIG_POWER_OFF: cmd = "^ON0;"; break;
|
||||
|
||||
case RIG_POWER_ON: cmd = "^ON1;"; break;
|
||||
|
||||
case RIG_POWER_OPERATE: cmd = "^OS1;"; break;
|
||||
|
||||
case RIG_POWER_STANDBY: cmd = "^OS0;"; break;
|
||||
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid status=%d\n", __func__, status);
|
||||
|
||||
}
|
||||
|
||||
retval = expert_transaction(amp, cmd, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int expert_reset(AMP *amp, amp_reset_t reset)
|
||||
{
|
||||
int retval;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
// toggling from standby to operate supposed to reset
|
||||
retval = expert_set_powerstat(amp, RIG_POWER_STANDBY);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error setting RIG_POWER_STANDBY '%s'\n", __func__,
|
||||
strerror(retval));
|
||||
|
||||
}
|
||||
|
||||
return expert_set_powerstat(amp, RIG_POWER_OPERATE);
|
||||
}
|
||||
|
||||
|
||||
struct expert_priv_data *expert_priv;
|
||||
/*
|
||||
* API local implementation
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Private helper function prototypes
|
||||
*/
|
||||
|
||||
//static int kpa1500_send_priv_cmd(AMP *amp, const char *cmd);
|
||||
//static int kpa1500_flush_buffer(AMP *amp);
|
||||
|
||||
/* *************************************
|
||||
*
|
||||
* Separate model capabilities
|
||||
*
|
||||
* *************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Expert 1.3K-FA, 1.5K-FA, and 2K-FA
|
||||
*/
|
||||
|
||||
const struct amp_caps kpa1500_amp_caps =
|
||||
{
|
||||
AMP_MODEL(AMP_MODEL_ELECRAFT_KPA1500),
|
||||
.model_name = "1.3K-FA/1.5K-FA/2K-FA",
|
||||
.mfg_name = "Expert",
|
||||
.version = "20230320.0",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_ALPHA,
|
||||
.amp_type = AMP_TYPE_OTHER,
|
||||
.port_type = RIG_PORT_SERIAL,
|
||||
.serial_rate_min = 9600,
|
||||
.serial_rate_max = 115200,
|
||||
.serial_data_bits = 8,
|
||||
.serial_stop_bits = 1,
|
||||
.serial_parity = RIG_PARITY_NONE,
|
||||
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||
.write_delay = 0,
|
||||
.post_write_delay = 0,
|
||||
.timeout = 2000,
|
||||
.retry = 2,
|
||||
.has_get_level = AMP_LEVEL_SWR | AMP_LEVEL_NH | AMP_LEVEL_PF | AMP_LEVEL_PWR_INPUT | AMP_LEVEL_PWR_FWD | AMP_LEVEL_PWR_REFLECTED | AMP_LEVEL_FAULT,
|
||||
.has_set_level = 0,
|
||||
|
||||
.amp_open = NULL,
|
||||
.amp_init = expert_init,
|
||||
.amp_close = expert_close,
|
||||
.reset = expert_reset,
|
||||
.get_info = expert_get_info,
|
||||
.get_powerstat = expert_get_powerstat,
|
||||
.set_powerstat = expert_set_powerstat,
|
||||
.set_freq = expert_set_freq,
|
||||
.get_freq = expert_get_freq,
|
||||
.get_level = expert_get_level,
|
||||
};
|
||||
|
||||
|
||||
/* ************************************
|
||||
*
|
||||
* API functions
|
||||
*
|
||||
* ************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#if 0 // not implemented yet
|
||||
/*
|
||||
* Send command string to amplifier
|
||||
*/
|
||||
|
||||
static int kpa1500_send_priv_cmd(AMP *amp, const char *cmdstr)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
int err;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs = &->state;
|
||||
err = write_block(&rs->ampport, cmdstr, strlen(cmdstr));
|
||||
|
||||
if (err != RIG_OK)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize backend
|
||||
*/
|
||||
|
||||
DECLARE_INITAMP_BACKEND(expert)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
amp_register(&expert_amp_caps);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hamlib backend library for the Expert amplifier set.
|
||||
*
|
||||
* expert.h - (C) Michael Black W9MDB 2023
|
||||
*
|
||||
* This shared library provides an API for communicating
|
||||
* via serial interface to Expert amplifiers.
|
||||
*
|
||||
*
|
||||
* 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 _AMP_EXPERT_H
|
||||
#define _AMP_EXPERT_H 1
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
#include <iofunc.h>
|
||||
#include <serial.h>
|
||||
|
||||
// Is this big enough?
|
||||
#define KPABUFSZ 100
|
||||
|
||||
extern const struct amp_caps expert_amp_caps;
|
||||
|
||||
/*
|
||||
* Private data structure
|
||||
*/
|
||||
struct expert_priv_data
|
||||
{
|
||||
char tmpbuf[256]; // for unknown error msg
|
||||
};
|
||||
|
||||
|
||||
int expert_init(AMP *amp);
|
||||
int expert_close(AMP *amp);
|
||||
int expert_reset(AMP *amp, amp_reset_t reset);
|
||||
int expert_flush_buffer(AMP *amp);
|
||||
int expert_transaction(AMP *amp, const char *cmd, char *response,
|
||||
int response_len);
|
||||
const char *expert_get_info(AMP *amp);
|
||||
int expert_get_freq(AMP *amp, freq_t *freq);
|
||||
int expert_set_freq(AMP *amp, freq_t freq);
|
||||
|
||||
int expert_get_level(AMP *amp, setting_t level, value_t *val);
|
||||
int expert_get_powerstat(AMP *amp, powerstat_t *status);
|
||||
int expert_set_powerstat(AMP *amp, powerstat_t status);
|
||||
|
||||
#endif /* _AMP_EXPERT_H */
|
||||
|
|
@ -55,6 +55,7 @@ static int rotorez_rot_set_position(ROT *rot, azimuth_t azimuth,
|
|||
elevation_t elevation);
|
||||
static int rotorez_rot_get_position(ROT *rot, azimuth_t *azimuth,
|
||||
elevation_t *elevation);
|
||||
static int rotorez_park(ROT *rot);
|
||||
static int erc_rot_get_position(ROT *rot, azimuth_t *azimuth,
|
||||
elevation_t *elevation);
|
||||
static int rt21_rot_get_position(ROT *rot, azimuth_t *azimuth,
|
||||
|
@ -129,7 +130,7 @@ const struct rot_caps rotorez_rot_caps =
|
|||
ROT_MODEL(ROT_MODEL_ROTOREZ),
|
||||
.model_name = "Rotor-EZ",
|
||||
.mfg_name = "Idiom Press",
|
||||
.version = "20220109.0",
|
||||
.version = "20230328.0",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_STABLE,
|
||||
.rot_type = ROT_TYPE_OTHER,
|
||||
|
@ -157,6 +158,7 @@ const struct rot_caps rotorez_rot_caps =
|
|||
.rot_cleanup = rotorez_rot_cleanup,
|
||||
.set_position = rotorez_rot_set_position,
|
||||
.get_position = rotorez_rot_get_position,
|
||||
.park = rotorez_park,
|
||||
.stop = rotorez_rot_stop,
|
||||
.set_conf = rotorez_rot_set_conf,
|
||||
.get_info = rotorez_rot_get_info,
|
||||
|
@ -174,7 +176,7 @@ const struct rot_caps rotorcard_rot_caps =
|
|||
ROT_MODEL(ROT_MODEL_ROTORCARD),
|
||||
.model_name = "RotorCard",
|
||||
.mfg_name = "Idiom Press",
|
||||
.version = "20100214.0",
|
||||
.version = "20230328.0",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_BETA,
|
||||
.rot_type = ROT_TYPE_OTHER,
|
||||
|
@ -202,6 +204,7 @@ const struct rot_caps rotorcard_rot_caps =
|
|||
.rot_cleanup = rotorez_rot_cleanup,
|
||||
.set_position = rotorez_rot_set_position,
|
||||
.get_position = rotorez_rot_get_position,
|
||||
.park = rotorez_park,
|
||||
.stop = rotorez_rot_stop,
|
||||
.set_conf = rotorez_rot_set_conf,
|
||||
.get_info = rotorez_rot_get_info,
|
||||
|
@ -218,7 +221,7 @@ const struct rot_caps dcu_rot_caps =
|
|||
ROT_MODEL(ROT_MODEL_DCU),
|
||||
.model_name = "DCU-1/DCU-1X",
|
||||
.mfg_name = "Hy-Gain",
|
||||
.version = "20100823.0",
|
||||
.version = "20230328.0",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_STABLE,
|
||||
.rot_type = ROT_TYPE_OTHER,
|
||||
|
@ -262,7 +265,7 @@ const struct rot_caps erc_rot_caps =
|
|||
ROT_MODEL(ROT_MODEL_ERC),
|
||||
.model_name = "ERC",
|
||||
.mfg_name = "DF9GR",
|
||||
.version = "20100823.2", /* second revision on 23 Aug 2010 */
|
||||
.version = "20230328.2", /* second revision on 23 Aug 2010 */
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_STABLE,
|
||||
.rot_type = ROT_TYPE_OTHER,
|
||||
|
@ -290,6 +293,7 @@ const struct rot_caps erc_rot_caps =
|
|||
.rot_cleanup = rotorez_rot_cleanup,
|
||||
.set_position = rotorez_rot_set_position,
|
||||
.get_position = erc_rot_get_position,
|
||||
.park = rotorez_park,
|
||||
.stop = dcu1_rot_stop,
|
||||
.reset = rotorez_rot_reset,
|
||||
// .stop = rotorez_rot_stop,
|
||||
|
@ -309,7 +313,7 @@ const struct rot_caps yrc1_rot_caps =
|
|||
ROT_MODEL(ROT_MODEL_YRC1),
|
||||
.model_name = "DCU2/DCU3/YRC-1",
|
||||
.mfg_name = "Hy-Gain",
|
||||
.version = "20100823.2",
|
||||
.version = "20230328.2",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_STABLE,
|
||||
.rot_type = ROT_TYPE_OTHER,
|
||||
|
@ -337,6 +341,7 @@ const struct rot_caps yrc1_rot_caps =
|
|||
.rot_cleanup = rotorez_rot_cleanup,
|
||||
.set_position = rotorez_rot_set_position,
|
||||
.get_position = erc_rot_get_position,
|
||||
.park = rotorez_park,
|
||||
.stop = dcu1_rot_stop,
|
||||
.reset = rotorez_rot_reset,
|
||||
// .stop = rotorez_rot_stop,
|
||||
|
@ -351,7 +356,7 @@ const struct rot_caps rt21_rot_caps =
|
|||
ROT_MODEL(ROT_MODEL_RT21),
|
||||
.model_name = "RT-21",
|
||||
.mfg_name = "Green Heron",
|
||||
.version = "20220104.0",
|
||||
.version = "20230328.0",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_STABLE,
|
||||
.rot_type = ROT_TYPE_OTHER,
|
||||
|
@ -379,6 +384,7 @@ const struct rot_caps rt21_rot_caps =
|
|||
.rot_cleanup = rotorez_rot_cleanup,
|
||||
.set_position = rt21_rot_set_position,
|
||||
.get_position = rt21_rot_get_position,
|
||||
.park = rotorez_park,
|
||||
.stop = rotorez_rot_stop,
|
||||
// .set_conf = rotorez_rot_set_conf,
|
||||
// .get_info = rotorez_rot_get_info,
|
||||
|
@ -1128,6 +1134,20 @@ static int rotorez_flush_buffer(ROT *rot)
|
|||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Moves to Home Position
|
||||
*/
|
||||
static int rotorez_park(ROT *rot)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
/* Assume home is 0,0 */
|
||||
rotorez_rot_set_position(rot, 0, 0);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Initialize backend
|
||||
|
|
Ładowanie…
Reference in New Issue