Project

General

Profile

New Model #1057 » tyt-uvf8d-1.0.patch

"hg diff" output for TYT TH-UVF8D support - Eric Wolak, 10/06/2013 01:39 PM

View differences:

chirp/chirp_common.py Tue Jul 30 17:59:18 2013 -0400 → chirp/chirp_common.py Sun Oct 06 13:38:26 2013 -0700
360 360
        else:
361 361
            dup = self.duplex
362 362

  
363
        return "Memory %i: %s%s%s %s (%s) r%.1f%s c%.1f%s d%03i%s%s [%.2f]"% \
363
        return "Memory %s: %s%s%s %s (%s) r%.1f%s c%.1f%s d%03i%s%s [%.2f]"% \
364 364
            (self.number,
365 365
             format_freq(self.freq),
366 366
             dup,
chirp/ict7h.py Tue Jul 30 17:59:18 2013 -0400 → chirp/ict7h.py Sun Oct 06 13:38:26 2013 -0700
57 57

  
58 58
    def get_features(self):
59 59
        rf = chirp_common.RadioFeatures()
60
        rf.memory_bounds = (0, 59)
60
        rf.memory_bounds = (1, 60)
61 61
        rf.valid_modes = list(MODES)
62 62
        rf.valid_tmodes = list(TMODES)
63 63
        rf.valid_duplexes = list(DUPLEX)
......
79 79
        return repr(self._memobj.memory[number])
80 80

  
81 81
    def get_memory(self, number):
82
        _mem = self._memobj.memory[number]
83
        _flag = self._memobj.flags[number]
82
        _mem = self._memobj.memory[number-1]
83
        _flag = self._memobj.flags[number-1]
84 84

  
85 85
        mem = chirp_common.Memory()
86 86
        mem.number = number
......
103 103
        return mem
104 104

  
105 105
    def set_memory(self, mem):
106
        _mem = self._memobj.memory[mem.number]
107
        _flag = self._memobj.flags[mem.number]
106
        _mem = self._memobj.memory[mem.number-1]
107
        _flag = self._memobj.flags[mem.number-1]
108 108

  
109 109
        _mem.freq = int(mem.freq / 100000)
110 110
        topfreq = int(mem.freq / 100000) * 100000
/dev/null Thu Jan 01 00:00:00 1970 +0000 → chirp/th_uvf8d.py Sun Oct 06 13:38:26 2013 -0700
1
# Copyright 2013 Dan Smith <dsmith@danplanet.com>, Eric Allen <eric@hackerengineer.net>
2
#
3
# This program is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation, either version 3 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15

  
16
"""TYT TH-UVF8D radio management module"""
17

  
18
# TODO: support FM Radio memories
19
# TODO: support bank B (another 128 memories)
20
# TODO: [setting] Battery Save
21
# TODO: [setting] Tail Eliminate
22
# TODO: [setting] Tail Mode
23

  
24

  
25
import struct
26

  
27
from chirp import chirp_common, bitwise, errors, directory, memmap, util
28
from chirp.settings import RadioSetting, RadioSettingGroup, \
29
    RadioSettingValueInteger, RadioSettingValueList, \
30
    RadioSettingValueList, RadioSettingValueBoolean, \
31
    RadioSettingValueString
32

  
33
def uvf8d_identify(radio):
34
    """Do identify handshake with TYT TH-UVF8D"""
35
    try:
36
        radio.pipe.write("\x02PROGRAM")
37
        ack = radio.pipe.read(2)
38
        if ack != "PG":
39
            raise errors.RadioError("Radio did not ACK first command: %x" % ord(ack))
40
    except:
41
        raise errors.RadioError("Unable to communicate with the radio")
42

  
43
    radio.pipe.write("\x02")
44
    ident = radio.pipe.read(32)
45
    radio.pipe.write("A")
46
    r = radio.pipe.read(1)
47
    if r != "A":
48
      raise errors.RadioError("Ack failed")
49
    return ident
50

  
51
def tyt_uvf8d_download(radio):
52
    data = uvf8d_identify(radio)
53
    for i in range(0, 0x4000, 0x20):
54
        msg = struct.pack(">cHb", "R", i, 0x20)
55
        radio.pipe.write(msg)
56
        block = radio.pipe.read(0x20 + 4)
57
        if len(block) != (0x20 + 4):
58
            raise errors.RadioError("Radio sent a short block")
59
        radio.pipe.write("A")
60
        ack = radio.pipe.read(1)
61
        if ack != "A":
62
            raise errors.RadioError("Radio NAKed block")
63
        data += block[4:]
64

  
65
        if radio.status_fn:
66
          status = chirp_common.Status()
67
          status.cur = i
68
          status.max = 0x4000
69
          status.msg = "Cloning from radio"
70
          radio.status_fn(status)
71

  
72
    radio.pipe.write("ENDR")
73

  
74
    return memmap.MemoryMap(data)
75

  
76
def tyt_uvf8d_upload(radio):
77
    """Upload to TYT TH-UVF8D"""
78
    data = uvf8d_identify(radio)
79
    
80
    radio.pipe.setTimeout(1)
81

  
82
    #if data != radio._mmap[:32]:
83
        #raise errors.RadioError("Model mis-match: \n%s\n%s" % (util.hexprint(data),
84
                                                               #util.hexprint(radio._mmap[:32])))
85

  
86
    for i in range(0, 0x4000, 0x20):
87
        addr = i + 0x20
88
        msg = struct.pack(">cHb", "W", i, 0x20)
89
        msg += radio._mmap[addr:addr+0x20]
90

  
91
        radio.pipe.write(msg)
92
        ack = radio.pipe.read(1)
93
        if ack != "A":
94
            raise errors.RadioError("Radio did not ack block %i" % i)
95

  
96
        if radio.status_fn:
97
            status = chirp_common.Status()
98
            status.cur = i
99
            status.max = 0x4000
100
            status.msg = "Cloning to radio"
101
            radio.status_fn(status)
102

  
103
    # End of clone?
104
    radio.pipe.write("ENDW")
105

  
106
    # Checksum?
107
    final_data = radio.pipe.read(3)
108

  
109
# these require working desktop software
110
# TODO: DTMF features (ID, delay, speed, kill, etc.)
111

  
112
# TODO: Display Name
113

  
114

  
115
UV8FD_MEM_FORMAT = """
116
struct memory {
117
  lbcd rx_freq[4];
118
  lbcd tx_freq[4];
119
  lbcd rx_tone[2];
120
  lbcd tx_tone[2];
121

  
122
  u8 apro:4,
123
     rpt_md:2,
124
     unknown1:2;
125
  u8 bclo:2,
126
     wideband:1,
127
     ishighpower:1,
128
     unknown21:1,
129
     vox:1,
130
     pttid:2;
131
  u8 unknown3:8;
132

  
133
  u8 unknown4:6,
134
     duplex:2;
135
  
136
  lbcd offset[4];
137

  
138
  char unknown5[4];
139

  
140
  char name[7];
141

  
142
  char unknown6[1];
143
};
144

  
145
struct fm_broadcast_memory {
146
  lbcd freq[3];
147
  u8 unknown;
148
};
149

  
150
struct enable_flags {
151
  bit flags[8];
152
};
153

  
154
#seekto 0x0020;
155
struct memory channels[128];
156

  
157
#seekto 0x2020;
158
struct memory vfo1;
159
struct memory vfo2;
160

  
161
#seekto 0x2060;
162
struct {
163
  u8 unknown2060:4,
164
     tot:4;
165
  u8 unknown2061;
166
  u8 squelch;
167
  u8 unknown2063:4,
168
     vox_level:4;
169
  u8 tuning_step;
170
  char unknown12;
171
  u8 lamp_t;
172
  char unknown11;
173
  u8 unknown2068;
174
  u8 ani:1,
175
     scan_mode:2,
176
     unknown2069:2,
177
     beep:1,
178
     tx_sel:1,
179
     roger:1;
180
  u8 light:2,
181
     led:2,
182
     unknown206a:1,
183
     autolk:1,
184
     unknown206ax:2;
185
  u8 unknown206b:1,
186
     b_display:2,
187
     a_display:2,
188
     ab_switch:1,
189
     dwait:1,
190
     mode:1;
191
  u8 dw:1,
192
     unknown206c:6,
193
     voice:1;
194
  u8 unknown206d:2,
195
     rxsave:2,
196
     opnmsg:2,
197
     lock_mode:2;
198
  u8 a_work_area:1,
199
     b_work_area:1,
200
     unknown206ex:6;
201
  u8 a_channel;
202
  u8 b_channel;
203
  u8 pad3[15];
204
  char ponmsg[7];
205
} settings;
206

  
207
#seekto 0x2E60;
208
struct enable_flags enable[16];
209
struct enable_flags skip[16];
210

  
211
#seekto 0x2FA0;
212
struct fm_broadcast_memory fm_current;
213

  
214
#seekto 0x2FA8;
215
struct fm_broadcast_memory fm_memories[20];
216
"""
217

  
218
THUVF8D_DUPLEX = ["", "-", "+"]
219
THUVF8D_CHARSET = "".join([chr(ord("0") + x) for x in range(0, 10)] +
220
                         [" -*+"] +
221
                         [chr(ord("A") + x) for x in range(0, 26)] +
222
                         ["_/"])
223
TXSEL_LIST = ["EDIT", "BUSY"]
224
LED_LIST = ["Off", "Auto", "On"]
225
MODE_LIST = ["Memory", "VFO"]
226
AB_LIST = ["A", "B"]
227
DISPLAY_LIST = ["Channel", "Frequency", "Name"]
228
LIGHT_LIST = ["Purple", "Orange", "Blue"]
229
RPTMD_LIST = ["Off", "Reverse", "Talkaround"]
230
VOX_LIST = ["1", "2", "3", "4", "5", "6", "7", "8"]
231
WIDEBAND_LIST = ["Narrow", "Wide"]
232
TOT_LIST = ["Off", "30s", "60s", "90s", "120s", "150s", "180s", "210s",
233
            "240s", "270s"]
234
SCAN_MODE_LIST = ["Time", "Carry", "Seek"]
235
OPNMSG_LIST = ["Off", "DC (Battery)", "Message"]
236

  
237
POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5),
238
                chirp_common.PowerLevel("Low", watts=0.5),
