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

winradio.c
/*
 *  Hamlib WiNRADiO backend - main file for interface through /dev/winradio API
 *  Copyright (C) 2001 pab@users.sourceforge.net
 *  Derived from hamlib code (C) 2000-2009 Stephane Fillod.
 *
 *    $Id: winradio.c,v 1.23 2009-01-11 13:21: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 "winradio.h"   /* config.h */

#include <stdlib.h>
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include <math.h>

#include "hamlib/rig.h"
#include "serial.h"
#include "misc.h"
#include "register.h"



#ifdef WINRADIO_IOCTL

#include <linradio/wrapi.h>
#include <linradio/radio_ioctl.h>

#define DEFAULT_WINRADIO_PATH "/dev/winradio0"

int wr_rig_init(RIG *rig) {
  rig->state.rigport.type.rig = RIG_PORT_DEVICE;
  strncpy(rig->state.rigport.pathname, DEFAULT_WINRADIO_PATH, FILPATHLEN);

  return RIG_OK;
}

int wr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) {
  unsigned long f;
  if (freq > GHz(4.2))
              return -RIG_EINVAL;
  f = (unsigned long)freq;
  if ( ioctl(rig->state.rigport.fd, RADIO_SET_FREQ, &f) ) return -RIG_EINVAL;
  return RIG_OK;
}

int wr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) {
  unsigned long f;
  if ( ioctl(rig->state.rigport.fd, RADIO_GET_FREQ, &f) < 0 ) return -RIG_EINVAL;
  *freq = (freq_t)f;
  return RIG_OK;
}

int wr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) {
  unsigned long m;
  switch ( mode ) {
  case RIG_MODE_AM:  m = RMD_AM; break;
  case RIG_MODE_CW:  m = RMD_CW; break;
  case RIG_MODE_LSB: m = RMD_LSB; break;
  case RIG_MODE_USB: m = RMD_USB; break;
  case RIG_MODE_WFM: m = RMD_FMW; break;
  case RIG_MODE_FM:
    switch ( width ) {
    case RIG_PASSBAND_NORMAL:
    case (int)kHz(17):
    case (int)kHz(15): m = RMD_FMN; break;

    case (int)kHz(6): m = RMD_FM6; break;
    case (int)kHz(50): m = RMD_FMM; break;
    default: return -RIG_EINVAL;
    }
  default: return -RIG_EINVAL;
  }
  if ( ioctl(rig->state.rigport.fd, RADIO_SET_MODE, &m) ) return -RIG_EINVAL;
  return  RIG_OK;
}

int wr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) {
  unsigned long m;
  if ( ioctl(rig->state.rigport.fd, RADIO_GET_MODE, &m) ) return -RIG_EINVAL;

  *width = RIG_PASSBAND_NORMAL;
  switch ( m ) {
  case RMD_CW: *mode = RIG_MODE_CW; break;
  case RMD_AM: *mode = RIG_MODE_AM; break;
  case RMD_FMN: *mode = RIG_MODE_FM; break; /* 15kHz or 17kHz on WR-3100 */
  case RMD_FM6: *mode = RIG_MODE_FM; break; /* 6kHz */
  case RMD_FMM: *mode = RIG_MODE_FM; break; /* 50kHz */
  case RMD_FMW: *mode = RIG_MODE_WFM; break;
  case RMD_LSB: *mode = RIG_MODE_LSB; break;
  case RMD_USB: *mode = RIG_MODE_USB; break;
  default: return -RIG_EINVAL;
  }
  if (*width == RIG_PASSBAND_NORMAL)
      *width = rig_passband_normal(rig,*mode);

  return RIG_OK;
}

int wr_set_powerstat(RIG *rig, powerstat_t status) {
  unsigned long p = 1;
  p = status==RIG_POWER_ON ? 1 : 0;
  if ( ioctl(rig->state.rigport.fd, RADIO_SET_POWER, &p) ) return -RIG_EINVAL;
  return RIG_OK;
}
int wr_get_powerstat(RIG *rig, powerstat_t *status) {
  unsigned long p;
  if ( ioctl(rig->state.rigport.fd, RADIO_GET_POWER, &p) ) return -RIG_EINVAL;
  *status = p ? RIG_POWER_ON : RIG_POWER_OFF;
  return RIG_OK;
}

