[chirp_devel] [PATCH 1 of 1] Added support for VFO and other special memories

Marco Filippi IZ3GME
Tue Mar 27 11:17:27 PDT 2012


# HG changeset patch
# User Marco Filippi <iz3gme.marco at gmail.com>
# Date 1332866460 -7200
# Node ID a06e9886b98643302d68f69dfe3a96f489200c6c
# Parent  4373b2839103d97e83fbb977662bb999b483cd3c
Added support for VFO and other special memories
Source reorganized

diff -r 4373b2839103 -r a06e9886b986 chirp/ft817.py
--- a/chirp/ft817.py	Mon Feb 20 20:06:04 2012 -0800
+++ b/chirp/ft817.py	Tue Mar 27 18:41:00 2012 +0200
@@ -110,14 +110,7 @@
 
     print "Clone completed in %i seconds" % (time.time() - start)
 
-mem_format = """
-#seekto 0x3fd;
-u8 visible[25];
-
-#seekto 0x417;
-u8 filled[25];
-
-#seekto 0x431;
+mem_struct = """
 struct {
   u8   tag_on_off:1,
        tag_default:1,
@@ -149,47 +142,40 @@
   u32 freq;
   u32 offset;
   u8   name[8];
-} memory[200];
+}
+"""
+
+# there is a bug in bitwise_grammar that prevent the definition of single structures
+# qmb should be only one mem_struct followed by
+#""" + mem_struct + """ mtqmb;
+# but both qmb and qmb[1] raise an exception so I had to define it as qmb[2]
+
+mem_format = """
+#seekto 0x2a;
+""" + mem_struct + """ vfoa[15];
+""" + mem_struct + """ vfob[15];
+""" + mem_struct + """ home[4];
+""" + mem_struct + """ qmb[2];
+""" + mem_struct + """ mtune;
+
+#seekto 0x3fd;
+u8 visible[25];
+
+#seekto 0x417;
+u8 filled[25];
+
+#seekto 0x431;
+""" + mem_struct + """ memory[200];
 
 #seekto 0x1979;
