[chirp_devel] [PATCH] [ft4] allow RO frequencies [#6651]
DanClemmensen
Thu Mar 28 08:55:17 PDT 2019
# HG changeset patch
# User DanClemmensen <DanClemmensen at gmail.com>
# Date 1553788333 25200
# Thu Mar 28 08:52:13 2019 -0700
# Node ID 7e1511f8e3b8aee9b6061033bb4cecde8c4c51f6
# Parent 1b1928be7a68878c54965e1fcc6e196e17db776d
[ft4] allow RO frequencies [#6651]
Fixes: #6615
After this patch is applied, the code will function as before if using only TX
frequencies. The code requires the earlier patch to memedit.py to actually
enable the use of the RO frequencies.
diff -r 1b1928be7a68 -r 7e1511f8e3b8 chirp/drivers/ft4.py
--- a/chirp/drivers/ft4.py Tue Mar 19 20:28:00 2019 -0700
+++ b/chirp/drivers/ft4.py Thu Mar 28 08:52:13 2019 -0700
@@ -464,10 +464,11 @@
banks.append(bank)
return banks
-# the values in these lists must also be in the canonical UI list
-# we can re-arrange the order, and we don't need to have all
-# the values, but we cannot add our own values here.
-DUPLEX = ["+", "", "-", "", "off", "", "split"] # (0,2,4,5)= (+,-,0, auto)
+# list used by the UI. These exact values are set and tested.
+VALID_DUPLEXES = ["", "+", "-", "split", "off"]
+ENCODE_DUPLEXES = {"": 4, "+": 0, "-": 2, "split": 4, "off": 4}
+# DUPLEX maps radio's duplex field to the duplex names
+DUPLEX = ["+", "", "-", "", "off", ""] # (0,2,4,5)= (+,-,0, auto)
# the radio implements duplex "auto" as 5. we map to "" It appears to be
# a convienience function in the radio that affects the offset, but I do not
# understand it.
@@ -628,6 +629,11 @@
BAUD_RATE = 9600
MAX_MEM_SLOT = 200
NEEDS_COMPAT_SERIAL = False
+ valid_rx_bands = [
+ (65000000, 108000000), # broadcast FM
+ (136000000, 174000000), # VHF
+ (400000000, 480000000) # UHF
+ ]
@classmethod
def get_prompts(cls):
@@ -653,7 +659,7 @@
specials = [name for s in self.class_specials for name in s[1]]
rf.valid_special_chans = specials
rf.memory_bounds = (1, self.MAX_MEM_SLOT)
- rf.valid_duplexes = DUPLEX
+ rf.valid_duplexes = VALID_DUPLEXES # displaylist != DUPLEX
rf.valid_tmodes = VALID_TONE_MODES
rf.valid_cross_modes = VALID_CROSS_MODES
rf.valid_power_levels = POWER_LEVELS
@@ -662,7 +668,7 @@
rf.valid_characters = CHARSET
rf.valid_name_length = self.namelen
rf.valid_modes = ["FM", "NFM"]
- rf.valid_bands = self.valid_bands
+ rf.valid_bands = self.valid_rx_bands
rf.can_odd_split = True
rf.has_ctone = True
rf.has_rx_dtcs = True
@@ -1003,6 +1009,57 @@
return (memloc, ndx, num, array, sname)
# end of slotloc
+ def tx_allowed(self, mem):
+ """
+ Given a mem, see if the tx frequency is within a valid tx band.
+ returns allowed (True or False), and the computed TX freq.
+ For FM broadcast, we allow duplex == "" also: the user doesn't
+ really expect the radio to Tx there anyway.
+ """
+ freq = mem.freq
+ dup = mem.duplex
+ if dup == "off":
+ return (True, freq)
+ if (dup == "") and freq <= self.valid_rx_bands[0][1]:
+ return (True, freq) # hack: don't complain about FM bands
+ offset = mem.offset
+ if dup == "split":
+ freq = offset
+ elif dup == "-":
+ freq -= offset
+ elif dup == "+":
+ freq += offset
+ for lo, hi in self.valid_tx_bands:
+ if lo <= freq <= hi:
+ return (True, freq)
+
+ return (False, freq)
+
+ def validate_memory(self, mem):
+ """
+ Called by UI when a mem is changed. Invoke the superclass' method to
+ get any generic error messages, then add any error msgs for our class.
+ returns a list of error messages for this channel's config
+ """
+ msgs = chirp_common.CloneModeRadio.validate_memory(self, mem)
+ memloc, ndx, num, regtype, sname = self.slotloc(mem.number)
+
+ def addmsg(msg):
+ msgs.append(chirp_common.ValidationError(msg))
+ allowed, freq = self.tx_allowed(mem)
+ if not allowed:
+ freqstr = chirp_common.format_freq(freq)
+ addmsg("Tx freq %s is not in supported Tx range" % freqstr)
+ if regtype in ["vfo", "home"]:
+ first_vfo_num = self.MAX_MEM_SLOT + len(PMSNAMES) + 1
+ band = BAND_ASSIGNMENTS[num - first_vfo_num]
+ freq = mem.freq
+ lo, hi = self.valid_rx_bands[band]
+ if not (lo <= freq < hi):
+ freqstr = chirp_common.format_freq(freq)
+ addmsg("freq %s is in wrong band for %s" % (freqstr, sname))
+ return msgs
+
# return the raw info for a memory channel
def get_raw_memory(self, memref):
memloc, ndx, num, regtype, sname = self.slotloc(memref)
@@ -1043,9 +1100,11 @@
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
+ if (txfreq == 0):
+ mem.duplex = "off"
+ elif (txfreq != mem.freq):
+ mem.duplex = "split"
+ mem.offset = txfreq
else:
mem.empty = False
mem.extd_number = sname
@@ -1053,21 +1112,6 @@
return mem
- def enforce_band(self, memloc, freq, mem_num, sname):
- """
- vfo and home channels are each restricted to a particular band.
- If the frequency is not in the band, use the lower bound
- Raise an exception to cause UI to pop up an error message
- """
- first_vfo_num = self.MAX_MEM_SLOT + len(PMSNAMES) + 1
- band = BAND_ASSIGNMENTS[mem_num - first_vfo_num]
- frange = self.valid_bands[band]
- if freq >= frange[0] and freq <= frange[1]:
- memloc.freq = freq / 10
- return freq
- memloc.freq = frange[0] / 10
- raise Exception("freq out of range for %s" % sname)
-
# modify a radio channel in memobj based on info in CHIRP canonical form
def set_memory(self, mem):
_mem, ndx, num, regtype, sname = self.slotloc(mem.number)
@@ -1076,9 +1120,14 @@
if regtype in ["memory", "pms"]:
store_bit(self._memobj.enable, ndx, False)
return
-
- txfreq = mem.freq / 10 # really. RX freq is used for TX base
- _mem.freq = txfreq
+ txfreq = mem.freq # really. RX freq is used for TX base
+ _mem.freq = txfreq / 10
+ duplex = mem.duplex
+ allowed, freq = self.tx_allowed(mem)
+ if not allowed:
+ mem.offset = 0
+ mem.duplex = "off"
+ txfreq = 0
self.encode_sql(mem, _mem)
if mem.power:
_mem.tx_pwr = POWER_LEVELS.index(mem.power)
@@ -1086,7 +1135,6 @@
_mem.step = STEP_CODE.index(mem.tuning_step)
_mem.offset = mem.offset / self.freq_offset_scale
- duplex = mem.duplex
if regtype in ["memory", "pms"]:
ndx = num - 1
store_bit(self._memobj.enable, ndx, True)
@@ -1094,13 +1142,9 @@
nametrim = (mem.name + " ")[:8]
self._memobj.names[ndx].chrs = bytearray(nametrim, "ascii")
if mem.duplex == "split":
- txfreq = mem.offset / 10
- duplex = "off" # radio ignores when tx != rx
- self._memobj.txfreqs[num-1].freq = txfreq
- _mem.duplex = DUPLEX.index(duplex)
- if regtype in ["vfo", "home"]:
- self.enforce_band(_mem, mem.freq, num, sname)
-
+ txfreq = mem.offset
+ self._memobj.txfreqs[num-1].freq = txfreq / 10
+ _mem.duplex = ENCODE_DUPLEXES[duplex]
return
@@ -1108,13 +1152,7 @@
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_tx_bands = [(144000000, 148000000), (430000000, 450000000)]
_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
@@ -1146,13 +1184,7 @@
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_tx_bands = [(144000000, 148000000), (430000000, 450000000)]
_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
More information about the chirp_devel
mailing list