diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..9eab85a78 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 diff --git a/.gitignore b/.gitignore index 4eb86cb8a..76e256014 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ *.la *.orig *.swp +$depbase.Tpo Makefile Makefile.in aclocal.m4 diff --git a/AUTHORS b/AUTHORS index e73e2129c..7f48f4783 100644 --- a/AUTHORS +++ b/AUTHORS @@ -361,4 +361,4 @@ Terry Dawson, VK2KTJ, Alexander Sack Nirgal Vourgère Andrew Errington -Kārlis Millers YL3CAAK +Kārlis Millers YL3ALK diff --git a/dummy/dummy.c b/dummy/dummy.c index 49a6a8fbc..4b5531f78 100644 --- a/dummy/dummy.c +++ b/dummy/dummy.c @@ -76,6 +76,9 @@ static const struct confparams dummy_ext_levels[] = { { TOK_EL_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", NULL, RIG_CONF_BUTTON }, + { TOK_EL_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", + "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } + }, { RIG_CONF_END, NULL, } }; @@ -92,7 +95,7 @@ static const struct confparams dummy_cfg_params[] = { { TOK_CFG_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", "DX", RIG_CONF_STRING, { } }, - { TOK_CFG_STATIC_DATA, "static_data", "Static data", "Output only static data, no randomization of S-meter values", + { TOK_CFG_STATIC_DATA, "static_data", "Static data", "Output only static data, no randomization of meter values", "0", RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } @@ -815,23 +818,54 @@ static int dummy_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) if (idx >= RIG_SETTING_MAX) return -RIG_EINVAL; - if (level == RIG_LEVEL_STRENGTH || level == RIG_LEVEL_RAWSTR) { - if (priv->static_data) { - curr->levels[idx].i = -12; - } else { - /* make S-Meter jiggle */ - int qrm = -56; - if (curr->freq < MHz(7)) + switch (level) { + case RIG_LEVEL_STRENGTH: + case RIG_LEVEL_RAWSTR: + if (priv->static_data) { + curr->levels[idx].i = -12; + } else { + /* make S-Meter jiggle */ + int qrm = -56; + if (curr->freq < MHz(7)) qrm = -20; - else if (curr->freq < MHz(21)) + else if (curr->freq < MHz(21)) qrm = -30; - else if (curr->freq < MHz(50)) + else if (curr->freq < MHz(50)) qrm = -50; - curr->levels[idx].i = qrm + time(NULL)%32 + rand()%4 - - curr->levels[LVL_ATT].i - + curr->levels[LVL_PREAMP].i; - } + curr->levels[idx].i = qrm + time(NULL)%32 + rand()%4 + - curr->levels[LVL_ATT].i + + curr->levels[LVL_PREAMP].i; + } + break; + case RIG_LEVEL_RFPOWER_METER: + if (priv->static_data) { + curr->levels[idx].f = 0.5f; + } else { + curr->levels[idx].f = (float) (time(NULL) % 32) / 64.0f + (float) (rand() % 4) / 8.0f; + } + break; + case RIG_LEVEL_COMP_METER: + if (priv->static_data) { + curr->levels[idx].f = 3.5f; + } else { + curr->levels[idx].f = 0.5f + (float) (time(NULL) % 32) / 16.0f + (float) (rand() % 200) / 20.0f; + } + break; + case RIG_LEVEL_VD_METER: + if (priv->static_data) { + curr->levels[idx].f = 13.82f; + } else { + curr->levels[idx].f = 13.82f + (float) (time(NULL) % 10) / 50.0f - (float) (rand() % 10) / 40.0f; + } + break; + case RIG_LEVEL_ID_METER: + if (priv->static_data) { + curr->levels[idx].f = 0.85f; + } else { + curr->levels[idx].f = 2.0f + (float) (time(NULL) % 320) / 16.0f - (float) (rand() % 40) / 20.0f; + } + break; } *val = curr->levels[idx]; @@ -857,6 +891,7 @@ static int dummy_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val) case TOK_EL_MAGICLEVEL: case TOK_EL_MAGICFUNC: case TOK_EL_MAGICOP: + case TOK_EL_MAGICCOMBO: break; default: @@ -910,6 +945,7 @@ static int dummy_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val) case TOK_EL_MAGICLEVEL: case TOK_EL_MAGICFUNC: case TOK_EL_MAGICOP: + case TOK_EL_MAGICCOMBO: break; default: @@ -1445,9 +1481,9 @@ static int dummy_mW2power(RIG * rig, float *power, unsigned int mwpower, * The following macros set bitmasks for the various funcs, levels, parms, * etc. This dummy backend claims support for almost all of them. */ -#define DUMMY_FUNC ((setting_t)-1UL) /* All possible functions */ -#define DUMMY_LEVEL (((setting_t)-1UL)&~(1UL<<27)) /* All levels except SQLSTAT */ -#define DUMMY_PARM ((setting_t)-1UL) /* All possible parms */ +#define DUMMY_FUNC ((setting_t)-1ULL) /* All possible functions */ +#define DUMMY_LEVEL (((setting_t)-1ULL)&~(1ULL<<27)) /* All levels except SQLSTAT */ +#define DUMMY_PARM ((setting_t)-1ULL) /* All possible parms */ #define DUMMY_VFO_OP 0x7ffffffUL /* All possible VFO OPs */ #define DUMMY_SCAN 0x7ffffffUL /* All possible scan OPs */ @@ -1521,21 +1557,34 @@ const struct rig_caps dummy_caps = { .rx_range_list1 = { {.start=kHz(150),.end=MHz(1500),.modes=DUMMY_MODES, .low_power=-1,.high_power=-1,DUMMY_VFOS, RIG_ANT_1|RIG_ANT_2}, RIG_FRNG_END, }, - .tx_range_list1 = { RIG_FRNG_END, }, + .tx_range_list1 = { {.start=kHz(150),.end=MHz(1500),.modes=DUMMY_MODES, + .low_power=W(5),.high_power=W(100),DUMMY_VFOS, RIG_ANT_1|RIG_ANT_2}, + RIG_FRNG_END, }, .rx_range_list2 = { {.start=kHz(150),.end=MHz(1500),.modes=DUMMY_MODES, .low_power=-1,.high_power=-1,DUMMY_VFOS, RIG_ANT_1|RIG_ANT_2}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DUMMY_MODES,1}, {DUMMY_MODES,RIG_TS_ANY}, RIG_TS_END, }, .filters = { - {RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY, kHz(2.4)}, - {RIG_MODE_CW, Hz(500)}, - {RIG_MODE_AM, kHz(8)}, - {RIG_MODE_AM, kHz(2.4)}, - {RIG_MODE_FM, kHz(15)}, - {RIG_MODE_FM, kHz(8)}, - {RIG_MODE_WFM, kHz(230)}, - RIG_FLT_END, + {RIG_MODE_SSB, kHz(2.4)}, + {RIG_MODE_SSB, kHz(1.8)}, + {RIG_MODE_SSB, kHz(3.0)}, + {RIG_MODE_SSB, RIG_FLT_ANY}, + {RIG_MODE_CW, Hz(500)}, + {RIG_MODE_CW, kHz(2.4)}, + {RIG_MODE_CW, Hz(50)}, + {RIG_MODE_CW, RIG_FLT_ANY}, + {RIG_MODE_RTTY, Hz(300)}, + {RIG_MODE_RTTY, kHz(2.4)}, + {RIG_MODE_RTTY, Hz(50)}, + {RIG_MODE_RTTY, RIG_FLT_ANY}, + {RIG_MODE_AM, kHz(8)}, + {RIG_MODE_AM, kHz(2.4)}, + {RIG_MODE_AM, kHz(10)}, + {RIG_MODE_FM, kHz(15)}, + {RIG_MODE_FM, kHz(8)}, + {RIG_MODE_WFM, kHz(230)}, + RIG_FLT_END, }, .max_rit = 9990, .max_xit = 9990, diff --git a/dummy/dummy.h b/dummy/dummy.h index 142f5622f..99cf0c276 100644 --- a/dummy/dummy.h +++ b/dummy/dummy.h @@ -35,6 +35,7 @@ #define TOK_EL_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_MAGICPARM TOKEN_BACKEND(4) +#define TOK_EL_MAGICCOMBO TOKEN_BACKEND(5) extern const struct rig_caps dummy_caps; diff --git a/gs232a/gs232.c b/gs232a/gs232.c index 78a85906c..b06b51534 100644 --- a/gs232a/gs232.c +++ b/gs232a/gs232.c @@ -137,7 +137,9 @@ gs232_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) unsigned u_az, u_el; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __FUNCTION__, az, el); - + if (az < 0.0){ + az = az + 360.0; + } u_az = (unsigned)rint(az); u_el = (unsigned)rint(el); @@ -196,14 +198,14 @@ gs232_rot_stop(ROT *rot) /* ************************************************************************* */ /* - * Generic GS232 (not A, not B) rotator capabilities. + * Generic GS232 Protocol (including those not correctly implmented) rotator capabilities. */ -const struct rot_caps gs232_rot_caps = { - .rot_model = ROT_MODEL_GS232, - .model_name = "GS-232", - .mfg_name = "Yaesu/Kenpro", - .version = "0.1", +const struct rot_caps gs232_generic_rot_caps = { + .rot_model = ROT_MODEL_GS232_GENERIC, + .model_name = "GS-232 Generic", + .mfg_name = "Various", + .version = "0.3", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rot_type = ROT_TYPE_AZEL, @@ -219,7 +221,7 @@ const struct rot_caps gs232_rot_caps = { .timeout = 400, .retry = 3, - .min_az = 0.0, + .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, @@ -229,6 +231,76 @@ const struct rot_caps gs232_rot_caps = { .stop = gs232_rot_stop, }; +/* ************************************************************************* */ +/* + * Generic AMSAT LVB Tracker rotator capabilities. + */ + +const struct rot_caps amsat_lvb_rot_caps = { + .rot_model = ROT_MODEL_LVB, + .model_name = "LVB Tracker", + .mfg_name = "AMSAT", + .version = "0.1", + .copyright = "LGPL", + .status = RIG_STATUS_ALPHA, + .rot_type = ROT_TYPE_AZEL, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 150, + .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 = 400, + .retry = 3, + + .min_az = -180.0, + .max_az = 450.0, /* vary according to rotator type */ + .min_el = 0.0, + .max_el = 180.0, + + .get_position = gs232_rot_get_position, + .set_position = gs232_rot_set_position, + .stop = gs232_rot_stop, +}; + + +/* ************************************************************************* */ +/* + * Generic FoxDelta ST2 rotator capabilities. + */ + +const struct rot_caps st2_rot_caps = { + .rot_model = ROT_MODEL_ST2, + .model_name = "GS232/ST2", + .mfg_name = "FoxDelta", + .version = "0.1", + .copyright = "LGPL", + .status = RIG_STATUS_ALPHA, + .rot_type = ROT_TYPE_AZEL, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 150, + .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 = 400, + .retry = 3, + + .min_az = -180.0, + .max_az = 450.0, /* vary according to rotator type */ + .min_el = 0.0, + .max_el = 180.0, + + .get_position = gs232_rot_get_position, + .set_position = gs232_rot_set_position, + .stop = gs232_rot_stop, +}; /* ************************************************************************* */ /* @@ -257,7 +329,7 @@ const struct rot_caps f1tetracker_rot_caps = { .timeout = 400, .retry = 0, - .min_az = 0.0, + .min_az = -180.0, .max_az = 360.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, diff --git a/gs232a/gs232a.c b/gs232a/gs232a.c index c791db7d3..6415c3d02 100644 --- a/gs232a/gs232a.c +++ b/gs232a/gs232a.c @@ -125,7 +125,9 @@ gs232a_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) unsigned u_az, u_el; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __FUNCTION__, az, el); - + if (az < 0.0) { + az = az + 360.0; + } u_az = (unsigned)rint(az); u_el = (unsigned)rint(el); @@ -231,6 +233,76 @@ gs232a_rot_move(ROT *rot, int direction, int speed) return RIG_OK; } +/* ************************************************************************* */ +/* + * Generic GS23 rotator capabilities. + */ + +const struct rot_caps gs23_rot_caps = { + .rot_model = ROT_MODEL_GS23, + .model_name = "GS-23", + .mfg_name = "Yaesu/Kenpro", + .version = "0.1", + .copyright = "LGPL", + .status = RIG_STATUS_ALPHA, + .rot_type = ROT_TYPE_AZEL, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 150, + .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 = 400, + .retry = 3, + + .min_az = -180.0, + .max_az = 450.0, /* vary according to rotator type */ + .min_el = 0.0, + .max_el = 180.0, + + .get_position = gs232a_rot_get_position, + .set_position = gs232a_rot_set_position, + .stop = gs232a_rot_stop, +}; + +/* ************************************************************************* */ +/* + * Generic GS232 rotator capabilities. + */ + +const struct rot_caps gs232_rot_caps = { + .rot_model = ROT_MODEL_GS232, + .model_name = "GS-232", + .mfg_name = "Yaesu/Kenpro", + .version = "0.1", + .copyright = "LGPL", + .status = RIG_STATUS_ALPHA, + .rot_type = ROT_TYPE_AZEL, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 150, + .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 = 400, + .retry = 3, + + .min_az = -180.0, + .max_az = 450.0, /* vary according to rotator type */ + .min_el = 0.0, + .max_el = 180.0, + + .get_position = gs232a_rot_get_position, + .set_position = gs232a_rot_set_position, + .stop = gs232a_rot_stop, +}; + /* ************************************************************************* */ /* * Generic GS232A rotator capabilities. @@ -240,7 +312,7 @@ const struct rot_caps gs232a_rot_caps = { .rot_model = ROT_MODEL_GS232A, .model_name = "GS-232A", .mfg_name = "Yaesu", - .version = "0.3", + .version = "0.5", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rot_type = ROT_TYPE_OTHER, @@ -256,30 +328,38 @@ const struct rot_caps gs232a_rot_caps = { .timeout = 400, .retry = 3, - .min_az = 0.0, + .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, /* requires G-5400B, G-5600B, G-5500, or G-500/G-550 */ .get_position = gs232a_rot_get_position, .set_position = gs232a_rot_set_position, - .stop = gs232a_rot_stop, + .stop = gs232a_rot_stop, .move = gs232a_rot_move, }; /* ************************************************************************* */ + + + + DECLARE_INITROT_BACKEND(gs232a) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__); rot_register(&gs232a_rot_caps); + rot_register(&gs232_generic_rot_caps); rot_register(&gs232b_rot_caps); - rot_register(&gs232_rot_caps); rot_register(&f1tetracker_rot_caps); - - return RIG_OK; + rot_register(&gs23_rot_caps); + rot_register(&gs232_rot_caps); + rot_register(&amsat_lvb_rot_caps); + rot_register(&st2_rot_caps); + + return RIG_OK; } /* ************************************************************************* */ diff --git a/gs232a/gs232a.h b/gs232a/gs232a.h index 227b0cd39..c6c840533 100644 --- a/gs232a/gs232a.h +++ b/gs232a/gs232a.h @@ -22,9 +22,13 @@ #ifndef _ROT_GS232A_H #define _ROT_GS232A_H 1 -extern const struct rot_caps gs232_rot_caps; extern const struct rot_caps gs232a_rot_caps; +extern const struct rot_caps gs232_generic_rot_caps; extern const struct rot_caps gs232b_rot_caps; extern const struct rot_caps f1tetracker_rot_caps; +extern const struct rot_caps gs23_rot_caps; +extern const struct rot_caps gs232_rot_caps; +extern const struct rot_caps amsat_lvb_rot_caps; +extern const struct rot_caps st2_rot_caps; #endif /* _ROT_GS232A_H */ diff --git a/gs232a/gs232b.c b/gs232a/gs232b.c index 807312748..f2dbbe91a 100644 --- a/gs232a/gs232b.c +++ b/gs232a/gs232b.c @@ -128,7 +128,9 @@ gs232b_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) unsigned u_az, u_el; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __FUNCTION__, az, el); - + if (az < 0.0){ + az = az + 360.0; + } u_az = (unsigned)rint(az); u_el = (unsigned)rint(el); @@ -242,12 +244,12 @@ const struct rot_caps gs232b_rot_caps = { .rot_model = ROT_MODEL_GS232B, .model_name = "GS-232B", .mfg_name = "Yaesu", - .version = "0.2", + .version = "0.4", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, - .serial_rate_min = 150, + .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, @@ -258,7 +260,7 @@ const struct rot_caps gs232b_rot_caps = { .timeout = 400, .retry = 3, - .min_az = 0.0, + .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, /* requires G-5400B, G-5600B, G-5500, or G-500/G-550 */ diff --git a/icom/frame.c b/icom/frame.c index 6d9f7ffa6..cfedf74aa 100644 --- a/icom/frame.c +++ b/icom/frame.c @@ -334,6 +334,8 @@ int rig2icom_mode(RIG *rig, rmode_t mode, pbwidth_t width, case RIG_MODE_LSB: icmode = S_LSB; break; case RIG_MODE_RTTY: icmode = S_RTTY; break; case RIG_MODE_RTTYR: icmode = S_RTTYR; break; + case RIG_MODE_PSK: icmode = S_PSK; break; + case RIG_MODE_PSKR: icmode = S_PSKR; break; case RIG_MODE_FM: icmode = S_FM; break; case RIG_MODE_FMN: icmode = S_FMN; break; case RIG_MODE_WFM: icmode = S_WFM; break; @@ -404,8 +406,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 S_PSK: *mode = RIG_MODE_PSK; break; + case S_PSKR: *mode = RIG_MODE_PSKR; break; case S_DSTAR: *mode = RIG_MODE_DSTAR; break; case S_P25: *mode = RIG_MODE_P25; break; case S_DPMR: *mode = RIG_MODE_DPMR; break; diff --git a/icom/ic7000.c b/icom/ic7000.c index 5897ec89b..e4d8aff1b 100644 --- a/icom/ic7000.c +++ b/icom/ic7000.c @@ -44,9 +44,9 @@ #define IC7000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC7000_AM_TX_MODES (RIG_MODE_AM) -#define IC7000_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) +#define IC7000_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) -#define IC7000_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) +#define IC7000_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_COMP_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB) #define IC7000_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7000_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) @@ -80,6 +80,35 @@ { 255, 63 } \ } } +#define IC7000_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC7000_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC7000_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +#define IC7000_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 241, 30.0f } \ + } } + /* * * IC7000 channel caps. @@ -100,21 +129,26 @@ .levels = RIG_LEVEL_SET(IC7000_LEVELS), \ } -int ic7000_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); +int ic7000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic7000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* * IC-7000 rig capabilities. - * - * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps IC7000_priv_caps = { - 0x70, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic7000_ts_sc_list + 0x70, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic7000_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; - const struct rig_caps ic7000_caps = { .rig_model = RIG_MODEL_IC7000, .model_name = "IC-7000", @@ -144,6 +178,9 @@ const struct rig_caps ic7000_caps = { .has_set_parm = RIG_PARM_SET(IC7000_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, @@ -229,6 +266,10 @@ const struct rig_caps ic7000_caps = { }, .str_cal = IC7000_STR_CAL, +.swr_cal = IC7000_SWR_CAL, +.alc_cal = IC7000_ALC_CAL, +.rfpower_meter_cal = IC7000_RFPOWER_METER_CAL, +.comp_meter_cal = IC7000_COMP_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -248,18 +289,16 @@ const struct rig_caps ic7000_caps = { .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, -.set_rit = icom_set_rit, - .decode_event = icom_decode_event, -.set_level = icom_set_level, -.get_level = icom_get_level, +.set_level = ic7000_set_level, +.get_level = ic7000_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, -.vfo_op = ic7000_vfo_op, +.vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, @@ -285,35 +324,34 @@ const struct rig_caps ic7000_caps = { }; -int ic7000_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) +int ic7000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { - unsigned char mvbuf[MAXFRAMELEN]; - unsigned char ackbuf[MAXFRAMELEN]; - int mv_len=0, ack_len=sizeof(ackbuf), retval; - int mv_cn, mv_sc; + unsigned char cmdbuf[MAXFRAMELEN]; - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - switch(op) { - case RIG_OP_TUNE: - mv_cn = C_CTL_PTT; - mv_sc = S_ANT_TUN; - mvbuf[0] = 2; - mv_len = 1; - break; - default: - return icom_vfo_op(rig, vfo, op); - } - - retval = icom_transaction (rig, mv_cn, mv_sc, mvbuf, mv_len, ackbuf, &ack_len); - if (retval != RIG_OK) - return retval; - - if (ack_len != 1 || ackbuf[0] != ACK) { - if (op != RIG_OP_XCHG) - rig_debug(RIG_DEBUG_ERR,"icom_vfo_op: ack NG (%#.2x), len=%d\n", ackbuf[0], ack_len); - return -RIG_ERJCTED; - } - - return RIG_OK; + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x17; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic7000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x17; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } } diff --git a/icom/ic703.c b/icom/ic703.c index 8f50e84a0..baae08aa7 100644 --- a/icom/ic703.c +++ b/icom/ic703.c @@ -35,7 +35,7 @@ #define IC703_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 IC703_AM_TX_MODES (RIG_MODE_AM) -#define IC703_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_ANF|RIG_FUNC_MON) +#define IC703_FUNC_ALL (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_ANF|RIG_FUNC_MON) #define IC703_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_ALC|RIG_LEVEL_SWR|RIG_LEVEL_METER|RIG_LEVEL_COMP|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_NR|RIG_LEVEL_IF|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT) diff --git a/icom/ic706.c b/icom/ic706.c index 6ffc22662..152cd152c 100644 --- a/icom/ic706.c +++ b/icom/ic706.c @@ -69,7 +69,7 @@ static int ic706_r2i_mode(RIG *rig, rmode_t mode, pbwidth_t width, #define IC706_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC706_AM_TX_MODES (RIG_MODE_AM) -#define IC706IIG_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) +#define IC706IIG_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) #define IC706IIG_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) diff --git a/icom/ic7100.c b/icom/ic7100.c index 855287749..e84930a00 100644 --- a/icom/ic7100.c +++ b/icom/ic7100.c @@ -34,9 +34,10 @@ #define IC7100_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\ - RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) + RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|\ + RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) -#define IC7100_OTHER_TX_MODES ((IC7100_MODES) & ~RIG_MODE_AM) +#define IC7100_OTHER_TX_MODES ((IC7100_MODES) & ~(RIG_MODE_AM|RIG_MODE_PKTAM)) #define IC7100_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) @@ -49,8 +50,7 @@ RIG_OP_XCHG| \ RIG_OP_TUNE) -#define IC7100_FUNC_ALL (RIG_FUNC_FAGC| \ - RIG_FUNC_NB| \ +#define IC7100_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ @@ -63,7 +63,8 @@ RIG_FUNC_VSC| \ RIG_FUNC_MN| \ RIG_FUNC_LOCK| \ - RIG_FUNC_SCOPE) + RIG_FUNC_SCOPE| \ + RIG_FUNC_TUNER) #define IC7100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ @@ -82,24 +83,94 @@ RIG_LEVEL_AGC| \ RIG_LEVEL_PBT_IN| \ RIG_LEVEL_PBT_OUT| \ - RIG_LEVEL_NOTCHF| \ + RIG_LEVEL_NOTCHF_RAW| \ RIG_LEVEL_ATT| \ - RIG_LEVEL_PREAMP) + RIG_LEVEL_PREAMP| \ + RIG_LEVEL_RAWSTR| \ + RIG_LEVEL_STRENGTH| \ + RIG_LEVEL_SWR| \ + RIG_LEVEL_ALC| \ + RIG_LEVEL_RFPOWER_METER| \ + RIG_LEVEL_COMP_METER| \ + RIG_LEVEL_VD_METER| \ + RIG_LEVEL_ID_METER| \ + RIG_LEVEL_MONITOR_GAIN| \ + RIG_LEVEL_NB) #define IC7100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) -#define IC7100_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ +// IC-7100 S-meter calibration data based on manual +#define IC7100_STR_CAL { 14, \ + { \ + { 0, -54 }, \ + { 120, 0 }, \ + { 241, 60 } \ + } } + +#define IC7100_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC7100_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC7100_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +#define IC7100_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 241, 30.0f } \ + } } + +#define IC7100_VD_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 13, 10.0f }, \ + { 241, 16.0f } \ + } } + +#define IC7100_ID_METER_CAL { 4, \ + { \ + { 0, 0.0f }, \ + { 97, 10.0f }, \ + { 146, 15.0f }, \ + { 241, 25.0f } \ + } } #define IC7100_HF_ANTS (RIG_ANT_1|RIG_ANT_2) +int ic7100_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic7100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); + /* + * IC-7100 rig capabilities. */ static const struct icom_priv_caps ic7100_priv_caps = { 0x88, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7100_ts_sc_list, /* FIXME */ - .civ_version = 1 + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; const struct rig_caps ic7100_caps = { @@ -125,12 +196,15 @@ const struct rig_caps ic7100_caps = { .retry = 3, .has_get_func = IC7100_FUNC_ALL, .has_set_func = IC7100_FUNC_ALL | RIG_FUNC_RESUME, -.has_get_level = IC7100_LEVEL_ALL | RIG_LEVEL_RAWSTR| RIG_LEVEL_SWR, -.has_set_level = IC7100_LEVEL_ALL, +.has_get_level = IC7100_LEVEL_ALL, +.has_set_level = RIG_LEVEL_SET(IC7100_LEVEL_ALL), .has_get_parm = IC7100_PARM_ALL, .has_set_parm = IC7100_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, @@ -204,12 +278,27 @@ const struct rig_caps ic7100_caps = { RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { - {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.4)}, /* builtin */ - {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, - {RIG_MODE_FM, kHz(15)}, /* builtin */ - {RIG_MODE_FM|RIG_MODE_AM, kHz(6)}, /* builtin */ + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(2.4)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(1.8)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(3)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(10)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(15)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(7)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(500)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(250)}, + {RIG_MODE_CW|RIG_MODE_CWR, kHz(1.2)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.4)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(6)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(3)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC7100_STR_CAL, +.swr_cal = IC7100_SWR_CAL, +.alc_cal = IC7100_ALC_CAL, +.rfpower_meter_cal = IC7100_RFPOWER_METER_CAL, +.comp_meter_cal = IC7100_COMP_METER_CAL, +.vd_meter_cal = IC7100_VD_METER_CAL, +.id_meter_cal = IC7100_ID_METER_CAL, .priv = (void*)&ic7100_priv_caps, .rig_init = icom_init, @@ -235,8 +324,8 @@ const struct rig_caps ic7100_caps = { .set_ts = icom_set_ts, .get_func = icom_get_func, .set_func = icom_set_func, -.get_level = icom_get_level, -.set_level = icom_set_level, +.get_level = ic7100_get_level, +.set_level = ic7100_set_level, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, @@ -263,12 +352,44 @@ const struct rig_caps ic7100_caps = { .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .set_split_vfo = icom_set_split_vfo, +.get_split_vfo = icom_get_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_powerstat = icom_set_powerstat, +.get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse }; -/* end of file */ +int ic7100_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x65; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic7100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x65; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} diff --git a/icom/ic718.c b/icom/ic718.c index 85aeac3ed..62f1ff75b 100644 --- a/icom/ic718.c +++ b/icom/ic718.c @@ -42,7 +42,7 @@ #define IC718_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC718_AM_TX_MODES (RIG_MODE_AM) -#define IC718_FUNC_ALL (RIG_FUNC_NR|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_ANF) +#define IC718_FUNC_ALL (RIG_FUNC_NR|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_ANF) #define IC718_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_MICGAIN|RIG_LEVEL_NR|RIG_LEVEL_CWPITCH|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RAWSTR|RIG_LEVEL_SQL) diff --git a/icom/ic7200.c b/icom/ic7200.c index 0e8cd922b..7cec85568 100644 --- a/icom/ic7200.c +++ b/icom/ic7200.c @@ -50,9 +50,9 @@ #define IC7200_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7200_AM_TX_MODES (RIG_MODE_AM) -#define IC7200_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) +#define IC7200_FUNCS (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_ANF|RIG_FUNC_LOCK|RIG_FUNC_ARO|RIG_FUNC_TUNER) -#define IC7200_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) +#define IC7200_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_NB) #define IC7200_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7200_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) @@ -62,30 +62,57 @@ #define IC7200_ANTS (RIG_ANT_1) /* ant-1 is Hf-6m */ -/* - * FIXME: This is a guess real measures please! - */ -#define IC7200_STR_CAL { 2, \ +#define IC7200_STR_CAL { 3, \ { \ - { 0, -60 }, \ - { 255, 60 } \ + { 0, -54 }, \ + { 120, 0 }, \ + { 241, 60 } \ } } +#define IC7200_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC7200_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC7200_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +int ic7200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic7200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); + /* * IC-7200 rig capabilities. * * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps IC7200_priv_caps = { - 0x76, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic7200_ts_sc_list, - .civ_version = 1 /* new version of some commands, e.g. ic7200/7300 */ - + 0x76, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic7200_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_OFF, .icom_level = 0 }, + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_SLOW, .icom_level = 2 }, + { .level = -1, .icom_level = 0 }, + }, }; - const struct rig_caps ic7200_caps = { .rig_model = RIG_MODEL_IC7200, .model_name = "IC-7200", @@ -115,6 +142,9 @@ const struct rig_caps ic7200_caps = { .has_set_parm = RIG_PARM_SET(IC7200_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = NULL, @@ -180,6 +210,9 @@ const struct rig_caps ic7200_caps = { }, .str_cal = IC7200_STR_CAL, +.swr_cal = IC7200_SWR_CAL, +.alc_cal = IC7200_ALC_CAL, +.rfpower_meter_cal = IC7200_RFPOWER_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -199,11 +232,9 @@ const struct rig_caps ic7200_caps = { .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, -.set_rit = icom_set_rit, - .decode_event = icom_decode_event, -.set_level = icom_set_level, -.get_level = icom_get_level, +.set_level = ic7200_set_level, +.get_level = ic7200_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, @@ -216,10 +247,10 @@ const struct rig_caps ic7200_caps = { .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, -.set_rptr_shift = icom_set_rptr_shift, +.set_rptr_shift = NULL, .get_rptr_shift = NULL, -.set_rptr_offs = icom_set_rptr_offs, -.get_rptr_offs = icom_get_rptr_offs, +.set_rptr_offs = NULL, +.get_rptr_offs = NULL, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, @@ -232,3 +263,33 @@ const struct rig_caps ic7200_caps = { .get_split_vfo = NULL, }; + +int ic7200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x55; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x03, 1, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic7200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x55; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x03, 1, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} diff --git a/icom/ic7300.c b/icom/ic7300.c index 888c2fd83..4fc48d398 100644 --- a/icom/ic7300.c +++ b/icom/ic7300.c @@ -38,7 +38,6 @@ #include "bandplan.h" #include "tones.h" -/* AM Data mode needs adding - this would require one more mode 'RIG_MODE_PKTAM' to rig.h */ #define IC7300_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM) #define IC7300_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM) #define IC7300_NOT_TS_MODES (IC7300_ALL_RX_MODES &~IC7300_1HZ_TS_MODES) @@ -46,15 +45,12 @@ #define IC7300_OTHER_TX_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7300_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) -#define IC7300_FUNCS (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_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_SCOPE|RIG_FUNC_TUNER) +#define IC7300_FUNCS (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_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_SCOPE|RIG_FUNC_TUNER) -#define IC7300_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) - -// Not implemented yet -//#define IC7300_EXT_LEVELS (TOK_LEVEL_MONITOR) +#define IC7300_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB) #define IC7300_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) -#define IC7300_PARMS (RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP) +#define IC7300_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP) #define IC7300_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7300_SCAN_OPS (RIG_SCAN_STOP|RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT) @@ -75,60 +71,152 @@ { 241, 64 } \ } } -#define IC7300_AGC_OFF 0x00 -#define IC7300_AGC_FAST 0x01 -#define IC7300_AGC_MID 0x02 -#define IC7300_AGC_SLOW 0x03 +#define IC7300_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC7300_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC7300_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +#define IC7300_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 241, 30.0f } \ + } } + +#define IC7300_VD_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 13, 10.0f }, \ + { 241, 16.0f } \ + } } + +#define IC7300_ID_METER_CAL { 4, \ + { \ + { 0, 0.0f }, \ + { 97, 10.0f }, \ + { 146, 15.0f }, \ + { 241, 25.0f } \ + } } + /* * IC9700 items that differ from IC7300 */ +#define IC9700_FUNCS (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_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_SCOPE) + #define IC9700_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC9700_ALL_TX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR|RIG_MODE_DD) #define IC9700_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR|RIG_MODE_DD) +#define IC9700_STR_CAL { 7, \ + { \ + { 0, -54 }, \ + { 10, -48 }, \ + { 30, -36 }, \ + { 60, -24 }, \ + { 90, -12 }, \ + { 120, 0 }, \ + { 241, 64 } \ + } } + +#define IC9700_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC9700_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC9700_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +#define IC9700_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 210, 25.5f } \ + } } + +#define IC9700_VD_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 13, 10.0f }, \ + { 241, 16.0f } \ + } } + +#define IC9700_ID_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 121, 10.0f }, \ + { 241, 20.0f } \ + } } + /* * IC-7300 rig capabilities. - * - * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps IC7300_priv_caps = { - 0x94, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic7300_ts_sc_list, - .civ_version = 1 /* new version of some commands, e.g. ic7200/7300 */ + 0x94, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic7300_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; static const struct icom_priv_caps IC9700_priv_caps = { - 0xA2, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic7300_ts_sc_list, - .civ_version = 1, /* new version of some commands, e.g. ic7200/7300 */ - .serial_USB_echo_check = 1 /* USB CI-V may not echo */ + 0xA2, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic7300_ts_sc_list, + .serial_USB_echo_check = 1, /* USB CI-V may not echo */ + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; -/* Private IC7300 extra levels definitions - * - * Token definitions for .cfgparams in rig_caps - * See enum rig_conf_e and struct confparams in rig.h - */ -const struct confparams ic7300_ext_levels[] = { - { TOK_LEVEL_MONITOR, "MONITORGAIN", "Monitor gain", "Monitor gain", - NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, 0 } } - }, - { RIG_CONF_END, NULL, } -}; - - -int ic7300_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *ts); -int ic7300_set_rit(RIG *rig, vfo_t vfo, shortfreq_t ts); -int ic7300_set_xit(RIG *rig, vfo_t vfo, shortfreq_t ts); -int ic7300_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); -int ic7300_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int ic7300_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ic7300_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int ic9700_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic9700_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int ic7300_set_parm(RIG *rig, setting_t parm, value_t val); +int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val); const struct rig_caps ic7300_caps = { .rig_model = RIG_MODEL_IC7300, @@ -158,14 +246,17 @@ const struct rig_caps ic7300_caps = { .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC7300_PARMS), .level_gran = { - [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_RAWSTR] = {.min = {.i = 0}, .max = {.i = 255}}, + [LVL_VOXDELAY] = {.min = {.i = 0}, .max = {.i = 20}, .step = {.i = 1}}, + [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, + [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, }, .parm_gran = {}, -.extlevels = ic7300_ext_levels, +.extlevels = NULL, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, -.attenuator = { 1, RIG_DBLST_END, }, /* value taken from p.45 of manual*/ +.attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), @@ -218,9 +309,9 @@ const struct rig_caps ic7300_caps = { /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { - {RIG_MODE_SSB, kHz(2.4)}, - {RIG_MODE_SSB, kHz(1.8)}, - {RIG_MODE_SSB, kHz(3)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(2.4)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(1.8)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW|RIG_MODE_CWR, kHz(1.2)}, @@ -228,13 +319,19 @@ const struct rig_caps ic7300_caps = { {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(9)}, - {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(15)}, {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(7)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7300_STR_CAL, +.swr_cal = IC7300_SWR_CAL, +.alc_cal = IC7300_ALC_CAL, +.rfpower_meter_cal = IC7300_RFPOWER_METER_CAL, +.comp_meter_cal = IC7300_COMP_METER_CAL, +.vd_meter_cal = IC7300_VD_METER_CAL, +.id_meter_cal = IC7300_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -255,23 +352,20 @@ const struct rig_caps ic7300_caps = { .set_ant = NULL, .get_ant = NULL, -.set_rit = ic7300_set_rit, -.get_rit = ic7300_get_rit, -// the 7300 has only one register for both RIT and Delta TX -// you can turn one or both on -- but both end up just being in sync -// so we'll just reuse the rit settings -.get_xit = ic7300_get_rit, -.set_xit = ic7300_set_xit, +.set_rit = icom_set_rit_new, +.get_rit = icom_get_rit_new, +.get_xit = icom_get_rit_new, +.set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = ic7300_set_level, .get_level = ic7300_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, -.set_func = ic7300_set_func, -.get_func = ic7300_get_func, -.set_parm = icom_set_parm, -.get_parm = icom_get_parm, +.set_func = icom_set_func, +.get_func = icom_get_func, +.set_parm = ic7300_set_parm, +.get_parm = ic7300_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, @@ -295,6 +389,7 @@ const struct rig_caps ic7300_caps = { .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, +.get_powerstat = icom_get_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse @@ -322,21 +417,24 @@ const struct rig_caps ic9700_caps = { .post_write_delay = 0, .timeout = 1000, .retry = 3, -.has_get_func = IC7300_FUNCS, -.has_set_func = IC7300_FUNCS, +.has_get_func = IC9700_FUNCS, +.has_set_func = IC9700_FUNCS, .has_get_level = IC7300_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7300_LEVELS), .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC7300_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, + [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, }, .parm_gran = {}, -.extlevels = ic7300_ext_levels, +.extlevels = NULL, .ctcss_list = full_ctcss_list, .dcs_list = NULL, -.preamp = { 1, 2, RIG_DBLST_END, }, -.attenuator = { 1, RIG_DBLST_END, }, /* value taken from p.45 of manual*/ +.preamp = { 1, 2, 3, RIG_DBLST_END, }, +.attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), @@ -397,12 +495,18 @@ const struct rig_caps ic9700_caps = { {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(15)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(10)}, - {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(7)}, RIG_FLT_END, }, -.str_cal = IC7300_STR_CAL, +.str_cal = IC9700_STR_CAL, +.swr_cal = IC9700_SWR_CAL, +.alc_cal = IC9700_ALC_CAL, +.rfpower_meter_cal = IC9700_RFPOWER_METER_CAL, +.comp_meter_cal = IC9700_COMP_METER_CAL, +.vd_meter_cal = IC9700_VD_METER_CAL, +.id_meter_cal = IC9700_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -423,21 +527,16 @@ const struct rig_caps ic9700_caps = { .set_ant = NULL, .get_ant = NULL, -.set_rit = ic7300_set_rit, -.get_rit = ic7300_get_rit, -// the 7300 has only one register for both RIT and Delta TX -// you can turn one or both on -- but both end up just being in sync -// so we'll just reuse the rit settings -.get_xit = ic7300_get_rit, -.set_xit = ic7300_set_xit, +.set_rit = icom_set_rit_new, +.get_rit = icom_get_rit_new, .decode_event = icom_decode_event, -.set_level = ic7300_set_level, -.get_level = ic7300_get_level, +.set_level = ic9700_set_level, +.get_level = ic9700_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, -.set_func = ic7300_set_func, -.get_func = ic7300_get_func, +.set_func = icom_set_func, +.get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, @@ -463,274 +562,134 @@ const struct rig_caps ic9700_caps = { .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, +.get_powerstat = icom_get_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse }; -int ic7300_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *ts) -{ - unsigned char tsbuf[MAXFRAMELEN]; - int ts_len, retval; - - retval = icom_transaction (rig, 0x21, 0x00, NULL, 0, tsbuf, &ts_len); - if (retval != RIG_OK) { - return retval; - } - - /* - * tsbuf nibbles should contain 10,1,1000,100 hz digits and 00=+, 01=- bit - */ - rig_debug(RIG_DEBUG_VERBOSE, "ts_len=%d\n", ts_len); - if (ts_len != 5) { - rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len); - return -RIG_ERJCTED; - } - - *ts = (shortfreq_t) from_bcd(tsbuf + 2, 4); - if (tsbuf[4] != 0) { - *ts *= -1; - } - - return RIG_OK; -} - -static int ic7300_set_it(RIG *rig, vfo_t vfo, shortfreq_t ts, int set_xit) { - unsigned char tsbuf[8]; - unsigned char ackbuf[16]; - int ack_len; - int retval; - - rig_debug(RIG_DEBUG_VERBOSE, "%s: ts=%d\n", __func__, ts); - - to_bcd(tsbuf, abs((int) ts), 4); - // set sign bit - tsbuf[2] = (ts < 0) ? 1 : 0; - - retval = icom_transaction(rig, 0x21, 0x00, tsbuf, 3, ackbuf, &ack_len); - if (retval != RIG_OK) { - return retval; - } - - if (ts == 0) { // turn off both rit/xit - retval = ic7300_set_func(rig, vfo, RIG_FUNC_XIT, 0); - if (retval != RIG_OK) { - return retval; - } - retval = ic7300_set_func(rig, vfo, RIG_FUNC_RIT, 0); - } else { - retval = ic7300_set_func(rig, vfo, set_xit ? RIG_FUNC_XIT : RIG_FUNC_RIT, 1); - } - return retval; -} - -int ic7300_set_rit(RIG *rig, vfo_t vfo, shortfreq_t ts) -{ - return ic7300_set_it(rig, vfo, ts, 0); -} - -int ic7300_set_xit(RIG *rig, vfo_t vfo, shortfreq_t ts) -{ - return ic7300_set_it(rig, vfo, ts, 1); -} - -int ic7300_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) -{ - unsigned char ackbuf[16]; - int ack_len; - int retval; - - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - - if (!rig || !status) - return -RIG_EINVAL; - - switch (func) { - case RIG_FUNC_RIT: - retval = icom_transaction(rig, 0x21, 0x01, NULL, 0, ackbuf, &ack_len); - if (retval != RIG_OK) return retval; - if (ack_len != 3) { - return RIG_BUSERROR; - } - *status = ackbuf[2]; - break; - - case RIG_FUNC_XIT: - retval = icom_transaction(rig, 0x21, 0x02, NULL, 0, ackbuf, &ack_len); - if (ack_len != 3) { - return RIG_BUSERROR; - } - *status = ackbuf[2]; - break; - - case RIG_FUNC_TUNER: - retval = icom_transaction (rig, 0x1C, 0x01, NULL, 0, ackbuf, &ack_len); - if (ack_len == 3) - { - *status = ackbuf[2]; // 0x01 = enabled, 0x00 = disabled, 0x02 = tuning in progress - } else { - return RIG_BUSERROR; - } - break; - - default: - return icom_get_func(rig, vfo, func, status); - } - return retval; -} - -int ic7300_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) -{ - unsigned char ts_buf[4]; - unsigned char ackbuf[8]; - int ack_len; - - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - - if (!rig) - return -RIG_EINVAL; - - switch (func) { - case RIG_FUNC_RIT: - ts_buf[0] = status; - return icom_transaction (rig, 0x21, 0x01, ts_buf, 1, ackbuf, &ack_len); - - case RIG_FUNC_XIT: - ts_buf[0] = status; - return icom_transaction (rig, 0x21, 0x02, ts_buf, 1, ackbuf, &ack_len); - - case RIG_FUNC_TUNER: - if(status==0 || status==1 || status==2) - { // 0=off, 1 = on, 2 = begin tuning - ts_buf[0] = status; - return icom_transaction (rig, 0x1C, 0x01, ts_buf, 1, ackbuf, &ack_len); - } else { - return -1; // perhaps some other reply would be more informative - } - - default: - return icom_set_func(rig, vfo, func, status); - } -} - int ic7300_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { - unsigned char lvlbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; - int ack_len=sizeof(ackbuf), lvl_len; - int lvl_cn, lvl_sc; /* Command Number, Subcommand */ - int retval; + unsigned char cmdbuf[MAXFRAMELEN]; - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - switch (level) { - case RIG_LEVEL_AGC: - lvl_cn = C_CTL_FUNC; - lvl_sc = S_FUNC_AGC; - lvl_len = 1; - - unsigned char agc_value; - switch (val.i) { - case RIG_AGC_OFF: - agc_value = IC7300_AGC_OFF; - break; - case RIG_AGC_SLOW: - agc_value = IC7300_AGC_SLOW; - break; - case RIG_AGC_MEDIUM: - agc_value = IC7300_AGC_MID; - break; - case RIG_AGC_FAST: - agc_value = IC7300_AGC_FAST; - break; - default: - rig_debug(RIG_DEBUG_ERR,"Unsupported LEVEL_AGC %d", val.i); - return -RIG_EINVAL; - } - - lvlbuf[0] = agc_value; - break; - default: - return icom_set_level(rig, vfo, level, val); - } - - retval = icom_transaction (rig, lvl_cn, lvl_sc, lvlbuf, lvl_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", __func__, ackbuf[0], ack_len); - return -RIG_ERJCTED; - } - - return RIG_OK; + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x91; + return icom_set_level_raw(rig, level, C_CTL_MEM, S_MEM_PARM, 2, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } } int ic7300_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { - unsigned char lvlbuf[MAXFRAMELEN], lvl2buf[MAXFRAMELEN]; - int lvl_len, lvl2_len; - int lvl_cn, lvl_sc; /* Command Number, Subcommand */ - int icom_val; - int cmdhead; - int retval; + unsigned char cmdbuf[MAXFRAMELEN]; - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - lvl2_len = 0; - - switch (level) { - case RIG_LEVEL_AGC: - lvl_cn = C_CTL_FUNC; - lvl_sc = S_FUNC_AGC; - break; - default: - return icom_get_level(rig, vfo, level, val); - } - - retval = icom_transaction (rig, lvl_cn, lvl_sc, lvl2buf, lvl2_len, - lvlbuf, &lvl_len); - if (retval != RIG_OK) - return retval; - - cmdhead = 2; - lvl_len -= cmdhead; - - if (lvlbuf[0] != ACK && lvlbuf[0] != lvl_cn) { - rig_debug(RIG_DEBUG_ERR,"%s: ack NG (%#.2x), len=%d\n", __func__, lvlbuf[0], lvl_len); - return -RIG_ERJCTED; - } - - /* - * The result is a 3 digit BCD, but in *big endian* order: 0000..0255 - * (from_bcd is little endian) - */ - icom_val = from_bcd_be(lvlbuf + cmdhead, lvl_len * 2); - - switch (level) { - case RIG_LEVEL_AGC: - switch (icom_val) { - case IC7300_AGC_OFF: - val->i = RIG_AGC_OFF; - break; - case IC7300_AGC_SLOW: - val->i = RIG_AGC_SLOW; - break; - case IC7300_AGC_MID: - val->i = RIG_AGC_MEDIUM; - break; - case IC7300_AGC_FAST: - val->i = RIG_AGC_FAST; - break; - default: - rig_debug(RIG_DEBUG_ERR,"Unexpected AGC 0x%02x", icom_val); - return -RIG_EPROTO; - } - break; - } - - rig_debug(RIG_DEBUG_TRACE ,"%s: %d %d %d %f\n", __func__, lvl_len, icom_val, val->i, val->f); - - return RIG_OK; + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x91; + return icom_get_level_raw(rig, level, C_CTL_MEM, S_MEM_PARM, 2, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} + +int ic9700_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x03; + cmdbuf[1] = 0x30; + return icom_set_level_raw(rig, level, C_CTL_MEM, S_MEM_PARM, 2, cmdbuf, 1, val); + default: + return ic7300_set_level(rig, vfo, level, val); + } +} + +int ic9700_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x03; + cmdbuf[1] = 0x30; + return icom_get_level_raw(rig, level, C_CTL_MEM, S_MEM_PARM, 2, cmdbuf, val); + default: + return ic7300_get_level(rig, vfo, level, val); + } +} + +int ic7300_set_parm(RIG *rig, setting_t parm, value_t val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x00; + parmbuf[1] = 0x23; + return icom_set_custom_parm(rig, 2, parmbuf, 1, val.i ? 1 : 0); + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x00; + parmbuf[1] = 0x81; + return icom_set_custom_parm(rig, 2, parmbuf, 2, (int) (val.f * 255.0f)); + case RIG_PARM_TIME: + parmbuf[0] = 0x00; + parmbuf[1] = 0x95; + return icom_set_custom_parm_time(rig, 2, parmbuf, val.i); + default: + return icom_set_parm(rig, parm, val); + } +} + +int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + int retval; + int icom_val; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x00; + parmbuf[1] = 0x23; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->i = icom_val ? 1 : 0; + break; + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x00; + parmbuf[1] = 0x81; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->f = (float) icom_val / 255.0f; + break; + case RIG_PARM_TIME: + parmbuf[0] = 0x00; + parmbuf[1] = 0x95; + return icom_get_custom_parm_time(rig, 2, parmbuf, &val->i); + default: + return icom_get_parm(rig, parm, val); + } + + return RIG_OK; } diff --git a/icom/ic7410.c b/icom/ic7410.c index 43c959f4d..32967264f 100644 --- a/icom/ic7410.c +++ b/icom/ic7410.c @@ -41,9 +41,9 @@ #define IC7410_ALL_RX_MODES IC7410_OTHER_TX_MODES | IC7410_AM_TX_MODES #define IC7410_1HZ_TS_MODES IC7410_ALL_RX_MODES -#define IC7410_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) +#define IC7410_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_TUNER) -#define IC7410_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) +#define IC7410_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER) #define IC7410_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7410_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) @@ -63,17 +63,47 @@ { 246, 60 } /* S9+60dB */ \ } } +#define IC7410_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC7410_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC7410_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +int ic7410_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic7410_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* * IC-7410 rig capabilities. - * - * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps ic7410_priv_caps = { - 0x80, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list + 0x80, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_OFF, .icom_level = 0 }, + { .level = RIG_AGC_SLOW, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_FAST, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; @@ -106,6 +136,9 @@ const struct rig_caps ic7410_caps = { .has_set_parm = RIG_PARM_SET(IC7410_PARMS), /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, @@ -176,6 +209,9 @@ const struct rig_caps ic7410_caps = { RIG_FLT_END, }, .str_cal = IC7410_STR_CAL, +.swr_cal = IC7410_SWR_CAL, +.alc_cal = IC7410_ALC_CAL, +.rfpower_meter_cal = IC7410_RFPOWER_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -198,8 +234,8 @@ const struct rig_caps ic7410_caps = { .set_rit = icom_set_rit, .decode_event = icom_decode_event, -.set_level = icom_set_level, -.get_level = icom_get_level, +.set_level = ic7410_set_level, +.get_level = ic7410_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, @@ -229,3 +265,32 @@ const struct rig_caps ic7410_caps = { }; +int ic7410_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x75; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 1, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic7410_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x75; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 1, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} diff --git a/icom/ic746.c b/icom/ic746.c index 2d8517193..530601eea 100644 --- a/icom/ic746.c +++ b/icom/ic746.c @@ -58,9 +58,9 @@ #define IC746_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC746_AM_TX_MODES (RIG_MODE_AM) -#define IC746_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|RIG_FUNC_ANF|RIG_FUNC_APF|RIG_FUNC_VSC|RIG_FUNC_RESUME|RIG_FUNC_ARO) +#define IC746_FUNC_ALL (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|RIG_FUNC_ANF|RIG_FUNC_APF|RIG_FUNC_RESUME|RIG_FUNC_ARO) -#define IC746_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) +#define IC746_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_APF) #define IC746_GET_PARM (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define IC746_SET_PARM (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP|RIG_PARM_ANN) @@ -68,7 +68,7 @@ #define IC746_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC746_ANTS (RIG_ANT_1|RIG_ANT_2) -#define IC746_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) +#define IC746_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC746_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_SLCT|RIG_SCAN_PROG|RIG_SCAN_DELTA) @@ -158,13 +158,20 @@ static int ic746pro_get_ext_parm(RIG *rig, token_t token, value_t *val); /* - * ic746 rig capabilities. + * IC-746 rig capabilities. */ static const struct icom_priv_caps ic746_priv_caps = { - 0x56, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list + 0x56, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_OFF, .icom_level = 0 }, + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_SLOW, .icom_level = 2 }, + { .level = -1, .icom_level = 0 }, + }, }; const struct rig_caps ic746_caps = { @@ -196,7 +203,9 @@ const struct rig_caps ic746_caps = { .has_set_parm = RIG_PARM_ANN, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, - }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, +}, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, @@ -365,13 +374,21 @@ static const struct confparams ic746pro_ext_parms[] = { /* - * ic746pro rig capabilities. + * IC-746pro rig capabilities. */ static const struct icom_priv_caps ic746pro_priv_caps = { - 0x66, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list + 0x66, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_OFF, .icom_level = 0 }, + { .level = RIG_AGC_SLOW, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_FAST, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; const struct rig_caps ic746pro_caps = { @@ -395,8 +412,8 @@ const struct rig_caps ic746pro_caps = { .post_write_delay = 0, .timeout = 1000, .retry = 3, -.has_get_func = IC746_FUNC_ALL, -.has_set_func = IC746_FUNC_ALL, +.has_get_func = IC746_FUNC_ALL|RIG_FUNC_TUNER|RIG_FUNC_VSC, +.has_set_func = IC746_FUNC_ALL|RIG_FUNC_TUNER|RIG_FUNC_VSC, .has_get_level = IC746_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC746_LEVEL_ALL), .has_get_parm = IC746_GET_PARM, @@ -414,7 +431,7 @@ const struct rig_caps ic746pro_caps = { .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, -.vfo_ops = IC746_VFO_OPS, +.vfo_ops = IC746_VFO_OPS|RIG_OP_TUNE, .scan_ops = IC746_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, diff --git a/icom/ic756.c b/icom/ic756.c index 7cc44cc88..1d92dba18 100644 --- a/icom/ic756.c +++ b/icom/ic756.c @@ -46,9 +46,10 @@ #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|RIG_FUNC_ANF) +#define IC756PRO_FUNC_ALL (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|RIG_FUNC_ANF) +#define IC756PRO_FUNC_SET (IC756PRO_FUNC_ALL|RIG_FUNC_DUAL_WATCH) -#define IC756PRO_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_COMP|RIG_LEVEL_BALANCE) +#define IC756PRO_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_COMP) /* Note that RIG_LEVEL_VOXGAIN and RIG_LEVEL_ANTIVOX are incorrectly handled in icom.c for * this model. @@ -81,6 +82,12 @@ { 247 ,60 } \ } } +int ic756_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); +int ic756pro2_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic756pro2_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int ic756pro2_set_parm(RIG *rig, setting_t parm, value_t val); +int ic756pro2_get_parm(RIG *rig, setting_t parm, value_t *val); + /* * This function deals with the older type radios with only 2 filter widths * (0 - normal, 1 - narrow) @@ -108,14 +115,21 @@ static int r2i_mode(RIG *rig, rmode_t mode, pbwidth_t width, } /* - * ic756 rig capabilities. + * IC-756 rig capabilities. */ static const struct icom_priv_caps ic756_priv_caps = { - 0x50, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756_ts_sc_list, - .r2i_mode = r2i_mode + 0x50, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756_ts_sc_list, + .r2i_mode = r2i_mode, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; const struct rig_caps ic756_caps = { @@ -229,7 +243,7 @@ const struct rig_caps ic756_caps = { .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, -.set_func = icom_set_func, +.set_func = ic756_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, @@ -244,21 +258,28 @@ const struct rig_caps ic756_caps = { .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, -.get_split_vfo = icom_mem_get_split_vfo, +.get_split_vfo = NULL, }; /* - * ic756pro rig capabilities. - * TODO: check every paramters, - * add antenna capabilities + * IC-756pro rig capabilities. + * + * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro_priv_caps = { - 0x5c, /* default address */ - 0, /* 731 mode */ + 0x5c, /* default address */ + 0, /* 731 mode */ 0, /* no XCHG */ - ic756pro_ts_sc_list + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; const struct rig_caps ic756pro_caps = { @@ -283,14 +304,16 @@ const struct rig_caps ic756pro_caps = { .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL, -.has_set_func = IC756PRO_FUNC_ALL, +.has_set_func = IC756PRO_FUNC_SET, .has_get_level = IC756PRO_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, - }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, +}, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, @@ -371,7 +394,7 @@ const struct rig_caps ic756pro_caps = { .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, -.set_func = icom_set_func, +.set_func = ic756_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, @@ -395,20 +418,27 @@ const struct rig_caps ic756pro_caps = { .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, -.get_split_vfo = icom_mem_get_split_vfo, +.get_split_vfo = NULL, }; /* - * ic756proII rig capabilities. - * TODO: check every paramters, - * add antenna capabilities + * IC-756proII rig capabilities. + * + * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro2_priv_caps = { - 0x64, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list + 0x64, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; /* @@ -467,6 +497,9 @@ static int ic756pro2_get_ext_parm(RIG *rig, token_t token, value_t *val); #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) +#define IC756PROII_LEVEL_ALL (IC756PRO_LEVEL_ALL|RIG_LEVEL_VOXDELAY) + +#define IC756PROII_PARMS (RIG_PARM_ANN|RIG_PARM_BEEP|RIG_PARM_BACKLIGHT|RIG_PARM_TIME) const struct rig_caps ic756pro2_caps = { .rig_model = RIG_MODEL_IC756PROII, @@ -490,13 +523,16 @@ const struct rig_caps ic756pro2_caps = { .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL, -.has_set_func = IC756PRO_FUNC_ALL, -.has_get_level = IC756PRO_LEVEL_ALL, -.has_set_level = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), +.has_set_func = IC756PRO_FUNC_SET, +.has_get_level = IC756PROII_LEVEL_ALL, +.has_set_level = RIG_LEVEL_SET(IC756PROII_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .extparms = ic756pro2_ext_parms, @@ -577,9 +613,11 @@ const struct rig_caps ic756pro2_caps = { .get_ant = icom_get_ant, .decode_event = icom_decode_event, -.set_level = icom_set_level, -.get_level = icom_get_level, -.set_func = icom_set_func, +.set_parm = ic756pro2_set_parm, +.get_parm = ic756pro2_get_parm, +.set_level = ic756pro2_set_level, +.get_level = ic756pro2_get_level, +.set_func = ic756_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, @@ -603,7 +641,7 @@ const struct rig_caps ic756pro2_caps = { .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, -.get_split_vfo = icom_mem_get_split_vfo, +.get_split_vfo = NULL, .set_ext_parm = ic756pro2_set_ext_parm, .get_ext_parm = ic756pro2_get_ext_parm, @@ -760,16 +798,22 @@ static int ic756pro2_get_ext_parm(RIG *rig, token_t token, value_t *val) /* - * ic756proIII rig capabilities. + * IC-756proIII rig capabilities. * - * TODO: check every paramters, - * add antenna capabilities + * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro3_priv_caps = { - 0x6e, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list + 0x6e, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; @@ -778,8 +822,7 @@ static const struct icom_priv_caps ic756pro3_priv_caps = { #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) -#define IC756PROIII_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) - +#define IC756PROIII_LEVEL_ALL (IC756PROII_LEVEL_ALL|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_COMP_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_NB) /* * TODO: check whether all func and levels are stored in memory @@ -802,6 +845,35 @@ static const struct icom_priv_caps ic756pro3_priv_caps = { .levels = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), \ } +#define IC756PROIII_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC756PROIII_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC756PROIII_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +#define IC756PROIII_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 241, 30.0f } \ + } } + const struct rig_caps ic756pro3_caps = { .rig_model = RIG_MODEL_IC756PROIII, .model_name = "IC-756PROIII", @@ -823,14 +895,17 @@ const struct rig_caps ic756pro3_caps = { .post_write_delay = 0, .timeout = 1000, .retry = 3, -.has_get_func = IC756PRO_FUNC_ALL, -.has_set_func = IC756PRO_FUNC_ALL, -.has_get_level = IC756PRO_LEVEL_ALL, -.has_set_level = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), -.has_get_parm = IC756PROIII_PARMS, -.has_set_parm = RIG_PARM_SET(IC756PROIII_PARMS), +.has_get_func = IC756PRO_FUNC_ALL|RIG_FUNC_TUNER, +.has_set_func = IC756PRO_FUNC_SET|RIG_FUNC_TUNER, +.has_get_level = IC756PROIII_LEVEL_ALL, +.has_set_level = RIG_LEVEL_SET(IC756PROIII_LEVEL_ALL), +.has_get_parm = IC756PROII_PARMS, +.has_set_parm = RIG_PARM_SET(IC756PROII_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .extparms = ic756pro2_ext_parms, @@ -898,6 +973,10 @@ const struct rig_caps ic756pro3_caps = { RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, +.swr_cal = IC756PROIII_SWR_CAL, +.alc_cal = IC756PROIII_ALC_CAL, +.rfpower_meter_cal = IC756PROIII_RFPOWER_METER_CAL, +.comp_meter_cal = IC756PROIII_COMP_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -918,11 +997,11 @@ const struct rig_caps ic756pro3_caps = { .get_ant = icom_get_ant, .decode_event = icom_decode_event, -.set_parm = icom_set_parm, -.get_parm = icom_get_parm, -.set_level = icom_set_level, -.get_level = icom_get_level, -.set_func = icom_set_func, +.set_parm = ic756pro2_set_parm, +.get_parm = ic756pro2_get_parm, +.set_level = ic756pro2_set_level, +.get_level = ic756pro2_get_level, +.set_func = ic756_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, @@ -942,10 +1021,121 @@ const struct rig_caps ic756pro3_caps = { .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, -.get_split_vfo = icom_mem_get_split_vfo, +.get_split_vfo = NULL, .set_ext_parm = ic756pro2_set_ext_parm, .get_ext_parm = ic756pro2_get_ext_parm, }; +int ic756_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +{ + unsigned char fctbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; + int fct_len = 0, acklen, retval; + int fct_cn, fct_sc; /* Command Number, Subcommand */ + switch (func) { + case RIG_FUNC_DUAL_WATCH: + fct_cn = C_SET_VFO; + fct_sc = status ? S_DUAL_ON : S_DUAL_OFF; + break; + default: + return icom_set_func(rig, vfo, func, status); + } + + retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf, &acklen); + if (retval != RIG_OK) { + return retval; + } + + if (acklen != 1) { + rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, acklen); + return -RIG_EPROTO; + } + + return RIG_OK; +} + +int ic756pro2_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x60; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 1, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic756pro2_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x60; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 1, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} + +int ic756pro2_set_parm(RIG *rig, setting_t parm, value_t val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x20; + return icom_set_custom_parm(rig, 1, parmbuf, 1, val.i ? 1 : 0); + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x09; + return icom_set_custom_parm(rig, 1, parmbuf, 2, (int) (val.f * 255.0f)); + case RIG_PARM_TIME: + parmbuf[0] = 0x16; + return icom_set_custom_parm_time(rig, 1, parmbuf, val.i); + default: + return icom_set_parm(rig, parm, val); + } +} + +int ic756pro2_get_parm(RIG *rig, setting_t parm, value_t *val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + int retval; + int icom_val; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x20; + retval = icom_get_custom_parm(rig, 1, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->i = icom_val ? 1 : 0; + break; + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x09; + retval = icom_get_custom_parm(rig, 1, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->f = (float) icom_val / 255.0f; + break; + case RIG_PARM_TIME: + parmbuf[0] = 0x16; + return icom_get_custom_parm_time(rig, 1, parmbuf, &val->i); + default: + return icom_get_parm(rig, parm, val); + } + + return RIG_OK; +} diff --git a/icom/ic7600.c b/icom/ic7600.c index 4db2e402a..f8543c4c8 100644 --- a/icom/ic7600.c +++ b/icom/ic7600.c @@ -36,20 +36,17 @@ #include "misc.h" #include "bandplan.h" -/* - * TODO: PSK and PSKR - */ -#define IC7600_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 IC7600_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7600_1HZ_TS_MODES IC7600_ALL_RX_MODES -#define IC7600_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 IC7600_AM_TX_MODES (RIG_MODE_AM) +#define IC7600_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) +#define IC7600_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) -#define IC7600_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) +#define IC7600_FUNCS (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_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH) -#define IC7600_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) +#define IC7600_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB) #define IC7600_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) -#define IC7600_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) +#define IC7600_PARMS (RIG_PARM_ANN|RIG_PARM_BEEP|RIG_PARM_TIME|RIG_PARM_BACKLIGHT|RIG_PARM_KEYLIGHT) #define IC7600_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7600_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) @@ -79,6 +76,54 @@ { 246, 60 } /* S9+60dB */ \ } } +#define IC7600_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC7600_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC7600_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +#define IC7600_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 241, 30.0f } \ + } } + +#define IC7600_VD_METER_CAL { 4, \ + { \ + { 0, 0.0f }, \ + { 152, 10.0f }, \ + { 181, 13.0f }, \ + { 212, 16.0f } \ + } } + +#define IC7600_ID_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 97, 10.0f }, \ + { 241, 25.0f } \ + } } + +int ic7600_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic7600_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int ic7600_set_parm(RIG *rig, setting_t parm, value_t val); +int ic7600_get_parm(RIG *rig, setting_t parm, value_t *val); /* * IC-7600 rig capabilities. @@ -86,13 +131,25 @@ * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps ic7600_priv_caps = { - 0x7a, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list, - .civ_version = 1 + 0x7a, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; +const struct confparams ic7600_ext_levels[] = { + { TOK_DRIVE_GAIN, "drive_gain", "Drive gain", "Drive gain", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } }, + }, + { RIG_CONF_END, NULL, } +}; const struct rig_caps ic7600_caps = { .rig_model = RIG_MODEL_IC7600, @@ -120,11 +177,15 @@ const struct rig_caps ic7600_caps = { .has_get_level = IC7600_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7600_LEVELS), .has_get_parm = IC7600_PARMS, -.has_set_parm = RIG_PARM_SET(IC7600_PARMS), /* FIXME: parms */ +.has_set_parm = RIG_PARM_SET(IC7600_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, +.extlevels = ic7600_ext_levels, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ @@ -181,18 +242,30 @@ const struct rig_caps ic7600_caps = { {IC7600_ALL_RX_MODES,kHz(25)}, RIG_TS_END, }, - /* mode/filter list, remember: order matters! */ +/* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { - {RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.4)}, - {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, - {RIG_MODE_CW|RIG_MODE_CWR, Hz(350)}, - {RIG_MODE_AM, kHz(6)}, - {RIG_MODE_AM, kHz(2.4)}, - {RIG_MODE_FM, kHz(12)}, - {RIG_MODE_FM, kHz(8)}, /* TBC */ - RIG_FLT_END, - }, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(2.4)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(1.8)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(3)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR, Hz(500)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR, Hz(250)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PSK|RIG_MODE_PSKR, kHz(1.2)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.4)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(6)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(3)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(9)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(10)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(7)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(15)}, + RIG_FLT_END, +}, .str_cal = IC7600_STR_CAL, +.swr_cal = IC7600_SWR_CAL, +.alc_cal = IC7600_ALC_CAL, +.rfpower_meter_cal = IC7600_RFPOWER_METER_CAL, +.comp_meter_cal = IC7600_COMP_METER_CAL, +.vd_meter_cal = IC7600_VD_METER_CAL, +.id_meter_cal = IC7600_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -212,15 +285,20 @@ const struct rig_caps ic7600_caps = { .set_ant = icom_set_ant, .get_ant = icom_get_ant, -.set_rit = icom_set_rit, +.set_rit = icom_set_rit_new, +.get_rit = icom_get_rit_new, +.get_xit = icom_get_rit_new, +.set_xit = icom_set_xit_new, .decode_event = icom_decode_event, -.set_level = icom_set_level, -.get_level = icom_get_level, +.set_level = ic7600_set_level, +.get_level = ic7600_get_level, +.set_ext_level = icom_set_ext_level, +.get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, -.set_parm = icom_set_parm, -.get_parm = icom_get_parm, +.set_parm = ic7600_set_parm, +.get_parm = ic7600_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, @@ -229,10 +307,6 @@ const struct rig_caps ic7600_caps = { .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, -.set_rptr_shift = icom_set_rptr_shift, -.get_rptr_shift = icom_get_rptr_shift, -.set_rptr_offs = icom_set_rptr_offs, -.get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, @@ -242,7 +316,114 @@ const struct rig_caps ic7600_caps = { .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, -.get_split_vfo = icom_mem_get_split_vfo, +.get_split_vfo = icom_get_split_vfo, +.set_powerstat = icom_set_powerstat, +.get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse }; +int ic7600_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x67; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic7600_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x67; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} + +int ic7600_set_parm(RIG *rig, setting_t parm, value_t val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x00; + parmbuf[1] = 0x59; + return icom_set_custom_parm(rig, 2, parmbuf, 1, val.i ? 1 : 0); + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x00; + parmbuf[1] = 0x38; + return icom_set_custom_parm(rig, 2, parmbuf, 2, (int) (val.f * 255.0f)); + case RIG_PARM_KEYLIGHT: + parmbuf[0] = 0x00; + parmbuf[1] = 0x39; + return icom_set_custom_parm(rig, 2, parmbuf, 2, val.f != 0 ? 255 : 0); + case RIG_PARM_TIME: + parmbuf[0] = 0x00; + parmbuf[1] = 0x54; + return icom_set_custom_parm_time(rig, 2, parmbuf, val.i); + default: + return icom_set_parm(rig, parm, val); + } +} + +int ic7600_get_parm(RIG *rig, setting_t parm, value_t *val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + int retval; + int icom_val; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x00; + parmbuf[1] = 0x59; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->i = icom_val ? 1 : 0; + break; + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x00; + parmbuf[1] = 0x38; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->f = (float) icom_val / 255.0f; + break; + case RIG_PARM_KEYLIGHT: + parmbuf[0] = 0x00; + parmbuf[1] = 0x39; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->f = icom_val > 0 ? 1 : 0; + break; + case RIG_PARM_TIME: + parmbuf[0] = 0x00; + parmbuf[1] = 0x54; + return icom_get_custom_parm_time(rig, 2, parmbuf, &val->i); + default: + return icom_get_parm(rig, parm, val); + } + + return RIG_OK; +} diff --git a/icom/ic7610.c b/icom/ic7610.c index 32d74df73..b9341806e 100644 --- a/icom/ic7610.c +++ b/icom/ic7610.c @@ -1,6 +1,6 @@ /* * Hamlib CI-V backend - description of IC-7610 - * Stolen from ic7600.c by Michael Black W9MDB + * Stolen from IC7610.c by Michael Black W9MDB * Copyright (c) 2010 by Stephane Fillod * * @@ -37,17 +37,14 @@ #include "misc.h" #include "bandplan.h" -/* - * TODO: PSK and PSKR - */ -#define IC7610_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 IC7610_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7610_1HZ_TS_MODES IC7610_ALL_RX_MODES -#define IC7610_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 IC7610_AM_TX_MODES (RIG_MODE_AM) +#define IC7610_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) +#define IC7610_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) -#define IC7610_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) +#define IC7610_FUNCS (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_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH) -#define IC7610_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) +#define IC7610_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB) #define IC7610_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7610_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) @@ -80,6 +77,52 @@ { 246, 60 } /* S9+60dB */ \ } } +#define IC7610_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC7610_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC7610_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 212, 1.0f } \ + } } + +#define IC7610_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 241, 30.0f } \ + } } + +#define IC7610_VD_METER_CAL { 4, \ + { \ + { 0, 0.0f }, \ + { 151, 10.0f }, \ + { 211, 16.0f } \ + } } + +#define IC7610_ID_METER_CAL { 4, \ + { \ + { 0, 0.0f }, \ + { 77, 10.0f }, \ + { 165, 20.0f }, \ + { 241, 30.0f } \ + } } + +int ic7610_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic7610_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* * IC-7610 rig capabilities. @@ -87,13 +130,31 @@ * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps ic7610_priv_caps = { - 0x98, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list, - .civ_version = 1 + 0x98, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; +const struct confparams ic7610_ext_levels[] = { + { TOK_DRIVE_GAIN, "drive_gain", "Drive gain", "Drive gain", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } }, + }, + { TOK_DIGI_SEL_FUNC, "digi_sel", "DIGI-SEL enable", "DIGI-SEL enable", + NULL, RIG_CONF_CHECKBUTTON, { }, + }, + { TOK_DIGI_SEL_LEVEL, "digi_sel_level", "DIGI-SEL level", "DIGI-SEL level", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } }, + }, + { RIG_CONF_END, NULL, } +}; const struct rig_caps ic7610_caps = { .rig_model = RIG_MODEL_IC7610, @@ -124,8 +185,12 @@ const struct rig_caps ic7610_caps = { .has_set_parm = RIG_PARM_SET(IC7610_PARMS), /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, +.extlevels = ic7610_ext_levels, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ @@ -182,18 +247,30 @@ const struct rig_caps ic7610_caps = { {IC7610_ALL_RX_MODES,kHz(25)}, RIG_TS_END, }, - /* mode/filter list, remember: order matters! */ +/* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { - {RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.4)}, - {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, - {RIG_MODE_CW|RIG_MODE_CWR, Hz(350)}, - {RIG_MODE_AM, kHz(6)}, - {RIG_MODE_AM, kHz(2.4)}, - {RIG_MODE_FM, kHz(12)}, - {RIG_MODE_FM, kHz(8)}, /* TBC */ - RIG_FLT_END, - }, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(2.4)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(1.8)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(3)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR, Hz(500)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR, Hz(250)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PSK|RIG_MODE_PSKR, kHz(1.2)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.4)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(6)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(3)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(9)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(10)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(7)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(15)}, + RIG_FLT_END, +}, .str_cal = IC7610_STR_CAL, +.swr_cal = IC7610_SWR_CAL, +.alc_cal = IC7610_ALC_CAL, +.rfpower_meter_cal = IC7610_RFPOWER_METER_CAL, +.comp_meter_cal = IC7610_COMP_METER_CAL, +.vd_meter_cal = IC7610_VD_METER_CAL, +.id_meter_cal = IC7610_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -213,11 +290,16 @@ const struct rig_caps ic7610_caps = { .set_ant = icom_set_ant, .get_ant = icom_get_ant, -.set_rit = icom_set_rit, +.set_rit = icom_set_rit_new, +.get_rit = icom_get_rit_new, +.get_xit = icom_get_rit_new, +.set_xit = icom_set_xit_new, .decode_event = icom_decode_event, -.set_level = icom_set_level, -.get_level = icom_get_level, +.set_level = ic7610_set_level, +.get_level = ic7610_get_level, +.set_ext_level = icom_set_ext_level, +.get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, @@ -230,10 +312,6 @@ const struct rig_caps ic7610_caps = { .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, -.set_rptr_shift = icom_set_rptr_shift, -.get_rptr_shift = icom_get_rptr_shift, -.set_rptr_offs = icom_set_rptr_offs, -.get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, @@ -243,7 +321,40 @@ const struct rig_caps ic7610_caps = { .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, -.get_split_vfo = icom_mem_get_split_vfo, +.get_split_vfo = icom_get_split_vfo, +.set_powerstat = icom_set_powerstat, +.get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse }; +int ic7610_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x02; + cmdbuf[1] = 0x92; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic7610_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x02; + cmdbuf[1] = 0x92; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} diff --git a/icom/ic7700.c b/icom/ic7700.c index 3ed14396f..e453c05c4 100644 --- a/icom/ic7700.c +++ b/icom/ic7700.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Strestate.attenuator[i]) { - val.i = i+1; - break; - } + for (i = 0; i < 7; i++) { + if (val.i == rig->state.attenuator[i]) { + val.i = i + 1; + break; + } } /* TODO: Should fail when not found? */ - } - - return icom_set_level(rig, vfo, level, val); + } + return icom_set_level(rig, vfo, level, val); + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x83; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } } /* @@ -263,18 +351,32 @@ int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) */ int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { - int ret; + unsigned char cmdbuf[MAXFRAMELEN]; + int retval; - ret = icom_get_level(rig, vfo, level, val); - if (ret != RIG_OK) - return ret; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - /* Convert index to dB - * Rem: ATT index 0 means attenuator Off - */ - if (level == RIG_LEVEL_ATT && val->i > 0 && val->i <= 7) + switch (level) { + case RIG_LEVEL_ATT: + retval = icom_get_level(rig, vfo, level, val); + if (retval != RIG_OK) { + return retval; + } + + /* Convert index to dB + * Rem: ATT index 0 means attenuator Off + */ + if (val->i > 0 && val->i <= 7) { val->i = rig->state.attenuator[val->i - 1]; + } + break; + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x83; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } - return RIG_OK; + return RIG_OK; } - diff --git a/icom/ic785x.c b/icom/ic785x.c index eff87b498..f93937650 100644 --- a/icom/ic785x.c +++ b/icom/ic785x.c @@ -37,17 +37,14 @@ #include "misc.h" #include "bandplan.h" -/* - * TODO: PSK and PSKR - */ -#define IC785x_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 IC785x_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC785x_1HZ_TS_MODES IC785x_ALL_RX_MODES -#define IC785x_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 IC785x_AM_TX_MODES (RIG_MODE_AM) +#define IC785x_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) +#define IC785x_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) -#define IC785x_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) +#define IC785x_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH) -#define IC785x_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) +#define IC785x_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB) #define IC785x_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC785x_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) @@ -57,9 +54,7 @@ #define IC785x_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) -/* - * FIXME: real measures! - */ +// IC-785x S-meter calibration data based on manual #define IC785x_STR_CAL { 3, \ { \ { 0, -54 }, /* S0 */ \ @@ -67,22 +62,89 @@ { 241, 60 } /* S9+60 */ \ } } +#define IC785x_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 48, 1.5f }, \ + { 80, 2.0f }, \ + { 120, 3.0f }, \ + { 240, 6.0f } \ + } } + +#define IC785x_ALC_CAL { 2, \ + { \ + { 0, 0.0f }, \ + { 120, 1.0f } \ + } } + +#define IC785x_RFPOWER_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 143, 0.5f }, \ + { 213, 1.0f } \ + } } + +#define IC785x_COMP_METER_CAL { 3, \ + { \ + { 0, 0.0f }, \ + { 130, 15.0f }, \ + { 241, 30.0f } \ + } } + +#define IC785x_VD_METER_CAL { 4, \ + { \ + { 0, 0.0f }, \ + { 151, 44.0f }, \ + { 180, 48.0f }, \ + { 211, 52.0f } \ + } } + +#define IC785x_ID_METER_CAL { 4, \ + { \ + { 0, 0.0f }, \ + { 97, 10.0f }, \ + { 146, 15.0f }, \ + { 241, 25.0f } \ + } } extern int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); extern int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int ic785x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ic785x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); + /* * IC-785x rig capabilities. * * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps ic785x_priv_caps = { - 0x8e, /* default address */ - 0, /* 731 mode */ - 0, /* no XCHG */ - ic756pro_ts_sc_list + 0x8e, /* default address */ + 0, /* 731 mode */ + 0, /* no XCHG */ + ic756pro_ts_sc_list, + .agc_levels_present = 1, + .agc_levels = { + { .level = RIG_AGC_OFF, .icom_level = 0 }, + { .level = RIG_AGC_FAST, .icom_level = 1 }, + { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, + { .level = RIG_AGC_SLOW, .icom_level = 3 }, + { .level = -1, .icom_level = 0 }, + }, }; +const struct confparams ic785x_ext_levels[] = { + { TOK_DRIVE_GAIN, "drive_gain", "Drive gain", "Drive gain", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } }, + }, + { TOK_DIGI_SEL_FUNC, "digi_sel", "DIGI-SEL enable", "DIGI-SEL enable", + NULL, RIG_CONF_CHECKBUTTON, { }, + }, + { TOK_DIGI_SEL_LEVEL, "digi_sel_level", "DIGI-SEL level", "DIGI-SEL level", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } }, + }, + { RIG_CONF_END, NULL, } +}; const struct rig_caps ic785x_caps = { .rig_model = RIG_MODEL_IC785x, @@ -113,8 +175,12 @@ const struct rig_caps ic785x_caps = { .has_set_parm = RIG_PARM_SET(IC785x_PARMS), /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, +.extlevels = ic785x_ext_levels, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ @@ -173,15 +239,28 @@ const struct rig_caps ic785x_caps = { }, /* mode/filter list, remember: order matters! */ .filters = { - {RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.4)}, - {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, - {RIG_MODE_AM, kHz(6)}, - {RIG_MODE_AM, kHz(2.4)}, - {RIG_MODE_FM, kHz(15)}, - {RIG_MODE_FM, kHz(8)}, - RIG_FLT_END, - }, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(2.4)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(1.8)}, + {RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB, kHz(3)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR, Hz(400)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR, Hz(50)}, + {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PSK|RIG_MODE_PSKR, kHz(1.0)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.4)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(6)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(3)}, + {RIG_MODE_AM|RIG_MODE_PKTAM, kHz(9)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(12)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(8)}, + {RIG_MODE_FM|RIG_MODE_PKTFM, kHz(15)}, + RIG_FLT_END, + }, .str_cal = IC785x_STR_CAL, +.swr_cal = IC785x_SWR_CAL, +.alc_cal = IC785x_ALC_CAL, +.rfpower_meter_cal = IC785x_RFPOWER_METER_CAL, +.comp_meter_cal = IC785x_COMP_METER_CAL, +.vd_meter_cal = IC785x_VD_METER_CAL, +.id_meter_cal = IC785x_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, @@ -201,11 +280,16 @@ const struct rig_caps ic785x_caps = { .set_ant = icom_set_ant, .get_ant = icom_get_ant, -.set_rit = icom_set_rit, +.set_rit = icom_set_rit_new, +.get_rit = icom_get_rit_new, +.get_xit = icom_get_rit_new, +.set_xit = icom_set_xit_new, .decode_event = icom_decode_event, -.set_level = ic7800_set_level, -.get_level = ic7800_get_level, +.set_level = ic785x_set_level, +.get_level = ic785x_get_level, +.set_ext_level = icom_set_ext_level, +.get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, @@ -218,10 +302,6 @@ const struct rig_caps ic785x_caps = { .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, -.set_rptr_shift = icom_set_rptr_shift, -.get_rptr_shift = icom_get_rptr_shift, -.set_rptr_offs = icom_set_rptr_offs, -.get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, @@ -231,8 +311,41 @@ const struct rig_caps ic785x_caps = { .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, -.get_split_vfo = icom_mem_get_split_vfo, +.get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, +.send_morse = icom_send_morse }; + +int ic785x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x03; + cmdbuf[1] = 0x09; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, 1, val); + default: + return ic7800_set_level(rig, vfo, level, val); + } +} + +int ic785x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x03; + cmdbuf[1] = 0x09; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, val); + default: + return ic7800_get_level(rig, vfo, level, val); + } +} diff --git a/icom/ic910.c b/icom/ic910.c index afc243ce7..54c305eee 100644 --- a/icom/ic910.c +++ b/icom/ic910.c @@ -1,6 +1,6 @@ /* - * Hamlib CI-V backend - description of IC-910 (VHF/UHF All-Mode - * Tranceiver) Contributed by Francois Retief + * Hamlib CI-V backend - description of IC-910 (VHF/UHF All-Mode Transceiver) + * Contributed by Francois Retief * Copyright (c) 2000-2010 by Stephane Fillod * * @@ -27,6 +27,7 @@ #include #include +#include "misc.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" @@ -290,8 +291,7 @@ static int ic910_r2i_mode(RIG *rig, rmode_t mode, pbwidth_t width, RIG_OP_MCL| \ RIG_OP_XCHG) -#define IC910_FUNC_ALL (RIG_FUNC_FAGC| \ - RIG_FUNC_NB| \ +#define IC910_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ @@ -321,9 +321,6 @@ static int ic910_r2i_mode(RIG *rig, rmode_t mode, pbwidth_t width, #define IC910_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ - -/* - */ static const struct icom_priv_caps ic910_priv_caps = { 0x60, /* default address */ 0, /* 731 mode */ @@ -332,6 +329,54 @@ static const struct icom_priv_caps ic910_priv_caps = { .r2i_mode = ic910_r2i_mode }; +int ic910_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +{ + switch (func) { + case RIG_FUNC_SCOPE: + return icom_set_raw(rig, C_CTL_MEM, S_MEM_BANDSCOPE, 0, NULL, 1, status ? 1 : 0); + case RIG_FUNC_SATMODE: + return icom_set_raw(rig, C_CTL_MEM, S_MEM_SATMODE, 0, NULL, 1, status ? 1 : 0); + default: + return icom_set_func(rig, vfo, func, status); + } +} + +int ic910_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) +{ + switch (func) { + case RIG_FUNC_SCOPE: + return icom_get_raw(rig, C_CTL_MEM, S_MEM_BANDSCOPE, 0, NULL, status); + case RIG_FUNC_SATMODE: + return icom_get_raw(rig, C_CTL_MEM, S_MEM_SATMODE, 0, NULL, status); + default: + return icom_get_func(rig, vfo, func, status); + } +} + +int ic910_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + return icom_set_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic910_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + return icom_get_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} + const struct rig_caps ic910_caps = { .rig_model = RIG_MODEL_IC910, .model_name = "IC-910", @@ -361,6 +406,7 @@ const struct rig_caps ic910_caps = { .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = NULL, @@ -457,10 +503,10 @@ const struct rig_caps ic910_caps = { .set_vfo = icom_set_vfo, .get_ts = icom_get_ts, .set_ts = icom_set_ts, -.get_func = icom_get_func, -.set_func = icom_set_func, -.get_level = icom_get_level, -.set_level = icom_set_level, +.get_func = ic910_get_func, +.set_func = ic910_set_func, +.get_level = ic910_get_level, +.set_level = ic910_set_level, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, @@ -475,5 +521,3 @@ const struct rig_caps ic910_caps = { .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, }; - -/* end of file */ diff --git a/icom/ic9100.c b/icom/ic9100.c index fb6daaf32..af1e26fa2 100644 --- a/icom/ic9100.c +++ b/icom/ic9100.c @@ -49,8 +49,7 @@ RIG_OP_XCHG| \ RIG_OP_TUNE) -#define IC9100_FUNC_ALL (RIG_FUNC_FAGC| \ - RIG_FUNC_NB| \ +#define IC9100_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ @@ -82,9 +81,10 @@ RIG_LEVEL_AGC| \ RIG_LEVEL_PBT_IN| \ RIG_LEVEL_PBT_OUT| \ - RIG_LEVEL_NOTCHF| \ + RIG_LEVEL_NOTCHF_RAW| \ RIG_LEVEL_ATT| \ - RIG_LEVEL_PREAMP) + RIG_LEVEL_PREAMP| \ + RIG_LEVEL_MONITOR_GAIN) #define IC9100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) @@ -130,6 +130,7 @@ const struct rig_caps ic9100_caps = { .has_set_parm = IC9100_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, @@ -270,4 +271,34 @@ const struct rig_caps ic9100_caps = { }; -/* end of file */ +int ic9100_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x27; + return icom_set_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, 1, val); + default: + return icom_set_level(rig, vfo, level, val); + } +} + +int ic9100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (level) { + case RIG_LEVEL_VOXDELAY: + cmdbuf[0] = 0x01; + cmdbuf[1] = 0x27; + return icom_get_level_raw(rig, level, C_CTL_MEM, 0x05, 2, cmdbuf, val); + default: + return icom_get_level(rig, vfo, level, val); + } +} diff --git a/icom/icom.c b/icom/icom.c index 2cf883160..a3a666ab8 100644 --- a/icom/icom.c +++ b/icom/icom.c @@ -39,6 +39,62 @@ #include "icom_defs.h" #include "frame.h" +const cal_table_float_t icom_default_swr_cal = { + 5, + { + { 0, 1.0f }, + { 48, 1.5f }, + { 80, 2.0f }, + { 120, 3.0f }, + { 240, 6.0f } + } +}; + +const cal_table_float_t icom_default_alc_cal = { + 2, + { + { 0, 0.0f }, + { 120, 1.0f } + } +}; + +const cal_table_float_t icom_default_rfpower_meter_cal = { + 3, + { + { 0, 0.0f }, + { 143, 0.5f }, + { 213, 1.0f } + } +}; + +const cal_table_float_t icom_default_comp_meter_cal = { + 3, + { + { 0, 0.0f }, + { 130, 15.0f }, + { 241, 30.0f } + } +}; + +const cal_table_float_t icom_default_vd_meter_cal = { + 3, + { + { 0, 0.0f }, + { 13, 10.0f }, + { 241, 16.0f } + } +}; + +const cal_table_float_t icom_default_id_meter_cal = { + 4, + { + { 0, 0.0f }, + { 97, 10.0f }, + { 146, 15.0f }, + { 241, 25.0f } + } +}; + const struct ts_sc_list r8500_ts_sc_list[] = { { 10, 0x00 }, { 50, 0x01 }, @@ -427,8 +483,7 @@ int icom_init(RIG *rig) priv->re_civ_addr = priv_caps->re_civ_addr; priv->civ_731_mode = priv_caps->civ_731_mode; priv->no_xchg = priv_caps->no_xchg; - priv->civ_version = priv_caps->civ_version; - rig_debug(RIG_DEBUG_TRACE,"icom_init: civ_version=%d\n", priv->civ_version); + rig_debug(RIG_DEBUG_TRACE,"icom_init\n"); return RIG_OK; } @@ -578,7 +633,7 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) case RIG_VFO_MAIN: cmd = C_SET_VFO; subcmd = S_SUB_SEL; - data = 0 ; + data = 0; datalen = 1; break; case RIG_VFO_SUB: @@ -592,20 +647,10 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) if (retval != RIG_OK) return retval; - // The command to read Main/Sub freq is 1 byte longer - // So a simple solution here is to just move left 1 byte - if (cmd == C_SEND_SEL_FREQ) { - memmove(freqbuf,freqbuf+1,freq_len-1); - freq_len--; // have to take off one more byte from the response - } /* * freqbuf should contain Cn,Data area */ freq_len--; - if (priv->civ_version >= 2) { - memmove(freqbuf,freqbuf+1,freq_len); - freq_len--; - } /* * is it a blank mem channel ? @@ -663,6 +708,73 @@ int icom_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) return RIG_OK; } +int icom_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *ts) +{ + unsigned char tsbuf[MAXFRAMELEN]; + int ts_len, retval; + + retval = icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, NULL, 0, tsbuf, &ts_len); + if (retval != RIG_OK) { + return retval; + } + + /* + * tsbuf nibbles should contain 10,1,1000,100 hz digits and 00=+, 01=- bit + */ + rig_debug(RIG_DEBUG_VERBOSE, "ts_len=%d\n", ts_len); + if (ts_len != 5) { + rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len); + return -RIG_ERJCTED; + } + + *ts = (shortfreq_t) from_bcd(tsbuf + 2, 4); + if (tsbuf[4] != 0) { + *ts *= -1; + } + + return RIG_OK; +} + +// The Icom rigs have only one register for both RIT and Delta TX +// you can turn one or both on -- but both end up just being in sync. +static int icom_set_it_new(RIG *rig, vfo_t vfo, shortfreq_t ts, int set_xit) { + unsigned char tsbuf[8]; + unsigned char ackbuf[16]; + int ack_len; + int retval; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: ts=%d\n", __func__, ts); + + to_bcd(tsbuf, abs((int) ts), 4); + // set sign bit + tsbuf[2] = (ts < 0) ? 1 : 0; + + retval = icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, tsbuf, 3, ackbuf, &ack_len); + if (retval != RIG_OK) { + return retval; + } + + if (ts == 0) { // Turn off both RIT/XIT + retval = icom_set_func(rig, vfo, RIG_FUNC_XIT, 0); + if (retval != RIG_OK) { + return retval; + } + retval = icom_set_func(rig, vfo, RIG_FUNC_RIT, 0); + } else { + retval = icom_set_func(rig, vfo, set_xit ? RIG_FUNC_XIT : RIG_FUNC_RIT, 1); + } + return retval; +} + +int icom_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t ts) +{ + return icom_set_it_new(rig, vfo, ts, 0); +} + +int icom_set_xit_new(RIG *rig, vfo_t vfo, shortfreq_t ts) +{ + return icom_set_it_new(rig, vfo, ts, 1); +} /* icom_get_dsp_flt returns the dsp filter width in hz or 0 if the command is not implemented or error. @@ -774,55 +886,63 @@ int icom_set_dsp_flt(RIG *rig, rmode_t mode, pbwidth_t width) { */ int icom_set_mode_with_data (RIG * rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { - int retval; - unsigned char datamode; - unsigned char ackbuf[MAXFRAMELEN]; - int ack_len=sizeof(ackbuf); - rmode_t icom_mode; - unsigned char dm_sub_cmd = RIG_MODEL_IC7200 == rig->caps->rig_model ? 0x04 : S_MEM_DATA_MODE; + int retval; + unsigned char datamode; + unsigned char ackbuf[MAXFRAMELEN]; + int ack_len = sizeof(ackbuf); + rmode_t icom_mode; + unsigned char dm_sub_cmd = RIG_MODEL_IC7200 == rig->caps->rig_model ? 0x04 : S_MEM_DATA_MODE; - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - switch (mode) - { - case RIG_MODE_PKTUSB: icom_mode = RIG_MODE_USB; break; - case RIG_MODE_PKTLSB: icom_mode = RIG_MODE_LSB; break; - case RIG_MODE_PKTFM: icom_mode = RIG_MODE_FM; break; - default: icom_mode = mode; break; - }; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - retval = icom_set_mode (rig, vfo, icom_mode, width); + switch (mode) { + case RIG_MODE_PKTUSB: + icom_mode = RIG_MODE_USB; + break; + case RIG_MODE_PKTLSB: + icom_mode = RIG_MODE_LSB; + break; + case RIG_MODE_PKTFM: + icom_mode = RIG_MODE_FM; + break; + case RIG_MODE_PKTAM: + icom_mode = RIG_MODE_AM; + break; + default: + icom_mode = mode; + break; + } - if (RIG_OK == retval) - { - if (RIG_MODE_PKTUSB == mode || RIG_MODE_PKTLSB == mode || RIG_MODE_PKTFM == mode) - { - datamode = 0x01; /* some rigs (e.g. IC-7700 & IC-7800) - have D1/2/3 but we cannot know - which to set so just set D1 */ - } - else - { - datamode = 0x00; + retval = icom_set_mode(rig, vfo, icom_mode, width); + + if (RIG_OK == retval) { + switch (mode) { + case RIG_MODE_PKTUSB: + case RIG_MODE_PKTLSB: + case RIG_MODE_PKTFM: + case RIG_MODE_PKTAM: + /* some rigs (e.g. IC-7700 & IC-7800) + have D1/2/3 but we cannot know + which to set so just set D1 */ + datamode = 0x01; + break; + default: + datamode = 0x00; + break; } - retval = icom_transaction (rig, C_CTL_MEM, dm_sub_cmd, &datamode, 1, - ackbuf, &ack_len); - if (retval != RIG_OK) - { - rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " - "len=%d\n", __FUNCTION__,ackbuf[0],ack_len); - } - else - { - if (ack_len != 1 || ackbuf[0] != ACK) - { - rig_debug(RIG_DEBUG_ERR,"%s: command not supported ? (%#.2x), " - "len=%d\n", __FUNCTION__,ackbuf[0],ack_len); + retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, &datamode, 1, ackbuf, &ack_len); + + if (retval != RIG_OK) { + rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n", __FUNCTION__, ackbuf[0], ack_len); + } else { + if (ack_len != 1 || ackbuf[0] != ACK) { + rig_debug(RIG_DEBUG_ERR, "%s: command not supported ? (%#.2x), len=%d\n", __FUNCTION__, ackbuf[0], ack_len); } } } - return retval; + return retval; } /* @@ -896,56 +1016,71 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) */ int icom_get_mode_with_data(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { - unsigned char databuf[MAXFRAMELEN]; - int data_len, retval; - unsigned char dm_sub_cmd = RIG_MODEL_IC7200 == rig->caps->rig_model ? 0x04 : S_MEM_DATA_MODE; + unsigned char databuf[MAXFRAMELEN]; + int data_len, retval; + unsigned char dm_sub_cmd = RIG_MODEL_IC7200 == rig->caps->rig_model ? 0x04 : S_MEM_DATA_MODE; - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - retval = icom_get_mode (rig, vfo, mode, width); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + retval = icom_get_mode(rig, vfo, mode, width); - if (RIG_OK == retval && (RIG_MODE_USB == *mode || RIG_MODE_LSB == *mode || RIG_MODE_FM == *mode)) - { + if (retval != RIG_OK) { + return retval; + } + + switch (*mode) { + case RIG_MODE_USB: + case RIG_MODE_LSB: + case RIG_MODE_AM: + case RIG_MODE_FM: /* * fetch data mode on/off */ - retval = icom_transaction (rig, C_CTL_MEM, dm_sub_cmd, 0, 0, - databuf, &data_len); - if (retval != RIG_OK) - { - rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " - "len=%d\n", __FUNCTION__, databuf[0], data_len); + retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, 0, 0, databuf, &data_len); + if (retval != RIG_OK) { + rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n", __FUNCTION__, databuf[0], data_len); return -RIG_ERJCTED; - } + } /* * databuf should contain Cn,Sc,D0[,D1] */ data_len -= 2; - if (1 > data_len || data_len > 2) /* manual says 1 byte answer - but at least IC756 ProIII - sends 2 - second byte - appears to be same as - second byte from 04 command - which is filter preset - number, whatever it is we - ignore it */ - { - rig_debug(RIG_DEBUG_ERR,"%s: wrong frame len=%d\n", - __FUNCTION__, data_len); + if (1 > data_len || data_len > 2) { + /* manual says 1 byte answer + but at least IC756 ProIII + sends 2 - second byte + appears to be same as + second byte from 04 command + which is filter preset + number, whatever it is we + ignore it */ + rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __FUNCTION__, data_len); return -RIG_ERJCTED; - } - if (databuf[2]) /* 0x01/0x02/0x03 -> data mode, 0x00 -> not data mode */ - { - switch (*mode) - { - case RIG_MODE_USB: *mode = RIG_MODE_PKTUSB; break; - case RIG_MODE_LSB: *mode = RIG_MODE_PKTLSB; break; - case RIG_MODE_FM: *mode = RIG_MODE_PKTFM; break; - default: break; - } - } + } + + if (databuf[2]) { /* 0x01/0x02/0x03 -> data mode, 0x00 -> not data mode */ + switch (*mode) { + case RIG_MODE_USB: + *mode = RIG_MODE_PKTUSB; + break; + case RIG_MODE_LSB: + *mode = RIG_MODE_PKTLSB; + break; + case RIG_MODE_AM: + *mode = RIG_MODE_PKTAM; + break; + case RIG_MODE_FM: + *mode = RIG_MODE_PKTFM; + break; + default: + break; + } + } + default: + break; } - return retval; + + return retval; } /* @@ -1103,7 +1238,6 @@ int icom_set_vfo(RIG *rig, vfo_t vfo) int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *rs; - struct icom_priv_data *priv; unsigned char lvlbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len=sizeof(ackbuf), lvl_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ @@ -1112,7 +1246,9 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rs = &rig->state; - priv = (struct icom_priv_data*)rs->priv; + + const struct icom_priv_caps *priv_caps = + (const struct icom_priv_caps*) rig->caps->priv; /* * So far, levels of float type are in [0.0..1.0] range @@ -1138,16 +1274,27 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) break; } } - if (priv->civ_version == 1) { - switch (level) { - case RIG_LEVEL_KEYSPD: - if (val.i < 6) val.i = 6; - if (val.i > 48) val.i = 48; - icom_val = (val.i-6)*(255/42.0)+.99; - default: - break; - } - } + + switch (level) { + case RIG_LEVEL_KEYSPD: + if (val.i < 6) { + icom_val = 6; + } else if (val.i > 48) { + icom_val = 48; + } + icom_val = (int) lroundf(((float) icom_val - 6.0f) * (255.0f / 42.0f)); + break; + case RIG_LEVEL_CWPITCH: + if (val.i < 300) { + icom_val = 300; + } else if (val.i >= 900) { + icom_val = 900; + } + icom_val = (int) lroundf(((float) icom_val - 300) * (255.0f / 600.0f)); + break; + default: + break; + } /* * Most of the time, the data field is a 3 digit BCD, @@ -1207,6 +1354,10 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NR; break; + case RIG_LEVEL_NB: + lvl_cn = C_CTL_LVL; + lvl_sc = S_LVL_NB; + break; case RIG_LEVEL_PBT_IN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTIN; @@ -1239,7 +1390,7 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_KEYSPD; break; - case RIG_LEVEL_NOTCHF: + case RIG_LEVEL_NOTCHF_RAW: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NOTCHF; break; @@ -1247,20 +1398,45 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_COMP; break; - case RIG_LEVEL_AGC: - lvl_cn = C_CTL_FUNC; - lvl_sc = S_FUNC_AGC; - lvl_len = 1; - switch (val.i) { - case RIG_AGC_SLOW: lvlbuf[0] = D_AGC_SLOW; break; - case RIG_AGC_MEDIUM: lvlbuf[0] = D_AGC_MID; break; - case RIG_AGC_FAST: lvlbuf[0] = D_AGC_FAST; break; - case RIG_AGC_SUPERFAST: lvlbuf[0] = D_AGC_SUPERFAST; break; - default: - rig_debug(RIG_DEBUG_ERR,"Unsupported LEVEL_AGC %d", val.i); + case RIG_LEVEL_AGC: + lvl_cn = C_CTL_FUNC; + lvl_sc = S_FUNC_AGC; + lvl_len = 1; + + if (priv_caps->agc_levels_present) { + int found = 0; + + for (i = 0; i <= RIG_AGC_LAST && priv_caps->agc_levels[i].level >= 0; i++) { + if (priv_caps->agc_levels[i].level == val.i) { + lvlbuf[0] = priv_caps->agc_levels[i].icom_level; + found = 1; + break; + } + } + if (!found) { return -RIG_EINVAL; + } + } else { + // Legacy mapping that does not apply to all rigs + switch (val.i) { + case RIG_AGC_SLOW: + lvlbuf[0] = D_AGC_SLOW; + break; + case RIG_AGC_MEDIUM: + lvlbuf[0] = D_AGC_MID; + break; + case RIG_AGC_FAST: + lvlbuf[0] = D_AGC_FAST; + break; + case RIG_AGC_SUPERFAST: + lvlbuf[0] = D_AGC_SUPERFAST; + break; + default: + rig_debug(RIG_DEBUG_ERR, "Unsupported LEVEL_AGC %d", val.i); + return -RIG_EINVAL; + } } - break; + break; case RIG_LEVEL_BKINDL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BKINDL; @@ -1279,19 +1455,6 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) lvl_sc = S_LVL_VOXGAIN; } break; - case RIG_LEVEL_VOXDELAY: - if (priv->civ_version == 1) { - lvl_cn = C_CTL_MEM; - lvl_sc = 0x05; // plus 0191 and value 0-20 = 0-2 secs - lvl_len = 2; - lvlbuf[0] = 0x01; - lvlbuf[1] = 0x91; - } - else { /* IC-910H */ - lvl_cn = C_CTL_MEM; - lvl_sc = S_MEM_VOXDELAY; - } - break; case RIG_LEVEL_ANTIVOX: if (rig->caps->rig_model == RIG_MODEL_IC910) { /* IC-910H */ @@ -1302,19 +1465,21 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) lvl_sc = S_LVL_ANTIVOX; } break; + case RIG_LEVEL_MONITOR_GAIN: + lvl_cn = C_CTL_LVL; + lvl_sc = S_LVL_MON; + break; default: rig_debug(RIG_DEBUG_ERR,"Unsupported set_level %d", level); return -RIG_EINVAL; } - retval = icom_transaction (rig, lvl_cn, lvl_sc, lvlbuf, lvl_len, - ackbuf, &ack_len); + retval = icom_transaction (rig, lvl_cn, lvl_sc, lvlbuf, lvl_len, ackbuf, &ack_len); if (retval != RIG_OK) return retval; if (ack_len != 1 || ackbuf[0] != ACK) { - rig_debug(RIG_DEBUG_ERR,"icom_set_level: ack NG (%#.2x), " - "len=%d\n", ackbuf[0], ack_len); + rig_debug(RIG_DEBUG_ERR,"icom_set_level: ack NG (%#.2x), len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } @@ -1325,16 +1490,10 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) * icom_get_level * Assumes rig!=NULL, rig->state.priv!=NULL, val!=NULL * - * TODO (missing RIG_LEVEL): - * - S_RiML: Read real RFpower-meter level - * - S_CMP: Read COMP-meter level - * - S_VD : Read Vd-meter level - * - S_ID : Read Id-meter level */ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *rs; - struct icom_priv_data *priv; unsigned char lvlbuf[MAXFRAMELEN], lvl2buf[MAXFRAMELEN]; int lvl_len, lvl2_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ @@ -1344,7 +1503,9 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rs = &rig->state; - priv = (struct icom_priv_data*)rs->priv; + + const struct icom_priv_caps *priv_caps = + (const struct icom_priv_caps*) rig->caps->priv; lvl2_len = 0; @@ -1362,6 +1523,22 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) lvl_cn = C_RD_SQSM; lvl_sc = S_SWR; break; + case RIG_LEVEL_RFPOWER_METER: + lvl_cn = C_RD_SQSM; + lvl_sc = S_RFML; + break; + case RIG_LEVEL_COMP_METER: + lvl_cn = C_RD_SQSM; + lvl_sc = S_CMP; + break; + case RIG_LEVEL_VD_METER: + lvl_cn = C_RD_SQSM; + lvl_sc = S_VD; + break; + case RIG_LEVEL_ID_METER: + lvl_cn = C_RD_SQSM; + lvl_sc = S_ID; + break; case RIG_LEVEL_PREAMP: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_PAMP; @@ -1394,6 +1571,10 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NR; break; + case RIG_LEVEL_NB: + lvl_cn = C_CTL_LVL; + lvl_sc = S_LVL_NB; + break; case RIG_LEVEL_PBT_IN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTIN; @@ -1425,7 +1606,7 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_KEYSPD; break; - case RIG_LEVEL_NOTCHF: + case RIG_LEVEL_NOTCHF_RAW: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NOTCHF; break; @@ -1455,10 +1636,6 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) lvl_sc = S_LVL_VOXGAIN; } break; - case RIG_LEVEL_VOXDELAY: /* IC-910H */ - lvl_cn = C_CTL_MEM; - lvl_sc = S_MEM_VOXDELAY; - break; case RIG_LEVEL_ANTIVOX: if (rig->caps->rig_model == RIG_MODEL_IC910) { /* IC-910H */ @@ -1469,21 +1646,17 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) lvl_sc = S_LVL_ANTIVOX; } break; -/* Not implemented yet - case TOK_LEVEL_MONITOR: - lvl_cn = C_CTL_MEM; - lvl_sc = S_MEM_MONITOR; - break; -*/ - + case RIG_LEVEL_MONITOR_GAIN: + lvl_cn = C_CTL_LVL; + lvl_sc = S_LVL_MON; + break; default: rig_debug(RIG_DEBUG_ERR,"Unsupported get_level %d", level); return -RIG_EINVAL; } /* use lvl2buf and lvl2_len for 'set mode' subcommand */ - retval = icom_transaction (rig, lvl_cn, lvl_sc, lvl2buf, lvl2_len, - lvlbuf, &lvl_len); + retval = icom_transaction (rig, lvl_cn, lvl_sc, lvl2buf, lvl2_len, lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; @@ -1499,8 +1672,7 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) } if (lvlbuf[0] != ACK && lvlbuf[0] != lvl_cn) { - rig_debug(RIG_DEBUG_ERR,"icom_get_level: ack NG (%#.2x), " - "len=%d\n", lvlbuf[0],lvl_len); + rig_debug(RIG_DEBUG_ERR,"icom_get_level: ack NG (%#.2x), len=%d\n", lvlbuf[0],lvl_len); return -RIG_ERJCTED; } @@ -1518,25 +1690,89 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) /* raw value */ val->i = icom_val; break; - case RIG_LEVEL_AGC: - switch (icom_val) { - case D_AGC_SLOW: val->i = RIG_AGC_SLOW; break; - case D_AGC_MID: val->i = RIG_AGC_MEDIUM; break; - case D_AGC_FAST: val->i = RIG_AGC_FAST; break; - case D_AGC_SUPERFAST: val->i = RIG_AGC_SUPERFAST; break; - default: - rig_debug(RIG_DEBUG_ERR,"Unexpected AGC 0x%02x", icom_val); + case RIG_LEVEL_AGC: + if (priv_caps->agc_levels_present) { + int found = 0; + + for (int i = 0; i <= RIG_AGC_LAST && priv_caps->agc_levels[i].level >= 0; i++) { + if (priv_caps->agc_levels[i].icom_level == icom_val) { + val->i = priv_caps->agc_levels[i].level; + found = 1; + break; + } + } + if (!found) { + rig_debug(RIG_DEBUG_ERR, "Unexpected AGC 0x%02x", icom_val); return -RIG_EPROTO; + } + } else { + switch (icom_val) { + case D_AGC_SLOW: + val->i = RIG_AGC_SLOW; + break; + case D_AGC_MID: + val->i = RIG_AGC_MEDIUM; + break; + case D_AGC_FAST: + val->i = RIG_AGC_FAST; + break; + case D_AGC_SUPERFAST: + val->i = RIG_AGC_SUPERFAST; + break; + default: + rig_debug(RIG_DEBUG_ERR, "Unexpected AGC 0x%02x", icom_val); + return -RIG_EPROTO; + } } - break; - case RIG_LEVEL_ALC: - /* 120 max on IC-7600 */ - val->f = (float)icom_val/120; - break; - case RIG_LEVEL_SWR: - /* {0->1, 48->1.5, 80->2} on IC-7600 */ - val->f = 1. + (float)icom_val/80; - break; + break; + case RIG_LEVEL_ALC: + if (rig->caps->alc_cal.size == 0) { + val->f = rig_raw2val_float(icom_val, &icom_default_alc_cal); + } else { + val->f = rig_raw2val_float(icom_val, &rig->caps->alc_cal); + } + break; + case RIG_LEVEL_SWR: + if (rig->caps->swr_cal.size == 0) { + val->f = rig_raw2val_float(icom_val, &icom_default_swr_cal); + } else { + val->f = rig_raw2val_float(icom_val, &rig->caps->swr_cal); + } + break; + case RIG_LEVEL_RFPOWER_METER: + if (rig->caps->rfpower_meter_cal.size == 0) { + val->f = rig_raw2val_float(icom_val, &icom_default_rfpower_meter_cal); + } else { + val->f = rig_raw2val_float(icom_val, &rig->caps->rfpower_meter_cal); + } + break; + case RIG_LEVEL_COMP_METER: + if (rig->caps->comp_meter_cal.size == 0) { + val->f = rig_raw2val_float(icom_val, &icom_default_comp_meter_cal); + } else { + val->f = rig_raw2val_float(icom_val, &rig->caps->comp_meter_cal); + } + break; + case RIG_LEVEL_VD_METER: + if (rig->caps->vd_meter_cal.size == 0) { + val->f = rig_raw2val_float(icom_val, &icom_default_vd_meter_cal); + } else { + val->f = rig_raw2val_float(icom_val, &rig->caps->vd_meter_cal); + } + break; + case RIG_LEVEL_ID_METER: + if (rig->caps->id_meter_cal.size == 0) { + val->f = rig_raw2val_float(icom_val, &icom_default_id_meter_cal); + } else { + val->f = rig_raw2val_float(icom_val, &rig->caps->id_meter_cal); + } + break; + case RIG_LEVEL_CWPITCH: + val->i = (int) lroundf(300.0f + ((float) icom_val * 600.0f / 255.0f)); + break; + case RIG_LEVEL_KEYSPD: + val->i = (int) lroundf((float) icom_val * (42.0f / 255.0f) + 6.0f); + break; case RIG_LEVEL_PREAMP: if (icom_val == 0) { val->i = 0; @@ -1574,13 +1810,6 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; } } - else if ((priv->civ_version == 1)&&(level==RIG_LEVEL_KEYSPD)){ - switch (level) { - case RIG_LEVEL_KEYSPD: - val->i = val->i*(42.0/255)+6+.5; - break; - } - } rig_debug(RIG_DEBUG_TRACE,"icom_get_level: %d %d %d %f\n", lvl_len, icom_val, val->i, val->f); @@ -1591,37 +1820,65 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) /* * icom_set_ext_level * Assumes rig!=NULL, rig->state.priv!=NULL - * */ int icom_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val) { - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - switch (token) { - case TOK_LEVEL_MONITOR: - rig_debug(RIG_DEBUG_VERBOSE, "TOK_LEVEL_MONITOR\n", __func__); - break; - default: return -RIG_EINVAL; - } - return RIG_OK; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (token) { + case TOK_DRIVE_GAIN: + return icom_set_raw(rig, C_CTL_LVL, S_LVL_DRIVE, 0, NULL, 2, (int) val.f); + case TOK_DIGI_SEL_FUNC: + return icom_set_raw(rig, C_CTL_FUNC, S_FUNC_DIGISEL, 0, NULL, 1, val.i ? 1 : 0); + case TOK_DIGI_SEL_LEVEL: + return icom_set_raw(rig, C_CTL_LVL, S_LVL_DIGI, 0, NULL, 2, (int) val.f); + default: + return -RIG_EINVAL; + } } /* * icom_get_ext_level * Assumes rig!=NULL, rig->state.priv!=NULL, val!=NULL - * */ int icom_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val) { - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - switch (token) { - case TOK_LEVEL_MONITOR: - rig_debug(RIG_DEBUG_VERBOSE, "TOK_LEVEL_MONITOR\n", __func__); - break; - default: return -RIG_EINVAL; - } - return RIG_OK; -} + int icom_val; + int retval; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (token) { + case TOK_DRIVE_GAIN: + retval = icom_get_raw(rig, C_CTL_LVL, S_LVL_DRIVE, 0, NULL, &icom_val); + if (retval != RIG_OK) { + return retval; + } + + val->f = (float) icom_val; + break; + case TOK_DIGI_SEL_FUNC: + retval = icom_get_raw(rig, C_CTL_FUNC, S_FUNC_DIGISEL, 0, NULL, &icom_val); + if (retval != RIG_OK) { + return retval; + } + + val->i = icom_val ? 1 : 0; + break; + case TOK_DIGI_SEL_LEVEL: + retval = icom_get_raw(rig, C_CTL_LVL, S_LVL_DIGI, 0, NULL, &icom_val); + if (retval != RIG_OK) { + return retval; + } + + val->f = (float) icom_val; + break; + default: + return -RIG_EINVAL; + } + + return RIG_OK; +} /* * Assumes rig!=NULL, rig->state.priv!=NULL @@ -1848,7 +2105,7 @@ int icom_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) *rptr_shift = RIG_RPT_SHIFT_NONE; /* Simplex mode */ break; case S_DUP_M: - *rptr_shift = RIG_RPT_SHIFT_MINUS; /* Duples - mode */ + *rptr_shift = RIG_RPT_SHIFT_MINUS; /* Duplex - mode */ break; case S_DUP_P: *rptr_shift = RIG_RPT_SHIFT_PLUS; /* Duplex + mode */ @@ -2475,171 +2732,148 @@ int icom_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) */ int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { - struct icom_priv_data *priv; - struct rig_state *rs; - unsigned char fctbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; - int fct_len, acklen, retval; - int fct_cn, fct_sc; /* Command Number, Subcommand */ + unsigned char fctbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; + int fct_len, acklen, retval; + int fct_cn, fct_sc; /* Command Number, Subcommand */ - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - rs = &rig->state; - priv = (struct icom_priv_data*)rs->priv; + fctbuf[0] = status ? 0x01 : 0x00; + fct_len = 1; - /* r8500, the problem rig */ - int r8500 = (rig->caps->rig_model == RIG_MODEL_ICR8500)? 1 : 0; - - /* - * except for IC-R8500 - */ - fctbuf[0] = status? 0x01:0x00; - fct_len = r8500 ? 0 : 1; - - switch (func) { - case RIG_FUNC_FAGC: - fct_cn = C_CTL_FUNC; - fct_sc = (r8500)?(status)?S_FUNC_AGCON:S_FUNC_AGCOFF:S_FUNC_AGC; - /* fct_sc = S_FUNC_AGC; */ - /* note: should it be a LEVEL only, and no func? --SF */ - if (priv->civ_version == 1) { - fct_len = 1; - fctbuf[0] = status; - } - else if (status != 0) { - fctbuf[0] = 0x03; /* default to 0x03 in IC746 pro super-fast */ - } - else { - fctbuf[0] = 0x02; - } - break; - case RIG_FUNC_NB: - fct_cn = C_CTL_FUNC; - fct_sc = (r8500)?(status)?S_FUNC_NBON:S_FUNC_NBOFF:S_FUNC_NB; - /* fct_sc = S_FUNC_NB; */ - break; - case RIG_FUNC_COMP: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_COMP; - break; - case RIG_FUNC_VOX: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_VOX; - break; - case RIG_FUNC_TONE: /* repeater tone */ - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_TONE; - break; - case RIG_FUNC_TSQL: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_TSQL; - break; - case RIG_FUNC_SBKIN: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_BKIN; - if (status != 0) - fctbuf[0] = 0x01; - else - fctbuf[0] = 0x00; - break; - case RIG_FUNC_FBKIN: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_BKIN; - if (status != 0) - fctbuf[0] = 0x02; - else - fctbuf[0] = 0x00; - break; - case RIG_FUNC_ANF: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_ANF; - break; - case RIG_FUNC_NR: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_NR; - break; - case RIG_FUNC_APF: - fct_cn = C_CTL_FUNC; - fct_sc = (r8500)?(status)?S_FUNC_APFON:S_FUNC_APFOFF:S_FUNC_APF; - /* fct_sc = S_FUNC_APF; */ - break; - case RIG_FUNC_MON: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_MON; - break; - case RIG_FUNC_MN: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_MN; - break; - case RIG_FUNC_RF: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_RF; - break; - case RIG_FUNC_VSC: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_VSC; - break; - case RIG_FUNC_LOCK: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_DIAL_LK; - break; + switch (func) { + case RIG_FUNC_NB: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_NB; + break; + case RIG_FUNC_COMP: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_COMP; + break; + case RIG_FUNC_VOX: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_VOX; + break; + case RIG_FUNC_TONE: /* repeater tone */ + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_TONE; + break; + case RIG_FUNC_TSQL: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_TSQL; + break; + case RIG_FUNC_SBKIN: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_BKIN; + if (status != 0) + fctbuf[0] = 0x01; + else + fctbuf[0] = 0x00; + break; + case RIG_FUNC_FBKIN: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_BKIN; + if (status != 0) + fctbuf[0] = 0x02; + else + fctbuf[0] = 0x00; + break; + case RIG_FUNC_ANF: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_ANF; + break; + case RIG_FUNC_NR: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_NR; + break; + case RIG_FUNC_APF: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_APF; + break; + case RIG_FUNC_MON: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_MON; + break; + case RIG_FUNC_MN: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_MN; + break; + case RIG_FUNC_RF: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_RF; + break; + case RIG_FUNC_VSC: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_VSC; + break; + case RIG_FUNC_LOCK: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_DIAL_LK; + break; case RIG_FUNC_AFC: /* IC-910H */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_AFC; break; - case RIG_FUNC_SATMODE: /* IC-910H */ - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_SATMODE; - break; case RIG_FUNC_SCOPE: - if (priv->civ_version == 1) { /* IC-7200/7300 */ - fct_cn = 0x27; - fct_sc = 0x10; - fctbuf[0] = status; - fct_len = 1; - } - else { /* IC-910H */ - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_BANDSCOPE; - } - break; - case RIG_FUNC_RESUME: /* IC-910H & IC-746-Pro*/ - fct_cn = C_CTL_SCAN; - fct_sc = status ? S_SCAN_RSMON : S_SCAN_RSMOFF; - fct_len = 0; - break; - case RIG_FUNC_DSQL: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_DSQL; - break; - case RIG_FUNC_AFLT: - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_AFLT; - break; - case RIG_FUNC_ANL: - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_ANL; - break; - case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ - fct_cn = C_CTL_MEM; /* 1a */ - fct_sc = S_FUNC_IPPLUS; - break; - default: - rig_debug(RIG_DEBUG_ERR,"Unsupported set_func %d", func); - return -RIG_EINVAL; - } + // The command 0x27 0x10 is supported by many newer Icom rigs + fct_cn = 0x27; + fct_sc = 0x10; + fctbuf[0] = status; + fct_len = 1; + break; + case RIG_FUNC_RESUME: /* IC-910H & IC-746-Pro*/ + fct_cn = C_CTL_SCAN; + fct_sc = status ? S_SCAN_RSMON : S_SCAN_RSMOFF; + fct_len = 0; + break; + case RIG_FUNC_DSQL: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_DSQL; + break; + case RIG_FUNC_AFLT: + fct_cn = C_CTL_MEM; + fct_sc = S_MEM_AFLT; + break; + case RIG_FUNC_ANL: + fct_cn = C_CTL_MEM; + fct_sc = S_MEM_ANL; + break; + case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ + fct_cn = C_CTL_MEM; + fct_sc = S_FUNC_IPPLUS; + break; + case RIG_FUNC_RIT: + fct_cn = C_CTL_RIT; + fct_sc = S_RIT; + break; + case RIG_FUNC_XIT: + fct_cn = C_CTL_RIT; + fct_sc = S_XIT; + break; + case RIG_FUNC_TUNER: + fct_cn = C_CTL_PTT; + fct_sc = S_ANT_TUN; + break; + case RIG_FUNC_DUAL_WATCH: + fct_cn = C_SET_VFO; + fct_sc = S_DUAL; + break; + default: + rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %d", func); + return -RIG_EINVAL; + } - retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, - ackbuf, &acklen); - if (retval != RIG_OK) - return retval; + retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf, &acklen); + if (retval != RIG_OK) { + return retval; + } - if (acklen != 1) { - rig_debug(RIG_DEBUG_ERR,"icom_set_func: wrong frame len=%d\n", - acklen); - return -RIG_EPROTO; - } + if (acklen != 1) { + rig_debug(RIG_DEBUG_ERR, "icom_set_func: wrong frame len=%d\n", acklen); + return -RIG_EPROTO; + } - return RIG_OK; + return RIG_OK; } /* @@ -2649,456 +2883,197 @@ int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) */ int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { - unsigned char ackbuf[MAXFRAMELEN]; - int ack_len=sizeof(ackbuf), retval; - int fct_cn, fct_sc; /* Command Number, Subcommand */ + unsigned char ackbuf[MAXFRAMELEN]; + int ack_len = sizeof(ackbuf), retval; + int fct_cn, fct_sc; /* Command Number, Subcommand */ - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - switch (func) { - case RIG_FUNC_FAGC: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_AGC; /* default to 0x01=slow 0x03=super-fast */ - break; - case RIG_FUNC_NB: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_NB; - break; - case RIG_FUNC_COMP: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_COMP; - break; - case RIG_FUNC_VOX: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_VOX; - break; - case RIG_FUNC_TONE: /* repeater tone */ - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_TONE; - break; - case RIG_FUNC_TSQL: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_TSQL; - break; - case RIG_FUNC_SBKIN: /* returns 1 for semi and 2 for full adjusted below */ - case RIG_FUNC_FBKIN: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_BKIN; - break; - case RIG_FUNC_ANF: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_ANF; - break; - case RIG_FUNC_NR: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_NR; - break; - case RIG_FUNC_APF: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_APF; - break; - case RIG_FUNC_MON: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_MON; - break; - case RIG_FUNC_MN: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_MN; - break; - case RIG_FUNC_RF: + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + switch (func) { + case RIG_FUNC_NB: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_NB; + break; + case RIG_FUNC_COMP: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_COMP; + break; + case RIG_FUNC_VOX: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_VOX; + break; + case RIG_FUNC_TONE: /* repeater tone */ + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_TONE; + break; + case RIG_FUNC_TSQL: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_TSQL; + break; + case RIG_FUNC_SBKIN: /* returns 1 for semi and 2 for full adjusted below */ + case RIG_FUNC_FBKIN: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_BKIN; + break; + case RIG_FUNC_ANF: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_ANF; + break; + case RIG_FUNC_NR: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_NR; + break; + case RIG_FUNC_APF: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_APF; + break; + case RIG_FUNC_MON: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_MON; + break; + case RIG_FUNC_MN: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_MN; + break; + case RIG_FUNC_RF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_RF; break; - case RIG_FUNC_VSC: + case RIG_FUNC_VSC: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VSC; break; - case RIG_FUNC_LOCK: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_DIAL_LK; - break; - case RIG_FUNC_AFC: /* IC-910H */ + case RIG_FUNC_LOCK: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_DIAL_LK; + break; + case RIG_FUNC_AFC: /* IC-910H */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_AFC; break; - case RIG_FUNC_SATMODE: /* IC-910H */ - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_SATMODE; + case RIG_FUNC_SCOPE: + // The command 0x27 0x10 is supported by many newer Icom rigs + fct_cn = 0x27; + fct_sc = 0x10; break; - case RIG_FUNC_SCOPE: /* IC-910H */ - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_BANDSCOPE; + case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ + fct_cn = C_CTL_MEM; /* 1a */ + fct_sc = S_FUNC_IPPLUS; break; - case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ - fct_cn = C_CTL_MEM; /* 1a */ - fct_sc = S_FUNC_IPPLUS; - break; - case RIG_FUNC_DSQL: - fct_cn = C_CTL_FUNC; - fct_sc = S_FUNC_DSQL; - break; - case RIG_FUNC_AFLT: - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_AFLT; - break; - case RIG_FUNC_ANL: - fct_cn = C_CTL_MEM; - fct_sc = S_MEM_ANL; - break; - default: - rig_debug(RIG_DEBUG_ERR,"Unsupported get_func %d", func); - return -RIG_EINVAL; - } + case RIG_FUNC_DSQL: + fct_cn = C_CTL_FUNC; + fct_sc = S_FUNC_DSQL; + break; + case RIG_FUNC_AFLT: + fct_cn = C_CTL_MEM; + fct_sc = S_MEM_AFLT; + break; + case RIG_FUNC_ANL: + fct_cn = C_CTL_MEM; + fct_sc = S_MEM_ANL; + break; + case RIG_FUNC_RIT: + fct_cn = C_CTL_RIT; + fct_sc = S_RIT; + break; + case RIG_FUNC_XIT: + fct_cn = C_CTL_RIT; + fct_sc = S_XIT; + break; + case RIG_FUNC_TUNER: + fct_cn = C_CTL_PTT; + fct_sc = S_ANT_TUN; + break; + case RIG_FUNC_DUAL_WATCH: + fct_cn = C_SET_VFO; + fct_sc = S_DUAL; + break; + default: + rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %d", func); + return -RIG_EINVAL; + } - retval = icom_transaction (rig, fct_cn, fct_sc, NULL, 0, - ackbuf, &ack_len); - if (retval != RIG_OK) - return retval; + retval = icom_transaction(rig, fct_cn, fct_sc, NULL, 0, ackbuf, &ack_len); + if (retval != RIG_OK) { + return retval; + } - if (ack_len != 3) { - rig_debug(RIG_DEBUG_ERR,"icom_get_func: wrong frame len=%d\n", - ack_len); - return -RIG_EPROTO; - } - if (func != RIG_FUNC_FBKIN) - *status = ackbuf[2]; - else - *status = ackbuf[2] == 2 ? 1 : 0; + if (ack_len != 3) { + rig_debug(RIG_DEBUG_ERR, "icom_get_func: wrong frame len=%d\n", ack_len); + return -RIG_EPROTO; + } + if (func != RIG_FUNC_FBKIN) { + *status = ackbuf[2]; + } else { + *status = ackbuf[2] == 2 ? 1 : 0; + } - return RIG_OK; + return RIG_OK; } /* * icom_set_parm * Assumes rig!=NULL -These are very much rig specific and should probably be in rig files. These are for ICR75C only. -Yes. Even more after the IC-R8600 waas added + * + * NOTE: Most of the parm commands are rig-specific. + * + * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands where + * icom_set_custom_parm()/icom_get_custom_parm() can be used. + * + * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used. */ int icom_set_parm(RIG *rig, setting_t parm, value_t val) { - struct rig_state *rs; - struct icom_priv_data *priv; - unsigned char prmbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; - int ack_len=sizeof(ackbuf), prm_len; - int prm_cn, prm_sc; - int icom_val; - int retval; - int min,hr,sec; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - rs = &rig->state; - priv = (struct icom_priv_data*)rs->priv; + switch (parm) { + case RIG_PARM_ANN: { + int ann_mode; - switch (parm) { - case RIG_PARM_ANN: - /* previously only for R75, which used RIG_ANN_? codes as subcommand as well. This does not work for IC-R8600 anymore */ - if ((val.i == RIG_ANN_FREQ) || (val.i == RIG_ANN_RXMODE) || ((val.i == RIG_ANN_NONE) && (rig->caps->rig_model == RIG_MODEL_ICR8600)) ) { - prm_cn = C_CTL_ANN; - prm_sc = val.i; - prm_len = 0; - } - else { - if ((val.i == RIG_ANN_ENG)||(val.i == RIG_ANN_JAP)) { - prm_cn = C_CTL_MEM; - prm_sc = S_MEM_MODE_SLCT; - prm_len = 2; - prmbuf[0] = S_PRM_LANG; - prmbuf[1] = (val.i == RIG_ANN_ENG ? 0 : 1); - } - else { - rig_debug(RIG_DEBUG_ERR,"Unsupported set_parm_ann %d\n", val.i); - return -RIG_EINVAL; - } - } - break; - case RIG_PARM_APO: - prm_cn = C_CTL_MEM; - prm_sc = S_MEM_MODE_SLCT; - hr = (float)val.i/60.0; - min = val.i - (hr*60); - prm_len = 3; - prmbuf[0] = S_PRM_SLPTM; - to_bcd_be(prmbuf+1, (long long)hr, 2); - to_bcd_be(prmbuf+2, (long long)min, 2); - break; - case RIG_PARM_BACKLIGHT: - prm_cn = C_CTL_MEM; - icom_val = val.f * 255; - if (priv->civ_version == 1) { - prm_sc = 0x05; - prm_len = 4; - if (rig->caps->rig_model == RIG_MODEL_ICR8600) { - prmbuf[0] = 0x01; - prmbuf[1] = 0x15; - } - else { - prmbuf[0] = 0x00; - prmbuf[1] = 0x81; - }; - to_bcd_be(prmbuf+2, (long long)icom_val, (prm_len-2)*2); - } - else { - prm_sc = S_MEM_MODE_SLCT; - prm_len = 3; - prmbuf[0] = S_PRM_BACKLT; - to_bcd_be(prmbuf+1, (long long)icom_val, (prm_len-1)*2); - } - break; - case RIG_PARM_KEYLIGHT: - prm_cn = C_CTL_MEM; - icom_val = val.f * 255; - if (priv->civ_version == 1) { - prm_sc = 0x05; - prm_len = 4; - if (rig->caps->rig_model == RIG_MODEL_ICR8600) { - prmbuf[0] = 0x01; - prmbuf[1] = 0x16; - } - else { - /* replace with sub-subcommand codes for your rig */ - return -RIG_EINVAL; - }; - to_bcd_be(prmbuf+2, (long long)icom_val, (prm_len-2)*2); - } - else { - /* only supported on newer rigs */ - return -RIG_EINVAL; - } - break; - case RIG_PARM_BEEP: - prm_cn = C_CTL_MEM; - if (priv->civ_version == 1) { - prm_sc = 0x05; - prm_len = 3; - prmbuf[0] = 0x00; - prmbuf[1] = 0x23; - prmbuf[2] = val.i; - } - else { - prm_sc = S_MEM_MODE_SLCT; - prm_len = 2; - prmbuf[0] = S_PRM_BEEP; - prmbuf[1] = val.i; - } - break; - case RIG_PARM_TIME: - prm_cn = C_CTL_MEM; - hr = (float)val.i/3600.0; - min = (float)(val.i - (hr*3600))/60.0; - sec = (val.i - (hr*3600) - (min*60)); - if (priv->civ_version == 1) { - prm_sc = 0x05; - prm_len = 4; - prmbuf[0] = 0x00; - prmbuf[1] = 0x95; - to_bcd_be(prmbuf+2, (long long)hr, 2); - to_bcd_be(prmbuf+3, (long long)min, 2); - } - else { - prm_sc = S_MEM_MODE_SLCT; - prm_len = 4; - prmbuf[0] = S_PRM_TIME; - to_bcd_be(prmbuf+1, (long long)hr, 2); - to_bcd_be(prmbuf+2, (long long)min, 2); - to_bcd_be(prmbuf+3, (long long)sec, 2); - } - break; - default: - rig_debug(RIG_DEBUG_ERR,"Unsupported set_parm %d\n", parm); - return -RIG_EINVAL; - } + switch (val.i) { + case RIG_ANN_OFF: + ann_mode = S_ANN_ALL; + break; + case RIG_ANN_FREQ: + ann_mode = S_ANN_FREQ; + break; + case RIG_ANN_RXMODE: + ann_mode = S_ANN_MODE; + break; + default: + rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); + return -RIG_EINVAL; + } - retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, - ackbuf, &ack_len); - if (retval != RIG_OK) - return retval; - - if (ack_len != 1) { - rig_debug(RIG_DEBUG_ERR,"icom_set_parm: wrong frame len=%d\n", - ack_len); - return -RIG_EPROTO; - } - - return RIG_OK; + return icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0); + } + default: + rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm %d\n", parm); + return -RIG_EINVAL; + } } /* * icom_get_parm * Assumes rig!=NULL + * + * NOTE: Most of the parm commands are rig-specific. + * + * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands where + * icom_set_custom_parm()/icom_get_custom_parm() can be used. + * + * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used. */ int icom_get_parm(RIG *rig, setting_t parm, value_t *val) { - struct rig_state *rs; - struct icom_priv_data *priv; - unsigned char prmbuf[MAXFRAMELEN], resbuf[MAXFRAMELEN]; - int prm_len, res_len; - int prm_cn, prm_sc; - int icom_val; - int cmdhead; - int retval; - int min,hr,sec; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - rs = &rig->state; - priv = (struct icom_priv_data*)rs->priv; + switch (parm) { + default: + rig_debug(RIG_DEBUG_ERR, "Unsupported get_parm %d", parm); + return -RIG_EINVAL; + } - switch (parm) { - case RIG_PARM_APO: - prm_cn = C_CTL_MEM; - prm_sc = S_MEM_MODE_SLCT; - prm_len = 1; - prmbuf[0] = S_PRM_SLPTM; - break; - case RIG_PARM_BACKLIGHT: - if (priv->civ_version == 1) { - prm_cn = C_CTL_MEM; - prm_sc = 0x05; - prm_len = 2; - if (rig->caps->rig_model == RIG_MODEL_ICR8600) { - prmbuf[0] = 0x01; - prmbuf[1] = 0x15; - } - else { - prmbuf[0] = 0x00; - prmbuf[1] = 0x81; - } - } - else { - prm_cn = C_CTL_MEM; - prm_sc = S_MEM_MODE_SLCT; - prm_len = 1; - prmbuf[0] = S_PRM_BACKLT; - } - break; - case RIG_PARM_KEYLIGHT: - if (priv->civ_version == 1) { - prm_cn = C_CTL_MEM; - prm_sc = 0x05; - prm_len = 2; - if (rig->caps->rig_model == RIG_MODEL_ICR8600) { - prmbuf[0] = 0x01; - prmbuf[1] = 0x16; - } - else { - /* replace with sub-subcommand codes for your rig */ - return -RIG_EINVAL; - } - } - else { - /* only supported on newer rigs */ - return -RIG_EINVAL; - } - break; - case RIG_PARM_BEEP: - if (priv->civ_version == 1) { - prm_cn = C_CTL_MEM; - prm_sc = 0x05; - prm_len = 2; - prmbuf[0] = 0x00; - prmbuf[1] = 0x23; - } - else { - prm_cn = C_CTL_MEM; - prm_sc = S_MEM_MODE_SLCT; - prm_len = 1; - prmbuf[0] = S_PRM_BEEP; - } - break; - case RIG_PARM_TIME: - if (priv->civ_version == 1) { - prm_cn = C_CTL_MEM; - prm_sc = 0x05; - prm_len = 2; - prmbuf[0] = 0x00; - prmbuf[1] = 0x95; - } - else { - prm_cn = C_CTL_MEM; - prm_sc = S_MEM_MODE_SLCT; - prm_len = 1; - prmbuf[0] = S_PRM_TIME; - } - break; - default: - rig_debug(RIG_DEBUG_ERR,"Unsupported get_parm %d", parm); - return -RIG_EINVAL; - } - - retval = icom_transaction (rig, prm_cn, prm_sc, prmbuf, prm_len, - resbuf, &res_len); - if (retval != RIG_OK) - return retval; - - /* - * strbuf should contain Cn,Sc,[pn],Data area - */ - cmdhead = (prm_sc == -1) ? 1:3; - res_len -= cmdhead; - - if (resbuf[0] != ACK && resbuf[0] != prm_cn) { - rig_debug(RIG_DEBUG_ERR,"%s: ack NG (%#.2x), " - "len=%d\n", __FUNCTION__,resbuf[0],res_len); - return -RIG_ERJCTED; - } - - switch (parm) { - case RIG_PARM_APO: - hr = from_bcd_be(resbuf+cmdhead, 2); - min = from_bcd_be(resbuf+cmdhead+1, 2); - icom_val = (hr*60)+min; - val->i = icom_val; - break; - case RIG_PARM_TIME: - if (priv->civ_version == 1) { - hr = from_bcd_be(resbuf+cmdhead+1, 2); - min = from_bcd_be(resbuf+cmdhead+2, 2); - sec = 0; - } - else { - hr = from_bcd_be(resbuf+cmdhead, 2); - min = from_bcd_be(resbuf+cmdhead+1, 2); - sec = from_bcd_be(resbuf+cmdhead+2, 2); - } - icom_val = (hr*3600)+(min*60)+sec; - val->i = icom_val; - break; - case RIG_PARM_BACKLIGHT: - icom_val = 0; - if (priv->civ_version == 1) { - icom_val = from_bcd_be(resbuf+cmdhead+1, (res_len-1)*2); - } else { - icom_val = from_bcd_be(resbuf+cmdhead, res_len*2); - } - val->f = (float)icom_val/255.0; - break; - case RIG_PARM_KEYLIGHT: - icom_val = 0; - if (priv->civ_version == 1) { - icom_val = from_bcd_be(resbuf+cmdhead+1, (res_len-1)*2); - } else { - return -RIG_EINVAL; - } - val->f = (float)icom_val/255.0; - break; - case RIG_PARM_BEEP: - if (priv->civ_version == 1) { - icom_val = from_bcd_be(resbuf+cmdhead+1, (res_len-1)*2); - } else { - icom_val = from_bcd_be(resbuf+cmdhead, res_len*2); - } - val->i = icom_val; - break; - default: - icom_val = from_bcd_be(resbuf+cmdhead, res_len*2); - if (RIG_PARM_IS_FLOAT(parm)) - val->f = (float)icom_val/255; - else - val->i = icom_val; - } - - rig_debug(RIG_DEBUG_TRACE,"%s: %d %d %d %f\n", - __FUNCTION__, res_len, icom_val, val->i, val->f); - - return RIG_OK; + return RIG_OK; } /* @@ -3364,7 +3339,7 @@ int icom_set_powerstat(RIG *rig, powerstat_t status) rig_debug(RIG_DEBUG_VERBOSE, "%s called status=\n", __func__,status); switch (status) { case RIG_POWER_ON: - pwr_sc = RIG_POWER_ON; + pwr_sc = S_PWR_ON; // ic7300 manual says ~150 for 115,200 // we'll just send 175 to be sure for all speeds for(fe_len=0;fe_len<175;++fe_len) { @@ -3372,17 +3347,17 @@ int icom_set_powerstat(RIG *rig, powerstat_t status) } break; default: - pwr_sc = RIG_POWER_OFF; + pwr_sc = S_PWR_OFF; fe_buf[0] = 0; } // we can ignore this retval // sending more than enough 0xfe's to wake up the rs232 - icom_transaction(rig, 0xfe, 0xfe, fe_buf, fe_len, - ackbuf, &ack_len); - retval = icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, - ackbuf, &ack_len); + icom_transaction(rig, 0xfe, 0xfe, fe_buf, fe_len, ackbuf, &ack_len); + + retval = icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len); rig_debug(RIG_DEBUG_VERBOSE, "%s #2 called retval=%d\n", __func__,retval); + int i=0; int retry = 3/rig->state.rigport.retry; if (status==RIG_POWER_ON) { // wait for wakeup only @@ -3588,8 +3563,6 @@ int icom_get_ant(RIG *rig, vfo_t vfo, ant_t *ant) */ int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { - struct rig_state *rs; - struct icom_priv_data *priv; unsigned char mvbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN]; int mv_len=0, ack_len=sizeof(ackbuf), retval; @@ -3597,8 +3570,6 @@ int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) int vfo_list; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - rs = &rig->state; - priv = (struct icom_priv_data*)rs->priv; switch(op) { case RIG_OP_CPY: @@ -3615,16 +3586,6 @@ int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) mv_cn = C_SET_VFO; mv_sc = S_XCHNG; break; -#if 0 - case RIG_OP_DUAL_OFF: - mv_cn = C_SET_VFO; - mv_sc = S_DUAL_OFF; - break; - case RIG_OP_DUAL_ON: - mv_cn = C_SET_VFO; - mv_sc = S_DUAL_ON; - break; -#endif case RIG_OP_FROM_VFO: mv_cn = C_WR_MEM; mv_sc = -1; @@ -3638,27 +3599,25 @@ int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) mv_sc = -1; break; case RIG_OP_TUNE: - if (priv->civ_version == 1) { - mvbuf[0] = 2; - mv_len = 1; - } mv_cn = C_CTL_PTT; mv_sc = S_ANT_TUN; + mvbuf[0] = 2; + mv_len = 1; break; default: rig_debug(RIG_DEBUG_ERR,"Unsupported mem/vfo op %#x", op); return -RIG_EINVAL; } - retval = icom_transaction (rig, mv_cn, mv_sc, mvbuf, mv_len, - ackbuf, &ack_len); - if (retval != RIG_OK) + retval = icom_transaction (rig, mv_cn, mv_sc, mvbuf, mv_len, ackbuf, &ack_len); + if (retval != RIG_OK) { return retval; + } if (ack_len != 1 || ackbuf[0] != ACK) { - if (op != RIG_OP_XCHG) - rig_debug(RIG_DEBUG_ERR,"icom_vfo_op: ack NG (%#.2x), " - "len=%d\n", ackbuf[0], ack_len); + if (op != RIG_OP_XCHG) { + rig_debug(RIG_DEBUG_ERR, "icom_vfo_op: ack NG (%#.2x), len=%d\n", ackbuf[0], ack_len); + } return -RIG_ERJCTED; } @@ -3895,6 +3854,175 @@ int icom_decode_event(RIG *rig) return RIG_OK; } +int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, int val) +{ + unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; + int acklen = sizeof(ackbuf); + int cmdbuflen = subcmdbuflen; + int retval; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (subcmdbuflen > 0) { + if (subcmdbuf == NULL) { + return -RIG_EINTERNAL; + } + + memcpy(cmdbuf, subcmdbuf, subcmdbuflen); + } + + if (val_bytes > 0) { + to_bcd_be(cmdbuf + subcmdbuflen, (long long) val, val_bytes * 2); + cmdbuflen += val_bytes; + } + + retval = icom_transaction(rig, cmd, subcmd, cmdbuf, cmdbuflen, ackbuf, &acklen); + if (retval != RIG_OK) { + return retval; + } + + if (acklen != 1 || ackbuf[0] != ACK) { + rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], acklen); + return -RIG_ERJCTED; + } + + return RIG_OK; +} + +int icom_get_raw_buf(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *reslen, unsigned char *res) +{ + unsigned char ackbuf[MAXFRAMELEN]; + int acklen = sizeof(ackbuf); + int cmdhead = subcmdbuflen; + int retval; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + retval = icom_transaction(rig, cmd, subcmd, subcmdbuf, subcmdbuflen, ackbuf, &acklen); + if (retval != RIG_OK) { + return retval; + } + + cmdhead += (subcmd == -1) ? 1 : 2; + acklen -= cmdhead; + + if (ackbuf[0] != ACK && ackbuf[0] != cmd) { + rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], acklen); + return -RIG_ERJCTED; + } + + rig_debug(RIG_DEBUG_TRACE, "%s: %d\n", __func__, acklen); + + if (*reslen < acklen || res == NULL) { + return -RIG_EINTERNAL; + } + + memcpy(res, ackbuf + cmdhead, acklen); + *reslen = acklen; + + return RIG_OK; +} + +int icom_get_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *val) +{ + unsigned char resbuf[MAXFRAMELEN]; + int reslen = sizeof(resbuf); + int retval; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + retval = icom_get_raw_buf(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &reslen, resbuf); + if (retval != RIG_OK) { + return retval; + } + + *val = from_bcd_be(resbuf, reslen * 2); + + rig_debug(RIG_DEBUG_TRACE, "%s: %d %d\n", __func__, reslen, *val); + + return RIG_OK; +} + +int icom_set_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, value_t val) +{ + int icom_val; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (RIG_LEVEL_IS_FLOAT(level)) { + icom_val = (int) (val.f * 255.0f); + } else { + icom_val = val.i; + } + + return icom_set_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, val_bytes, icom_val); +} + +int icom_get_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, value_t *val) +{ + int icom_val; + int retval; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + retval = icom_get_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + + if (RIG_LEVEL_IS_FLOAT(level)) { + val->f = (float) icom_val / 255.0f; + } else { + val->i = icom_val; + } + + return RIG_OK; +} + +int icom_set_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int val_bytes, int value) +{ + return icom_set_raw(rig, C_CTL_MEM, S_MEM_PARM, parmbuflen, parmbuf, val_bytes, value); +} + +int icom_get_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *value) +{ + return icom_get_raw(rig, C_CTL_MEM, S_MEM_PARM, parmbuflen, parmbuf, value); +} + +int icom_set_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int seconds) +{ + unsigned char cmdbuf[MAXFRAMELEN]; + int hour = (int) ((float) seconds / 3600.0); + int min = (int) ((float) (seconds - (hour * 3600)) / 60.0); + + if (parmbuflen > 0) { + memcpy(cmdbuf, parmbuf, parmbuflen); + } + + to_bcd_be(cmdbuf + parmbuflen, (long long) hour, 2); + to_bcd_be(cmdbuf + parmbuflen + 1, (long long) min, 2); + + return icom_set_raw(rig, C_CTL_MEM, S_MEM_PARM, parmbuflen + 2, cmdbuf, 0, 0); +} + +int icom_get_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *seconds) +{ + unsigned char resbuf[MAXFRAMELEN]; + int reslen = sizeof(resbuf); + int retval; + + retval = icom_get_raw_buf(rig, C_CTL_MEM, S_MEM_PARM, parmbuflen, parmbuf, &reslen, resbuf); + if (retval != RIG_OK) { + return retval; + } + + int hour = from_bcd_be(resbuf, 2); + int min = from_bcd_be(resbuf + 1, 2); + *seconds = (hour * 3600) + (min * 60); + + return RIG_OK; +} + /* * init_icom is called by rig_probe_all (register.c) * diff --git a/icom/icom.h b/icom/icom.h index c45cd1a3e..39e32210b 100644 --- a/icom/icom.h +++ b/icom/icom.h @@ -95,6 +95,11 @@ typedef struct rig_pltstate { int usleep_time; /* dependent on radio module & serial data rate */ } pltstate_t; +struct icom_agc_level { + enum agc_level_e level; /* Hamlib AGC level from agc_level_e enum, the last entry should have level -1 */ + unsigned char icom_level; /* Icom AGC level for C_CTL_FUNC (0x16), S_FUNC_AGC (0x12) command */ +}; + struct icom_priv_caps { unsigned char re_civ_addr; /* the remote dlft equipment's CI-V address*/ int civ_731_mode; /* Off: freqs on 10 digits, On: freqs on 8 digits */ @@ -111,9 +116,10 @@ struct icom_priv_caps { tokens to bandwidth and mode */ int serial_full_duplex; /*!< Whether RXD&TXD are not tied together */ - unsigned char civ_version; // default to 0, 1=IC7200,IC7300,etc differences int offs_len; /* Number of bytes in offset frequency field. 0 defaults to 3 */ int serial_USB_echo_check; /* Flag to test USB echo state */ + int agc_levels_present; /* Flag to indicate that agc_levels array is populated */ + struct icom_agc_level agc_levels[RIG_AGC_LAST + 1]; /* Icom rig-specific AGC levels, the last entry should have level -1 */ }; @@ -124,7 +130,6 @@ struct icom_priv_data { int no_1a_03_cmd; /* rig doesn't tell IF widths */ int split_on; /* record split state */ pltstate_t *pltstate; /* only on optoscan */ - unsigned char civ_version; /* 0=default, 1=new commands for IC7200,IC7300, etc */ int serial_USB_echo_off; /* USB is not set to echo */ }; @@ -156,6 +161,9 @@ int icom_cleanup(RIG *rig); int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icom_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); +int icom_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *ts); +int icom_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t ts); +int icom_set_xit_new(RIG *rig, vfo_t vfo, shortfreq_t ts); int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icom_get_mode_with_data(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); @@ -210,6 +218,17 @@ int icom_mW2power(RIG * rig, float *power, unsigned int mwpower, freq_t freq, rm int icom_send_morse (RIG * rig, vfo_t vfo, const char *msg); /* Exposed routines */ int icom_get_split_vfos(const RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo); +int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, int val); +int icom_get_raw_buf(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *reslen, unsigned char *res); +int icom_get_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *val); +int icom_set_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, + int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, value_t val); +int icom_get_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, + int subcmdbuflen, unsigned char *subcmdbuf, value_t *val); +int icom_set_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int val_bytes, int value); +int icom_get_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *value); +int icom_set_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int seconds); +int icom_get_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *seconds); extern const struct confparams icom_cfg_params[]; diff --git a/icom/icom_defs.h b/icom/icom_defs.h index 6f2d7ff76..384bcc294 100644 --- a/icom/icom_defs.h +++ b/icom/icom_defs.h @@ -50,10 +50,10 @@ * Cn controller commands * - Most radios have 2 or 3 recieve passbands available. Where only 2 are available they + Most radios have 2 or 3 receive passbands available. Where only 2 are available they are selected by 01 for wide and 02 for narrow Actual bandwidth is determined by the filters installed. With the newer DSP rigs there are 3 presets 01 = wide 02 = middle and 03 = narrow. - Acutally you can set change any of these presets to any thing you want. + Actually, you can set change any of these presets to any thing you want. * Notes: * The following only applies to IC-706. @@ -63,8 +63,8 @@ * 2. Memory channel number 1A=0100/1b=0101, 2A=0102/2b=0103, * 3A=0104/3b=0105, C1=0106, C2=0107 */ -#define C_SND_FREQ 0x00 /* Send frequency data trancieve mode does not ack*/ -#define C_SND_MODE 0x01 /* Send mode data, Sc for trancieve mode does not ack */ +#define C_SND_FREQ 0x00 /* Send frequency data transceive mode does not ack*/ +#define C_SND_MODE 0x01 /* Send mode data, Sc for transceive mode does not ack */ #define C_RD_BAND 0x02 /* Read band edge frequencies */ #define C_RD_FREQ 0x03 /* Read display frequency */ #define C_RD_MODE 0x04 /* Read display mode */ @@ -93,6 +93,7 @@ #define C_SET_TONE 0x1b /* Set tone frequency */ #define C_CTL_PTT 0x1c /* Control Transmit On/Off, Sc */ #define C_CTL_DIG 0x20 /* Digital modes settings & status */ +#define C_CTL_RIT 0x21 /* RIT/XIT control */ #define C_SEND_SEL_FREQ 0x25 /* Send/Recv sel/unsel VFO frequency */ #define C_CTL_MTEXT 0x70 /* Microtelecom Extension */ #define C_CTL_MISC 0x7f /* Miscellaneous control, Sc */ @@ -151,6 +152,7 @@ #define S_SUBTOMAIN 0xb1 /* MAIN = SUB */ #define S_DUAL_OFF 0xc0 /* Dual watch off */ #define S_DUAL_ON 0xc1 /* Dual watch on */ +#define S_DUAL 0xc2 /* Dual watch (0 = off, 1 = on) */ #define S_MAIN 0xd0 /* Select MAIN band */ #define S_SUB 0xd1 /* Select SUB band */ #define S_SUB_SEL 0xd2 /* Read/Set Main/Sub selection */ @@ -354,6 +356,13 @@ #define S_PTT 0x00 #define S_ANT_TUN 0x01 /* Auto tuner 0=OFF, 1 = ON, 2=Start Tuning */ +/* + * RIT/XIT control (C_CTL_RIT) subcommands + */ +#define S_RIT_FREQ 0x00 +#define S_RIT 0x01 /* RIT 0 = OFF, 1 = ON */ +#define S_XIT 0x02 /* XIT (delta TX) 0 = OFF, 1 = ON */ + /* * Misc contents (C_CTL_MEM) subcommands applies to newer rigs. * @@ -487,7 +496,8 @@ #define TOK_RTTY_FLTR TOKEN_BACKEND(100) #define TOK_SSBBASS TOKEN_BACKEND(101) #define TOK_SQLCTRL TOKEN_BACKEND(102) -#define TOK_LEVEL_MONITOR TOKEN_BACKEND(103) - +#define TOK_DRIVE_GAIN TOKEN_BACKEND(103) +#define TOK_DIGI_SEL_FUNC TOKEN_BACKEND(104) +#define TOK_DIGI_SEL_LEVEL TOKEN_BACKEND(105) #endif /* _ICOM_DEFS_H */ diff --git a/icom/icr75.c b/icom/icr75.c index 71ba197a6..ae79b662f 100644 --- a/icom/icr75.c +++ b/icom/icr75.c @@ -93,6 +93,8 @@ static int icr75_set_channel(RIG *rig, const channel_t *chan); static int icr75_get_channel(RIG *rig, channel_t *chan); +int icr75_set_parm(RIG *rig, setting_t parm, value_t val); +int icr75_get_parm(RIG *rig, setting_t parm, value_t *val); static const struct icom_priv_caps icr75_priv_caps = { 0x5a, /* default address */ @@ -221,8 +223,8 @@ const struct rig_caps icr75_caps = { .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, -.set_parm = icom_set_parm, -.get_parm = icom_get_parm, +.set_parm = icr75_set_parm, +.get_parm = icr75_get_parm, .get_dcd = icom_get_dcd, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, @@ -392,3 +394,159 @@ int icr75_get_channel(RIG *rig, channel_t *chan) return RIG_OK; } +int icr75_set_parm(RIG *rig, setting_t parm, value_t val) +{ + unsigned char prmbuf[MAXFRAMELEN]; + int min, hr, sec; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_ANN: { + int ann_mode = -1; + int ann_lang = -1; + + switch (val.i) { + case RIG_ANN_OFF: + ann_mode = S_ANN_ALL; + break; + case RIG_ANN_FREQ: + ann_mode = S_ANN_FREQ; + break; + case RIG_ANN_RXMODE: + ann_mode = S_ANN_MODE; + break; + case RIG_ANN_ENG: + case RIG_ANN_JAP: + ann_lang = (val.i == RIG_ANN_ENG) ? 0 : 1; + break; + default: + rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); + return -RIG_EINVAL; + } + + if (ann_mode >= 0) { + return icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0); + } else if (ann_lang >= 0) { + prmbuf[0] = S_PRM_LANG; + prmbuf[1] = ann_lang; + return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 2, prmbuf, 0, 0); + } + + rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); + return -RIG_EINVAL; + } + case RIG_PARM_APO: + prmbuf[0] = S_PRM_SLPTM; + hr = (int) ((float) val.i / 60.0f); + min = val.i - (hr * 60); + to_bcd_be(prmbuf + 1, (long long) hr, 2); + to_bcd_be(prmbuf + 2, (long long) min, 2); + return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 3, prmbuf, 0, 0); + case RIG_PARM_BACKLIGHT: + prmbuf[0] = S_PRM_BACKLT; + to_bcd_be(prmbuf + 1, (long long) (val.f * 255.0f), 2 * 2); + return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 3, prmbuf, 0, 0); + case RIG_PARM_BEEP: + prmbuf[0] = S_PRM_BEEP; + prmbuf[1] = val.i ? 1 : 0; + return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 2, prmbuf, 0, 0); + case RIG_PARM_TIME: + hr = (int) ((float) val.i / 3600.0); + min = (int) ((float) (val.i - (hr * 3600)) / 60.0); + sec = (val.i - (hr * 3600) - (min * 60)); + + prmbuf[0] = S_PRM_TIME; + to_bcd_be(prmbuf + 1, (long long) hr, 2); + to_bcd_be(prmbuf + 2, (long long) min, 2); + to_bcd_be(prmbuf + 3, (long long) sec, 2); + return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 4, prmbuf, 0, 0); + default: + rig_debug(RIG_DEBUG_ERR,"Unsupported set_parm %d\n", parm); + return -RIG_EINVAL; + } +} + +int icr75_get_parm(RIG *rig, setting_t parm, value_t *val) +{ + unsigned char prmbuf[MAXFRAMELEN], resbuf[MAXFRAMELEN]; + int prm_len, res_len; + int prm_cn, prm_sc; + int icom_val = 0; + int cmdhead; + int retval; + int min, hr, sec; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_APO: + prm_cn = C_CTL_MEM; + prm_sc = S_MEM_MODE_SLCT; + prm_len = 1; + prmbuf[0] = S_PRM_SLPTM; + break; + case RIG_PARM_BACKLIGHT: + prm_cn = C_CTL_MEM; + prm_sc = S_MEM_MODE_SLCT; + prm_len = 1; + prmbuf[0] = S_PRM_BACKLT; + break; + case RIG_PARM_BEEP: + prm_cn = C_CTL_MEM; + prm_sc = S_MEM_MODE_SLCT; + prm_len = 1; + prmbuf[0] = S_PRM_BEEP; + break; + case RIG_PARM_TIME: + prm_cn = C_CTL_MEM; + prm_sc = S_MEM_MODE_SLCT; + prm_len = 1; + prmbuf[0] = S_PRM_TIME; + break; + default: + rig_debug(RIG_DEBUG_ERR,"Unsupported get_parm %d", parm); + return -RIG_EINVAL; + } + + retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, resbuf, &res_len); + if (retval != RIG_OK) { + return retval; + } + + cmdhead = 3; + res_len -= cmdhead; + + if (resbuf[0] != ACK && resbuf[0] != prm_cn) { + rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __FUNCTION__, resbuf[0], res_len); + return -RIG_ERJCTED; + } + + switch (parm) { + case RIG_PARM_APO: + hr = from_bcd_be(resbuf + cmdhead, 2); + min = from_bcd_be(resbuf + cmdhead + 1, 2); + icom_val = (hr * 60) + min; + val->i = icom_val; + break; + case RIG_PARM_TIME: + hr = from_bcd_be(resbuf + cmdhead, 2); + min = from_bcd_be(resbuf + cmdhead + 1, 2); + sec = from_bcd_be(resbuf + cmdhead + 2, 2); + icom_val = (hr * 3600) + (min * 60) + sec; + val->i = icom_val; + break; + case RIG_PARM_BACKLIGHT: + icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); + val->f = (float) icom_val / 255.0; + break; + case RIG_PARM_BEEP: + icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); + val->i = icom_val; + break; + } + + rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __FUNCTION__, res_len, icom_val, val->i, val->f); + + return RIG_OK; +} diff --git a/icom/icr8500.c b/icom/icr8500.c index 60b5d7fd9..adf1d94f6 100644 --- a/icom/icr8500.c +++ b/icom/icr8500.c @@ -28,14 +28,14 @@ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" - +#include "icom_defs.h" #define ICR8500_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_WFM) #define ICR8500_1MHZ_TS_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ICR8500_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_APF) -#define ICR8500_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_APF|RIG_LEVEL_SQL|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR) +#define ICR8500_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_APF|RIG_LEVEL_SQL|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR) #define ICR8500_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) @@ -61,6 +61,7 @@ { 238, 60 }, \ } } +int icr8500_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static const struct icom_priv_caps icr8500_priv_caps = { 0x4a, /* default address */ @@ -68,8 +69,9 @@ static const struct icom_priv_caps icr8500_priv_caps = { 0, /* no XCHG */ r8500_ts_sc_list }; + /* - * ICR8500 rigs capabilities. + * IC-R8500 rig capabilities. */ const struct rig_caps icr8500_caps = { .rig_model = RIG_MODEL_ICR8500, @@ -187,7 +189,7 @@ const struct rig_caps icr8500_caps = { .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, -.set_func = icom_set_func, +.set_func = icr8500_set_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, @@ -196,7 +198,16 @@ const struct rig_caps icr8500_caps = { .get_dcd = icom_get_dcd, }; - -/* - * Function definitions below - */ +int icr8500_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +{ + switch (func) { + case RIG_FUNC_NB: + return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_NBON : S_FUNC_NBOFF, 0, NULL, 0, 0); + case RIG_FUNC_FAGC: + return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_AGCON : S_FUNC_AGCOFF, 0, NULL, 0, 0); + case RIG_FUNC_APF: + return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_APFON : S_FUNC_APFOFF, 0, NULL, 0, 0); + default: + return icom_set_func(rig, vfo, func, status); + } +} diff --git a/icom/icr8600.c b/icom/icr8600.c index 4d48bb9ee..c65e236e2 100644 --- a/icom/icr8600.c +++ b/icom/icr8600.c @@ -41,7 +41,7 @@ RIG_MODE_SAH|RIG_MODE_P25|RIG_MODE_DSTAR|RIG_MODE_DPMR|RIG_MODE_NXDNVN|\ RIG_MODE_NXDN_N|RIG_MODE_DCR) -#define ICR8600_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_MN|RIG_FUNC_AFC|\ +#define ICR8600_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_MN|RIG_FUNC_AFC|\ RIG_FUNC_NR|RIG_FUNC_AIP|RIG_FUNC_LOCK|RIG_FUNC_VSC|RIG_FUNC_RESUME|RIG_FUNC_TSQL|\ RIG_FUNC_DSQL) @@ -79,12 +79,14 @@ .flags = 1, \ } +int icr8600_set_parm(RIG *rig, setting_t parm, value_t val); +int icr8600_get_parm(RIG *rig, setting_t parm, value_t *val); + static const struct icom_priv_caps icr8600_priv_caps = { 0x96, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8600_ts_sc_list, /* list of tuning steps */ - .civ_version = 1, /* modifies behaviour in various icom.c functions */ .offs_len = 4, /* Repeater offset is 4 bytes */ .serial_USB_echo_check = 1 /* USB CI-V may not echo */ }; @@ -216,8 +218,8 @@ const struct rig_caps icr8600_caps = { .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, - .set_parm = icom_set_parm, - .get_parm = icom_get_parm, + .set_parm = icr8600_set_parm, + .get_parm = icr8600_get_parm, .get_dcd = icom_get_dcd, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, @@ -230,3 +232,77 @@ const struct rig_caps icr8600_caps = { .get_dcs_code = icom_get_dcs_code, }; + +int icr8600_set_parm(RIG *rig, setting_t parm, value_t val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x00; + parmbuf[1] = 0x38; + return icom_set_custom_parm(rig, 2, parmbuf, 1, val.i ? 1 : 0); + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x01; + parmbuf[1] = 0x15; + return icom_set_custom_parm(rig, 2, parmbuf, 2, (int) (val.f * 255.0f)); + case RIG_PARM_KEYLIGHT: + parmbuf[0] = 0x01; + parmbuf[1] = 0x16; + return icom_set_custom_parm(rig, 2, parmbuf, 2, val.f != 0 ? 255 : 0); + case RIG_PARM_TIME: + parmbuf[0] = 0x01; + parmbuf[1] = 0x32; + return icom_set_custom_parm_time(rig, 2, parmbuf, val.i); + default: + return icom_set_parm(rig, parm, val); + } +} + +int icr8600_get_parm(RIG *rig, setting_t parm, value_t *val) +{ + unsigned char parmbuf[MAXFRAMELEN]; + int retval; + int icom_val; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + switch (parm) { + case RIG_PARM_BEEP: + parmbuf[0] = 0x00; + parmbuf[1] = 0x38; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->i = icom_val ? 1 : 0; + break; + case RIG_PARM_BACKLIGHT: + parmbuf[0] = 0x01; + parmbuf[1] = 0x15; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->f = (float) icom_val / 255.0f; + break; + case RIG_PARM_KEYLIGHT: + parmbuf[0] = 0x01; + parmbuf[1] = 0x16; + retval = icom_get_custom_parm(rig, 2, parmbuf, &icom_val); + if (retval != RIG_OK) { + return retval; + } + val->f = icom_val != 0; + break; + case RIG_PARM_TIME: + parmbuf[0] = 0x01; + parmbuf[1] = 0x32; + return icom_get_custom_parm_time(rig, 2, parmbuf, &val->i); + default: + return icom_get_parm(rig, parm, val); + } + + return RIG_OK; +} diff --git a/icom/icr9500.c b/icom/icr9500.c index 1681e52b8..eb744cbbe 100644 --- a/icom/icr9500.c +++ b/icom/icr9500.c @@ -41,8 +41,8 @@ #define ICR9500_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) -#define ICR9500_FUNCS (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_NR|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) -#define ICR9500_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF) +#define ICR9500_FUNCS (RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_NR|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) +#define ICR9500_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF) #define ICR9500_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define ICR9500_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|RIG_SCAN_PRIO) /* TBC */ diff --git a/icom/x108g.c b/icom/x108g.c index 6cb8156ad..7808d2114 100644 --- a/icom/x108g.c +++ b/icom/x108g.c @@ -53,9 +53,9 @@ #define X108G_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define X108G_AM_TX_MODES (RIG_MODE_AM) -#define X108G_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) +#define X108G_FUNCS (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_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) -#define X108G_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) +#define X108G_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define X108G_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define X108G_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index 4be9d0819..0e4c354ab 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -641,6 +641,8 @@ typedef int ant_t; #define RIG_ANT_4 RIG_ANT_N(3) #define RIG_ANT_5 RIG_ANT_N(4) +#define RIG_ANT_MAX 32 + /** * \brief AGC delay settings @@ -656,6 +658,7 @@ enum agc_level_e { RIG_AGC_AUTO }; +#define RIG_AGC_LAST RIG_AGC_AUTO /** * \brief Level display meters @@ -728,14 +731,19 @@ enum rig_level_e { RIG_LEVEL_SQLSTAT = (1 << 27), /*!< \c SQLSTAT -- SQL status, arg int (open=1/closed=0). Deprecated, use get_dcd instead */ RIG_LEVEL_SWR = (1 << 28), /*!< \c SWR -- SWR, arg float [0.0 ... infinite] */ RIG_LEVEL_ALC = (1 << 29), /*!< \c ALC -- ALC, arg float */ - RIG_LEVEL_STRENGTH = (1 << 30) /*!< \c STRENGTH -- Effective (calibrated) signal strength relative to S9, arg int (dB) */ + RIG_LEVEL_STRENGTH = (1 << 30), /*!< \c STRENGTH -- Effective (calibrated) signal strength relative to S9, arg int (dB) */ /* RIG_LEVEL_BWC = (1<<31) */ /*!< Bandwidth Control, arg int (Hz) */ + RIG_LEVEL_RFPOWER_METER = CONSTANT_64BIT_FLAG(32), /*!< \c RFPOWER_METER -- RF power output meter, arg float [0.0 ... 1.0] (percentage of maximum power) */ + RIG_LEVEL_COMP_METER = CONSTANT_64BIT_FLAG(33), /*!< \c COMP_METER -- Audio output level compression meter, arg float (dB) */ + RIG_LEVEL_VD_METER = CONSTANT_64BIT_FLAG(34), /*!< \c VD_METER -- Input voltage level meter, arg float (V, volts) */ + RIG_LEVEL_ID_METER = CONSTANT_64BIT_FLAG(35), /*!< \c ID_METER -- Current draw meter, arg float (A, amperes) */ + + RIG_LEVEL_NOTCHF_RAW = CONSTANT_64BIT_FLAG(36), /*!< \c NOTCHF_RAW -- Notch Freq., arg float [0.0 ... 1.0] */ + RIG_LEVEL_MONITOR_GAIN = CONSTANT_64BIT_FLAG(37), /*!< \c MONITOR_GAIN -- Monitor gain (level for monitoring of transmitted audio), arg float [0.0 ... 1.0] */ + RIG_LEVEL_NB = CONSTANT_64BIT_FLAG(38), /*!< \c NB -- Noise Blanker level, arg float [0.0 ... 1.0] */ }; - -#define RIG_LEVEL_FLOAT_LIST (RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_APF|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_COMP|RIG_LEVEL_BALANCE|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX) - -#define RIG_LEVEL_READONLY_LIST (RIG_LEVEL_SQLSTAT|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_STRENGTH|RIG_LEVEL_RAWSTR) +#define RIG_LEVEL_READONLY_LIST (RIG_LEVEL_SQLSTAT|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_STRENGTH|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER) #define RIG_LEVEL_IS_FLOAT(l) ((l)&RIG_LEVEL_FLOAT_LIST) #define RIG_LEVEL_SET(l) ((l)&~RIG_LEVEL_READONLY_LIST) @@ -844,8 +852,8 @@ typedef uint64_t setting_t; #define RIG_FUNC_AFLT CONSTANT_64BIT_FLAG (34) /*!< \c AFLT -- AF Filter setting */ #define RIG_FUNC_ANL CONSTANT_64BIT_FLAG (35) /*!< \c ANL -- Noise limiter setting */ #define RIG_FUNC_BC2 CONSTANT_64BIT_FLAG (36) /*!< \c BC2 -- 2nd Beat Cancel */ -#define RIG_FUNC_BIT37 CONSTANT_64BIT_FLAG (37) /* available for future RIG_FUNC items */ -#define RIG_FUNC_BIT38 CONSTANT_64BIT_FLAG (38) /* available for future RIG_FUNC items */ +#define RIG_FUNC_DUAL_WATCH CONSTANT_64BIT_FLAG (37) /*!< \c DUAL_WATCH -- Dual Watch / Sub Receiver */ +#define RIG_FUNC_DIVERSITY CONSTANT_64BIT_FLAG (38) /*!< \c DIVERSITY -- Diversity receive */ #define RIG_FUNC_BIT39 CONSTANT_64BIT_FLAG (39) /* available for future RIG_FUNC items */ #define RIG_FUNC_BIT40 CONSTANT_64BIT_FLAG (40) /* available for future RIG_FUNC items */ #define RIG_FUNC_BIT41 CONSTANT_64BIT_FLAG (41) /* available for future RIG_FUNC items */ @@ -1289,6 +1297,33 @@ typedef struct cal_table cal_table_t; #define EMPTY_STR_CAL { 0, { { 0, 0 }, } } +/** + * \brief Calibration table struct for float values + */ +struct cal_table_float { + int size; /*!< number of plots in the table */ + struct { + int raw; /*!< raw (A/D) value */ + float val; /*!< associated value */ + } table[MAX_CAL_LENGTH]; /*!< table of plots */ +}; + +/** + * \brief calibration table type for float values + * + * cal_table_float_t is a data type suited to hold linear calibration. + * cal_table_float_t.size tells the number of plots cal_table_float_t.table contains. + * + * If a value is below or equal to cal_table_float_t.table[0].raw, + * rig_raw2val_float() will return cal_table_float_t.table[0].val. + * + * If a value is greater or equal to cal_table_float_t.table[cal_table_float_t.size-1].raw, + * rig_raw2val_float() will return cal_table_float_t.table[cal_table_float_t.size-1].val. + */ +typedef struct cal_table_float cal_table_float_t; + +#define EMPTY_FLOAT_CAL { 0, { { 0, 0f }, } } + typedef int (* chan_cb_t)(RIG *, channel_t **, int, const chan_t *, rig_ptr_t); typedef int (* confval_cb_t)(RIG *, const struct confparams *, @@ -1382,7 +1417,13 @@ struct rig_caps { struct tuning_step_list tuning_steps[TSLSTSIZ]; /*!< Tuning step list */ struct filter_list filters[FLTLSTSIZ]; /*!< mode/filter table, at -6dB */ - cal_table_t str_cal; /*!< S-meter calibration table */ + cal_table_t str_cal; /*!< S-meter calibration table */ + cal_table_float_t swr_cal; /*!< SWR meter calibration table */ + cal_table_float_t alc_cal; /*!< ALC meter calibration table */ + cal_table_float_t rfpower_meter_cal; /*!< RF power meter calibration table */ + cal_table_float_t comp_meter_cal; /*!< COMP meter calibration table */ + cal_table_float_t vd_meter_cal; /*!< Voltage meter calibration table */ + cal_table_float_t id_meter_cal; /*!< Current draw meter calibration table */ const struct confparams *cfgparams; /*!< Configuration parametres. */ const rig_ptr_t priv; /*!< Private data. */ diff --git a/include/hamlib/riglist.h b/include/hamlib/riglist.h index 44edbb844..f56432b14 100644 --- a/include/hamlib/riglist.h +++ b/include/hamlib/riglist.h @@ -157,6 +157,9 @@ #define RIG_MODEL_HPSDR RIG_MAKE_MODEL(RIG_KENWOOD, 40) /* OpenHPSDR, PiHPSDR */ #define RIG_MODEL_TS890S RIG_MAKE_MODEL(RIG_KENWOOD, 41) #define RIG_MODEL_THD74 RIG_MAKE_MODEL(RIG_KENWOOD, 42) +#define RIG_MODEL_K3S RIG_MAKE_MODEL(RIG_KENWOOD, 43) +#define RIG_MODEL_KX2 RIG_MAKE_MODEL(RIG_KENWOOD, 44) +#define RIG_MODEL_KX3 RIG_MAKE_MODEL(RIG_KENWOOD, 45) /* diff --git a/include/hamlib/rotlist.h b/include/hamlib/rotlist.h index a40268730..8ecc0d77d 100644 --- a/include/hamlib/rotlist.h +++ b/include/hamlib/rotlist.h @@ -177,10 +177,10 @@ * protocol. */ /** - * \def ROT_MODEL_GS232 + * \def ROT_MODEL_GS232_GENERIC * \brief A macro that returns the model number of the GS-232 backend. * - * The GS-232 backend can be used with rotators that support the GS-232 + * The GS-232 backend can be used with rotators that support the generic (even if not coded correctly) GS-232 * protocol. */ /** @@ -197,13 +197,38 @@ * The F1TETRACKER backend can be used with rotators that support the * F1TETRACKER protocol. */ + /** + * \def ROT_MODEL_GS23 + * \brief A macro that returns the model number of the GS23 backend. + * + * The GS23 backend can be used with rotators that support the + * GS23 protocol. + */ + /** + * \def ROT_MODEL_AMSAT_LVB + * \brief A macro that returns the model number of the AMSAT_LVB TRACKER backend. + * + * The AMSAT LVB TRACKER backend can be used with rotators that support the + * AMSAT LVB TRACKER GS232 based protocol. + */ + /** + * \def ROT_MODEL_ST2 + * \brief A macro that returns the model number of the Fox Delta ST2 backend. + * + * The Fox Delta ST2 backend can be used with rotators that support the + * Fox Delta ST2 GS232 based protocol. + */ + #define ROT_GS232A 6 #define ROT_BACKEND_GS232A "gs232a" #define ROT_MODEL_GS232A ROT_MAKE_MODEL(ROT_GS232A, 1) -#define ROT_MODEL_GS232 ROT_MAKE_MODEL(ROT_GS232A, 2) /* Not A or B */ +#define ROT_MODEL_GS232_GENERIC ROT_MAKE_MODEL(ROT_GS232A, 2) /* GENERIC */ #define ROT_MODEL_GS232B ROT_MAKE_MODEL(ROT_GS232A, 3) #define ROT_MODEL_F1TETRACKER ROT_MAKE_MODEL(ROT_GS232A, 4) - +#define ROT_MODEL_GS23 ROT_MAKE_MODEL(ROT_GS232A, 5) +#define ROT_MODEL_GS232 ROT_MAKE_MODEL(ROT_GS232A, 6) /* Not A or B */ +#define ROT_MODEL_LVB ROT_MAKE_MODEL(ROT_GS232A, 7) +#define ROT_MODEL_ST2 ROT_MAKE_MODEL(ROT_GS232A, 8) /** * \def ROT_MODEL_PCROTOR diff --git a/kenwood/elecraft.c b/kenwood/elecraft.c index d5e06718b..f1be6812c 100644 --- a/kenwood/elecraft.c +++ b/kenwood/elecraft.c @@ -57,7 +57,7 @@ static char k3_fw_rev[KENWOOD_MAX_BUF_LEN]; * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams elecraft_ext_levels[] = { - { TOK_IF_FREQ, "ifctr", "IF center frequency", "IF center freq", + { TOK_IF_FREQ, "ifctr", "IF freq", "IF center frequency", NULL, RIG_CONF_NUMERIC, { .n = { 0, 9990, 10 } } }, { TOK_TX_STAT, "txst", "TX status", "TX status", @@ -154,6 +154,9 @@ int elecraft_open(RIG *rig) break; case RIG_MODEL_K3: + case RIG_MODEL_K3S: + case RIG_MODEL_KX2: + case RIG_MODEL_KX3: err = elecraft_get_extension_level(rig, "K2", &priv->k2_ext_lvl); if (err != RIG_OK) return err; diff --git a/kenwood/elecraft.h b/kenwood/elecraft.h index fce623e96..efed41c9e 100644 --- a/kenwood/elecraft.h +++ b/kenwood/elecraft.h @@ -59,9 +59,14 @@ enum k3_data_submodes_e { * * See Private Elecraft extra levels definitions in elecraft.c */ -#define TOK_IF_FREQ TOKEN_BACKEND(101) /* K3 FI command */ -#define TOK_TX_STAT TOKEN_BACKEND(102) /* K3 TQ command */ -#define TOK_RIT_CLR TOKEN_BACKEND(103) /* K3 RC command */ +#define TOK_IF_FREQ TOKEN_BACKEND(101) /* K3 FI command - IF center frequency (K3/K3S only) */ +#define TOK_TX_STAT TOKEN_BACKEND(102) /* K3 TQ command - transmit query (K3/K3S/KX3/KX2) */ +#define TOK_RIT_CLR TOKEN_BACKEND(103) /* K3 RC command - RIT/XIT clear (K3/K3S/KX3/KX2) */ +#define TOK_ESSB TOKEN_BACKEND(104) /* K3 ES command - ESSB mode (K3/K3S/KX3/KX2) */ +#define TOK_RX_ANT TOKEN_BACKEND(105) /* K3 AR command - RX antenna on/off (K3/K3S only) */ +#define TOK_LINK_VFOS TOKEN_BACKEND(106) /* K3 LN command - link VFOs on/off (K3/K3S only) */ +#define TOK_TX_METER TOKEN_BACKEND(107) /* K3 TM command - Transmit meter mode, SWR/ALC (K3/K3S only) */ +#define TOK_IF_NB TOKEN_BACKEND(108) /* K3 NL command - IF noise blanker level (K3/K3S only) */ /* Token structure assigned to .cfgparams in rig_caps */ extern const struct confparams elecraft_ext_levels[]; diff --git a/kenwood/k3.c b/kenwood/k3.c index 92637b2e3..fb18709f5 100644 --- a/kenwood/k3.c +++ b/kenwood/k3.c @@ -29,6 +29,7 @@ #include #include +#include "idx_builtin.h" #include "kenwood.h" #include "bandplan.h" #include "elecraft.h" @@ -39,17 +40,80 @@ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_PKTUSB|\ RIG_MODE_PKTLSB) -#define K3_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT) +#define K3_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_VOX|RIG_FUNC_APF|\ + RIG_FUNC_DUAL_WATCH|RIG_FUNC_DIVERSITY|\ + RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT) #define K3_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ - RIG_LEVEL_STRENGTH|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|\ - RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_RAWSTR) + RIG_LEVEL_STRENGTH|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|\ + RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_COMP|\ + RIG_LEVEL_NR|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER_METER) #define K3_VFO (RIG_VFO_A|RIG_VFO_B) #define K3_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define K3_ANTS (RIG_ANT_1|RIG_ANT_2) +#define KX3_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_VOX|RIG_FUNC_APF|\ + RIG_FUNC_DUAL_WATCH|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT) + +#define KX3_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ + RIG_LEVEL_STRENGTH|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|\ + RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_COMP|\ + RIG_LEVEL_NR|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER_METER) + +/* + * Elecraft K3/K3S extra level definitions + * + * Token definitions for .cfgparams in rig_caps + * See enum rig_conf_e and struct confparams in rig.h + */ +const struct confparams k3_ext_levels[] = { + { TOK_IF_FREQ, "ifctr", "IF freq", "IF center frequency", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 9990, 10 } } + }, + { TOK_TX_STAT, "txst", "TX status", "TX status", + NULL, RIG_CONF_CHECKBUTTON, { { } }, + }, + { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", + NULL, RIG_CONF_BUTTON, { { } }, + }, + { TOK_ESSB, "essb", "ESSB", "Extended SSB frequency response", + NULL, RIG_CONF_CHECKBUTTON, { { } }, + }, + { TOK_RX_ANT, "rx_ant", "RX ANT", "RX antenna", + NULL, RIG_CONF_CHECKBUTTON, { { } }, + }, + { TOK_LINK_VFOS, "link_vfos", "Link VFOs", "Link VFOs", + NULL, RIG_CONF_CHECKBUTTON, { { } }, + }, + { TOK_TX_METER, "tx_meter", "TX meter", "Transmit meter mode", + NULL, RIG_CONF_COMBO, { .c = { .combostr = { "SWR", "ALC", NULL } } } + }, + { TOK_IF_NB, "if_nb", "IF NB", "IF noise blanker level", + NULL, RIG_CONF_NUMERIC, { .n = { 0, 21, 1 } }, + }, + { RIG_CONF_END, NULL, } +}; + +/* + * Elecraft KX3/KX2 extra level definitions + * + * Token definitions for .cfgparams in rig_caps + * See enum rig_conf_e and struct confparams in rig.h + */ +const struct confparams kx3_ext_levels[] = { + { TOK_TX_STAT, "txst", "TX status", "TX status", + NULL, RIG_CONF_CHECKBUTTON, { { } }, + }, + { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", + NULL, RIG_CONF_BUTTON, { { } }, + }, + { TOK_ESSB, "essb", "ESSB", "Extended SSB frequency response", + NULL, RIG_CONF_CHECKBUTTON, { { } }, + }, + { RIG_CONF_END, NULL, } +}; /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from @@ -70,11 +134,18 @@ int k3_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int k3_set_xit(RIG * rig, vfo_t vfo, shortfreq_t rit); int k3_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); +int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int kx3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int k3_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int k3_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); /* Private helper functions */ int set_rit_xit(RIG *rig, shortfreq_t rit); +int k3_set_nb_level(RIG *rig, float dsp_nb, float if_nb); +int k3_get_nb_level(RIG *rig, float *dsp_nb, float *if_nb); +int k3_get_bar_graph_level(RIG *rig, float *smeter, float *pwr, float *alc, int *mode_tx); +int kx3_get_bar_graph_level(RIG *rig, float *level); /* @@ -91,9 +162,9 @@ int set_rit_xit(RIG *rig, shortfreq_t rit); */ const struct rig_caps k3_caps = { .rig_model = RIG_MODEL_K3, - .model_name = "K3/KX3", + .model_name = "K3", .mfg_name = "Elecraft", - .version = "20170812", + .version = "20190529", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -117,11 +188,13 @@ const struct rig_caps k3_caps = { .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ - .level_gran = {}, /* FIXME: granularity */ + .level_gran = { + [LVL_KEYSPD] = { .min = { .i = 8 }, .max = { .i = 50 }, .step = { .i = 1 } }, + }, .parm_gran = {}, - .extlevels = elecraft_ext_levels, + .extlevels = k3_ext_levels, .extparms = kenwood_cfg_params, - .preamp = { 14, RIG_DBLST_END, }, + .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), @@ -166,18 +239,25 @@ const struct rig_caps k3_caps = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, + {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW|RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW|RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW|RIG_MODE_CWR, Hz(50)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW|RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(500)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY|RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(50)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(2400)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(500)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, @@ -209,11 +289,11 @@ const struct rig_caps k3_caps = { .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, - .set_func = kenwood_set_func, + .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, - .set_level = kenwood_set_level, + .set_level = k3_set_level, .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, @@ -228,6 +308,449 @@ const struct rig_caps k3_caps = { }; +const struct rig_caps k3s_caps = { + .rig_model = RIG_MODEL_K3S, + .model_name = "K3S", + .mfg_name = "Elecraft", + .version = "20190529", + .copyright = "LGPL", + .status = RIG_STATUS_BETA, + .rig_type = RIG_TYPE_TRANSCEIVER, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_RIG, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 4800, + .serial_rate_max = 38400, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_NONE, + .write_delay = 0, /* Timing between bytes */ + .post_write_delay = 0, /* Timing between command strings */ + .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ + .retry = 5, + + .has_get_func = K3_FUNC_ALL, + .has_set_func = K3_FUNC_ALL, + .has_get_level = K3_LEVEL_ALL, + .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), + .has_get_parm = RIG_PARM_NONE, + .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ + .level_gran = { + [LVL_KEYSPD] = { .min = { .i = 8 }, .max = { .i = 50 }, .step = { .i = 1 } }, + }, + .parm_gran = {}, + .extlevels = k3_ext_levels, + .extparms = kenwood_cfg_params, + .preamp = { 1, RIG_DBLST_END, }, + .attenuator = { 5, 10, 15, RIG_DBLST_END, }, + .max_rit = Hz(9990), + .max_xit = Hz(9990), + .max_ifshift = Hz(0), + .vfo_ops = K3_VFO_OP, + .targetable_vfo = RIG_TARGETABLE_FREQ, + .transceive = RIG_TRN_RIG, + .bank_qty = 0, + .chan_desc_sz = 0, + + .chan_list = { RIG_CHAN_END }, + + .rx_range_list1 = { + {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + { MHz(48), MHz(54), K3_MODES, -1,- 1, K3_VFO, K3_ANTS}, + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list1 = { + FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + RIG_FRNG_END, + }, /* tx range */ + + .rx_range_list2 = { + {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list2 = { + FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + RIG_FRNG_END, + }, /* tx range */ + .tuning_steps = { + {K3_MODES, 1}, + RIG_TS_END, + }, + + /* mode/filter list, remember: order matters! */ + /* Values are arbitrary based on common K3 filter options. */ + .filters = { + {RIG_MODE_SSB, kHz(2.7)}, + {RIG_MODE_SSB, kHz(2.8)}, + {RIG_MODE_SSB, kHz(1.8)}, + {RIG_MODE_SSB, kHz(2.4)}, + {RIG_MODE_SSB, RIG_FLT_ANY}, + {RIG_MODE_CW|RIG_MODE_CWR, kHz(1)}, + {RIG_MODE_CW|RIG_MODE_CWR, kHz(2.8)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(50)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(300)}, + {RIG_MODE_CW|RIG_MODE_CWR, RIG_FLT_ANY}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.7)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(500)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(300)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, RIG_FLT_ANY}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.7)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.8)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(50)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(2400)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(500)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(300)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, RIG_FLT_ANY}, + {RIG_MODE_AM, kHz(6)}, + {RIG_MODE_AM, kHz(13)}, + {RIG_MODE_AM, kHz(2.7)}, + {RIG_MODE_AM, RIG_FLT_ANY}, + {RIG_MODE_FM, kHz(13)}, /* TBC */ + RIG_FLT_END, + }, + .priv = (void *)&k3_priv_caps, + + .rig_init = kenwood_init, + .rig_cleanup = kenwood_cleanup, + .rig_open = elecraft_open, + .rig_close = kenwood_close, + .set_freq = kenwood_set_freq, + .get_freq = kenwood_get_freq, + .set_mode = k3_set_mode, + .get_mode = k3_get_mode, + .set_vfo = k3_set_vfo, + .get_vfo = kenwood_get_vfo_if, + .set_split_mode = k3_set_split_mode, + .get_split_mode = k3_get_split_mode, + .set_split_vfo = kenwood_set_split_vfo, + .get_split_vfo = kenwood_get_split_vfo_if, + .set_rit = k3_set_rit, + .get_rit = kenwood_get_rit, + .set_xit = k3_set_xit, + .get_xit = kenwood_get_xit, + .get_ptt = kenwood_get_ptt, + .set_ptt = kenwood_set_ptt, + .get_dcd = kenwood_get_dcd, + .set_func = k3_set_func, + .get_func = k3_get_func, + .set_ext_parm = kenwood_set_ext_parm, + .get_ext_parm = kenwood_get_ext_parm, + .set_level = k3_set_level, + .get_level = k3_get_level, + .set_ext_level = k3_set_ext_level, + .get_ext_level = k3_get_ext_level, + .vfo_op = kenwood_vfo_op, + .set_trn = kenwood_set_trn, + .get_trn = kenwood_get_trn, + .set_powerstat = kenwood_set_powerstat, + .get_powerstat = kenwood_get_powerstat, + .set_ant = kenwood_set_ant_no_ack, + .get_ant = kenwood_get_ant, + .send_morse = kenwood_send_morse, + +}; + +const struct rig_caps kx3_caps = { + .rig_model = RIG_MODEL_KX3, + .model_name = "KX3", + .mfg_name = "Elecraft", + .version = "20190529", + .copyright = "LGPL", + .status = RIG_STATUS_BETA, + .rig_type = RIG_TYPE_TRANSCEIVER, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_RIG, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 4800, + .serial_rate_max = 38400, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_NONE, + .write_delay = 0, /* Timing between bytes */ + .post_write_delay = 0, /* Timing between command strings */ + .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ + .retry = 5, + + .has_get_func = KX3_FUNC_ALL, + .has_set_func = KX3_FUNC_ALL, + .has_get_level = KX3_LEVEL_ALL, + .has_set_level = RIG_LEVEL_SET(KX3_LEVEL_ALL), + .has_get_parm = RIG_PARM_NONE, + .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ + .level_gran = { + [LVL_KEYSPD] = { .min = { .i = 8 }, .max = { .i = 50 }, .step = { .i = 1 } }, + }, + .parm_gran = {}, + .extlevels = kx3_ext_levels, + .extparms = kenwood_cfg_params, + .preamp = { 1, RIG_DBLST_END, }, + .attenuator = { 10, RIG_DBLST_END, }, + .max_rit = Hz(9990), + .max_xit = Hz(9990), + .max_ifshift = Hz(0), + .vfo_ops = K3_VFO_OP, + .targetable_vfo = RIG_TARGETABLE_FREQ, + .transceive = RIG_TRN_RIG, + .bank_qty = 0, + .chan_desc_sz = 0, + + .chan_list = { RIG_CHAN_END }, + + .rx_range_list1 = { + {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + { MHz(48), MHz(54), K3_MODES, -1,- 1, K3_VFO, K3_ANTS}, + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list1 = { + FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + RIG_FRNG_END, + }, /* tx range */ + + .rx_range_list2 = { + {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list2 = { + FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + RIG_FRNG_END, + }, /* tx range */ + .tuning_steps = { + {K3_MODES, 1}, + RIG_TS_END, + }, + + /* mode/filter list, remember: order matters! */ + /* Values are arbitrary based on common K3 filter options. */ + .filters = { + {RIG_MODE_SSB, kHz(2.7)}, + {RIG_MODE_SSB, kHz(2.8)}, + {RIG_MODE_SSB, kHz(1.8)}, + {RIG_MODE_SSB, kHz(2.4)}, + {RIG_MODE_SSB, RIG_FLT_ANY}, + {RIG_MODE_CW|RIG_MODE_CWR, kHz(1)}, + {RIG_MODE_CW|RIG_MODE_CWR, kHz(2.8)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(50)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(300)}, + {RIG_MODE_CW|RIG_MODE_CWR, RIG_FLT_ANY}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.7)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(500)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(300)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, RIG_FLT_ANY}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.7)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.8)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(50)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(2400)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(500)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(300)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, RIG_FLT_ANY}, + {RIG_MODE_AM, kHz(6)}, + {RIG_MODE_AM, kHz(13)}, + {RIG_MODE_AM, kHz(2.7)}, + {RIG_MODE_AM, RIG_FLT_ANY}, + {RIG_MODE_FM, kHz(13)}, /* TBC */ + RIG_FLT_END, + }, + .priv = (void *)&k3_priv_caps, + + .rig_init = kenwood_init, + .rig_cleanup = kenwood_cleanup, + .rig_open = elecraft_open, + .rig_close = kenwood_close, + .set_freq = kenwood_set_freq, + .get_freq = kenwood_get_freq, + .set_mode = k3_set_mode, + .get_mode = k3_get_mode, + .set_vfo = k3_set_vfo, + .get_vfo = kenwood_get_vfo_if, + .set_split_mode = k3_set_split_mode, + .get_split_mode = k3_get_split_mode, + .set_split_vfo = kenwood_set_split_vfo, + .get_split_vfo = kenwood_get_split_vfo_if, + .set_rit = k3_set_rit, + .get_rit = kenwood_get_rit, + .set_xit = k3_set_xit, + .get_xit = kenwood_get_xit, + .get_ptt = kenwood_get_ptt, + .set_ptt = kenwood_set_ptt, + .get_dcd = kenwood_get_dcd, + .set_func = k3_set_func, + .get_func = k3_get_func, + .set_ext_parm = kenwood_set_ext_parm, + .get_ext_parm = kenwood_get_ext_parm, + .set_level = k3_set_level, + .get_level = kx3_get_level, + .set_ext_level = k3_set_ext_level, + .get_ext_level = k3_get_ext_level, + .vfo_op = kenwood_vfo_op, + .set_trn = kenwood_set_trn, + .get_trn = kenwood_get_trn, + .set_powerstat = kenwood_set_powerstat, + .get_powerstat = kenwood_get_powerstat, + .set_ant = kenwood_set_ant_no_ack, + .get_ant = kenwood_get_ant, + .send_morse = kenwood_send_morse, + +}; + +const struct rig_caps kx2_caps = { + .rig_model = RIG_MODEL_KX2, + .model_name = "KX2", + .mfg_name = "Elecraft", + .version = "20190529", + .copyright = "LGPL", + .status = RIG_STATUS_BETA, + .rig_type = RIG_TYPE_TRANSCEIVER, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_RIG, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 4800, + .serial_rate_max = 38400, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_NONE, + .write_delay = 0, /* Timing between bytes */ + .post_write_delay = 0, /* Timing between command strings */ + .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ + .retry = 5, + + .has_get_func = KX3_FUNC_ALL, + .has_set_func = KX3_FUNC_ALL, + .has_get_level = KX3_LEVEL_ALL, + .has_set_level = RIG_LEVEL_SET(KX3_LEVEL_ALL), + .has_get_parm = RIG_PARM_NONE, + .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ + .level_gran = { + [LVL_KEYSPD] = { .min = { .i = 8 }, .max = { .i = 50 }, .step = { .i = 1 } }, + }, + .parm_gran = {}, + .extlevels = kx3_ext_levels, + .extparms = kenwood_cfg_params, + .preamp = { 1, RIG_DBLST_END, }, + .attenuator = { 10, RIG_DBLST_END, }, + .max_rit = Hz(9990), + .max_xit = Hz(9990), + .max_ifshift = Hz(0), + .vfo_ops = K3_VFO_OP, + .targetable_vfo = RIG_TARGETABLE_FREQ, + .transceive = RIG_TRN_RIG, + .bank_qty = 0, + .chan_desc_sz = 0, + + .chan_list = { RIG_CHAN_END }, + + .rx_range_list1 = { + {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + { MHz(48), MHz(54), K3_MODES, -1,- 1, K3_VFO, K3_ANTS}, + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list1 = { + FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + RIG_FRNG_END, + }, /* tx range */ + + .rx_range_list2 = { + {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, + RIG_FRNG_END, + }, /* rx range */ + .tx_range_list2 = { + FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), + RIG_FRNG_END, + }, /* tx range */ + .tuning_steps = { + {K3_MODES, 1}, + RIG_TS_END, + }, + + /* mode/filter list, remember: order matters! */ + /* Values are arbitrary based on common K3 filter options. */ + .filters = { + {RIG_MODE_SSB, kHz(2.7)}, + {RIG_MODE_SSB, kHz(2.8)}, + {RIG_MODE_SSB, kHz(1.8)}, + {RIG_MODE_SSB, kHz(2.4)}, + {RIG_MODE_SSB, RIG_FLT_ANY}, + {RIG_MODE_CW|RIG_MODE_CWR, kHz(1)}, + {RIG_MODE_CW|RIG_MODE_CWR, kHz(2.8)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(50)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, + {RIG_MODE_CW|RIG_MODE_CWR, Hz(300)}, + {RIG_MODE_CW|RIG_MODE_CWR, RIG_FLT_ANY}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, kHz(2.7)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(500)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, Hz(300)}, + {RIG_MODE_RTTY|RIG_MODE_RTTYR, RIG_FLT_ANY}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.7)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, kHz(2.8)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(50)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(2400)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(500)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, Hz(300)}, + {RIG_MODE_PKTUSB|RIG_MODE_PKTLSB, RIG_FLT_ANY}, + {RIG_MODE_AM, kHz(6)}, + {RIG_MODE_AM, kHz(13)}, + {RIG_MODE_AM, kHz(2.7)}, + {RIG_MODE_AM, RIG_FLT_ANY}, + {RIG_MODE_FM, kHz(13)}, /* TBC */ + RIG_FLT_END, + }, + .priv = (void *)&k3_priv_caps, + + .rig_init = kenwood_init, + .rig_cleanup = kenwood_cleanup, + .rig_open = elecraft_open, + .rig_close = kenwood_close, + .set_freq = kenwood_set_freq, + .get_freq = kenwood_get_freq, + .set_mode = k3_set_mode, + .get_mode = k3_get_mode, + .set_vfo = k3_set_vfo, + .get_vfo = kenwood_get_vfo_if, + .set_split_mode = k3_set_split_mode, + .get_split_mode = k3_get_split_mode, + .set_split_vfo = kenwood_set_split_vfo, + .get_split_vfo = kenwood_get_split_vfo_if, + .set_rit = k3_set_rit, + .get_rit = kenwood_get_rit, + .set_xit = k3_set_xit, + .get_xit = kenwood_get_xit, + .get_ptt = kenwood_get_ptt, + .set_ptt = kenwood_set_ptt, + .get_dcd = kenwood_get_dcd, + .set_func = k3_set_func, + .get_func = k3_get_func, + .set_ext_parm = kenwood_set_ext_parm, + .get_ext_parm = kenwood_get_ext_parm, + .set_level = k3_set_level, + .get_level = kx3_get_level, + .set_ext_level = k3_set_ext_level, + .get_ext_level = k3_get_ext_level, + .vfo_op = kenwood_vfo_op, + .set_trn = kenwood_set_trn, + .get_trn = kenwood_get_trn, + .set_powerstat = kenwood_set_powerstat, + .get_powerstat = kenwood_get_powerstat, + .set_ant = kenwood_set_ant_no_ack, + .get_ant = kenwood_get_ant, + .send_morse = kenwood_send_morse, + +}; /* * K3 extension function definitions follow @@ -466,29 +989,35 @@ int k3_set_vfo(RIG *rig, vfo_t vfo) */ int k3_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val) { - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (!rig) - return -RIG_EINVAL; + if (!rig) { + return -RIG_EINVAL; + } - int err; + char buf[10]; - switch(token) { - case TOK_RIT_CLR: - /* Clear offset */ - err = kenwood_transaction(rig, "RC", NULL, 0); - if (err != RIG_OK) - return err; - - /* val is ignored for RC command */ - break; - default: - rig_debug(RIG_DEBUG_WARN, "%s: Unsupported set_ext_level %d\n", - __func__, token); - return -RIG_EINVAL; - } - - return RIG_OK; + switch (token) { + case TOK_RIT_CLR: + return kenwood_transaction(rig, "RC", NULL, 0); + case TOK_ESSB: + snprintf(buf, sizeof (buf), "ES%c", (val.i == 0) ? '0' : '1'); + return kenwood_transaction(rig, buf, NULL, 0); + case TOK_RX_ANT: + snprintf(buf, sizeof (buf), "AR%c", (val.i == 0) ? '0' : '1'); + return kenwood_transaction(rig, buf, NULL, 0); + case TOK_LINK_VFOS: + snprintf(buf, sizeof (buf), "LN%c", (val.i == 0) ? '0' : '1'); + return kenwood_transaction(rig, buf, NULL, 0); + case TOK_TX_METER: + snprintf(buf, sizeof (buf), "TM%c", val.i + '0'); + return kenwood_transaction(rig, buf, NULL, 0); + case TOK_IF_NB: + return k3_set_nb_level(rig, -1, val.f / 21.0f); + default: + rig_debug(RIG_DEBUG_WARN, "%s: Unsupported set_ext_level %d\n", __func__, token); + return -RIG_EINVAL; + } } @@ -505,49 +1034,48 @@ int k3_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val) */ int k3_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val) { - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (!rig || !val) - return -RIG_EINVAL; + if (!rig || !val) { + return -RIG_EINVAL; + } - char buf[KENWOOD_MAX_BUF_LEN]; - int err; - const struct confparams *cfp; + char buf[KENWOOD_MAX_BUF_LEN]; + int err; - cfp = rig_ext_lookup_tok(rig, token); + switch (token) { + case TOK_IF_FREQ: + err = kenwood_safe_transaction(rig, "FI", buf, KENWOOD_MAX_BUF_LEN, 6); + if (err != RIG_OK) { + return err; + } + val->f = 8210000.0 + (float) atoi(&buf[2]); + break; + case TOK_TX_STAT: + return get_kenwood_func(rig, "TQ", &val->i); + case TOK_ESSB: + return get_kenwood_func(rig, "ES", &val->i); + case TOK_RX_ANT: + return get_kenwood_func(rig, "AR", &val->i); + case TOK_LINK_VFOS: + return get_kenwood_func(rig, "LN", &val->i); + case TOK_TX_METER: + return get_kenwood_func(rig, "TM", &val->i); + case TOK_IF_NB: { + float if_nb; + err = k3_get_nb_level(rig, NULL, &if_nb); + if (err != RIG_OK) { + return err; + } + val->f = (float) ((int) (if_nb * 21.0f)); + break; + } + default: + rig_debug(RIG_DEBUG_WARN, "%s: Unsupported get_ext_level %d\n", __func__, token); + return -RIG_EINVAL; + } - switch(token) { - case TOK_IF_FREQ: - err = kenwood_safe_transaction(rig, "FI", buf, KENWOOD_MAX_BUF_LEN, 6); - if (err != RIG_OK) - return err; - if (cfp->type == RIG_CONF_NUMERIC) { - val->f = 8210000.0 + (float)atoi(&buf[2]); - } else { - rig_debug(RIG_DEBUG_ERR, "%s: protocol error, invalid token type\n", - __func__); - return -RIG_EPROTO; - } - break; - case TOK_TX_STAT: - err = kenwood_safe_transaction(rig, "TQ", buf, KENWOOD_MAX_BUF_LEN, 3); - if (err != RIG_OK) - return err; - if (cfp->type == RIG_CONF_CHECKBUTTON) { - val->i = atoi(&buf[2]); - } else { - rig_debug(RIG_DEBUG_ERR, "%s: protocol error, invalid token type\n", - __func__); - return -RIG_EPROTO; - } - break; - default: - rig_debug(RIG_DEBUG_WARN, "%s: Unsupported get_ext_level %d\n", - __func__, token); - return -RIG_EINVAL; - } - - return RIG_OK; + return RIG_OK; } @@ -769,94 +1297,357 @@ int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width return RIG_OK; } +int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) { + return -RIG_EINVAL; + } + + char levelbuf[16]; + int i, kenwood_val; + + if (RIG_LEVEL_IS_FLOAT(level)) + kenwood_val = val.f * 255; + else + kenwood_val = val.i; + + switch (level) { + case RIG_LEVEL_AGC: + switch (val.i) { + case RIG_AGC_OFF: + kenwood_val = 0; + break; + case RIG_AGC_SUPERFAST: + case RIG_AGC_FAST: + kenwood_val = 2; + break; + case RIG_AGC_MEDIUM: + case RIG_AGC_SLOW: + kenwood_val = 4; + break; + case RIG_AGC_USER: + case RIG_AGC_AUTO: + return -RIG_EINVAL; + } + + snprintf(levelbuf, sizeof (levelbuf), "GT%03d", kenwood_val); + break; + case RIG_LEVEL_ATT: + if (val.i == 0) { + snprintf(levelbuf, sizeof (levelbuf), "RA00"); + } else if (val.i == 10) { + snprintf(levelbuf, sizeof (levelbuf), "RA01"); + } else { + for (i = 0; i < MAXDBLSTSIZ && rig->state.attenuator[i]; i++) { + if (val.i == rig->state.attenuator[i]) { + snprintf(levelbuf, sizeof (levelbuf), "RA%02d", i+1); + break; + } + } + if (val.i != rig->state.attenuator[i]) + return -RIG_EINVAL; + } + break; + case RIG_LEVEL_MICGAIN: + snprintf(levelbuf, sizeof (levelbuf), "MG%03d", (int) (val.f * 60.0f)); + break; + case RIG_LEVEL_COMP: + snprintf(levelbuf, sizeof (levelbuf), "CP%03d", (int) (val.f * 40.0f)); + break; + case RIG_LEVEL_SQL: + snprintf(levelbuf, sizeof (levelbuf), "SQ%03d", (int) (val.f * 29.0f)); + break; + case RIG_LEVEL_RF: + snprintf(levelbuf, sizeof (levelbuf), "RG%03d", (int) (val.f * 250.0f)); + break; + case RIG_LEVEL_NR: + return k3_set_nb_level(rig, val.f, -1); + case RIG_LEVEL_MONITOR_GAIN: + snprintf(levelbuf, sizeof (levelbuf), "ML%03d", (int) (val.f * 60.0f)); + break; + default: + return kenwood_set_level(rig, vfo, level, val); + } + + return kenwood_transaction(rig, levelbuf, NULL, 0); +} /* * Handle S-meter (SM, SMH) level locally and pass rest to kenwood_get_level() */ int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (!rig || !val) - return -RIG_EINVAL; + if (!rig || !val) + return -RIG_EINVAL; - char lvlbuf[50]; - int retval; - struct kenwood_priv_data *priv = rig->state.priv; + char lvlbuf[50]; + int retval, i; + int lvl; + struct kenwood_priv_data *priv = rig->state.priv; - switch (level) { - case RIG_LEVEL_STRENGTH: - /* As of FW rev 4.37 the K3 supports an 'SMH' command that - * offers a higher resolution, 0-100 (mine went to 106), - * rawstr value for more precise S-meter reporting. - */ - retval = strncmp(priv->fw_rev, "4.37", 4); - if (retval < 0) { - cal_table_t str_cal = K3_SM_CAL; + switch (level) { + case RIG_LEVEL_STRENGTH: + /* As of FW rev 4.37 the K3 supports an 'SMH' command that + * offers a higher resolution, 0-100 (mine went to 106), + * rawstr value for more precise S-meter reporting. + */ + retval = strncmp(priv->fw_rev, "4.37", 4); + if (retval < 0) { + cal_table_t str_cal = K3_SM_CAL; - retval = kenwood_safe_transaction(rig, "SM", lvlbuf, 10, 6); - if (retval != RIG_OK) - return retval; + retval = kenwood_safe_transaction(rig, "SM", lvlbuf, sizeof(lvlbuf), 6); + if (retval != RIG_OK) + return retval; - sscanf(lvlbuf+2, "%d", &val->i); /* rawstr */ + sscanf(lvlbuf + 2, "%d", &val->i); /* rawstr */ - val->i = (int) rig_raw2val(val->i, &str_cal); - } else if (retval >= 0) { - cal_table_t str_cal = K3_SMH_CAL; + val->i = (int) rig_raw2val(val->i, &str_cal); + } else if (retval >= 0) { + cal_table_t str_cal = K3_SMH_CAL; - retval = kenwood_safe_transaction(rig, "SMH", lvlbuf, 10, 6); - if (retval != RIG_OK) - return retval; + retval = kenwood_safe_transaction(rig, "SMH", lvlbuf, sizeof(lvlbuf), 6); + if (retval != RIG_OK) + return retval; - sscanf(lvlbuf+3, "%d", &val->i); /* rawstr */ + sscanf(lvlbuf + 3, "%d", &val->i); /* rawstr */ - val->i = (int) rig_raw2val(val->i, &str_cal); - } else { - rig_debug(RIG_DEBUG_ERR, "%s: Firmware version comparison failed!\n", - __func__); - return -RIG_EINVAL; - } + val->i = (int) rig_raw2val(val->i, &str_cal); + } else { + rig_debug(RIG_DEBUG_ERR, "%s: Firmware version comparison failed!\n", + __func__); + return -RIG_EINVAL; + } + break; + case RIG_LEVEL_ALC: { + int tx_mode; + float alc; - break; + retval = k3_get_bar_graph_level(rig, NULL, NULL, &alc, &tx_mode); + if (retval != RIG_OK) { + return retval; + } - default: - retval = kenwood_get_level(rig, vfo, level, val); - if (retval != RIG_OK) - return retval; - break; - } + if (!tx_mode) { + val->f = 0.0f; + return RIG_OK; + } - return RIG_OK; + if (alc < 0) { + return -RIG_EINVAL; + } + + val->f = alc; + break; + } + case RIG_LEVEL_RFPOWER_METER: { + int tx_mode; + float pwr; + + retval = k3_get_bar_graph_level(rig, NULL, &pwr, NULL, &tx_mode); + if (retval != RIG_OK) { + return retval; + } + + if (!tx_mode) { + val->f = 0.0f; + return RIG_OK; + } + + if (pwr < 0) { + return -RIG_EINVAL; + } + + val->f = pwr; + break; + } + case RIG_LEVEL_AGC: + retval = kenwood_safe_transaction(rig, "GT", lvlbuf, sizeof(lvlbuf), 5); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%d", &lvl); + if (lvl == 0) { + val->i = RIG_AGC_OFF; + } else if (lvl == 2) { + val->i = RIG_AGC_FAST; + } else if (lvl == 4) { + val->i = RIG_AGC_SLOW; + } else { + return -RIG_EPROTO; + } + break; + case RIG_LEVEL_ATT: + retval = kenwood_safe_transaction(rig, "RA", lvlbuf, sizeof(lvlbuf), 4); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%d", &lvl); + if (lvl == 0) { + val->i = 0; + } else if (lvl == 1) { + val->i = 10; + } else { + for (i = 0; i < lvl && i < MAXDBLSTSIZ; i++) { + if (rig->state.attenuator[i] == 0) { + rig_debug(RIG_DEBUG_ERR, "%s: unexpected att level %d\n", __func__, lvl); + return -RIG_EPROTO; + } + } + if (i != lvl) { + return -RIG_EINTERNAL; + } + val->i = rig->state.attenuator[i-1]; + } + break; + case RIG_LEVEL_MICGAIN: + retval = kenwood_safe_transaction(rig, "MG", lvlbuf, sizeof(lvlbuf), 5); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%d", &lvl); + val->f = (float) lvl / 60.0f; + break; + case RIG_LEVEL_COMP: + retval = kenwood_safe_transaction(rig, "CP", lvlbuf, sizeof(lvlbuf), 5); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%d", &lvl); + val->f = (float) lvl / 40.0f; + break; + case RIG_LEVEL_SQL: + retval = kenwood_safe_transaction(rig, "SQ", lvlbuf, sizeof(lvlbuf), 5); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%d", &lvl); + val->f = (float) lvl / 29.0f; + break; + case RIG_LEVEL_RF: + retval = kenwood_safe_transaction(rig, "RG", lvlbuf, sizeof(lvlbuf), 5); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%d", &lvl); + val->f = (float) lvl / 250.0f; + break; + case RIG_LEVEL_NR: + return k3_get_nb_level(rig, &val->f, NULL); + case RIG_LEVEL_MONITOR_GAIN: + retval = kenwood_safe_transaction(rig, "ML", lvlbuf, sizeof(lvlbuf), 5); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%d", &lvl); + val->f = (float) lvl / 60.0f; + break; + default: + return kenwood_get_level(rig, vfo, level, val); + } + + return RIG_OK; } +int kx3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + int retval; + + switch (level) { + case RIG_LEVEL_RFPOWER_METER: { + int tx_status = 0; + float pwr; + + // Return zero RF power when not in TX mode + retval = get_kenwood_func(rig, "TQ", &tx_status); + if (retval != RIG_OK) { + return retval; + } + if (!tx_status) { + val->f = 0.0f; + return RIG_OK; + } + + retval = kx3_get_bar_graph_level(rig, &pwr); + if (retval != RIG_OK) { + return retval; + } + + val->f = pwr; + break; + } + default: + return k3_get_level(rig, vfo, level, val); + } + + return RIG_OK; +} + + +int k3_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) { + return -RIG_EINVAL; + } + + char buf[10]; + + switch (func) { + case RIG_FUNC_APF: + snprintf(buf, sizeof (buf), "AP%c", (status == 0) ? '0' : '1'); + break; + case RIG_FUNC_DUAL_WATCH: + snprintf(buf, sizeof (buf), "SB%c", (status == 0) ? '0' : '1'); + break; + case RIG_FUNC_DIVERSITY: + snprintf(buf, sizeof (buf), "DV%c", (status == 0) ? '0' : '1'); + break; + default: + return kenwood_set_func(rig, vfo, func, status); + } + + return kenwood_transaction(rig, buf, NULL, 0); +} /* * Some functions, notably RIT and XIT On/Off status, can be queried * on the K3. Those functions are handled here and others are passed * through to kenwood_get_func(). */ -int k3_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) -{ - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); +int k3_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - if (!rig || !status) - return -RIG_EINVAL; + if (!rig || !status) + return -RIG_EINVAL; - switch (func) { - case RIG_FUNC_RIT: - return get_kenwood_func(rig, "RT", status); - - case RIG_FUNC_XIT: - return get_kenwood_func(rig, "XT", status); - - default: - return kenwood_get_func(rig, vfo, func, status); - } + switch (func) { + case RIG_FUNC_RIT: + return get_kenwood_func(rig, "RT", status); + case RIG_FUNC_XIT: + return get_kenwood_func(rig, "XT", status); + case RIG_FUNC_APF: + return get_kenwood_func(rig, "AP", status); + case RIG_FUNC_DUAL_WATCH: + return get_kenwood_func(rig, "SB", status); + case RIG_FUNC_DIVERSITY: + return get_kenwood_func(rig, "DV", status); + default: + return kenwood_get_func(rig, vfo, func, status); + } } - - - /* Private K3 helper functions */ /* @@ -899,3 +1690,188 @@ int set_rit_xit(RIG *rig, shortfreq_t rit) return RIG_OK; } + +int k3_set_nb_level(RIG *rig, float dsp_nb, float if_nb) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) { + return -RIG_EINVAL; + } + + char lvlbuf[16]; + int retval; + + int dsp_nb_raw; + int if_nb_raw; + + if (dsp_nb >= 0) { + dsp_nb_raw = (int) (dsp_nb * 21.0f); + } + if (if_nb >= 0) { + if_nb_raw = (int) (if_nb * 21.0f); + } + + if (dsp_nb < 0 || if_nb < 0) { + int current_dsp_nb_raw; + int current_if_nb_raw; + + retval = kenwood_safe_transaction(rig, "NL", lvlbuf, sizeof(lvlbuf), 6); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%02d%02d", ¤t_dsp_nb_raw, ¤t_if_nb_raw); + + if (dsp_nb < 0) { + dsp_nb_raw = current_dsp_nb_raw; + } + if (if_nb < 0) { + if_nb_raw = current_if_nb_raw; + } + } + + snprintf(lvlbuf, sizeof(lvlbuf), "NL%02d%02d", dsp_nb_raw, if_nb_raw); + + return kenwood_transaction(rig, lvlbuf, NULL, 0); +} + +int k3_get_nb_level(RIG *rig, float *dsp_nb, float *if_nb) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) { + return -RIG_EINVAL; + } + + char lvlbuf[16]; + int retval; + + int dsp_nb_raw; + int if_nb_raw; + + retval = kenwood_safe_transaction(rig, "NL", lvlbuf, sizeof(lvlbuf), 6); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%02d%02d", &dsp_nb_raw, &if_nb_raw); + + if (dsp_nb != NULL) { + *dsp_nb = (float) dsp_nb_raw / 21.0f; + } + if (if_nb != NULL) { + *if_nb = (float) if_nb_raw / 21.0f; + } + + return RIG_OK; +} + +int k3_get_bar_graph_level(RIG *rig, float *smeter, float *pwr, float *alc, int *mode_tx) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) { + return -RIG_EINVAL; + } + + char lvlbuf[16]; + int retval; + + int tm_raw; + int bg_raw; + char mode; + + // Determine transmit metering mode: 0 = RF POWER, 1 = ALC + retval = get_kenwood_func(rig, "TM", &tm_raw); + if (retval != RIG_OK) { + return retval; + } + + retval = kenwood_safe_transaction(rig, "BG", lvlbuf, sizeof(lvlbuf), 5); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%02d%c", &bg_raw, &mode); + + if (mode == 'R') { + // S-meter: nn is 00 - 21 (CWT off) or 00 - 09 (CWT on) + if (smeter != NULL) { + *smeter = (float) bg_raw / 21.0f; + } + if (pwr != NULL) { + *pwr = -1; + } + if (alc != NULL) { + *alc = -1; + } + } else if (mode == 'T') { + if (tm_raw) { + // ALC: nn is 00 - 07 + if (alc != NULL) { + *alc = (float) bg_raw / 7.0f; + } + if (pwr != NULL) { + *pwr = -1; + } + if (smeter != NULL) { + *smeter = -1; + } + } else { + // PWR: nn is 00 - 12 + if (pwr != NULL) { + *pwr = (float) bg_raw / 12.0f; + } + if (alc != NULL) { + *alc = -1; + } + if (smeter != NULL) { + *smeter = -1; + } + } + } else { + return -RIG_EPROTO; + } + + if (mode_tx != NULL) { + *mode_tx = (mode == 'T'); + } + + return RIG_OK; +} + +int kx3_get_bar_graph_level(RIG *rig, float *level) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) { + return -RIG_EINVAL; + } + + char lvlbuf[16]; + int retval; + + int bg_raw; + + retval = kenwood_safe_transaction(rig, "BG", lvlbuf, sizeof(lvlbuf), 4); + if (retval != RIG_OK) { + return retval; + } + + sscanf(lvlbuf + 2, "%02d", &bg_raw); + + if (bg_raw >= 0 && bg_raw <= 10) { + if (level != NULL) { + *level = (float) bg_raw / 10.0f; + } + } else if (bg_raw >= 12 && bg_raw <= 22) { + if (level != NULL) { + *level = (float) (bg_raw - 12) / 10.0f; + } + } else { + return -RIG_EPROTO; + } + + return RIG_OK; +} diff --git a/kenwood/kenwood.c b/kenwood/kenwood.c index 5cf171d7c..99123e9aa 100644 --- a/kenwood/kenwood.c +++ b/kenwood/kenwood.c @@ -2929,6 +2929,9 @@ int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg) */ switch(rig->caps->rig_model) { case RIG_MODEL_K3: // probably a lot more rigs need to go here + case RIG_MODEL_K3S: + case RIG_MODEL_KX2: + case RIG_MODEL_KX3: snprintf(morsebuf, sizeof (morsebuf), "KY %s", m2); break; default: @@ -3505,6 +3508,9 @@ DECLARE_INITRIG_BACKEND(kenwood) rig_register(&trc80_caps); rig_register(&k2_caps); rig_register(&k3_caps); + rig_register(&k3s_caps); + rig_register(&kx2_caps); + rig_register(&kx3_caps); rig_register(&xg3_caps); rig_register(&ts440_caps); diff --git a/kenwood/kenwood.h b/kenwood/kenwood.h index 7a8b0a9c0..fb3554668 100644 --- a/kenwood/kenwood.h +++ b/kenwood/kenwood.h @@ -176,6 +176,9 @@ extern const struct rig_caps ts930_caps; extern const struct rig_caps ts2000_caps; extern const struct rig_caps k2_caps; extern const struct rig_caps k3_caps; +extern const struct rig_caps k3s_caps; +extern const struct rig_caps kx2_caps; +extern const struct rig_caps kx3_caps; extern const struct rig_caps xg3_caps; extern const struct rig_caps trc80_caps; diff --git a/kenwood/ts480.c b/kenwood/ts480.c index b5827aadb..e5dab69ea 100644 --- a/kenwood/ts480.c +++ b/kenwood/ts480.c @@ -39,8 +39,8 @@ #define TS480_VFO (RIG_VFO_A|RIG_VFO_B) #define TS480_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC) -#define TS480_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2) -#define TS890_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2) +#define TS480_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT) +#define TS890_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT) /* diff --git a/src/cal.c b/src/cal.c index fdafc3de6..f8dc268b3 100644 --- a/src/cal.c +++ b/src/cal.c @@ -41,10 +41,10 @@ /** - * \brief Convert raw S-meter data to calibated value, according to table + * \brief Convert raw data to a calibrated integer value, according to table * \param rawval input value * \param cal calibration table - * \return calibrated value + * \return calibrated integer value * cal_table_t is a data type suited to hold linear calibration * cal_table_t.size tell the number of plot cal_table_t.table contains @@ -111,4 +111,63 @@ float HAMLIB_API rig_raw2val(int rawval, const cal_table_t *cal) return cal->table[i].val - interpolation; } +/** + * \brief Convert raw data to a calibrated floating-point value, according to table + * \param rawval input value + * \param cal calibration table + * \return calibrated floating-point value + + * cal_table_float_t is a data type suited to hold linear calibration + * cal_table_float_t.size tell the number of plot cal_table_t.table contains + * If a value is below or equal to cal_table_float_t.table[0].raw, + * rig_raw2val_float() will return cal_table_float_t.table[0].val + * If a value is greater or equal to cal_table_float_t.table[cal_table_float_t.size-1].raw, + * rig_raw2val_float() will return cal_table_float_t.table[cal_table_float_t.size-1].val + */ +float HAMLIB_API rig_raw2val_float(int rawval, const cal_table_float_t *cal) +{ + float interpolation; + int i; + + /* ASSERT(cal != NULL) */ + /* ASSERT(cal->size <= MAX_CAL_LENGTH) */ + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (cal->size == 0) + { + return rawval; + } + + for (i = 0; i < cal->size; i++) + { + if (rawval < cal->table[i].raw) + { + break; + } + } + + if (i == 0) + { + return cal->table[0].val; + } + + if (i >= cal->size) + { + return cal->table[i - 1].val; + } + + /* catch divide by 0 error */ + if (cal->table[i].raw == cal->table[i - 1].raw) + { + return cal->table[i].val; + } + + interpolation = ((cal->table[i].raw - rawval) + * (float)(cal->table[i].val - cal->table[i - 1].val)) + / (float)(cal->table[i].raw - cal->table[i - 1].raw); + + return cal->table[i].val - interpolation; +} + /** @} */ diff --git a/src/cal.h b/src/cal.h index 730c20a33..b456a0c61 100644 --- a/src/cal.h +++ b/src/cal.h @@ -25,5 +25,6 @@ #include extern HAMLIB_EXPORT(float) rig_raw2val(int rawval, const cal_table_t *cal); +extern HAMLIB_EXPORT(float) rig_raw2val_float(int rawval, const cal_table_float_t *cal); #endif /* _CAL_H */ diff --git a/src/idx_builtin.h b/src/idx_builtin.h index 826f7d79d..18eeb4990 100644 --- a/src/idx_builtin.h +++ b/src/idx_builtin.h @@ -104,6 +104,14 @@ #define LVL_STRENGTH setting2idx_builtin(RIG_LEVEL_STRENGTH) /*#define LVL_BWC setting2idx_builtin(RIG_LEVEL_BWC)*/ +#define LVL_RFPOWER_METER setting2idx_builtin(RIG_LEVEL_RFPOWER_METER) +#define LVL_COMP_METER setting2idx_builtin(RIG_LEVEL_COMP_METER) +#define LVL_VD_METER setting2idx_builtin(RIG_LEVEL_VD_METER) +#define LVL_ID_METER setting2idx_builtin(RIG_LEVEL_ID_METER) + +#define LVL_NOTCHF_RAW setting2idx_builtin(RIG_LEVEL_NOTCHF_RAW) +#define LVL_MONITOR_GAIN setting2idx_builtin(RIG_LEVEL_MONITOR_GAIN) + #define PARM_ANN setting2idx_builtin(RIG_PARM_ANN) #define PARM_APO setting2idx_builtin(RIG_PARM_APO) #define PARM_BACKLIGHT setting2idx_builtin(RIG_PARM_BACKLIGHT) diff --git a/src/misc.c b/src/misc.c index d9a88b959..b38d5925d 100644 --- a/src/misc.c +++ b/src/misc.c @@ -522,6 +522,8 @@ static struct { RIG_FUNC_AFLT, "AFLT" }, { RIG_FUNC_ANL, "ANL" }, { RIG_FUNC_BC2, "BC2" }, + { RIG_FUNC_DUAL_WATCH, "DUAL_WATCH"}, + { RIG_FUNC_DIVERSITY, "DIVERSITY"}, { RIG_FUNC_NONE, "" }, }; @@ -626,6 +628,13 @@ static struct { RIG_LEVEL_SWR, "SWR" }, { RIG_LEVEL_ALC, "ALC" }, { RIG_LEVEL_STRENGTH, "STRENGTH" }, + { RIG_LEVEL_RFPOWER_METER, "RFPOWER_METER" }, + { RIG_LEVEL_COMP_METER, "COMP_METER" }, + { RIG_LEVEL_VD_METER, "VD_METER" }, + { RIG_LEVEL_ID_METER, "ID_METER" }, + { RIG_LEVEL_NOTCHF_RAW, "NOTCHF_RAW" }, + { RIG_LEVEL_MONITOR_GAIN, "MONITOR_GAIN" }, + { RIG_LEVEL_NB, "NB" }, { RIG_LEVEL_NONE, "" }, }; diff --git a/src/serial.c b/src/serial.c index 14f5e4959..b34b68c48 100644 --- a/src/serial.c +++ b/src/serial.c @@ -88,6 +88,19 @@ static int uh_ptt_fd = -1; static int uh_radio_fd = -1; +typedef struct term_options_backup { + int fd; +#if defined(HAVE_TERMIOS_H) + struct termios options; +#elif defined(HAVE_TERMIO_H) + struct termio options; +#elif defined(HAVE_SGTTY_H) + struct sgttyb sg; +#endif + struct term_options_backup *next; +} term_options_backup_t; +static term_options_backup_t *term_options_backup_head = NULL; + /* * This function simply returns TRUE if the argument matches uh_radio_fd and @@ -211,14 +224,15 @@ int HAMLIB_API serial_setup(hamlib_port_t *rp) /* There's a lib replacement for termios under Mingw */ #if defined(HAVE_TERMIOS_H) speed_t speed; /* serial comm speed */ - struct termios options; + struct termios options, orig_options; #elif defined(HAVE_TERMIO_H) - struct termio options; + struct termio options, orig_options; #elif defined(HAVE_SGTTY_H) - struct sgttyb sg; + struct sgttyb sg, orig_sg; #else # error "No term control supported!" #endif + term_options_backup_t *term_backup = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -234,10 +248,13 @@ int HAMLIB_API serial_setup(hamlib_port_t *rp) */ #if defined(HAVE_TERMIOS_H) tcgetattr(fd, &options); + memcpy(&orig_options, &options, sizeof(orig_options)); #elif defined(HAVE_TERMIO_H) IOCTL(fd, TCGETA, &options); + memcpy(&orig_options, &options, sizeof(orig_options)); #else /* sgtty */ IOCTL(fd, TIOCGETP, &sg); + memcpy(&orig_sg, &sg, sizeof(orig_sg)); #endif #ifdef HAVE_CFMAKERAW @@ -518,6 +535,19 @@ int HAMLIB_API serial_setup(hamlib_port_t *rp) #endif + // Store a copy of the original options for this FD, to be restored on close. + term_backup = malloc(sizeof(term_options_backup_t)); + term_backup-> fd = fd; +#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H) + memcpy(&term_backup->options, &orig_options, sizeof(orig_options)); +#elif defined(HAVE_SGTTY_H) + memcpy(&term_backup->sg, &orig_sg, sizeof(orig_sg)); +#endif + + // insert at head of list + term_backup->next = term_options_backup_head; + term_options_backup_head = term_backup; + return RIG_OK; } @@ -597,6 +627,7 @@ int ser_open(hamlib_port_t *p) int ser_close(hamlib_port_t *p) { int rc; + term_options_backup_t *term_backup, *term_backup_prev; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -619,6 +650,63 @@ int ser_close(hamlib_port_t *p) return 0; } + // Find backup termios options to restore before closing + term_backup = term_options_backup_head; + term_backup_prev = term_options_backup_head; + while(term_backup) { + if(term_backup->fd == p->fd) { + // Found matching. Remove from list + if(term_backup == term_options_backup_head) { + term_options_backup_head = term_backup->next; + } else { + term_backup_prev->next = term_backup->next; + } + break; + } + term_backup_prev = term_backup; + term_backup = term_backup->next; + } + + // Restore backup termios + if(term_backup) { + rig_debug(RIG_DEBUG_VERBOSE, "%s: restoring options\n", __func__); +#if defined(HAVE_TERMIOS_H) + + if (tcsetattr(p->fd, TCSANOW, &term_backup->options) == -1) + { + rig_debug(RIG_DEBUG_ERR, + "%s: tcsetattr restore failed: %s\n", + __func__, + strerror(errno)); + } + +#elif defined(HAVE_TERMIO_H) + + if (IOCTL(p->fd, TCSETA, &term_backup->options) == -1) + { + rig_debug(RIG_DEBUG_ERR, + "%s: ioctl(TCSETA) restore failed: %s\n", + __func__, + strerror(errno)); + } + +#else + + /* sgtty */ + if (IOCTL(p->fd, TIOCSETP, &term_backup->sg) == -1) + { + rig_debug(RIG_DEBUG_ERR, + "%s: ioctl(TIOCSETP) restore failed: %s\n", + __func__, + strerror(errno)); + } +#endif + + free(term_backup); + } else { + rig_debug(RIG_DEBUG_WARN, "%s: no options for fd to restore\n", __func__); + } + rc = CLOSE(p->fd); p->fd = -1; return rc; diff --git a/tests/dumpcaps.c b/tests/dumpcaps.c index 6ed40d55c..364ace842 100644 --- a/tests/dumpcaps.c +++ b/tests/dumpcaps.c @@ -34,13 +34,14 @@ #include "rigctl_parse.h" static int print_ext(RIG *rig, const struct confparams *cfp, rig_ptr_t ptr); +void range_print(FILE *fout, const struct freq_range_list range_list[], int rx); int range_sanity_check(const struct freq_range_list range_list[], int rx); int ts_sanity_check(const struct tuning_step_list tuning_step[]); static void dump_chan_caps(const channel_cap_t *chan, FILE *fout); /* - * the rig may be in rig_init state, but not openned + * the rig may be in rig_init state, but not opened */ int dumpcaps(RIG *rig, FILE *fout) { @@ -359,9 +360,8 @@ int dumpcaps(RIG *rig, FILE *fout) backend_warnings++; } - fprintf(fout, "Extra levels:"); + fprintf(fout, "Extra levels:\n"); rig_ext_level_foreach(rig, print_ext, fout); - fprintf(fout, "\n"); sprintf_parm_gran(prntbuf, caps->has_get_parm, caps->parm_gran); fprintf(fout, "Get parameters: %s\n", prntbuf); @@ -375,9 +375,8 @@ int dumpcaps(RIG *rig, FILE *fout) backend_warnings++; } - fprintf(fout, "Extra parameters:"); + fprintf(fout, "Extra parameters:\n"); rig_ext_parm_foreach(rig, print_ext, fout); - fprintf(fout, "\n"); if (rig->state.mode_list != 0) @@ -433,7 +432,18 @@ int dumpcaps(RIG *rig, FILE *fout) fprintf(fout, "\n"); - /* TODO: print rx/tx ranges here */ + fprintf(fout, "TX ranges, region 1:\n"); + range_print(fout, caps->tx_range_list1, 0); + + fprintf(fout, "RX ranges, region 1:\n"); + range_print(fout, caps->rx_range_list1, 1); + + fprintf(fout, "TX ranges, region 2:\n"); + range_print(fout, caps->tx_range_list2, 0); + + fprintf(fout, "RX ranges, region 2:\n"); + range_print(fout, caps->rx_range_list2, 1); + status = range_sanity_check(caps->tx_range_list1, 0); fprintf(fout, "TX ranges status, region 1:\t%s (%d)\n", @@ -711,14 +721,67 @@ int dumpcaps(RIG *rig, FILE *fout) return backend_warnings; } - static int print_ext(RIG *rig, const struct confparams *cfp, rig_ptr_t ptr) { - fprintf((FILE *)ptr, " %s", cfp->name); + fprintf((FILE *)ptr, "\t%s\n", cfp->name); + fprintf((FILE *)ptr, "\t\tType: %s\n", get_rig_conf_type(cfp->type)); + fprintf((FILE *)ptr, "\t\tDefault: %s\n", cfp->dflt != NULL ? cfp->dflt : ""); + fprintf((FILE *)ptr, "\t\tLabel: %s\n", cfp->label != NULL ? cfp->label : ""); + fprintf((FILE *)ptr, "\t\tTooltip: %s\n", cfp->tooltip != NULL ? cfp->tooltip : ""); + + switch (cfp->type) { + case RIG_CONF_NUMERIC: + fprintf((FILE *)ptr, "\t\tRange: %g..%g/%g\n", cfp->u.n.min, cfp->u.n.max, cfp->u.n.step); + break; + case RIG_CONF_COMBO: + fprintf((FILE *)ptr, "\t\tValues:"); + if (cfp->u.c.combostr != NULL) { + for (int i = 0; i < RIG_COMBO_MAX && cfp->u.c.combostr[i] != NULL; i++) { + fprintf((FILE *)ptr, " %d=\"%s\"", i, cfp->u.c.combostr[i]); + } + } + fprintf((FILE *)ptr, "\n"); + break; + default: + break; + } return 1; /* process them all */ } +void range_print(FILE *fout, const struct freq_range_list range_list[], int rx) +{ + int i; + char prntbuf[1024]; /* a malloc would be better.. */ + + for (i = 0; i < FRQRANGESIZ; i++) { + if (range_list[i].start == 0 && range_list[i].end == 0) { + break; + } + + fprintf(fout, "\t%.0f Hz - %.0f Hz\n", range_list[i].start, range_list[i].end); + + fprintf(fout, "\t\tVFO list: "); + sprintf_vfo(prntbuf, range_list[i].vfo); + fprintf(fout, prntbuf); + fprintf(fout, "\n"); + + fprintf(fout, "\t\tMode list: "); + sprintf_mode(prntbuf, range_list[i].modes); + fprintf(fout, prntbuf); + fprintf(fout, "\n"); + + fprintf(fout, "\t\tAntenna list: "); + sprintf_ant(prntbuf, range_list[i].ant); + fprintf(fout, prntbuf); + fprintf(fout, "\n"); + + if (!rx) { + fprintf(fout, "\t\tLow power: %.0f W, High power: %.0f W\n", + range_list[i].low_power / 1000.0f, range_list[i].high_power / 1000.0f); + } + } +} /* * check for: diff --git a/tests/sprintflst.c b/tests/sprintflst.c index 53766eda3..f44c1ade1 100644 --- a/tests/sprintflst.c +++ b/tests/sprintflst.c @@ -131,6 +131,26 @@ int sprintf_mode(char *str, rmode_t mode) } +int sprintf_ant(char *str, ant_t ant) +{ + int i, len = 0; + + *str = '\0'; + + if (ant == RIG_ANT_NONE) { + return 0; + } + + for (i = 0; i < RIG_ANT_MAX; i++) { + if (ant & (1UL << i)) { + len += sprintf(str + len, "%d ", i + 1); + } + } + + return len; +} + + int sprintf_func(char *str, setting_t func) { uint64_t i, len = 0; @@ -453,3 +473,21 @@ int sprintf_scan(char *str, scan_t rscan) return len; } + +char *get_rig_conf_type(enum rig_conf_e type) +{ + switch (type) { + case RIG_CONF_STRING: + return "STRING"; + case RIG_CONF_COMBO: + return "COMBO"; + case RIG_CONF_NUMERIC: + return "NUMERIC"; + case RIG_CONF_CHECKBUTTON: + return "CHECKBUTTON"; + case RIG_CONF_BUTTON: + return "BUTTON"; + } + + return "UNKNOWN"; +} diff --git a/tests/sprintflst.h b/tests/sprintflst.h index f0a0c95e4..db4e61657 100644 --- a/tests/sprintflst.h +++ b/tests/sprintflst.h @@ -30,6 +30,7 @@ __BEGIN_DECLS extern int sprintf_mode(char *str, rmode_t); extern int sprintf_vfo(char *str, vfo_t); +extern int sprintf_ant(char *str, ant_t); extern int sprintf_func(char *str, setting_t); extern int sprintf_level(char *str, setting_t); extern int sprintf_level_amp(char *str, setting_t); @@ -39,6 +40,7 @@ extern int sprintf_parm(char *str, setting_t); extern int sprintf_parm_gran(char *str, setting_t, const gran_t gran[]); extern int sprintf_vfop(char *str, vfo_op_t); extern int sprintf_scan(char *str, scan_t); +extern char *get_rig_conf_type(enum rig_conf_e type); __END_DECLS diff --git a/yaesu/ft600.c b/yaesu/ft600.c index 7078326a5..7c35a0381 100644 --- a/yaesu/ft600.c +++ b/yaesu/ft600.c @@ -2,7 +2,8 @@ * hamlib - (C) Frank Singleton 2000-2003 * (C) Stephane Fillod 2000-2010 * - * ft600.c - (C) Kārlis Millers YL3CAAK 2019 + * ft600.c -(C) Kārlis Millers YL3ALK 2019 + * * This shared library provides an API for communicating * via serial interface to an FT-600 using the "CAT" interface. * The starting point for this code was Chris Karpinsky's ft100 implementation. @@ -133,9 +134,9 @@ const struct rig_caps ft600_caps = { .rig_model = RIG_MODEL_FT600, .model_name = "FT-600", .mfg_name = "Yaesu", - .version = "0.1", + .version = "0.2", .copyright = "LGPL", - .status = RIG_STATUS_ALPHA, + .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, @@ -383,10 +384,7 @@ int ft600_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft600_priv_data *priv = (struct ft600_priv_data*)rig->state.priv; freq_t f; - char *ptr; - char freq_str[10]; int ret; - rig_debug(RIG_DEBUG_VERBOSE,"ft600: get_freq \n"); if( !freq ) return -RIG_EINVAL; @@ -396,13 +394,11 @@ int ft600_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { return ret; } - sprintf(freq_str, "%hhx%hhx%hhx", - priv->status.freq[1], - priv->status.freq[2], - priv->status.freq[3]); + f = ((((priv->status.freq[1] <<8) + priv->status.freq[2])<<8) + priv->status.freq[3]) * 10; - f=strtol(freq_str,&ptr,16); - *freq = f * 10; + rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz\n", __func__, f); + + *freq = f; return RIG_OK; } diff --git a/yaesu/ft600.h b/yaesu/ft600.h index 9b0fad901..22963d472 100644 --- a/yaesu/ft600.h +++ b/yaesu/ft600.h @@ -2,9 +2,10 @@ * hamlib - (C) Frank Singleton 2000-2003 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * - * ft600.h - (C) Kārlis Millers YL3CAAK 2019 + * ft600.h -(C) Kārlis Millers YL3ALK 2019 + * * This shared library provides an API for communicating - * via serial interface to an FT-100 using the "CAT" interface. + * via serial interface to an FT-600 using the "CAT" interface. * The starting point for this code was Chris Karpinsky's ft100 implementation. * * This library is free software; you can redistribute it and/or @@ -12,7 +13,7 @@ * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * This l ibrary is distributed in the hope that it will be useful, + * This library 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 * Lesser General Public License for more details.