kopia lustrzana https://github.com/Hamlib/Hamlib
* added added dynamic loading support,
* added CI-V ID list, * added generic icom_set_mode,icom_get_mode,icom_set_vfo,icom_get_vfo,icom_get_strength,icom_decode_event git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@191 7ae35d74-ebe9-4afe-98af-79ac388436b8Hamlib-1.1.0
rodzic
41cb317ec4
commit
7fc40d85c4
263
icom/icom.c
263
icom/icom.c
|
@ -6,7 +6,7 @@
|
|||
* via serial interface to an ICOM using the "CI-V" interface.
|
||||
*
|
||||
*
|
||||
* $Id: icom.c,v 1.4 2000-10-01 12:37:10 f4cfe Exp $
|
||||
* $Id: icom.c,v 1.5 2000-10-08 21:38:45 f4cfe Exp $
|
||||
*
|
||||
*
|
||||
*
|
||||
|
@ -34,27 +34,72 @@
|
|||
#include <errno.h> /* Error number definitions */
|
||||
#include <termios.h> /* POSIX terminal control definitions */
|
||||
#include <sys/ioctl.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <rig.h>
|
||||
#include <riglist.h>
|
||||
#include <hamlib/rig.h>
|
||||
#include <hamlib/riglist.h>
|
||||
#include <serial.h>
|
||||
#include <misc.h>
|
||||
#include "icom.h"
|
||||
#include "icom_defs.h"
|
||||
#include "frame.h"
|
||||
|
||||
/* Prototypes */
|
||||
int read_icom_block(int fd, unsigned char *rxbuffer, size_t count, int timeout);
|
||||
|
||||
struct icom_addr {
|
||||
rig_model_t model;
|
||||
unsigned char re_civ_addr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Please, if the default CI-V address of your rig is listed as UNKNOWN_ADDR,
|
||||
* send the value to <f4cfe@users.sourceforge.net> for inclusion. Thanks --SF
|
||||
*
|
||||
* TODO: sort this list with most frequent rigs first.
|
||||
*/
|
||||
#define UNKNOWN_ADDR 0x01
|
||||
static const struct icom_addr icom_addr_list[] = {
|
||||
{ RIG_MODEL_IC706, 0x58 },
|
||||
{ RIG_MODEL_IC706MKII, 0x58 },
|
||||
{ RIG_MODEL_IC706, 0x48 },
|
||||
{ RIG_MODEL_IC706MKII, 0x4e },
|
||||
{ RIG_MODEL_IC706MKIIG, 0x58 },
|
||||
{ RIG_MODEL_IC1271, 0x24 },
|
||||
{ RIG_MODEL_IC1275, 0x18 },
|
||||
{ RIG_MODEL_IC271, 0x20 },
|
||||
{ RIG_MODEL_IC275, 0x10 },
|
||||
{ RIG_MODEL_IC375, 0x12 },
|
||||
{ RIG_MODEL_IC471, 0x22 },
|
||||
{ RIG_MODEL_IC475, 0x14 },
|
||||
{ RIG_MODEL_IC575, 0x16 },
|
||||
{ RIG_MODEL_IC725, 0x28 },
|
||||
{ RIG_MODEL_IC726, 0x30 },
|
||||
{ RIG_MODEL_IC731, 0x04 },
|
||||
{ RIG_MODEL_IC735, 0x04 },
|
||||
{ RIG_MODEL_IC751, 0x1c },
|
||||
{ RIG_MODEL_IC751A, 0x1c },
|
||||
{ RIG_MODEL_IC756, 0x50 },
|
||||
{ RIG_MODEL_IC761, 0x1e },
|
||||
{ RIG_MODEL_IC765, 0x2c },
|
||||
{ RIG_MODEL_IC775, 0x46 },
|
||||
{ RIG_MODEL_IC781, 0x26 },
|
||||
{ RIG_MODEL_IC821, 0x4c },
|
||||
{ RIG_MODEL_IC821H, 0x4c },
|
||||
{ RIG_MODEL_IC970, 0x2e },
|
||||
{ RIG_MODEL_ICR7000, 0x08 },
|
||||
{ RIG_MODEL_ICR71, 0x1a },
|
||||
{ RIG_MODEL_ICR7100, 0x34 },
|
||||
{ RIG_MODEL_ICR72, 0x32 },
|
||||
{ RIG_MODEL_ICR8500, 0x4a },
|
||||
{ RIG_MODEL_ICR9000, 0x2a },
|
||||
{ RIG_MODEL_IC707, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC718, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC728, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC729, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC731, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC736, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC737, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC738, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC746, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC756PRO, UNKNOWN_ADDR },
|
||||
{ RIG_MODEL_IC820, UNKNOWN_ADDR },
|
||||
{ -1, 0 },
|
||||
};
|
||||
|
||||
|
@ -93,7 +138,8 @@ int icom_init(RIG *rig)
|
|||
}
|
||||
}
|
||||
|
||||
if (rig->caps->rig_model == RIG_MODEL_IC731)
|
||||
if (rig->caps->rig_model == RIG_MODEL_IC731 ||
|
||||
rig->caps->rig_model == RIG_MODEL_IC735)
|
||||
priv->civ_731_mode = 1;
|
||||
else
|
||||
priv->civ_731_mode = 0;
|
||||
|
@ -180,10 +226,209 @@ int icom_get_freq(RIG *rig, freq_t *freq)
|
|||
}
|
||||
|
||||
/*
|
||||
* to_bcd requires nibble len
|
||||
* from_bcd requires nibble len
|
||||
*/
|
||||
*freq = from_bcd(freqbuf+1, freq_len*2);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_set_mode
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||
*/
|
||||
int icom_set_mode(RIG *rig, rmode_t mode)
|
||||
{
|
||||
struct icom_priv_data *priv;
|
||||
struct rig_state *rig_s;
|
||||
unsigned char ackbuf[16];
|
||||
int ack_len,icmode;
|
||||
|
||||
rig_s = &rig->state;
|
||||
priv = (struct icom_priv_data*)rig_s->priv;
|
||||
|
||||
icmode = hamlib2icom_mode(mode);
|
||||
|
||||
icom_transaction (rig, C_SET_MODE, icmode, NULL, 0, ackbuf, &ack_len);
|
||||
|
||||
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||
rig_debug(RIG_DEBUG_ERR,"icom_set_mode: ack NG (%#.2x),
|
||||
len=%d\n", ackbuf[0],ack_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_get_mode
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL, mode!=NULL
|
||||
*/
|
||||
int icom_get_mode(RIG *rig, rmode_t *mode)
|
||||
{
|
||||
struct icom_priv_data *priv;
|
||||
struct rig_state *rig_s;
|
||||
unsigned char modebuf[16];
|
||||
int mode_len;
|
||||
|
||||
rig_s = &rig->state;
|
||||
priv = (struct icom_priv_data*)rig_s->priv;
|
||||
|
||||
icom_transaction (rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len);
|
||||
|
||||
/*
|
||||
* modebuf should contain Cn,Data area
|
||||
*/
|
||||
mode_len--;
|
||||
if (mode_len != 2 && mode_len != 1) {
|
||||
rig_debug(RIG_DEBUG_ERR,"icom_get_mode: wrong frame len=%d\n",
|
||||
mode_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
|
||||
*mode = icom2hamlib_mode(modebuf[1]| modebuf[2]<<8);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_set_vfo
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||
*/
|
||||
int icom_set_vfo(RIG *rig, vfo_t vfo)
|
||||
{
|
||||
struct icom_priv_data *priv;
|
||||
struct rig_state *rig_s;
|
||||
unsigned char ackbuf[16];
|
||||
int ack_len,icvfo;
|
||||
|
||||
rig_s = &rig->state;
|
||||
priv = (struct icom_priv_data*)rig_s->priv;
|
||||
|
||||
switch(vfo) {
|
||||
case RIG_VFO_A: icvfo = S_VFOA; break;
|
||||
case RIG_VFO_B: icvfo = S_VFOB; break;
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR,"icom: Unsupported VFO %d\n",
|
||||
vfo);
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
icom_transaction (rig, C_SET_VFO, icvfo, NULL, 0, ackbuf, &ack_len);
|
||||
|
||||
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||
rig_debug(RIG_DEBUG_ERR,"icom_set_vfo: ack NG (%#.2x),
|
||||
len=%d\n", ackbuf[0],ack_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_get_strength
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL, freq!=NULL
|
||||
*/
|
||||
int icom_get_strength(RIG *rig, int *strength)
|
||||
{
|
||||
struct icom_priv_data *priv;
|
||||
struct rig_state *rig_s;
|
||||
unsigned char strbuf[16];
|
||||
int str_len;
|
||||
float str;
|
||||
|
||||
rig_s = &rig->state;
|
||||
priv = (struct icom_priv_data*)rig_s->priv;
|
||||
|
||||
icom_transaction (rig, C_RD_SQSM, S_SML, NULL, 0, strbuf, &str_len);
|
||||
|
||||
/*
|
||||
* strbuf should contain Cn,Sc,Data area
|
||||
*/
|
||||
str_len-=2;
|
||||
if (str_len != 2) {
|
||||
rig_debug(RIG_DEBUG_ERR,"icom_get_strength: wrong frame len=%d\n",
|
||||
str_len);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
/*
|
||||
* The result is a 3 digit BCD, but in *big endian* order: 0000..0255
|
||||
* (from_bcd is little endian)
|
||||
*/
|
||||
str = (strbuf[2]&0x0f)*100+ (strbuf[3]>>4)*10 + (strbuf[3]&0x0f);
|
||||
#ifndef DONT_WANT_STR_DB
|
||||
/* translate it to dBs */
|
||||
str = (str-47)*114/(223-47);
|
||||
#endif
|
||||
*strength = rint(str);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_decode is called by sa_sigio, when some asynchronous
|
||||
* data has been received from the rig
|
||||
*/
|
||||
int icom_decode_event(RIG *rig)
|
||||
{
|
||||
struct icom_priv_data *priv;
|
||||
struct rig_state *rig_s;
|
||||
unsigned char buf[32];
|
||||
int frm_len;
|
||||
freq_t freq;
|
||||
rmode_t mode;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "icom: icom_decode called\n");
|
||||
|
||||
rig_s = &rig->state;
|
||||
priv = (struct icom_priv_data*)rig_s->priv;
|
||||
|
||||
frm_len = read_icom_frame(rig_s->stream, buf, rig_s->timeout);
|
||||
/*
|
||||
* the first 2 bytes must be 0xfe
|
||||
* the 3rd one the emitter
|
||||
* the 4rd one 0x00 since this is transceive mode
|
||||
* then the command number
|
||||
* the rest is data
|
||||
* and don't forget one byte at the end for the EOM
|
||||
*/
|
||||
switch (buf[4]) {
|
||||
case C_SND_FREQ:
|
||||
/* TODO: check the read freq len is 4 or 5 bytes */
|
||||
if (rig->callbacks.freq_event) {
|
||||
freq = from_bcd(buf+5, (priv->civ_731_mode ? 4:5)*2);
|
||||
return rig->callbacks.freq_event(rig,freq);
|
||||
} else
|
||||
return -RIG_ENAVAIL;
|
||||
break;
|
||||
case C_SND_MODE:
|
||||
if (rig->callbacks.mode_event) {
|
||||
mode = icom2hamlib_mode(buf[5]| buf[6]<<8);
|
||||
return rig->callbacks.mode_event(rig,mode);
|
||||
} else
|
||||
return -RIG_ENAVAIL;
|
||||
break;
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_VERBOSE,"icom_decode: tranceive cmd "
|
||||
"unsupported %#2.2x\n",buf[4]);
|
||||
return -RIG_ENIMPL;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init_icom is called by rig_backend_load
|
||||
*/
|
||||
int init_icom(void *be_handle)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "icom: _init called\n");
|
||||
|
||||
rig_register(&ic706_caps);
|
||||
rig_register(&ic706mkii_caps);
|
||||
rig_register(&ic706mkiig_caps);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue