kopia lustrzana https://github.com/Hamlib/Hamlib
Initial release
git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@1843 7ae35d74-ebe9-4afe-98af-79ac388436b8Hamlib-1.2.3
rodzic
5375dcfd4c
commit
7851a4eca9
|
@ -0,0 +1,8 @@
|
||||||
|
RACALSRCLIST = ra6790.c
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = hamlib-racal.la
|
||||||
|
hamlib_racal_la_SOURCES = $(RACALSRCLIST) racal.c
|
||||||
|
hamlib_racal_la_LDFLAGS = -no-undefined -module -avoid-version
|
||||||
|
hamlib_racal_la_LIBADD = $(top_builddir)/src/libhamlib.la
|
||||||
|
|
||||||
|
noinst_HEADERS = racal.h
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Racal backend - RA6790 description
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: ra6790.c,v 1.1 2004-09-12 21:28:26 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <hamlib/rig.h>
|
||||||
|
#include "idx_builtin.h"
|
||||||
|
#include "racal.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: ISB */
|
||||||
|
#define RA6790_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AMS|RIG_MODE_FM)
|
||||||
|
|
||||||
|
#define RA6790_FUNC (RIG_FUNC_NONE)
|
||||||
|
|
||||||
|
#define RA6790_LEVEL_ALL (RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_IF)
|
||||||
|
|
||||||
|
#define RA6790_PARM_ALL (RIG_PARM_NONE)
|
||||||
|
|
||||||
|
#define RA6790_VFO (RIG_VFO_A)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ra6790 rig capabilities.
|
||||||
|
*
|
||||||
|
* Required A6A1 serial asynchronous interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const struct rig_caps ra6790_caps = {
|
||||||
|
.rig_model = RIG_MODEL_RA6790,
|
||||||
|
.model_name = "RA6790/GM",
|
||||||
|
.mfg_name = "Racal",
|
||||||
|
.version = "0.1",
|
||||||
|
.copyright = "LGPL",
|
||||||
|
.status = RIG_STATUS_UNTESTED,
|
||||||
|
.rig_type = RIG_TYPE_RECEIVER,
|
||||||
|
.ptt_type = RIG_PTT_NONE,
|
||||||
|
.dcd_type = RIG_DCD_NONE,
|
||||||
|
.port_type = RIG_PORT_SERIAL,
|
||||||
|
.serial_rate_min = 300,
|
||||||
|
.serial_rate_max = 9600,
|
||||||
|
.serial_data_bits = 7,
|
||||||
|
.serial_stop_bits = 2,
|
||||||
|
.serial_parity = RIG_PARITY_EVEN,
|
||||||
|
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||||
|
.write_delay = 0,
|
||||||
|
.post_write_delay = 10,
|
||||||
|
.timeout = 2000,
|
||||||
|
.retry = 3,
|
||||||
|
|
||||||
|
.has_get_func = RA6790_FUNC,
|
||||||
|
.has_set_func = RA6790_FUNC,
|
||||||
|
.has_get_level = RA6790_LEVEL_ALL,
|
||||||
|
.has_set_level = RIG_LEVEL_SET(RA6790_LEVEL_ALL),
|
||||||
|
.has_get_parm = RA6790_PARM_ALL,
|
||||||
|
.has_set_parm = RIG_PARM_SET(RA6790_PARM_ALL),
|
||||||
|
.vfo_ops = RIG_OP_NONE,
|
||||||
|
.preamp = { RIG_DBLST_END },
|
||||||
|
.attenuator = { RIG_DBLST_END },
|
||||||
|
.max_rit = Hz(0),
|
||||||
|
.max_xit = Hz(0),
|
||||||
|
.max_ifshift = kHz(8),
|
||||||
|
.targetable_vfo = 0,
|
||||||
|
.transceive = RIG_TRN_OFF,
|
||||||
|
.bank_qty = 0,
|
||||||
|
.chan_desc_sz = 0,
|
||||||
|
|
||||||
|
.chan_list = { RIG_CHAN_END, },
|
||||||
|
|
||||||
|
.rx_range_list1 = {
|
||||||
|
{kHz(500),MHz(30)-1,RA6790_MODES,-1,-1,RA6790_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
},
|
||||||
|
.tx_range_list1 = { RIG_FRNG_END, },
|
||||||
|
.rx_range_list2 = {
|
||||||
|
{kHz(500),MHz(30)-1,RA6790_MODES,-1,-1,RA6790_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
},
|
||||||
|
.tx_range_list2 = { RIG_FRNG_END, },
|
||||||
|
.tuning_steps = {
|
||||||
|
{RA6790_MODES,1},
|
||||||
|
RIG_TS_END,
|
||||||
|
},
|
||||||
|
/* mode/filter list, remember: order matters! */
|
||||||
|
.filters = {
|
||||||
|
/* at -3dB */
|
||||||
|
{RIG_MODE_SSB, kHz(2.55)}, /* BW2 */
|
||||||
|
{RA6790_MODES, Hz(300)}, /* BW1 */
|
||||||
|
{RA6790_MODES, kHz(1)}, /* BW2 */
|
||||||
|
{RA6790_MODES, kHz(3.2)}, /* BW3 */
|
||||||
|
{RA6790_MODES, kHz(6)}, /* BW4 */
|
||||||
|
{RA6790_MODES, kHz(20)}, /* BW5 */
|
||||||
|
{RA6790_MODES, 0}, /* accept any BW */
|
||||||
|
RIG_FLT_END,
|
||||||
|
},
|
||||||
|
|
||||||
|
.cfgparams = racal_cfg_params,
|
||||||
|
|
||||||
|
.rig_init = racal_init,
|
||||||
|
.rig_cleanup = racal_cleanup,
|
||||||
|
.rig_open = racal_open,
|
||||||
|
.rig_close = racal_close,
|
||||||
|
.set_conf = racal_set_conf,
|
||||||
|
.get_conf = racal_get_conf,
|
||||||
|
|
||||||
|
.set_freq = racal_set_freq,
|
||||||
|
.get_freq = racal_get_freq,
|
||||||
|
.set_mode = racal_set_mode,
|
||||||
|
.get_mode = racal_get_mode,
|
||||||
|
.set_level = racal_set_level,
|
||||||
|
.get_level = racal_get_level,
|
||||||
|
|
||||||
|
.reset = racal_reset,
|
||||||
|
.get_info = racal_get_info,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function definitions below
|
||||||
|
*/
|
||||||
|
|
|
@ -0,0 +1,474 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Racal backend - main file
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: racal.c,v 1.1 2004-09-12 21:28:26 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> /* String function definitions */
|
||||||
|
#include <unistd.h> /* UNIX standard function definitions */
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "hamlib/rig.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "cal.h"
|
||||||
|
#include "register.h"
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
#include "racal.h"
|
||||||
|
|
||||||
|
|
||||||
|
const struct confparams racal_cfg_params[] = {
|
||||||
|
{ TOK_RIGID, "receiver_id", "receiver ID", "receiver ID",
|
||||||
|
"0", RIG_CONF_NUMERIC, { .n = { 0, 99, 1 } }
|
||||||
|
},
|
||||||
|
{ RIG_CONF_END, NULL, }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define BUFSZ 32
|
||||||
|
|
||||||
|
#define SOM "$"
|
||||||
|
#define EOM "\x0d" /* CR */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* modes
|
||||||
|
*/
|
||||||
|
#define MD_AM 1
|
||||||
|
#define MD_FM 2
|
||||||
|
#define MD_MCW 3 /* variable BFO */
|
||||||
|
#define MD_CW 4 /* BFO center */
|
||||||
|
#define MD_ISB 5 /* option */
|
||||||
|
#define MD_LSB 6
|
||||||
|
#define MD_USB 7
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* racal_transaction
|
||||||
|
* We assume that rig!=NULL, rig->state!= NULL
|
||||||
|
*
|
||||||
|
* TODO: Status Response handling with G/T commands
|
||||||
|
*/
|
||||||
|
static int racal_transaction(RIG *rig, const char *cmd, char *data, int *data_len)
|
||||||
|
{
|
||||||
|
struct racal_priv_data *priv = (struct racal_priv_data*)rig->state.priv;
|
||||||
|
struct rig_state *rs = &rig->state;
|
||||||
|
char cmdbuf[BUFSZ+1];
|
||||||
|
int cmd_len;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
cmd_len = sprintf(cmdbuf, SOM "%d%s" EOM, priv->receiver_id, cmd);
|
||||||
|
|
||||||
|
serial_flush(&rs->rigport);
|
||||||
|
|
||||||
|
retval = write_block(&rs->rigport, cmdbuf, cmd_len);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
|
||||||
|
/* no data expected */
|
||||||
|
if (!data || !data_len) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = read_string(&rs->rigport, data, BUFSZ, EOM, strlen(EOM));
|
||||||
|
if (retval <= 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* strip CR from string
|
||||||
|
*/
|
||||||
|
if (data[retval-1] == '\x0d') {
|
||||||
|
data[--retval] = '\0'; /* chomp */
|
||||||
|
}
|
||||||
|
*data_len = retval;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int racal_init(RIG *rig)
|
||||||
|
{
|
||||||
|
struct racal_priv_data *priv;
|
||||||
|
|
||||||
|
if (!rig || !rig->caps)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
|
priv = (struct racal_priv_data*)malloc(sizeof(struct racal_priv_data));
|
||||||
|
if (!priv) {
|
||||||
|
/* whoops! memory shortage! */
|
||||||
|
return -RIG_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rig->state.priv = (void*)priv;
|
||||||
|
|
||||||
|
priv->receiver_id = 0;
|
||||||
|
priv->bfo = 0;
|
||||||
|
priv->threshold = 0;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
int racal_cleanup(RIG *rig)
|
||||||
|
{
|
||||||
|
if (!rig)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
|
if (rig->state.priv)
|
||||||
|
free(rig->state.priv);
|
||||||
|
rig->state.priv = NULL;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||||
|
*/
|
||||||
|
int racal_set_conf(RIG *rig, token_t token, const char *val)
|
||||||
|
{
|
||||||
|
struct racal_priv_data *priv = (struct racal_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
switch (token) {
|
||||||
|
case TOK_RIGID:
|
||||||
|
priv->receiver_id = atoi(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* assumes rig!=NULL,
|
||||||
|
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||||
|
* and val points to a buffer big enough to hold the conf value.
|
||||||
|
*/
|
||||||
|
int racal_get_conf(RIG *rig, token_t token, char *val)
|
||||||
|
{
|
||||||
|
struct racal_priv_data *priv = (struct racal_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
switch(token) {
|
||||||
|
case TOK_RIGID:
|
||||||
|
sprintf(val, "%d", priv->receiver_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* racal_open
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int racal_open(RIG *rig)
|
||||||
|
{
|
||||||
|
/* Set Receiver to remote control
|
||||||
|
*
|
||||||
|
* TODO: Perform the BITE routine (1mn!) at each open?
|
||||||
|
* TODO: "S5" request values of IF bandwidth filters found?
|
||||||
|
*/
|
||||||
|
return racal_transaction (rig, "S2", NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* racal_close
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int racal_close(RIG *rig)
|
||||||
|
{
|
||||||
|
/* Set Receiver to local control */
|
||||||
|
return racal_transaction (rig, "S1", NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* racal_set_freq
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int racal_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||||
|
{
|
||||||
|
char freqbuf[BUFSZ];
|
||||||
|
int freq_len;
|
||||||
|
|
||||||
|
freq_len = sprintf(freqbuf, "F%0g", (double)(freq/MHz(1)));
|
||||||
|
|
||||||
|
return racal_transaction (rig, freqbuf, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int racal_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
||||||
|
{
|
||||||
|
char freqbuf[BUFSZ];
|
||||||
|
int retval, len;
|
||||||
|
double f;
|
||||||
|
|
||||||
|
retval = racal_transaction (rig, "TF", freqbuf, &len);
|
||||||
|
if (retval < RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (len < 2 || freqbuf[0] != 'F')
|
||||||
|
return -RIG_EPROTO;
|
||||||
|
|
||||||
|
sscanf(freqbuf+1, "%lf", &f);
|
||||||
|
*freq = (freq_t)f * MHz(1);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* racal_set_mode
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int racal_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
|
{
|
||||||
|
struct racal_priv_data *priv = (struct racal_priv_data*)rig->state.priv;
|
||||||
|
int ra_mode;
|
||||||
|
char buf[BUFSZ];
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case RIG_MODE_CW: ra_mode = (priv->bfo!=0) ? MD_MCW:MD_CW; break;
|
||||||
|
case RIG_MODE_USB: ra_mode = MD_USB; break;
|
||||||
|
case RIG_MODE_LSB: ra_mode = MD_LSB; break;
|
||||||
|
case RIG_MODE_AM: ra_mode = MD_AM; break;
|
||||||
|
case RIG_MODE_AMS: ra_mode = MD_ISB; break; /* TBC */
|
||||||
|
case RIG_MODE_FM: ra_mode = MD_FM; break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %d\n",
|
||||||
|
__FUNCTION__, mode);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width == RIG_PASSBAND_NORMAL)
|
||||||
|
width = rig_passband_normal(rig, mode);
|
||||||
|
|
||||||
|
sprintf(buf, "D%dI%.f", ra_mode, (double)(width/kHz(1)));
|
||||||
|
|
||||||
|
return racal_transaction (rig, buf, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int racal_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||||
|
{
|
||||||
|
char resbuf[BUFSZ], *p;
|
||||||
|
int retval, len;
|
||||||
|
double f;
|
||||||
|
|
||||||
|
retval = racal_transaction (rig, "TDI", resbuf, &len);
|
||||||
|
if (retval < RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
p = strchr(resbuf, 'I');
|
||||||
|
if (len < 3 || resbuf[0] != 'D' || !p)
|
||||||
|
return -RIG_EPROTO;
|
||||||
|
|
||||||
|
switch (resbuf[1]-'0') {
|
||||||
|
case MD_MCW:
|
||||||
|
case MD_CW: *mode = RIG_MODE_CW; break;
|
||||||
|
case MD_LSB: *mode = RIG_MODE_LSB; break;
|
||||||
|
case MD_USB: *mode = RIG_MODE_USB; break;
|
||||||
|
case MD_ISB: *mode = RIG_MODE_AMS; break; /* TBC */
|
||||||
|
case MD_FM: *mode = RIG_MODE_FM; break;
|
||||||
|
case MD_AM: *mode = RIG_MODE_AM; break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %d\n",
|
||||||
|
__FUNCTION__, mode);
|
||||||
|
return -RIG_EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
sscanf(p+1, "%lf", &f);
|
||||||
|
*width = (pbwidth_t)(f * kHz(1));
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* racal_set_level
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int racal_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
||||||
|
{
|
||||||
|
struct racal_priv_data *priv = (struct racal_priv_data*)rig->state.priv;
|
||||||
|
char cmdbuf[BUFSZ];
|
||||||
|
int agc;
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case RIG_LEVEL_RF:
|
||||||
|
/* Manually set threshold */
|
||||||
|
sprintf(cmdbuf, "A%d", (int)(val.f*120));
|
||||||
|
priv->threshold = val.f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_IF:
|
||||||
|
sprintf(cmdbuf, "B%+0g", ((double)val.i)/kHz(1));
|
||||||
|
priv->bfo = val.i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_AGC:
|
||||||
|
switch (val.i) {
|
||||||
|
case RIG_AGC_FAST: agc = 1; break;
|
||||||
|
case RIG_AGC_MEDIUM: agc = 2; break;
|
||||||
|
case RIG_AGC_SLOW: agc = 3; break;
|
||||||
|
case RIG_AGC_USER: agc = 4; break;
|
||||||
|
default: return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
if (priv->threshold != 0 && agc != 4)
|
||||||
|
agc += 4; /* with manually set threshold */
|
||||||
|
sprintf(cmdbuf, "M%d", agc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR,"%s: unsupported %d\n",
|
||||||
|
__FUNCTION__, level);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return racal_transaction (rig, cmdbuf, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* racal_get_level
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int racal_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
||||||
|
{
|
||||||
|
struct racal_priv_data *priv = (struct racal_priv_data*)rig->state.priv;
|
||||||
|
char resbuf[BUFSZ];
|
||||||
|
int retval, len, att;
|
||||||
|
double f;
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case RIG_LEVEL_RF:
|
||||||
|
/* Manually set threshold */
|
||||||
|
retval = racal_transaction (rig, "TA", resbuf, &len);
|
||||||
|
if (retval < RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (len < 2 || resbuf[0] != 'A')
|
||||||
|
return -RIG_EPROTO;
|
||||||
|
|
||||||
|
sscanf(resbuf+1, "%d", &att);
|
||||||
|
|
||||||
|
val->f = priv->threshold = (float)att/120;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_IF:
|
||||||
|
retval = racal_transaction (rig, "TB", resbuf, &len);
|
||||||
|
if (retval < RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (len < 2 || resbuf[0] != 'B')
|
||||||
|
return -RIG_EPROTO;
|
||||||
|
|
||||||
|
sscanf(resbuf+1, "%lf", &f);
|
||||||
|
val->i = priv->bfo = (shortfreq_t)(f * kHz(1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_AGC:
|
||||||
|
retval = racal_transaction (rig, "TM", resbuf, &len);
|
||||||
|
if (retval < RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (len < 2 || resbuf[0] != 'M')
|
||||||
|
return -RIG_EPROTO;
|
||||||
|
|
||||||
|
switch (resbuf[1]-'0') {
|
||||||
|
case 1:
|
||||||
|
case 5: val->i = RIG_AGC_FAST; break;
|
||||||
|
case 2:
|
||||||
|
case 6: val->i = RIG_AGC_MEDIUM; break;
|
||||||
|
case 3:
|
||||||
|
case 7: val->i = RIG_AGC_SLOW; break;
|
||||||
|
case 4: val->i = RIG_AGC_USER; break;
|
||||||
|
default: return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR,"%s: Unsupported %d\n", __FUNCTION__, level);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||||
|
*/
|
||||||
|
int racal_reset(RIG *rig, reset_t reset)
|
||||||
|
{
|
||||||
|
/* Initiate BITE routine, takes 1 minute! */
|
||||||
|
return racal_transaction (rig, "S3", NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* racal_get_info(RIG *rig)
|
||||||
|
{
|
||||||
|
static char infobuf[64];
|
||||||
|
char bitebuf[BUFSZ];
|
||||||
|
char filterbuf[BUFSZ];
|
||||||
|
int res_len, retval;
|
||||||
|
|
||||||
|
/* get BITE results */
|
||||||
|
retval = racal_transaction (rig, "S6", bitebuf, &res_len);
|
||||||
|
if (retval < 0)
|
||||||
|
return "IO error";
|
||||||
|
if (bitebuf[1] == 'O' && bitebuf[2] == 'K') {
|
||||||
|
bitebuf[3] = '\0';
|
||||||
|
} else {
|
||||||
|
char *p = strstr(bitebuf, "END");
|
||||||
|
if (p)
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get filters */
|
||||||
|
retval = racal_transaction (rig, "S5", filterbuf, &res_len);
|
||||||
|
if (retval < 0)
|
||||||
|
strcpy(filterbuf,"IO error");
|
||||||
|
|
||||||
|
sprintf(infobuf, "BITE errors: %s, Filters: %s\n",
|
||||||
|
bitebuf+1, filterbuf);
|
||||||
|
|
||||||
|
return infobuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initrigs_racal is called by rig_backend_load
|
||||||
|
*/
|
||||||
|
DECLARE_INITRIG_BACKEND(racal)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "racal: _init called\n");
|
||||||
|
|
||||||
|
rig_register(&ra6790_caps);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Racal backend - main header
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: racal.h,v 1.1 2004-09-12 21:28:26 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RACAL_H
|
||||||
|
#define _RACAL_H 1
|
||||||
|
|
||||||
|
#include "hamlib/rig.h"
|
||||||
|
|
||||||
|
#define TOK_RIGID TOKEN_BACKEND(1)
|
||||||
|
|
||||||
|
extern const struct confparams racal_cfg_params[];
|
||||||
|
|
||||||
|
struct racal_priv_data {
|
||||||
|
unsigned receiver_id;
|
||||||
|
int bfo;
|
||||||
|
float threshold; /* attenuation */
|
||||||
|
};
|
||||||
|
|
||||||
|
int racal_set_conf(RIG *rig, token_t token, const char *val);
|
||||||
|
int racal_get_conf(RIG *rig, token_t token, char *val);
|
||||||
|
int racal_init(RIG *rig);
|
||||||
|
int racal_cleanup(RIG *rig);
|
||||||
|
int racal_open(RIG *rig);
|
||||||
|
int racal_close(RIG *rig);
|
||||||
|
|
||||||
|
int racal_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
|
||||||
|
int racal_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
|
||||||
|
int racal_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
|
||||||
|
int racal_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
|
||||||
|
int racal_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val);
|
||||||
|
int racal_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
|
||||||
|
int racal_reset(RIG *rig, reset_t reset);
|
||||||
|
const char* racal_get_info(RIG *rig);
|
||||||
|
|
||||||
|
extern const struct rig_caps ra6790_caps;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _RACAL_H */
|
|
@ -0,0 +1,8 @@
|
||||||
|
TUNERSRCLIST = v4l.c
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = hamlib-tuner.la
|
||||||
|
hamlib_tuner_la_SOURCES = $(TUNERSRCLIST) tuner.c
|
||||||
|
hamlib_tuner_la_LDFLAGS = -no-undefined -module -avoid-version
|
||||||
|
hamlib_tuner_la_LIBADD = $(top_builddir)/src/libhamlib.la
|
||||||
|
|
||||||
|
noinst_HEADERS = tuner.h videodev.h
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Tuner backend - main file
|
||||||
|
* Copyright (C) 2004 Stephane Fillodpab@users.sourceforge.net
|
||||||
|
*
|
||||||
|
* $Id: tuner.c,v 1.1 2004-09-12 21:30:21 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tuner.h" /* config.h */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "hamlib/rig.h"
|
||||||
|
#include "register.h"
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_INITRIG_BACKEND(tuner)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "tuner: _init called\n");
|
||||||
|
|
||||||
|
#ifdef V4L_IOCTL
|
||||||
|
rig_register(&v4l_caps);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Tuners backend - main header
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: tuner.h,v 1.1 2004-09-12 21:30:21 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TUNER_H
|
||||||
|
#define _TUNER_H 1
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* So far, only Linux has Video4Linux support through ioctl :)
|
||||||
|
* until someone port it to some other OS...
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_LINUX_IOCTL_H
|
||||||
|
#define V4L_IOCTL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "hamlib/rig.h"
|
||||||
|
|
||||||
|
extern const struct rig_caps v4l_caps;
|
||||||
|
|
||||||
|
#endif /* _TUNER_H */
|
|
@ -0,0 +1,394 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Tuner backend - Video4Linux description
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: v4l.c,v 1.1 2004-09-12 21:30:21 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> /* String function definitions */
|
||||||
|
#include <unistd.h> /* UNIX standard function definitions */
|
||||||
|
#include <math.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "hamlib/rig.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
#include "tuner.h" /* include config.h */
|
||||||
|
|
||||||
|
#ifdef V4L_IOCTL
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "idx_builtin.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define V4L_FUNC (RIG_FUNC_MUTE)
|
||||||
|
|
||||||
|
#define V4L_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RAWSTR)
|
||||||
|
|
||||||
|
#define V4L_PARM_ALL (RIG_PARM_NONE)
|
||||||
|
|
||||||
|
#define V4L_VFO (RIG_VFO_A)
|
||||||
|
|
||||||
|
/* FIXME: per card measures? */
|
||||||
|
#define V4L_STR_CAL { 2, { \
|
||||||
|
{ 0, -60 }, \
|
||||||
|
{ 65535, 60 }, \
|
||||||
|
} }
|
||||||
|
|
||||||
|
static int v4l_init(RIG *rig);
|
||||||
|
static int v4l_open(RIG *rig);
|
||||||
|
static int v4l_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
|
||||||
|
static int v4l_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
|
||||||
|
static int v4l_set_func(RIG *rig, vfo_t vfo, setting_t func, int status);
|
||||||
|
static int v4l_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status);
|
||||||
|
static int v4l_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val);
|
||||||
|
static int v4l_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
|
||||||
|
static const char *v4l_get_info(RIG *rig);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* v4l rig capabilities.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const struct rig_caps v4l_caps = {
|
||||||
|
.rig_model = RIG_MODEL_V4L,
|
||||||
|
.model_name = "BW/FM radio",
|
||||||
|
.mfg_name = "Video4Linux",
|
||||||
|
.version = "0.1",
|
||||||
|
.copyright = "LGPL",
|
||||||
|
.status = RIG_STATUS_UNTESTED,
|
||||||
|
.rig_type = RIG_TYPE_PCRECEIVER,
|
||||||
|
.ptt_type = RIG_PTT_NONE,
|
||||||
|
.dcd_type = RIG_DCD_NONE,
|
||||||
|
.port_type = RIG_PORT_DEVICE,
|
||||||
|
.serial_rate_min = 1200,
|
||||||
|
.serial_rate_max = 9600,
|
||||||
|
.serial_data_bits = 8,
|
||||||
|
.serial_stop_bits = 1,
|
||||||
|
.serial_parity = RIG_PARITY_NONE,
|
||||||
|
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||||
|
.write_delay = 0,
|
||||||
|
.post_write_delay = 0,
|
||||||
|
.timeout = 2000,
|
||||||
|
.retry = 1,
|
||||||
|
|
||||||
|
.has_get_func = V4L_FUNC,
|
||||||
|
.has_set_func = V4L_FUNC,
|
||||||
|
.has_get_level = V4L_LEVEL_ALL,
|
||||||
|
.has_set_level = RIG_LEVEL_SET(V4L_LEVEL_ALL),
|
||||||
|
.has_get_parm = V4L_PARM_ALL,
|
||||||
|
.has_set_parm = RIG_PARM_SET(V4L_PARM_ALL),
|
||||||
|
.vfo_ops = RIG_OP_NONE,
|
||||||
|
.level_gran = {
|
||||||
|
[LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 65535 } },
|
||||||
|
},
|
||||||
|
.preamp = { RIG_DBLST_END },
|
||||||
|
.attenuator = { RIG_DBLST_END },
|
||||||
|
.max_rit = Hz(0),
|
||||||
|
.max_xit = Hz(0),
|
||||||
|
.max_ifshift = Hz(0),
|
||||||
|
.targetable_vfo = 0,
|
||||||
|
.transceive = RIG_TRN_OFF,
|
||||||
|
.bank_qty = 0,
|
||||||
|
.chan_desc_sz = 0,
|
||||||
|
|
||||||
|
.chan_list = { RIG_CHAN_END, },
|
||||||
|
|
||||||
|
/* will be rewritten at runtime */
|
||||||
|
.rx_range_list1 = {
|
||||||
|
{MHz(87.9),MHz(108.9),RIG_MODE_WFM,-1,-1,V4L_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
},
|
||||||
|
.tx_range_list1 = { RIG_FRNG_END, },
|
||||||
|
.rx_range_list2 = {
|
||||||
|
{MHz(87.9),MHz(108.9),RIG_MODE_WFM,-1,-1,V4L_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
},
|
||||||
|
.tx_range_list2 = { RIG_FRNG_END, },
|
||||||
|
.tuning_steps = {
|
||||||
|
{RIG_MODE_WFM,100},
|
||||||
|
RIG_TS_END,
|
||||||
|
},
|
||||||
|
/* mode/filter list, remember: order matters! */
|
||||||
|
.filters = {
|
||||||
|
{RIG_MODE_WFM, kHz(230)}, /* guess */
|
||||||
|
{RIG_MODE_AM, kHz(8)}, /* guess */
|
||||||
|
RIG_FLT_END,
|
||||||
|
},
|
||||||
|
.str_cal = V4L_STR_CAL,
|
||||||
|
|
||||||
|
.rig_init = v4l_init,
|
||||||
|
.rig_open = v4l_open,
|
||||||
|
|
||||||
|
.set_freq = v4l_set_freq,
|
||||||
|
.get_freq = v4l_get_freq,
|
||||||
|
.set_func = v4l_set_func,
|
||||||
|
.get_func = v4l_get_func,
|
||||||
|
.set_level = v4l_set_level,
|
||||||
|
.get_level = v4l_get_level,
|
||||||
|
|
||||||
|
.get_info = v4l_get_info,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function definitions below
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "videodev.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFAULT_V4L_PATH "/dev/radio0"
|
||||||
|
|
||||||
|
int v4l_init(RIG *rig)
|
||||||
|
{
|
||||||
|
rig->state.rigport.type.rig = RIG_PORT_DEVICE;
|
||||||
|
strncpy(rig->state.rigport.pathname, DEFAULT_V4L_PATH, FILPATHLEN);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v4l_open(RIG *rig)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
struct video_tuner vt;
|
||||||
|
struct rig_state *rs = &rig->state;
|
||||||
|
double fact;
|
||||||
|
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
vt.tuner = i;
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGTUNER, &vt);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fact = (vt.flags & VIDEO_TUNER_LOW) == 0 ? 16 : 16000;
|
||||||
|
rs->rx_range_list[i].start = vt.rangelow/fact;
|
||||||
|
rs->rx_range_list[i].end = vt.rangehigh/fact;
|
||||||
|
rs->rx_range_list[i].modes = vt.rangehigh/fact < MHz(30) ? RIG_MODE_AM : RIG_MODE_WFM;
|
||||||
|
/* hack! hack! store the resolution in low_power! */
|
||||||
|
rs->rx_range_list[i].low_power = rint(fact);
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int v4l_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||||
|
{
|
||||||
|
struct rig_state *rs = &rig->state;
|
||||||
|
struct video_tuner vt;
|
||||||
|
const freq_range_t *range;
|
||||||
|
unsigned long f;
|
||||||
|
double fact;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* AM or WFM */
|
||||||
|
range = rig_get_range (rs->rx_range_list, freq, RIG_MODE_AM|RIG_MODE_WFM);
|
||||||
|
if (!range)
|
||||||
|
return -RIG_ECONF;
|
||||||
|
|
||||||
|
/* at this point, we are trying to tune to a frequency */
|
||||||
|
|
||||||
|
vt.tuner = (rs->rx_range_list-range)/sizeof(freq_range_t);
|
||||||
|
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCSTUNER, &vt); /* set tuner # */
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSTUNER: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
fact = range->low_power;
|
||||||
|
|
||||||
|
f = rint(freq * fact); /* rounding to nearest int */
|
||||||
|
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCSFREQ, &freq);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSFREQ: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v4l_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
||||||
|
{
|
||||||
|
struct rig_state *rs = &rig->state;
|
||||||
|
const freq_range_t *range;
|
||||||
|
unsigned long f;
|
||||||
|
double fact;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGFREQ, &f);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGFREQ: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: remember tuner and current *fact* */
|
||||||
|
range = rig_get_range (rs->rx_range_list, f/16, RIG_MODE_AM|RIG_MODE_WFM);
|
||||||
|
if (!range)
|
||||||
|
return -RIG_ECONF;
|
||||||
|
fact = range->low_power;
|
||||||
|
|
||||||
|
|
||||||
|
*freq = f/fact;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v4l_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
|
||||||
|
{
|
||||||
|
struct video_audio va;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch ( func ) {
|
||||||
|
case RIG_FUNC_MUTE:
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGAUDIO, &va);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
va.flags = status ? VIDEO_AUDIO_MUTE : 0;
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCSAUDIO, &va);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSAUDIO: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v4l_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status)
|
||||||
|
{
|
||||||
|
struct video_audio va;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch ( func ) {
|
||||||
|
case RIG_FUNC_MUTE:
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGAUDIO, &va);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
*status = (va.flags & VIDEO_AUDIO_MUTE) == VIDEO_AUDIO_MUTE ;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int v4l_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
||||||
|
{
|
||||||
|
struct video_audio va;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGAUDIO, &va);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( level ) {
|
||||||
|
case RIG_LEVEL_AF:
|
||||||
|
va.volume = val.f * 65535;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCSAUDIO, &va);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSAUDIO: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v4l_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
||||||
|
{
|
||||||
|
struct video_audio va;
|
||||||
|
struct video_tuner vt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch ( level ) {
|
||||||
|
case RIG_LEVEL_AF:
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGAUDIO, &va);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
val->f = (float)va.volume / 65535.;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_RAWSTR:
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGTUNER, &vt); /* get info */
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGTUNER: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -RIG_EIO;
|
||||||
|
}
|
||||||
|
val->i = vt.signal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: static buf does not allow reentrancy!
|
||||||
|
*/
|
||||||
|
const char *v4l_get_info(RIG *rig)
|
||||||
|
{
|
||||||
|
static struct video_tuner vt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
vt.tuner = 0;
|
||||||
|
ret = ioctl(rig->state.rigport.fd, VIDIOCGTUNER, &vt);
|
||||||
|
if (ret < 0) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGTUNER: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return "Get info failed";
|
||||||
|
}
|
||||||
|
return vt.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* V4L_IOCTL */
|
||||||
|
|
|
@ -0,0 +1,348 @@
|
||||||
|
/* This header is extracted from linux/videodev.h, approximately
|
||||||
|
version 2.6.0. We can't use linux/videodev.h directly because
|
||||||
|
it indirectly defines struct timespec, which is also defined
|
||||||
|
by the standard C library headers. Argh. -blp */
|
||||||
|
|
||||||
|
#ifndef FM_VIDEODEV_H
|
||||||
|
#define FM_VIDEODEV_H 1
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define VID_TYPE_CAPTURE 1 /* Can capture */
|
||||||
|
#define VID_TYPE_TUNER 2 /* Can tune */
|
||||||
|
#define VID_TYPE_TELETEXT 4 /* Does teletext */
|
||||||
|
#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
|
||||||
|
#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
|
||||||
|
#define VID_TYPE_CLIPPING 32 /* Can clip */
|
||||||
|
#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
|
||||||
|
#define VID_TYPE_SCALES 128 /* Scalable */
|
||||||
|
#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
|
||||||
|
#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
|
||||||
|
#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
|
||||||
|
#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
|
||||||
|
#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
|
||||||
|
#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
|
||||||
|
|
||||||
|
struct video_capability
|
||||||
|
{
|
||||||
|
char name[32];
|
||||||
|
int type;
|
||||||
|
int channels; /* Num channels */
|
||||||
|
int audios; /* Num audio devices */
|
||||||
|
int maxwidth; /* Supported width */
|
||||||
|
int maxheight; /* And height */
|
||||||
|
int minwidth; /* Supported width */
|
||||||
|
int minheight; /* And height */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct video_channel
|
||||||
|
{
|
||||||
|
int channel;
|
||||||
|
char name[32];
|
||||||
|
int tuners;
|
||||||
|
uint32_t flags;
|
||||||
|
#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
|
||||||
|
#define VIDEO_VC_AUDIO 2 /* Channel has audio */
|
||||||
|
uint16_t type;
|
||||||
|
#define VIDEO_TYPE_TV 1
|
||||||
|
#define VIDEO_TYPE_CAMERA 2
|
||||||
|
uint16_t norm; /* Norm set by channel */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_tuner
|
||||||
|
{
|
||||||
|
int tuner;
|
||||||
|
char name[32];
|
||||||
|
unsigned long rangelow, rangehigh; /* Tuner range */
|
||||||
|
uint32_t flags;
|
||||||
|
#define VIDEO_TUNER_PAL 1
|
||||||
|
#define VIDEO_TUNER_NTSC 2
|
||||||
|
#define VIDEO_TUNER_SECAM 4
|
||||||
|
#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
|
||||||
|
#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
|
||||||
|
#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
|
||||||
|
#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
|
||||||
|
#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
|
||||||
|
uint16_t mode; /* PAL/NTSC/SECAM/OTHER */
|
||||||
|
#define VIDEO_MODE_PAL 0
|
||||||
|
#define VIDEO_MODE_NTSC 1
|
||||||
|
#define VIDEO_MODE_SECAM 2
|
||||||
|
#define VIDEO_MODE_AUTO 3
|
||||||
|
uint16_t signal; /* Signal strength 16bit scale */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_picture
|
||||||
|
{
|
||||||
|
uint16_t brightness;
|
||||||
|
uint16_t hue;
|
||||||
|
uint16_t colour;
|
||||||
|
uint16_t contrast;
|
||||||
|
uint16_t whiteness; /* Black and white only */
|
||||||
|
uint16_t depth; /* Capture depth */
|
||||||
|
uint16_t palette; /* Palette in use */
|
||||||
|
#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
|
||||||
|
#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
|
||||||
|
#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
|
||||||
|
#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
|
||||||
|
#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
|
||||||
|
#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
|
||||||
|
#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
|
||||||
|
#define VIDEO_PALETTE_YUYV 8
|
||||||
|
#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
|
||||||
|
#define VIDEO_PALETTE_YUV420 10
|
||||||
|
#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
|
||||||
|
#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
|
||||||
|
#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
|
||||||
|
#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
|
||||||
|
#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
|
||||||
|
#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
|
||||||
|
#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
|
||||||
|
#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_audio
|
||||||
|
{
|
||||||
|
int audio; /* Audio channel */
|
||||||
|
uint16_t volume; /* If settable */
|
||||||
|
uint16_t bass, treble;
|
||||||
|
uint32_t flags;
|
||||||
|
#define VIDEO_AUDIO_MUTE 1
|
||||||
|
#define VIDEO_AUDIO_MUTABLE 2
|
||||||
|
#define VIDEO_AUDIO_VOLUME 4
|
||||||
|
#define VIDEO_AUDIO_BASS 8
|
||||||
|
#define VIDEO_AUDIO_TREBLE 16
|
||||||
|
#define VIDEO_AUDIO_BALANCE 32
|
||||||
|
char name[16];
|
||||||
|
#define VIDEO_SOUND_MONO 1
|
||||||
|
#define VIDEO_SOUND_STEREO 2
|
||||||
|
#define VIDEO_SOUND_LANG1 4
|
||||||
|
#define VIDEO_SOUND_LANG2 8
|
||||||
|
uint16_t mode;
|
||||||
|
uint16_t balance; /* Stereo balance */
|
||||||
|
uint16_t step; /* Step actual volume uses */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_clip
|
||||||
|
{
|
||||||
|
int32_t x,y;
|
||||||
|
int32_t width, height;
|
||||||
|
struct video_clip *next; /* For user use/driver use only */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_window
|
||||||
|
{
|
||||||
|
uint32_t x,y; /* Position of window */
|
||||||
|
uint32_t width,height; /* Its size */
|
||||||
|
uint32_t chromakey;
|
||||||
|
uint32_t flags;
|
||||||
|
struct video_clip *clips; /* Set only */
|
||||||
|
int clipcount;
|
||||||
|
#define VIDEO_WINDOW_INTERLACE 1
|
||||||
|
#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
|
||||||
|
#define VIDEO_CLIP_BITMAP -1
|
||||||
|
/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
|
||||||
|
#define VIDEO_CLIPMAP_SIZE (128 * 625)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_capture
|
||||||
|
{
|
||||||
|
uint32_t x,y; /* Offsets into image */
|
||||||
|
uint32_t width, height; /* Area to capture */
|
||||||
|
uint16_t decimation; /* Decimation divider */
|
||||||
|
uint16_t flags; /* Flags for capture */
|
||||||
|
#define VIDEO_CAPTURE_ODD 0 /* Temporal */
|
||||||
|
#define VIDEO_CAPTURE_EVEN 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_buffer
|
||||||
|
{
|
||||||
|
void *base;
|
||||||
|
int height,width;
|
||||||
|
int depth;
|
||||||
|
int bytesperline;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_mmap
|
||||||
|
{
|
||||||
|
unsigned int frame; /* Frame (0 - n) for double buffer */
|
||||||
|
int height,width;
|
||||||
|
unsigned int format; /* should be VIDEO_PALETTE_* */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct video_key
|
||||||
|
{
|
||||||
|
uint8_t key[8];
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define VIDEO_MAX_FRAME 32
|
||||||
|
|
||||||
|
struct video_mbuf
|
||||||
|
{
|
||||||
|
int size; /* Total memory to map */
|
||||||
|
int frames; /* Frames */
|
||||||
|
int offsets[VIDEO_MAX_FRAME];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define VIDEO_NO_UNIT (-1)
|
||||||
|
|
||||||
|
|
||||||
|
struct video_unit
|
||||||
|
{
|
||||||
|
int video; /* Video minor */
|
||||||
|
int vbi; /* VBI minor */
|
||||||
|
int radio; /* Radio minor */
|
||||||
|
int audio; /* Audio minor */
|
||||||
|
int teletext; /* Teletext minor */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vbi_format {
|
||||||
|
uint32_t sampling_rate; /* in Hz */
|
||||||
|
uint32_t samples_per_line;
|
||||||
|
uint32_t sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
|
||||||
|
int32_t start[2]; /* starting line for each frame */
|
||||||
|
uint32_t count[2]; /* count of lines for each frame */
|
||||||
|
uint32_t flags;
|
||||||
|
#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
|
||||||
|
#define VBI_INTERLACED 2 /* lines are interlaced */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* video_info is biased towards hardware mpeg encode/decode */
|
||||||
|
/* but it could apply generically to any hardware compressor/decompressor */
|
||||||
|
struct video_info
|
||||||
|
{
|
||||||
|
uint32_t frame_count; /* frames output since decode/encode began */
|
||||||
|
uint32_t h_size; /* current unscaled horizontal size */
|
||||||
|
uint32_t v_size; /* current unscaled veritcal size */
|
||||||
|
uint32_t smpte_timecode; /* current SMPTE timecode (for current GOP) */
|
||||||
|
uint32_t picture_type; /* current picture type */
|
||||||
|
uint32_t temporal_reference; /* current temporal reference */
|
||||||
|
uint8_t user_data[256]; /* user data last found in compressed stream */
|
||||||
|
/* user_data[0] contains user data flags, user_data[1] has count */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* generic structure for setting playback modes */
|
||||||
|
struct video_play_mode
|
||||||
|
{
|
||||||
|
int mode;
|
||||||
|
int p1;
|
||||||
|
int p2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* for loading microcode / fpga programming */
|
||||||
|
struct video_code
|
||||||
|
{
|
||||||
|
char loadwhat[16]; /* name or tag of file being passed */
|
||||||
|
int datasize;
|
||||||
|
uint8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
|
||||||
|
#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
|
||||||
|
#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
|
||||||
|
#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
|
||||||
|
#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
|
||||||
|
#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
|
||||||
|
#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
|
||||||
|
#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
|
||||||
|
#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
|
||||||
|
#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
|
||||||
|
#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
|
||||||
|
#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
|
||||||
|
#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
|
||||||
|
#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
|
||||||
|
#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
|
||||||
|
#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
|
||||||
|
#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
|
||||||
|
#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
|
||||||
|
#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
|
||||||
|
#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
|
||||||
|
#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */
|
||||||
|
#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */
|
||||||
|
#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */
|
||||||
|
#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */
|
||||||
|
#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */
|
||||||
|
#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */
|
||||||
|
#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */
|
||||||
|
#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
|
||||||
|
#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
|
||||||
|
|
||||||
|
|
||||||
|
#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
|
||||||
|
|
||||||
|
/* VIDIOCSWRITEMODE */
|
||||||
|
#define VID_WRITE_MPEG_AUD 0
|
||||||
|
#define VID_WRITE_MPEG_VID 1
|
||||||
|
#define VID_WRITE_OSD 2
|
||||||
|
#define VID_WRITE_TTX 3
|
||||||
|
#define VID_WRITE_CC 4
|
||||||
|
#define VID_WRITE_MJPEG 5
|
||||||
|
|
||||||
|
/* VIDIOCSPLAYMODE */
|
||||||
|
#define VID_PLAY_VID_OUT_MODE 0
|
||||||
|
/* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
|
||||||
|
#define VID_PLAY_GENLOCK 1
|
||||||
|
/* p1: 0 = OFF, 1 = ON */
|
||||||
|
/* p2: GENLOCK FINE DELAY value */
|
||||||
|
#define VID_PLAY_NORMAL 2
|
||||||
|
#define VID_PLAY_PAUSE 3
|
||||||
|
#define VID_PLAY_SINGLE_FRAME 4
|
||||||
|
#define VID_PLAY_FAST_FORWARD 5
|
||||||
|
#define VID_PLAY_SLOW_MOTION 6
|
||||||
|
#define VID_PLAY_IMMEDIATE_NORMAL 7
|
||||||
|
#define VID_PLAY_SWITCH_CHANNELS 8
|
||||||
|
#define VID_PLAY_FREEZE_FRAME 9
|
||||||
|
#define VID_PLAY_STILL_MODE 10
|
||||||
|
#define VID_PLAY_MASTER_MODE 11
|
||||||
|
/* p1: see below */
|
||||||
|
#define VID_PLAY_MASTER_NONE 1
|
||||||
|
#define VID_PLAY_MASTER_VIDEO 2
|
||||||
|
#define VID_PLAY_MASTER_AUDIO 3
|
||||||
|
#define VID_PLAY_ACTIVE_SCANLINES 12
|
||||||
|
/* p1 = first active; p2 = last active */
|
||||||
|
#define VID_PLAY_RESET 13
|
||||||
|
#define VID_PLAY_END_MARK 14
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define VID_HARDWARE_BT848 1
|
||||||
|
#define VID_HARDWARE_QCAM_BW 2
|
||||||
|
#define VID_HARDWARE_PMS 3
|
||||||
|
#define VID_HARDWARE_QCAM_C 4
|
||||||
|
#define VID_HARDWARE_PSEUDO 5
|
||||||
|
#define VID_HARDWARE_SAA5249 6
|
||||||
|
#define VID_HARDWARE_AZTECH 7
|
||||||
|
#define VID_HARDWARE_SF16MI 8
|
||||||
|
#define VID_HARDWARE_RTRACK 9
|
||||||
|
#define VID_HARDWARE_ZOLTRIX 10
|
||||||
|
#define VID_HARDWARE_SAA7146 11
|
||||||
|
#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */
|
||||||
|
#define VID_HARDWARE_RTRACK2 13
|
||||||
|
#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */
|
||||||
|
#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */
|
||||||
|
#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */
|
||||||
|
#define VID_HARDWARE_BROADWAY 17 /* Broadway project */
|
||||||
|
#define VID_HARDWARE_GEMTEK 18
|
||||||
|
#define VID_HARDWARE_TYPHOON 19
|
||||||
|
#define VID_HARDWARE_VINO 20 /* SGI Indy Vino */
|
||||||
|
#define VID_HARDWARE_CADET 21 /* Cadet radio */
|
||||||
|
#define VID_HARDWARE_TRUST 22 /* Trust FM Radio */
|
||||||
|
#define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */
|
||||||
|
#define VID_HARDWARE_CPIA 24
|
||||||
|
#define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */
|
||||||
|
#define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */
|
||||||
|
#define VID_HARDWARE_OV511 27
|
||||||
|
#define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */
|
||||||
|
#define VID_HARDWARE_W9966 29
|
||||||
|
#define VID_HARDWARE_SE401 30 /* SE401 USB webcams */
|
||||||
|
#define VID_HARDWARE_PWC 31 /* Philips webcams */
|
||||||
|
#define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */
|
||||||
|
#define VID_HARDWARE_CPIA2 33
|
||||||
|
#define VID_HARDWARE_VICAM 34
|
||||||
|
#define VID_HARDWARE_SF16FMR2 35
|
||||||
|
|
||||||
|
#endif /* videodev.h */
|
|
@ -0,0 +1,8 @@
|
||||||
|
WJSRCLIST = wj8888.c
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = hamlib-wj.la
|
||||||
|
hamlib_wj_la_SOURCES = $(WJSRCLIST) wj.c
|
||||||
|
hamlib_wj_la_LDFLAGS = -no-undefined -module -avoid-version
|
||||||
|
hamlib_wj_la_LIBADD = $(top_builddir)/src/libhamlib.la
|
||||||
|
|
||||||
|
noinst_HEADERS = wj.h
|
|
@ -0,0 +1,407 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Watkins-Johnson backend - main file
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: wj.c,v 1.1 2004-09-12 21:29:10 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h> /* String function definitions */
|
||||||
|
#include <unistd.h> /* UNIX standard function definitions */
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "hamlib/rig.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "cal.h"
|
||||||
|
#include "register.h"
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
#include "wj.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define CMDSZ 10
|
||||||
|
|
||||||
|
const struct confparams wj_cfg_params[] = {
|
||||||
|
{ TOK_RIGID, "receiver_id", "receiver ID", "receiver ID",
|
||||||
|
"0", RIG_CONF_NUMERIC, { .n = { 0, 15, 1 } }
|
||||||
|
},
|
||||||
|
{ RIG_CONF_END, NULL, }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* modes
|
||||||
|
*/
|
||||||
|
#define MD_AM 0
|
||||||
|
#define MD_FM 1
|
||||||
|
#define MD_CW 2
|
||||||
|
#define MD_VCW 3 /* BFO variable */
|
||||||
|
#define MD_ISB 4
|
||||||
|
#define MD_LSB 5
|
||||||
|
#define MD_USB 6
|
||||||
|
#define MD_AMNL 7
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wj_transaction
|
||||||
|
*
|
||||||
|
* I'm not sure how monitor protocol works, whether you have
|
||||||
|
* to send the full frame, or just the modal byte. --SF
|
||||||
|
*
|
||||||
|
* TODO: decode the whole reply, and maybe do some caching
|
||||||
|
*/
|
||||||
|
static int wj_transaction(RIG *rig, int monitor)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
unsigned char buf[CMDSZ] = { 0x8, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
unsigned char rxbuf[CMDSZ];
|
||||||
|
unsigned char freqbuf[4];
|
||||||
|
unsigned wj_agc, wj_mode, wj_width, wj_bfo, wj_rfgain;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (monitor)
|
||||||
|
buf[1] |= 0x40; /* Monitor+AGC dump */
|
||||||
|
else
|
||||||
|
buf[0] |= 0x40; /* Command */
|
||||||
|
|
||||||
|
buf[0] |= priv->receiver_id & 0x0f;
|
||||||
|
|
||||||
|
/* tuned frequency */
|
||||||
|
to_bcd_be(freqbuf, priv->freq/10, 7);
|
||||||
|
buf[1] |= freqbuf[0] & 0x3f;
|
||||||
|
buf[2] |= freqbuf[1]>>1;
|
||||||
|
buf[3] |= ((freqbuf[1]&0x1)<<6) | (freqbuf[2]>>2);
|
||||||
|
buf[4] |= ((freqbuf[2]&0x2)<<5) | (freqbuf[3]>>3);
|
||||||
|
|
||||||
|
/* gain mode */
|
||||||
|
switch (priv->agc.i) {
|
||||||
|
case RIG_AGC_SLOW: wj_agc = 0; break; /* slow, 2s */
|
||||||
|
case RIG_AGC_OFF: wj_agc = 1; break; /* "not used" */
|
||||||
|
case RIG_AGC_FAST: wj_agc = 2; break; /* normal, 0.1s */
|
||||||
|
case RIG_AGC_USER: wj_agc = 3; break; /* manual */
|
||||||
|
default: return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
buf[4] |= wj_agc & 0x1;
|
||||||
|
buf[5] |= (wj_agc & 0x2)<<5;
|
||||||
|
|
||||||
|
/* IF BW */
|
||||||
|
switch (priv->width) {
|
||||||
|
case 200:
|
||||||
|
case 1000: wj_width = 0; break; /* spare */
|
||||||
|
|
||||||
|
case 500: wj_width = 1; break;
|
||||||
|
case 2000: wj_width = 2; break;
|
||||||
|
case 4000: wj_width = 3; break;
|
||||||
|
case 8000: wj_width = 4; break;
|
||||||
|
|
||||||
|
case 3000:
|
||||||
|
case 6000:
|
||||||
|
case 12000:
|
||||||
|
case 16000: wj_width = 5; break; /* spare */
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
buf[5] |= (wj_width & 0x2)<<3;
|
||||||
|
|
||||||
|
/* Detection mode */
|
||||||
|
switch (priv->mode) {
|
||||||
|
case RIG_MODE_CW: wj_mode = (priv->ifshift.i!=0) ? MD_VCW:MD_CW; break;
|
||||||
|
case RIG_MODE_USB: wj_mode = MD_USB; break;
|
||||||
|
case RIG_MODE_LSB: wj_mode = MD_LSB; break;
|
||||||
|
case RIG_MODE_FM: wj_mode = MD_FM; break;
|
||||||
|
case RIG_MODE_AM: wj_mode = MD_AM; break;
|
||||||
|
case RIG_MODE_AMS: wj_mode = MD_ISB; break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %d\n",
|
||||||
|
__FUNCTION__, priv->mode);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
buf[5] |= wj_mode & 0x3;
|
||||||
|
|
||||||
|
/* BFO frequency, not sure though */
|
||||||
|
wj_bfo = (priv->ifshift.i/10) + 0x400; /* LSBit is 10Hz, +455kHz */
|
||||||
|
buf[6] |= (wj_bfo >> 5) & 0x3f;
|
||||||
|
buf[7] |= (wj_bfo & 0x1f) << 2;
|
||||||
|
|
||||||
|
/* RF gain */
|
||||||
|
wj_rfgain = (unsigned)(priv->rfgain.f * 0x7f);
|
||||||
|
buf[7] |= (wj_rfgain >> 6) & 0x1;
|
||||||
|
buf[8] |= (wj_rfgain & 0x3f) << 1;
|
||||||
|
|
||||||
|
/* buf[9]: not used if command byte, but must be transmitted */
|
||||||
|
|
||||||
|
serial_flush(&rig->state.rigport);
|
||||||
|
|
||||||
|
retval = write_block(&rig->state.rigport, buf, CMDSZ);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (monitor) {
|
||||||
|
/*
|
||||||
|
* Transceiver sends back ">"
|
||||||
|
*/
|
||||||
|
retval = read_block(&rig->state.rigport, rxbuf, CMDSZ);
|
||||||
|
if (retval < 0 || retval > CMDSZ)
|
||||||
|
return RIG_ERJCTED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: analyze back the reply, and fill in the priv struct
|
||||||
|
*/
|
||||||
|
priv->rawstr.i = rxbuf[9] & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wj_init(RIG *rig)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv;
|
||||||
|
|
||||||
|
if (!rig || !rig->caps)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
|
priv = (struct wj_priv_data*)malloc(sizeof(struct wj_priv_data));
|
||||||
|
if (!priv) {
|
||||||
|
/* whoops! memory shortage! */
|
||||||
|
return -RIG_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rig->state.priv = (void*)priv;
|
||||||
|
|
||||||
|
priv->receiver_id = 0;
|
||||||
|
priv->freq = kHz(500);
|
||||||
|
priv->mode = RIG_MODE_AM;
|
||||||
|
priv->width = kHz(8);
|
||||||
|
priv->agc.i = RIG_AGC_SLOW;
|
||||||
|
priv->rfgain.f = 1;
|
||||||
|
priv->ifshift.i = 0;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
int wj_cleanup(RIG *rig)
|
||||||
|
{
|
||||||
|
if (!rig)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
|
if (rig->state.priv)
|
||||||
|
free(rig->state.priv);
|
||||||
|
rig->state.priv = NULL;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||||
|
*/
|
||||||
|
int wj_set_conf(RIG *rig, token_t token, const char *val)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
switch (token) {
|
||||||
|
case TOK_RIGID:
|
||||||
|
priv->receiver_id = atoi(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* assumes rig!=NULL,
|
||||||
|
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||||
|
* and val points to a buffer big enough to hold the conf value.
|
||||||
|
*/
|
||||||
|
int wj_get_conf(RIG *rig, token_t token, char *val)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
switch(token) {
|
||||||
|
case TOK_RIGID:
|
||||||
|
sprintf(val, "%d", priv->receiver_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wj_set_freq
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int wj_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
priv->freq = freq;
|
||||||
|
|
||||||
|
return wj_transaction (rig, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wj_get_freq
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int wj_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
retval = wj_transaction (rig, 1);
|
||||||
|
if (retval == RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
*freq = priv->freq;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wj_set_mode
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int wj_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
priv->mode = mode;
|
||||||
|
|
||||||
|
if (width == RIG_PASSBAND_NORMAL)
|
||||||
|
width = rig_passband_normal(rig, mode);
|
||||||
|
|
||||||
|
priv->width = width;
|
||||||
|
|
||||||
|
return wj_transaction (rig, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wj_get_mode
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int wj_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
retval = wj_transaction (rig, 1);
|
||||||
|
if (retval == RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
*mode = priv->mode;
|
||||||
|
*width = priv->width;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wj_set_level
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int wj_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case RIG_LEVEL_IF:
|
||||||
|
priv->ifshift.i = val.i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_RF:
|
||||||
|
priv->rfgain.f = val.f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_AGC:
|
||||||
|
priv->agc.i = val.i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR,"%s: unsupported %d\n", __FUNCTION__, level);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wj_transaction (rig, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wj_get_level
|
||||||
|
* Assumes rig!=NULL
|
||||||
|
*/
|
||||||
|
int wj_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
||||||
|
{
|
||||||
|
struct wj_priv_data *priv = (struct wj_priv_data*)rig->state.priv;
|
||||||
|
int retval = RIG_OK;
|
||||||
|
|
||||||
|
retval = wj_transaction (rig, 1);
|
||||||
|
if (retval == RIG_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case RIG_LEVEL_RAWSTR:
|
||||||
|
val->i = priv->rawstr.i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_IF:
|
||||||
|
val->i = priv->ifshift.i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_RF:
|
||||||
|
val->f = priv->rfgain.f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_LEVEL_AGC:
|
||||||
|
val->i = priv->agc.i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR,"%s: Unsupported %d\n", __FUNCTION__, level);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initrigs_wj is called by rig_backend_load
|
||||||
|
*/
|
||||||
|
DECLARE_INITRIG_BACKEND(wj)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "wj: _init called\n");
|
||||||
|
|
||||||
|
rig_register(&wj8888_caps);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Watkins-Johnson backend - main header
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: wj.h,v 1.1 2004-09-12 21:29:10 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WJ_H
|
||||||
|
#define _WJ_H 1
|
||||||
|
|
||||||
|
#include <hamlib/rig.h>
|
||||||
|
|
||||||
|
#define TOK_RIGID TOKEN_BACKEND(1)
|
||||||
|
|
||||||
|
extern const struct confparams wj_cfg_params[];
|
||||||
|
|
||||||
|
struct wj_priv_data {
|
||||||
|
unsigned receiver_id;
|
||||||
|
freq_t freq;
|
||||||
|
rmode_t mode;
|
||||||
|
pbwidth_t width;
|
||||||
|
value_t agc;
|
||||||
|
value_t rfgain;
|
||||||
|
value_t ifshift;
|
||||||
|
value_t rawstr;
|
||||||
|
};
|
||||||
|
|
||||||
|
int wj_set_conf(RIG *rig, token_t token, const char *val);
|
||||||
|
int wj_get_conf(RIG *rig, token_t token, char *val);
|
||||||
|
int wj_init(RIG *rig);
|
||||||
|
int wj_cleanup(RIG *rig);
|
||||||
|
int wj_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
|
||||||
|
int wj_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
|
||||||
|
int wj_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
|
||||||
|
int wj_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
|
||||||
|
int wj_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val);
|
||||||
|
int wj_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
|
||||||
|
|
||||||
|
extern const struct rig_caps wj8888_caps;
|
||||||
|
|
||||||
|
#endif /* _WJ_H */
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Watkins-Johnson backend - WJ-8888 description
|
||||||
|
* Copyright (c) 2004 by Stephane Fillod
|
||||||
|
*
|
||||||
|
* $Id: wj8888.c,v 1.1 2004-09-12 21:29:10 fillods Exp $
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <hamlib/rig.h>
|
||||||
|
#include "idx_builtin.h"
|
||||||
|
#include "wj.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* modes: what about ISB(Idependant Sideband)? */
|
||||||
|
#define WJ8888_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_AMS)
|
||||||
|
|
||||||
|
#define WJ8888_FUNC (RIG_FUNC_NONE)
|
||||||
|
|
||||||
|
#define WJ8888_LEVEL (RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR)
|
||||||
|
|
||||||
|
#define WJ8888_VFO (RIG_VFO_A)
|
||||||
|
|
||||||
|
/* FIXME: real measures */
|
||||||
|
#define WJ8888_STR_CAL { 2, \
|
||||||
|
{ \
|
||||||
|
{ 0x00, -60 }, /* -115.5dBm .. -99.5dBm */ \
|
||||||
|
{ 0x7f, 60 } \
|
||||||
|
} }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WJ-8888 receiver capabilities.
|
||||||
|
*
|
||||||
|
* Needs async I/O board
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* TODO: BFO
|
||||||
|
*/
|
||||||
|
const struct rig_caps wj8888_caps = {
|
||||||
|
.rig_model = RIG_MODEL_WJ8888,
|
||||||
|
.model_name = "WJ-8888",
|
||||||
|
.mfg_name = "Watkins-Johnson",
|
||||||
|
.version = "0.1",
|
||||||
|
.copyright = "LGPL",
|
||||||
|
.status = RIG_STATUS_UNTESTED,
|
||||||
|
.rig_type = RIG_TYPE_RECEIVER,
|
||||||
|
.ptt_type = RIG_PTT_NONE,
|
||||||
|
.dcd_type = RIG_DCD_NONE,
|
||||||
|
.port_type = RIG_PORT_SERIAL,
|
||||||
|
.serial_rate_min = 75, /* jumper E26 */
|
||||||
|
.serial_rate_max = 9600, /* jumper E19 */
|
||||||
|
.serial_data_bits = 8,
|
||||||
|
.serial_stop_bits = 1, /* jumper between E5 & E6 */
|
||||||
|
.serial_parity = RIG_PARITY_NONE, /* no jumper between E3 & E4 */
|
||||||
|
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||||
|
.write_delay = 0,
|
||||||
|
.post_write_delay = 5, /* typical 5ms, max 15ms */
|
||||||
|
.timeout = 2000,
|
||||||
|
.retry = 3,
|
||||||
|
|
||||||
|
.has_get_func = WJ8888_FUNC,
|
||||||
|
.has_set_func = WJ8888_FUNC,
|
||||||
|
.has_get_level = WJ8888_LEVEL,
|
||||||
|
.has_set_level = RIG_LEVEL_SET(WJ8888_LEVEL),
|
||||||
|
.has_get_parm = RIG_PARM_NONE,
|
||||||
|
.has_set_parm = RIG_PARM_NONE,
|
||||||
|
.vfo_ops = RIG_OP_NONE,
|
||||||
|
.preamp = { RIG_DBLST_END },
|
||||||
|
.attenuator = { RIG_DBLST_END },
|
||||||
|
.level_gran = {
|
||||||
|
[LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 0x7f } },
|
||||||
|
},
|
||||||
|
.max_rit = Hz(0),
|
||||||
|
.max_xit = Hz(0),
|
||||||
|
.max_ifshift = kHz(8), /* IF at 455kHz */
|
||||||
|
.targetable_vfo = 0,
|
||||||
|
.transceive = RIG_TRN_OFF,
|
||||||
|
.bank_qty = 0,
|
||||||
|
.chan_desc_sz = 0,
|
||||||
|
.str_cal = WJ8888_STR_CAL,
|
||||||
|
|
||||||
|
.cfgparams = wj_cfg_params,
|
||||||
|
|
||||||
|
.chan_list = { RIG_CHAN_END, },
|
||||||
|
|
||||||
|
.rx_range_list1 = {
|
||||||
|
{kHz(500),MHz(30),WJ8888_MODES,-1,-1,WJ8888_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
},
|
||||||
|
.tx_range_list1 = { RIG_FRNG_END, },
|
||||||
|
.rx_range_list2 = {
|
||||||
|
{kHz(500),MHz(30),WJ8888_MODES,-1,-1,WJ8888_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
},
|
||||||
|
.tx_range_list2 = { RIG_FRNG_END, },
|
||||||
|
|
||||||
|
.tuning_steps = {
|
||||||
|
{WJ8888_MODES,10},
|
||||||
|
RIG_TS_END,
|
||||||
|
},
|
||||||
|
/* mode/filter list, remember: order matters! */
|
||||||
|
.filters = {
|
||||||
|
{WJ8888_MODES, kHz(2)},
|
||||||
|
{WJ8888_MODES, Hz(500)},
|
||||||
|
{WJ8888_MODES, kHz(4)},
|
||||||
|
{WJ8888_MODES, kHz(8)},
|
||||||
|
/* option (in spare, to be fixed) */
|
||||||
|
{WJ8888_MODES, Hz(200)},
|
||||||
|
{WJ8888_MODES, kHz(1)},
|
||||||
|
{WJ8888_MODES, kHz(3)},
|
||||||
|
{WJ8888_MODES, kHz(6)},
|
||||||
|
{WJ8888_MODES, kHz(12)},
|
||||||
|
{WJ8888_MODES, kHz(16)},
|
||||||
|
RIG_FLT_END,
|
||||||
|
},
|
||||||
|
|
||||||
|
.rig_init = wj_init,
|
||||||
|
.rig_cleanup = wj_cleanup,
|
||||||
|
.set_conf = wj_set_conf,
|
||||||
|
.get_conf = wj_get_conf,
|
||||||
|
|
||||||
|
.set_freq = wj_set_freq,
|
||||||
|
.get_freq = wj_get_freq,
|
||||||
|
.set_mode = wj_set_mode,
|
||||||
|
.get_mode = wj_get_mode,
|
||||||
|
.set_level = wj_set_level,
|
||||||
|
.get_level = wj_get_level,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function definitions below
|
||||||
|
*/
|
||||||
|
|
Ładowanie…
Reference in New Issue