-struct {
-  u8   tag_on_off:1,
-       tag_default:1,
-       unknown1:3,
-       mode:3;
-  u8   duplex:2,
-       is_duplex:1,
-       is_cwdig_narrow:1,
-       is_fm_narrow:1,
-       freq_range:3;
-  u8   skip:1,
-       unknown2:1,
-       ipo:1,
-       att:1,
-       unknown3:4;
-  u8   ssb_step:2,
-       am_step:3,
-       fm_step:3;
-  u8   unknown4:6,
-       tmode:2;
-  u8   unknown5:2,
-       tx_mode:3,
-       tx_freq_range:3;
-  u8   unknown6:2,
-       tone:6;
-  u8   unknown7:1,
-       dcs:7;
-  ul16 rit;
-  u32 freq;
-  u32 offset;
-  u8   name[8];
-} sixtymeterchannels[5];
+""" + mem_struct + """ sixtymeterchannels[5];
 """
 
 @directory.register
 class FT817Radio(yaesu_clone.YaesuCloneModeRadio):
     BAUD_RATE = 9600
     MODEL = "FT-817"
+    _model = ""
 
     DUPLEX = ["", "-", "+", "split"]
     MODES  = ["LSB", "USB", "CW", "CWR", "AM", "FM", "DIG", "PKT", "NCW", "NCWR", "NFM"]   # narrow modes has to be at end
@@ -199,7 +185,6 @@
     STEPSSSB = [1.0, 2.5, 5.0]
     VALID_BANDS = [(100000,33000000), (33000000,56000000), (76000000,108000000), (108000000,137000000), (137000000,154000000), (420000000,470000000)] # warning ranges has to be in this exact order
 
-
     CHARSET = [chr(x) for x in range(0, 256)]
 
     POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00),       # not used in memory
@@ -207,11 +192,51 @@
                     chirp_common.PowerLevel("L2", watts=1.00),
                     chirp_common.PowerLevel("L1", watts=0.5)]
 
-    _model = ""
     _memsize = 6509
     # block 9 (130 Bytes long) is to be repeted 40 times
     _block_lengths = [ 2, 40, 208, 182, 208, 182, 198, 53, 130, 118, 118]
 
+    SPECIAL_MEMORIES = {        # WARNING Index are hard wired in memory management code !!!
+        "VFOa-1.8M" : -35,
+        "VFOa-3.5M" : -34,
+        "VFOa-7M" : -33,
+        "VFOa-10M" : -32,
+        "VFOa-14M" : -31,
+        "VFOa-18M" : -30,
+        "VFOa-21M" : -29,
+        "VFOa-24M" : -28,
+        "VFOa-28M" : -27,
+        "VFOa-50M" : -26,
+        "VFOa-FM" : -25,
+        "VFOa-AIR" : -24,
+        "VFOa-144" : -23,
+        "VFOa-430" : -22,
+        "VFOa-HF" : -21,
+        "VFOb-1.8M" : -20,
+        "VFOb-3.5M" : -19,
+        "VFOb-7M" : -18,
+        "VFOb-10M" : -17,
+        "VFOb-14M" : -16,
+        "VFOb-18M" : -15,
+        "VFOb-21M" : -14,
+        "VFOb-24M" : -13,
+        "VFOb-28M" : -12,
+        "VFOb-50M" : -11,
+        "VFOb-FM" : -10,
+        "VFOb-AIR" : -9,
+        "VFOb-144M" : -8,
+        "VFOb-430M" : -7,
+        "VFOb-HF" : -6,
+        "HOME HF" : -5,
+        "HOME 50M" : -4,
+        "HOME 144M" : -3,
+        "HOME 430M" : -2,
+        "QMB" : -1,
+    }
+    FIRST_VFOB_INDEX = -6
+    LAST_VFOB_INDEX = -20
+    FIRST_VFOA_INDEX = -21
+    LAST_VFOA_INDEX = -35
 
     def sync_in(self):
         self._mmap = clone_in(self)
@@ -254,7 +279,81 @@
     def get_tmode(self, mem, _mem):
         mem.tmode = self.TMODES[_mem.tmode]
 
+    def set_duplex(self, mem, _mem):
+        _mem.duplex = self.DUPLEX.index(mem.duplex)
+        _mem.is_duplex = mem.duplex != ""
+
+    def set_tmode(self, mem, _mem):
+        _mem.tmode = self.TMODES.index(mem.tmode)
+
     def get_memory(self, number):
+        if isinstance(number, str):
+            return self._get_special(number)
+        else:
+            return self._get_normal(number)
+
+    def set_memory(self, memory):
+        if memory.number < 0:
+            return self._set_special(memory)
+        else:
+            return self._set_normal(memory)
+
+    def get_special_locations(self):
+        return self.SPECIAL_MEMORIES.keys()
+
+    def _get_special(self, number):
+        mem = chirp_common.Memory()
+        mem.number = self.SPECIAL_MEMORIES[number]
+        mem.extd_number = number
+
+        if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX -1, -1):
+            _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number]
+            immutable = ["number", "skip", "rtone", "ctone", "extd_number", "name",
+                         "dtcs_polarity", "power", "comment"]
+        elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX -1, -1):
+            _mem = self._memobj.vfob[-self.LAST_VFOB_INDEX + mem.number]
+            immutable = ["number", "skip", "rtone", "ctone", "extd_number", "name",
+                         "dtcs_polarity", "power", "comment"]
+        elif mem.number in range(-2, -6, -1):
+            _mem = self._memobj.home[5 + mem.number]
+            immutable = ["number", "skip", "rtone", "ctone", "extd_number",
+                         "dtcs_polarity", "power", "comment"]
+        elif mem.number == -1:
+            _mem = self._memobj.qmb[0]
+            immutable = ["number", "skip", "rtone", "ctone", "extd_number", "name",
+                         "dtcs_polarity", "power", "comment"]
+	else:
+            raise Exception("Sorry, special memory index %i unknown you hit a bug!!" % mem.number)
+
+        mem = self._get_memory(mem, _mem)
+	mem.immutable = immutable
+
+        return mem
+
+    def _set_special(self, mem):
+        cur_mem = self._get_special(mem.extd_number)
+
+        for key in cur_mem.immutable:
+            if cur_mem.__dict__[key] != mem.__dict__[key]:
+                raise errors.RadioError("Editing field `%s' " % key +
+                                        "is not supported on this chanel")
+
+        # TODO add frequency range check for vfo and home memories
+
+        if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX -1, -1):
+            _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number]
+        elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX -1, -1):
+            _mem = self._memobj.vfob[self.LAST_VFOB_INDEX + mem.number]
+        elif mem.number in range(-2, -6, -1):
+            _mem = self._memobj.home[5 + mem.number]
+        elif mem.number == -1:
+            _mem = self._memobj.qmb[0]
+	else:
+            raise Exception("Sorry, special memory index %i unknown you hit a bug!!" % mem.number)
+
+        self._set_memory(mem, _mem)
+
+    def _get_normal(self, number):
         _mem = self._memobj.memory[number-1]
         used = (self._memobj.visible[(number-1)/8] >> (number-1)%8) & 0x01
 
@@ -266,6 +365,21 @@
 
         return self._get_memory(mem, _mem)
 
+    def _set_normal(self, mem):
+        _mem = self._memobj.memory[mem.number-1]
+        if mem.empty:
+            if mem.number == 1:
+                # as Dan says "yaesus are not good about that :("
+		# if you ulpoad an empty image you can brick your radio
+                raise Exception("Sorry, can't delete first memory") 
+            self._memobj.visible[(mem.number-1)/8] &= ~ (1 << (mem.number-1)%8)
+            self._memobj.filled[(mem.number-1)/8] = self._memobj.visible[(mem.number-1)/8]
+            return
+        
+        self._memobj.visible[(mem.number-1)/8] |= 1 << (mem.number-1)%8
+        self._memobj.filled[(mem.number-1)/8] = self._memobj.visible[(mem.number-1)/8]
+        self._set_memory(mem, _mem)
+
     def _get_memory(self, mem, _mem):
         mem.freq = int(_mem.freq) * 10
         mem.offset = int(_mem.offset) * 10
@@ -281,8 +395,11 @@
             if _mem.is_cwdig_narrow == 1:
                 mem.mode = "N" + mem.mode
             mem.tuning_step = self.STEPSSSB[_mem.ssb_step]
-        else:   # TODO more investigation needed on steps for other modes 
-            mem.tuning_step = self.STEPSSSB[_mem.ssb_step]
+        else:
+            try:
+                mem.tuning_step = self.STEPSSSB[_mem.ssb_step]
+            except IndexError:
+                pass
         mem.skip = _mem.skip and "S" or ""
         self.get_tmode(mem, _mem)
         mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone]
@@ -299,30 +416,7 @@
 
         return mem
 
-    def set_duplex(self, mem, _mem):
-        _mem.duplex = self.DUPLEX.index(mem.duplex)
-        _mem.is_duplex = mem.duplex != ""
-
-    def set_tmode(self, mem, _mem):
-        _mem.tmode = self.TMODES.index(mem.tmode)
-
-    def set_memory(self, mem):
-        _mem = self._memobj.memory[mem.number-1]
-        if mem.empty:
-            if mem.number == 1:
-                # as Dan says "yaesus are not good about that :("
-		# if you ulpoad an empty image you can brick your radio
-                raise Exception("Sorry, can't delete first memory") 
-            self._memobj.visible[(mem.number-1)/8] &= ~ (1 << (mem.number-1)%8)
-            self._memobj.filled[(mem.number-1)/8] = self._memobj.visible[(mem.number-1)/8]
-            return
-        
-        self._set_memory(mem, _mem)
-
     def _set_memory(self, mem, _mem):
-        self._memobj.visible[(mem.number-1)/8] |= 1 << (mem.number-1)%8
-        self._memobj.filled[(mem.number-1)/8] = self._memobj.visible[(mem.number-1)/8]
-
         if len(mem.name) > 0:     # not supported in chirp
                                   # so I make label visible if have one
             _mem.tag_on_off = 1
@@ -397,14 +491,6 @@
     # block 9 (130 Bytes long) is to be repeted 40 times
     _block_lengths = [ 2, 40, 208, 182, 208, 182, 198, 53, 130, 118, 130]
 
-SPECIAL_60M = {
-    "M-601" : -1,
-    "M-602" : -2,
-    "M-603" : -3,
-    "M-604" : -4,
-    "M-605" : -5,
-    }
-
 @directory.register
 class FT817ND_US_Radio(FT817Radio):
     # seems that radios configured for 5MHz operations send one paket more than others
@@ -416,15 +502,26 @@
     # block 9 (130 Bytes long) is to be repeted 40 times
     _block_lengths = [ 2, 40, 208, 182, 208, 182, 198, 53, 130, 118, 130, 130]
 
+    SPECIAL_60M = {
+        "M-601" : -40,
+        "M-602" : -39,
+        "M-603" : -38,
+        "M-604" : -37,
+        "M-605" : -36,
+        }
+    LAST_SPECIAL60M_INDEX = -40
+
     def get_special_locations(self):
-        return SPECIAL_60M.keys()
+        lista = self.SPECIAL_60M.keys()
+        lista.extend(FT817Radio.get_special_locations(self))
+        return lista
 
-    def _get_special(self, number):
+    def _get_special_60M(self, number):
         mem = chirp_common.Memory()
-        mem.number = SPECIAL_60M[number]
+        mem.number = self.SPECIAL_60M[number]
         mem.extd_number = number
 
-        _mem = self._memobj.sixtymeterchannels[abs(mem.number)-1]
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
 
         mem = self._get_memory(mem, _mem)
 
@@ -435,7 +532,7 @@
 
         return mem
 
-    def _set_special(self, mem):
+    def _set_special_60M(self, mem):
         cur_mem = self._get_special(mem.extd_number)
 
         for key in cur_mem.immutable:
@@ -446,17 +543,17 @@
         if mem.mode not in ["USB", "LSB", "CW", "CWR", "NCW", "NCWR", "DIG"]:
             raise errors.RadioError(_("Mode {mode} is not valid "
                                       "in 60m channels").format(mode=mem.mode))
-        _mem = self._memobj.sixtymeterchannels[abs(mem.number)-1]
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
         self._set_memory(mem, _mem)
 
     def get_memory(self, number):
-        if isinstance(number, str):
-            return self._get_special(number)
+        if number in self.SPECIAL_60M.keys():
+            return self._get_special_60M(number)
         else:
             return FT817Radio.get_memory(self, number)
 
     def set_memory(self, memory):
-        if memory.number < 0:
-            return self._set_special(memory)
+        if memory.extd_number in self.SPECIAL_60M.keys():
+            return self._set_special_60M(memory)
         else:
             return FT817Radio.set_memory(self, memory)
diff -r 4373b2839103 -r a06e9886b986 chirp/ft857.py
--- a/chirp/ft857.py	Mon Feb 20 20:06:04 2012 -0800
+++ b/chirp/ft857.py	Tue Mar 27 18:41:00 2012 +0200
@@ -17,14 +17,7 @@
 from chirp import ft817, chirp_common, errors, directory
 from chirp import bitwise
 
-mem_format = """
-#seekto 0x4a9;
-u8 visible[25];
-
-#seekto 0x4c4;
-u8 filled[25];
-
-#seekto 0x4df;
+mem_struct = """
 struct {
   u8   tag_on_off:1,
        tag_default:1,
@@ -59,52 +52,58 @@
   u32 freq;
   u32 offset;
   u8   name[8];
-} memory[200];
+}
+"""
+
+# there is a bug in bitwise_grammar that prevent the definition of single structures
+# qmb should be only one mem_struct followed by
+#""" + mem_struct + """ mtqmb;
+# but both qmb and qmb[1] raise an exception so I had to define it as qmb[2]
+
+mem_format = """
+#seekto 0x54;
+""" + mem_struct + """ vfoa[16];
+""" + mem_struct + """ vfob[16];
+""" + mem_struct + """ home[4];
+""" + mem_struct + """ qmb[2];
+""" + mem_struct + """ mtune;
+
+#seekto 0x4a9;
+u8 visible[25];
+u16 pmsvisible;
+
+#seekto 0x4c4;
+u8 filled[25];
+u16 pmsfilled;
+
+#seekto 0x4df;
+""" + mem_struct + """ memory[200];
+""" + mem_struct + """ pms[10];
 
 #seekto 0x1CAD;
-struct {
-  u8   tag_on_off:1,
-       tag_default:1,
-       unknown1:3,
-       mode:3;
-  u8   duplex:2,
-       is_duplex:1,
-       is_cwdig_narrow:1,
-       is_fm_narrow:1,
-       freq_range:3;
-  u8   skip:1,
-       unknokwn1_1:1,
-       ipo:1,
-       att:1,
-       unknown2:4;
-  u8   ssb_step:2,
-       am_step:3,
-       fm_step:3;
-  u8   unknown3:3,
-       is_split_tone:1,
-       tmode:4;
-  u8   unknown4:2,
-       tx_mode:3,
-       tx_freq_range:3;
-  u8   unknown5:2,
-       tone:6;
-  u8   unknown6:8;
-  u8   unknown7:1,
-       dcs:7;
-  u8   unknown8:8;
-  ul16 rit;
-  u32 freq;
-  u32 offset;
-  u8   name[8];
-} sixtymeterchannels[5];
+""" + mem_struct + """ sixtymeterchannels[5];
 
 """
 
 