int wr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) {
  switch ( func ) {
  case RIG_FUNC_FAGC: {
    unsigned long v = status ? 1 : 0;
    if ( ioctl(rig->state.rigport.fd, RADIO_SET_AGC, &v) ) return -RIG_EINVAL;
    return RIG_OK;
  }
  default:
    return -RIG_EINVAL;
  }    
}

int wr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) {
  switch ( func ) {
  case RIG_FUNC_FAGC: {
    unsigned long v;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_AGC, &v) ) return -RIG_EINVAL;
      *status = v;
    return RIG_OK;
  }
  default:
    return -RIG_EINVAL;
  }   
}


int wr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) {
  switch ( level ) {
  case RIG_LEVEL_AF: {
    unsigned long v;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_MAXVOL, &v) ) return -RIG_EINVAL;
    v *= val.f;
    if ( ioctl(rig->state.rigport.fd, RADIO_SET_VOL, &v) ) return -RIG_EINVAL;
    return RIG_OK;
  }
  case RIG_LEVEL_ATT: {
    unsigned long v = val.i ? 1 : 0;
    if ( ioctl(rig->state.rigport.fd, RADIO_SET_ATTN, &v) ) return -RIG_EINVAL;
    return RIG_OK;
  }
  case RIG_LEVEL_IF: {
    long v = val.i;
    if ( ioctl(rig->state.rigport.fd, RADIO_SET_IFS, &v) ) return -RIG_EINVAL;
    return RIG_OK;
  }
  case RIG_LEVEL_RF: {
    long v = val.f*100; /* iMaxIFGain on wHWVer > RHV_3150 */
    if ( ioctl(rig->state.rigport.fd, RADIO_SET_IFG, &v) ) return -RIG_EINVAL;
    return RIG_OK;
  }
  default:
    return -RIG_EINVAL;
  }    
}

int wr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) {
  switch ( level ) {
  case RIG_LEVEL_AF: {
    unsigned long v, mv;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_MAXVOL, &mv) ) return -RIG_EINVAL;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_VOL, &v) ) return -RIG_EINVAL;
    val->f = (float)v / mv;
    return RIG_OK;
  }
  case RIG_LEVEL_ATT: {
    unsigned long v;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_VOL, &v) ) return -RIG_EINVAL;
    val->i = v ? rig->state.attenuator[0] : 0;
    return RIG_OK;
  }
  case RIG_LEVEL_STRENGTH: {
    unsigned long v;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_SS, &v) ) return -RIG_EINVAL;
    val->i = v-60; /* 0..120, Hamlib assumes S9 = 0dB */
    return RIG_OK;
  }
  case RIG_LEVEL_IF: {
    long v;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_IFS, &v) ) return -RIG_EINVAL;
    val->i = v;
    return RIG_OK;
  }
  case RIG_LEVEL_RF: {
    long v;
    if ( ioctl(rig->state.rigport.fd, RADIO_GET_IFG, &v) ) return -RIG_EINVAL;
    val->f = (float)v/100;    /* iMaxIFGain on wHWVer > RHV_3150 */
    return RIG_OK;
  }
  default:
    return -RIG_EINVAL;
  }   
}

/*
 * FIXME: static buf does not allow reentrancy!
 */
const char *wr_get_info(RIG *rig) {
  static char buf[100];
  if ( ioctl(rig->state.rigport.fd, RADIO_GET_DESCR, buf) < 0 ) return "?";
  return buf;
}

#endif      /* WINRADIO_IOCTL */

DECLARE_INITRIG_BACKEND(winradio)
{
      rig_debug(RIG_DEBUG_VERBOSE, "winradio: _init called\n");

#ifdef WINRADIO_IOCTL
      rig_register(&wr1000_caps);
      rig_register(&wr1500_caps);
      rig_register(&wr1550_caps);
      rig_register(&wr3100_caps);
      rig_register(&wr3150_caps);
      rig_register(&wr3500_caps);
      rig_register(&wr3700_caps);
#endif      /* WINRADIO_IOCTL */

      /* Receivers with DLL only available under Windows */
#ifdef _WIN32
      rig_register(&g303_caps);
      rig_register(&g305_caps);
      rig_register(&g313_caps);
#endif

      return RIG_OK;
}

Generated by  Doxygen 1.6.0   Back to index