<html><body><div style="color:#000; background-color:#fff; font-family:tahoma, new york, times, serif;font-size:12pt"><div># HG changeset patch<br># User Jens Jensen &lt;kd4tjx@yahoo.com&gt;<br># Date 1377497847 18000<br># Node ID 7c95e9d39dfc07ea1e3192834d8a339e100347f6<br># Parent&nbsp; 86910885e998d559dfdd6ba4c5fb0bf520fdee31<br>initial support for Yaesu FT-90R, revised #1087<br><br>diff -r 86910885e998 -r 7c95e9d39dfc chirp/ft90.py<br>--- /dev/null&nbsp;&nbsp;&nbsp; Thu Jan 01 00:00:00 1970 +0000<br>+++ b/chirp/ft90.py&nbsp;&nbsp;&nbsp; Mon Aug 26 01:17:27 2013 -0500<br>@@ -0,0 +1,379 @@<br>+# Copyright 2011 Dan Smith &lt;dsmith@danplanet.com&gt;<br>+# Copyright 2013 Jens Jensen &lt;kd4tjx@yahoo.com&gt;<br>+#<br>+# This program is free software: you can redistribute it and/or modify<br>+# it under the terms of the GNU General Public License as published by<br>+# the Free Software Foundation, either version 3 of the License, or<br>+# (at your option)
 any later version.<br>+#<br>+# This program is distributed in the hope that it will be useful,<br>+# but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the<br>+# GNU General Public License for more details.<br>+#<br>+# You should have received a copy of the GNU General Public License<br>+# along with this program.&nbsp; If not, see &lt;http://www.gnu.org/licenses/&gt;.<br>+<br>+from chirp import chirp_common, bitwise, memmap, directory, errors, util, yaesu_clone<br>+import time, os, traceback<br>+<br>+CHIRP_DEBUG=True<br>+CMD_ACK = chr(0x06)<br>+<br>+@directory.register<br>+class FT90Radio(yaesu_clone.YaesuCloneModeRadio):<br>+&nbsp;&nbsp;&nbsp; VENDOR = "Yaesu"<br>+&nbsp;&nbsp;&nbsp; MODEL = "FT-90"<br>+&nbsp;&nbsp;&nbsp; ID = "\x8E\xF6"<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; STEPS = [5, 10, 12.5, 15, 20, 25, 50]<br>+&nbsp;&nbsp;&nbsp; MODES = ["AM", "FM",
 "Auto"]<br>+&nbsp;&nbsp;&nbsp; TMODES = ["", "Tone", "TSQL", "", "DTCS"] # idx 3 (Bell) not supported yet<br>+<br>+&nbsp;&nbsp;&nbsp; TONES = list(chirp_common.TONES)<br>+&nbsp;&nbsp;&nbsp; for tone in [ 165.5, 171.3, 177.3 ]:<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TONES.remove(tone)&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; POWER_LEVELS = ["Hi", "Mid1", "Mid2", "Low"]<br>+&nbsp;&nbsp;&nbsp; DUPLEX = ["", "-", "+", "split"]<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; _memsize = 4063<br>+&nbsp;&nbsp;&nbsp; # block 03 (200 Bytes long) repeats 18 times; channel memories<br>+&nbsp;&nbsp;&nbsp; _block_lengths = [ 2, 232, 24, 200, 205]<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; mem_format = """<br>+&nbsp;&nbsp;&nbsp; #seekto 0x22;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; struct {<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf_active;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
 u8&nbsp;&nbsp;&nbsp; dtmf1_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf2_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf3_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf4_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf5_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf6_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf7_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf8_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf1[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf2[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf3[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf4[8];&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf5[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd
 dtmf6[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf7[8];&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf8[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char cwid[7];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8 &nbsp;&nbsp;&nbsp; unk1;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8 &nbsp;&nbsp;&nbsp; unk2:2,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; beep_dis:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk3:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rfsqlvl:4;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; cwid_en:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk4:3,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; txnarrow:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dtmfspeed:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pttlock:2;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
 u8&nbsp;&nbsp;&nbsp; dtmftxdelay:3,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fancontrol:2,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk5:3;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dimmer:3,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk6:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lcdcontrast:4;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; tot;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; unk8:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ars:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lock:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; txpwrsave:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; apo:4;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_rt;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp;
 key_lt;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_p1;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_p2;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_acc;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; demomsg1[32];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; demomsg2[32];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; } settings;<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; struct mem_struct {<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 mode:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isUhf1:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown1:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; step:3;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 artsmode:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown2:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 isUhf2:1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; power:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shift:2;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 skip:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; showname:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown3:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isUhfHi:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown4:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmode:3;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 rxfreq;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 txfreqoffset;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 UseDefaultName:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ars:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tone:6;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 packetmode:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown5:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 dcstone:6;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char name[7];<br>+&nbsp;&nbsp;&nbsp; };<br>+<br>+&nbsp;&nbsp;&nbsp; #seekto 0x86;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct vfo_v;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct call_v;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct vfo_u;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct call_u;<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; #seekto 0x102;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct memory[180];<br>+<br>+&nbsp;&nbsp;&nbsp; #seekto 0xf12;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_1L;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_1U;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_2L;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_2U;<br>+&nbsp;&nbsp;&nbsp; """<br>+<br>+&nbsp;&nbsp;&nbsp; @classmethod<br>+&nbsp;&nbsp;&nbsp; def match_model(cls, filedata, filename):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return len(filedata) == cls._memsize<br>+<br>+&nbsp;&nbsp;&nbsp; def
 get_features(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf = chirp_common.RadioFeatures()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_ctone = False<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_bank = False<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_dtcs_polarity = False<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_dtcs = True<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_modes = self.MODES<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_tmodes = self.TMODES<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_duplexes = self.DUPLEX<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_tuning_steps = self.STEPS<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_power_levels = self.POWER_LEVELS<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_name_length = 7<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_characters =
 chirp_common.CHARSET_ASCII<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_skips = ["", "S"]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.memory_bounds = (1, 180)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_bands = [(100000000, 230000000), <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (300000000, 530000000), (810000000, 999975000)]<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rf<br>+<br>+&nbsp;&nbsp;&nbsp; def _read(self, blocksize, blocknum):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = self.pipe.read(blocksize+2)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # chew echo'd ack<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.write(CMD_ACK)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(0.02)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.read(1) # chew echoed ACK from 1-wire
 serial<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if len(data) == blocksize+2 and data[0] == chr(blocknum):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksum = yaesu_clone.YaesuChecksum(1, blocksize)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if checksum.get_existing(data) != checksum.get_calculated(data):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise Exception("Checksum Failed [%02X&lt;&gt;%02X] block %02X, data len: %i" %<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 (checksum.get_existing(data),<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksum.get_calculated(data), blocknum, len(data) ))<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = data[1:blocksize+1] # Chew blocknum and checksum<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise Exception("Unable to read blocknum %02X expected blocksize %i got %i." %<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (blocknum, blocksize+2,
 len(data)))<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return data&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def _clone_in(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Be very patient with the radio<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.setTimeout(4)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start = time.time()<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = ""<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = chirp_common.Status()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.msg = "Cloning from radio.\nPut radio into clone mode then\npress SET to send"<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.max = len(self._block_lengths) + 18<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for
 blocksize in self._block_lengths:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if blocksize == 200:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # repeated read of 200 block same size (memory area)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat = 18<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for _i in range(0, repeat): <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data += self._read(blocksize, blocknum)<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum +=
 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.cur = blocknum<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.msg = "Clone completed."<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Clone completed in %i seconds, blocks read: %i" % (time.time() - start, blocknum)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return memmap.MemoryMap(data)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def _clone_out(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delay = 0.2<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start = time.time()<br>+&nbsp;&nbsp;&nbsp;
 <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pos = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = chirp_common.Status()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.msg = "Cloning to radio.\nPut radio into clone mode and press DISP/SS\n to start receive within 3 secs..."<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio likes to have port open <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.open()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(3)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.max = len(self._block_lengths) + 18<br>+<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for blocksize in self._block_lengths:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if blocksize ==
 200:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # repeat channel blocks<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat = 18<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for _i in range(0, repeat):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(0.1)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksum = yaesu_clone.YaesuChecksum(pos, pos+blocksize-1)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknumbyte =
 chr(blocknum)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; payloadbytes = self.get_mmap()[pos:pos+blocksize]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksumbyte = chr(checksum.get_calculated(self.get_mmap()))<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Block %i - will send from %i to %i byte " % \<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (blocknum, pos, pos + blocksize)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print
 util.hexprint(blocknumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print util.hexprint(payloadbytes)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print util.hexprint(checksumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # send wrapped bytes<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.write(blocknumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.write(payloadbytes)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.write(checksumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp = self.pipe.read(blocksize+2)&nbsp; #chew
 echo<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "bytes echoed: "<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print util.hexprint(tmp)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio is slow to write/ack:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(0.9) <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf =
 self.pipe.read(1)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "ack recd:"<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print util.hexprint(buf)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if buf != CMD_ACK:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise Exception("Radio did not ack block %i" % blocknum)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pos +=
 blocksize<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum += 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.cur = blocknum<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Clone completed in %i seconds" % (time.time() - start)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def sync_in(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._mmap = self._clone_in()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except errors.RadioError:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except Exception,
 e:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trace = traceback.format_exc()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise errors.RadioError("Failed to communicate with radio: %s" % trace)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.process_mmap()<br>+<br>+&nbsp;&nbsp;&nbsp; def sync_out(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._clone_out()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except errors.RadioError:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except Exception, e:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trace = traceback.format_exc()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise errors.RadioError("Failed to communicate with radio: %s" %
 trace)<br>+<br>+&nbsp;&nbsp;&nbsp; def process_mmap(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._memobj = bitwise.parse(self.mem_format, self._mmap)<br>+<br>+&nbsp;&nbsp;&nbsp; def get_memory(self, number):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem = self._memobj.memory[number-1]<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem = chirp_common.Memory()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.number = number<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.freq = _mem.rxfreq * 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.offset = _mem.txfreqoffset * 10<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not _mem.tmode &lt; len(self.TMODES):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.tmode = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.tmode = self.TMODES[_mem.tmode]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.rtone =
 self.TONES[_mem.tone]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.dtcs = chirp_common.DTCS_CODES[_mem.dcstone]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.mode = self.MODES[_mem.mode]<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ars mode note yet working...<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ARS mode:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if _mem.ars and _mem.shift == 0:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.duplex = self.DUPLEX[4] <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.duplex = self.DUPLEX[_mem.shift]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.duplex = self.DUPLEX[_mem.shift]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.power =
 self.POWER_LEVELS[_mem.power]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio has a known bug with 5khz step and squelch<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if _mem.step == 0:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = 2<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.tuning_step = self.STEPS[_mem.step]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.skip = _mem.skip and "S" or ""<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.name = _mem.name<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mem<br>+<br>+&nbsp;&nbsp;&nbsp; def get_raw_memory(self, number):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return repr(self._memobj.memory[number-1])<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def set_memory(self, mem):<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem = self._memobj.memory[mem.number - 1]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.skip = mem.skip ==
 "S"<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio has a known bug with 5khz step and dead squelch<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not mem.tuning_step or mem.tuning_step == self.STEPS[0]:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = 2<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = self.STEPS.index(mem.tuning_step)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.rxfreq = mem.freq / 10<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # vfo will unlock if not in right band?<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if mem.freq &gt; 300000000: <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # uhf<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf1 = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf2 =
 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if mem.freq &gt; 810000000:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # uhf hiband<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhfHi = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhfHi = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # vhf<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf1 = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf2 = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhfHi = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.txfreqoffset
 = mem.offset / 10<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.tone = self.TONES.index(mem.rtone)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.tmode = self.TMODES.index(mem.tmode)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.mode = self.MODES.index(mem.mode)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ars not yet working<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ARS mode:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if mem.duplex == 4:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.shift = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.ars = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.shift = self.DUPLEX.index(mem.duplex)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 _mem.shift = self.DUPLEX.index(mem.duplex)&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.dcstone = chirp_common.DTCS_CODES.index(mem.dtcs)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if self.get_features().has_tuning_step:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = self.STEPS.index(mem.tuning_step)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.shift = self.DUPLEX.index(mem.duplex)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if mem.power:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.power = self.POWER_LEVELS.index(mem.power)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.power = 3&nbsp; # default to low power<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.name = mem.name.ljust(7)<br>+ <br>+<br>diff -r 86910885e998 -r 7c95e9d39dfc ft90.py<br>---
 /dev/null&nbsp;&nbsp;&nbsp; Thu Jan 01 00:00:00 1970 +0000<br>+++ b/ft90.py&nbsp;&nbsp;&nbsp; Mon Aug 26 01:17:27 2013 -0500<br>@@ -0,0 +1,379 @@<br>+# Copyright 2011 Dan Smith &lt;dsmith@danplanet.com&gt;<br>+# Copyright 2013 Jens Jensen &lt;kd4tjx@yahoo.com&gt;<br>+#<br>+# This program is free software: you can redistribute it and/or modify<br>+# it under the terms of the GNU General Public License as published by<br>+# the Free Software Foundation, either version 3 of the License, or<br>+# (at your option) any later version.<br>+#<br>+# This program is distributed in the hope that it will be useful,<br>+# but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the<br>+# GNU General Public License for more details.<br>+#<br>+# You should have received a copy of the GNU General Public License<br>+# along with this program.&nbsp; If not, see
 &lt;http://www.gnu.org/licenses/&gt;.<br>+<br>+from chirp import chirp_common, bitwise, memmap, directory, errors, util, yaesu_clone<br>+import time, os, traceback<br>+<br>+CHIRP_DEBUG=True<br>+CMD_ACK = chr(0x06)<br>+<br>+@directory.register<br>+class FT90Radio(yaesu_clone.YaesuCloneModeRadio):<br>+&nbsp;&nbsp;&nbsp; VENDOR = "Yaesu"<br>+&nbsp;&nbsp;&nbsp; MODEL = "FT-90"<br>+&nbsp;&nbsp;&nbsp; ID = "\x8E\xF6"<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; STEPS = [5, 10, 12.5, 15, 20, 25, 50]<br>+&nbsp;&nbsp;&nbsp; MODES = ["AM", "FM", "Auto"]<br>+&nbsp;&nbsp;&nbsp; TMODES = ["", "Tone", "TSQL", "", "DTCS"] # idx 3 (Bell) not supported yet<br>+<br>+&nbsp;&nbsp;&nbsp; TONES = list(chirp_common.TONES)<br>+&nbsp;&nbsp;&nbsp; for tone in [ 165.5, 171.3, 177.3 ]:<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TONES.remove(tone)&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; POWER_LEVELS = ["Hi", "Mid1", "Mid2", "Low"]<br>+&nbsp;&nbsp;&nbsp; DUPLEX
 = ["", "-", "+", "split"]<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; _memsize = 4063<br>+&nbsp;&nbsp;&nbsp; # block 03 (200 Bytes long) repeats 18 times; channel memories<br>+&nbsp;&nbsp;&nbsp; _block_lengths = [ 2, 232, 24, 200, 205]<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; mem_format = """<br>+&nbsp;&nbsp;&nbsp; #seekto 0x22;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; struct {<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf_active;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf1_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf2_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf3_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf4_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf5_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf6_len;<br>+&nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf7_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmf8_len;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf1[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf2[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf3[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf4[8];&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf5[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf6[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf7[8];&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bbcd dtmf8[8];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char cwid[7];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8 &nbsp;&nbsp;&nbsp; unk1;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8 &nbsp;&nbsp;&nbsp; unk2:2,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; beep_dis:1,<br>+&nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk3:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rfsqlvl:4;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; cwid_en:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk4:3,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; txnarrow:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dtmfspeed:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pttlock:2;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dtmftxdelay:3,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fancontrol:2,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk5:3;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; dimmer:3,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unk6:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lcdcontrast:4;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
 u8&nbsp;&nbsp;&nbsp; tot;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; unk8:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ars:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lock:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; txpwrsave:1,<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; apo:4;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_rt;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_lt;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_p1;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_p2;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp; key_acc;<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; demomsg1[32];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; demomsg2[32];<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; }
 settings;<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; struct mem_struct {<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 mode:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isUhf1:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown1:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; step:3;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 artsmode:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown2:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isUhf2:1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; power:2,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shift:2;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 skip:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; showname:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown3:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isUhfHi:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 unknown4:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmode:3;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 rxfreq;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 txfreqoffset;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 UseDefaultName:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ars:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tone:6;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 packetmode:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unknown5:1,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dcstone:6;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char name[7];<br>+&nbsp;&nbsp;&nbsp; };<br>+<br>+&nbsp;&nbsp;&nbsp; #seekto 0x86;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct vfo_v;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct call_v;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct vfo_u;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct call_u;<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; #seekto 0x102;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct
 memory[180];<br>+<br>+&nbsp;&nbsp;&nbsp; #seekto 0xf12;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_1L;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_1U;<br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_2L;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; struct mem_struct pms_2U;<br>+&nbsp;&nbsp;&nbsp; """<br>+<br>+&nbsp;&nbsp;&nbsp; @classmethod<br>+&nbsp;&nbsp;&nbsp; def match_model(cls, filedata, filename):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return len(filedata) == cls._memsize<br>+<br>+&nbsp;&nbsp;&nbsp; def get_features(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf = chirp_common.RadioFeatures()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_ctone = False<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_bank = False<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_dtcs_polarity = False<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.has_dtcs = True<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_modes =
 self.MODES<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_tmodes = self.TMODES<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_duplexes = self.DUPLEX<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_tuning_steps = self.STEPS<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_power_levels = self.POWER_LEVELS<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_name_length = 7<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_characters = chirp_common.CHARSET_ASCII<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_skips = ["", "S"]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.memory_bounds = (1, 180)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rf.valid_bands = [(100000000, 230000000), <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (300000000, 530000000), (810000000, 999975000)]<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rf<br>+<br>+&nbsp;&nbsp;&nbsp; def
 _read(self, blocksize, blocknum):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = self.pipe.read(blocksize+2)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # chew echo'd ack<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.write(CMD_ACK)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(0.02)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.read(1) # chew echoed ACK from 1-wire serial<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if len(data) == blocksize+2 and data[0] == chr(blocknum):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksum = yaesu_clone.YaesuChecksum(1, blocksize)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if checksum.get_existing(data) !=
 checksum.get_calculated(data):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise Exception("Checksum Failed [%02X&lt;&gt;%02X] block %02X, data len: %i" %<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (checksum.get_existing(data),<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksum.get_calculated(data), blocknum, len(data) ))<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = data[1:blocksize+1] # Chew blocknum and checksum<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise Exception("Unable to read blocknum %02X expected blocksize %i got %i." %<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (blocknum, blocksize+2, len(data)))<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return data&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def _clone_in(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Be very patient with the radio<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.setTimeout(4)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start = time.time()<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = ""<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 status = chirp_common.Status()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.msg = "Cloning from radio.\nPut radio into clone mode then\npress SET to send"<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.max = len(self._block_lengths) + 18<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for blocksize in self._block_lengths:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if blocksize == 200:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # repeated read of 200 block same size (memory area)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat = 18<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat =
 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for _i in range(0, repeat): <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data += self._read(blocksize, blocknum)<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum += 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.cur = blocknum<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.msg = "Clone completed."<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Clone completed in %i seconds, blocks read: %i" % (time.time() - start,
 blocknum)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return memmap.MemoryMap(data)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def _clone_out(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delay = 0.2<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start = time.time()<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pos = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = chirp_common.Status()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.msg = "Cloning to radio.\nPut radio into clone mode and press DISP/SS\n to start receive within 3 secs..."<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio likes to have port open <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.open()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 time.sleep(3)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.max = len(self._block_lengths) + 18<br>+<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for blocksize in self._block_lengths:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if blocksize == 200:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # repeat channel blocks<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat = 18<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeat = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for _i in range(0, repeat):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 time.sleep(0.1)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksum = yaesu_clone.YaesuChecksum(pos, pos+blocksize-1)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknumbyte = chr(blocknum)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; payloadbytes = self.get_mmap()[pos:pos+blocksize]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checksumbyte = chr(checksum.get_calculated(self.get_mmap()))<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Block %i - will send from %i to %i byte " %
 \<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (blocknum, pos, pos + blocksize)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print util.hexprint(blocknumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print util.hexprint(payloadbytes)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print util.hexprint(checksumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # send wrapped bytes<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 self.pipe.write(blocknumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.write(payloadbytes)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pipe.write(checksumbyte)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp = self.pipe.read(blocksize+2)&nbsp; #chew echo<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "bytes echoed: "<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print
 util.hexprint(tmp)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio is slow to write/ack:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(0.9) <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf = self.pipe.read(1)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "ack recd:"<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print
 util.hexprint(buf)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if buf != CMD_ACK:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise Exception("Radio did not ack block %i" % blocknum)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pos += blocksize<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocknum += 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status.cur = blocknum<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status_fn(status)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Clone completed in %i seconds" % (time.time() - start)<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def
 sync_in(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._mmap = self._clone_in()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except errors.RadioError:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except Exception, e:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trace = traceback.format_exc()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise errors.RadioError("Failed to communicate with radio: %s" % trace)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.process_mmap()<br>+<br>+&nbsp;&nbsp;&nbsp; def sync_out(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._clone_out()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except
 errors.RadioError:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except Exception, e:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trace = traceback.format_exc()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise errors.RadioError("Failed to communicate with radio: %s" % trace)<br>+<br>+&nbsp;&nbsp;&nbsp; def process_mmap(self):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._memobj = bitwise.parse(self.mem_format, self._mmap)<br>+<br>+&nbsp;&nbsp;&nbsp; def get_memory(self, number):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem = self._memobj.memory[number-1]<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem = chirp_common.Memory()<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.number = number<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.freq = _mem.rxfreq * 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.offset = _mem.txfreqoffset * 10<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not _mem.tmode &lt; len(self.TMODES):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.tmode = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.tmode = self.TMODES[_mem.tmode]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.rtone = self.TONES[_mem.tone]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.dtcs = chirp_common.DTCS_CODES[_mem.dcstone]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.mode = self.MODES[_mem.mode]<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ars mode note yet working...<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ARS mode:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if _mem.ars and _mem.shift == 0:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.duplex =
 self.DUPLEX[4] <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.duplex = self.DUPLEX[_mem.shift]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.duplex = self.DUPLEX[_mem.shift]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.power = self.POWER_LEVELS[_mem.power]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio has a known bug with 5khz step and squelch<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if _mem.step == 0:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = 2<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.tuning_step = self.STEPS[_mem.step]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.skip = _mem.skip and "S" or ""<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem.name = _mem.name<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
 mem<br>+<br>+&nbsp;&nbsp;&nbsp; def get_raw_memory(self, number):<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return repr(self._memobj.memory[number-1])<br>+&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp; def set_memory(self, mem):<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem = self._memobj.memory[mem.number - 1]<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.skip = mem.skip == "S"<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radio has a known bug with 5khz step and dead squelch<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not mem.tuning_step or mem.tuning_step == self.STEPS[0]:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = 2<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = self.STEPS.index(mem.tuning_step)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.rxfreq = mem.freq /
 10<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # vfo will unlock if not in right band?<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if mem.freq &gt; 300000000: <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # uhf<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf1 = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf2 = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if mem.freq &gt; 810000000:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # uhf hiband<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhfHi = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhfHi =
 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # vhf<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf1 = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhf2 = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.isUhfHi = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.txfreqoffset = mem.offset / 10<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.tone = self.TONES.index(mem.rtone)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.tmode = self.TMODES.index(mem.tmode)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.mode = self.MODES.index(mem.mode)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ars not yet working<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ARS mode:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if
 mem.duplex == 4:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.shift = 0<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.ars = 1<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.shift = self.DUPLEX.index(mem.duplex)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.shift = self.DUPLEX.index(mem.duplex)&nbsp;&nbsp;&nbsp; <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.dcstone = chirp_common.DTCS_CODES.index(mem.dtcs)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if self.get_features().has_tuning_step:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.step = self.STEPS.index(mem.tuning_step)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.shift = self.DUPLEX.index(mem.duplex)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if
 mem.power:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.power = self.POWER_LEVELS.index(mem.power)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.power = 3&nbsp; # default to low power<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _mem.name = mem.name.ljust(7)<br>+ <br>+<br></div></div></body></html>