239
                ]
240

  
241
PTTID_LIST = ["Off", "BOT", "EOT", "Both"]
242
BCLO_LIST = ["Off", "Wave", "Call"]
243
APRO_LIST = ["Off", "Compander", "Scramble 1", "Scramble 2", "Scramble 3",
244
             "Scramble 4", "Scramble 5", "Scramble 6", "Scramble 7",
245
             "Scramble 8"]
246
LOCK_MODE_LIST = ["PTT", "Key", "Key+S", "All"]
247

  
248
TUNING_STEPS_LIST = ["2.5", "5.0", "6.25", "10.0", "12.5", "25.0", "50.0", "100.0"]
249
BACKLIGHT_TIMEOUT_LIST = ["1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"]
250

  
251
SPECIALS = {
252
    "VFO1": -2,
253
    "VFO2": -1,
254
    }
255

  
256
@directory.register
257
class TYTUVF8DRadio(chirp_common.CloneModeRadio):
258
    VENDOR = "TYT"
259
    MODEL = "TH-UV8FD"
260
    BAUD_RATE = 9600
261

  
262
    def get_features(self):
263
        rf = chirp_common.RadioFeatures()
264
        rf.memory_bounds = (1, 128)
265
        rf.has_bank = False
266
        rf.has_ctone = True
