Project

General

Profile

New Model #4279 » ftm3200dr.py

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

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

    
5

    
6

    
7
# Copyright 2013 Dan Smith <dsmith@danplanet.com>
8
#
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, either version 3 of the License, or
12
# (at your option) any later version.
13
#
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21

    
22
from chirp.drivers import yaesu_clone
23

    
24
from chirp import chirp_common, directory, memmap
25
from chirp import bitwise
26

    
27
from chirp.settings import RadioSetting, RadioSettingGroup, RadioSettingValueList
28

    
29
MEM_FORMAT = """
30
#seekto 0x2d4a;
31
struct {
32
  u8 unknown1[1];
33
  u8 rptshift[1];
34
  bbcd freq[3];
35
  u8 txpwr:2,
36
     unknown2:2,
37
     tmode:4;
38
  u8 unknown3[2];
39
  char name[8];
40
  u8 name2[8];
41
  bbcd rptoffset[3];
42
  u8 ctcss[1];
43
  u8 dtcs[1];
44
  u8 unknown4[1];
45
  u8 unknown5:4,
46
     rfsquelch:4;
47
  u8 unknown6[1];
48
} memory[199];
49

    
50

    
51
#seekto 0xceca;
52
struct {
53
  u8 unknown5;
54
  u8 unknown3;
55
  u8 unknown4:6,
56
     dsqtype:2;
57
  u8 dsqcode;
58
  u8 unknown1[2];
59
  char mycall[10];
60
  u8 unknown2[368];
61
} settings;
62
"""
63
#still to find in memory: 
64
# -split\transmitfreq (i'm guessing a bbcd[3])
65
# -masked (bool)
66
# -bell (bool)
67
# -scanskip (preferential, skip, off)
68
# -clktype (bool)
69
# -digital\analog
70
# -tuning step
71

    
72

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

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

    
94

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

    
109
        return rf
110

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

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

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

    
121

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

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

    
130
        mem.number = number
131

    
132
        mem.freq = int(_mem.freq) * 1000
133
        #if the frequency = bbcd 0xffffff = 0 assume empty
134
        if mem.freq == 1666665000:
135
            mem.freq = 0
136
            mem.empty = True
137
            return mem
138

    
139
        mem.name = str(_mem.name).rstrip(chr(0xff))
140
        mem.offset = int(_mem.rptoffset) * 1000
141
        mem.tmode = TMODES[_mem.tmode]
142
        mem.rtone = chirp_common.TONES[_mem.ctcss]
143
        mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs]
144
        mem.tuning_step = TUNING_STEPS[0]
145
        mem.power = POWER_LEVELS[_mem.txpwr-1]
146
        
147
        #mem.rptshift
148
        #x20 (00100000) = plus
149
        #x10 (00010000) = minus
150
        #x04 (00000100) = tx disabled (maybe)
151
        #x00 (00000000) = simplex
152
        if _mem.rptshift == 0x20:
153
		    mem.duplex = '+'
154
        elif _mem.rptshift == 0x10:
155
            mem.duplex = '-'
156
        else:
157
            mem.duplex = ''
158

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

    
162
        return mem
163

    
164
    def set_memory(self, mem):
165
        # Get a low-level memory object mapped to the image
166
        _mem = self._memobj.memory[mem.number-1]
167
        
168
        if mem.empty:
169
            #blank the row in 0xff
170
            _mem.set_raw(b'\xFF'*32)
171
            return
172
        else:
173
            #set default since I don't know what all the bits do and these work while the bitwise defaults do not
174
            _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')
175
            
176
            
177
        _mem.freq = mem.freq / 1000
178
        _mem.name = mem.name.ljust(8)[:8]  # Store the alpha tag
179
        _mem.rptoffset = mem.offset / 1000
180
        _mem.ctcss = chirp_common.TONES.index(mem.rtone)
181
        _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs)
182
        #mem.tuning_step = TUNING_STEPS[0]
183
        _mem.txpwr = POWER_LEVELS.index(mem.power) + 1
184
        _mem.tmode = TMODES.index(mem.tmode)
185

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

    
190
        
191
        #mem.rptshift
192
        #x20 (00100000) = plus
193
        #x10 (00010000) = minus
194
        #x04 (00000100) = tx disabled (maybe)
195
        #x00 (00000000) = simplex
196
        if mem.duplex == '+':
197
		    _mem.rptshift = 0x20
198
        elif mem.duplex == '-':
199
            _mem.rptshift = 0x10
200
        else:
201
            _mem.rptshift = 0x00
202
        
203
        for setting in mem.extra:
204
            if setting.get_name() == 'rfsquelch':
205
                _mem.rfsquelch = RFSQUELCH.index(str(setting.value))
206
        
207

    
(1-1/2)