+SPECIAL_PMS = {          # WARNING Index are hard wired in memory management code !!!
+    "PMS-1L" : -47,
+    "PMS-1U" : -46,
+    "PMS-2L" : -45,
+    "PMS-2U" : -44,
+    "PMS-3L" : -43,
+    "PMS-3U" : -42,
+    "PMS-4L" : -41,
+    "PMS-4U" : -40,
+    "PMS-5L" : -39,
+    "PMS-5U" : -38,
+}
+
 
 @directory.register
 class FT857Radio(ft817.FT817Radio):
     MODEL = "FT-857"
+    _model = ""
 
     TMODES = {
         0x04 : "Tone",
@@ -137,12 +136,55 @@
         "Off->DCS"   : 0x02,
     }
 
-    _model = ""
     _memsize = 7341
     # block 9 (140 Bytes long) is to be repeted 40 times 
-    # should be 42 times but this way I cam use original 817 functions
+    # should be 42 times but this way I can use original 817 functions
     _block_lengths = [ 2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140, 38, 176]
 
+    SPECIAL_MEMORIES = {        # WARNING Index are hard wired in memory management code !!!
+        "VFOa-1.8M" : -37,
+        "VFOa-3.5M" : -36,
+        "VFOa-5M" : -35,
+        "VFOa-7M" : -34,
+        "VFOa-10M" : -33,
+        "VFOa-14M" : -32,
+        "VFOa-18M" : -31,
+        "VFOa-21M" : -30,
+        "VFOa-24M" : -29,
+        "VFOa-28M" : -28,
+        "VFOa-50M" : -27,
+        "VFOa-FM" : -26,
+        "VFOa-AIR" : -25,
+        "VFOa-144" : -24,
+        "VFOa-430" : -23,
+        "VFOa-HF" : -22,
+        "VFOb-1.8M" : -21,
+        "VFOb-3.5M" : -20,
+        "VFOb-5M" : -19,
+        "VFOb-7M" : -18,
+        "VFOb-10M" : -17,
+        "VFOb-14M" : -16,
+        "VFOb-18M" : -15,
+        "VFOb-21M" : -14,
+        "VFOb-24M" : -13,
+        "VFOb-28M" : -12,
+        "VFOb-50M" : -11,
+        "VFOb-FM" : -10,
+        "VFOb-AIR" : -9,
+        "VFOb-144M" : -8,
+        "VFOb-430M" : -7,
+        "VFOb-HF" : -6,
+        "HOME HF" : -5,
+        "HOME 50M" : -4,
+        "HOME 144M" : -3,
+        "HOME 430M" : -2,
+        "QMB" : -1,
+    }
+    FIRST_VFOB_INDEX = -6
+    LAST_VFOB_INDEX = -21
+    FIRST_VFOA_INDEX = -22
+    LAST_VFOA_INDEX = -37
+
     def get_features(self):
         rf = ft817.FT817Radio.get_features(self)
         rf.has_cross = True