267
        rf.has_tuning_step = False
268
        rf.has_cross = False
269
        rf.has_rx_dtcs = True
270
        rf.has_settings = True
271
        rf.can_odd_split = False # it may actually be supported, but I haven't tested
272
        rf.valid_duplexes = THUVF8D_DUPLEX
273
        rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"]
274
        rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-"
275
        rf.valid_bands = [(136000000, 174000000),
276
                          (400000000, 520000000)]
277
        rf.valid_skips = ["", "S"]
278
        rf.valid_power_levels = POWER_LEVELS
279
        rf.valid_modes = ["FM", "NFM"]
280
        rf.valid_special_chans = SPECIALS.keys()
281
        rf.valid_name_length = 7
282
        return rf
283

  
284
    def sync_in(self):
285
        self._mmap = tyt_uvf8d_download(self)
286
        self.process_mmap()
287

  
288
    def sync_out(self):
289
        tyt_uvf8d_upload(self)
290

  
291
    @classmethod
292
    def match_model(cls, filedata, filename):
293
        return filedata.startswith("TYT-F10\x00")
294

  
295
    def process_mmap(self):
296
        self._memobj = bitwise.parse(UV8FD_MEM_FORMAT, self._mmap)
297

  
298
    def _decode_tone(self, toneval):
