FUNcube interface added by Stefano Speretta

Added FUNcube interface to Hamlib.  This is a basic FUNcube interface:
at the moment only frequency set/readout is supported.  From Stefano
Speretta <s.speretta@isispace.nl>.

git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@3026 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.13
Nate Bargmann, N0NB 2011-01-28 00:40:45 +00:00
rodzic bd20ccd356
commit 53dad4d957
7 zmienionych plików z 328 dodań i 8 usunięć

Wyświetl plik

@ -470,6 +470,7 @@
#define RIG_MODEL_PMSDR RIG_MAKE_MODEL(RIG_KIT, 10)
#define RIG_MODEL_SI570PICUSB RIG_MAKE_MODEL(RIG_KIT, 11) /* SoftRock Si570 PIC */
#define RIG_MODEL_SI570FIFISDRUSB RIG_MAKE_MODEL(RIG_KIT, 12) /* FiFi-SDR USB */
#define RIG_MODEL_FUNCUBEDONGLE RIG_MAKE_MODEL(RIG_KIT, 13) /* FunCUBE Dongle */
/*
* SW/FM/TV tuner cards supported by Video4Linux,*BSD, ..

Wyświetl plik

@ -2,7 +2,7 @@ AM_CFLAGS = @LIBUSB_CFLAGS@
# FIXME: compile usrp only if CXX available
KITSRCLIST = elektor304.c drt1.c dwt.c usrp.c elektor507.c \
dds60.c miniVNA.c si570avrusb.c
dds60.c miniVNA.c si570avrusb.c funcube.c
if HAVE_USRP
AM_CXXFLAGS = @USRP_CFLAGS@
@ -26,5 +26,5 @@ hamlib_kit_la_LIBADD = $(top_builddir)/lib/libmisc.la \
@MATH_LIBS@ \
$(top_builddir)/src/libhamlib.la
noinst_HEADERS = kit.h usrp_impl.h si570avrusb.h
noinst_HEADERS = kit.h usrp_impl.h si570avrusb.h funcube.h

262
kit/funcube.c 100644
Wyświetl plik

@ -0,0 +1,262 @@
/*
* Hamlib KIT backend - FUNcube Dongle USB tuner description
* Copyright (c) 2009-2010 by Stephane Fillod
*
* Derived from usbsoftrock-0.5:
* Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com)
*
* Author: Stefano Speretta, Innovative Solutions In Space BV
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU 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
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "hamlib/rig.h"
#include "token.h"
#include "kit.h"
/*
* Compile this model only if libusb is available
*/
#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
#include <errno.h>
#include <usb.h>
#include "funcube.h"
static int funcube_init(RIG *rig);
static int funcube_cleanup(RIG *rig);
static int funcube_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
static int funcube_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
static const char *funcube_get_info(RIG *rig);
static const struct confparams funcube_cfg_params[] = {
{ RIG_CONF_END, NULL, }
};
/*
* Common data struct
*/
struct funcube_priv_data {
int freq; /* Hz */
};
/*
* FunCUBE Dongle description
*
* Based on Jan Axelson HID examples
* http://www.lvr.com/
*
*/
const struct rig_caps funcube_caps = {
.rig_model = RIG_MODEL_FUNCUBEDONGLE,
.model_name = "FUNcube Dongle",
.mfg_name = "AMSAT-UK",
.version = "0.1",
.copyright = "GPL",
.status = RIG_STATUS_BETA,
.rig_type = RIG_TYPE_TUNER,
.ptt_type = RIG_PTT_RIG,
.dcd_type = RIG_DCD_NONE,
.port_type = RIG_PORT_USB,
.write_delay = 0,
.post_write_delay = 0,
.timeout = 1000,
.retry = 0,
.has_get_func = RIG_FUNC_NONE,
.has_set_func = RIG_FUNC_NONE,
.has_get_level = RIG_LEVEL_NONE,
.has_set_level = RIG_LEVEL_NONE,
.has_get_parm = RIG_PARM_NONE,
.has_set_parm = RIG_PARM_NONE,
.level_gran = {},
.parm_gran = {},
.ctcss_list = NULL,
.dcs_list = NULL,
.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, },
.rx_range_list1 = {
{MHz(50),MHz(2500),RIG_MODE_USB,-1,-1,RIG_VFO_A},
RIG_FRNG_END,
},
.tuning_steps = {
{RIG_MODE_USB,kHz(1)},
RIG_TS_END,
},
.filters = {
{RIG_MODE_USB, kHz(192)},
RIG_FLT_END,
},
.cfgparams = funcube_cfg_params,
.rig_init = funcube_init,
.rig_cleanup = funcube_cleanup,
.set_freq = funcube_set_freq,
.get_freq = funcube_get_freq,
.get_info = funcube_get_info,
};
int funcube_init(RIG *rig)
{
hamlib_port_t *rp = &rig->state.rigport;
struct funcube_priv_data *priv;
priv = (struct funcube_priv_data*)calloc(sizeof(struct funcube_priv_data), 1);
if (!priv) {
/* whoops! memory shortage! */
return -RIG_ENOMEM;
}
priv->freq = 0;
rp->parm.usb.vid = VID;
rp->parm.usb.pid = PID;
rp->parm.usb.conf = FUNCUBE_CONFIGURATION;
rp->parm.usb.iface = FUNCUBE_INTERFACE;
rp->parm.usb.alt = FUNCUBE_ALTERNATIVE_SETTING;
rp->parm.usb.vendor_name = VENDOR_NAME;
rp->parm.usb.product = PRODUCT_NAME;
rig->state.priv = (void*)priv;
return RIG_OK;
}
int funcube_cleanup(RIG *rig)
{
if (!rig)
return -RIG_EINVAL;
if (rig->state.priv)
free(rig->state.priv);
rig->state.priv = NULL;
return RIG_OK;
}
const char * funcube_get_info(RIG *rig)
{
static char buf[64];
struct usb_dev_handle *udh = rig->state.rigport.handle;
struct usb_device *q = usb_device(udh);
sprintf(buf, "USB dev %04d", q->descriptor.bcdDevice);
return buf;
}
int funcube_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
struct funcube_priv_data *priv = (struct funcube_priv_data *)rig->state.priv;
struct usb_dev_handle *udh = rig->state.rigport.handle;
int ret;
unsigned int f;
char au8BufOut[64]; // endpoint size
char au8BufIn[64]; // endpoint size
if (freq < funcube_caps.rx_range_list1[0].start) {
rig_debug(RIG_DEBUG_WARN, "Error in %s: frequency is lower than minimum supported value (%.0f Hz)\n",
__FUNCTION__, funcube_caps.rx_range_list1[0].start);
return -RIG_EPROTO;
}
if (freq > funcube_caps.rx_range_list1[0].end) {
rig_debug(RIG_DEBUG_WARN, "Error in %s: frequency is higher than maximum supported value (%.0f Hz)\n",
__FUNCTION__, funcube_caps.rx_range_list1[0].end);
return -RIG_EPROTO;
}
// frequency is in Hz, while the dongle expects it in kHz
f = freq / 1e3;
au8BufOut[0]=REQUEST_SET_FREQ; // Command to Set Frequency on dongle
au8BufOut[1]=(char)f;
au8BufOut[2]=(char)(f>>8);
au8BufOut[3]=(char)(f>>16);
rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n",
__func__, (unsigned)au8BufOut[0] & 0xFF, (unsigned)au8BufOut[1] & 0xFF, (unsigned)au8BufOut[2] & 0xFF, (unsigned)au8BufOut[3] & 0xFF);
ret = usb_interrupt_write(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), rig->state.rigport.timeout);
if( ret < 0 )
{
rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_write failed (%d): %s\n",
__func__,ret,
usb_strerror ());
}
ret = usb_interrupt_read(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), rig->state.rigport.timeout);
if( ret != sizeof(au8BufIn) )
{
rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_read failed (%d): %s\n",
__func__, ret,
usb_strerror ());
}
rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n",
__func__, (unsigned)au8BufIn[0] & 0xFF, (unsigned)au8BufIn[1] & 0xFF);
if (!ret) {
rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n",
__func__,
usb_strerror ());
return -RIG_EIO;
}
priv->freq = freq;
return RIG_OK;
}
int funcube_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
struct funcube_priv_data *priv = (struct funcube_priv_data *)rig->state.priv;
rig_debug(RIG_DEBUG_TRACE, "%s: frequency is not read from the device, the value shown is the last succesfully set.\n",__func__);
*freq = priv->freq;
return RIG_OK;
}
#endif /* defined(HAVE_LIBUSB) && defined(HAVE_USB_H) */

