# HG changeset patch # User Patrick Lang # Date 1420151967 28800 # Thu Jan 01 14:39:27 2015 -0800 # Node ID a54fca6875d18b5b7be644735e6c9ad7c42b4352 # Parent 1d6fb56e2220b39b4b23239a9edfb3afa965f4b1 [FT-60] Feature Request: Memory Bank Support #1945 diff -r 1d6fb56e2220 -r a54fca6875d1 chirp/ft60.py --- a/chirp/ft60.py Sun Dec 28 23:53:43 2014 -0800 +++ b/chirp/ft60.py Thu Jan 01 14:39:27 2015 -0800 @@ -17,6 +17,7 @@ from chirp import chirp_common, yaesu_clone, memmap, bitwise, directory from chirp import errors from textwrap import dedent +from collections import defaultdict ACK = "\x06" @@ -148,10 +149,94 @@ unknown2:7; } names[1000]; +#seekto 0x69c8; +struct { + u8 bitmap[128]; +} bank_channels[10]; + #seekto 0x6FC8; u8 checksum; """ +class FT60BankModel(chirp_common.MTOBankModel): + """Memory Bank Model for FT60""" + # Banks are numbered 1-10 on the radio + # Each memory can be in zero or more banks + + def __init__(self, radio): + super(FT60BankModel, self).__init__(radio) + self.__b2m_cache = defaultdict(list) + self.__m2b_cache = defaultdict(list) + + def __precache(self): + if self.__b2m_cache: + return + + for bank in self.get_mappings(): + self.__b2m_cache[bank.index] = self._get_bank_memories(bank) + for memnum in self.__b2m_cache[bank.index]: + self.__m2b_cache[memnum].append(bank.index) + + def _get_bank_memories(self, bank): + # Returns array of memory indexes (1-indexed) contained in bank + memories = [] + upper = self._radio.get_features().memory_bounds[1] + for i in range(0, upper+1): + _bitmap = self._radio._memobj.bank_channels[bank.index].bitmap[i/8] + ishft = i % 8 #7 - (i % 8) + if _bitmap & (1 << ishft): + memories.append(i + 1) + return memories + + def get_num_mappings(self): + return 10 # equal to size of bank_channels in MEM_FORMAT + + def get_mappings(self): + # mappings always exist for banks 1-10, even if empty. Just return list of all banks + banks = [] + for i in range(0, self.get_num_mappings()): + bank = chirp_common.Bank(self, "%i" % i, "BANK-%i" % (i + 1)) + bank.index = i + banks.append(bank) + return banks + + def add_memory_to_mapping(self, memory, bank): + self.__precache() + + index = memory.number - 1 + _bitmap = self._radio._memobj.bank_channels[bank.index] + ishft = index % 8 + _bitmap.bitmap[index / 8] |= (1 << ishft) + self.__m2b_cache[memory.number].append(bank.index) + self.__b2m_cache[bank.index].append(memory.number) + + def remove_memory_from_mapping(self, memory, bank): + self.__precache() + + index = memory.number - 1 + _bitmap = self._radio._memobj.bank_channels[bank.index] + ishft = index % 8 + if not (_bitmap.bitmap[index / 8] & (1 << ishft)): + raise Exception("Memory {num} is " + + "not in bank {bank}".format(num=memory.number, + bank=bank)) + _bitmap.bitmap[index / 8] &= ~(1 << ishft) + self.__b2m_cache[bank.index].remove(memory.number) + self.__m2b_cache[memory.number].remove(bank.index) + + def get_mapping_memories(self, bank): + self.__precache() + + return [self._radio.get_memory(n) + for n in self.__b2m_cache[bank.index]] + + def get_memory_mappings(self, memory): + self.__precache() + + _banks = self.get_mappings() + return [_banks[b] for b in self.__m2b_cache[memory.number]] + + DUPLEX = ["", "", "-", "+", "split"] TMODES = ["", "Tone", "TSQL", "TSQL-R", "DTCS"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.0), @@ -206,10 +291,12 @@ rf.valid_bands = [(108000000, 520000000), (700000000, 999990000)] rf.can_odd_split = True rf.has_ctone = False - rf.has_bank = False + rf.has_bank = True rf.has_dtcs_polarity = False + return rf - return rf + def get_bank_model(self): + return FT60BankModel(self) def _checksums(self): return [ yaesu_clone.YaesuChecksum(0x0000, 0x6FC7) ]