@@ -174,13 +216,64 @@
     def process_mmap(self):
         self._memobj = bitwise.parse(mem_format, self._mmap)
 
-SPECIAL_60M = {
-    "M-601" : -1,
-    "M-602" : -2,
-    "M-603" : -3,
-    "M-604" : -4,
-    "M-605" : -5,
-    }
+    def get_special_locations(self):
+        lista = SPECIAL_PMS.keys()
+        lista.extend(self.SPECIAL_MEMORIES)
+        return lista
+
+    def _get_special_pms(self, number):
+        mem = chirp_common.Memory()
+        mem.number = SPECIAL_PMS[number]
+        mem.extd_number = number
+
+	bitindex = -38 - mem.number
+        used = ((self._memobj.pmsvisible & self._memobj.pmsfilled) >> bitindex) & 0x01
+	print "mem.number %i bitindex %i pmsvisible %i pmsfilled %i used %i" % (mem.number, bitindex, self._memobj.pmsvisible, self._memobj.pmsfilled, used)
+        if not used:
+            mem.empty = True
+            return mem
+
+        _mem = self._memobj.pms[47 + mem.number]
+
+        mem = self._get_memory(mem, _mem)
+
+        mem.immutable = ["number", "skip", "rtone", "ctone",
+                         "extd_number", "dtcs", "tmode", "cross_mode",
+                         "dtcs_polarity", "power", "duplex", "offset",
+                         "comment", "empty"]
+
+        return mem
+
+    def _set_special_pms(self, mem):
+        cur_mem = self._get_special(mem.extd_number)
+
+	bitindex = -38 - mem.number
+	if mem.empty:
+            self._memobj.pmsvisible &= ~ (1 << bitindex)
+            self._memobj.pmsfilled = self._memobj.pmsvisible
+            return
+        self._memobj.pmsvisible |=  1 << bitindex
+        self._memobj.pmsfilled = self._memobj.pmsvisible
+        
+        for key in cur_mem.immutable:
+            if cur_mem.__dict__[key] != mem.__dict__[key]:
+                raise errors.RadioError("Editing field `%s' " % key +
+                                        "is not supported on PMS channels")
+
+        _mem = self._memobj.pms[47 + mem.number]
+        self._set_memory(mem, _mem)
+
+    def get_memory(self, number):
+        if number in SPECIAL_PMS.keys():
+            return self._get_special_pms(number)
+        else:
+            return ft817.FT817Radio.get_memory(self, number)
+
+    def set_memory(self, memory):
+        if memory.extd_number in SPECIAL_PMS.keys():
+            return self._set_special_pms(memory)
+        else:
+            return ft817.FT817Radio.set_memory(self, memory)
 
 @directory.register
 class FT857_US_Radio(FT857Radio):