43
kit/funcube.h 100644
Wyświetl plik

@ -0,0 +1,43 @@
/*
* Hamlib KIT backend - FUNcube Dongle USB tuner description
* Copyright (c) 2009-2010 by Stephane Fillod
*
* Derived from usbsoftrock-0.5:
* Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com)
*
* Author: Stefano Speretta, Innovative Solutions In Space BV
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _FUNCUBE_H
#define _FUNCUBE_H 1
#define VID 0x04D8
#define PID 0xFB56
#define VENDOR_NAME "Hanlincrest Ltd. "
#define PRODUCT_NAME "FunCube Dongle V0.0 "
#define FUNCUBE_INTERFACE 0x02
#define FUNCUBE_CONFIGURATION 0x00
#define FUNCUBE_ALTERNATIVE_SETTING 0x00
#define INPUT_ENDPOINT 0x82
#define OUTPUT_ENDPOINT 0x02
// Commands
#define REQUEST_SET_FREQ 0x64
#endif /* _FUNCUBE_H */

Wyświetl plik

@ -49,6 +49,7 @@ DECLARE_INITRIG_BACKEND(kit)
rig_register(&si570avrusb_caps);
rig_register(&si570picusb_caps);
rig_register(&si570fifisdrusb_caps);
rig_register(&funcube_caps);
#endif
#if (defined(HAVE_LIBUSB) && defined(HAVE_USB_H)) || defined(_WIN32)
/* rigs with alternate DLL support on Win32 */

