diff --git a/ChangeLog b/ChangeLog index 131084b59..f000b3832 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-09-04 AD7AI + + * Changed Icom make_cmd_frame code to accept multi-byte subcommands; + + * Added HAMLIB_API rig_ext_lookup_tok to return pointer ext parameter table with token input. + + * Added icom_get_dsp_filter to allow lib to read the programable filter assignments. This includes + the rtty filter modes for some of the dsp rigs. Does not allow them to be set yet. + + * Added get/set_ext_parm code for IC746 pro and fixed the 756proII/III ext_parm code. + This should be easily modified for the IC7000 and 7800 ext parameters. + + * fixed misc mismatched sign warnings on parameters. + 2006-07-30 AD7AI * RIG_SETTING_MAX changed back to 32 and rigctl and rigmatrix corrected to reflect 32 diff --git a/icom/frame.c b/icom/frame.c index ea16869c4..a13afa455 100644 --- a/icom/frame.c +++ b/icom/frame.c @@ -2,7 +2,7 @@ * Hamlib CI-V backend - low level communication routines * Copyright (c) 2000-2006 by Stephane Fillod * - * $Id: frame.c,v 1.29 2006-07-18 22:51:42 n0nb Exp $ + * $Id: frame.c,v 1.30 2006-09-22 19:55:58 n0nb 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 @@ -63,9 +63,17 @@ int make_cmd_frame(char frame[], char re_id, char cmd, int subcmd, const unsigne frame[i++] = re_id; frame[i++] = CTRLID; frame[i++] = cmd; - if (subcmd != -1) + if (subcmd != -1) { +#ifdef MULTIB_SUBCMD + register int j; + if (j = subcmd & 0xff0000) { /* allows multi-byte subcmd for dsp rigs */ + frame[i++] = j >> 16; + frame[i++] = (subcmd & 0xff00) >> 8; + } + else if (j = subcmd & 0xff00) frame[i++] = j >> 8; +#endif frame[i++] = subcmd & 0xff; - + } if (data_len != 0) { memcpy(frame+i, data, data_len); i += data_len; @@ -283,7 +291,7 @@ int read_icom_frame(hamlib_port_t *p, unsigned char rxbuffer[]) * assumes rig!=NULL */ int rig2icom_mode(RIG *rig, rmode_t mode, pbwidth_t width, - unsigned char *md, char *pd) + unsigned char *md, signed char *pd) { unsigned char icmode; signed char icmode_ext; @@ -354,6 +362,8 @@ void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t case S_LSB: *mode = RIG_MODE_LSB; break; case S_RTTY: *mode = RIG_MODE_RTTY; break; case S_RTTYR: *mode = RIG_MODE_RTTYR; break; + case S_PSK: *mode = RIG_MODE_PKTUSB; break; /* IC-7800 */ + case S_PSKR: *mode = RIG_MODE_PKTLSB; break; case 0xff: *mode = RIG_MODE_NONE; break; /* blank mem channel */ default: @@ -362,18 +372,24 @@ void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *mode = RIG_MODE_NONE; } - /* Most rigs return 1-wide, 2-normal,3-narrow see defs of PD_NARROW etc in the ICOM_defs file. That is what the rig2icom func uses. */ - + /* Most rigs return 1-wide, 2-narrow; or if it has 3 filters: 1-wide, 2-middle, 3-narrow. (Except for the 706 mkIIg 0-wide, 1-middle, 2-narrow.) For DSP rigs these are presets, which can be programmed for 30 - 41 bandwidths, depending on mode */ + + if (rig->caps->rig_model == RIG_MODEL_IC706MKIIG || rig->caps->rig_model == RIG_MODEL_IC706 || rig->caps->rig_model == RIG_MODEL_IC706MKII) pd--; switch (pd) { + case 0x01: if (!(*width = rig_passband_wide(rig, *mode))) /* if no wide filter defined it's the default */ + *width = rig_passband_normal(rig, *mode); + break; + case 0x02: if (*width = rig_passband_wide(rig, *mode)) + *width = rig_passband_normal(rig, *mode); + else *width = rig_passband_narrow(rig, *mode); /* This really just depends on how you program the table. */ + break; case 0x03: *width = rig_passband_narrow(rig, *mode); break; - case 0x02: *width = rig_passband_normal(rig, *mode); break; - case 0x01: *width = rig_passband_wide(rig, *mode); break; case -1: break; /* no passband data */ default: - rig_debug(RIG_DEBUG_ERR,"icom: Unsupported Icom mode width %#.2x\n", - pd); + rig_debug(RIG_DEBUG_ERR,"icom: Unsupported Icom mode width %#.2x\n", pd); } +return ; } diff --git a/icom/frame.h b/icom/frame.h index 23bfc86f5..b06f261f3 100644 --- a/icom/frame.h +++ b/icom/frame.h @@ -2,7 +2,7 @@ * Hamlib CI-V backend - low level communication header * Copyright (c) 2000-2005 by Stephane Fillod * - * $Id: frame.h,v 1.15 2006-07-18 22:51:42 n0nb Exp $ + * $Id: frame.h,v 1.16 2006-09-22 19:55:58 n0nb 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 @@ -33,7 +33,7 @@ int make_cmd_frame(char frame[], char re_id, char cmd, int subcmd, const unsigne int icom_transaction (RIG *rig, int cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len); int read_icom_frame(hamlib_port_t *p, unsigned char rxbuffer[]); -int rig2icom_mode(RIG *rig, rmode_t mode, pbwidth_t width, unsigned char *md, char *pd); +int rig2icom_mode(RIG *rig, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd); void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width); #endif /* _FRAME_H */ diff --git a/icom/ic746.c b/icom/ic746.c index f09d13ee0..1b168ba67 100644 --- a/icom/ic746.c +++ b/icom/ic746.c @@ -2,7 +2,7 @@ * Hamlib CI-V backend - description of IC-746 and variations * Copyright (c) 2000-2003 by Stephane Fillod * - * $Id: ic746.c,v 1.6 2006-07-18 22:51:42 n0nb Exp $ + * $Id: ic746.c,v 1.7 2006-09-22 19:55:58 n0nb 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 @@ -43,11 +43,9 @@ * * TODO: * - advanced scanning functions - * - fix: set_ant 0x12,[1|2] * - set_channel * - set_ctcss_tone/ctcss_sql * - set keyer? - * - read IF filter setting? * - test all that stuff.. */ @@ -156,6 +154,8 @@ typedef channel_str_t band_stack_reg_t; static int ic746_set_parm(RIG *rig, setting_t parm, value_t val); static int ic746_get_parm(RIG *rig, setting_t parm, value_t *val); static int ic746pro_get_channel(RIG *rig, channel_t *chan); +static int ic746pro_set_ext_parm(RIG *rig, token_t token, value_t val); +static int ic746pro_get_ext_parm(RIG *rig, token_t token, value_t *val); /* @@ -313,6 +313,55 @@ const struct rig_caps ic746_caps = { }; + /*IC-746Pro Rig parameters Only available in this namespace*/ +#define S_MEM_SC_LEN 2 /* 756PRO S_MEM subcmd length */ +#define S_MEM_LCD_CONT 0x501 /* LCD Contrast 0-256/0-100% */ +#define S_MEM_BKLIT 0x502 /* Backlight 0-256/0-100% */ +#define S_MEM_BEEP 0x506 /* Button confirmation */ +#define S_MEM_SQL_CTL 0x508 /* RF/SQL ctl set 0=auto; 1 = sql; 2 = RF+SQL */ +#define S_MEM_QSPLT 0x511 /* enable quick split mode */ + /* values -9.999 MHz to + 9.999 Mhz */ +#define S_MEM_SPLT_OFST 0x512 /* default split offset 4 bytes little endian last byte sign*/ +#define S_MEM_SPLT_LOCK 0x513 /* split lock set */ + /* values 0.000 MHz to + 9.999 Mhz */ +#define S_MEM_HF_DUP_OFST 0x514 /* default HF band duplex offset 3 byte little endian */ +#define S_MEM_6M_DUP_OFST 0x515 /* default 50 mHz duplex offset 3 byte little endian */ +#define S_MEM_2M_DUP_OFST 0x516 /* default 144 MHz duplex offset 3 byte little endian */ +#define S_MEM_AUTO_RPTR 0x518 /* auto repeater set 0=OFF; 1=ON-1; 2=ON-2 */ +#define S_MEM_LANG 0x523 /* 0=English 1=Japanese for voice announcer */ +#define S_MEM_TRCV 0x536 /* CI-V trancieve mode */ +#define S_MEM_CMP_LVL 0x538 /* speech compressor level 0-10 */ +#define S_MEM_SBASS 0x539 /* SSB TX tone bass level */ +#define S_MEM_RTTY_FL_PB 0x562 /* 0=250 Hz, 1=300' 2 = 350, 3 = 500, 4 = 1 KHz */ +#define S_MEM_RTTY_TWNPK 0x563 /* rtty twin peak filter off/on */ +#define S_MEM_SCN_SPD 0x570 /* 0 = low; 1 = high */ +#define S_MEM_NB_LVL 0x572 /* NB level 0-255 */ +#define S_MEM_VOX_GN_LVL 0x573 /* vox gain */ +#define S_MEM_AVOX_GN_LVL 0x574 /* anti-vox gain */ +#define S_MEM_VOX_DEL_LVL 0x575 /* vox delay 0=0 - 20=2.0 sec */ + +static const struct confparams ic746pro_ext_parms[] = { + { TOK_SSBBASS, "ssbbass", "SSB Tx Tone (Bass)", "SSB Tx Tone (Bass)", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } + }, + { TOK_SQLCTRL, "sqlctrl", "RF/Sql control", "set RF/Squelch control", + NULL, RIG_CONF_COMBO, { .c = {{ "Auto", "Sql", "RF+Sql", NULL }} } + }, + { TOK_RTTY_FLTR, "rttyfltr", "RTTY Fltr Width preset", "Set/Read RTTY preset filter width", + "3", RIG_CONF_COMBO, { .c = {{"250", "300", "350", "500", "1000", NULL }} } + }, + { RIG_CONF_END, NULL, } +}; + + +/* + * NUMERIC: val.f + * COMBO: val.i, starting from 0 + * STRING: val.cs for set, val.s for get + * CHECKBUTTON: val.i 0/1 + */ + + /* * ic746pro rig capabilities. */ @@ -353,6 +402,7 @@ const struct rig_caps ic746pro_caps = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, +.extparms = ic746pro_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ @@ -425,7 +475,7 @@ const struct rig_caps ic746pro_caps = { {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, - /* There are 5 rtty filters when rtty filter mode is set (default condition) { 1k, 500, 350, 300, 250 }. These are fixed. If rtty filter mode is unset there are 3 general IF filters { 2.4k, 500, 250 are the defaults }. These can be changed. There is a "twin-peak" filter mode as well. It boosts the 2125 and 2295 recieve frequency reponse. I'm not sure what the icom_defs S_FUNC_RNF (rtty notch filter) is supposed to refer to, it has no notch function, but, the commands turns the rtty filter mode on and off. Changed to S_FUNC_RF */ + /* There are 5 rtty filters when rtty filter mode is set (default condition) { 1k, 500, 350, 300, 250 }. These are fixed. If rtty filter mode is unset there are 3 general IF filters { 2.4k, 500, 250 are the defaults }. These can be changed. There is a "twin-peak" filter mode as well. It boosts the 2125 and 2295 recieve frequency reponse. The S_FUNC_RF (rtty filter) turns the rtty filter mode on and off. */ {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(500)}, /* RTTY & "normal" IF Filters */ {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(250)}, /* RTTY & "narrow" IF Filters */ @@ -487,10 +537,155 @@ const struct rig_caps ic746pro_caps = { .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, +.set_ext_parm = ic746pro_set_ext_parm, +.get_ext_parm = ic746pro_get_ext_parm, .get_channel = ic746pro_get_channel, }; +/* + * Assumes rig!=NULL, rig->state.priv!=NULL + */ +static int ic746pro_set_ext_parm(RIG *rig, token_t token, value_t val) +{ + struct icom_priv_data *priv; + struct rig_state *rs; + unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; + int ack_len, ep_len, val_len; + int ep_cmd = C_CTL_MEM; + int ep_sc; /* Subcommand in $1A $05xx */ + int icom_val = 0; + int retval; + + rs = &rig->state; + priv = (struct icom_priv_data*)rs->priv; + + ep_len = 0; /* 0 implies BCD data */ + val_len = 1; + + switch(token) { + case TOK_SSBBASS: + ep_sc = S_MEM_SBASS ; + icom_val = val.f; + break; + case TOK_SQLCTRL: + ep_sc = S_MEM_SQL_CTL; + /* TODO: check range this actually doesn't decode the input type 'string' */ + icom_val = val.i; + break; + case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 = 250, 300, 350, 500, 1000 */ + if (val.f < 0 || val.f > 4) return -RIG_EINVAL; + ep_sc = S_MEM_RTTY_FL_PB; + icom_val = val.f; + break; + default: + return -RIG_EINVAL; + } + + if (ep_len == 0) { + to_bcd_be(epbuf, (long long)icom_val, val_len*2); + ep_len += val_len; + } + + retval = icom_transaction (rig, ep_cmd, ep_sc, epbuf, ep_len, + ackbuf, &ack_len); + if (retval != RIG_OK) + return retval; + + if (ack_len != 1 || ackbuf[0] != ACK) { + rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " + "len=%d\n", __FUNCTION__, ackbuf[0], ack_len); + return -RIG_ERJCTED; + } + return RIG_OK; +} + +/* + * Assumes rig!=NULL, rig->state.priv!=NULL + * and val points to a buffer big enough to hold the conf value. + */ +static int ic746pro_get_ext_parm(RIG *rig, token_t token, value_t *val) +{ + struct icom_priv_data *priv; + struct rig_state *rs; + const struct confparams *cfp; + + unsigned char resbuf[MAXFRAMELEN]; + int res_len, icom_val; + int cmdhead; + int retval; + + int ep_cmd = C_CTL_MEM; + int ep_sc; /* Subcommand in $1A $05xx */ + + rs = &rig->state; + priv = (struct icom_priv_data*)rs->priv; + + switch(token) { + case TOK_SSBBASS: + ep_sc = S_MEM_SBASS ; + break; + case TOK_SQLCTRL: + ep_sc = S_MEM_SQL_CTL; + break; + case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 */ + ep_sc = S_MEM_RTTY_FL_PB; + break; + default: + rig_debug(RIG_DEBUG_ERR,"Unsupported get_ext_parm %d", token); + return -RIG_EINVAL; + } + + retval = icom_transaction (rig, ep_cmd, ep_sc, NULL, 0, + resbuf, &res_len); + if (retval != RIG_OK) + return retval; + + /* + * strbuf should contain Cn,Sc,Data area + */ + cmdhead = (ep_sc == -1) ? 1:S_MEM_SC_LEN + 1; + res_len -= cmdhead; +/* should echo cmd, subcmd and then data, if you get an ack something is wrong */ + if (resbuf[0] != ep_cmd) { + if (resbuf[0] == ACK) { + rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); + return -RIG_EPROTO; + } + else { + rig_debug(RIG_DEBUG_ERR,"%s: ack NG (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); + return -RIG_ERJCTED; + } + } + cfp = rig_ext_lookup_tok(rig, token); + switch(cfp->type) { + case RIG_CONF_STRING: + memcpy(val->s, resbuf, res_len); + break; + case RIG_CONF_COMBO: + val->i = from_bcd_be(resbuf+cmdhead, res_len*2); + break; + case RIG_CONF_NUMERIC: + val->f = from_bcd_be(resbuf+cmdhead, res_len*2); + break; + default: + rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); + return -RIG_EPROTO; + + /* The examples of code usage for RIG_CONF_NUMERIC types seems to be restricted to raw floating + point values. Although the Val definitions allow both integer and floating point types The combo + types appear to be left in undecoded form*/ + } + rig_debug(RIG_DEBUG_TRACE,"%s: %d %d %d %f\n", + __FUNCTION__, res_len, icom_val, val->i, val->f); + + return RIG_OK; +} + + /* * icom_set_parm * Assumes rig!=NULL @@ -517,10 +712,9 @@ int ic746_set_parm(RIG *rig, setting_t parm, value_t val) else { if ((val.i == RIG_ANN_ENG)||(val.i == RIG_ANN_JAP)) { prm_cn = C_CTL_MEM; - prm_sc = S_MEM_LANG >> 8; - prmbuf[0] = S_MEM_LANG & 0xff; - prm_len = 2; - prmbuf[1] = (val.i == RIG_ANN_ENG ? 0 : 1); + prm_sc = S_MEM_LANG; + prm_len = 1; + prmbuf[0] = (val.i == RIG_ANN_ENG ? 0 : 1); } else { rig_debug(RIG_DEBUG_ERR,"Unsupported set_parm_ann %d\n", val.i); @@ -529,14 +723,14 @@ int ic746_set_parm(RIG *rig, setting_t parm, value_t val) } break; case RIG_PARM_BACKLIGHT: - prmbuf[0] = S_MEM_BKLIT; - prm_len = 3; + prm_sc = S_MEM_BKLIT; + prm_len = 2; icom_val = val.f * 255 ; to_bcd_be(prmbuf + 1, (long long)icom_val, 4); break; case RIG_PARM_BEEP: - prmbuf[0] = S_MEM_BEEP; - prm_len = 2; + prm_sc = S_MEM_BEEP; + prm_len = 1; prmbuf[1] = val.i; break; default: @@ -564,28 +758,27 @@ int ic746_set_parm(RIG *rig, setting_t parm, value_t val) */ int ic746_get_parm(RIG *rig, setting_t parm, value_t *val) { - unsigned char resbuf[MAXFRAMELEN], data; + unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val; int prm_cn, prm_sc; int cmdhead; int retval; prm_cn = C_CTL_MEM; - prm_sc = S_MEM_PARM; switch (parm) { case RIG_PARM_BACKLIGHT: - data = S_MEM_BKLIT; + prm_sc = S_MEM_BKLIT; break; case RIG_PARM_BEEP: - data = S_MEM_BEEP; + prm_sc = S_MEM_BEEP; break; default: rig_debug(RIG_DEBUG_ERR,"Unsupported get_parm %d", parm); return -RIG_EINVAL; } - retval = icom_transaction (rig, prm_cn, prm_sc, &data, 1, + retval = icom_transaction (rig, prm_cn, prm_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) return retval; @@ -598,8 +791,8 @@ int ic746_get_parm(RIG *rig, setting_t parm, value_t *val) /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != prm_cn) { if (resbuf[0] == ACK) { - rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " - "len=%d\n", __FUNCTION__,resbuf[0],res_len); + rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); return -RIG_EPROTO; } else { @@ -609,7 +802,7 @@ int ic746_get_parm(RIG *rig, setting_t parm, value_t *val) } } - icom_val = from_bcd_be(resbuf+cmdhead, res_len*2); /* is this method necessary? Why not just use unsigned char directly on the buf ? */ + icom_val = from_bcd_be(resbuf+cmdhead, res_len*2); if (RIG_PARM_IS_FLOAT(parm)) val->f = (float)icom_val/255; else @@ -631,7 +824,7 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) { struct icom_priv_data *priv; struct rig_state *rs; - unsigned char chanbuf[46], databuf[32], data; + unsigned char chanbuf[46], databuf[32]; mem_buf_t *membuf; int chan_len, freq_len, retval, data_len, sc, band; @@ -682,7 +875,7 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) strcpy(chan->channel_desc, " "); /* - * freqbuf should contain Cn,Sc,Data area + * chanbuf should contain Cn,Sc, Chan #, Data area */ if ((chan_len != freq_len*2+40) && (chan_len != 1)) { rig_debug(RIG_DEBUG_ERR,"ic746pro_get_channel: wrong frame len=%d\n", @@ -712,12 +905,11 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) /* offset is default for the band & is not stored in channel memory. The following retrieves the system default for the band */ band = (int) chan->freq / 1000000; /* hf, 2m or 6 m */ - sc = S_MEM_PARM; - if (band < 50 ) data = S_MEM_HF_DUP_OFST; - else if (band < 108) data = S_MEM_6M_DUP_OFST; - else data = S_MEM_2M_DUP_OFST; + if (band < 50 ) sc = S_MEM_HF_DUP_OFST; + else if (band < 108) sc = S_MEM_6M_DUP_OFST; + else sc = S_MEM_2M_DUP_OFST; retval = icom_transaction (rig, C_CTL_MEM, sc, - &data, 1, databuf, &data_len); + NULL, 0 , databuf, &data_len); if (retval != RIG_OK) return retval; chan->rptr_offs = from_bcd(databuf + 3, 6) * 100; @@ -726,7 +918,7 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) chan->ctcss_sql = from_bcd_be(membuf->rx.tone_sql, 6); chan->dcs_code = from_bcd_be(membuf->rx.dcs.code, 4); /* The dcs information include in the channel includes polarity information - for both tx and recieve. Both directions are enabled when in dcs mode */ + for both tx and receive. Both directions are enabled when in dcs mode */ chan->tx_freq = from_bcd(membuf->tx.freq, freq_len*2); icom2rig_mode(rig, membuf->tx.mode, membuf->tx.pb, diff --git a/icom/ic756.c b/icom/ic756.c index 5fa768ee3..ef62de49c 100644 --- a/icom/ic756.c +++ b/icom/ic756.c @@ -2,7 +2,7 @@ * Hamlib CI-V backend - description of IC-756 and variations * Copyright (c) 2000-2004 by Stephane Fillod * - * $Id: ic756.c,v 1.13 2006-07-18 22:51:42 n0nb Exp $ + * $Id: ic756.c,v 1.14 2006-09-22 19:55:58 n0nb 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 @@ -44,7 +44,7 @@ /* * 100W in all modes but AM (40W) */ -#define IC756_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) +#define IC756_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC756_AM_TX_MODES (RIG_MODE_AM) #define IC756PRO_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_RF) @@ -380,10 +380,8 @@ static const struct icom_priv_caps ic756pro2_priv_caps = { /* * These TOKEN_BACKEND's are on a different name space than conf's */ -#define TOK_SSBBASS TOKEN_BACKEND(1) -#define TOK_MEMNAME TOKEN_BACKEND(2) -#define TOK_SQLCTRL TOKEN_BACKEND(3) -#define TOK_MYCALL TOKEN_BACKEND(4) +#define TOK_MEMNAME TOKEN_BACKEND(1) +#define TOK_MYCALL TOKEN_BACKEND(2) static const struct confparams ic756pro2_ext_parms[] = { { TOK_SSBBASS, "ssbbass", "SSB Tx Tone (Bass)", "SSB Tx Tone (Bass)", @@ -398,6 +396,9 @@ static const struct confparams ic756pro2_ext_parms[] = { { TOK_MYCALL, "mycall", "Callsign", "My call sign", NULL, RIG_CONF_STRING, { } }, + { TOK_RTTY_FLTR, "rttyfltr", "RTTY Fltr Width preset", "Set/Read RTTY preset filter width", + "3", RIG_CONF_COMBO, { .c = {{"250", "300", "350", "500", "1000", NULL }} } + }, { RIG_CONF_END, NULL, } }; @@ -408,13 +409,28 @@ static const struct confparams ic756pro2_ext_parms[] = { * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ + + /*IC-756Pro Rig parameters Only available in this namespace*/ +#define S_MEM_SC_LEN 2 /* 756PRO S_MEM subcmd length */ +#define S_MEM_SBASS 0x501 /* SSB TX tone bass level */ +#define S_MEM_NAME 0x514 /* send/read memory name */ +#define S_MEM_MYCALL 0x515 +#define S_MEM_BEEP 0x520 /* Button confirmation */ +#define S_MEM_SQL_CTL 0x522 /* RF/SQL ctl set 0=auto; 1 = sql; 2 = RF+SQL */ +#define S_MEM_QSPLT 0x524 /* enable quick split mode */ +#define S_MEM_TRCV 0x532 /* CI-V trancieve mode */ +#define S_MEM_LANG 0x536 /* 0=English 1=Japanese for voice announcer */ +#define S_MEM_SCN_SPD 0x556 /* 0 = low; 1 = high */ +#define S_MEM_RTTY_FL_PB 0x561 /* 0=250 Hz, 1=300' 2 = 350, 3 = 500, 4 = 1 KHz */ +#define S_MEM_RTTY_TWNPK 0x562 /* rtty twin peak filter off/on */ + static int ic756pro2_set_ext_parm(RIG *rig, token_t token, value_t val); static int ic756pro2_get_ext_parm(RIG *rig, token_t token, value_t *val); #define IC756PROII_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROII_1HZ_TS_MODES IC756PROII_ALL_RX_MODES -#define IC756PROII_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) +#define IC756PROII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROII_AM_TX_MODES (RIG_MODE_AM) @@ -567,7 +583,8 @@ static int ic756pro2_set_ext_parm(RIG *rig, token_t token, value_t val) struct rig_state *rs; unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, ep_len, val_len; - int ep_menu; /* Menu in $1A $05 */ + int ep_cmd = C_CTL_MEM; + int ep_sc; /* Subcommand in $1A $05xx */ int icom_val = 0; int retval; @@ -579,36 +596,40 @@ static int ic756pro2_set_ext_parm(RIG *rig, token_t token, value_t val) switch(token) { case TOK_SSBBASS: - ep_menu = 0x01; + ep_sc = S_MEM_SBASS ; icom_val = val.f; break; case TOK_MEMNAME: - ep_menu = 0x14; + ep_sc = S_MEM_NAME; icom_val = val.i ? 1 : 0; break; case TOK_SQLCTRL: - ep_menu = 0x22; - /* TODO: check range */ + ep_sc = S_MEM_SQL_CTL; + /* TODO: check range this actually doesn't decode the input type 'string' */ icom_val = val.i; break; case TOK_MYCALL: /* max 10 ASCII char */ ep_len = strlen(val.cs); if (ep_len > 10) return -RIG_EINVAL; - ep_menu = 0x15; - memcpy(epbuf+1, val.cs, ep_len); + ep_sc = S_MEM_MYCALL; + memcpy(epbuf, val.cs, ep_len); + break; + case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 = 250, 300, 350, 500, 1000 */ + if (val.i < 0 || val.i > 4) return -RIG_EINVAL; + ep_sc = S_MEM_RTTY_FL_PB; + icom_val = val.f; break; default: return -RIG_EINVAL; } - epbuf[0] = ep_menu; - if (ep_len++ == 0) { - to_bcd_be(epbuf+1, (long long)icom_val, val_len*2); + if (ep_len == 0) { + to_bcd_be(epbuf, (long long)icom_val, val_len*2); ep_len += val_len; } - retval = icom_transaction (rig, C_CTL_MEM, 0x05, epbuf, ep_len, + retval = icom_transaction (rig, ep_cmd, ep_sc, epbuf, ep_len, ackbuf, &ack_len); if (retval != RIG_OK) return retval; @@ -629,14 +650,86 @@ static int ic756pro2_get_ext_parm(RIG *rig, token_t token, value_t *val) { struct icom_priv_data *priv; struct rig_state *rs; + const struct confparams *cfp; + + unsigned char resbuf[MAXFRAMELEN]; + int res_len, icom_val; + int cmdhead; + int retval; + + int ep_cmd = C_CTL_MEM; + int ep_sc; /* Subcommand in $1A $05xx */ rs = &rig->state; priv = (struct icom_priv_data*)rs->priv; switch(token) { + case TOK_SSBBASS: + ep_sc = S_MEM_SBASS ; + break; + case TOK_MEMNAME: + ep_sc = S_MEM_NAME; + break; + case TOK_SQLCTRL: + ep_sc = S_MEM_SQL_CTL; + break; + case TOK_MYCALL: /* max 10 ASCII char */ + ep_sc = S_MEM_MYCALL; + break; + case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 */ + ep_sc = S_MEM_RTTY_FL_PB; + break; default: - return -RIG_ENIMPL; + rig_debug(RIG_DEBUG_ERR,"Unsupported get_ext_parm %d", token); + return -RIG_EINVAL; } + + retval = icom_transaction (rig, ep_cmd, ep_sc, NULL, 0, + resbuf, &res_len); + if (retval != RIG_OK) + return retval; + + /* + * strbuf should contain Cn,Sc,Data area + */ + cmdhead = (ep_sc == -1) ? 1:S_MEM_SC_LEN + 1; + res_len -= cmdhead; +/* should echo cmd, subcmd and then data, if you get an ack something is wrong */ + if (resbuf[0] != ep_cmd) { + if (resbuf[0] == ACK) { + rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); + return -RIG_EPROTO; + } + else { + rig_debug(RIG_DEBUG_ERR,"%s: ack NG (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); + return -RIG_ERJCTED; + } + } + cfp = rig_ext_lookup_tok(rig, token); + switch(cfp->type) { + case RIG_CONF_STRING: + memcpy(val->s, resbuf, res_len); + break; + case RIG_CONF_COMBO: + val->i = from_bcd_be(resbuf+cmdhead, res_len*2); + break; + case RIG_CONF_NUMERIC: + val->f = from_bcd_be(resbuf+cmdhead, res_len*2); + break; + default: + rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); + return -RIG_EPROTO; + + /* The examples of code usage for RIG_CONF_NUMERIC types seems to be restricted to raw floating + point values. Although the Val definitions allow both integer and floating point types The combo + types appear to be left in undecoded form*/ + } + rig_debug(RIG_DEBUG_TRACE,"%s: %d %d %d %f\n", + __FUNCTION__, res_len, icom_val, val->i, val->f); + return RIG_OK; } @@ -657,7 +750,7 @@ static const struct icom_priv_caps ic756pro3_priv_caps = { #define IC756PROIII_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROIII_1HZ_TS_MODES IC756PROIII_ALL_RX_MODES -#define IC756PROIII_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) +#define IC756PROIII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROIII_AM_TX_MODES (RIG_MODE_AM) diff --git a/icom/icom.c b/icom/icom.c index 65f447827..9682ccf80 100644 --- a/icom/icom.c +++ b/icom/icom.c @@ -2,7 +2,7 @@ * Hamlib CI-V backend - main file * Copyright (c) 2000-2005 by Stephane Fillod * - * $Id: icom.c,v 1.96 2006-07-18 22:51:42 n0nb Exp $ + * $Id: icom.c,v 1.97 2006-09-22 19:55:58 n0nb 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 @@ -178,12 +178,14 @@ const struct ts_sc_list ic910_ts_sc_list[] = { { 0, 0 }, }; -const struct rtty_fltr_list rtty_fil[] = { - { Hz(250), 0x00 }, - { Hz(300), 0x01 }, - { Hz(350), 0x02 }, - { Hz(500), 0x03 }, - { kHz(1), 0x04 }, +/* rtty filter list for some DSP rigs ie PRO */ +const pbwidth_t rtty_fil[] = { + Hz(250), + Hz(300), + Hz(350), + Hz(500), + kHz(1), + 0, }; struct icom_addr { @@ -448,6 +450,45 @@ int icom_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) } +/* icom_get_dsp_flt + returns the dsp filter width in hz or 0 if the command is not implemented or error. This allows the default parameters to be assigned from the get_mode routine if the command is not implemented. + Assumes rig != null and the current mode is in mode. + + Has been tested for IC-746pro, Should work on the all dsp rigs ie pro models. + The 746 documentation says it has the get_if_filter, but doesn't give any decoding information ? Please test. +*/ + +pbwidth_t icom_get_dsp_flt(RIG *rig, rmode_t mode) { + + int retval, res_len, rfstatus; + unsigned char resbuf[MAXFRAMELEN]; + value_t rfwidth; + + if (rig_has_get_func(rig, RIG_FUNC_RF) && (mode & (RIG_MODE_RTTY | RIG_MODE_RTTYR))) { + if(!rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_RF, &rfstatus) && (rfstatus)) { + retval = rig_get_ext_parm (rig, TOK_RTTY_FLTR, &rfwidth); + if (retval != RIG_OK) return 0; /* use default */ + else return rtty_fil[rfwidth.i]; + } + } + retval = icom_transaction (rig, C_CTL_MEM, S_MEM_FILT_WDTH, 0, 0, + resbuf, &res_len); + if (retval != RIG_OK) { + rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " + "len=%d\n", __FUNCTION__,resbuf[0],res_len); + return 0; /* use default */ + } + if (res_len == 3 && resbuf[0] == C_CTL_MEM) { + int i; + i = (int) from_bcd(resbuf + 2, 2); + + if (mode & RIG_MODE_AM) return (i + 1)* 200; /* Ic_7800 */ + else if ( mode & (RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY | RIG_MODE_RTTYR)) return i < 10 ? ++i * 50 : (i -4) * 100; + } + return 0; +} + + /* * icom_set_mode * Assumes rig!=NULL, rig->state.priv!=NULL @@ -473,7 +514,7 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) icmode_ext = -1; retval = icom_transaction (rig, C_SET_MODE, icmode, &icmode_ext, - icmode_ext == -1 ? 0 : 1, ackbuf, &ack_len); + (icmode_ext == -1 ? 0 : 1), ackbuf, &ack_len); if (retval != RIG_OK) return retval; @@ -521,6 +562,10 @@ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) icom2rig_mode(rig, modebuf[1], mode_len==2 ? modebuf[2] : -1, mode, width); + /* Most rigs return 1-wide, 2-normal,3-narrow For DSP rigs these are presets, can be programmed for 30 - 41 bandwidths, depending on mode Lets check for dsp filters */ + + if (retval = icom_get_dsp_flt(rig, *mode)) *width = retval; + return RIG_OK; } diff --git a/icom/icom.h b/icom/icom.h index 495aaf08c..e702fc432 100644 --- a/icom/icom.h +++ b/icom/icom.h @@ -2,7 +2,7 @@ * Hamlib CI-V backend - main header * Copyright (c) 2000-2004 by Stephane Fillod * - * $Id: icom.h,v 1.71 2006-07-18 22:51:42 n0nb Exp $ + * $Id: icom.h,v 1.72 2006-09-22 19:55:59 n0nb 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 @@ -37,10 +37,12 @@ * defines used by comp_cal_str in rig.c * STR_CAL_LENGTH is the lenght of the S Meter calibration table * STR_CAL_S0 is the value in dB of the lowest value (not even in table) + * MULTIB_SUBCMD allows the dsp rigs ie pro models to use multibyte subcommands for all the extra + * parameters and levels. */ #define STR_CAL_LENGTH 16 #define STR_CAL_S0 -54 - +#define MULTIB_SUBCMD /* * minimal channel caps. @@ -79,14 +81,6 @@ struct ts_sc_list { unsigned char sc; /* sub command */ }; -/* - * rtty filter passband width; available on pro rigs - */ -struct rtty_fltr_list { - shortfreq_t bw; /* filter width */ - unsigned char sel; -}; - /** * \brief Pipelined tuning state data structure. */ @@ -127,7 +121,9 @@ extern const struct ts_sc_list ic706_ts_sc_list[]; extern const struct ts_sc_list ic910_ts_sc_list[]; extern const struct ts_sc_list ic718_ts_sc_list[]; -extern const struct rtty_fltr_list rtty_fil[]; +extern const pbwidth_t rtty_fil[]; /* rtty filter passband width; available on pro rigs */ + +pbwidth_t icom_get_dsp_flt(RIG *rig, rmode_t mode); int icom_init(RIG *rig); int icom_cleanup(RIG *rig); diff --git a/icom/icom_defs.h b/icom/icom_defs.h index fb7b839f6..3286c75c0 100644 --- a/icom/icom_defs.h +++ b/icom/icom_defs.h @@ -2,7 +2,7 @@ * Hamlib CI-V backend - defines for the ICOM "CI-V" interface. * Copyright (c) 2000-2004 by Stephane Fillod * - * $Id: icom_defs.h,v 1.18 2006-07-18 22:51:42 n0nb Exp $ + * $Id: icom_defs.h,v 1.19 2006-09-22 19:55:59 n0nb 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 @@ -90,7 +90,7 @@ #define C_SND_CW 0x17 /* Send CW message */ #define C_SET_PWR 0x18 /* Set Power ON/OFF, Sc */ #define C_RD_TRXID 0x19 /* Read transceiver ID code */ -#define C_CTL_MEM 0x1a /* Misc memory/bank functions, Sc */ +#define C_CTL_MEM 0x1a /* Misc memory/bank/rig control functions, Sc */ #define C_SET_TONE 0x1b /* Set tone frequency */ #define C_CTL_PTT 0x1c /* Control Transmit On/Off, Sc */ #define C_CTL_MISC 0x7f /* Miscellaneous control, Sc */ @@ -113,6 +113,8 @@ #define S_CWR 0x07 /* Set to CW Reverse */ #define S_RTTYR 0x08 /* Set to RTTY Reverse */ #define S_AMS 0x11 /* Set to AMS */ +#define S_PSK 0x12 /* 7800 PSK USB */ +#define S_PSKR 0x13 /* 7800 PSK LSB */ #define S_R7000_SSB 0x05 /* Set to SSB on R-7000 */ #define PD_WIDE 0x01 /* Wide */ @@ -154,6 +156,7 @@ #define S_SCAN_PRIO 0x42 /* Priority / window scan */ #define S_SCAN_NSLCT 0xB0 /* Set as non select channel */ #define S_SCAN_SLCT 0xB1 /* Set as select channel */ +#define S_SCAN_SL_NUM 0xB2 /* select programed mem scan 7800 only */ #define S_SCAN_RSMOFF 0xD0 /* Set scan resume OFF */ #define S_SCAN_RSMON 0xD3 /* Set scan resume ON */ @@ -228,6 +231,7 @@ #define S_RFML 0x11 /* Read RF-meter level */ #define S_SWR 0x12 /* Read SWR-meter level */ #define S_ALC 0x13 /* Read ALC-meter level */ +#define S_CMP 0x14 /* Read COMP-meter level */ /* * Function settings (C_CTL_FUNC) subcommands Set and Read @@ -235,7 +239,7 @@ #define S_FUNC_PAMP 0x02 /* Preamp setting */ #define S_FUNC_AGCOFF 0x10 /* IC-R8500 only */ #define S_FUNC_AGCON 0x11 /* IC-R8500 only */ -#define S_FUNC_AGC 0x12 /* AGC setting */ +#define S_FUNC_AGC 0x12 /* AGC setting presets: the dsp models allow these to be modified */ #define S_FUNC_NBOFF 0x20 /* IC-R8500 only */ #define S_FUNC_NBON 0x21 /* IC-R8500 only */ #define S_FUNC_NB 0x22 /* NB setting */ @@ -255,6 +259,8 @@ #define S_FUNC_AFC 0x4A /* Auto Frequency Control (AFC) setting */ #define S_FUNC_DTCS 0x4B /*DTCS tone code squelch setting*/ #define S_FUNC_VSC 0x4C /* voice squelch control useful for scanning*/ +#define S_FUNC_TW_PK 0x4F /* RTTY Twin Peak filter 0= off 1 = on */ +#define S_FUNC_DIAL_LK 0x50 /* Dial lock */ /* * Set Power On/Off (C_SET_PWR) subcommands @@ -269,15 +275,16 @@ #define S_ANT_TUN 0x01 /* Auto tuner 0=OFF, 1 = ON, 2=Start Tuning */ /* - * Misc contents (C_CTL_MEM) subcommands + * Misc contents (C_CTL_MEM) subcommands applies to newer rigs. */ #define S_MEM_CNTNT 0x00 /* Memory content 2 bigendian */ #define S_MEM_BAND_REG 0x01 /* band stacking register */ #define S_MEM_FILT_WDTH 0x03 /* current passband filter width */ -#define S_MEM_PARM 0x05 /* rig parameters; extended parm # + param value */ +#define S_MEM_PARM 0x05 /* rig parameters; extended parm # + param value: should be coded */ + /* in the rig files because they are different for each rig */ #define S_MEM_DATA_MODE 0x06 /* data mode */ #define S_MEM_TX_PB 0x07 /* SSB tx passband */ -#define S_MEM_FLTR_SHAPE 0x08 /* filter shape 0=sharp 1=soft */ +#define S_MEM_FLTR_SHAPE 0x08 /* DSP filter shape 0=sharp 1=soft */ /* Icr75c */ #define S_MEM_CNTNT_SLCT 0x01 @@ -294,27 +301,6 @@ #define S_MEM_SATMODE 0x07 /* Satellite mode (on/off) */ #define S_MEM_BANDSCOPE 0x08 /* Simple bandscope (on/off) */ - /*IC-746Pro Rig parameters Sc=S_MEM_PARM */ -#define S_MEM_LCD_CONT 0x01 /* LCD Contrast 0-256/0-100% */ -#define S_MEM_BKLIT 0x02 /* Backlight 0-256/0-100% */ -#define S_MEM_BEEP 0x06 /* Button confirmation */ - - /* values -9.999 MHz to + 9.999 Mhz */ -#define S_MEM_SPLT_OFST 0x12 /* default split offset 4 bytes little endian last byte sign*/ - - /* values 0.000 MHz to + 9.999 Mhz */ -#define S_MEM_HF_DUP_OFST 0x14 /* default HF band duplex offset 3 byte little endian */ -#define S_MEM_6M_DUP_OFST 0x15 /* default 50 mHz duplex offset 3 byte little endian */ -#define S_MEM_2M_DUP_OFST 0x16 /* default 144 MHz duplex offset 3 byte little endian */ - -#define S_MEM_LANG 0x23 /* 0=English 1=Japanese */ -#define S_MEM_RTTY_FLTR_PB 0x62 /* 0=250 Hz, 1=300' 2 = 350, 3 = 500, 4 = 1 KHz */ -#define S_MEM_RTTY_TWNPEAK 0x63 /* rtty twin peak filter off/on */ -#define S_MEM_SCN_SPD 0x70 /* 0 = low; 1 = high */ -#define S_MEM_NB_LVL 0x72 /* NB level 0-255 */ -#define S_MEM_VOX_GN_LVL 0x73 -#define S_MEM_AVOX_GN_LVL 0x74 /* anti-vox gain */ -#define S_MEM_VOX_DEL_LVL 0x75 /* vox delay 0=0 - 20=2.0 sec */ /* * Tone control (C_SET_TONE) subcommands @@ -359,4 +345,18 @@ #define S_PRM_SLPTM 0x33 #define S_PRM_TIME 0x27 +/* + * Tokens for Extra Level and Parameters common to multiple rigs. Use token # > 99. Defined here so they + * will be available in ICOM name space. They have different internal commands primarily in dsp rigs. These + * tokens are used ext_lvl and ext_parm funtions in the individual rig files. + * Extra parameters which are rig specific should be coded in the individual rig files and token #s < 100. + */ + +#define TOKEN_BACKEND(t) (t) + +#define TOK_RTTY_FLTR TOKEN_BACKEND(100) +#define TOK_SSBBASS TOKEN_BACKEND(101) +#define TOK_SQLCTRL TOKEN_BACKEND(102) + + #endif /* _ICOM_DEFS_H */ diff --git a/src/ext.c b/src/ext.c index 203aab684..9da202a86 100644 --- a/src/ext.c +++ b/src/ext.c @@ -2,7 +2,7 @@ * Hamlib Interface - extrq parameter interface * Copyright (c) 2000-2004 by Stephane Fillod * - * $Id: ext.c,v 1.3 2004-10-02 10:32:08 fillods Exp $ + * $Id: ext.c,v 1.4 2006-09-22 19:55:59 n0nb 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 @@ -98,6 +98,29 @@ const struct confparams * HAMLIB_API rig_ext_lookup(RIG *rig, const char *name) return NULL; } +/* + * lookup ext token, return pointer to confparams struct. + * + * lookup extlevels table first, then fall back to extparms. + * + * Returns NULL if nothing found + */ +const struct confparams * HAMLIB_API rig_ext_lookup_tok(RIG *rig, token_t token) +{ + const struct confparams *cfp; + + if (!rig || !rig->caps) + return NULL; + + for (cfp = rig->caps->extlevels; cfp && cfp->token; cfp++) + if (cfp->token == token) + return cfp; + for (cfp = rig->caps->extparms; cfp && cfp->token; cfp++) + if (cfp->token == token) + return cfp; + return NULL; +} + /* * Simple lookup returning token id assicated with name */