<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<div class="moz-cite-prefix">On 2013-02-19 06:38, Dan Smith wrote:<br>
</div>
<blockquote cite="mid:20130219063826.323c1f1f@theine.danplanet.com"
type="cite">
<blockquote type="cite">
<pre wrap="">Okay, here is my ID-51 (id51.py) new driver. Also included is an
image file for same.
</pre>
</blockquote>
<pre wrap="">
Could you put it into the proper patch format?
<a class="moz-txt-link-freetext" href="http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Submitting-a-patch">http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Submitting-a-patch</a>
</pre>
</blockquote>
<br>
OK, I'm confoozed. I previously read that page, and I know that's
the correct format for a <b>change</b>. Once you/me have decided
that the changes I have for the ID-31 are appropriate as well, those
will obviously be in patch format. However, for a new driver, the
whole file is new, so I don't understand the procedure for that.
For the image file, your page says:<br>
<br>
<i>If you are adding a new driver, you will need to add an image to
the </i><i><code>tests/images/</code></i><i> directory which is
correctly named for your model. <b>These do not communicate well
in patch form</b>, so just send a sample image to the
development mailing list to accompany your patch submission.</i><br>
<br>
So, that's what I did. "hg status -mar" only shows the id31.py
changes, which I'm not ready (per above) to submit yet. I included
the complete id51.py file in my previous eMail so you could see the
differences (via the two diffs) before I formally submitted a patch.<br>
<br>
So, just now I did "hg add chirp/id51.py", and now "hg status -mar"
shows the id51.py. I then did "hg diff" and got the output shown at
the bottom of this eMail. Note that the diff does not (yet) include
adding the D-Star tag field into the "mycall" structure in id31.py;
that needs to be verified as needed (98% guess it's needed).<br>
<br>
<blockquote cite="mid:20130219063826.323c1f1f@theine.danplanet.com"
type="cite">
<blockquote type="cite">
<pre wrap="">I didn't use the one in tests/images because there isn't one.
</pre>
</blockquote>
<pre wrap="">
There is, but I suppose you're using a tarball snapshot which perhaps
doesn't have it:
% ls tests/images/Icom_ID-31A.img -l
-rw-r--r-- 1 dan dan 86K May 6 2012 tests/images/Icom_ID-31A.img</pre>
</blockquote>
<br>
<br>
No, I did a "hg clone <a class="moz-txt-link-freetext" href="http://d-rats.com/hg/chirp.hg">http://d-rats.com/hg/chirp.hg</a>" I got lots of
test files, but none for the ID-31. When I ran the tests, it ran
one for the ID-51 (I suppose because I had an image file there --
the test passed), but none for the ID-31.<br>
<br>
hg diff:<br>
<br>
<br>
diff -r 5528bdcdc34e chirp/id31.py<br>
--- a/chirp/id31.py Sun Feb 17 18:58:44 2013 -0800<br>
+++ b/chirp/id31.py Tue Feb 19 08:19:42 2013 -0800<br>
@@ -33,7 +33,7 @@<br>
duplex:2,<br>
dtcs_polarity:2;<br>
char name[16];<br>
- u8 unknow13;<br>
+ u8 unknown13;<br>
u8 urcall[7];<br>
u8 rpt1call[7];<br>
u8 rpt2call[7];<br>
@@ -88,6 +88,8 @@<br>
<br>
"""<br>
<br>
+MODES = [ "FM", "NFM", "DV" ]<br>
+MODE_INDEX = [ 0, 1, 5 ]<br>
TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS", "TSQL-R",
"DTCS-R"]<br>
DUPLEX = ["", "-", "+"]<br>
DTCS_POLARITY = ["NN", "NR", "RN", "RR"]<br>
@@ -198,7 +200,7 @@<br>
rf.has_bank_names = True<br>
rf.valid_tmodes = list(TMODES)<br>
rf.valid_tuning_steps = sorted(list(TUNING_STEPS))<br>
- rf.valid_modes = ["FM", "NFM", "DV"]<br>
+ rf.valid_modes = list(MODES)<br>
rf.valid_skips = ["", "S", "P"]<br>
rf.valid_characters = chirp_common.CHARSET_ASCII<br>
rf.valid_name_length = 16<br>
@@ -218,7 +220,7 @@<br>
<br>
bit = (1 << (number % 8))<br>
<br>
- if _mem.is_dv:<br>
+ if MODES[MODE_INDEX.index(_mem.mode)] == "DV":<br>
mem = chirp_common.DVMemory()<br>
else:<br>
mem = chirp_common.Memory()<br>
@@ -237,16 +239,12 @@<br>
mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs]<br>
mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity]<br>
mem.tuning_step = TUNING_STEPS[_mem.tune_step]<br>
-<br>
- if _mem.is_dv:<br>
- mem.mode = "DV"<br>
+ mem.mode = MODES[MODE_INDEX.index(_mem.mode)]<br>
+<br>
+ if mem.mode == "DV":<br>
mem.dv_urcall = _decode_call(_mem.urcall).rstrip()<br>
mem.dv_rpt1call = _decode_call(_mem.rpt1call).rstrip()<br>
mem.dv_rpt2call = _decode_call(_mem.rpt2call).rstrip()<br>
- elif _mem.is_narrow:<br>
- mem.mode = "NFM"<br>
- else:<br>
- mem.mode = "FM"<br>
<br>
if _psk & bit:<br>
mem.skip = "P"<br>
@@ -279,9 +277,7 @@<br>
_mem.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs)<br>
_mem.dtcs_polarity =
DTCS_POLARITY.index(memory.dtcs_polarity)<br>
_mem.tune_step = TUNING_STEPS.index(memory.tuning_step)<br>
-<br>
- _mem.is_narrow = memory.mode in ["NFM", "DV"]<br>
- _mem.is_dv = memory.mode == "DV"<br>
+ _mem.mode = MODE_INDEX[MODES.index(memory.mode)]<br>
<br>
if isinstance(memory, chirp_common.DVMemory):<br>
_mem.urcall = _encode_call(memory.dv_urcall.ljust(8))<br>
@@ -327,8 +323,3 @@<br>
call = ""<br>
calls.append(call.rstrip())<br>
return calls<br>
-<br>
-if __name__ == "__main__":<br>
- print repr(_decode_call(_encode_call("KD7REX B")))<br>
- print repr(_decode_call(_encode_call(" B")))<br>
- print repr(_decode_call(_encode_call(" ")))<br>
diff -r 5528bdcdc34e chirp/id51.py<br>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000<br>
+++ b/chirp/id51.py Tue Feb 19 08:19:42 2013 -0800<br>
@@ -0,0 +1,323 @@<br>
+# Copyright 2012 Dan Smith <a class="moz-txt-link-rfc2396E" href="mailto:dsmith@danplanet.com"><dsmith@danplanet.com></a><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. 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. If not, see
<a class="moz-txt-link-rfc2396E" href="http://www.gnu.org/licenses/"><http://www.gnu.org/licenses/></a>.<br>
+<br>
+from chirp import directory, icf, bitwise, chirp_common<br>
+<br>
+MEM_FORMAT = """<br>
+struct {<br>
+ u24 freq;<br>
+ u16 offset;<br>
+ u16 rtone:6,<br>
+ ctone:6,<br>
+ unknown2:1,<br>
+ mode:3;<br>
+ u8 dtcs;<br>
+ u8 tune_step:4,<br>
+ unknown5:4;<br>
+ u8 unknown4;<br>
+ u8 tmode:4,<br>
+ duplex:2,<br>
+ dtcs_polarity:2;<br>
+ char name[16];<br>
+ u8 unknown13;<br>
+ u8 urcall[7];<br>
+ u8 rpt1call[7];<br>
+ u8 rpt2call[7];<br>
+} memory[500];<br>
+<br>
+#seekto 0x6A40;<br>
+u8 used_flags[70];<br>
+<br>
+#seekto 0x6A86;<br>
+u8 skip_flags[69];<br>
+<br>
+#seekto 0x6ACB;<br>
+u8 pskp_flags[69];<br>
+<br>
+#seekto 0x6B40;<br>
+struct {<br>
+ u8 bank;<br>
+ u8 index;<br>
+} banks[500];<br>
+<br>
+#seekto 0x6FD0;<br>
+struct {<br>
+ char name[16];<br>
+} bank_names[26];<br>
+<br>
+#seekto 0xA8C0;<br>
+struct {<br>
+ u24 freq;<br>
+ u16 offset;<br>
+ u8 unknown1[3];<br>
+ u8 call[7];<br>
+ char name[16];<br>
+ char subname[8];<br>
+ u8 unknown3[10];<br>
+} repeaters[700];<br>
+<br>
+#seekto 0x1384E;<br>
+struct {<br>
+ u8 call[7];<br>
+} rptcall[700];<br>
+<br>
+#seekto 0x14E60;<br>
+struct {<br>
+ char call[8];<br>
+ char tag[4];<br>
+} mycall[6];<br>
+<br>
+#seekto 0x14EA8;<br>
+struct {<br>
+ char call[8];<br>
+} urcall[200];<br>
+<br>
+"""<br>
+<br>
+MODES = [ "FM", "NFM", "AM", "DV" ]<br>
+MODE_INDEX = [ 0, 1, 3, 5 ]<br>
+TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS", "TSQL-R",
"DTCS-R"]<br>
+DUPLEX = ["", "-", "+"]<br>
+DTCS_POLARITY = ["NN", "NR", "RN", "RR"]<br>
+TUNING_STEPS = [5.0, 6.25, 0, 0, 10.0, 12.5, 15.0, 20.0, 25.0,
30.0, 50.0,<br>
+ 100.0, 125.0, 200.0]<br>
+<br>
+def _decode_call(_call):<br>
+ # Why Icom, why?<br>
+ call = ""<br>
+ shift = 1<br>
+ acc = 0<br>
+ for val in _call:<br>
+ mask = (1 << (shift)) - 1<br>
+ call += chr((val >> shift) | acc)<br>
+ acc = (val & mask) << (7 - shift)<br>
+ shift += 1<br>
+ call += chr(acc)<br>
+ return call<br>
+<br>
+def _encode_call(call):<br>
+ _call = [0x00] * 7<br>
+ for i in range(0, 7):<br>
+ val = ord(call[i]) << (i + 1)<br>
+ if i > 0:<br>
+ _call[i-1] |= (val & 0xFF00) >> 8<br>
+ _call[i] = val<br>
+ _call[6] |= (ord(call[7]) & 0x7F)<br>
+<br>
+ return _call<br>
+<br>
+def _get_freq(_mem):<br>
+ freq = int(_mem.freq)<br>
+ offs = int(_mem.offset)<br>
+<br>
+ if freq & 0x00200000:<br>
+ mult = 6250<br>
+ else:<br>
+ mult = 5000<br>
+<br>
+ freq &= 0x0003FFFF<br>
+<br>
+ return (freq * mult), (offs * mult)<br>
+<br>
+def _set_freq(_mem, freq, offset):<br>
+ if chirp_common.is_fractional_step(freq):<br>
+ mult = 6250<br>
+ flag = 0x00200000<br>
+ else:<br>
+ mult = 5000<br>
+ flag = 0x00000000<br>
+<br>
+ _mem.freq = (freq / mult) | flag<br>
+ _mem.offset = (offset / mult)<br>
+<br>
+class ID51Bank(icf.IcomBank):<br>
+ """A ID-51 Bank"""<br>
+ def get_name(self):<br>
+ _banks = self._model._radio._memobj.bank_names<br>
+ return str(_banks[self.index].name).rstrip()<br>
+<br>
+ def set_name(self, name):<br>
+ _banks = self._model._radio._memobj.bank_names<br>
+ _banks[self.index].name = str(name).ljust(16)[:16]<br>
+<br>
+@directory.register<br>
+class ID51Radio(icf.IcomCloneModeRadio,
chirp_common.IcomDstarSupport):<br>
+ """Icom ID-51"""<br>
+ MODEL = "ID-51A"<br>
+<br>
+ _memsize = 0x1FB40<br>
+ _model = "\x33\x90\x00\x01"<br>
+ _endframe = "Icom Inc\x2E\x44\x41"<br>
+ _num_banks = 26<br>
+ _bank_class = ID51Bank<br>
+ _can_hispeed = True<br>
+<br>
+ _ranges = [(0x00000, 0x1FB40, 32)]<br>
+<br>
+ def _get_bank(self, loc):<br>
+ _bank = self._memobj.banks[loc]<br>
+ if _bank.bank == 0xFF:<br>
+ return None<br>
+ else:<br>
+ return _bank.bank<br>
+<br>
+ def _set_bank(self, loc, bank):<br>
+ _bank = self._memobj.banks[loc]<br>
+ if bank is None:<br>
+ _bank.bank = 0xFF<br>
+ else:<br>
+ _bank.bank = bank<br>
+<br>
+ def _get_bank_index(self, loc):<br>
+ _bank = self._memobj.banks[loc]<br>
+ return _bank.index<br>
+<br>
+ def _set_bank_index(self, loc, index):<br>
+ _bank = self._memobj.banks[loc]<br>
+ _bank.index = index<br>
+<br>
+ def get_features(self):<br>
+ rf = chirp_common.RadioFeatures()<br>
+ rf.memory_bounds = (0, 499)<br>
+ rf.valid_bands = [(108000000, 174000000), (400000000,
479000000)]<br>
+ rf.has_settings = True<br>
+ rf.has_ctone = True<br>
+ rf.has_bank_index = True<br>
+ rf.has_bank_names = True<br>
+ rf.valid_tmodes = list(TMODES)<br>
+ rf.valid_tuning_steps = sorted(list(TUNING_STEPS))<br>
+ rf.valid_modes = list(MODES)<br>
+ rf.valid_skips = ["", "S", "P"]<br>
+ rf.valid_characters = chirp_common.CHARSET_ASCII<br>
+ rf.valid_name_length = 16<br>
+ return rf<br>
+<br>
+ def process_mmap(self):<br>
+ self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)<br>
+<br>
+ def get_raw_memory(self, number):<br>
+ return repr(self._memobj.memory[number])<br>
+<br>
+ def get_memory(self, number):<br>
+ _mem = self._memobj.memory[number]<br>
+ _usd = self._memobj.used_flags[number / 8]<br>
+ _skp = self._memobj.skip_flags[number / 8]<br>
+ _psk = self._memobj.pskp_flags[number / 8]<br>
+<br>
+ bit = (1 << (number % 8))<br>
+<br>
+ if MODES[MODE_INDEX.index(_mem.mode)] == "DV":<br>
+ mem = chirp_common.DVMemory()<br>
+ else:<br>
+ mem = chirp_common.Memory()<br>
+ mem.number = number<br>
+<br>
+ if _usd & bit:<br>
+ mem.empty = True<br>
+ return mem<br>
+<br>
+ mem.freq, mem.offset = _get_freq(_mem)<br>
+ mem.name = str(_mem.name).rstrip()<br>
+ mem.rtone = chirp_common.TONES[_mem.rtone]<br>
+ mem.ctone = chirp_common.TONES[_mem.ctone]<br>
+ mem.tmode = TMODES[_mem.tmode]<br>
+ mem.duplex = DUPLEX[_mem.duplex]<br>
+ mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs]<br>
+ mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity]<br>
+ mem.tuning_step = TUNING_STEPS[_mem.tune_step]<br>
+ mem.mode = MODES[MODE_INDEX.index(_mem.mode)]<br>
+<br>
+ if mem.mode == "DV":<br>
+ mem.dv_urcall = _decode_call(_mem.urcall).rstrip()<br>
+ mem.dv_rpt1call = _decode_call(_mem.rpt1call).rstrip()<br>
+ mem.dv_rpt2call = _decode_call(_mem.rpt2call).rstrip()<br>
+<br>
+ if _psk & bit:<br>
+ mem.skip = "P"<br>
+ if _skp & bit:<br>
+ mem.skip = "S"<br>
+<br>
+ return mem<br>
+<br>
+ def set_memory(self, memory):<br>
+ _mem = self._memobj.memory[memory.number]<br>
+ _usd = self._memobj.used_flags[memory.number / 8]<br>
+ _skp = self._memobj.skip_flags[memory.number / 8]<br>
+ _psk = self._memobj.pskp_flags[memory.number / 8]<br>
+<br>
+ bit = (1 << (memory.number % 8))<br>
+<br>
+ if memory.empty:<br>
+ _usd |= bit<br>
+ self._set_bank(memory.number, None)<br>
+ return<br>
+<br>
+ _usd &= ~bit<br>
+<br>
+ _set_freq(_mem, memory.freq, memory.offset)<br>
+ _mem.name = memory.name.ljust(16)[:16]<br>
+ _mem.rtone = chirp_common.TONES.index(memory.rtone)<br>
+ _mem.ctone = chirp_common.TONES.index(memory.ctone)<br>
+ _mem.tmode = TMODES.index(memory.tmode)<br>
+ _mem.duplex = DUPLEX.index(memory.duplex)<br>
+ _mem.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs)<br>
+ _mem.dtcs_polarity =
DTCS_POLARITY.index(memory.dtcs_polarity)<br>
+ _mem.tune_step = TUNING_STEPS.index(memory.tuning_step)<br>
+ _mem.mode = MODE_INDEX[MODES.index(memory.mode)]<br>
+<br>
+ if isinstance(memory, chirp_common.DVMemory):<br>
+ _mem.urcall = _encode_call(memory.dv_urcall.ljust(8))<br>
+ _mem.rpt1call =
_encode_call(memory.dv_rpt1call.ljust(8))<br>
+ _mem.rpt2call =
_encode_call(memory.dv_rpt2call.ljust(8))<br>
+ elif memory.mode == "DV":<br>
+ raise Exception("BUG")<br>
+<br>
+ if memory.skip == "S":<br>
+ _skp |= bit<br>
+ _psk &= ~bit<br>
+ elif memory.skip == "P":<br>
+ _skp &= ~bit<br>
+ _psk |= bit<br>
+ else:<br>
+ _skp &= ~bit<br>
+ _psk &= ~bit<br>
+<br>
+ def get_urcall_list(self):<br>
+ calls = []<br>
+ for i in range(0, 200):<br>
+ call = str(self._memobj.urcall[i].call)<br>
+ if call == "CALLSIGN":<br>
+ call = ""<br>
+ calls.append(call)<br>
+ return calls<br>
+<br>
+ def get_mycall_list(self):<br>
+ calls = []<br>
+ for i in range(0, 6):<br>
+ calls.append(str(self._memobj.mycall[i].call))<br>
+ return calls<br>
+<br>
+ def get_repeater_call_list(self):<br>
+ calls = []<br>
+ for rptcall in self._memobj.rptcall:<br>
+ call = _decode_call(rptcall.call)<br>
+ if call.rstrip() and not call == "CALLSIGN":<br>
+ calls.append(call)<br>
+ for repeater in self._memobj.repeaters:<br>
+ call = _decode_call(repeater.call)<br>
+ if call == "CALLSIGN":<br>
+ call = ""<br>
+ calls.append(call.rstrip())<br>
+ return calls<br>
<br>
<br>
</body>
</html>