Logo Search packages:      
Sourcecode: hamlib version File versions  Download package

dwt.c

/*
 *  Hamlib KIT backend - Digital World Traveller DRM receiver description
 *  Copyright (c) 2005 by Stephane Fillod
 *
 *    $Id: dwt.c,v 1.2 2005/11/01 23:40:35 fillods Exp $
 *
 *   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

#include <stdlib.h>
#include <stdio.h>
#include "hamlib/rig.h"

#include "kit.h"


/*
 * Compile only this model if libusb is available
 * or if .DLL is available under Windows
 */
#ifdef _WIN32

#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
#ifdef HAVE_WINBASE_H
#include <winbase.h>
#endif

#include <math.h>

/*
 * Coding Technologies Digital World Traveller DRM tuner.
 *
 * TODO: rig_scan, set/get FM mode (mono/stereo), 
 *          get antenna mode (loop/wire),
 *          get low intermediate frequency (LIF) which may vary up to +-667 Hz
 *          and may be additionally increased of up to 2000 Hz
 */

#define DWTDLL "afgusbfe.dll"


/* Some type definitions needed for dll access */
typedef enum _tFrontendMode
{
  eFrontendModeUndefined  = 0,
  eFrontendModeDrm    = 1,
  eFrontendModeAm     = 2,
  eFrontendModeFm     = 6,
} tFrontendMode;

typedef short (__stdcall *FNCFrontendOpen)(void);
typedef short (__stdcall *FNCFrontendClose)(void);
typedef short (__stdcall *FNCFrontendGetId)(char *id);
typedef short (__stdcall *FNCFrontendSetMode)(tFrontendMode mode);
typedef tFrontendMode (__stdcall *FNCFrontendGetMode)(void);
typedef short (__stdcall *FNCFrontendSetFrequency)(double freq);
typedef double (__stdcall *FNCFrontendGetFrequency)(void);
typedef short (__stdcall *FNCFrontendGetRfLevel)(void);
typedef double (__stdcall *FNCFrontendGetLIF)(void);
typedef short (__stdcall *FNCFrontendStartScan)(short ScanMode, double WindowStartFreq, double WindowEndFreq, double DeltaFreq, double StepSize);
typedef short (__stdcall *FNCFrontendStopScan)(void);
typedef short (__stdcall *FNCFrontendGetScanStatus)(void);
typedef short (__stdcall *FNCFrontendSetRfAttenuator)(short n);
typedef short (__stdcall *FNCFrontendGetRfAttenuator)(void);
typedef short (__stdcall *FNCFrontendSetAntennaMode)(short n);
typedef short (__stdcall *FNCFrontendGetAntennaMode)(void);
typedef short (__stdcall *FNCFrontendSetFmMode)(short n);
typedef short (__stdcall *FNCFrontendGetFmMode)(void);


struct dwtdll_priv_data {
      HMODULE dll;

      FNCFrontendOpen FrontendOpen;
      FNCFrontendClose FrontendClose;
      FNCFrontendGetId FrontendGetId;
      FNCFrontendSetMode FrontendSetMode;
      FNCFrontendGetMode FrontendGetMode;
      FNCFrontendSetFrequency FrontendSetFrequency;
      FNCFrontendGetFrequency FrontendGetFrequency;
      FNCFrontendGetRfLevel FrontendGetRfLevel;
      FNCFrontendGetLIF FrontendGetLIF;
      FNCFrontendStartScan FrontendStartScan;
      FNCFrontendStopScan FrontendStopScan;
      FNCFrontendGetScanStatus FrontendGetScanStatus;
      FNCFrontendSetRfAttenuator FrontendSetRfAttenuator;
      FNCFrontendGetRfAttenuator FrontendGetRfAttenuator;
      FNCFrontendSetAntennaMode FrontendSetAntennaMode;
      FNCFrontendGetAntennaMode FrontendGetAntennaMode;
      FNCFrontendSetFmMode FrontendSetFmMode;
      FNCFrontendGetFmMode FrontendGetFmMode;
};