299
        pol = "N"
300
        rawval = (toneval[1].get_bits(0xFF) << 8) | toneval[0].get_bits(0xFF)
301
                              
302
        if toneval[0].get_bits(0xFF) == 0xFF:
303
            mode = ""
304
            val = 0
305
        elif toneval[1].get_bits(0xC0) == 0xC0:
306
            mode = "DTCS"
307
            val = int("%x" % (rawval & 0x3FFF))
308
            pol = "R"
309
        elif toneval[1].get_bits(0x80):
310
            mode = "DTCS"
311
            val = int("%x" % (rawval & 0x3FFF))
312
        else:
313
            mode = "Tone"
314
            val = int(toneval) / 10.0
315

  
316
        return mode, val, pol
317

  
318
    def _encode_tone(self, _toneval, mode, val, pol):
319
        toneval = 0
320
        if mode == "Tone":
321
            toneval = int("%i" % (val * 10), 16)
322
        elif mode == "DTCS":
323
            toneval = int("%i" % val, 16)
324
            toneval |= 0x8000
325
            if pol == "R":
326
                toneval |= 0x4000
327
        else:
328
            toneval = 0xFFFF
329

  
330
        _toneval[0].set_raw(toneval & 0xFF)
331
        _toneval[1].set_raw((toneval >> 8) & 0xFF)
332

  
333
    def get_raw_memory(self, number):
334
        return repr(self._memobj.channels[number - 1])
335

  
336
    def _get_memobjs(self, number):
337
        if isinstance(number, str):
338
            return (getattr(self._memobj, number.lower()), None)
339
        elif number < 0:
340
            for k, v in SPECIALS.items():
341
                if number == v:
342
                    return (getattr(self._memobj, k.lower()), None)
343
        else:
344
            return (self._memobj.channels[number - 1],
345
                    None)
346

  
347
    def get_memory(self, number):
348
        _mem, _name = self._get_memobjs(number)
349

  
350
        mem = chirp_common.Memory()
351

  
352
        if isinstance(number, str):
353
            mem.number = SPECIALS[number]
354
            mem.extd_number = number
355
        else:
356
            mem.number = number
357

  
358
        if _mem.get_raw().startswith("\xFF\xFF\xFF\xFF"):
359
            mem.empty = True
360
            return mem
361

  
362
        if isinstance(number, int):
363
            enabled = self._memobj.enable[(number - 1) / 8].flags[7-((number - 1) % 8)]
364
            dont_skip = self._memobj.skip[(number - 1) / 8].flags[7-((number - 1) % 8)]
365
        else:
366
            enabled = True
367
            dont_skip = True
368

  
369
        if not enabled:
370
          mem.empty = True
371
          return mem
372

  
373
        mem.freq = int(_mem.rx_freq) * 10
374

  
375
        txfreq = int(_mem.tx_freq) * 10
376

  
377
        mem.duplex = THUVF8D_DUPLEX[_mem.duplex]
378
        mem.offset = int(_mem.offset) * 10
