From 12cc40f4f77c5dea54d03b39c8657e8a6038a05f Mon Sep 17 00:00:00 2001 From: Kenji Rikitake Date: Fri, 2 May 2025 12:58:33 +0000 Subject: [PATCH] Fix IC-705 filter selection and bandwidth handling for FM and WFM * Enable `.fm_filters` in `IC705_priv_caps` * `icom_get_mode_without_data()`: activate FM filter selection code if `RIG_IS_IC705` * `icom2rig_mode()`: activate FM filter fixed width code if `RIG_IS_IC705` * TODO: cases in WFM should be solved independently * `icom2rig_mode()`: handle FM and WFM separately and correctly at least for IC-705, no changes for IC-7300 and IC-9700 * `icom_get_mode_without_data()`: add WFM to the code assuming that values from `icom2rig_mode()` is correct * icom.c: A partial rollback for https://github.com/Hamlib/Hamlib/pull/1719/commits/a395b91be6bd19d760e57005ecb8079b15af9ede * The workaround to use `icom_set_mode_without_data()` is not necessary * The later experiments showed CI-V command 0x26 worked OK too for WFM * Add WFM freq to ic705_caps.filters * Fix icom_set_mode_x26() FM behavior `icom_set_mode_x26()` did not pass the correct command value for FM or PKTFM modes when width is set to `RIG_PASSBAND_NORMAL` (i.e., 0 (zero)). With this source code change, the command value `buf[2]` is forcefully set to 1 when `RIG_PASSBAND_NORMAL` or `RIG_PASSBAND_NOCHANGE` are passed to the parameter `width`. This fix solves the bug for IC-705 with rigctl when entering the command `M FM 0` after `M WFM 0` *did not* change the mode properly to (narrow) FM. --- rigs/icom/frame.c | 26 +++++++++++++++++++------- rigs/icom/ic7300.c | 4 +++- rigs/icom/icom.c | 44 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/rigs/icom/frame.c b/rigs/icom/frame.c index 09a2faddd..df2019e09 100644 --- a/rigs/icom/frame.c +++ b/rigs/icom/frame.c @@ -814,15 +814,27 @@ void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, rig_debug(RIG_DEBUG_TRACE, "%s: mode=0x%02x, pd=%d\n", __func__, md, pd); // Some rigs return fixed with for FM mode - if ((RIG_IS_IC7300 || RIG_IS_IC9700) && (md == S_FM || md == S_WFM)) - { - *mode = RIG_MODE_FM; + if (RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) { + if (md == S_FM) { + *mode = RIG_MODE_FM; - if (*width == 1) { *width = 15000; } - else if (*width == 2) { *width = 10000; } - else { *width = 7000; } + if (*width == 1) { *width = 15000; } + else if (*width == 2) { *width = 10000; } + else { *width = 7000; } - return; + return; + } else if (md == S_WFM) { + + // For IC-705, *width will always be 1 + // At least this works for IC-705 + + *mode = RIG_MODE_WFM; + *width = 200000; + + return; + } + // If not FM nor SFM mode, + // fall down this block for further processing } *width = RIG_PASSBAND_NORMAL; diff --git a/rigs/icom/ic7300.c b/rigs/icom/ic7300.c index a43939060..fe633a77e 100644 --- a/rigs/icom/ic7300.c +++ b/rigs/icom/ic7300.c @@ -637,7 +637,8 @@ static const struct icom_priv_caps IC705_priv_caps = .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, - .data_mode_supported = 1 + .data_mode_supported = 1, + .fm_filters = { 7000, 10000, 15000 } }; static const struct icom_priv_caps IC905_priv_caps = @@ -1498,6 +1499,7 @@ struct rig_caps ic705_caps = {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_MODE_WFM, kHz(200)}, RIG_FLT_END, }, diff --git a/rigs/icom/icom.c b/rigs/icom/icom.c index b55608983..71cd24eba 100644 --- a/rigs/icom/icom.c +++ b/rigs/icom/icom.c @@ -2441,6 +2441,22 @@ static int icom_set_mode_x26(RIG *rig, vfo_t vfo, rmode_t mode, if (width > 10000) { buf[2] = 1; } else if (width > 7000) { buf[2] = 2; } else if (width > 3) { buf[2] = 3; } + // Set "normal" bandwidth explicitly here + // when width is zero or even less + // (namely RIG_PASSBAND_NORMAL or RIG_PASSBAND_NOCHANGE) + else if (width < 1) { buf[2] = 1; } + + if (width == RIG_PASSBAND_NOCHANGE) + { + buf_len = 1; + } + } + else if (mode == RIG_MODE_WFM) + { + rig_debug(RIG_DEBUG_TRACE, "%s: wfm_width=%d\n", __func__, (int)width); + // For IC-705, there's only one filter mode for WFM + // So set always to 1 + buf[2] = 1; if (width == RIG_PASSBAND_NOCHANGE) { @@ -2574,9 +2590,7 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) (int) base_mode, (int) width, rig_strvfo(rs->current_vfo)); // It is only necessary to change base mode if command 0x26 is not supported - // NOTE: IC-705 does not support WFM for command 0x26 - if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap || - (RIG_IS_IC705 && (mode == RIG_MODE_WFM))) + if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { retval = icom_set_mode_without_data(rig, vfo, base_mode, width); } @@ -2625,8 +2639,8 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) if (datamode[0] == 0) { datamode[1] = 0; } // the only good combo possible according to manual // we need to let FM mode widths through here with datamode[1] set to FM width - if ((priv_caps->fm_filters[0] != 0) && (mode == RIG_MODE_FM - || mode == RIG_MODE_WFM)) + // (This is not applicable to WFM) + if ((priv_caps->fm_filters[0] != 0) && (mode == RIG_MODE_FM)) { // assumed fm_filters is ascending sequence -- see ic7300.c for example if (width >= 1 && width <= 3) { datamode[1] = width; } @@ -2653,6 +2667,13 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { if (datamode[0] == 0) { datamode[1] = 0; } + // For IC-705, this is the only valid values for WFM + if (RIG_IS_IC705 && (mode == RIG_MODE_WFM)) + { + datamode[0] = 0; + datamode[1] = 1; + } + retval = icom_set_mode_x26(rig, vfo, mode, mode_icom, datamode[0], datamode[1], width); } @@ -2816,8 +2837,8 @@ static int icom_get_mode_without_data(RIG *rig, vfo_t vfo, rmode_t *mode, mode_len == 2 ? modebuf[2] : -1, mode, width); } - if ((RIG_IS_IC7300 || RIG_IS_IC9700) && (*mode == RIG_MODE_FM - || *mode == RIG_MODE_PKTFM)) + if ((RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) && (*mode == RIG_MODE_FM + || *mode == RIG_MODE_PKTFM || *mode == RIG_MODE_WFM)) { // we already have width from icom2rig_mode RETURNFUNC2(RIG_OK); @@ -2849,7 +2870,7 @@ static int icom_get_mode_without_data(RIG *rig, vfo_t vfo, rmode_t *mode, if (vfo == rs->current_vfo) { - if (!((RIG_IS_IC7300 || RIG_IS_IC9700) && (*mode == RIG_MODE_FM + if (!((RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) && (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM))) // can't do this in FM mode { filter_width = icom_get_dsp_flt(rig, *mode); @@ -2872,13 +2893,18 @@ static int icom_get_mode_without_data(RIG *rig, vfo_t vfo, rmode_t *mode, { *width = 12000; // some default to 12000 - if (RIG_IS_IC7300 || RIG_IS_IC9700) + if (RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) { if (priv_data->filter == 1) { *width = 15000; } else if (priv_data->filter == 2) { *width = 10000; } else if (priv_data->filter == 3) { *width = 7000; } } } + else if (*mode == RIG_MODE_WFM) + { + // IC-705 only valid value + if (RIG_IS_IC705) { *width = 200000; } + } RETURNFUNC2(RIG_OK); }