#define DWT_MODES (RIG_MODE_AM|RIG_MODE_USB)    /* USB is for DRM */

#define DWT_FUNC (RIG_FUNC_NONE)

#define DWT_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_STRENGTH|RIG_LEVEL_RAWSTR)

#define DWT_PARM_ALL (RIG_PARM_NONE)

#define DWT_VFO (RIG_VFO_A)

#define DWT_ANT (RIG_ANT_1)

static int dwtdll_init(RIG *rig);
static int dwtdll_cleanup(RIG *rig);
static int dwtdll_open(RIG *rig);
static int dwtdll_close(RIG *rig);
static int dwtdll_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
static int dwtdll_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
static int dwtdll_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
static int dwtdll_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
static int dwtdll_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val);
static int dwtdll_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
static const char * dwtdll_get_info(RIG *rig);

/*
 * Coding Technologies Digital World Traveller DRM tuner.
 *
 * The receiver is controlled via USB, through a Windows DLL.
 *
 * see Winradio G303 as an example
 */

const struct rig_caps dwt_caps = {
.rig_model =  RIG_MODEL_DWT,
.model_name = "Digital World Traveller",
.mfg_name =  "Coding Technologies",
.version =  "0.1",
.copyright =  "LGPL",
.status =  RIG_STATUS_ALPHA,
.rig_type =  RIG_TYPE_PCRECEIVER,
.ptt_type =  RIG_PTT_NONE,
.dcd_type =  RIG_DCD_NONE,
.port_type =  RIG_PORT_NONE,
.write_delay =  0,
.post_write_delay =  0,
.timeout =  200,
.retry = 0,

.has_get_func =  DWT_FUNC,
.has_set_func =  DWT_FUNC,
.has_get_level =  DWT_LEVEL_ALL,
.has_set_level =  RIG_LEVEL_SET(DWT_LEVEL_ALL),
.has_get_parm =  DWT_PARM_ALL,
.has_set_parm =  RIG_PARM_SET(DWT_PARM_ALL),
.level_gran =  {},
.parm_gran =  {},
.ctcss_list =  NULL,
.dcs_list =  NULL,
.preamp =   { RIG_DBLST_END },
.attenuator =     { 20, RIG_DBLST_END, }, /* TBC */
.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 =  {
    {kHz(150),MHz(30)-kHz(1),DWT_MODES,-1,-1,DWT_VFO,DWT_ANT},
    {kHz(87.5),MHz(108),RIG_MODE_WFM,-1,-1,DWT_VFO,DWT_ANT},
      RIG_FRNG_END,
  },
.tx_range_list1 =  { RIG_FRNG_END, },
.rx_range_list2 =  {
    {kHz(150),MHz(30)-kHz(1),DWT_MODES,-1,-1,DWT_VFO,DWT_ANT},
    {kHz(87.5),MHz(108),RIG_MODE_WFM,-1,-1,DWT_VFO,DWT_ANT},
      RIG_FRNG_END,
  },
.tx_range_list2 =  { RIG_FRNG_END, },
.tuning_steps =  {
       {DWT_MODES,1},
       RIG_TS_END,
      },
        /* mode/filter list, remember: order matters! */
.filters =  {
            {RIG_MODE_USB, kHz(22)},      /* FIXME */
            {RIG_MODE_AM, kHz(9)},  /* FIXME */
            {RIG_MODE_WFM, kHz(230)},     /* FIXME */
            RIG_FLT_END,
      },

.rig_init =     dwtdll_init,
.rig_cleanup =  dwtdll_cleanup,
.rig_open =     dwtdll_open,
.rig_close =    dwtdll_close,

.set_freq =  dwtdll_set_freq,
.get_freq =  dwtdll_get_freq,
.set_mode =  dwtdll_set_mode,
.get_mode =  dwtdll_get_mode,
.set_level = dwtdll_set_level,
.get_level = dwtdll_get_level,
.get_info =  dwtdll_get_info,
};