379

  
380
        txmode, txval, txpol = self._decode_tone(_mem.tx_tone)
381
        rxmode, rxval, rxpol = self._decode_tone(_mem.rx_tone)
382

  
383
        chirp_common.split_tone_decode(mem,
384
                                      (txmode, txval, txpol),
385
                                      (rxmode, rxval, rxpol))
386

  
387
        mem.name = str(_mem.name).rstrip('\xFF ')
388

  
389
        if dont_skip:
390
          mem.skip = ""
391
        else:
392
          mem.skip = "S"
393
        mem.mode = _mem.wideband and "FM" or "NFM"
394
        mem.power = POWER_LEVELS[1 - _mem.ishighpower]
395

  
396
        mem.extra = RadioSettingGroup("extra", "Extra Settings")
397

  
398
        rs = RadioSetting("pttid", "PTT ID",
399
                          RadioSettingValueList(PTTID_LIST,
400
                                                PTTID_LIST[_mem.pttid]))
401
        mem.extra.append(rs)
402

  
403
        rs = RadioSetting("vox", "VOX",
404
                          RadioSettingValueBoolean(_mem.vox))
405
        mem.extra.append(rs)
406

  
407
        rs = RadioSetting("bclo", "Busy Channel Lockout",
408
                          RadioSettingValueList(BCLO_LIST,
409
                                                BCLO_LIST[_mem.bclo]))
410
        mem.extra.append(rs)
411

  
412
        rs = RadioSetting("apro", "APRO",
413
                          RadioSettingValueList(APRO_LIST,
414
                                                APRO_LIST[_mem.apro]))
415
        mem.extra.append(rs)
416

  
417
        rs = RadioSetting("rpt_md", "Repeater Mode",
418
                          RadioSettingValueList(RPTMD_LIST,
419
                                                RPTMD_LIST[_mem.rpt_md]))
420
        mem.extra.append(rs)
421

  
422
        return mem
423

  
424
    def set_memory(self, mem):
425
        _mem, _name = self._get_memobjs(mem.number)
426

  
427
        if mem.empty:
428
            _mem.set_raw("\xFF" * 32)
429
            self._memobj.enable[(mem.number - 1) / 8].flags[7-((mem.number - 1) % 8)] = False
430
            self._memobj.skip[(mem.number - 1) / 8].flags[7-((mem.number - 1) % 8)] = False
431
            return
432
        else:
433
            self._memobj.enable[(mem.number - 1) / 8].flags[7-((mem.number - 1) % 8)] = True
434

  
435
        if _mem.get_raw() == ("\xFF" * 32):
436
            print "Initializing empty memory"
437
            _mem.set_raw("\x00" * 32)
438

  
439
        _mem.rx_freq = mem.freq / 10
440
        if mem.duplex == "-":
441
            _mem.tx_freq = (mem.freq - mem.offset) / 10
442
        elif mem.duplex == "+":
443
            _mem.tx_freq = (mem.freq + mem.offset) / 10
444
        else:
445
            _mem.tx_freq = mem.freq / 10
446

  
447
        _mem.duplex = THUVF8D_DUPLEX.index(mem.duplex)
448
        _mem.offset = mem.offset / 10
449

  
450
        (txmode, txval, txpol), (rxmode, rxval, rxpol) = \
451
            chirp_common.split_tone_encode(mem)
452

  
453
        self._encode_tone(_mem.tx_tone, txmode, txval, txpol)
454
        self._encode_tone(_mem.rx_tone, rxmode, rxval, rxpol)
455

  
456
        _mem.name = mem.name.rstrip(' ').ljust(7, "\xFF")
457

  
458
        self._memobj.skip[(mem.number - 1) / 8].flags[7-((mem.number - 1) % 8)] = (mem.skip == "")
459
        _mem.wideband = mem.mode == "FM"
460
        _mem.ishighpower = mem.power == POWER_LEVELS[0]
461

  
462
        for element in mem.extra:
463
            setattr(_mem, element.get_name(), element.value)
464

  
465
    def get_settings(self):
