diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index 8a27d7820..f0dbd0388 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -495,7 +495,7 @@ typedef unsigned int vfo_t; * \brief Macro for bandpass to be set to normal * \def RIG_PASSBAND_NORMAL */ -#define RIG_PASSBAND_NORMAL s_Hz(0) // was 0 but collided with Yasue SH00; capability +#define RIG_PASSBAND_NORMAL s_Hz(0) // was 0 but collided with Yaesu SH00; capability /** * \brief Macro for bandpass to be left alone diff --git a/rigs/yaesu/ft1200.c b/rigs/yaesu/ft1200.c index 7706d463c..14dacd3fe 100644 --- a/rigs/yaesu/ft1200.c +++ b/rigs/yaesu/ft1200.c @@ -112,14 +112,16 @@ const struct rig_caps ftdx1200_caps = // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ + .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), - .max_ifshift = Hz(1000), + .max_ifshift = Hz(1200), .vfo_ops = FTDX1200_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 1200 has an Auto Info command */ @@ -172,12 +174,11 @@ const struct rig_caps ftdx1200_caps = {FTDX1200_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, - }, /* mode/filter list, .remember = order matters! */ .filters = { - {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Normal CW, RTTY, PKT/USER */ + {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ @@ -185,8 +186,10 @@ const struct rig_caps ftdx1200_caps = {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ - {FTDX1200_FM_RX_MODES, Hz(12000)}, /* Normal FM */ - {FTDX1200_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ + {FTDX1200_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM */ + {FTDX1200_FM_WIDE_RX_MODES, Hz(9000)}, /* Narrow FM */ + {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ + {FTDX1200_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, diff --git a/rigs/yaesu/ft1200.h b/rigs/yaesu/ft1200.h index 7910be05a..88afd85de 100644 --- a/rigs/yaesu/ft1200.h +++ b/rigs/yaesu/ft1200.h @@ -34,12 +34,13 @@ /* Receiver caps */ #define FTDX1200_ALL_RX_MODES (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_FM) + RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN) #define FTDX1200_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX1200_AM_RX_MODES (RIG_MODE_AM) -#define FTDX1200_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) +#define FTDX1200_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) +#define FTDX1200_FM_RX_MODES (FTDX1200_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FTDX1200_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) diff --git a/rigs/yaesu/ft2000.c b/rigs/yaesu/ft2000.c index 68ca3398d..af7a73d62 100644 --- a/rigs/yaesu/ft2000.c +++ b/rigs/yaesu/ft2000.c @@ -40,12 +40,49 @@ #include "idx_builtin.h" #include "tones.h" -/* - * ft2000 rigs capabilities. - * Also this struct is READONLY! - * - */ +const struct newcat_priv_caps ft2000_priv_caps = +{ + .roofing_filter_count = 7, + .roofing_filters = + { + // The index must match ext level combo index + { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, + { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, + { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, + { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, + { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, + { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, + { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, + } +}; +const struct confparams ft2000_ext_levels[] = +{ + { + TOK_ROOFING_FILTER, + "ROOFINGFILTER", + "Roofing filter", + "Roofing filter", + NULL, + RIG_CONF_COMBO, + { .c = { .combostr = { + "AUTO", "15 kHz", "6 kHz", "3 kHz", + "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", + NULL } + } } + }, + { RIG_CONF_END, NULL, } +}; + +int ft2000_ext_tokens[] = +{ + TOK_ROOFING_FILTER, TOK_BACKEND_NONE +}; + + +/* + * FT-2000 rig capabilities + */ const struct rig_caps ft2000_caps = { RIG_MODEL(RIG_MODEL_FT2000), @@ -78,10 +115,12 @@ const struct rig_caps ft2000_caps = // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ + .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), @@ -138,7 +177,6 @@ const struct rig_caps ft2000_caps = {FT2000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, - }, /* mode/filter list, .remember = order matters! */ @@ -157,7 +195,10 @@ const struct rig_caps ft2000_caps = RIG_FLT_END, }, - .priv = NULL, + .ext_tokens = ft2000_ext_tokens, + .extlevels = ft2000_ext_levels, + + .priv = &ft2000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, @@ -207,5 +248,7 @@ const struct rig_caps ft2000_caps = .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, + .set_ext_level = newcat_set_ext_level, + .get_ext_level = newcat_get_ext_level, }; diff --git a/rigs/yaesu/ft3000.c b/rigs/yaesu/ft3000.c index 516a181b4..32f245504 100644 --- a/rigs/yaesu/ft3000.c +++ b/rigs/yaesu/ft3000.c @@ -115,11 +115,13 @@ const struct rig_caps ftdx3000_caps = .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, - [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ + .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), @@ -138,7 +140,7 @@ const struct rig_caps ftdx3000_caps = .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ - {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "USA"}, + {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "USA"}, RIG_FRNG_END, }, @@ -152,7 +154,7 @@ const struct rig_caps ftdx3000_caps = }, .rx_range_list2 = { - {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "EUR"}, + {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "EUR"}, RIG_FRNG_END, }, @@ -176,7 +178,6 @@ const struct rig_caps ftdx3000_caps = {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, - }, /* mode/filter list, .remember = order matters! */ @@ -184,13 +185,14 @@ const struct rig_caps ftdx3000_caps = {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ - {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ - {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ - {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ - {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ - {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ - {FTDX5000_FM_RX_MODES, Hz(15000)}, /* Normal FM */ - {FTDX5000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ + {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ + {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ + {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ + {FTDX5000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ + {FTDX5000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ + {FTDX5000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ + {FTDX5000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ + {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, diff --git a/rigs/yaesu/ft450.c b/rigs/yaesu/ft450.c index 057c86e95..98857ed43 100644 --- a/rigs/yaesu/ft450.c +++ b/rigs/yaesu/ft450.c @@ -77,11 +77,13 @@ const struct rig_caps ft450_caps = // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 400 }, .max = { .i = 800 }, .step = { .i = 100 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, RIG_DBLST_END, }, /* TBC */ - .attenuator = { 18, RIG_DBLST_END, }, /* TBC */ + .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ + .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(1000), diff --git a/rigs/yaesu/ft5000.c b/rigs/yaesu/ft5000.c index c02df103a..cfb13e238 100644 --- a/rigs/yaesu/ft5000.c +++ b/rigs/yaesu/ft5000.c @@ -110,11 +110,13 @@ const struct rig_caps ftdx5000_caps = .level_gran = { // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, - [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ + .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), @@ -171,21 +173,21 @@ const struct rig_caps ftdx5000_caps = {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, - }, /* mode/filter list, .remember = order matters! */ .filters = { - {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ + {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1700)}, /* Normal CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ - {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ - {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ - {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ - {FTDX5000_FM_RX_MODES, Hz(15000)}, /* Normal FM */ - {FTDX5000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ + {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ + {FTDX5000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ + {FTDX5000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ + {FTDX5000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ + {FTDX5000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ + {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, diff --git a/rigs/yaesu/ft5000.h b/rigs/yaesu/ft5000.h index db32b61b6..7b045376e 100644 --- a/rigs/yaesu/ft5000.h +++ b/rigs/yaesu/ft5000.h @@ -32,13 +32,13 @@ /* Receiver caps */ -#define FTDX5000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ +#define FTDX5000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|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_FM|RIG_MODE_FMN) #define FTDX5000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) -#define FTDX5000_AM_RX_MODES (RIG_MODE_AM) +#define FTDX5000_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FTDX5000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) #define FTDX5000_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) @@ -47,7 +47,7 @@ #define FTDX5000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */ -#define FTDX5000_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ +#define FTDX5000_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ /* TBC */ #define FTDX5000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ @@ -100,7 +100,7 @@ * */ -#define FTDX5000_TX_ANTS (RIG_ANT_1|RIG_ANT_2) +#define FTDX5000_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) #define FTDX5000_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX5000_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ diff --git a/rigs/yaesu/ft891.c b/rigs/yaesu/ft891.c index da1997b08..3a73d4fb2 100644 --- a/rigs/yaesu/ft891.c +++ b/rigs/yaesu/ft891.c @@ -77,14 +77,16 @@ const struct rig_caps ft891_caps = // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ - .attenuator = { 6, 12, 18, RIG_DBLST_END, }, + .preamp = { 10, RIG_DBLST_END, }, /* TBC */ + .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), - .max_ifshift = Hz(1000), + .max_ifshift = Hz(1200), .vfo_ops = FT891_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ @@ -170,6 +172,7 @@ const struct rig_caps ft891_caps = {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ + {FT891_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY }, {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ {FT891_FM_RX_MODES, Hz(16000)}, /* Normal FM */ @@ -200,8 +203,6 @@ const struct rig_caps ft891_caps = .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, - .set_ant = newcat_set_ant, - .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, diff --git a/rigs/yaesu/ft891.h b/rigs/yaesu/ft891.h index e95401aee..6a3b541f0 100644 --- a/rigs/yaesu/ft891.h +++ b/rigs/yaesu/ft891.h @@ -95,7 +95,7 @@ * */ -#define FT891_ANTS (RIG_ANT_1|RIG_ANT_2) +#define FT891_ANTS (RIG_ANT_CURR) #define FT891_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT891_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ diff --git a/rigs/yaesu/ft9000.c b/rigs/yaesu/ft9000.c index b0d626ae3..149a43df3 100644 --- a/rigs/yaesu/ft9000.c +++ b/rigs/yaesu/ft9000.c @@ -78,11 +78,13 @@ const struct rig_caps ft9000_caps = // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ - .attenuator = { 6, 12, 18, RIG_DBLST_END, }, + .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ + .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), diff --git a/rigs/yaesu/ft9000.h b/rigs/yaesu/ft9000.h index 5cfc27d71..03525832d 100644 --- a/rigs/yaesu/ft9000.h +++ b/rigs/yaesu/ft9000.h @@ -68,14 +68,13 @@ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ - RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF) + RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|RIG_LEVEL_MONITOR_GAIN) /* TBC */ #define FT9000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ - RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ - RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ - RIG_FUNC_RIT|RIG_FUNC_XIT\ - ) + RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ + RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|\ + RIG_FUNC_RIT|RIG_FUNC_XIT) /* TBC */ #define FT9000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ diff --git a/rigs/yaesu/ft950.c b/rigs/yaesu/ft950.c index 6703daa93..27bba7c0f 100644 --- a/rigs/yaesu/ft950.c +++ b/rigs/yaesu/ft950.c @@ -25,7 +25,6 @@ * */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -39,12 +38,48 @@ #include "ft950.h" #include "idx_builtin.h" -/* - * ft950 rigs capabilities. - * Also this struct is READONLY! - * - */ +const struct newcat_priv_caps ft950_priv_caps = +{ + .roofing_filter_count = 7, + .roofing_filters = + { + // The index must match ext level combo index + { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, + { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, + { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, + { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, + { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, + { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, + { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, + } +}; +const struct confparams ft950_ext_levels[] = +{ + { + TOK_ROOFING_FILTER, + "ROOFINGFILTER", + "Roofing filter", + "Roofing filter", + NULL, + RIG_CONF_COMBO, + { .c = { .combostr = { + "AUTO", "15 kHz", "6 kHz", "3 kHz", + "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", + NULL } + } } + }, + { RIG_CONF_END, NULL, } +}; + +int ft950_ext_tokens[] = +{ + TOK_ROOFING_FILTER, TOK_BACKEND_NONE +}; + +/* + * FT-950 rig capabilities + */ const struct rig_caps ft950_caps = { RIG_MODEL(RIG_MODEL_FT950), @@ -77,10 +112,12 @@ const struct rig_caps ft950_caps = // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ + .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), @@ -140,7 +177,6 @@ const struct rig_caps ft950_caps = {FT950_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, - }, /* mode/filter list, .remember = order matters! */ @@ -177,22 +213,25 @@ const struct rig_caps ft950_caps = {RIG_MODE_SSB, Hz(200)}, /* SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ - {FT950_FM_RX_MODES, Hz(16000)}, /* Normal FM */ - {FT950_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ + {FT950_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM */ + {FT950_FM_WIDE_RX_MODES, Hz(9000)}, /* Narrow FM */ + {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ + {FT950_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, + .ext_tokens = ft950_ext_tokens, + .extlevels = ft950_ext_levels, - - .priv = NULL, /* private data FIXME: */ + .priv = &ft950_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ - .cfgparams = newcat_cfg_params, + .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf = newcat_get_conf, .set_freq = newcat_set_freq, @@ -235,5 +274,7 @@ const struct rig_caps ft950_caps = .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, + .set_ext_level = newcat_set_ext_level, + .get_ext_level = newcat_get_ext_level, }; diff --git a/rigs/yaesu/ft950.h b/rigs/yaesu/ft950.h index 64c4961d0..09de523e1 100644 --- a/rigs/yaesu/ft950.h +++ b/rigs/yaesu/ft950.h @@ -38,19 +38,20 @@ /* Receiver caps */ #define FT950_ALL_RX_MODES (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_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FMN) #define FT950_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT950_AM_RX_MODES (RIG_MODE_AM) -#define FT950_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) +#define FT950_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) +#define FT950_FM_RX_MODES (FT950_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FT950_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT950_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ -#define FT950_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ -#define FT950_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ +#define FT950_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB) /* 100 W class */ +#define FT950_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ #define FT950_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ diff --git a/rigs/yaesu/ft991.c b/rigs/yaesu/ft991.c index 0db7f3fcf..e643c0253 100644 --- a/rigs/yaesu/ft991.c +++ b/rigs/yaesu/ft991.c @@ -76,14 +76,16 @@ const struct rig_caps ft991_caps = // cppcheck-suppress * [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, - .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ - .attenuator = { 6, 12, 18, RIG_DBLST_END, }, + .preamp = { 10, 20, RIG_DBLST_END, }, + .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), - .max_ifshift = Hz(1000), + .max_ifshift = Hz(1200), .vfo_ops = FT991_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ @@ -161,10 +163,11 @@ const struct rig_caps ft991_caps = {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ + {FT991_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY }, {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ - {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ - {FT991_FM_RX_MODES, Hz(16000)}, /* Normal FM */ - {FT991_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ + {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ + {FT991_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM */ + {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ RIG_FLT_END, }, @@ -192,8 +195,6 @@ const struct rig_caps ft991_caps = .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, - .set_ant = newcat_set_ant, - .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, diff --git a/rigs/yaesu/ft991.h b/rigs/yaesu/ft991.h index 4557d1a13..159aeeac0 100644 --- a/rigs/yaesu/ft991.h +++ b/rigs/yaesu/ft991.h @@ -38,7 +38,8 @@ #define FT991_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT991_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) -#define FT991_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_C4FM) +#define FT991_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_C4FM) +#define FT991_FM_RX_MODES (FT991_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FT991_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT991_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) diff --git a/rigs/yaesu/ftdx101.c b/rigs/yaesu/ftdx101.c index a330c1e10..75b3668af 100644 --- a/rigs/yaesu/ftdx101.c +++ b/rigs/yaesu/ftdx101.c @@ -104,6 +104,8 @@ const struct rig_caps ftdx101d_caps = .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, + [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, + [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, @@ -125,7 +127,7 @@ const struct rig_caps ftdx101d_caps = .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ - {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS | RIG_ANT_5, "USA"}, + {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "USA"}, RIG_FRNG_END, }, @@ -139,7 +141,7 @@ const struct rig_caps ftdx101d_caps = }, .rx_range_list2 = { - {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS | RIG_ANT_5, "EUR"}, + {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "EUR"}, RIG_FRNG_END, }, diff --git a/rigs/yaesu/ftdx101.h b/rigs/yaesu/ftdx101.h index 66be4a8a5..5e0309f4b 100644 --- a/rigs/yaesu/ftdx101.h +++ b/rigs/yaesu/ftdx101.h @@ -91,7 +91,7 @@ * Other features (used by rig_caps) */ -#define FTDX101_TX_ANTS (RIG_ANT_1|RIG_ANT_2) +#define FTDX101_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define FTDX101_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX101_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c index 3a410cbbd..24e760196 100644 --- a/rigs/yaesu/newcat.c +++ b/rigs/yaesu/newcat.c @@ -203,7 +203,7 @@ static ncboolean is_ft891; static ncboolean is_ft950; static ncboolean is_ft991; static ncboolean is_ft2000; -static ncboolean is_ft9000; +static ncboolean is_ftdx9000; static ncboolean is_ftdx5000; static ncboolean is_ftdx1200; static ncboolean is_ftdx3000; @@ -2849,25 +2849,34 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) switch (val.i) { - case RIG_AGC_OFF: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT00;"); + case RIG_AGC_OFF: + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT00;"); break; - case RIG_AGC_FAST: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT01;"); + case RIG_AGC_FAST: + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT01;"); break; - case RIG_AGC_MEDIUM: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT02;"); + case RIG_AGC_MEDIUM: + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT02;"); break; - case RIG_AGC_SLOW: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT03;"); + case RIG_AGC_SLOW: + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT03;"); break; - case RIG_AGC_AUTO: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT04;"); + case RIG_AGC_AUTO: + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT04;"); break; - default: return -RIG_EINVAL; + default: + return -RIG_EINVAL; } - priv->cmd_str[2] = main_sub_vfo; + if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) + { + priv->cmd_str[2] = main_sub_vfo; + } break; case RIG_LEVEL_IF: @@ -2895,6 +2904,11 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS%c0%+.4d%c", main_sub_vfo, val.i, cat_term); } + else if (is_ft891) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS0%d%+.4d%c", val.i == 0 ? 0 : 1, + val.i, cat_term); + } else { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS%c%+.4d%c", main_sub_vfo, @@ -2906,9 +2920,12 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) priv->cmd_str[2] = main_sub_vfo; } + // Some Yaesu rigs reject this command in AM/FM modes + priv->question_mark_response_means_rejected = 1; break; - case RIG_LEVEL_CWPITCH: + case RIG_LEVEL_CWPITCH: { + int kp; if (!newcat_valid_command(rig, "KP")) { return -RIG_ENAVAIL; @@ -2927,9 +2944,19 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) i = val.i; } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c", - 2 * ((i + 50 - 300) / 100), cat_term); + if (is_ft950 || is_ft2000) + { + kp = (i - 300) / 50; + } + else + { + // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps + kp = (i - 300) / 10; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c", kp, cat_term); break; + } case RIG_LEVEL_KEYSPD: if (!newcat_valid_command(rig, "KS")) @@ -2956,6 +2983,9 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) } snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MG%03d%c", fpf, cat_term); + + // Some Yaesu rigs reject this command in RTTY modes + priv->question_mark_response_means_rejected = 1; break; case RIG_LEVEL_METER: @@ -3037,23 +3067,25 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) priv->cmd_str[0] = '\0'; for (i = 0; state->preamp[i] != RIG_DBLST_END; i++) + { if (state->preamp[i] == val.i) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PA0%d%c", i + 1, cat_term); break; } - - if (strlen(priv->cmd_str) != 0) - { - if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) - { - priv->cmd_str[2] = main_sub_vfo; - } - - break; } - return -RIG_EINVAL; + if (strlen(priv->cmd_str) == 0) + { + return -RIG_EINVAL; + } + + if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) + { + priv->cmd_str[2] = main_sub_vfo; + } + + break; case RIG_LEVEL_ATT: if (!newcat_valid_command(rig, "RA")) @@ -3076,23 +3108,25 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) priv->cmd_str[0] = '\0'; for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++) + { if (state->attenuator[i] == val.i) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RA0%d%c", i + 1, cat_term); - break; /* for loop */ + break; } - - if (strlen(priv->cmd_str) != 0) - { - if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) - { - priv->cmd_str[2] = main_sub_vfo; - } - - break; } - return -RIG_EINVAL; + if (strlen(priv->cmd_str) == 0) + { + return -RIG_EINVAL; + } + + if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) + { + priv->cmd_str[2] = main_sub_vfo; + } + + break; case RIG_LEVEL_RF: if (!newcat_valid_command(rig, "RG")) @@ -3100,7 +3134,16 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - fpf = newcat_scale_float(255, val.f); + if (is_ft891) + { + scale = 30; + } + else + { + scale = 255; + } + + fpf = newcat_scale_float(scale, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%03d%c", main_sub_vfo, fpf, cat_term); break; @@ -3149,6 +3192,8 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) } } + // Some Yaesu rigs reject this command in AM/FM modes + priv->question_mark_response_means_rejected = 1; break; case RIG_LEVEL_COMP: @@ -3157,74 +3202,107 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - scale = (is_ft950) ? 100 : 255; - scale = (is_ftdx1200 || is_ftdx101) ? 100 : scale ; + if (is_ft2000 || is_ftdx9000 || is_ftdx5000) + { + scale = 255; + } + else + { + scale = 100; + } + fpf = newcat_scale_float(scale, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PL%03d%c", fpf, cat_term); break; - case RIG_LEVEL_BKINDL: + case RIG_LEVEL_BKINDL: { + int millis; + value_t keyspd; - /* Standard: word "PARIS" == 50 Unit Intervals, UIs */ - /* 1 dot == 2 UIs */ - /* tenth_dots-per-second -to- milliseconds */ if (!newcat_valid_command(rig, "SD")) { return -RIG_ENAVAIL; } - // we don't get full resolution as long as val->i is in integer tenths - // consider changing this to float or to milliseconds - val.i *= 100; // tenths to ms conversion + // Convert 10/ths of dots to milliseconds using the current key speed + err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd); + if (err != RIG_OK) + { + return err; + } + + millis = dot10ths_to_millis(val.i, keyspd.i); if (is_ftdx101) { - if (val.i <= 30) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD00;"); } - - else if (val.i <= 50) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD01;"); } - - else if (val.i <= 100) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD02;"); } - - else if (val.i <= 150) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD03;"); } - - else if (val.i <= 200) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD04;"); } - - else if (val.i <= 250) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD05;"); } - - else if (val.i > 2900) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD33;"); } - // this covers 300-2900 06-32 - else { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%02d;", 6 + ((val.i - 300) / 100)); } + if (millis <= 30) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD00;"); } + else if (millis <= 50) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD01;"); } + else if (millis <= 100) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD02;"); } + else if (millis <= 150) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD03;"); } + else if (millis <= 200) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD04;"); } + else if (millis <= 250) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD05;"); } + else if (millis > 2900) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD33;"); } + else + { + // This covers 300-2900 06-32 + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%02d;", 6 + ((millis - 300) / 100)); + } } - else if (is_ft950 || is_ft450 || is_ftdx1200) + else if (is_ftdx5000) { - if (val.i < 30) + if (millis < 20) { - val.i = 30; + millis = 20; + } + if (millis > 5000) + { + millis = 5000; } - if (val.i > 3000) + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); + } + else if (is_ft950 || is_ft450 || is_ft891 || is_ft991 || is_ftdx1200 || is_ftdx3000) + { + if (millis < 30) { - val.i = 3000; + millis = 30; + } + if (millis > 3000) + { + millis = 3000; } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", val.i, cat_term); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); + } + else if (is_ft2000 || is_ftdx9000) + { + if (millis < 0) + { + millis = 0; + } + if (millis > 5000) + { + millis = 5000; + } + + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } else // default { - if (val.i < 1) + if (millis < 1) { - val.i = 1; + millis = 1; + } + if (millis > 5000) + { + millis = 5000; } - if (val.i > 5000) - { - val.i = 5000; - } - - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", val.i, cat_term); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } break; + } case RIG_LEVEL_SQL: if (!newcat_valid_command(rig, "SQ")) @@ -3232,7 +3310,16 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - fpf = newcat_scale_float(255, val.f); + if (is_ft891 || is_ft991 || is_ftdx101) + { + scale = 100; + } + else + { + scale = 255; + } + + fpf = newcat_scale_float(scale, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%03d%c", main_sub_vfo, fpf, cat_term); break; @@ -3303,28 +3390,55 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_ENAVAIL; } - scale = (is_ft950 || is_ftdx101) ? 100 : 255; - scale = (is_ftdx1200) ? 100 : scale; + if (is_ft2000 || is_ftdx9000 || is_ftdx5000) + { + scale = 255; + } + else + { + scale = 100; + } + fpf = newcat_scale_float(scale, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VG%03d%c", fpf, cat_term); break; case RIG_LEVEL_ANTIVOX: - if (is_ft950) - { - fpf = newcat_scale_float(100, val.f); - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term); - } - else if (is_ftdx101) + if (is_ftdx101) { fpf = newcat_scale_float(100, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AV%03d%c", fpf, cat_term); } - else if (is_ftdx1200) + else if (is_ftdx5000) + { + fpf = newcat_scale_float(100, val.f); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX176%03d%c", fpf, cat_term); + } + else if (is_ftdx3000 || is_ftdx1200) { fpf = newcat_scale_float(100, val.f); snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%03d%c", fpf, cat_term); } + else if (is_ft991) + { + fpf = newcat_scale_float(100, val.f); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX147%03d%c", fpf, cat_term); + } + else if (is_ft891) + { + fpf = newcat_scale_float(100, val.f); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%03d%c", fpf, cat_term); + } + else if (is_ft950) + { + fpf = newcat_scale_float(100, val.f); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term); + } + else if (is_ft2000) + { + fpf = newcat_scale_float(100, val.f); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX042%03d%c", fpf, cat_term); + } else { return -RIG_EINVAL; @@ -3340,12 +3454,29 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) val.i = val.i / 10; - if (val.i < 1) /* fix lower bounds limit */ + if (is_ftdx9000) { - val.i = 1; + if (val.i < 0) + { + val.i = 0; + } + } + else + { + if (val.i < 1) + { + val.i = 1; + } } - if (newcat_is_rig(rig, RIG_MODEL_FT950)) + if (is_ft891 || is_ft991 || is_ftdx101) + { + if (val.i > 320) + { + val.i = 320; + } + } + if (is_ft950 || is_ftdx9000) { if (val.i > 300) { @@ -3362,14 +3493,14 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP01%03d%c", val.i, cat_term); - if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE && !is_ft9000) - { - priv->cmd_str[2] = main_sub_vfo; - } - else if (is_ft9000) // different BP command format + if (is_ftdx9000) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP%03d%c", val.i, cat_term); } + else if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) + { + priv->cmd_str[2] = main_sub_vfo; + } break; @@ -3388,14 +3519,26 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) fpf = newcat_scale_float(255, val.f); } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%03d%c", fpf, cat_term); + if (is_ftdx9000) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML%03d%c", fpf, cat_term); + } + else + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%03d%c", fpf, cat_term); + } break; default: return -RIG_EINVAL; } - return newcat_set_cmd(rig); + err = newcat_set_cmd(rig); + + // Clear flag after executing command + priv->question_mark_response_means_rejected = 0; + + return err; } @@ -3409,6 +3552,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) int retlvl_len; float scale; char main_sub_vfo = '0'; + int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -3484,7 +3628,6 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { priv->cmd_str[2] = main_sub_vfo; } - break; case RIG_LEVEL_CWPITCH: @@ -3578,7 +3721,6 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) return -RIG_ENAVAIL; } - /* should be tenth of dots */ snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%c", cat_term); break; @@ -3681,18 +3823,38 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; case RIG_LEVEL_ANTIVOX: - if (is_ft950) - { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term); - } - else if (is_ftdx101) + if (is_ftdx101) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AV%c", cat_term); } + else if (is_ftdx5000) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX176%c", cat_term); + } + else if (is_ftdx3000 || is_ftdx1200) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term); + } else if (is_ftdx1200) { snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term); } + else if (is_ft991) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX147%c", cat_term); + } + else if (is_ft891) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%c", cat_term); + } + else if (is_ft950) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term); + } + else if (is_ft2000) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX042%c", cat_term); + } else { return -RIG_EINVAL; @@ -3708,7 +3870,11 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP01%c", cat_term); - if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) + if (is_ftdx9000) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP%c", cat_term); + } + else if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } @@ -3721,14 +3887,23 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) return -RIG_ENAVAIL; } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%c", cat_term); + if (is_ftdx9000) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML%c", cat_term); + } + else + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML1%c", cat_term); + } break; default: return -RIG_EINVAL; } - if (RIG_OK != (err = newcat_get_cmd(rig))) + err = newcat_get_cmd(rig); + + if (err != RIG_OK) { return err; } @@ -3763,10 +3938,20 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) case RIG_LEVEL_VOXGAIN: case RIG_LEVEL_COMP: + if (is_ft2000 || is_ftdx9000 || is_ftdx5000) + { + scale = 255; + } + else + { + scale = 100; + } + + val->f = (float) atoi(retlvl) / scale; + break; + case RIG_LEVEL_ANTIVOX: - scale = (is_ft950 || is_ftdx101) ? 100. : 255.; - scale = (is_ftdx1200 || is_ftdx101) ? 100. : scale ; - val->f = (float)atoi(retlvl) / scale; + val->f = (float) atoi(retlvl) / 100.; break; case RIG_LEVEL_SWR: @@ -3891,52 +4076,71 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; case RIG_LEVEL_AF: - case RIG_LEVEL_RF: - case RIG_LEVEL_SQL: - val->f = (float)atoi(retlvl) / 255.; + val->f = (float)atoi(retlvl) / 255; break; - case RIG_LEVEL_BKINDL: - val->i = atoi(retlvl); /* milliseconds */ + case RIG_LEVEL_RF: + if (is_ft891) + { + scale = 30.; + } + else + { + scale = 255.; + } + + val->f = (float)atoi(retlvl) / scale; + break; + + case RIG_LEVEL_SQL: + if (is_ft891 || is_ft991 || is_ftdx101) + { + scale = 100.; + } + else + { + scale = 255.; + } + + val->f = (float)atoi(retlvl) / scale; + break; + + case RIG_LEVEL_BKINDL: { + int raw_value = atoi(retlvl); + int millis; + value_t keyspd; if (is_ftdx101) { - switch (val->i) + switch (raw_value) { - case 0: val->i = 1; break; - - case 1: val->i = 1; break; - - case 2: val->i = 1; break; - - case 3: val->i = 2; break; - - case 4: val->i = 2; break; - - case 5: val->i = 3; break; - - case 6: val->i = 3; break; - - default: val->i = (val->i - 6) + 3; + case 0: millis = 30; break; + case 1: millis = 50; break; + case 2: millis = 100; break; + case 3: millis = 150; break; + case 4: millis = 200; break; + case 5: millis = 250; break; + case 6: millis = 300; break; + default: + millis = (raw_value - 6) * 100 + 300; } - - return RIG_OK; } - - if (val->i < 1) + else { - val->i = 1; + // The rest of Yaesu rigs indicate break-in delay directly as milliseconds + millis = raw_value; } - val->i = 5000 / val->i; /* ms -to- tenth_dots-per-second */ - - if (val->i < 1) + // Convert milliseconds to 10/ths of dots using the current key speed + err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd); + if (err != RIG_OK) { - val->i = 1; + return err; } + val->i = millis_to_dot10ths(millis, keyspd.i); break; - + } case RIG_LEVEL_STRENGTH: if (rig->caps->str_cal.size > 0) { @@ -3949,17 +4153,27 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { val->i = round(rig_raw2val(atoi(retlvl), &yaesu_default_str_cal)); } - else // some Yaesu rigs return straight s-meter answers + else { + // Some Yaesu rigs return straight S-meter answers // Return dbS9 -- does >S9 mean 10dB increments? If not, add to rig driver - if (val->i > 0) { val->i = (atoi(retlvl) - 9) * 10; } - else { val->i = (atoi(retlvl) - 9) * 6; } // Return dbS9 does >S9 mean 10dB increments? + if (val->i > 0) + { + val->i = (atoi(retlvl) - 9) * 10; + } + else + { + val->i = (atoi(retlvl) - 9) * 6; + } } break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_KEYSPD: + val->i = atoi(retlvl); + break; + case RIG_LEVEL_IF: // IS00+0400 rig_debug(RIG_DEBUG_TRACE, "%s: ret_data=%s(%d), retlvl=%s\n", __func__, @@ -3983,9 +4197,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; case RIG_LEVEL_NR: - - /* ratio 0 - 1.0 */ - if (newcat_is_rig(rig, RIG_MODEL_FT450)) + if (is_ft450) { val->f = (float)(atoi(retlvl) / 11.); } @@ -4028,47 +4240,94 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; - case RIG_LEVEL_PREAMP: + case RIG_LEVEL_PREAMP: { + int preamp; + if (retlvl[0] < '0' || retlvl[0] > '9') { return -RIG_EPROTO; } - val->i = (retlvl[0] == '0') ? 0 : state->preamp[retlvl[0] - '1']; - break; + preamp = retlvl[0] - '0'; + + val->i = 0; + + if (preamp > 0) + { + for (i = 0; state->preamp[i] != RIG_DBLST_END; i++) + { + if (i == preamp - 1) + { + val->i = state->preamp[i]; + break; + } + } + } + break; + } + + case RIG_LEVEL_ATT: { + int att; - case RIG_LEVEL_ATT: if (retlvl[0] < '0' || retlvl[0] > '9') { return -RIG_EPROTO; } - val->i = (retlvl[0] == '0') ? 0 : state->attenuator[retlvl[0] - '1']; + att = retlvl[0] - '0'; + + val->i = 0; + + if (att > 0) + { + for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++) + { + if (i == att - 1) + { + val->i = state->attenuator[i]; + break; + } + } + } break; + } case RIG_LEVEL_AGC: switch (retlvl[0]) { - case '0': val->i = RIG_AGC_OFF; break; - - case '1': val->i = RIG_AGC_FAST; break; - - case '2': val->i = RIG_AGC_MEDIUM; break; - - case '3': val->i = RIG_AGC_SLOW; break; - + case '0': + val->i = RIG_AGC_OFF; + break; + case '1': + val->i = RIG_AGC_FAST; + break; + case '2': + val->i = RIG_AGC_MEDIUM; + break; + case '3': + val->i = RIG_AGC_SLOW; + break; case '4': case '5': case '6': val->i = RIG_AGC_AUTO; break; - default: return -RIG_EPROTO; + default: + return -RIG_EPROTO; } break; case RIG_LEVEL_CWPITCH: - val->i = (atoi(retlvl) / 2) * 100 + 300; + if (is_ft950 || is_ft2000) + { + val->i = (atoi(retlvl) * 50) + 300; + } + else + { + // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps + val->i = (atoi(retlvl) * 10) + 300; + } break; case RIG_LEVEL_METER: @@ -4153,6 +4412,8 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) priv->cmd_str[2] = main_sub_vfo; } + // Some Yaesu rigs reject this command in AM/FM modes + priv->question_mark_response_means_rejected = 1; break; case RIG_FUNC_MN: @@ -4169,6 +4430,8 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) priv->cmd_str[2] = main_sub_vfo; } + // Some Yaesu rigs reject this command in AM/FM modes + priv->question_mark_response_means_rejected = 1; break; case RIG_FUNC_FBKIN: @@ -4273,6 +4536,8 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) priv->cmd_str[2] = main_sub_vfo; } + // Some Yaesu rigs reject this command in AM/FM modes + priv->question_mark_response_means_rejected = 1; break; case RIG_FUNC_COMP: @@ -4281,15 +4546,14 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) return -RIG_ENAVAIL; } - if (is_ftdx1200 || is_ftdx3000 || is_ft891 || is_ft991 || is_ftdx101) + if (is_ft891 || is_ft991 || is_ftdx1200 || is_ftdx3000 || is_ftdx101) { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR0%d%c", status ? 1 : 0, - cat_term); + // There seems to be an error in the manuals for some of these rigs stating that values should be 1 = OFF and 2 = ON, but they are 0 = OFF and 1 = ON instead + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR0%d%c", status ? 1 : 0, cat_term); } else { - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR%d%c", status ? 1 : 0, - cat_term); + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR%d%c", status ? 1 : 0, cat_term); } break; @@ -4342,7 +4606,12 @@ int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) return -RIG_EINVAL; } - return newcat_set_cmd(rig); + err = newcat_set_cmd(rig); + + // Clear flag after executing command + priv->question_mark_response_means_rejected = 0; + + return err; } @@ -5430,14 +5699,14 @@ ncboolean newcat_valid_command(RIG *rig, char const *const command) is_ft950 = newcat_is_rig(rig, RIG_MODEL_FT950); is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991); is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000); - is_ft9000 = newcat_is_rig(rig, RIG_MODEL_FT9000); + is_ftdx9000 = newcat_is_rig(rig, RIG_MODEL_FT9000); is_ftdx5000 = newcat_is_rig(rig, RIG_MODEL_FTDX5000); is_ftdx1200 = newcat_is_rig(rig, RIG_MODEL_FTDX1200); is_ftdx3000 = newcat_is_rig(rig, RIG_MODEL_FTDX3000); is_ftdx101 = newcat_is_rig(rig, RIG_MODEL_FTDX101D); if (!is_ft450 && !is_ft950 && !is_ft891 && !is_ft991 && !is_ft2000 - && !is_ftdx5000 && !is_ft9000 && !is_ftdx1200 && !is_ftdx3000 && !is_ftdx101) + && !is_ftdx5000 && !is_ftdx9000 && !is_ftdx1200 && !is_ftdx3000 && !is_ftdx101) { rig_debug(RIG_DEBUG_ERR, "%s: '%s' is unknown\n", __func__, caps->model_name); return FALSE; @@ -5496,7 +5765,7 @@ ncboolean newcat_valid_command(RIG *rig, char const *const command) { return TRUE; } - else if (is_ft9000 && valid_commands[search_index].ft9000) + else if (is_ftdx9000 && valid_commands[search_index].ft9000) { return TRUE; } @@ -5933,7 +6202,15 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: - if (width <= 100) { w = 3; } + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 100) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 300) { w = 5; } else if (width <= 400) { w = 6; } @@ -5943,13 +6220,20 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) else if (width <= 1400) { w = 10; } else if (width <= 1700) { w = 11; } else if (width <= 2000) { w = 12; } - else { w = 13; } // 2400 is the max - + else { w = 13; } // 2400 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: - if (width <= 200) { w = 1; } + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } @@ -5968,10 +6252,27 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } - else { w = 20; } // 3000 is the max - + else { w = 20; } // 3000 Hz break; + case RIG_MODE_AM: + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + case RIG_MODE_FMN: + // Set roofing filter and narrow mode + break; + + default: + return -RIG_EINVAL; + } // end switch(mode) + + if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) + { + return err; + } + + switch (mode) + { case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: @@ -5983,13 +6284,12 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { err = newcat_set_narrow(rig, vfo, FALSE); } - return err; - default: - return -RIG_EINVAL; - } // end switch(mode) - } // end is_ft950 */ + case RIG_MODE_FMN: + return RIG_OK; + } + } // end is_ft950 */ else if (is_ft891) { switch (mode) @@ -6000,204 +6300,14 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: - if (width <= 50) { w = 1; } - else if (width <= 100) { w = 2; } - else if (width <= 150) { w = 3; } - else if (width <= 200) { w = 4; } - else if (width <= 250) { w = 5; } - else if (width <= 300) { w = 6; } - else if (width <= 350) { w = 7; } - else if (width <= 400) { w = 8; } - else if (width <= 450) { w = 9; } - else if (width <= 500) { w = 10; } - else if (width <= 800) { w = 11; } - else if (width <= 1200) { w = 12; } - else if (width <= 1400) { w = 13; } - else if (width <= 1700) { w = 14; } - else if (width <= 2000) { w = 15; } - else if (width <= 2400) { w = 16; } - else { w = 17; } // 3000 is the max - - break; - - case RIG_MODE_LSB: - case RIG_MODE_USB: - if (width <= 200) { w = 1; } - else if (width <= 400) { w = 2; } - else if (width <= 600) { w = 3; } - else if (width <= 850) { w = 4; } - else if (width <= 1100) { w = 5; } - else if (width <= 1350) { w = 6; } - else if (width <= 1500) { w = 7; } - else if (width <= 1600) { w = 8; } - else if (width <= 1800) { w = 9; } - else if (width <= 1950) { w = 10; } - else if (width <= 2100) { w = 11; } - else if (width <= 2200) { w = 12; } - else if (width <= 2300) { w = 13; } - else if (width <= 2400) { w = 14; } - else if (width <= 2500) { w = 15; } - else if (width <= 2600) { w = 16; } - else if (width <= 2700) { w = 17; } - else if (width <= 2800) { w = 18; } - else if (width <= 2900) { w = 19; } - else if (width <= 3000) { w = 20; } - else { w = 21; } // 3000 is the max - - break; - - case RIG_MODE_AM: - case RIG_MODE_FM: - case RIG_MODE_PKTFM: - if (width < rig_passband_normal(rig, mode)) + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); + if (err != RIG_OK) { - err = newcat_set_narrow(rig, vfo, TRUE); - } - else - { - err = newcat_set_narrow(rig, vfo, FALSE); + return err; } - return err; - - default: - return -RIG_EINVAL; - } // end switch(mode) - } // end is_ft891 - else if (is_ft991) - { - switch (mode) - { - case RIG_MODE_PKTUSB: - case RIG_MODE_PKTLSB: - case RIG_MODE_RTTY: - case RIG_MODE_RTTYR: - case RIG_MODE_CW: - case RIG_MODE_CWR: - if (width <= 50) { w = 1; } - else if (width <= 100) { w = 2; } - else if (width <= 150) { w = 3; } - else if (width <= 200) { w = 4; } - else if (width <= 250) { w = 5; } - else if (width <= 305) { w = 6; } - else if (width <= 350) { w = 7; } - else if (width <= 400) { w = 8; } - else if (width <= 450) { w = 9; } - else if (width <= 500) { w = 10; } - else if (width <= 800) { w = 11; } - else if (width <= 1200) { w = 12; } - else if (width <= 1400) { w = 13; } - else if (width <= 1700) { w = 14; } - else if (width <= 2000) { w = 15; } - else if (width <= 2400) { w = 16; } - else { w = 17; } // 3000 is the max - - break; - - case RIG_MODE_LSB: - case RIG_MODE_USB: - if (width <= 200) { w = 1; } - else if (width <= 400) { w = 2; } - else if (width <= 600) { w = 3; } - else if (width <= 850) { w = 4; } - else if (width <= 1100) { w = 5; } - else if (width <= 1350) { w = 6; } - else if (width <= 1500) { w = 7; } - else if (width <= 1660) { w = 8; } - else if (width <= 1800) { w = 9; } - else if (width <= 1950) { w = 10; } - else if (width <= 2100) { w = 11; } - else if (width <= 2200) { w = 12; } - else if (width <= 2300) { w = 13; } - else if (width <= 2400) { w = 14; } - else if (width <= 2500) { w = 15; } - else if (width <= 2600) { w = 16; } - else if (width <= 2700) { w = 17; } - else if (width <= 2800) { w = 18; } - else if (width <= 2900) { w = 19; } - else if (width <= 3000) { w = 20; } - else { w = 21; } // 3200 is the max - - break; - - case RIG_MODE_AM: //Only 1 passband each for AM or AMN - if (width == 0 || width == 9000) - { - err = newcat_set_narrow(rig, vfo, FALSE); - } - - return err; - - case RIG_MODE_AMN: - if (width == 0 || width == 6000) - { - err = newcat_set_narrow(rig, vfo, TRUE); - } - - return err; - - case RIG_MODE_FM: //Only 1 passband each for FM or FMN - - if (width == 0 || width == 16000) - { - err = newcat_set_narrow(rig, vfo, FALSE); - } - - return err; - - case RIG_MODE_FMN: - - if (width == 0 || width == 9000) - { - err = newcat_set_narrow(rig, vfo, TRUE); - } - - return err; - - case RIG_MODE_C4FM: - - if (width == 0 || width == 16000) - { - err = newcat_set_narrow(rig, vfo, TRUE); - } - else if (width == 9000) - { - err = newcat_set_narrow(rig, vfo, FALSE); - } - else - { - return -RIG_EINVAL; - } - - return err; - - case RIG_MODE_PKTFM: - if (width < rig_passband_normal(rig, mode)) - { - err = newcat_set_narrow(rig, vfo, TRUE); - } - else - { - err = newcat_set_narrow(rig, vfo, FALSE); - } - - return err; - - default: - return -RIG_EINVAL; - } // end switch(mode) - } // end is_ft991 - else if (is_ftdx1200) - { - switch (mode) - { - case RIG_MODE_PKTUSB: - case RIG_MODE_PKTLSB: - case RIG_MODE_RTTY: - case RIG_MODE_RTTYR: - case RIG_MODE_CW: - case RIG_MODE_CWR: - if (width == 0) { w = 0; } + if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } @@ -6213,13 +6323,238 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } - else { w = 16; } // 2400 is max - + else if (width <= 2400) { w = 16; } + else { w = 17; } // 3000 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: - if (width == 0) { w = 0; } + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 200) { w = 1; } + else if (width <= 400) { w = 2; } + else if (width <= 600) { w = 3; } + else if (width <= 850) { w = 4; } + else if (width <= 1100) { w = 5; } + else if (width <= 1350) { w = 6; } + else if (width <= 1500) { w = 7; } + else if (width <= 1650) { w = 8; } + else if (width <= 1800) { w = 9; } + else if (width <= 1950) { w = 10; } + else if (width <= 2100) { w = 11; } + else if (width <= 2200) { w = 12; } + else if (width <= 2300) { w = 13; } + else if (width <= 2400) { w = 14; } + else if (width <= 2500) { w = 15; } + else if (width <= 2600) { w = 16; } + else if (width <= 2700) { w = 17; } + else if (width <= 2800) { w = 18; } + else if (width <= 2900) { w = 19; } + else if (width <= 3000) { w = 20; } + else { w = 21; } // 3000 Hz + break; + + case RIG_MODE_AM: + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + if (width < rig_passband_normal(rig, mode)) + { + err = newcat_set_narrow(rig, vfo, TRUE); + } + else + { + err = newcat_set_narrow(rig, vfo, FALSE); + } + return err; + + case RIG_MODE_FMN: + break; + + default: + return -RIG_EINVAL; + } // end switch(mode) + } // end is_ft891 + else if (is_ft991) + { + switch (mode) + { + case RIG_MODE_PKTUSB: + case RIG_MODE_PKTLSB: + case RIG_MODE_RTTY: + case RIG_MODE_RTTYR: + case RIG_MODE_CW: + case RIG_MODE_CWR: + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 50) { w = 1; } + else if (width <= 100) { w = 2; } + else if (width <= 150) { w = 3; } + else if (width <= 200) { w = 4; } + else if (width <= 250) { w = 5; } + else if (width <= 305) { w = 6; } + else if (width <= 350) { w = 7; } + else if (width <= 400) { w = 8; } + else if (width <= 450) { w = 9; } + else if (width <= 500) { w = 10; } + else if (width <= 800) { w = 11; } + else if (width <= 1200) { w = 12; } + else if (width <= 1400) { w = 13; } + else if (width <= 1700) { w = 14; } + else if (width <= 2000) { w = 15; } + else if (width <= 2400) { w = 16; } + else { w = 17; } // 3000 Hz + break; + + case RIG_MODE_LSB: + case RIG_MODE_USB: + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 200) { w = 1; } + else if (width <= 400) { w = 2; } + else if (width <= 600) { w = 3; } + else if (width <= 850) { w = 4; } + else if (width <= 1100) { w = 5; } + else if (width <= 1350) { w = 6; } + else if (width <= 1500) { w = 7; } + else if (width <= 1650) { w = 8; } + else if (width <= 1800) { w = 9; } + else if (width <= 1950) { w = 10; } + else if (width <= 2100) { w = 11; } + else if (width <= 2200) { w = 12; } + else if (width <= 2300) { w = 13; } + else if (width <= 2400) { w = 14; } + else if (width <= 2500) { w = 15; } + else if (width <= 2600) { w = 16; } + else if (width <= 2700) { w = 17; } + else if (width <= 2800) { w = 18; } + else if (width <= 2900) { w = 19; } + else if (width <= 3000) { w = 20; } + else { w = 21; } // 3200 Hz + break; + + case RIG_MODE_AM: // Only 1 passband each for AM or AMN + if (width == RIG_PASSBAND_NORMAL || width == 9000) + { + err = newcat_set_narrow(rig, vfo, FALSE); + } + return err; + + case RIG_MODE_AMN: + if (width == RIG_PASSBAND_NORMAL || width == 6000) + { + err = newcat_set_narrow(rig, vfo, TRUE); + } + return err; + + case RIG_MODE_FM: // Only 1 passband each for FM or FMN + if (width == RIG_PASSBAND_NORMAL || width == 16000) + { + err = newcat_set_narrow(rig, vfo, FALSE); + } + return err; + + case RIG_MODE_FMN: + if (width == RIG_PASSBAND_NORMAL || width == 9000) + { + err = newcat_set_narrow(rig, vfo, TRUE); + } + return err; + + case RIG_MODE_C4FM: + if (width == RIG_PASSBAND_NORMAL || width == 16000) + { + err = newcat_set_narrow(rig, vfo, TRUE); + } + else if (width == 9000) + { + err = newcat_set_narrow(rig, vfo, FALSE); + } + else + { + return -RIG_EINVAL; + } + return err; + + case RIG_MODE_PKTFM: + if (width < rig_passband_normal(rig, mode)) + { + err = newcat_set_narrow(rig, vfo, TRUE); + } + else + { + err = newcat_set_narrow(rig, vfo, FALSE); + } + return err; + + default: + return -RIG_EINVAL; + } // end switch(mode) + } // end is_ft991 + else if (is_ftdx1200 || is_ftdx3000) + { + // FTDX 1200 and FTDX 3000 have the same set of filter choices + switch (mode) + { + case RIG_MODE_PKTUSB: + case RIG_MODE_PKTLSB: + case RIG_MODE_RTTY: + case RIG_MODE_RTTYR: + case RIG_MODE_CW: + case RIG_MODE_CWR: + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 50) { w = 1; } + else if (width <= 100) { w = 2; } + else if (width <= 150) { w = 3; } + else if (width <= 200) { w = 4; } + else if (width <= 250) { w = 5; } + else if (width <= 300) { w = 6; } + else if (width <= 350) { w = 7; } + else if (width <= 400) { w = 8; } + else if (width <= 450) { w = 9; } + else if (width <= 500) { w = 10; } + else if (width <= 800) { w = 11; } + else if (width <= 1200) { w = 12; } + else if (width <= 1400) { w = 13; } + else if (width <= 1700) { w = 14; } + else if (width <= 2000) { w = 15; } + else { w = 16; } // 2400 Hz + break; + + case RIG_MODE_LSB: + case RIG_MODE_USB: + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } @@ -6244,13 +6579,33 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) else if (width <= 3400) { w = 22; } else if (width <= 3600) { w = 23; } else if (width <= 3800) { w = 24; } - else { w = 25; } // 4000Hz is max - + else { w = 25; } // 4000 Hz break; case RIG_MODE_AM: + case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: + case RIG_MODE_FMN: + // Set roofing filter and narrow mode + break; + + default: + return -RIG_EINVAL; + } // end switch(mode) + + if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) + { + return err; + } + + switch (mode) + { + case RIG_MODE_AM: + case RIG_MODE_AMN: + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + case RIG_MODE_FMN: if (width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); @@ -6259,13 +6614,116 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { err = newcat_set_narrow(rig, vfo, FALSE); } - return err; + } + } // end is_ftdx1200 and is_ftdx3000 + else if (is_ftdx5000) + { + switch (mode) + { + case RIG_MODE_PKTUSB: + case RIG_MODE_PKTLSB: + case RIG_MODE_RTTY: + case RIG_MODE_RTTYR: + case RIG_MODE_CW: + case RIG_MODE_CWR: + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 50) { w = 1; } + else if (width <= 100) { w = 2; } + else if (width <= 150) { w = 3; } + else if (width <= 200) { w = 4; } + else if (width <= 250) { w = 5; } + else if (width <= 300) { w = 6; } + else if (width <= 350) { w = 7; } + else if (width <= 400) { w = 8; } + else if (width <= 450) { w = 9; } + else if (width <= 500) { w = 10; } + else if (width <= 800) { w = 11; } + else if (width <= 1200) { w = 12; } + else if (width <= 1400) { w = 13; } + else if (width <= 1700) { w = 14; } + else if (width <= 2000) { w = 15; } + else { w = 16; } // 2400 Hz + break; + + case RIG_MODE_LSB: + case RIG_MODE_USB: + // Narrow mode must be chosen correctly before filter width + err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); + if (err != RIG_OK) + { + return err; + } + + if (width == RIG_PASSBAND_NORMAL) { w = 0; } + else if (width <= 200) { w = 1; } + else if (width <= 400) { w = 2; } + else if (width <= 600) { w = 3; } + else if (width <= 850) { w = 4; } + else if (width <= 1100) { w = 5; } + else if (width <= 1350) { w = 6; } + else if (width <= 1500) { w = 7; } + else if (width <= 1650) { w = 8; } + else if (width <= 1800) { w = 9; } + else if (width <= 1950) { w = 10; } + else if (width <= 2100) { w = 11; } + else if (width <= 2250) { w = 12; } + else if (width <= 2400) { w = 13; } + else if (width <= 2500) { w = 15; } + else if (width <= 2600) { w = 16; } + else if (width <= 2700) { w = 17; } + else if (width <= 2800) { w = 18; } + else if (width <= 2900) { w = 19; } + else if (width <= 3000) { w = 20; } + else if (width <= 3200) { w = 21; } + else if (width <= 3400) { w = 22; } + else if (width <= 3600) { w = 23; } + else if (width <= 3800) { w = 24; } + else { w = 25; } // 4000 Hz + break; + + case RIG_MODE_AM: + case RIG_MODE_AMN: + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + case RIG_MODE_FMN: + // Set roofing filter and narrow mode + break; default: return -RIG_EINVAL; - } // end switch(mode) - } // end is_ftdx1200 + } // end switch(mode) + + if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) + { + return err; + } + + switch (mode) + { + case RIG_MODE_AM: + case RIG_MODE_AMN: + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + case RIG_MODE_FMN: + if (width < rig_passband_normal(rig, mode)) + { + err = newcat_set_narrow(rig, vfo, TRUE); + } + else + { + err = newcat_set_narrow(rig, vfo, FALSE); + } + return err; + } + } // end is_ftdx5000 else if (is_ftdx101) { switch (mode) @@ -6295,7 +6753,6 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) else if (width <= 2000) { w = 16; } else if (width <= 2400) { w = 17; } else { w = 18; } - break; case RIG_MODE_LSB: @@ -6324,17 +6781,49 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) else if (width <= 3200) { w = 21; } else if (width <= 3500) { w = 22; } else { w = 23; } // 4000Hz + break; + + case RIG_MODE_AM: + case RIG_MODE_AMN: + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + case RIG_MODE_FMN: + // Set roofing filter and narrow mode + break; + + default: + return -RIG_EINVAL; } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { return err; } + + switch (mode) + { + case RIG_MODE_AM: + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + if (width < rig_passband_normal(rig, mode)) + { + err = newcat_set_narrow(rig, vfo, TRUE); + } + else + { + err = newcat_set_narrow(rig, vfo, FALSE); + } + return err; + + case RIG_MODE_AMN: + case RIG_MODE_FMN: + return RIG_OK; + } } // end is_ftdx101 else { - // FT450, FT2000, FT5000, FT9000 - // we need details on the widths here...manuals lack information + // FT-450, FT-2000, FTDX 9000 + // We need details on the widths here, manuals lack information. switch (mode) { case RIG_MODE_PKTUSB: @@ -6346,7 +6835,6 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) if (width <= 500) { w = 6; } else if (width <= 1800) { w = 16; } else { w = 24; } - break; case RIG_MODE_LSB: @@ -6354,7 +6842,6 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) if (width <= 1800) { w = 8; } else if (width <= 2400) { w = 16; } else { w = 25; } // 3000 - break; case RIG_MODE_AM: @@ -6368,16 +6855,16 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { err = newcat_set_narrow(rig, vfo, FALSE); } - return err; + case RIG_MODE_FMN: + return RIG_OK; + default: return -RIG_EINVAL; - } /* end switch(mode) */ + } /* end switch(mode) */ - } - - /* end else */ + } /* end else */ if (is_ftdx101) { @@ -6464,7 +6951,7 @@ static int set_roofing_filter(RIG *rig, vfo_t vfo, int index) static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width) { struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; - int index = -1; + int index = 0; int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); @@ -6494,11 +6981,6 @@ static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width) index = current_filter->index; } - if (index < 0) - { - return -RIG_EINVAL; - } - return set_roofing_filter(rig, vfo, index); } @@ -6570,6 +7052,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv; int err; int w; + int sh_command_valid = 1; char narrow = '!'; char cmd[] = "SH"; char main_sub_vfo = '0'; @@ -6588,19 +7071,20 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) return err; } - if (is_ft950) + if (is_ft950 || is_ftdx5000) { - // can't query SH in some modes - switch (rig->state.current_mode) + // Some Yaesu rigs cannot query SH in modes such as AM/FM + switch (mode) { - case RIG_MODE_FM: *width = 12000; break; - - case RIG_MODE_AM: *width = 6000; break; - - case RIG_MODE_AMN: *width = 2400; break; + case RIG_MODE_FM: + case RIG_MODE_FMN: + case RIG_MODE_PKTFM: + case RIG_MODE_AM: + case RIG_MODE_AMN: + case RIG_MODE_PKTAM: + sh_command_valid = 0; + break; } - - return RIG_OK; } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) @@ -6608,47 +7092,54 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } - snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, - cat_term); + if (sh_command_valid) + { + snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, + cat_term); - /* Get RX BANDWIDTH */ - if (RIG_OK != (err = newcat_get_cmd(rig))) - { - return err; - } + err = newcat_get_cmd(rig); + if (err != RIG_OK) + { + return err; + } - if (strlen(priv->ret_data) == 7) - { - if (sscanf(priv->ret_data, "SH%*1d0%3d", &w) != 1) + if (strlen(priv->ret_data) == 7) { - err = -RIG_EPROTO; + if (sscanf(priv->ret_data, "SH%*1d0%3d", &w) != 1) + { + err = -RIG_EPROTO; + } } - } - else if (strlen(priv->ret_data) == 6) - { - if (sscanf(priv->ret_data, "SH%*1d%3d", &w) != 1) + else if (strlen(priv->ret_data) == 6) { - err = -RIG_EPROTO; + if (sscanf(priv->ret_data, "SH%*1d%3d", &w) != 1) + { + err = -RIG_EPROTO; + } } + else + { + rig_debug(RIG_DEBUG_ERR, "%s: unknown SH response='%s'\n", __func__, + priv->ret_data); + return -RIG_EPROTO; + } + + if (err != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__, + priv->ret_data); + return -RIG_EPROTO; + } + + rig_debug(RIG_DEBUG_TRACE, "%s: w=%d\n", __func__, w); } else { - rig_debug(RIG_DEBUG_ERR, "%s: unknown SH response='%s'\n", __func__, - priv->ret_data); - return -RIG_EPROTO; + // Some Yaesu rigs cannot query filter width using SH command in modes such as AM/FM + w = 0; } - if (err != RIG_OK) - { - rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__, - priv->ret_data); - return -RIG_EPROTO; - } - - rig_debug(RIG_DEBUG_TRACE, "%s: w=%d\n", __func__, w); - - // ft950 and ftdx1200 overlap so we'll combine them - if (is_ft950 || is_ftdx1200) + if (is_ft950) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { @@ -6666,42 +7157,30 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) switch (w) { case 0: - if (is_ft950) { *width = narrow ? 300 : 500; } - else { *width = narrow ? 500 : 2400; } // ft1200 - + *width = narrow ? 300 : 500; break; - case 1: *width = 50; break; // ft1200 only + case 3: *width = 100; break; - case 2: *width = 100; break; // ft1200 only + case 4: *width = 200; break; - case 3: *width = is_ft950 ? 100 : 150; break; + case 5: *width = 300; break; - case 4: *width = is_ft950 ? 200 : 200; break; + case 6: *width = 400; break; - case 5: *width = is_ft950 ? 300 : 250; break; + case 7: *width = 5000; break; - case 6: *width = is_ft950 ? 400 : 300; break; + case 8: *width = 800; break; - case 7: *width = is_ft950 ? 500 : 350; break; + case 9: *width = 1200; break; - case 8: *width = is_ft950 ? 800 : 400; break; + case 10: *width = 1400; break; - case 9: *width = is_ft950 ? 1200 : 450; break; + case 11: *width = 1700; break; - case 10: *width = is_ft950 ? 1400 : 500; break; + case 12: *width = 2000; break; - case 11: *width = is_ft950 ? 1700 : 800; break; - - case 12: *width = is_ft950 ? 2000 : 1200; break; - - case 13: *width = is_ft950 ? 2400 : 1400; break; - - case 14: *width = 1700; break; // 14+ is ft1200 only - - case 15: *width = 2000; break; - - case 16: *width = 2400; break; + case 13: *width = 2400; break; default: return -RIG_EINVAL; } @@ -6710,12 +7189,10 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) case RIG_MODE_LSB: case RIG_MODE_USB: - switch (w) // ft950 and ft1200 overlap + switch (w) { case 0: - if (is_ft950) { *width = narrow ? 1800 : 2400; } - else { *width = narrow ? 1500 : 2400; } // ft1200 - + *width = narrow ? 1800 : 2400; break; case 1: *width = 200; break; @@ -6758,34 +7235,30 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) case 20: *width = 3000; break; - // 21+ is for the FTDX1200 - case 21: *width = 3200; break; - - case 22: *width = 3400; break; - - case 23: *width = 3600; break; - - case 24: *width = 3800; break; - - case 25: *width = 4000; break; - - default: return -RIG_EINVAL; + default: + return -RIG_EINVAL; } - break; case RIG_MODE_AM: + *width = narrow ? 6000 : 9000; + break; + case RIG_MODE_PKTFM: case RIG_MODE_FM: - return RIG_OK; + *width = narrow ? 9000 : 16000; + break; + + case RIG_MODE_FMN: + *width = 9000; + break; default: return -RIG_EINVAL; } /* end switch(mode) */ - } /* end if FT950 FTDX1200 */ - - else if (newcat_is_rig(rig, RIG_MODEL_FT991)) + } /* end if is_ft950 */ + else if (is_ft891) { if ((narrow = get_narrow(rig, vfo)) < 0) { @@ -6803,9 +7276,14 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) switch (w) { case 0: - if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { *width = narrow ? 500 : 2400; } - else { *width = narrow ? 300 : 500; } - + if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) + { + *width = narrow ? 500 : 2400; + } + else + { + *width = narrow ? 300 : 500; + } break; case 1: *width = 50; break; @@ -6901,8 +7379,152 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) break; case RIG_MODE_AM: + case RIG_MODE_FMN: + *width = 9000; + break; + case RIG_MODE_AMN: - *width = 9000; break; + *width = 6000; + break; + + case RIG_MODE_FM: + case RIG_MODE_PKTFM: + *width = 16000; + break; + + default: + return -RIG_EINVAL; + } /* end switch(mode) */ + + } /* end if is_ft891 */ + else if (is_ft991) + { + if ((narrow = get_narrow(rig, vfo)) < 0) + { + return -RIG_EPROTO; + } + + switch (mode) + { + case RIG_MODE_PKTUSB: + case RIG_MODE_PKTLSB: + case RIG_MODE_RTTY: + case RIG_MODE_RTTYR: + case RIG_MODE_CW: + case RIG_MODE_CWR: + switch (w) + { + case 0: + if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) + { + *width = narrow ? 500 : 2400; + } + else + { + *width = narrow ? 300 : 500; + } + break; + + case 1: *width = 50; break; + + case 2: *width = 100; break; + + case 3: *width = 150; break; + + case 4: *width = 200; break; + + case 5: *width = 250; break; + + case 6: *width = 300; break; + + case 7: *width = 350; break; + + case 8: *width = 400; break; + + case 9: *width = 450; break; + + case 10: *width = 500; break; + + case 11: *width = 800; break; + + case 12: *width = 1200; break; + + case 13: *width = 1400; break; + + case 14: *width = 1700; break; + + case 15: *width = 2000; break; + + case 16: *width = 2400; break; + + case 17: *width = 3000; break; + + default: return -RIG_EINVAL; + } + + break; + + case RIG_MODE_LSB: + case RIG_MODE_USB: + switch (w) + { + case 0: *width = narrow ? 1500 : 2400; break; + + case 1: *width = 200; break; + + case 2: *width = 400; break; + + case 3: *width = 600; break; + + case 4: *width = 850; break; + + case 5: *width = 1100; break; + + case 6: *width = 1350; break; + + case 7: *width = 1500; break; + + case 8: *width = 1650; break; + + case 9: *width = 1800; break; + + case 10: *width = 1950; break; + + case 11: *width = 2100; break; + + case 12: *width = 2200; break; + + case 13: *width = 2300; break; + + case 14: *width = 2400; break; + + case 15: *width = 2500; break; + + case 16: *width = 2600; break; + + case 17: *width = 2700; break; + + case 18: *width = 2800; break; + + case 19: *width = 2900; break; + + case 20: *width = 3000; break; + + case 21: *width = 3200; break; + + default: return -RIG_EINVAL; + } + + break; + + case RIG_MODE_AM: + case RIG_MODE_FMN: + *width = 9000; + break; + + case RIG_MODE_AMN: + *width = 6000; + break; case RIG_MODE_FM: case RIG_MODE_C4FM: @@ -6914,9 +7536,295 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) return -RIG_EINVAL; } /* end switch(mode) */ - } + } /* end if is_ft991 */ + else if (is_ftdx1200 || is_ftdx3000) + { + if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) + { + return -RIG_EPROTO; + } - else if (newcat_is_rig(rig, RIG_MODEL_FTDX101D)) + switch (mode) + { + case RIG_MODE_PKTUSB: + case RIG_MODE_PKTLSB: + case RIG_MODE_RTTY: + case RIG_MODE_RTTYR: + case RIG_MODE_CW: + case RIG_MODE_CWR: + switch (w) + { + case 0: + *width = narrow ? 500 : 2400; + break; + + case 1: *width = 50; break; + + case 2: *width = 100; break; + + case 3: *width = 150; break; + + case 4: *width = 200; break; + + case 5: *width = 250; break; + + case 6: *width = 300; break; + + case 7: *width = 350; break; + + case 8: *width = 400; break; + + case 9: *width = 450; break; + + case 10: *width = 500; break; + + case 11: *width = 800; break; + + case 12: *width = 1200; break; + + case 13: *width = 1400; break; + + case 14: *width = 1700; break; + + case 15: *width = 2000; break; + + case 16: *width = 2400; break; + + default: return -RIG_EINVAL; + } + + break; + + case RIG_MODE_LSB: + case RIG_MODE_USB: + switch (w) + { + case 0: + *width = narrow ? 1500 : 2400; + break; + + case 1: *width = 200; break; + + case 2: *width = 400; break; + + case 3: *width = 600; break; + + case 4: *width = 850; break; + + case 5: *width = 1100; break; + + case 6: *width = 1350; break; + + case 7: *width = 1500; break; + + case 8: *width = 1650; break; + + case 9: *width = 1800; break; + + case 10: *width = 1950; break; + + case 11: *width = 2100; break; + + case 12: *width = 2250; break; + + case 13: *width = 2400; break; + + case 14: *width = 2450; break; + + case 15: *width = 2500; break; + + case 16: *width = 2600; break; + + case 17: *width = 2700; break; + + case 18: *width = 2800; break; + + case 19: *width = 2900; break; + + case 20: *width = 3000; break; + + case 21: *width = 3200; break; + + case 22: *width = 3400; break; + + case 23: *width = 3600; break; + + case 24: *width = 3800; break; + + case 25: *width = 4000; break; + + default: return -RIG_EINVAL; + } + + break; + + case RIG_MODE_AM: + *width = narrow ? 6000 : 9000; + break; + + case RIG_MODE_PKTFM: + case RIG_MODE_FM: + *width = narrow ? 9000 : 16000; + break; + + case RIG_MODE_FMN: + *width = 9000; + break; + + case RIG_MODE_AMN: + *width = 6000; + break; + + default: + return -RIG_EINVAL; + } /* end switch(mode) */ + + } /* end if is_ftdx1200 or is_ftdx3000 */ + else if (is_ftdx5000) + { + if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) + { + return -RIG_EPROTO; + } + + switch (mode) + { + case RIG_MODE_PKTUSB: + case RIG_MODE_PKTLSB: + case RIG_MODE_RTTY: + case RIG_MODE_RTTYR: + case RIG_MODE_CW: + case RIG_MODE_CWR: + switch (w) + { + case 0: + *width = narrow ? 500 : 2400; + break; + + case 1: *width = 50; break; + + case 2: *width = 100; break; + + case 3: *width = 150; break; + + case 4: *width = 200; break; + + case 5: *width = 250; break; + + case 6: *width = 300; break; + + case 7: *width = 350; break; + + case 8: *width = 400; break; + + case 9: *width = 450; break; + + case 10: *width = 500; break; + + case 11: *width = 800; break; + + case 12: *width = 1200; break; + + case 13: *width = 1400; break; + + case 14: *width = 1700; break; + + case 15: *width = 2000; break; + + case 16: *width = 2400; break; + + default: return -RIG_EINVAL; + } + + break; + + case RIG_MODE_LSB: + case RIG_MODE_USB: + switch (w) + { + case 0: + *width = narrow ? 1500 : 2400; + break; + + case 1: *width = 200; break; + + case 2: *width = 400; break; + + case 3: *width = 600; break; + + case 4: *width = 850; break; + + case 5: *width = 1100; break; + + case 6: *width = 1350; break; + + case 7: *width = 1500; break; + + case 8: *width = 1650; break; + + case 9: *width = 1800; break; + + case 10: *width = 1950; break; + + case 11: *width = 2100; break; + + case 12: *width = 2250; break; + + case 13: *width = 2400; break; + + // 14 is not defined for FTDX 5000, but leaving here for completeness + case 14: *width = 2400; break; + + case 15: *width = 2500; break; + + case 16: *width = 2600; break; + + case 17: *width = 2700; break; + + case 18: *width = 2800; break; + + case 19: *width = 2900; break; + + case 20: *width = 3000; break; + + case 21: *width = 3200; break; + + case 22: *width = 3400; break; + + case 23: *width = 3600; break; + + case 24: *width = 3800; break; + + case 25: *width = 4000; break; + + default: return -RIG_EINVAL; + } + + break; + + case RIG_MODE_AM: + *width = narrow ? 6000 : 9000; + break; + + case RIG_MODE_PKTFM: + case RIG_MODE_FM: + *width = narrow ? 9000 : 16000; + break; + + case RIG_MODE_FMN: + *width = 9000; + break; + + case RIG_MODE_AMN: + *width = 6000; + break; + + default: + return -RIG_EINVAL; + } /* end switch(mode) */ + + } /* end if is_ftdx5000 */ + else if (is_ftdx101) { rig_debug(RIG_DEBUG_TRACE, "%s: is_ftdx101 w=%d, mode=%s\n", __func__, w, rig_strrmode(mode)); @@ -6942,7 +7850,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) case RIG_MODE_CWR: switch (w) { - case 0: *width = 50; break; /* this is the default but 50 is probably wrong */ + case 0: break; /* use roofing filter width */ case 1: *width = 50; break; @@ -6989,7 +7897,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) case RIG_MODE_USB: switch (w) { - case 0: *width = 300; break; /* this is the default but 300 is probably wrong */ + case 0: break; /* use roofing filter width */ case 1: *width = 300; break; @@ -7047,14 +7955,17 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) case RIG_MODE_AM: case RIG_MODE_FMN: case RIG_MODE_PKTFMN: - *width = 9000; break; + *width = 9000; + break; case RIG_MODE_AMN: - *width = 6000; break; + *width = 6000; + break; case RIG_MODE_FM: case RIG_MODE_PKTFM: - *width = 16000; break; + *width = 16000; + break; default: rig_debug(RIG_DEBUG_TRACE, "%s: bad mode\n", __func__); @@ -7062,11 +7973,10 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) } /* end switch(mode) */ rig_debug(RIG_DEBUG_TRACE, "%s: end if FTDX101D\n", __func__); - - } /* end if FTDX101D */ - else /* end if FT991 */ + } /* end if is_ftdx101 */ + else { - /* FT450, FT2000, FT5000, FT9000 */ + /* FT450, FT2000, FT9000 */ switch (mode) { case RIG_MODE_PKTUSB: @@ -7089,7 +7999,6 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) { *width = rig_passband_normal(rig, mode); } - break; case RIG_MODE_AM: @@ -7100,7 +8009,7 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) default: return -RIG_EINVAL; } /* end switch (mode) */ - } /* end else */ + } /* end else */ rig_debug(RIG_DEBUG_TRACE, "%s: return RIG_OK\n", __func__); return RIG_OK; @@ -7464,18 +8373,25 @@ int newcat_get_cmd(RIG *rig) break; /* retry */ case '?': - if (priv->question_mark_response_means_rejected) - { - /* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */ - rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__, - priv->cmd_str); - return -RIG_ERJCTED; - } - - /* Rig busy wait please */ - rig_debug(RIG_DEBUG_ERR, "%s: Rig busy\n", __func__); - rc = -RIG_BUSBUSY; - break; /* retry read only */ + /* The ? response is ambiguous and undocumented by Yaesu, but for get commands it seems to + * indicate that the rig rejected the command because the state of the rig is not valid for the command + * or that the command parameter is invalid. Retrying the command does not fix the issue, + * as the error is caused by the an invalid combination of rig state. + * + * For example, the following cases have been observed: + * - MR and MC commands are rejected when referring to an _empty_ memory channel even + * if the channel number is in a valid range + * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are + * supported only in SSB/CW/RTTY modes + * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode + * + * There are many more cases like these and they vary by rig model. + * + * So far, "rig busy" type situations with the ? response have not been observed for get commands. + */ + rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig: '%s'\n", __func__, + priv->cmd_str); + return -RIG_ERJCTED; } continue; @@ -7595,10 +8511,25 @@ int newcat_set_cmd(RIG *rig) break; /* retry */ case '?': + /* The ? response is ambiguous and undocumented by Yaesu. For set commands it seems to indicate: + * 1) either that the rig is busy and the command needs to be retried + * 2) or that the rig rejected the command because the state of the rig is not valid for the command + * or that the command parameter is invalid. Retrying the command does not fix the issue + * in this case, as the error is caused by the an invalid combination of rig state. + * The latter case is consistent with behaviour of get commands. + * + * For example, the following cases have been observed: + * - MR and MC commands are rejected when referring to an _empty_ memory channel even + * if the channel number is in a valid range + * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are + * supported only in SSB/CW/RTTY modes + * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode + * + * There are many more cases like these and they vary by rig model. + */ if (priv->question_mark_response_means_rejected) { - /* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */ - rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__, + rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig: '%s'\n", __func__, priv->cmd_str); return -RIG_ERJCTED; } diff --git a/src/misc.c b/src/misc.c index b867c9f39..d4f5e6814 100644 --- a/src/misc.c +++ b/src/misc.c @@ -49,6 +49,7 @@ #endif #include <unistd.h> +#include <math.h> #include <hamlib/rig.h> #include <hamlib/amplifier.h> @@ -230,6 +231,48 @@ unsigned long long HAMLIB_API from_bcd_be(const unsigned char bcd_data[], return f; } +/** + * \brief Convert duration of one morse code dot (element) to milliseconds at the given speed. + * \param wpm morse code speed in words per minute + * \return double duration in milliseconds + * + * The morse code speed is calculated using the standard based on word PARIS. + * + * "If you send PARIS 5 times in a minute (5WPM) you have sent 250 elements (using correct spacing). + * 250 elements into 60 seconds per minute = 240 milliseconds per element." + * + * Source: http://kent-engineers.com/codespeed.htm + */ +double morse_code_dot_to_millis(int wpm) +{ + return 240.0 * (5.0 / (double) wpm); +} + +/** + * \brief Convert duration of tenths of morse code dots to milliseconds at the given speed. + * \param tenths_of_dots number of 1/10ths of dots + * \param wpm morse code speed in words per minute + * \return int duration in milliseconds + * + * The morse code speed is calculated using the standard based on word PARIS. + */ +int dot10ths_to_millis(int dot10ths, int wpm) +{ + return ceil(morse_code_dot_to_millis(wpm) * (double) dot10ths / 10.0); +} + +/** + * \brief Convert duration in milliseconds to tenths of morse code dots at the given speed. + * \param millis duration in milliseconds + * \param wpm morse code speed in words per minute + * \return int number of 1/10ths of dots + * + * The morse code speed is calculated using the standard based on word PARIS. + */ +int millis_to_dot10ths(int millis, int wpm) +{ + return ceil(millis / morse_code_dot_to_millis(wpm) * 10.0); +} //! @cond Doxygen_Suppress #ifndef llabs diff --git a/src/misc.h b/src/misc.h index 5378f1da7..de88ec683 100644 --- a/src/misc.h +++ b/src/misc.h @@ -72,6 +72,10 @@ extern HAMLIB_EXPORT(unsigned long long) from_bcd_be(const unsigned char bcd_data[], unsigned bcd_len); +extern HAMLIB_EXPORT(double) morse_code_dot_to_millis(int wpm); +extern HAMLIB_EXPORT(int) dot10ths_to_millis(int dot10ths, int wpm); +extern HAMLIB_EXPORT(int) millis_to_dot10ths(int millis, int wpm); + extern HAMLIB_EXPORT(int) sprintf_freq(char *str, freq_t); /* flag that determines if AI mode should be restored on exit on