int dwtdll_init(RIG *rig)
{
      struct dwtdll_priv_data *priv;

      priv = (struct dwtdll_priv_data*)malloc(sizeof(struct dwtdll_priv_data));
      if (!priv) {
            /* whoops! memory shortage! */
            return -RIG_ENOMEM;
      }

      /* Try to load required dll */
      priv->dll = LoadLibrary(DWTDLL);

      if (!priv->dll) {
            rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n",
                        __FUNCTION__, DWTDLL);
            free(priv);
            return -RIG_EIO;  /* huh! */
      }

      /* Get process addresses from dll for function access */
      priv->FrontendOpen =
            (FNCFrontendOpen) GetProcAddress(priv->dll, "FrontendOpen");
      priv->FrontendClose = 
            (FNCFrontendClose) GetProcAddress(priv->dll, "FrontendClose");
      priv->FrontendGetId = 
            (FNCFrontendGetId) GetProcAddress(priv->dll, "FrontendGetId");
      priv->FrontendSetMode = 
            (FNCFrontendSetMode) GetProcAddress(priv->dll, "FrontendSetMode");
      priv->FrontendGetMode = 
            (FNCFrontendGetMode) GetProcAddress(priv->dll, "FrontendGetMode");
      priv->FrontendSetFrequency = 
            (FNCFrontendSetFrequency) GetProcAddress(priv->dll, "FrontendSetFrequency");
      priv->FrontendGetFrequency = 
            (FNCFrontendGetFrequency) GetProcAddress(priv->dll, "FrontendGetFrequency");
      priv->FrontendGetRfLevel = 
            (FNCFrontendGetRfLevel) GetProcAddress(priv->dll, "FrontendGetRfLevel");
      priv->FrontendGetLIF = 
            (FNCFrontendGetLIF) GetProcAddress(priv->dll, "FrontendGetLIF");
      priv->FrontendStartScan = 
            (FNCFrontendStartScan) GetProcAddress(priv->dll, "FrontendStartScan");
      priv->FrontendStopScan = 
            (FNCFrontendStopScan) GetProcAddress(priv->dll, "FrontendStopScan");
      priv->FrontendGetScanStatus = 
            (FNCFrontendGetScanStatus) GetProcAddress(priv->dll, "FrontendGetScanStatus");
      priv->FrontendSetRfAttenuator = 
            (FNCFrontendSetRfAttenuator) GetProcAddress(priv->dll, "FrontendSetRfAttenuator");
      priv->FrontendGetRfAttenuator = 
            (FNCFrontendGetRfAttenuator) GetProcAddress(priv->dll, "FrontendGetRfAttenuator");
      priv->FrontendSetAntennaMode = 
            (FNCFrontendSetAntennaMode) GetProcAddress(priv->dll, "FrontendSetAntennaMode");
      priv->FrontendGetAntennaMode = 
            (FNCFrontendGetAntennaMode) GetProcAddress(priv->dll, "FrontendGetAntennaMode");
      priv->FrontendSetFmMode = 
            (FNCFrontendSetFmMode) GetProcAddress(priv->dll, "FrontendSetFmMode");
      priv->FrontendGetFmMode = 
            (FNCFrontendGetFmMode) GetProcAddress(priv->dll, "FrontendGetFmMode");

      rig->state.priv = (void*)priv;

      return RIG_OK;
}

int dwtdll_open(RIG *rig)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      short ret;

      /* Open DWT receiver */
      ret = priv->FrontendOpen();
      if (ret < 0)
            return -RIG_EIO;  /* huh! */

      /* default to DRM mode */
      ret = priv->FrontendSetMode(eFrontendModeDrm);
      if (ret < 0)
            return -RIG_EIO;  /* huh! */

      return RIG_OK;
}

int dwtdll_close(RIG *rig)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      short ret;

      /* Open DWT receiver */
      ret = priv->FrontendClose();
      if (ret < 0)
            return -RIG_EIO;  /* huh! */

      return RIG_OK;
}

