[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