Initial release

git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@1843 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.3
Stéphane Fillod, F8CFE 2004-09-12 21:30:21 +00:00
rodzic 5375dcfd4c
commit 7851a4eca9
13 zmienionych plików z 2139 dodań i 0 usunięć

Wyświetl plik

@ -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

143
racal/ra6790.c 100644
Wyświetl plik

@ -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
*/

474
racal/racal.c 100644
Wyświetl plik

@ -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;
}

57
racal/racal.h 100644
Wyświetl plik

@ -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 */

Wyświetl plik

@ -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

42
tuner/tuner.c 100644
Wyświetl plik

@ -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;
}

41
tuner/tuner.h 100644
Wyświetl plik

@ -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 */

394
tuner/v4l.c 100644
Wyświetl plik

@ -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 */

348
tuner/videodev.h 100644
Wyświetl plik

@ -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 */

8
wj/Makefile.am 100644
Wyświetl plik

@ -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

407
wj/wj.c 100644
Wyświetl plik

@ -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;
}

56
wj/wj.h 100644
Wyświetl plik

@ -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 */

153
wj/wj8888.c 100644
Wyświetl plik

@ -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
*/