[chirp_devel] [PATCH] [icomciv] Restructuring of IcomCIVRadio radio classes; breakout each radio into its own module in preparetion for simplifying support for upcomming CIV feature #4547
Kosta Arvanitis
Fri Apr 30 13:23:15 PDT 2021
Thanks for the feedback Martin, please see my responses inline below. I
remain open to suggestions and feedback.
On Fri, Apr 30, 2021 at 10:51 AM Martin Cooper <mfncooper at gmail.com> wrote:
> This patch actually combines two distinct changes:
>
> 1) Changing the way probe_model() works to enumerate the global driver
> list instead of the local model list. This would have been a trivial change
> in and of itself, and is unrelated to the refactoring. Presumably this
> change is somehow necessitated by your approach to #4547, but it's not at
> all clear that it's a meaningful change. If it's needed at all, I would
> think it might make more sense as a part of the patch for #4547, and not as
> part of an unrelated refactoring.
>
This change is precipitated by the requirement to support configurable
civ's (#4547) such that we are no longer able to hard code these values
into the code base. While I agree that it would be ideal to not include it
as part of the refactoring effort, so as to reduce its scope, the
refactoring itself would introduce a circular dependency on the hard coded
classes and thus makes it a requirement of this change. The directory
method fwiw, is a fairly common practice in the codebase as it stands.
https://chirp.danplanet.com/projects/chirp/repository/entry/chirp/detect.py#L104
>
> 2) The splitting up of the classes. Without seeing how you intend to
> implement #4547, it is hard to see how this huge change could simplify
> anything.
>
The intent of this change is to reduce potential conflicts amongst
developers working on similar radio models. Currently there are multiple
implementations of icom live mode radios being introduced into the code
base - this change should minimize the scope of those changes making it i)
easier to develop and ii) reducing merge conflicts and iii) easier to test.
https://chirp.danplanet.com/issues/8431
https://chirp.danplanet.com/issues/8987
Another outcome of this change is to allow for a clear isolation of radio
specific implementation details from the base class, thus reducing the
potential for knock on effects from a developer introducing a new radio
model while unknowingly breaking another.
The root of the impending changes to support #4547 stems from the current
implementation of how CIV values are handled, in that they are currently
implemented as static variables and will need to become class variables.
As this is a significant deviation to the implementation of the base
IcomCIVRadio class, this change will allow for the development of specific
radio models mentioned above to continue unimpeded by that work.
> Most importantly, this change means the loss of history for all of the
> drivers currently in icomciv.py insofar as someone would have to know to
> look at the history of that module in order to find any history at all for
> all of the drivers being split out from here.
>
This particular situation arises anytime new source files are introduced
into the code base; there is however precedence for this type of change on
this code base, for example:
https://chirp.danplanet.com/projects/chirp/repository/revisions/d135e492dfa3
.
In our particular situation the history is not lost as in the previous
revision. In fact, the icomciv.py file is retained in the repo along with
its history.
I just don't see a good reason to make this change.
>
>
Every one of us is welcome to an opinion, in my own personal view I simply
find that the separation of implementation classes from their inherited
base class to be cleaner and good programming practice which in the long
run creates for a healthier code base and development experience overall.
In this case however the intent was not imposed merely for aesthetic
reasons but rather to avoid conflict and allow for concurrent development
to take place moving forward. Given the scope of the changed code itself is
relatively small I see a small risk impact.
> Personally, I would prefer to not see this patch applied at least until we
> understand why it might be helpful to the upcoming changes for #4547, since
> I just don't see the justification right now.
>
> Martin.
> KD6YAM
>
> On Fri, Apr 30, 2021 at 9:42 AM Kosta A. via chirp_devel <
> chirp_devel at intrepid.danplanet.com> wrote:
>
>> # HG changeset patch
>> # User Kosta A. <ve7kcy at gmail.com>
>> # Date 1619800737 25200
>> # Fri Apr 30 09:38:57 2021 -0700
>> # Node ID 941a95de942d7c263a6197bf115cc75bc3624de9
>> # Parent cd3e2444040876b4a19b41c6cfecedb79ff4a8fe
>> [icomciv] Restructuring of IcomCIVRadio radio classes; breakout each
>> radio into its own module in preparetion for simplifying support for
>> upcomming CIV feature #4547.
>>
>> diff --git a/chirp/drivers/ic7000.py b/chirp/drivers/ic7000.py
>> new file mode 100644
>> --- /dev/null
>> +++ b/chirp/drivers/ic7000.py
>> @@ -0,0 +1,84 @@
>> +# Copyright 2008 Dan Smith <dsmith at danplanet.com>
>> +#
>> +# This program is free software: you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation, either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +
>> +import struct
>> +import logging
>> +
>> +from chirp import chirp_common, errors, directory
>> +from chirp.drivers import icf, icomciv
>> +
>> +LOG = logging.getLogger(__name__)
>> +
>> +# http://www.vk4adc.com/
>> +# web/index.php/reference-information/49-general-ref-info/182-civ7400
>> +MEM_IC7000_FORMAT = """
>> +u8 bank;
>> +bbcd number[2];
>> +u8 spl:4,
>> + skip:4;
>> +lbcd freq[5];
>> +u8 mode;
>> +u8 filter;
>> +u8 duplex:4,
>> + tmode:4;
>> +bbcd rtone[3];
>> +bbcd ctone[3];
>> +u8 dtcs_polarity;
>> +bbcd dtcs[2];
>> +lbcd freq_tx[5];
>> +u8 mode_tx;
>> +u8 filter_tx;
>> +u8 duplex_tx:4,
>> + tmode_tx:4;
>> +bbcd rtone_tx[3];
>> +bbcd ctone_tx[3];
>> +u8 dtcs_polarity_tx;
>> +bbcd dtcs_tx[2];
>> +char name[9];
>> +"""
>> +
>> +class IC7000MemFrame(icomciv.BankMemFrame):
>> + FORMAT = MEM_IC7000_FORMAT
>> +
>> + at directory.register
>> +class Icom7000Radio(icomciv.IcomCIVRadio):
>> + """Icom IC-7000"""
>> + MODEL = "IC-7000"
>> + _model = "\x70"
>> + _template = 102
>> +
>> + _num_banks = 5 # Banks A-E
>> + _bank_index_bounds = (1, 99)
>> + _bank_class = icf.IcomBank
>> +
>> + def _initialize(self):
>> + self._classes["mem"] = IC7000MemFrame
>> + self._rf.has_bank = True
>> + self._rf.has_dtcs_polarity = True
>> + self._rf.has_dtcs = True
>> + self._rf.has_ctone = True
>> + self._rf.has_offset = True
>> + self._rf.has_name = True
>> + self._rf.has_tuning_step = False
>> + self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY", "FM",
>> "WFM"]
>> + self._rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
>> + self._rf.valid_duplexes = ["", "-", "+", "split"]
>> + self._rf.valid_bands = [(30000, 199999999), (400000000,
>> 470000000)]
>> + self._rf.valid_tuning_steps = []
>> + self._rf.valid_skips = ["S", ""]
>> + self._rf.valid_name_length = 9
>> + self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> + self._rf.memory_bounds = (0, 99 * self._num_banks - 1)
>> + self._rf.can_odd_split = True
>> diff --git a/chirp/drivers/ic7100.py b/chirp/drivers/ic7100.py
>> new file mode 100644
>> --- /dev/null
>> +++ b/chirp/drivers/ic7100.py
>> @@ -0,0 +1,88 @@
>> +# Copyright 2008 Dan Smith <dsmith at danplanet.com>
>> +#
>> +# This program is free software: you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation, either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +
>> +import struct
>> +import logging
>> +
>> +from chirp import chirp_common, errors, directory
>> +from chirp.drivers import icf, icomciv
>> +
>> +LOG = logging.getLogger(__name__)
>> +
>> +
>> +MEM_IC7100_FORMAT = """
>> +u8 bank; // 1 bank number
>> +bbcd number[2]; // 2,3
>> +u8 splitSelect; // 4 split and select memory settings
>> +lbcd freq[5]; // 5-9 operating freq
>> +u8 mode; // 10 operating mode
>> +u8 filter; // 11 filter
>> +u8 dataMode; // 12 data mode setting (on or off)
>> +u8 duplex:4, // 13 duplex on/-/+
>> + tmode:4; // 13 tone
>> +u8 dsql:4, // 14 digital squelch
>> + unknown1:4; // 14 zero
>> +bbcd rtone[3]; // 15-17 repeater tone freq
>> +bbcd ctone[3]; // 18-20 tone squelch setting
>> +u8 dtcsPolarity; // 21 DTCS polarity
>> +u8 unknown2:4, // 22 zero
>> + firstDtcs:4; // 22 first digit of DTCS code
>> +u8 secondDtcs:4, // 23 second digit DTCS
>> + thirdDtcs:4; // 23 third digit DTCS
>> +u8 digitalSquelch; // 24 Digital code squelch setting
>> +lbcd duplexOffset[3]; // 25-27 duplex offset freq
>> +char destCall[8]; // 28-35 destination call sign
>> +char accessRepeaterCall[8];// 36-43 access repeater call sign
>> +char linkRepeaterCall[8]; // 44-51 gateway/link repeater call sign
>> +bbcd duplexSettings[47]; // repeat of 5-51 for duplex
>> +char name[16]; // 52-60 Name of station
>> +"""
>> +
>> +class IC7100MemFrame(icomciv.BankMemFrame):
>> + FORMAT = MEM_IC7100_FORMAT
>> +
>> + at directory.register
>> +class Icom7100Radio(icomciv.IcomCIVRadio):
>> + """Icom IC-7100"""
>> + MODEL = "IC-7100"
>> + _model = "\x88"
>> + _template = 102
>> +
>> + _num_banks = 5
>> + _bank_index_bounds = (1, 99)
>> + _bank_class = icf.IcomBank
>> +
>> + def _initialize(self):
>> + self._classes["mem"] = IC7100MemFrame
>> + self._rf.has_bank = True
>> + self._rf.has_bank_index = False
>> + self._rf.has_bank_names = False
>> + self._rf.has_dtcs_polarity = False
>> + self._rf.has_dtcs = False
>> + self._rf.has_ctone = True
>> + self._rf.has_offset = False
>> + self._rf.has_name = True
>> + self._rf.has_tuning_step = False
>> + self._rf.valid_modes = [
>> + "LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", "CWR",
>> "RTTYR", "DV"
>> + ]
>> + self._rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
>> + self._rf.valid_duplexes = ["", "-", "+"]
>> + self._rf.valid_bands = [(30000, 199999999), (400000000,
>> 470000000)]
>> + self._rf.valid_tuning_steps = []
>> + self._rf.valid_skips = []
>> + self._rf.valid_name_length = 16
>> + self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> + self._rf.memory_bounds = (0, 99 * self._num_banks - 1)
>> diff --git a/chirp/drivers/ic7200.py b/chirp/drivers/ic7200.py
>> new file mode 100644
>> --- /dev/null
>> +++ b/chirp/drivers/ic7200.py
>> @@ -0,0 +1,48 @@
>> +# Copyright 2008 Dan Smith <dsmith at danplanet.com>
>> +#
>> +# This program is free software: you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation, either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +
>> +import struct
>> +import logging
>> +
>> +from chirp import chirp_common, errors, directory
>> +from chirp.drivers import icf, icomciv
>> +
>> +LOG = logging.getLogger(__name__)
>> +
>> +
>> + at directory.register
>> +class Icom7200Radio(icomciv.IcomCIVRadio):
>> + """Icom IC-7200"""
>> + MODEL = "7200"
>> + _model = "\x76"
>> + _template = 201
>> +
>> + _num_banks = 1 # Banks not supported
>> +
>> + def _initialize(self):
>> + self._rf.has_bank = False
>> + self._rf.has_dtcs_polarity = False
>> + self._rf.has_dtcs = False
>> + self._rf.has_ctone = False
>> + self._rf.has_offset = False
>> + self._rf.has_name = False
>> + self._rf.has_tuning_step = False
>> + self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY",
>> + "CWR", "RTTYR"]
>> + self._rf.valid_tmodes = []
>> + self._rf.valid_duplexes = []
>> + self._rf.valid_bands = [(30000, 60000000)]
>> + self._rf.valid_skips = []
>> + self._rf.memory_bounds = (1, 201)
>> diff --git a/chirp/drivers/ic7300.py b/chirp/drivers/ic7300.py
>> new file mode 100644
>> --- /dev/null
>> +++ b/chirp/drivers/ic7300.py
>> @@ -0,0 +1,103 @@
>> +# Copyright 2008 Dan Smith <dsmith at danplanet.com>
>> +#
>> +# This program is free software: you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation, either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +
>> +import struct
>> +import logging
>> +
>> +from chirp import chirp_common, errors, directory
>> +from chirp.drivers import icf, icomciv
>> +
>> +LOG = logging.getLogger(__name__)
>> +
>> +
>> +MEM_IC7300_FORMAT = """
>> +bbcd number[2]; // 1,2
>> +u8 spl:4, // 3 split and select memory settings
>> + select:4;
>> +lbcd freq[5]; // 4-8 receive freq
>> +u8 mode; // 9 operating mode
>> +u8 filter; // 10 filter 1-3 (undocumented)
>> +u8 dataMode:4, // 11 data mode setting (on or off)
>> + tmode:4; // 11 tone type
>> +char pad1;
>> +bbcd rtone[2]; // 12-14 tx tone freq
>> +char pad2;
>> +bbcd ctone[2]; // 15-17 tone rx squelch setting
>> +lbcd freq_tx[5]; // 4-8 transmit freq
>> +u8 mode_tx; // 9 tx operating mode
>> +u8 filter_tx; // 10
>> +u8 dataMode_tx:4, // 11 tx data mode setting (on or off)
>> + tmode_tx:4; // 11 tx tone type
>> +char pad3;
>> +bbcd rtone_tx[2]; // 12-14 repeater tone freq
>> +char pad4;
>> +bbcd ctone_tx[2]; // 15-17 tone squelch setting
>> +char name[10]; // 18-27 Callsign
>> +"""
>> +
>> +class IC7300MemFrame(icomciv.MemFrame):
>> + FORMAT = MEM_IC7300_FORMAT
>> +
>> + at directory.register
>> +class Icom7300Radio(icomciv.IcomCIVRadio):
>> + """Icom IC-7300"""
>> + MODEL = "IC-7300"
>> + _model = "\x94"
>> + _template = 100 # Use P1 as blank template
>> +
>> + _SPECIAL_CHANNELS = {
>> + "P1": 100,
>> + "P2": 101,
>> + }
>> + _SPECIAL_CHANNELS_REV = dict(zip(_SPECIAL_CHANNELS.values(),
>> + _SPECIAL_CHANNELS.keys()))
>> +
>> + def _is_special(self, number):
>> + return number > 99 or isinstance(number, str)
>> +
>> + def _get_special_info(self, number):
>> + info = SpecialChannel()
>> + if isinstance(number, str):
>> + info.name = number
>> + info.channel = self._SPECIAL_CHANNELS[number]
>> + info.location = info.channel
>> + else:
>> + info.location = number
>> + info.name = self._SPECIAL_CHANNELS_REV[number]
>> + info.channel = info.location
>> + return info
>> +
>> + def _initialize(self):
>> + self._classes["mem"] = IC7300MemFrame
>> + self._rf.has_name = True
>> + self._rf.has_dtcs = False
>> + self._rf.has_dtcs_polarity = False
>> + self._rf.has_bank = False
>> + self._rf.has_tuning_step = False
>> + self._rf.has_nostep_tuning = True
>> + self._rf.can_odd_split = True
>> + self._rf.memory_bounds = (1, 99)
>> + self._rf.valid_modes = [
>> + "LSB", "USB", "AM", "CW", "RTTY", "FM", "CWR", "RTTYR",
>> + "Data+LSB", "Data+USB", "Data+AM", "N/A", "N/A", "Data+FM"
>> + ]
>> + self._rf.valid_tmodes = ["", "Tone", "TSQL"]
>> + # self._rf.valid_duplexes = ["", "-", "+", "split"]
>> + self._rf.valid_duplexes = [] # To prevent using memobj.duplex
>> + self._rf.valid_bands = [(1800000, 70500000)]
>> + self._rf.valid_skips = []
>> + self._rf.valid_name_length = 10
>> + self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> + self._rf.valid_special_chans =
>> sorted(self._SPECIAL_CHANNELS.keys())
>> diff --git a/chirp/drivers/ic746.py b/chirp/drivers/ic746.py
>> new file mode 100644
>> --- /dev/null
>> +++ b/chirp/drivers/ic746.py
>> @@ -0,0 +1,76 @@
>> +# Copyright 2008 Dan Smith <dsmith at danplanet.com>
>> +#
>> +# This program is free software: you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation, either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +
>> +import struct
>> +import logging
>> +
>> +from chirp import chirp_common, errors, directory
>> +from chirp.drivers import icf, icomciv
>> +
>> +LOG = logging.getLogger(__name__)
>> +
>> +
>> +MEM_IC746_FORMAT = """
>> +bbcd number[2];
>> +u8 unknown1;
>> +lbcd freq[5];
>> +u8 unknown2:5,
>> + mode:3;
>> +u8 unknown1;
>> +u8 unknown2:2,
>> + duplex:2,
>> + unknown3:1,
>> + tmode:3;
>> +u8 unknown4;
>> +bbcd rtone[2];
>> +u8 unknown5;
>> +bbcd ctone[2];
>> +u8 dtcs_polarity;
>> +bbcd dtcs[2];
>> +u8 unknown[11];
>> +char name[9];
>> +"""
>> +
>> +class IC746MemFrame(icomciv.MemFrame):
>> + FORMAT = MEM_IC746_FORMAT
>> +
>> + at directory.register
>> +class Icom746Radio(icomciv.IcomCIVRadio):
>> + """Icom IC-746"""
>> + MODEL = "746"
>> + BAUD_RATE = 9600
>> + _model = "\x56"
>> + _template = 102
>> +
>> + _num_banks = 1 # Banks not supported
>> +
>> + def _initialize(self):
>> + self._classes["mem"] = IC746MemFrame
>> + self._rf.has_bank = False
>> + self._rf.has_dtcs_polarity = False
>> + self._rf.has_dtcs = False
>> + self._rf.has_ctone = True
>> + self._rf.has_offset = False
>> + self._rf.has_name = True
>> + self._rf.has_tuning_step = False
>> + self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY", "FM"]
>> + self._rf.valid_tmodes = ["", "Tone", "TSQL"]
>> + self._rf.valid_duplexes = ["", "-", "+"]
>> + self._rf.valid_bands = [(30000, 199999999)]
>> + self._rf.valid_tuning_steps = []
>> + self._rf.valid_skips = []
>> + self._rf.valid_name_length = 9
>> + self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> + self._rf.memory_bounds = (1, 99)
>> diff --git a/chirp/drivers/ic910.py b/chirp/drivers/ic910.py
>> new file mode 100644
>> --- /dev/null
>> +++ b/chirp/drivers/ic910.py
>> @@ -0,0 +1,142 @@
>> +# Copyright 2008 Dan Smith <dsmith at danplanet.com>
>> +#
>> +# This program is free software: you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation, either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +
>> +import struct
>> +import logging
>> +
>> +from chirp import chirp_common, errors, directory
>> +from chirp.drivers import icf, icomciv
>> +
>> +LOG = logging.getLogger(__name__)
>> +
>> +
>> +MEM_IC910_FORMAT = """
>> +u8 bank; // 1 bank number
>> +bbcd number[2]; // 2,3
>> +lbcd freq[5]; // 4-8 operating freq
>> +u8 mode; // 9 operating mode
>> +u8 filter; // 10 filter
>> +u8 tmode:4, // 11 tone
>> + duplex:4; // 11 duplex off/-/+
>> +bbcd rtone[3]; // 12-14 repeater tone freq
>> +bbcd ctone[3]; // 15-17 tone squelch setting
>> +lbcd duplexOffset[3]; // 18-20 duplex offset freq
>> +"""
>> +
>> +class IC910MemFrame(icomciv.BankMemFrame):
>> + FORMAT = MEM_IC910_FORMAT
>> +
>> + at directory.register
>> +class Icom910Radio(icomciv.IcomCIVRadio):
>> + """Icom IC-910"""
>> + MODEL = "IC-910"
>> + BAUD_RATE = 19200
>> + _model = "\x60"
>> + _template = 100
>> +
>> + _num_banks = 3 # Banks for 2m, 70cm, 23cm
>> + _bank_index_bounds = (1, 99)
>> + _bank_class = icf.IcomBank
>> +
>> + _SPECIAL_CHANNELS = {
>> + "1A": 100,
>> + "1b": 101,
>> + "2A": 102,
>> + "2b": 103,
>> + "3A": 104,
>> + "3b": 105,
>> + "C": 106,
>> + }
>> + _SPECIAL_CHANNELS_REV = {v: k for k, v in _SPECIAL_CHANNELS.items()}
>> +
>> + _SPECIAL_BANKS = {
>> + "2m": 1,
>> + "70cm": 2,
>> + "23cm": 3,
>> + }
>> + _SPECIAL_BANKS_REV = {v: k for k, v in _SPECIAL_BANKS.items()}
>> +
>> + def _get_special_names(self, band):
>> + return sorted([band + "-" + key
>> + for key in self._SPECIAL_CHANNELS.keys()])
>> +
>> + def _is_special(self, number):
>> + return number >= 1000 or isinstance(number, str)
>> +
>> + def _get_special_info(self, number):
>> + info = BankSpecialChannel()
>> + if isinstance(number, str):
>> + info.name = number
>> + (band_name, chan_name) = number.split("-")
>> + info.bank = self._SPECIAL_BANKS[band_name]
>> + info.channel = self._SPECIAL_CHANNELS[chan_name]
>> + info.location = info.bank * 1000 + info.channel
>> + else:
>> + info.location = number
>> + (info.bank, info.channel) = divmod(number, 1000)
>> + band_name = self._SPECIAL_BANKS_REV[info.bank]
>> + chan_name = self._SPECIAL_CHANNELS_REV[info.channel]
>> + info.name = band_name + "-" + chan_name
>> + return info
>> +
>> + # The IC-910 has a bank of memories for each band. The 23cm band is
>> only
>> + # available when the optional UX-910 unit is installed, but there is
>> no
>> + # direct means of detecting its presence. Instead, attempt to access
>> the
>> + # first memory in the 23cm bank. If that's successful, the unit is
>> there,
>> + # and we can present all 3 banks to the user. Otherwise, the unit is
>> not
>> + # installed, so we present 2 banks to the user, for 2m and 70cm.
>> + def _detect_23cm_unit(self):
>> + if not self.pipe:
>> + return True
>> + f = IC910MemFrame()
>> + f.set_location(1, 3) # First memory in 23cm bank
>> + self._send_frame(f)
>> + f.read(self.pipe)
>> + if f._cmd == 0xFA: # Error code lands in command field
>> + self._num_banks = 2
>> + LOG.debug("UX-910 unit is %sinstalled" %
>> + ("not " if self._num_banks == 2 else ""))
>> + return self._num_banks == 3
>> +
>> + def _initialize(self):
>> + self._classes["mem"] = IC910MemFrame
>> + self._has_23cm_unit = self._detect_23cm_unit()
>> + self._rf.has_bank = True
>> + self._rf.has_dtcs_polarity = False
>> + self._rf.has_dtcs = False
>> + self._rf.has_ctone = True
>> + self._rf.has_offset = True
>> + self._rf.has_name = False
>> + self._rf.has_tuning_step = False
>> + self._rf.valid_modes = ["LSB", "USB", "CW", "NCW", "FM", "NFM"]
>> + self._rf.valid_tmodes = ["", "Tone", "TSQL"]
>> + self._rf.valid_duplexes = ["", "-", "+"]
>> + self._rf.valid_bands = [(136000000, 174000000),
>> + (420000000, 480000000)]
>> + self._rf.valid_tuning_steps = []
>> + self._rf.valid_skips = []
>> + self._rf.valid_special_chans = (self._get_special_names("2m") +
>> + self._get_special_names("70cm"))
>> + self._rf.memory_bounds = (1, 99 * self._num_banks)
>> +
>> + if self._has_23cm_unit:
>> + self._rf.valid_bands.append((1240000000, 1320000000))
>> + self._rf.valid_special_chans +=
>> self._get_special_names("23cm")
>> +
>> + # Combine mode and filter into unified mode
>> + self._unified_modes = True
>> +
>> + # Use Chirp locations starting with 1
>> + self._adjust_bank_loc_start = True
>> diff --git a/chirp/drivers/icomciv.py b/chirp/drivers/icomciv.py
>> --- a/chirp/drivers/icomciv.py
>> +++ b/chirp/drivers/icomciv.py
>> @@ -1,6 +1,21 @@
>> -# Latest update: March, 2021 RJ DeWitt added IC-7300
>> +# Copyright 2008 Dan Smith <dsmith at danplanet.com>
>> +#
>> +# This program is free software: you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation, either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
>> +
>> import struct
>> import logging
>> +
>> from chirp.drivers import icf
>> from chirp import chirp_common, util, errors, bitwise, directory
>> from chirp.memmap import MemoryMap
>> @@ -23,122 +38,6 @@
>> unknown_2:4;
>> """
>>
>> -
>> -# http://www.vk4adc.com/
>> -# web/index.php/reference-information/49-general-ref-info/182-civ7400
>> -MEM_IC7000_FORMAT = """
>> -u8 bank;
>> -bbcd number[2];
>> -u8 spl:4,
>> - skip:4;
>> -lbcd freq[5];
>> -u8 mode;
>> -u8 filter;
>> -u8 duplex:4,
>> - tmode:4;
>> -bbcd rtone[3];
>> -bbcd ctone[3];
>> -u8 dtcs_polarity;
>> -bbcd dtcs[2];
>> -lbcd freq_tx[5];
>> -u8 mode_tx;
>> -u8 filter_tx;
>> -u8 duplex_tx:4,
>> - tmode_tx:4;
>> -bbcd rtone_tx[3];
>> -bbcd ctone_tx[3];
>> -u8 dtcs_polarity_tx;
>> -bbcd dtcs_tx[2];
>> -char name[9];
>> -"""
>> -
>> -MEM_IC7100_FORMAT = """
>> -u8 bank; // 1 bank number
>> -bbcd number[2]; // 2,3
>> -u8 splitSelect; // 4 split and select memory settings
>> -lbcd freq[5]; // 5-9 operating freq
>> -u8 mode; // 10 operating mode
>> -u8 filter; // 11 filter
>> -u8 dataMode; // 12 data mode setting (on or off)
>> -u8 duplex:4, // 13 duplex on/-/+
>> - tmode:4; // 13 tone
>> -u8 dsql:4, // 14 digital squelch
>> - unknown1:4; // 14 zero
>> -bbcd rtone[3]; // 15-17 repeater tone freq
>> -bbcd ctone[3]; // 18-20 tone squelch setting
>> -u8 dtcsPolarity; // 21 DTCS polarity
>> -u8 unknown2:4, // 22 zero
>> - firstDtcs:4; // 22 first digit of DTCS code
>> -u8 secondDtcs:4, // 23 second digit DTCS
>> - thirdDtcs:4; // 23 third digit DTCS
>> -u8 digitalSquelch; // 24 Digital code squelch setting
>> -lbcd duplexOffset[3]; // 25-27 duplex offset freq
>> -char destCall[8]; // 28-35 destination call sign
>> -char accessRepeaterCall[8];// 36-43 access repeater call sign
>> -char linkRepeaterCall[8]; // 44-51 gateway/link repeater call sign
>> -bbcd duplexSettings[47]; // repeat of 5-51 for duplex
>> -char name[16]; // 52-60 Name of station
>> -"""
>> -
>> -MEM_IC910_FORMAT = """
>> -u8 bank; // 1 bank number
>> -bbcd number[2]; // 2,3
>> -lbcd freq[5]; // 4-8 operating freq
>> -u8 mode; // 9 operating mode
>> -u8 filter; // 10 filter
>> -u8 tmode:4, // 11 tone
>> - duplex:4; // 11 duplex off/-/+
>> -bbcd rtone[3]; // 12-14 repeater tone freq
>> -bbcd ctone[3]; // 15-17 tone squelch setting
>> -lbcd duplexOffset[3]; // 18-20 duplex offset freq
>> -"""
>> -
>> -mem_duptone_format = """
>> -bbcd number[2];
>> -u8 unknown1;
>> -lbcd freq[5];
>> -u8 unknown2:5,
>> - mode:3;
>> -u8 unknown1;
>> -u8 unknown2:2,
>> - duplex:2,
>> - unknown3:1,
>> - tmode:3;
>> -u8 unknown4;
>> -bbcd rtone[2];
>> -u8 unknown5;
>> -bbcd ctone[2];
>> -u8 dtcs_polarity;
>> -bbcd dtcs[2];
>> -u8 unknown[11];
>> -char name[9];
>> -"""
>> -
>> -MEM_IC7300_FORMAT = """
>> -bbcd number[2]; // 1,2
>> -u8 spl:4, // 3 split and select memory settings
>> - select:4;
>> -lbcd freq[5]; // 4-8 receive freq
>> -u8 mode; // 9 operating mode
>> -u8 filter; // 10 filter 1-3 (undocumented)
>> -u8 dataMode:4, // 11 data mode setting (on or off)
>> - tmode:4; // 11 tone type
>> -char pad1;
>> -bbcd rtone[2]; // 12-14 tx tone freq
>> -char pad2;
>> -bbcd ctone[2]; // 15-17 tone rx squelch setting
>> -lbcd freq_tx[5]; // 4-8 transmit freq
>> -u8 mode_tx; // 9 tx operating mode
>> -u8 filter_tx; // 10
>> -u8 dataMode_tx:4, // 11 tx data mode setting (on or off)
>> - tmode_tx:4; // 11 tx tone type
>> -char pad3;
>> -bbcd rtone_tx[2]; // 12-14 repeater tone freq
>> -char pad4;
>> -bbcd ctone_tx[2]; // 15-17 tone squelch setting
>> -char name[10]; // 18-27 Callsign
>> -"""
>> -
>> SPLIT = ["", "spl"]
>>
>>
>> @@ -207,6 +106,7 @@
>>
>> class MemFrame(Frame):
>> """A memory frame"""
>> + FORMAT = MEM_FORMAT
>> _cmd = 0x1A
>> _sub = 0x00
>> _loc = 0
>> @@ -227,7 +127,7 @@
>> def get_obj(self):
>> """Return a bitwise parsed object"""
>> self._data = MemoryMap(str(self._data)) # Make sure we're
>> assignable
>> - return bitwise.parse(MEM_FORMAT, self._data)
>> + return bitwise.parse(self.FORMAT, self._data)
>>
>> def initialize(self):
>> """Initialize to sane values"""
>> @@ -236,7 +136,7 @@
>>
>> class BankMemFrame(MemFrame):
>> """A memory frame for radios with multiple banks"""
>> - FORMAT = MEM_IC7000_FORMAT
>> + FORMAT = None
>> _bnk = 0
>>
>> def set_location(self, loc, bank=1):
>> @@ -256,28 +156,6 @@
>> return bitwise.parse(self.FORMAT, self._data)
>>
>>
>> -class IC7100MemFrame(BankMemFrame):
>> - FORMAT = MEM_IC7100_FORMAT
>> -
>> -
>> -class IC910MemFrame(BankMemFrame):
>> - FORMAT = MEM_IC910_FORMAT
>> -
>> -
>> -class DupToneMemFrame(MemFrame):
>> - def get_obj(self):
>> - self._data = MemoryMap(str(self._data))
>> - return bitwise.parse(mem_duptone_format, self._data)
>> -
>> -
>> -class IC7300MemFrame(MemFrame):
>> - FORMAT = MEM_IC7300_FORMAT
>> -
>> - def get_obj(self):
>> - self._data = MemoryMap(str(self._data))
>> - return bitwise.parse(self.FORMAT, self._data)
>> -
>> -
>> class SpecialChannel(object):
>> """Info for special (named) channels"""
>>
>> @@ -442,10 +320,10 @@
>> else:
>> return repr(f.get_obj())
>>
>> -# We have a simple mapping between the memory location in the frequency
>> -# editor and (bank, channel) of the radio. The mapping doesn't
>> -# change so we use a little math to calculate what bank a location
>> -# is in. We can't change the bank a location is in so we just pass.
>> + # We have a simple mapping between the memory location in the
>> frequency
>> + # editor and (bank, channel) of the radio. The mapping doesn't
>> + # change so we use a little math to calculate what bank a location
>> + # is in. We can't change the bank a location is in so we just pass.
>> def _get_bank(self, loc):
>> if self._adjust_bank_loc_start:
>> loc -= 1
>> @@ -562,6 +440,8 @@
>>
>> if self._rf.can_odd_split and memobj.spl:
>> mem.duplex = "split"
>> + if hasattr(memobj, "duplex"):
>> + mem.duplex = "split"
>> mem.offset = int(memobj.freq_tx)
>> mem.immutable = []
>> elif hasattr(memobj, "duplexOffset"):
>> @@ -620,10 +500,10 @@
>> f.make_empty()
>> self._send_frame(f)
>>
>> -# The next two lines accept the radio's status after setting the memory
>> -# and reports the results to the debug log. This is needed for the
>> -# IC-7000. No testing was done to see if it breaks memory delete on the
>> -# IC-746 or IC-7200.
>> + # The next two lines accept the radio's status after setting
>> the memory
>> + # and reports the results to the debug log. This is needed
>> for the
>> + # IC-7000. No testing was done to see if it breaks memory
>> delete on the
>> + # IC-746 or IC-7200.
>> f = self._recv_frame()
>> LOG.debug("Result:\n%s" % util.hexprint(f.get_data()))
>> return
>> @@ -708,311 +588,28 @@
>> LOG.debug("Result:\n%s" % util.hexprint(f.get_data()))
>>
>>
>> - at directory.register
>> -class Icom7200Radio(IcomCIVRadio):
>> - """Icom IC-7200"""
>> - MODEL = "7200"
>> - _model = "\x76"
>> - _template = 201
>> -
>> - _num_banks = 1 # Banks not supported
>> -
>> - def _initialize(self):
>> - self._rf.has_bank = False
>> - self._rf.has_dtcs_polarity = False
>> - self._rf.has_dtcs = False
>> - self._rf.has_ctone = False
>> - self._rf.has_offset = False
>> - self._rf.has_name = False
>> - self._rf.has_tuning_step = False
>> - self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY",
>> - "CWR", "RTTYR"]
>> - self._rf.valid_tmodes = []
>> - self._rf.valid_duplexes = []
>> - self._rf.valid_bands = [(30000, 60000000)]
>> - self._rf.valid_skips = []
>> - self._rf.memory_bounds = (1, 201)
>> -
>> -
>> - at directory.register
>> -class Icom7000Radio(IcomCIVRadio):
>> - """Icom IC-7000"""
>> - MODEL = "IC-7000"
>> - _model = "\x70"
>> - _template = 102
>> -
>> - _num_banks = 5 # Banks A-E
>> - _bank_index_bounds = (1, 99)
>> - _bank_class = icf.IcomBank
>> -
>> - def _initialize(self):
>> - self._classes["mem"] = BankMemFrame
>> - self._rf.has_bank = True
>> - self._rf.has_dtcs_polarity = True
>> - self._rf.has_dtcs = True
>> - self._rf.has_ctone = True
>> - self._rf.has_offset = True
>> - self._rf.has_name = True
>> - self._rf.has_tuning_step = False
>> - self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY", "FM",
>> "WFM"]
>> - self._rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
>> - self._rf.valid_duplexes = ["", "-", "+", "split"]
>> - self._rf.valid_bands = [(30000, 199999999), (400000000,
>> 470000000)]
>> - self._rf.valid_tuning_steps = []
>> - self._rf.valid_skips = ["S", ""]
>> - self._rf.valid_name_length = 9
>> - self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> - self._rf.memory_bounds = (0, 99 * self._num_banks - 1)
>> - self._rf.can_odd_split = True
>> -
>> -
>> - at directory.register
>> -class Icom7100Radio(IcomCIVRadio):
>> - """Icom IC-7100"""
>> - MODEL = "IC-7100"
>> - _model = "\x88"
>> - _template = 102
>> -
>> - _num_banks = 5
>> - _bank_index_bounds = (1, 99)
>> - _bank_class = icf.IcomBank
>> -
>> - def _initialize(self):
>> - self._classes["mem"] = IC7100MemFrame
>> - self._rf.has_bank = True
>> - self._rf.has_bank_index = False
>> - self._rf.has_bank_names = False
>> - self._rf.has_dtcs_polarity = False
>> - self._rf.has_dtcs = False
>> - self._rf.has_ctone = True
>> - self._rf.has_offset = False
>> - self._rf.has_name = True
>> - self._rf.has_tuning_step = False
>> - self._rf.valid_modes = [
>> - "LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", "CWR",
>> "RTTYR", "DV"
>> - ]
>> - self._rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
>> - self._rf.valid_duplexes = ["", "-", "+"]
>> - self._rf.valid_bands = [(30000, 199999999), (400000000,
>> 470000000)]
>> - self._rf.valid_tuning_steps = []
>> - self._rf.valid_skips = []
>> - self._rf.valid_name_length = 16
>> - self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> - self._rf.memory_bounds = (0, 99 * self._num_banks - 1)
>> -
>> -
>> - at directory.register
>> -class Icom746Radio(IcomCIVRadio):
>> - """Icom IC-746"""
>> - MODEL = "746"
>> - BAUD_RATE = 9600
>> - _model = "\x56"
>> - _template = 102
>> -
>> - _num_banks = 1 # Banks not supported
>> -
>> - def _initialize(self):
>> - self._classes["mem"] = DupToneMemFrame
>> - self._rf.has_bank = False
>> - self._rf.has_dtcs_polarity = False
>> - self._rf.has_dtcs = False
>> - self._rf.has_ctone = True
>> - self._rf.has_offset = False
>> - self._rf.has_name = True
>> - self._rf.has_tuning_step = False
>> - self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY", "FM"]
>> - self._rf.valid_tmodes = ["", "Tone", "TSQL"]
>> - self._rf.valid_duplexes = ["", "-", "+"]
>> - self._rf.valid_bands = [(30000, 199999999)]
>> - self._rf.valid_tuning_steps = []
>> - self._rf.valid_skips = []
>> - self._rf.valid_name_length = 9
>> - self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> - self._rf.memory_bounds = (1, 99)
>> -
>> -
>> - at directory.register
>> -class Icom910Radio(IcomCIVRadio):
>> - """Icom IC-910"""
>> - MODEL = "IC-910"
>> - BAUD_RATE = 19200
>> - _model = "\x60"
>> - _template = 100
>> -
>> - _num_banks = 3 # Banks for 2m, 70cm, 23cm
>> - _bank_index_bounds = (1, 99)
>> - _bank_class = icf.IcomBank
>> -
>> - _SPECIAL_CHANNELS = {
>> - "1A": 100,
>> - "1b": 101,
>> - "2A": 102,
>> - "2b": 103,
>> - "3A": 104,
>> - "3b": 105,
>> - "C": 106,
>> - }
>> - _SPECIAL_CHANNELS_REV = {v: k for k, v in _SPECIAL_CHANNELS.items()}
>> -
>> - _SPECIAL_BANKS = {
>> - "2m": 1,
>> - "70cm": 2,
>> - "23cm": 3,
>> - }
>> - _SPECIAL_BANKS_REV = {v: k for k, v in _SPECIAL_BANKS.items()}
>> -
>> - def _get_special_names(self, band):
>> - return sorted([band + "-" + key
>> - for key in self._SPECIAL_CHANNELS.keys()])
>> -
>> - def _is_special(self, number):
>> - return number >= 1000 or isinstance(number, str)
>> -
>> - def _get_special_info(self, number):
>> - info = BankSpecialChannel()
>> - if isinstance(number, str):
>> - info.name = number
>> - (band_name, chan_name) = number.split("-")
>> - info.bank = self._SPECIAL_BANKS[band_name]
>> - info.channel = self._SPECIAL_CHANNELS[chan_name]
>> - info.location = info.bank * 1000 + info.channel
>> - else:
>> - info.location = number
>> - (info.bank, info.channel) = divmod(number, 1000)
>> - band_name = self._SPECIAL_BANKS_REV[info.bank]
>> - chan_name = self._SPECIAL_CHANNELS_REV[info.channel]
>> - info.name = band_name + "-" + chan_name
>> - return info
>> -
>> - # The IC-910 has a bank of memories for each band. The 23cm band is
>> only
>> - # available when the optional UX-910 unit is installed, but there is
>> no
>> - # direct means of detecting its presence. Instead, attempt to access
>> the
>> - # first memory in the 23cm bank. If that's successful, the unit is
>> there,
>> - # and we can present all 3 banks to the user. Otherwise, the unit is
>> not
>> - # installed, so we present 2 banks to the user, for 2m and 70cm.
>> - def _detect_23cm_unit(self):
>> - if not self.pipe:
>> - return True
>> - f = IC910MemFrame()
>> - f.set_location(1, 3) # First memory in 23cm bank
>> - self._send_frame(f)
>> - f.read(self.pipe)
>> - if f._cmd == 0xFA: # Error code lands in command field
>> - self._num_banks = 2
>> - LOG.debug("UX-910 unit is %sinstalled" %
>> - ("not " if self._num_banks == 2 else ""))
>> - return self._num_banks == 3
>> -
>> - def _initialize(self):
>> - self._classes["mem"] = IC910MemFrame
>> - self._has_23cm_unit = self._detect_23cm_unit()
>> - self._rf.has_bank = True
>> - self._rf.has_dtcs_polarity = False
>> - self._rf.has_dtcs = False
>> - self._rf.has_ctone = True
>> - self._rf.has_offset = True
>> - self._rf.has_name = False
>> - self._rf.has_tuning_step = False
>> - self._rf.valid_modes = ["LSB", "USB", "CW", "NCW", "FM", "NFM"]
>> - self._rf.valid_tmodes = ["", "Tone", "TSQL"]
>> - self._rf.valid_duplexes = ["", "-", "+"]
>> - self._rf.valid_bands = [(136000000, 174000000),
>> - (420000000, 480000000)]
>> - self._rf.valid_tuning_steps = []
>> - self._rf.valid_skips = []
>> - self._rf.valid_special_chans = (self._get_special_names("2m") +
>> - self._get_special_names("70cm"))
>> - self._rf.memory_bounds = (1, 99 * self._num_banks)
>> -
>> - if self._has_23cm_unit:
>> - self._rf.valid_bands.append((1240000000, 1320000000))
>> - self._rf.valid_special_chans +=
>> self._get_special_names("23cm")
>> -
>> - # Combine mode and filter into unified mode
>> - self._unified_modes = True
>> -
>> - # Use Chirp locations starting with 1
>> - self._adjust_bank_loc_start = True
>> -
>> -
>> - at directory.register
>> -class Icom7300Radio(IcomCIVRadio): # Added March, 2021 by Rick
>> DeWitt
>> - """Icom IC-7300"""
>> - MODEL = "IC-7300"
>> - _model = "\x94"
>> - _template = 100 # Use P1 as blank template
>> -
>> - _SPECIAL_CHANNELS = {
>> - "P1": 100,
>> - "P2": 101,
>> - }
>> - _SPECIAL_CHANNELS_REV = dict(zip(_SPECIAL_CHANNELS.values(),
>> - _SPECIAL_CHANNELS.keys()))
>> -
>> - def _is_special(self, number):
>> - return number > 99 or isinstance(number, str)
>> -
>> - def _get_special_info(self, number):
>> - info = SpecialChannel()
>> - if isinstance(number, str):
>> - info.name = number
>> - info.channel = self._SPECIAL_CHANNELS[number]
>> - info.location = info.channel
>> - else:
>> - info.location = number
>> - info.name = self._SPECIAL_CHANNELS_REV[number]
>> - info.channel = info.location
>> - return info
>> -
>> - def _initialize(self):
>> - self._classes["mem"] = IC7300MemFrame
>> - self._rf.has_name = True
>> - self._rf.has_dtcs = False
>> - self._rf.has_dtcs_polarity = False
>> - self._rf.has_bank = False
>> - self._rf.has_tuning_step = False
>> - self._rf.has_nostep_tuning = True
>> - self._rf.can_odd_split = True
>> - self._rf.memory_bounds = (1, 99)
>> - self._rf.valid_modes = [
>> - "LSB", "USB", "AM", "CW", "RTTY", "FM", "CWR", "RTTYR",
>> - "Data+LSB", "Data+USB", "Data+AM", "N/A", "N/A", "Data+FM"
>> - ]
>> - self._rf.valid_tmodes = ["", "Tone", "TSQL"]
>> - # self._rf.valid_duplexes = ["", "-", "+", "split"]
>> - self._rf.valid_duplexes = [] # To prevent using memobj.duplex
>> - self._rf.valid_bands = [(1800000, 70500000)]
>> - self._rf.valid_skips = []
>> - self._rf.valid_name_length = 10
>> - self._rf.valid_characters = chirp_common.CHARSET_ASCII
>> - self._rf.valid_special_chans =
>> sorted(self._SPECIAL_CHANNELS.keys())
>> -
>> -
>> -CIV_MODELS = {
>> - (0x76, 0xE0): Icom7200Radio,
>> - (0x88, 0xE0): Icom7100Radio,
>> - (0x70, 0xE0): Icom7000Radio,
>> - (0x46, 0xE0): Icom746Radio,
>> - (0x60, 0xE0): Icom910Radio,
>> - (0x94, 0xE0): Icom7300Radio,
>> -}
>> -
>> -
>> def probe_model(ser):
>> """Probe the radio attatched to @ser for its model"""
>> f = Frame()
>> f.set_command(0x19, 0x00)
>>
>> - for model, controller in CIV_MODELS.keys():
>> - f.send(model, controller, ser)
>> + models = {}
>> + for rclass in directory.DRV_TO_RADIO.values():
>> + if issubclass(rclass, IcomCIVRadio):
>> + models[rclass.MODEL] = rclass
>> +
>> + for rclass in models.values():
>> + model = ord(rclass._model)
>> + f.send(model, 0xE0, ser)
>> try:
>> f.read(ser)
>> except errors.RadioError:
>> continue
>>
>> if len(f.get_data()) == 1:
>> - model = ord(f.get_data()[0])
>> - return CIV_MODELS[(model, controller)]
>> + md = ord(f.get_data()[0])
>> + if (md == model):
>> + return rclass
>>
>> if f.get_data():
>> LOG.debug("Got data, but not 1 byte:")
>> _______________________________________________
>> chirp_devel mailing list
>> chirp_devel at intrepid.danplanet.com
>> http://intrepid.danplanet.com/mailman/listinfo/chirp_devel
>> Developer docs: http://chirp.danplanet.com/projects/chirp/wiki/Developers
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://intrepid.danplanet.com/pipermail/chirp_devel/attachments/20210430/761f7500/attachment-0001.html
More information about the chirp_devel
mailing list