Wyświetl plik

@ -35,6 +35,7 @@ extern const struct rig_caps usrp0_caps;
extern const struct rig_caps usrp_caps;
extern const struct rig_caps dds60_caps;
extern const struct rig_caps miniVNA_caps;
extern const struct rig_caps funcube_caps;
extern const struct rot_caps pcrotor_caps;

Wyświetl plik

@ -182,11 +182,21 @@ int usb_port_open(hamlib_port_t *port)
return -RIG_EIO;
#ifdef LIBUSB_HAS_GET_DRIVER_NP
/* Try to detach ftdi_sio kernel module
* Returns ENODATA if driver is not loaded.
* Don't check return value, let it fail later.
*/
usb_detach_kernel_driver_np(udh, port->parm.usb.iface);
/* Try to detach ftdi_sio kernel module
* This should be performed only for devices using
* USB-serial converters (like FTDI chips), for other
* devices this may cause problems, so do not do it.
*/
char dname[32] = {0};
int retval = usb_get_driver_np(udh, port->parm.usb.iface, dname, 31);
if (!retval)
{
/* Try to detach ftdi_sio kernel module
* Returns ENODATA if driver is not loaded.
* Don't check return value, let it fail later.
*/
usb_detach_kernel_driver_np(udh, port->parm.usb.iface);
}
#endif
if (port->parm.usb.iface >= 0) {
@ -235,6 +245,8 @@ int usb_port_close(hamlib_port_t *port)
{
struct usb_dev_handle *udh = port->handle;
usb_release_interface (udh, port->parm.usb.iface);
/* we're assuming that closing an interface automatically releases it. */
return usb_close (udh) == 0 ? RIG_OK : -RIG_EIO;
}
@ -253,4 +265,4 @@ int usb_port_close(hamlib_port_t *port)
#endif /* defined(HAVE_LIBUSB) && defined(HAVE_USB_H) */
/** @} */
/** @} */