int dwtdll_cleanup(RIG *rig)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;

      if (!rig)
            return -RIG_EINVAL;

      if (rig->state.priv)
            free(rig->state.priv);
      rig->state.priv = NULL;

      /* Clean up the dll access */
      FreeLibrary(priv->dll);

      return RIG_OK;
}

int dwtdll_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      short ret;

      ret = priv->FrontendSetFrequency((double) freq);

      return ret < 0 ? -RIG_EIO : RIG_OK;
}

int dwtdll_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      
      *freq = (freq_t) priv->FrontendGetFrequency();

      return RIG_OK;
}

int dwtdll_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      tFrontendMode dwtmode;
      short ret;

      switch (mode) {
      case RIG_MODE_USB: dwtmode = eFrontendModeDrm; break;
      case RIG_MODE_AM: dwtmode = eFrontendModeAm; break;
      case RIG_MODE_WFM: dwtmode = eFrontendModeFm; break;
      default:
            return -RIG_EINVAL;
      }

      ret = priv->FrontendSetMode(dwtmode);
      
      return ret < 0 ? -RIG_EIO : RIG_OK;
}

int dwtdll_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      tFrontendMode dwtmode;

      dwtmode = priv->FrontendGetMode();

      switch (dwtmode) {
      case eFrontendModeDrm: *mode = RIG_MODE_USB; break;
      case eFrontendModeAm: *mode = RIG_MODE_AM; break;
      case eFrontendModeFm: *mode = RIG_MODE_WFM; break;
      default:
            return -RIG_EPROTO;
      }
      *width = rig_passband_normal(rig, *mode);

      return RIG_OK;
}


int dwtdll_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      short ret=0;
      
      switch(level) {
      case RIG_LEVEL_ATT:
            ret = priv->FrontendSetRfAttenuator(val.i ? 1 : 0);
            break;

      default:
            return -RIG_EINVAL;
      }

      return ret < 0 ? -RIG_EIO : RIG_OK;
}

int dwtdll_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      short ret=0;

      switch(level) {
      case RIG_LEVEL_ATT:
            ret = priv->FrontendGetRfAttenuator();
            if (ret < 0)
                  break;
            /* local vs. DX mode */
            val->i = ret ? 0 : rig->caps->attenuator[0];
            break;

      case RIG_LEVEL_STRENGTH:
            /* actual RMS signal strength in dBuV */
            ret = priv->FrontendGetRfLevel();
            if (ret < 0)
                  break;
            val->i = (int)(10.*log10(((10e-6*ret*ret)/50)/1e-3))+73;
            break;

      case RIG_LEVEL_RAWSTR:
            /* actual RMS signal strength in dBuV */
            ret = priv->FrontendGetRfLevel();
            if (ret < 0)
                  break;
            val->i = ret;
            break;

      default:
            return -RIG_EINVAL;
      }

      return ret < 0 ? -RIG_EIO : RIG_OK;
}


static const char* dwtdll_get_info(RIG *rig)
{
      struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)rig->state.priv;
      static char info[22];

      if (priv->FrontendGetId(info) < 0)
            return NULL;

      info[21] = '\0';

      return info;
}


#elif defined(HAVE_LIBUSB) && defined(HAVE_USB_H)


#include <errno.h>
#include <usb.h>

#include "token.h"


#define USB_VID_CT      0x1539      /* AFG Engineering */
#define USB_PID_CT_DWT  0x1730      /* Digital World Traveller */


#define DWT_MODES (RIG_MODE_NONE)

#define DWT_FUNC (RIG_FUNC_NONE)

#define DWT_LEVEL_ALL (RIG_LEVEL_NONE)

#define DWT_PARM_ALL (RIG_PARM_NONE)

#define DWT_VFO (RIG_VFO_A)

static int dwt_init(RIG *rig);
static int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
static const char * dwt_get_info(RIG *rig);

