[chirp_devel] Patch ft4.py restructure, #7615
Bernhard Hailer
Sat Feb 1 15:18:14 PST 2020
# HG changeset patch
# User Bernhard Hailer <ham73tux at gmail.com>
# Date 1580597959 28800
# Sat Feb 01 14:59:19 2020 -0800
# Node ID 04404b4e386b95acfe95b590af75d9f26619d0ba
# Parent 53cd045bbf8253d32b43a528b245caff243e4c02
While implementing two more radios of the Yaesu FT-4 family (the FT-25,
see #7543, and the FT-4V, see #7387), I found that with some moderate
reorganization, implementation of new radios will become easier. The
proposed reorganization implements one more interstitial layer of
inheritance to support the sub families of FT-4 (containing the FT-4X
and FT-4V) and FT-65 (containing FT-65 and FT-25). Also, some variable
assignments have been moved from the individual radio classes to the
SCU-35 base class and to the interstitial classes named above.
This change also adds the infrastructure for adding European or Asian
models, and as such prepare for addressing a number of currently open
issues (6.25kHz tune step issues on EU models, frequency limitations;
see #6619, #6651, #6677, #6761, #6869). It will also make it easier for
a few additional fixes for issues which were found during my work on
this driver (#7601, #7603, #7605). I will submit these fixes in
additional patches.
Fixes: #7615
diff --git a/chirp/drivers/ft4.py b/chirp/drivers/ft4.py
--- a/chirp/drivers/ft4.py
+++ b/chirp/drivers/ft4.py
@@ -2,6 +2,7 @@
# Derives loosely from two sources released under GPLv2:
# ./template.py, Copyright 2012 Dan Smith <dsmith at danplanet.com>
# ./ft60.py, Copyright 2011 Dan Smith <dsmith at danplanet.com>
+# Edited 2020 Bernhard Hailer AE6YN <ham73tux at gmail.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
@@ -18,8 +19,8 @@
"""
CHIRP driver for Yaesu radios that use the SCU-35 cable. This includes at
-least the FT-4, FT-25, FT-35, and FT-65. This driver will not work with
-older Yaesu models.
+least the FT-4X, FT-4V, FT-65, and FT-25. This driver will not work
with older
+Yaesu models.
"""
import logging
import struct
@@ -261,7 +262,8 @@
msg = "Bad echo. Sent:" + util.hexprint(cmd) + ", "
msg += "Received:" + util.hexprint(echo)
LOG.debug(msg)
- raise errors.RadioError("Incorrect echo on serial port. Bad
cable?")
+ raise errors.RadioError(
+ "Incorrect echo on serial port. Radio off? Bad cable?")
if response_len is None:
return variable_len_resp(pipe)
if response_len > 0:
@@ -474,8 +476,6 @@
SKIPS = ["", "S"]
-BASETYPE_FT4 = ["FT-4XR", "FT-4XE"]
-BASETYPE_FT65 = ["FT-65R"]
POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=0.5),
chirp_common.PowerLevel("Mid", watts=2.5),
chirp_common.PowerLevel("High", watts=5.0)]
@@ -560,16 +560,53 @@
# Each special has unique constrants: band, name yes/no, and pms L/U
# The FT-65 class replaces the "prog" entry in this list.
# The name field must be the name of a slot array in MEM_FORMAT
-SPECIALS = [
+SPECIALS_FT4 = [
("pms", PMSNAMES),
("vfo", ["VFO A UHF", "VFO A VHF", "VFO B FM", "VFO B VHF", "VFO B
UHF"]),
("home", ["HOME FM", "HOME VHF", "HOME UHF"]),
("prog", ["P1", "P2"])
]
-BAND_ASSIGNMENTS = [2, 1, 0, 1, 2, 0, 1, 2] # bands for the vfos and homes
+SPECIALS_FT65 = SPECIALS_FT4
FT65_PROGS = ("prog", ["P1", "P2", "P3", "P4"])
-FT65_SPECIALS = list(SPECIALS) # a shallow copy works here
-FT65_SPECIALS[-1] = FT65_PROGS # replace the last entry (P key names)
+SPECIALS_FT65[-1] = FT65_PROGS # replace the last entry (P key names)
+
+# I wonder whether we should simply open the bands to what the radios allow
+# for RX? The radios do take care of allowing or prohibiting TX on
their own.
+# In that case, the ASIA settings can be used for any region model.
+# To be discussed with Dan Clemmensen. [AE6YN]
+
+VALID_BANDS_US_DUAL = [
+ (65000000, 108000000), # broadcast FM, receive only
+ (144000000, 148000000), # VHF, US version, TX and RX
+ (430000000, 450000000) # UHF, US version, TX and RX
+ ]
+VALID_BANDS_EU_DUAL = [
+ (65000000, 108000000), # broadcast FM, receive only
+ (144000000, 146000000), # VHF, EU version, TX and RX
+ (430000000, 440000000) # UHF, EU version, TX and RX
+ ]
+VALID_BANDS_ASIA_DUAL = [
+ (65000000, 108000000), # broadcast FM, receive only
+ (136000000, 174000000), # VHF, Asia version, TX and RX
+ (400000000, 480000000) # UHF, Asia version, TX and RX
+ ]
+
+VALID_BANDS_US_VHF = [
+ (65000000, 108000000), # broadcast FM, receive only
+ (144000000, 148000000), # VHF, US version, TX and RX
+ ]
+VALID_BANDS_EU_VHF = [
+ (65000000, 108000000), # broadcast FM, receive only
+ (144000000, 146000000), # VHF, EU version, TX and RX
+ ]
+VALID_BANDS_ASIA_VHF = [
+ (65000000, 108000000), # broadcast FM, receive only
+ (136000000, 174000000), # VHF, Asia version, TX and RX
+ ]
+
+# bands for the five VFO and three home channel memories
+BAND_ASSIGNMENTS_DUALBAND = [2, 1, 0, 1, 2, 0, 1, 2] # all locations used
+BAND_ASSIGNMENTS_MONO_VHF = [1, 1, 0, 1, 1, 0, 1, 1] # UHF locations
unused
# None, and 50 Tones. Use this explicit array because the
@@ -620,8 +657,8 @@
chirp_common.ExperimentalRadio):
"""
Base class for all Yaesu radios using the SCU-35 programming cable
- and its protocol. Classes for specific radios extend this class and
- are found at the end of this file.
+ and its protocol. Classes for sub families extend this class and
+ are found towards the end of this file.
"""
VENDOR = "Yaesu"
MODEL = "SCU-35Generic" # No radio directly uses the base class
@@ -629,6 +666,12 @@
MAX_MEM_SLOT = 200
NEEDS_COMPAT_SERIAL = False
+ # These settings are common to all radios in this family.
+ _valid_chars = chirp_common.CHARSET_ASCII
+ numblocks = 0x215 # number of 16-byte blocks in the radio
+ _memsize = 16 * numblocks # used by CHIRP file loader to guess
radio type
+ MAX_MEM_SLOT = 200
+
@classmethod
def get_prompts(cls):
rp = chirp_common.RadioPrompts()
@@ -669,7 +712,6 @@
rf.has_dtcs_polarity = False # REV TN reverses the tone,
not the dcs
rf.has_cross = True
rf.has_settings = True
- rf.valid_tuning_steps = self.legal_steps
return rf
@@ -1027,14 +1069,11 @@
mem = chirp_common.Memory()
_mem, ndx, num, regtype, sname = self.slotloc(memref)
mem.number = num
- mem.freq = int(_mem.freq) * 10
- mem.offset = int(_mem.offset) * self.freq_offset_scale
- mem.duplex = DUPLEX[_mem.duplex]
- self.decode_sql(mem, _mem)
- mem.power = POWER_LEVELS[_mem.tx_pwr]
- mem.mode = ["FM", "NFM"][_mem.tx_width]
- mem.tuning_step = STEP_CODE[_mem.step]
+ # First, we need to know whether a channel is enabled,
+ # then we can process any channel parameters.
+ # It was found (at least on an FT-25) that channels might be
+ # uninitialized and memory is just completely filled with 0xFF.
if regtype == "pms":
mem.extd_number = sname
@@ -1043,15 +1082,34 @@
mem.name = clean_name(self._memobj.names[ndx].chrs)
mem.empty = not retrieve_bit(self._memobj.enable, ndx)
mem.skip = SKIPS[retrieve_bit(self._memobj.scan, ndx)]
- txfreq = int(self._memobj.txfreqs[ndx].freq) * 10
- if (txfreq != 0) and (txfreq != mem.freq):
- mem.duplex = "split"
- mem.offset = txfreq
else:
mem.empty = False
mem.extd_number = sname
mem.immutable = ["number", "extd_number", "name", "skip"]
+ # So, now if channel is not empty, we can do the evaluation of
+ # all parameters. Otherwise we set them to defaults.
+
+ if mem.empty:
+ mem.freq = 0
+ mem.offset = 0
+ mem.duplex = "off"
+ mem.power = POWER_LEVELS[0] # "High"
+ mem.mode = "FM"
+ mem.tuning_step = 0
+ else:
+ mem.freq = int(_mem.freq) * 10
+ txfreq = int(self._memobj.txfreqs[ndx].freq) * 10
+ if (txfreq != 0) and (txfreq != mem.freq):
+ mem.duplex = "split"
+ mem.offset = txfreq
+ else:
+ mem.offset = int(_mem.offset) * self.freq_offset_scale
+ mem.duplex = DUPLEX[_mem.duplex]
+ self.decode_sql(mem, _mem)
+ mem.power = POWER_LEVELS[2 - _mem.tx_pwr]
+ mem.mode = ["FM", "NFM"][_mem.tx_width]
+ mem.tuning_step = STEP_CODE[_mem.step]
return mem
def enforce_band(self, memloc, freq, mem_num, sname):
@@ -1105,28 +1163,16 @@
return
- at directory.register
-class YaesuFT4Radio(YaesuSC35GenericRadio):
- MODEL = "FT-4XR"
- _basetype = BASETYPE_FT4
- valid_bands = [
- (65000000, 108000000), # broadcast FM, receive only
- (144000000, 148000000), # VHF, US version, TX and RX
- (430000000, 450000000) # UHF, US version, TX and RX
- # VHF, RX (136000000, 174000000)
- # UHF, RX (400000000, 480000000)
- ]
- _valid_chars = chirp_common.CHARSET_ASCII
- numblocks = 0x215 # number of 16-byte blocks in the radio
- _memsize = 16 * numblocks # used by CHIRP file loader to guess
radio type
- MAX_MEM_SLOT = 200
- Pkeys = 2 # number of programmable keys on the FT-4
- namelen = 6 # length of the mem name display on the FT-4 front-panel
- id_str = b'IFT-35R\x00\x00V100\x00\x00'
+class YaesuFT4GenericRadio(YaesuSC35GenericRadio):
+ """
+ FT-4 sub family class. Classes for individual radios extend
+ these classes and are found at the end of this file.
+ """
+ class_specials = SPECIALS_FT4
+ Pkeys = 2 # number of programmable keys
+ namelen = 6 # length of the mem name display on the front-panel
freq_offset_scale = 25000
- legal_steps = US_LEGAL_STEPS
class_group_descs = YaesuSC35GenericRadio.group_descriptions
- class_specials = SPECIALS
# names for the setmode function for the programmable keys. Mode
zero means
# that the key is programmed for a memory not a setmode.
SETMODES = [
@@ -1143,31 +1189,19 @@
]
- at directory.register
-class YaesuFT65Radio(YaesuSC35GenericRadio):
- MODEL = "FT-65R"
- _basetype = BASETYPE_FT65
- valid_bands = [
- (65000000, 108000000), # broadcast FM, receive only
- (144000000, 148000000), # VHF, US version, TX and RX
- (430000000, 450000000) # UHF, US version, TX and RX
- # VHF, RX (136000000, 174000000)
- # UHF, RX (400000000, 480000000)
- ]
- _valid_chars = chirp_common.CHARSET_ASCII
- numblocks = 0x215 # number of 16-byte blocks in the radio
- _memsize = 16 * numblocks # used by CHIRP file loader to guess
radio type
- MAX_MEM_SLOT = 200
- Pkeys = 4 # number of programmable keys on the FT-65
- namelen = 8 # length of the mem name display on the FT-65 front panel
- id_str = b'IH-420\x00\x00\x00V100\x00\x00'
+class YaesuFT65GenericRadio(YaesuSC35GenericRadio):
+ """
+ FT-65 sub family class. Classes for individual radios extend
+ these classes and are found at the end of this file.
+ """
+ class_specials = SPECIALS_FT65
+ Pkeys = 4 # number of programmable keys
+ namelen = 8 # length of the mem name display on the front-panel
freq_offset_scale = 50000
- legal_steps = US_LEGAL_STEPS
# we need a deep copy here because we are adding deeper than the
top level.
class_group_descs =
copy.deepcopy(YaesuSC35GenericRadio.group_descriptions)
add_paramdesc(
class_group_descs, "misc", ("compander", "Compander", ["OFF",
"ON"]))
- class_specials = FT65_SPECIALS
# names for the setmode function for the programmable keys. Mode
zero means
# that the key is programmed for a memory not a setmode.
SETMODES = [
@@ -1180,3 +1214,31 @@
"step", "tot", "tx pwr", "tx save", "vfo.spl", # 30-34
"vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" # 35-39
]
+
+
+# Classes for each individual radio.
+
+
+ at directory.register
+class YaesuFT4XRRadio(YaesuFT4GenericRadio):
+ """
+ FT-4X dual band, US version
+ """
+ MODEL = "FT-4XR"
+ id_str = b'IFT-35R\x00\x00V100\x00\x00'
+ valid_bands = VALID_BANDS_US_DUAL
+ legal_steps = US_LEGAL_STEPS
+ BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_DUALBAND
+
+
+ at directory.register
+class YaesuFT65RRadio(YaesuFT65GenericRadio):
+ """
+ FT-65 dual band, US version
+ """
+ MODEL = "FT-65R"
+ id_str = b'IH-420\x00\x00\x00V100\x00\x00'
+ valid_bands = VALID_BANDS_US_DUAL
+ legal_steps = US_LEGAL_STEPS
+ BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_DUALBAND
+
More information about the chirp_devel
mailing list