@@ -191,30 +284,43 @@
     _model = ""
     _memsize = 7481
     # block 9 (140 Bytes long) is to be repeted 40 times 
-    # should be 42 times but this way I cam use original 817 functions
+    # should be 42 times but this way I can use original 817 functions
     _block_lengths = [ 2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140, 38, 176, 140]
 
 
+    SPECIAL_60M = {
+        "M-601" : -52,
+        "M-602" : -51,
+        "M-603" : -50,
+        "M-604" : -49,
+        "M-605" : -48,
+        }
+    LAST_SPECIAL60M_INDEX = -52
+    
     def get_special_locations(self):
-        return SPECIAL_60M.keys()
+        lista = self.SPECIAL_60M.keys()
+        lista.extend(FT857Radio.get_special_locations(self))
+        return lista
 
-    def _get_special(self, number):
+    # this is identical to the one in FT817ND_US_Radio but we inherit from 857
+    def _get_special_60M(self, number):
         mem = chirp_common.Memory()
-        mem.number = SPECIAL_60M[number]
+        mem.number = self.SPECIAL_60M[number]
         mem.extd_number = number
 
-        _mem = self._memobj.sixtymeterchannels[abs(mem.number)-1]
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
 
-        self._get_memory(mem, _mem)
+        mem = self._get_memory(mem, _mem)
 
         mem.immutable = ["number", "skip", "rtone", "ctone",
                          "extd_number", "name", "dtcs", "tmode", "cross_mode",
                          "dtcs_polarity", "power", "duplex", "offset",
-                         "tuning_step", "comment", "empty"]
+                         "comment", "empty"]
 
         return mem
 
-    def _set_special(self, mem):
+    # this is identical to the one in FT817ND_US_Radio but we inherit from 857
+    def _set_special_60M(self, mem):
         cur_mem = self._get_special(mem.extd_number)
 
         for key in cur_mem.immutable:
@@ -225,17 +331,17 @@
         if mem.mode not in ["USB", "LSB", "CW", "CWR", "NCW", "NCWR", "DIG"]:
             raise errors.RadioError(_("Mode {mode} is not valid "
                                       "in 60m channels").format(mode=mem.mode))
-        _mem = self._memobj.sixtymeterchannels[abs(mem.number)-1]
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
         self._set_memory(mem, _mem)
 
     def get_memory(self, number):
-        if isinstance(number, str):
-            return self._get_special(number)
+        if number in self.SPECIAL_60M.keys():
+            return self._get_special_60M(number)
         else:
             return FT857Radio.get_memory(self, number)
 
     def set_memory(self, memory):
-        if memory.number < 0:
-            return self._set_special(memory)
+        if memory.extd_number in self.SPECIAL_60M.keys():
+            return self._set_special_60M(memory)
         else:
             return FT857Radio.set_memory(self, memory)



More information about the chirp_devel mailing list