[chirp_devel] [PATCH] [ft2900] Add support for ft2900 banks (#2381)

Richard Cochran
Mon Mar 23 20:45:28 PDT 2015


# HG changeset patch
# User Richard Cochran <ag6qr at sonic.net>
# Date 1427168290 25200
#      Mon Mar 23 20:38:10 2015 -0700
# Node ID ee81cedd447b16eacca70ff6e8bff3552e4a5227
# Parent  05bc6d0ff5d3f7c48131963030ed3d393c456875
[ft2900] Add support for ft2900 banks (#2381)
This adds support for banks in the FT-2900/FT-1900.  This radio
implements banks in much the same way as the Yaesu VX-6, and much
of the code was lifted from the VX-6 driver.

diff -r 05bc6d0ff5d3 -r ee81cedd447b chirp/drivers/ft2900.py
--- a/chirp/drivers/ft2900.py	Thu Mar 19 21:08:24 2015 -0700
+++ b/chirp/drivers/ft2900.py	Mon Mar 23 20:38:10 2015 -0700
@@ -157,6 +157,11 @@
     _send(radio.pipe, chr(cs & 0xFF))
 
 MEM_FORMAT = """
+#seekto 0x00c0;
+struct {
+  u16 in_use;
+} bank_used[8];
+
 #seekto 0x00ef;
   u8 currentTone;
 
@@ -166,18 +171,32 @@
 #seekto 0x0127;
   u8 curChannelNum;
 
+#seekto 0x012a;
+  u8 banksoff1;
+
 #seekto 0x15f;
   u8 checksum1;
 
 #seekto 0x16f;
   u8 curentTone2;
 
-#seekto 0x1a7;
-  u8 curChannelMem2[20];
+#seekto 0x1aa;
+  u16 banksoff2;
 
 #seekto 0x1df;
   u8 checksum2;
 
+#seekto 0x0360;
+struct{
+  u8 name[6];
+} bank_names[8];
+
+
+#seekto 0x03c4;
+struct{
+  u16 channels[50];
+} banks[8];
+
 #seekto 0x06e4;
 struct {
   u8 even_pskip:1,
@@ -283,6 +302,98 @@
     mem.set_raw("\xff" * (mem.size() / 8))
 
 
+class FT2900Bank(chirp_common.NamedBank):
+    def get_name(self):
+        _bank = self._model._radio._memobj.bank_names[self.index]
+        name = ""
+        for i in _bank.name:
+            if i == 0xff:
+                break
+            name += CHARSET[i & 0x7f]
+
+        return name.rstrip()
+
+    def set_name(self, name):
+        name = name.upper().ljust(6)[:6]
+        _bank = self._model._radio._memobj.bank_names[self.index]
+        _bank.name = [CHARSET.index(x) for x in name.ljust(6)[:6]]
+
+
+class FT2900BankModel(chirp_common.BankModel):
+    def get_num_mappings(self):
+        return 8
+
+    def get_mappings(self):
+        banks = self._radio._memobj.banks
+        bank_mappings = []
+        for index, _bank in enumerate(banks):
+            bank = FT2900Bank(self, "%i" % index, "b%i" % (index + 1))
+            bank.index = index
+            bank_mappings.append(bank)
+
+        return bank_mappings
+
+    def _get_channel_numbers_in_bank(self, bank):
+        _bank_used = self._radio._memobj.bank_used[bank.index]
+        if _bank_used.in_use == 0xffff:
+            return set()
+
+        _members = self._radio._memobj.banks[bank.index]
+        return set([int(ch) for ch in _members.channels if ch != 0xffff])
+
+    def _update_bank_with_channel_numbers(self, bank, channels_in_bank):
+        _members = self._radio._memobj.banks[bank.index]
+        if len(channels_in_bank) > len(_members.channels):
+            raise Exception("More than %i entries in bank %d" %
+                            (len(_members.channels), bank.index))
+
+        empty = 0
+        for index, channel_number in enumerate(sorted(channels_in_bank)):
+            _members.channels[index] = channel_number
+            empty = index + 1
+        for index in range(empty, len(_members.channels)):
+            _members.channels[index] = 0xffff
+
+        _bank_used = self._radio._memobj.bank_used[bank.index]
+        if empty == 0:
+            _bank_used.in_use = 0xffff
+        else:
+            _bank_used.in_use = empty - 1
+
+    def add_memory_to_mapping(self, memory, bank):
+        channels_in_bank = self._get_channel_numbers_in_bank(bank)
+        channels_in_bank.add(memory.number)
+        self._update_bank_with_channel_numbers(bank, channels_in_bank)
+
+        # tells radio that banks are active
+        self._radio._memobj.banksoff1 = bank.index
+        self._radio._memobj.banksoff2 = bank.index
+
+    def remove_memory_from_mapping(self, memory, bank):
+        channels_in_bank = self._get_channel_numbers_in_bank(bank)
+        try:
+            channels_in_bank.remove(memory.number)
+        except KeyError:
+            raise Exception("Memory %i is not in bank %s. Cannot remove" %
+                            (memory.number, bank))
+        self._update_bank_with_channel_numbers(bank, channels_in_bank)
+
+    def get_mapping_memories(self, bank):
+        memories = []
+        for channel in self._get_channel_numbers_in_bank(bank):
+            memories.append(self._radio.get_memory(channel))
+
+        return memories
+
+    def get_memory_mappings(self, memory):
+        banks = []
+        for bank in self.get_mappings():
+            if memory.number in self._get_channel_numbers_in_bank(bank):
+                banks.append(bank)
+
+        return banks
+
+
 @directory.register
 class FT2900Radio(YaesuCloneModeRadio):
     """Yaesu FT-2900"""
@@ -303,7 +414,8 @@
         rf.has_rx_dtcs = True
         rf.has_cross = True
         rf.has_dtcs_polarity = False
-        rf.has_bank = False
+        rf.has_bank = True
+        rf.has_bank_names = True
 
         rf.valid_tuning_steps = STEPS
         rf.valid_modes = MODES
@@ -493,6 +605,9 @@
 
         LOG.debug("encoded mem\n%s\n" % (util.hexprint(_mem.get_raw()[0:20])))
 
+    def get_bank_model(self):
+        return FT2900BankModel(self)
+
     @classmethod
     def match_model(cls, filedata, filename):
         return len(filedata) == cls._memsize




More information about the chirp_devel mailing list