466
        _settings = self._memobj.settings
467

  
468
        group = RadioSettingGroup("top", "All Settings")
469

  
470
        group.append(
471
            RadioSetting("Mode", "Mode",
472
                         RadioSettingValueList(MODE_LIST,
473
                                               MODE_LIST[_settings.mode])))
474

  
475
        group.append(
476
            RadioSetting("ab_switch", "A/B",
477
                         RadioSettingValueList(AB_LIST,
478
                                               AB_LIST[_settings.ab_switch])))
479

  
480
        group.append(
481
            RadioSetting("a_channel", "A Selected Memory",
482
                         RadioSettingValueInteger(1, 128, _settings.a_channel+1)))
483

  
484
        group.append(
485
            RadioSetting("b_channel", "B Selected Memory",
486
                         RadioSettingValueInteger(1, 128, _settings.b_channel+1)))
487

  
488
        group.append(
489
            RadioSetting("a_display", "A Channel Display",
490
                         RadioSettingValueList(DISPLAY_LIST,
491
                                               DISPLAY_LIST[_settings.a_display])))
492
        group.append(
493
            RadioSetting("b_display", "B Channel Display",
494
                         RadioSettingValueList(DISPLAY_LIST,
495
                                               DISPLAY_LIST[_settings.b_display])))
496
        group.append(
497
            RadioSetting("tx_sel", "Priority Transmit",
498
                         RadioSettingValueList(TXSEL_LIST,
499
                                               TXSEL_LIST[_settings.tx_sel])))
500
        group.append(
501
            RadioSetting("vox_level", "VOX Level",
502
                         RadioSettingValueList(VOX_LIST,
503
                                               VOX_LIST[_settings.vox_level])))
504

  
505
        group.append(
506
            RadioSetting("squelch", "Squelch Level",
507
                          RadioSettingValueInteger(0, 9, _settings.squelch)))
508

  
509
        group.append(
510
            RadioSetting("dwait", "Dual Wait",
511
                         RadioSettingValueBoolean(_settings.dwait)))
512

  
513
        group.append(
514
            RadioSetting("led", "LED Mode",
515
                         RadioSettingValueList(LED_LIST,
516
                                               LED_LIST[_settings.led])))
517

  
518
        group.append(
519
            RadioSetting("light", "Light Color",
520
                         RadioSettingValueList(LIGHT_LIST,
521
                                               LIGHT_LIST[_settings.light])))
522

  
523
        group.append(
524
            RadioSetting("beep", "Beep",
525
                         RadioSettingValueBoolean(_settings.beep)))
526

  
527
        group.append(
528
            RadioSetting("ani", "ANI",
529
                         RadioSettingValueBoolean(_settings.ani)))
530

  
531
        group.append(
532
            RadioSetting("tot", "Timeout Timer",
533
                         RadioSettingValueList(TOT_LIST,
534
                                               TOT_LIST[_settings.tot])))
535

  
536
        group.append(
537
            RadioSetting("roger", "Roger Beep",
538
                         RadioSettingValueBoolean(_settings.roger)))
539

  
540
        group.append(
541
            RadioSetting("dw", "Dual Watch",
542
                         RadioSettingValueBoolean(_settings.dw)))
543

  
544
        group.append(
545
            RadioSetting("rxsave", "RX Save",
546
                         RadioSettingValueBoolean(_settings.rxsave)))
547

  
548
        def _filter(name):
549
            return str(name).rstrip("\xFF").rstrip()
550

  
551
        group.append(
552
            RadioSetting("ponmsg", "Power-On Message",
553
                         RadioSettingValueString(0, 7,
554
                                                 _filter(_settings.ponmsg))))
555

  
556
        group.append(
557
            RadioSetting("scan_mode", "Scan Mode",
558
                         RadioSettingValueList(SCAN_MODE_LIST,
559
                                               SCAN_MODE_LIST[_settings.scan_mode])))
560

  
561
        group.append(
562
            RadioSetting("autolk", "Auto Lock",
563
                         RadioSettingValueBoolean(_settings.autolk)))