/*
 * Coding Technologies Digital World Traveller DRM tuner.
 *
 * The receiver is controlled via USB.
 *
 * see dsbr100.c as an example
 */

const struct rig_caps dwt_caps = {
.rig_model =  RIG_MODEL_DWT,
.model_name = "Digital World Traveller",
.mfg_name =  "Coding Technologies",
.version =  "0.1",
.copyright =  "LGPL",
.status =  RIG_STATUS_UNTESTED,
.rig_type =  RIG_TYPE_TUNER,
.ptt_type =  RIG_PTT_NONE,
.dcd_type =  RIG_DCD_NONE,
.port_type =  RIG_PORT_USB,
.serial_rate_min =  9600,     /* don't care */
.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 =  200,
.retry = 0,

.has_get_func =  DWT_FUNC,
.has_set_func =  DWT_FUNC,
.has_get_level =  DWT_LEVEL_ALL,
.has_set_level =  RIG_LEVEL_SET(DWT_LEVEL_ALL),
.has_get_parm =  DWT_PARM_ALL,
.has_set_parm =  RIG_PARM_SET(DWT_PARM_ALL),
.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 =  {
    {kHz(150),MHz(30)-kHz(1),DWT_MODES,-1,-1,DWT_VFO},
    {kHz(87.5),MHz(108),RIG_MODE_WFM,-1,-1,DWT_VFO},
      RIG_FRNG_END,
  },
.tx_range_list1 =  { RIG_FRNG_END, },
.rx_range_list2 =  {
    {kHz(150),MHz(30)-kHz(1),DWT_MODES,-1,-1,DWT_VFO},
    {kHz(87.5),MHz(108),RIG_MODE_WFM,-1,-1,DWT_VFO},
      RIG_FRNG_END,
  },
.tx_range_list2 =  { RIG_FRNG_END, },
.tuning_steps =  {
       {DWT_MODES,kHz(1)},
       RIG_TS_END,
      },
        /* mode/filter list, remember: order matters! */
.filters =  {
            {RIG_MODE_USB, kHz(22)},      /* FIXME */
            {RIG_MODE_AM, kHz(9)},  /* FIXME */
            {RIG_MODE_WFM, kHz(230)},     /* FIXME */
            RIG_FLT_END,
      },

.rig_init =  dwt_init,

.set_freq =  dwt_set_freq,
.get_info =  dwt_get_info,

};


int dwt_init(RIG *rig)
{
      hamlib_port_t *rp = &rig->state.rigport;

      rp->parm.usb.vid = USB_VID_CT;
      rp->parm.usb.pid = USB_PID_CT_DWT;
      rp->parm.usb.conf = 1;
      rp->parm.usb.iface = 0;
      rp->parm.usb.alt = 0;

      return RIG_OK;
}

#define MSG_LEN 16
int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
      struct usb_dev_handle *udh = rig->state.rigport.handle;
      int request, value, index;
      unsigned char buf[MSG_LEN] = { 0x4a, 0x00, 0x03, 0x00, 0xff, 0xff, 0x32 };
      int requesttype, r;
      int ifreq = (int)(freq/1000);

      /* FIXME */
      requesttype = 0x00;
      request = 0x00;
      value = 0x00;
      index = 0x00;

      buf[8] = ifreq & 0xff;
      buf[7] = (ifreq>>8) & 0xff;
      r = usb_control_msg (udh, requesttype, request, value, index,
                     (char *) buf, 9, 1000);
      if (r < 0) {
            /* we get EPIPE if the firmware stalls the endpoint. */
            if (errno != EPIPE)
                  rig_debug (RIG_DEBUG_ERR, 
                              "usb_control_msg failed: %s\n", 
                              usb_strerror ());
            return -RIG_EIO;
      }

      return RIG_OK;
}

const char * dwt_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, "Dev %04d", q->descriptor.bcdDevice);

      return buf;
}

#endif      /* HAVE_LIBUSB */

Generated by  Doxygen 1.6.0   Back to index