[chirp_devel] [PATCH] [ft1802] Add support for Yaesu FT-1802. #273

Tom Hayward
Wed Sep 5 13:23:41 PDT 2012


# HG changeset patch
# User Tom Hayward <tom at tomh.us>
# Date 1346803573 21600
# Node ID 399056e3b5df7308907dd83a3425d62967c0a168
# Parent  59e3294b7d91870406bd4ec97b53878168543d98
[ft1802] Add support for Yaesu FT-1802. #273

diff -r 59e3294b7d91 -r 399056e3b5df chirp/ft1802.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chirp/ft1802.py	Tue Sep 04 18:06:13 2012 -0600
@@ -0,0 +1,232 @@
+# Copyright 2012 Tom Hayward <tom at tomh.us>
+#
+# 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/>.
+
+# FT-1802 Clone Proceedure
+# 1. Turn radio off.
+# 2. Connect cable to mic jack.
+# 3. Press and hold in the [LOW(A/N)] key while turning the radio on.
+# 4. In Chirp, choose Download from Radio.
+# 5. Press the [MHz(SET)] key to send image.
+# or
+# 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD).
+# 5. In Chirp, choose Upload to Radio.
+
+from chirp import chirp_common, bitwise, directory, yaesu_clone
+from chirp.settings import RadioSetting, RadioSettingGroup, \
+    RadioSettingValueBoolean
+
+MEM_FORMAT = """
+#seekto 0x06ea;
+struct {
+  u8 odd_pskip:1,
+     odd_skip:1,
+     odd_visible:1,
+     odd_valid:1,
+     even_pskip:1,
+     even_skip:1,
+     even_visible:1,
+     even_valid:1;
+} flags[100];
+
+#seekto 0x076a;
+struct {
+  u8 unknown1a:1,
+     step_changed:1,
+     narrow:1,
+     clk_shift:1,
+     unknown1b:4;
+  u8 unknown2a:2,
+     duplex:2,
+     unknown2b:1,
+     tune_step:3;
+  bbcd freq[3];
+  u8 power:2,
+     unknown3:3,
+     tmode:3;
+  u8 name[6];
+  bbcd offset[3];
+  u8 tone;
+  u8 dtcs;
+  u8 unknown4;
+} memory[200];
+"""
+
+
+MODES = ["FM", "NFM"]
+TMODES = ["", "Tone", "TSQL", "DTCS", "TSQL-R", "Cross"]
+CROSS_MODES = ["DTCS->", "Tone->DTCS", "DTCS->Tone"]
+DUPLEX = ["", "-", "+", "split"]
+STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0]
+POWER_LEVELS = [chirp_common.PowerLevel("LOW1", watts=5),
+                chirp_common.PowerLevel("LOW2", watts=10),
+                chirp_common.PowerLevel("LOW3", watts=25),
+                chirp_common.PowerLevel("HIGH", watts=50),
+                ]
+CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-/?()?_"
+
+
+ at directory.register
+class FT1802Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu FT-1802"""
+    VENDOR = "Yaesu"
+    MODEL = "FT-1802M"
+    BAUD_RATE = 19200
+
+    _model = "AH023"
+    _block_lengths = [10, 8001]
+    _memsize = 8011
+
+    def get_features(self):
+        rf = chirp_common.RadioFeatures()
+
+        rf.memory_bounds = (0, 199)
+
+        rf.has_ctone = False
+        rf.has_tuning_step = True
+        rf.has_dtcs_polarity = False # in radio settings, not per memory
+        rf.has_bank = False # has banks, but not implemented
+
+        rf.valid_tuning_steps = STEPS
+        rf.valid_modes = MODES
+        rf.valid_tmodes = TMODES
+        rf.valid_bands = [(137000000, 174000000)]
+        rf.valid_power_levels = POWER_LEVELS
+        rf.valid_duplexes = DUPLEX
+        rf.valid_skips = ["", "S", "P"]
+        rf.valid_name_length = 6
+        rf.valid_characters = CHARSET
+        rf.has_cross = True
+        rf.valid_cross_modes = list(CROSS_MODES)
+
+        return rf
+
+    def _checksums(self):
+        return [yaesu_clone.YaesuChecksum(0, self._memsize-2)]
+
+    def process_mmap(self):
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
+
+    def get_raw_memory(self, number):
+        return repr(self._memobj.memory[number]) + \
+               repr(self._memobj.flags[number/2])
+
+    def get_memory(self, number):
+        _mem = self._memobj.memory[number]
+        _flag = self._memobj.flags[number/2]
+
+        nibble = (number % 2) and "odd" or "even"
+        visible = _flag["%s_visible" % nibble]
+        valid = _flag["%s_valid" % nibble]
+        pskip = _flag["%s_pskip" % nibble]
+        skip = _flag["%s_skip" % nibble]
+
+        mem = chirp_common.Memory()
+        mem.number = number
+
+        if not visible:
+            mem.empty = True
+        if not valid:
+            mem.empty = True
+            return mem
+
+        mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000)
+        mem.offset = chirp_common.fix_rounded_step(int(_mem.offset) * 1000)
+        mem.duplex = DUPLEX[_mem.duplex]
+        mem.tuning_step = _mem.step_changed and STEPS[_mem.tune_step] or STEPS[0]
+        if _mem.tmode < TMODES.index("Cross"):
+            mem.tmode = TMODES[_mem.tmode]
+            mem.cross_mode = CROSS_MODES[0]
+        else:
+            mem.tmode = "Cross"
+            mem.cross_mode = CROSS_MODES[_mem.tmode - TMODES.index("Cross")]
+        mem.rtone = chirp_common.TONES[_mem.tone]
+        mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs]
+        for i in _mem.name:
+            if i == 0xFF:
+                break
+            if i & 0x80 == 0x80:
+                # first bit in name is "show name"
+                mem.name += CHARSET[0x80 ^ int(i)]
+            else:
+                mem.name += CHARSET[i]
+        mem.mode = _mem.narrow and "NFM" or "FM"
+        mem.skip = pskip and "P" or skip and "S" or ""
+        mem.power = POWER_LEVELS[_mem.power]
+
+        mem.extra = RadioSettingGroup("extra", "Extra Settings")
+        rs = RadioSetting("clk_shift", "Clock Shift",
+                          RadioSettingValueBoolean(_mem.clk_shift))
+        mem.extra.append(rs)
+
+        return mem
+
+    def set_memory(self, mem):
+        _mem = self._memobj.memory[mem.number]
+        _flag = self._memobj.flags[mem.number/2]
+
+        nibble = (mem.number % 2) and "odd" or "even"
+        
+        valid = _flag["%s_valid" % nibble]
+        visible = _flag["%s_visible" % nibble]
+
+        if not mem.empty and not valid:
+            _flag["%s_valid" % nibble] = True
+            _mem.unknown1a = 0x00
+            _mem.clk_shift = 0x00
+            _mem.unknown1b = 0x00
+            _mem.unknown2a = 0x00
+            _mem.unknown2b = 0x00
+            _mem.unknown3 = 0x00
+            _mem.unknown4 = 0x00
+
+        if mem.empty and valid and not visible:
+            _flag["%s_valid" % nibble] = False
+            return
+        _flag["%s_visible" % nibble] = not mem.empty
+
+        if mem.empty:
+            return
+
+        _flag["%s_valid" % nibble] = True
+
+        _mem.freq = mem.freq / 1000
+        _mem.offset = mem.offset / 1000
+        _mem.duplex = DUPLEX.index(mem.duplex)
+        _mem.tune_step = STEPS.index(mem.tuning_step)
+        _mem.step_changed = mem.tuning_step != STEPS[0]
+        if mem.tmode != "Cross":
+            _mem.tmode = TMODES.index(mem.tmode)
+        else:
+            _mem.tmode = TMODES.index("Cross") + CROSS_MODES.index(mem.cross_mode)
+        _mem.tone = chirp_common.TONES.index(mem.rtone)
+        _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs)
+
+        _mem.name = [0xFF] * 6
+        for i in range(0, len(mem.name)):
+            try:
+                _mem.name[i] = CHARSET.index(mem.name[i])
+            except IndexError:
+                raise Exception("Character `%s' not supported")
+        if _mem.name[0] != 0xFF:
+            _mem.name[0] += 0x80 # show name instead of frequency
+
+        _mem.narrow = MODES.index(mem.mode)
+        _mem.power = POWER_LEVELS.index(mem.power)
+
+        _flag["%s_pskip" % nibble] = mem.skip == "P"
+        _flag["%s_skip" % nibble] = mem.skip == "S"
+
+        for element in mem.extra:
+            setattr(_mem, element.get_name(), element.value)



More information about the chirp_devel mailing list