564

  
565
        group.append(
566
            RadioSetting("lock_mode", "Keypad Lock Mode",
567
                         RadioSettingValueList(LOCK_MODE_LIST,
568
                                               LOCK_MODE_LIST[_settings.lock_mode])))
569

  
570
        group.append(
571
            RadioSetting("voice", "Voice Prompt",
572
                         RadioSettingValueBoolean(_settings.voice)))
573

  
574
        group.append(
575
            RadioSetting("opnmsg", "Opening Message",
576
                         RadioSettingValueList(OPNMSG_LIST,
577
                                               OPNMSG_LIST[_settings.opnmsg])))
578

  
579
        group.append(
580
            RadioSetting("tuning_step", "Tuning Step",
581
                         RadioSettingValueList(TUNING_STEPS_LIST,
582
                                               TUNING_STEPS_LIST[_settings.tuning_step])))
583

  
584
        group.append(
585
            RadioSetting("lamp_t", "Backlight Timeout",
586
                         RadioSettingValueList(BACKLIGHT_TIMEOUT_LIST,
587
                                               BACKLIGHT_TIMEOUT_LIST[_settings.lamp_t])))
588

  
589
        group.append(
590
            RadioSetting("a_work_area", "A Work Area",
591
                         RadioSettingValueList(AB_LIST,
592
                                               AB_LIST[_settings.a_work_area])))
593

  
594
        group.append(
595
            RadioSetting("b_work_area", "B Work Area",
596
                         RadioSettingValueList(AB_LIST,
597
                                               AB_LIST[_settings.b_work_area])))
598

  
599

  
600
        return group
601

  
602
        group.append(
603
            RadioSetting("disnm", "Display Name",
604
                         RadioSettingValueBoolean(_settings.disnm)))
605

  
606
        return group
607

  
608
    def set_settings(self, settings):
609
        _settings = self._memobj.settings
610

  
611
        for element in settings:
612
            if element.get_name() == 'rxsave':
613
                if bool(element.value.get_value()):
614
                    _settings.rxsave = 3
615
                else:
616
                    _settings.rxsave = 0
617
                continue
618
            if element.get_name().endswith('_channel'):
619
              print element.value, type(element.value)
620
              setattr(_settings, element.get_name(), int(element.value)-1)
621
              continue
622
            if not isinstance(element, RadioSetting):
623
                self.set_settings(element)
624
                continue
625
            setattr(_settings, element.get_name(), element.value)
chirp/wouxun_common.py Tue Jul 30 17:59:18 2013 -0400 → chirp/wouxun_common.py Sun Oct 06 13:38:26 2013 -0700
24 24
    """Cleanup a memory"""
25 25
    _mem.set_raw(byte * (_mem.size() / 8))
26 26
    
27
def do_download(radio, start, end, blocksize):
27
def do_download(radio, start, end, blocksize, ack_chr="\x06"):
28 28
    """Initiate a download of @radio between @start and @end"""
29 29
    image = ""
30 30
    for i in range(start, end, blocksize):
......
40 40
                                (len(resp),
41 41
                                 len(cmd) + blocksize))
42 42
        
43
        radio.pipe.write("\x06")
43
        radio.pipe.write(ack_chr)
44 44
        radio.pipe.read(1)
45 45
        image += resp[4:]
46 46

  
......
53 53
    
54 54
    return memmap.MemoryMap(image)
55 55

  
56
def do_upload(radio, start, end, blocksize):
56
def do_upload(radio, start, end, blocksize, ack_chr="\x06"):
57 57
    """Initiate an upload of @radio between @start and @end"""
58 58
    ptr = start
59 59
    for i in range(start, end, blocksize):
......
65 65
            print util.hexprint(cmd + chunk)
66 66

  
67 67
        ack = radio.pipe.read(1)
68
        if not ack == "\x06":
68
        if not ack == ack_chr:
69 69
            raise Exception("Radio did not ack block %i" % ptr)
70 70
        #radio.pipe.write(ack)
71 71

  
(1-1/6)