Project

General

Profile

New Model #4279 » ftm3200dr.py

Andrew Coursen, 01/10/2017 07:45 PM

 
# - Other Notes
# In memedit, around line 1353 need to add:
# self.choices[_("Tune Step")] = self._features["valid_tuning_steps"]



# Copyright 2013 Dan Smith <dsmith@danplanet.com>
#
# 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/>.

from chirp.drivers import yaesu_clone

from chirp import chirp_common, directory, memmap
from chirp import bitwise

from chirp.settings import RadioSetting, RadioSettingGroup, RadioSettingValueList

MEM_FORMAT = """
#seekto 0x2d4a;
struct {
u8 unknown1[1];
u8 rptshift[1];
bbcd freq[3];
u8 txpwr:2,
unknown2:2,
tmode:4;
u8 unknown3[2];
char name[8];
u8 name2[8];
bbcd rptoffset[3];
u8 ctcss[1];
u8 dtcs[1];
u8 unknown4[1];
u8 unknown5:4,
rfsquelch:4;
u8 unknown6[1];
} memory[199];


#seekto 0xceca;
struct {
u8 unknown5;
u8 unknown3;
u8 unknown4:6,
dsqtype:2;
u8 dsqcode;
u8 unknown1[2];
char mycall[10];
u8 unknown2[368];
} settings;
"""
#still to find in memory:
# -split\transmitfreq (i'm guessing a bbcd[3])
# -masked (bool)
# -bell (bool)
# -scanskip (preferential, skip, off)
# -clktype (bool)
# -digital\analog
# -tuning step


POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5),
chirp_common.PowerLevel("Mid", watts=30),
chirp_common.PowerLevel("Hi", watts=65)]
TMODES = ["", "Tone", "TSQL", "DTCS", "TSQL-R", "PAGER"]
MODES = ["NFM","FM"]
TUNING_STEPS = [0,5,6.25,10,12.5,15,20,25,50,100] # 0 = auto
DTCS_POLS = ["NORMAL","INVERT","BOTH"]
RFSQUELCH = ["OFF","S1","S2","S3","S4","S5","S6","S7","S8"]

@directory.register
class FTM3200DRRadio(yaesu_clone.YaesuCloneModeRadio):
"""Yaesu FTM-3200DR"""
VENDOR = "Yaesu"
MODEL = "FTM-3200DR"
BAUD_RATE = 38400
_block_lengths = [10, 65536]
_block_size = 16 #i increased this because it took so long but if it messes up, then it probably needs to be 8
_memsize = 65227
_model = "AH52N"


def get_features(self):
rf = chirp_common.RadioFeatures()
rf.has_bank = True
rf.has_dtcs_polarity = False #can't get to work (ValueError: `NORMAL' is not in valid list: ['NN', 'NR', 'RN', 'RR'])
rf.memory_bounds = (1, 199)
rf.valid_bands = [(136000000, 174000000)]#these are valid receiving not transmitting
rf.valid_power_levels = POWER_LEVELS
rf.valid_tuning_steps = TUNING_STEPS
rf.valid_dtcs_pols = DTCS_POLS
rf.valid_name_length = 8
rf.can_odd_split = True
rf.valid_tmodes = TMODES
rf.valid_modes = MODES

return rf

def _checksums(self):
"""Return a list of checksum objects that need to be calculated"""
return [yaesu_clone.YaesuChecksum(0x0000, 0xFEC9)]

def process_mmap(self):
self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)

def get_raw_memory(self, number):
return repr(self._memobj.memory[number])


def get_memory(self, number):
# Get a low-level memory object mapped to the image
_mem = self._memobj.memory[number-1]

# Create a high-level memory object to return to the UI
mem = chirp_common.Memory()
mem.extra = RadioSettingGroup("Extra", "extra")

mem.number = number

mem.freq = int(_mem.freq) * 1000
#if the frequency = bbcd 0xffffff = 0 assume empty
if mem.freq == 1666665000:
mem.freq = 0
mem.empty = True
return mem

mem.name = str(_mem.name).rstrip(chr(0xff))
mem.offset = int(_mem.rptoffset) * 1000
mem.tmode = TMODES[_mem.tmode]
mem.rtone = chirp_common.TONES[_mem.ctcss]
mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs]
mem.tuning_step = TUNING_STEPS[0]
mem.power = POWER_LEVELS[_mem.txpwr-1]
#mem.rptshift
#x20 (00100000) = plus
#x10 (00010000) = minus
#x04 (00000100) = tx disabled (maybe)
#x00 (00000000) = simplex
if _mem.rptshift == 0x20:
mem.duplex = '+'
elif _mem.rptshift == 0x10:
mem.duplex = '-'
else:
mem.duplex = ''

mem.extra.append(RadioSetting("rfsquelch","RF Squelch",RadioSettingValueList(RFSQUELCH,RFSQUELCH[int(_mem.rfsquelch)])))

return mem

def set_memory(self, mem):
# Get a low-level memory object mapped to the image
_mem = self._memobj.memory[mem.number-1]
if mem.empty:
#blank the row in 0xff
_mem.set_raw(b'\xFF'*32)
return
else:
#set default since I don't know what all the bits do and these work while the bitwise defaults do not
_mem.set_raw(b'\x00\x00\x14\x65\x20\xC0\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x06\x00\x0C\x00\x0D\x00\x18')
_mem.freq = mem.freq / 1000
_mem.name = mem.name.ljust(8)[:8] # Store the alpha tag
_mem.rptoffset = mem.offset / 1000
_mem.ctcss = chirp_common.TONES.index(mem.rtone)
_mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs)
#mem.tuning_step = TUNING_STEPS[0]
_mem.txpwr = POWER_LEVELS.index(mem.power) + 1
_mem.tmode = TMODES.index(mem.tmode)

#not sure what this does but when there is is a name it is all \xFF otherwise it is all \x20
for byte in _mem.name2:
byte.set_raw(b'\x00') # only have seen \x00

#mem.rptshift
#x20 (00100000) = plus
#x10 (00010000) = minus
#x04 (00000100) = tx disabled (maybe)
#x00 (00000000) = simplex
if mem.duplex == '+':
_mem.rptshift = 0x20
elif mem.duplex == '-':
_mem.rptshift = 0x10
else:
_mem.rptshift = 0x00
for setting in mem.extra:
if setting.get_name() == 'rfsquelch':
_mem.rfsquelch = RFSQUELCH.index(str(setting.value))

(1-1/2)