[chirp_devel] Icom ID-51
OK, I made a couple of token additions to id31.py; eg:
1. Copied class "ID31Radio" to "ID51Radio". 2. Changed the .ICF file size, signature, and endframe. 3. Changed the rf.valid_bands to [(108000000, 174000000), (400000000, 479000000)]
I then imported my ID-51 .ICF file, and most of the memory lines imported correctly !! Ditto for reading from the radio (serial port COM220) !!
Since some of the frequencies didn't import correctly, I suspect that this is the same (or similar) issue as reported in bug 559 for the ID-880H. There are other "Gotchas" as well, like not knowing about AM mode, and it appears that the "Skip" bit has moved ...
I then imported my ID-51 .ICF file, and most of the memory lines imported correctly !! Ditto for reading from the radio (serial port COM220) !!
Nice!
Since some of the frequencies didn't import correctly, I suspect that this is the same (or similar) issue as reported in bug 559 for the ID-880H. There are other "Gotchas" as well, like not knowing about AM mode, and it appears that the "Skip" bit has moved ...
Okay, cool. Sounds like it may be best to make them share either from a common base class (if you prefer) or just make the id51 inherit from the '31 and break out / override bits you need. Let me know if you need help with any of that syntax.
Running the integration tests against the id31 driver should give you a pretty good indication that you haven't broken anything, but I can test the '31 driver here if anything concerns you.
Thanks Dean!
On 2013-02-17 19:11, Dan Smith wrote:
... There are other "Gotchas" as well, like not knowing about AM mode, and it appears that the "Skip" bit has moved ... Okay, cool. Sounds like it may be best to make them share either from a common base class (if you prefer) or just make the id51 inherit from the '31 and break out / override bits you need. Let me know if you need help with any of that syntax.
After looking at the code for the ID-31, I think that the decoding for the modulation type may be wrong for that radio as well: I just looked at the C++ code I have for the six Icom D-Star radios I included in DStarCom, and NONE of them used separate bits for "DV" and "FM-N" modes; instead, the fields were all *two-bit* (literal meaning!) fields that indexed into an array of at least three different modulation modes. The id31.py code does not reflect that, and I'd be very surprised if the ID-31 was any different in that regard (since it supports more than two modulation modes).
So, rather than modify ID-31 code that I cannot test, I think it's wiser (and more bullet-proof) for me to just have a separate id51.py file, and get that working. It's not like id31.py and id51.py are large files, and if after I'm done, someone with an ID-31 radio wants to investigate the differences between the two files in terms of bit processing (and possibly provide a body of common code), they are welcome to do so with my help (assuming it's not the middle of summer when I'm flying 4-7 hours a day).
Also, upon further examination, it appears that some of the "#seekto" values may be different, which to me calls for either a separate file, or some renaming of existing structs (etc) in a combined file.
-- Dean
After looking at the code for the ID-31, I think that the decoding for the modulation type may be wrong for that radio as well: I just looked at the C++ code I have for the six Icom D-Star radios I included in DStarCom, and NONE of them used separate bits for "DV" and "FM-N" modes; instead, the fields were all *two-bit* (literal meaning!) fields that indexed into an array of at least three different modulation modes. The id31.py code does not reflect that, and I'd be very surprised if the ID-31 was any different in that regard (since it supports more than two modulation modes).
Sounds reasonable.
So, rather than modify ID-31 code that I cannot test, I think it's wiser (and more bullet-proof) for me to just have a separate id51.py file, and get that working.
Your call, but I could make and test the change before you get started if you want.
It's not like id31.py and id51.py are large files, and if after I'm done, someone with an ID-31 radio wants to investigate the differences between the two files in terms of bit processing (and possibly provide a body of common code), they are welcome to do so with my help (assuming it's not the middle of summer when I'm flying 4-7 hours a day).
Also, upon further examination, it appears that some of the "#seekto" values may be different, which to me calls for either a separate file, or some renaming of existing structs (etc) in a combined file.
The way we've handled that in other files is to put some variables in the format and fill them in when the format is passed to bitwise.parse(). However, going with a separate file entirely is fine if that's how you'd like to proceed.
chirpw:136: Warning: g_value_type_compatible: assertion `G_TYPE_IS_VALUE (src_type)' failed gtk.main() chirpw:136: Warning: gsignal.c:2964: invalid object type ` gtk.main()
OK, any hints as to what I messed up? Emitted when I load a .ICF file.
-- Dean
On 2013-02-17 23:04, Dean Gibson AE7Q wrote:
chirpw:136: Warning: g_value_type_compatible: assertion `G_TYPE_IS_VALUE (src_type)' failed gtk.main() chirpw:136: Warning: gsignal.c:2964: invalid object type ` gtk.main()
OK, any hints as to what I messed up? Emitted the first time I load a .ICF file, at the end. Probably when some byte-code is being generated ???
-- Dean
OK, except for the above (which appears on stdout but has no other noticeable effect), I think I have a working id51.py. Further, it looks like the the modulation modes change I made, can be *trivially* retrofitted into id31.py. After that, a simple diff will show no more than a dozen lines changed (aside from ID31/ID51 names).
There are a couple of differences in a couple structures, although I wouldn't be surprised if the one in id31py is wrong. Eg, the mycall table I found in memory had both callsigns and tags. I wonder if the id31.py structure shouldn't have them as well???
Shoot me someone's reasonable .ICF file for the ID-31 and I'll check (I have Icom's CS-31 software to see what is actually there and/or I'll add tags).
-- Dean
ps: Now if someone can give me some hints as to how to add support for banks "B" thru "E" on the IC-7000, I will be really happy (# 551)
OK, except for the above (which appears on stdout but has no other noticeable effect), I think I have a working id51.py. Further, it looks like the the modulation modes change I made, can be *trivially* retrofitted into id31.py. After that, a simple diff will show no more than a dozen lines changed (aside from ID31/ID51 names).
Cool.
There are a couple of differences in a couple structures, although I wouldn't be surprised if the one in id31py is wrong. Eg, the mycall table I found in memory had both callsigns and tags. I wonder if the id31.py structure shouldn't have them as well???
Sure, I can take a look when I see your change.
Shoot me someone's reasonable .ICF file for the ID-31 and I'll check (I have Icom's CS-31 software to see what is actually there and/or I'll add tags).
I don't have a reasonable one (or an .icf for that matter) but there should be a test image you can use in tests/images/Icom_ID-31A.img. Probably doesn't have much/any D-STAR stuff in there though, if that's what you're looking for. You should be able to download CS-31 and make ICF files to test what you want, right?
ps: Now if someone can give me some hints as to how to add support for banks "B" thru "E" on the IC-7000, I will be really happy (# 551)
The CIV drivers are a bit messy, but it shouldn't be that hard. I'd guess one of the zero bytes is the bank number, so I'd just start incrementing them one at a time until you get back a B-bank memory :)
Okay, here is my ID-51 (id51.py) new driver. Also included is an image file for same.
I also included a modified id31.py file to handle modulation modes the way I do for the ID-51; if you do two regular diffs, you can see how minimal the changes are, between both it and my id51.py, and between it and the repository version of id31.py. The only thing that I didn't retrofit into id31.py, is the "char tag[4]" line. I need to look at a real ID-31 .ICF file to see if that field is really there (I suspect it is). While I have the Icom CS-31 software installed, remember that it needs to be "primed" with a radio load or a .ICF file to set the country version in Icom's software. I have someone that I can get an ID-31 .ICF file from, and will check it.
I didn't use the one in tests/images because there isn't one.
Remember, this version generates the following messages to stdout when loading the ID-51 .ICF file:
/chirpw:136: Warning: g_value_type_compatible: assertion `G_TYPE_IS_VALUE (src_type)' failed// // gtk.main()// //chirpw:136: Warning: gsignal.c:2964: invalid object type `// // gtk.main()/
I have no idea what those are.
-- Dean
Okay, here is my ID-51 (id51.py) new driver. Also included is an image file for same.
Could you put it into the proper patch format?
http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Submitting-...
I also included a modified id31.py file to handle modulation modes the way I do for the ID-51; if you do two regular diffs, you can see how minimal the changes are, between both it and my id51.py, and between it and the repository version of id31.py. The only thing that I didn't retrofit into id31.py, is the "char tag[4]" line. I need to look at a real ID-31 .ICF file to see if that field is really there (I suspect it is). While I have the Icom CS-31 software installed, remember that it needs to be "primed" with a radio load or a .ICF file to set the country version in Icom's software. I have someone that I can get an ID-31 .ICF file from, and will check it.
It would be really great to have this as a patch.
I didn't use the one in tests/images because there isn't one.
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
Remember, this version generates the following messages to stdout when loading the ID-51 .ICF file:
/chirpw:136: Warning: g_value_type_compatible: assertion `G_TYPE_IS_VALUE (src_type)' failed// // gtk.main()// //chirpw:136: Warning: gsignal.c:2964: invalid object type `// // gtk.main()/
I have no idea what those are.
They're harmless GTK warnings, and unrelated to your changes.
Thanks!
On 2013-02-19 06:38, Dan Smith wrote:
Okay, here is my ID-51 (id51.py) new driver. Also included is an image file for same.
Could you put it into the proper patch format?
http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Submitting-...
OK, I'm confoozed. I previously read that page, and I know that's the correct format for a *change*. 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:
/If you are adding a new driver, you will need to add an image to the //|tests/images/|//directory which is correctly named for your model. *These do not communicate well in patch form*, so just send a sample image to the development mailing list to accompany your patch submission./
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.
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).
I didn't use the one in tests/images because there isn't one.
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
No, I did a "hg clone http://d-rats.com/hg/chirp.hg" 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.
hg diff:
diff -r 5528bdcdc34e chirp/id31.py --- a/chirp/id31.py Sun Feb 17 18:58:44 2013 -0800 +++ b/chirp/id31.py Tue Feb 19 08:19:42 2013 -0800 @@ -33,7 +33,7 @@ duplex:2, dtcs_polarity:2; char name[16]; - u8 unknow13; + u8 unknown13; u8 urcall[7]; u8 rpt1call[7]; u8 rpt2call[7]; @@ -88,6 +88,8 @@
"""
+MODES = [ "FM", "NFM", "DV" ] +MODE_INDEX = [ 0, 1, 5 ] TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS", "TSQL-R", "DTCS-R"] DUPLEX = ["", "-", "+"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] @@ -198,7 +200,7 @@ rf.has_bank_names = True rf.valid_tmodes = list(TMODES) rf.valid_tuning_steps = sorted(list(TUNING_STEPS)) - rf.valid_modes = ["FM", "NFM", "DV"] + rf.valid_modes = list(MODES) rf.valid_skips = ["", "S", "P"] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 16 @@ -218,7 +220,7 @@
bit = (1 << (number % 8))
- if _mem.is_dv: + if MODES[MODE_INDEX.index(_mem.mode)] == "DV": mem = chirp_common.DVMemory() else: mem = chirp_common.Memory() @@ -237,16 +239,12 @@ mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.tuning_step = TUNING_STEPS[_mem.tune_step] - - if _mem.is_dv: - mem.mode = "DV" + mem.mode = MODES[MODE_INDEX.index(_mem.mode)] + + if mem.mode == "DV": mem.dv_urcall = _decode_call(_mem.urcall).rstrip() mem.dv_rpt1call = _decode_call(_mem.rpt1call).rstrip() mem.dv_rpt2call = _decode_call(_mem.rpt2call).rstrip() - elif _mem.is_narrow: - mem.mode = "NFM" - else: - mem.mode = "FM"
if _psk & bit: mem.skip = "P" @@ -279,9 +277,7 @@ _mem.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs) _mem.dtcs_polarity = DTCS_POLARITY.index(memory.dtcs_polarity) _mem.tune_step = TUNING_STEPS.index(memory.tuning_step) - - _mem.is_narrow = memory.mode in ["NFM", "DV"] - _mem.is_dv = memory.mode == "DV" + _mem.mode = MODE_INDEX[MODES.index(memory.mode)]
if isinstance(memory, chirp_common.DVMemory): _mem.urcall = _encode_call(memory.dv_urcall.ljust(8)) @@ -327,8 +323,3 @@ call = "" calls.append(call.rstrip()) return calls - -if __name__ == "__main__": - print repr(_decode_call(_encode_call("KD7REX B"))) - print repr(_decode_call(_encode_call(" B"))) - print repr(_decode_call(_encode_call(" "))) diff -r 5528bdcdc34e chirp/id51.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chirp/id51.py Tue Feb 19 08:19:42 2013 -0800 @@ -0,0 +1,323 @@ +# Copyright 2012 Dan Smith dsmith@danplanet.com +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. + +from chirp import directory, icf, bitwise, chirp_common + +MEM_FORMAT = """ +struct { + u24 freq; + u16 offset; + u16 rtone:6, + ctone:6, + unknown2:1, + mode:3; + u8 dtcs; + u8 tune_step:4, + unknown5:4; + u8 unknown4; + u8 tmode:4, + duplex:2, + dtcs_polarity:2; + char name[16]; + u8 unknown13; + u8 urcall[7]; + u8 rpt1call[7]; + u8 rpt2call[7]; +} memory[500]; + +#seekto 0x6A40; +u8 used_flags[70]; + +#seekto 0x6A86; +u8 skip_flags[69]; + +#seekto 0x6ACB; +u8 pskp_flags[69]; + +#seekto 0x6B40; +struct { + u8 bank; + u8 index; +} banks[500]; + +#seekto 0x6FD0; +struct { + char name[16]; +} bank_names[26]; + +#seekto 0xA8C0; +struct { + u24 freq; + u16 offset; + u8 unknown1[3]; + u8 call[7]; + char name[16]; + char subname[8]; + u8 unknown3[10]; +} repeaters[700]; + +#seekto 0x1384E; +struct { + u8 call[7]; +} rptcall[700]; + +#seekto 0x14E60; +struct { + char call[8]; + char tag[4]; +} mycall[6]; + +#seekto 0x14EA8; +struct { + char call[8]; +} urcall[200]; + +""" + +MODES = [ "FM", "NFM", "AM", "DV" ] +MODE_INDEX = [ 0, 1, 3, 5 ] +TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS", "TSQL-R", "DTCS-R"] +DUPLEX = ["", "-", "+"] +DTCS_POLARITY = ["NN", "NR", "RN", "RR"] +TUNING_STEPS = [5.0, 6.25, 0, 0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, + 100.0, 125.0, 200.0] + +def _decode_call(_call): + # Why Icom, why? + call = "" + shift = 1 + acc = 0 + for val in _call: + mask = (1 << (shift)) - 1 + call += chr((val >> shift) | acc) + acc = (val & mask) << (7 - shift) + shift += 1 + call += chr(acc) + return call + +def _encode_call(call): + _call = [0x00] * 7 + for i in range(0, 7): + val = ord(call[i]) << (i + 1) + if i > 0: + _call[i-1] |= (val & 0xFF00) >> 8 + _call[i] = val + _call[6] |= (ord(call[7]) & 0x7F) + + return _call + +def _get_freq(_mem): + freq = int(_mem.freq) + offs = int(_mem.offset) + + if freq & 0x00200000: + mult = 6250 + else: + mult = 5000 + + freq &= 0x0003FFFF + + return (freq * mult), (offs * mult) + +def _set_freq(_mem, freq, offset): + if chirp_common.is_fractional_step(freq): + mult = 6250 + flag = 0x00200000 + else: + mult = 5000 + flag = 0x00000000 + + _mem.freq = (freq / mult) | flag + _mem.offset = (offset / mult) + +class ID51Bank(icf.IcomBank): + """A ID-51 Bank""" + def get_name(self): + _banks = self._model._radio._memobj.bank_names + return str(_banks[self.index].name).rstrip() + + def set_name(self, name): + _banks = self._model._radio._memobj.bank_names + _banks[self.index].name = str(name).ljust(16)[:16] + +@directory.register +class ID51Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): + """Icom ID-51""" + MODEL = "ID-51A" + + _memsize = 0x1FB40 + _model = "\x33\x90\x00\x01" + _endframe = "Icom Inc\x2E\x44\x41" + _num_banks = 26 + _bank_class = ID51Bank + _can_hispeed = True + + _ranges = [(0x00000, 0x1FB40, 32)] + + def _get_bank(self, loc): + _bank = self._memobj.banks[loc] + if _bank.bank == 0xFF: + return None + else: + return _bank.bank + + def _set_bank(self, loc, bank): + _bank = self._memobj.banks[loc] + if bank is None: + _bank.bank = 0xFF + else: + _bank.bank = bank + + def _get_bank_index(self, loc): + _bank = self._memobj.banks[loc] + return _bank.index + + def _set_bank_index(self, loc, index): + _bank = self._memobj.banks[loc] + _bank.index = index + + def get_features(self): + rf = chirp_common.RadioFeatures() + rf.memory_bounds = (0, 499) + rf.valid_bands = [(108000000, 174000000), (400000000, 479000000)] + rf.has_settings = True + rf.has_ctone = True + rf.has_bank_index = True + rf.has_bank_names = True + rf.valid_tmodes = list(TMODES) + rf.valid_tuning_steps = sorted(list(TUNING_STEPS)) + rf.valid_modes = list(MODES) + rf.valid_skips = ["", "S", "P"] + rf.valid_characters = chirp_common.CHARSET_ASCII + rf.valid_name_length = 16 + return rf + + def process_mmap(self): + self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) + + def get_raw_memory(self, number): + return repr(self._memobj.memory[number]) + + def get_memory(self, number): + _mem = self._memobj.memory[number] + _usd = self._memobj.used_flags[number / 8] + _skp = self._memobj.skip_flags[number / 8] + _psk = self._memobj.pskp_flags[number / 8] + + bit = (1 << (number % 8)) + + if MODES[MODE_INDEX.index(_mem.mode)] == "DV": + mem = chirp_common.DVMemory() + else: + mem = chirp_common.Memory() + mem.number = number + + if _usd & bit: + mem.empty = True + return mem + + mem.freq, mem.offset = _get_freq(_mem) + mem.name = str(_mem.name).rstrip() + mem.rtone = chirp_common.TONES[_mem.rtone] + mem.ctone = chirp_common.TONES[_mem.ctone] + mem.tmode = TMODES[_mem.tmode] + mem.duplex = DUPLEX[_mem.duplex] + mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] + mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] + mem.tuning_step = TUNING_STEPS[_mem.tune_step] + mem.mode = MODES[MODE_INDEX.index(_mem.mode)] + + if mem.mode == "DV": + mem.dv_urcall = _decode_call(_mem.urcall).rstrip() + mem.dv_rpt1call = _decode_call(_mem.rpt1call).rstrip() + mem.dv_rpt2call = _decode_call(_mem.rpt2call).rstrip() + + if _psk & bit: + mem.skip = "P" + if _skp & bit: + mem.skip = "S" + + return mem + + def set_memory(self, memory): + _mem = self._memobj.memory[memory.number] + _usd = self._memobj.used_flags[memory.number / 8] + _skp = self._memobj.skip_flags[memory.number / 8] + _psk = self._memobj.pskp_flags[memory.number / 8] + + bit = (1 << (memory.number % 8)) + + if memory.empty: + _usd |= bit + self._set_bank(memory.number, None) + return + + _usd &= ~bit + + _set_freq(_mem, memory.freq, memory.offset) + _mem.name = memory.name.ljust(16)[:16] + _mem.rtone = chirp_common.TONES.index(memory.rtone) + _mem.ctone = chirp_common.TONES.index(memory.ctone) + _mem.tmode = TMODES.index(memory.tmode) + _mem.duplex = DUPLEX.index(memory.duplex) + _mem.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs) + _mem.dtcs_polarity = DTCS_POLARITY.index(memory.dtcs_polarity) + _mem.tune_step = TUNING_STEPS.index(memory.tuning_step) + _mem.mode = MODE_INDEX[MODES.index(memory.mode)] + + if isinstance(memory, chirp_common.DVMemory): + _mem.urcall = _encode_call(memory.dv_urcall.ljust(8)) + _mem.rpt1call = _encode_call(memory.dv_rpt1call.ljust(8)) + _mem.rpt2call = _encode_call(memory.dv_rpt2call.ljust(8)) + elif memory.mode == "DV": + raise Exception("BUG") + + if memory.skip == "S": + _skp |= bit + _psk &= ~bit + elif memory.skip == "P": + _skp &= ~bit + _psk |= bit + else: + _skp &= ~bit + _psk &= ~bit + + def get_urcall_list(self): + calls = [] + for i in range(0, 200): + call = str(self._memobj.urcall[i].call) + if call == "CALLSIGN": + call = "" + calls.append(call) + return calls + + def get_mycall_list(self): + calls = [] + for i in range(0, 6): + calls.append(str(self._memobj.mycall[i].call)) + return calls + + def get_repeater_call_list(self): + calls = [] + for rptcall in self._memobj.rptcall: + call = _decode_call(rptcall.call) + if call.rstrip() and not call == "CALLSIGN": + calls.append(call) + for repeater in self._memobj.repeaters: + call = _decode_call(repeater.call) + if call == "CALLSIGN": + call = "" + calls.append(call.rstrip()) + return calls
Another reason I didn't submit the id31.py changes as a patch is that there was no bug # for it. I will create one, once I know there is a definite issue.
And, I've just found out that the patch I submitted for the ID-31 probably doesn't even compile (I can't tell, without a test). So, remove that from my previous patch submission. I won't submit a new patch for the id31.py unless I've tested it in the test suite. The only reason I submitted it previously, is for you to look at the changes BEFORE I formally submitted a patch, which is what I thought you wanted.
-- Dean
On 2013-02-19 08:27, Dean Gibson AE7Q wrote:
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.
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).
I didn't use the one in tests/images because there isn't one.
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
No, I did a "hg clone http://d-rats.com/hg/chirp.hg" 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.
hg diff:
On Tue, Feb 19, 2013 at 8:27 AM, Dean Gibson AE7Q data@ae7q.net wrote:
On 2013-02-19 06:38, Dan Smith wrote:
Okay, here is my ID-51 (id51.py) new driver. Also included is an image file for same.
Could you put it into the proper patch format?
http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Submitting-...
OK, I'm confoozed. I previously read that page, and I know that's the correct format for a change. 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:
A new file is a change to Chirp. After adding the new file, Chirp is not the same as it was before. But that's not the point here...
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.
"hg status -mar" does nothing to attribute the changes to you, or label them with an appropriate commit message. Our goal here isn't just to add new lines of code, but to document who added them and why, so that future readers of the code can ask "what was the guy who wrote this thinking??" and have both the explanation (commit message) and name/email of the guy who wrote it. If we find that your change introduces a regression, we are also easily able to search for commit messages containing "id?1" and revert each as needed until the regression disappears.
hg diff:
For this all to work, you must use a different command, "hg qnew ..." to create your patch. You will be prompted to enter a commit message, and when you export it ("hg export tip") your name and email address will be automatically be added to the header. The commands to accomplish this are all listed here:
http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Soft-commit...
When using "hg q.." commands, your changes are not permanent. You can send a work-in-progress patch (see Sending a Change), ask some questions, modify your code, then use "hg qref" to update the patch.
A little bit of record keeping is necessary for managing a large codebase, and I think you'll find the learning curve for hg mq is minimal and saves you effort in the long run.
Tom KD7LXL
Thanks for your reply!
On 2013-02-19 10:14, Tom Hayward wrote:
... A new file is a change to Chirp. After adding the new file, Chirp is not the same as it was before. But that's not the point here...
I understand that. In CVS, to add a new file, I do "cvs add <filename". I presume in Mercurial I do "hg add chirp\id51py" (which I did), which would be added to the repository by a commit. However, if I do the commit, Chirp's web site seems to imply that creates a fork that creates problems, so I haven't done that.
... "hg status -mar" does nothing to attribute the changes to you, or label them with an appropriate commit message.
I understand that "hg status -mar" is the same as "cvs upd"; ie, just lists the files that have changed or been added, and will be committed on the next commit.
Our goal here isn't just to add new lines of code, but to document who added them and why, so that future readers of the code can ask "what was the guy who wrote this thinking??" and have both the explanation (commit message) and name/email of the guy who wrote it. If we find that your change introduces a regression, we are also easily able to search for commit messages containing "id?1" and revert each as needed until the regression disappears.
hg diff:
For this all to work, you must use a different command, "hg qnew ..." to create your patch. You will be prompted to enter a commit message, and when you export it ("hg export tip") your name and email address will be automatically be added to the header. The commands to accomplish this are all listed here:
http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Soft-commit...
So far, I've been sent that link THREE TIMES. Each time I have read it IN DETAIL. I don't want to start an argument here, BUT IT IS FAR FROM CLEAR. The Mercurial website documentation is poorer; I had to Google to find the format of the configuration file (named ".hg/hgrc", not ".hg/config" as the Chirp website indicates). Note that I have worked with several source control systems over the forty years I've been developing, so I have a bit of a clue.
EG:
1. The first time I ran "hg export tip", it showed changes (by Dan) to files that I hadn't touched. What's that about? 2. Subsequent invocations return my changes to two files. These two files need to be two separate patches (two separate bug #s). 3. What the hell is "tip" ??? 4. OK, I did "hg qnew -l chirp\id51.py -ef <comment>". Then I removed it with "hg qpop". Somewhere in these few steps my changes (including all of id51.py) were *deleted*. Is that what you mean by "minimal learning curve" below? Fortunately (that means having some experience with the batch of new SCM packages out there), I had a complete backup elsewhere. 5. I just now decided to have multiple backups of my changes. Perhaps I'll use CVS internally ... 6. Another "hg qpop" also removed a "patch" named "help"; I'll let you guess as to how that got there (grin).
When using "hg q.." commands, your changes are not permanent. You can send a work-in-progress patch (see Sending a Change), ask some questions, modify your code, then use "hg qref" to update the patch.
A little bit of record keeping is necessary for managing a large codebase, and I think you'll find the learning curve for hg mq is minimal and saves you effort in the long run.
Tom KD7LXL
*<rant>*
So far this has been all downhill. I've spent *far more time* screwing around with the submission process, that I did to create id51.py (and make proposed changes to id31.py). I don't have/need/want an ID-31A. I have an ID-51A, and the free Icom CS-51 software is sufficient for my needs (including the import of some 250 memories via .CSV files). Frankly, it's less buggy as well.
I thought, "Chirp lacks ID-51 support, and I have one; let's see if I can help". That's my sole motivation. Just as changing DStarCom to open source so that Chirp could use some of that code, was to help (see Dan's blog on my code). The changes I have to id31.py are because (having cloned id51.py from it) I think there are errors in the memory layout, and it seems reasonable to help fix that as well.
We're all volunteers here, and I don't expect anyone to jump through hoops for me. On the other hand, I'm retired, and have plenty of spare time to contribute to useful efforts. Of course, I have MANY choices for how I spend that time (that includes being paid to fly small airplanes in wonderful weather), and screwing around with yet another inadequately documented tool is not high on my list.
I don't know if you have read the book "Psychology of Computer Programming" by Gerald Weinberg. Written in 1972, it's considered a classic. He reported that back then, someone was inventing a new computer language about once a week. This industry is filled with people that "have to" create new ("vanity") languages or tools, with very marginal additional utility (or worse) between them. Remember "BitKeeper"? That was the SCM rage a couple years ago. No one these days counts the productivity cost of learning new tools (for Microsoft, that means new versions of productive software, with the main change being useless changes to the GUI) that are not adequately documented.
*</rant>*
So, I'll try once more:
hg qnew -l chirp\id51.py -ef "[id51] Add support for Icom ID-51"
I'm supposed to enter the bug # (553), but "qnew" won't take a "#" on the command line, and up pops a NotePad window with the changed file (??? I just closed it). So, no info on that. What follows is the output from the next command. I sure don't see my comment (above), and I sure thought that almost all of the lines would be prefixed by a "+". So,, my guess is that this will be unacceptable as well. I'm sure not going to submit any changes to id31.py until I've sorted this out.
hg export tip
# HG changeset patch # User Dean Gibson data@ae7q.net # Date 1361307603 28800 # Node ID b94ce8ef429fb5bf5750d96341c6d38354837b57 # Parent 5528bdcdc34e5966d5b7f0dbb6859f700b5f9366 # Copyright 2012 Dan Smith dsmith@danplanet.com # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/.
from chirp import directory, icf, bitwise, chirp_common
MEM_FORMAT = """ struct { u24 freq; u16 offset; u16 rtone:6, ctone:6, unknown2:1, mode:3; u8 dtcs; u8 tune_step:4, unknown5:4; u8 unknown4; u8 tmode:4, duplex:2, dtcs_polarity:2; char name[16]; u8 unknown13; u8 urcall[7]; u8 rpt1call[7]; u8 rpt2call[7]; } memory[500];
#seekto 0x6A40; u8 used_flags[70];
#seekto 0x6A86; u8 skip_flags[69];
#seekto 0x6ACB; u8 pskp_flags[69];
#seekto 0x6B40; struct { u8 bank; u8 index; } banks[500];
#seekto 0x6FD0; struct { char name[16]; } bank_names[26];
#seekto 0xA8C0; struct { u24 freq; u16 offset; u8 unknown1[3]; u8 call[7]; char name[16]; char subname[8]; u8 unknown3[10]; } repeaters[700];
#seekto 0x1384E; struct { u8 call[7]; } rptcall[700];
#seekto 0x14E60; struct { char call[8]; char tag[4]; } mycall[6];
#seekto 0x14EA8; struct { char call[8]; } urcall[200];
"""
MODES = [ "FM", "NFM", "AM", "DV" ] MODE_INDEX = [ 0, 1, 3, 5 ] TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS", "TSQL-R", "DTCS-R"] DUPLEX = ["", "-", "+"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] TUNING_STEPS = [5.0, 6.25, 0, 0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 125.0, 200.0]
def _decode_call(_call): # Why Icom, why? call = "" shift = 1 acc = 0 for val in _call: mask = (1 << (shift)) - 1 call += chr((val >> shift) | acc) acc = (val & mask) << (7 - shift) shift += 1 call += chr(acc) return call
def _encode_call(call): _call = [0x00] * 7 for i in range(0, 7): val = ord(call[i]) << (i + 1) if i > 0: _call[i-1] |= (val & 0xFF00) >> 8 _call[i] = val _call[6] |= (ord(call[7]) & 0x7F)
return _call
def _get_freq(_mem): freq = int(_mem.freq) offs = int(_mem.offset)
if freq & 0x00200000: mult = 6250 else: mult = 5000
freq &= 0x0003FFFF
return (freq * mult), (offs * mult)
def _set_freq(_mem, freq, offset): if chirp_common.is_fractional_step(freq): mult = 6250 flag = 0x00200000 else: mult = 5000 flag = 0x00000000
_mem.freq = (freq / mult) | flag _mem.offset = (offset / mult)
class ID51Bank(icf.IcomBank): """A ID-51 Bank""" def get_name(self): _banks = self._model._radio._memobj.bank_names return str(_banks[self.index].name).rstrip()
def set_name(self, name): _banks = self._model._radio._memobj.bank_names _banks[self.index].name = str(name).ljust(16)[:16]
@directory.register class ID51Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): """Icom ID-51""" MODEL = "ID-51A"
_memsize = 0x1FB40 _model = "\x33\x90\x00\x01" _endframe = "Icom Inc\x2E\x44\x41" _num_banks = 26 _bank_class = ID51Bank _can_hispeed = True
_ranges = [(0x00000, 0x1FB40, 32)]
def _get_bank(self, loc): _bank = self._memobj.banks[loc] if _bank.bank == 0xFF: return None else: return _bank.bank
def _set_bank(self, loc, bank): _bank = self._memobj.banks[loc] if bank is None: _bank.bank = 0xFF else: _bank.bank = bank
def _get_bank_index(self, loc): _bank = self._memobj.banks[loc] return _bank.index
def _set_bank_index(self, loc, index): _bank = self._memobj.banks[loc] _bank.index = index
def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 499) rf.valid_bands = [(108000000, 174000000), (400000000, 479000000)] rf.has_settings = True rf.has_ctone = True rf.has_bank_index = True rf.has_bank_names = True rf.valid_tmodes = list(TMODES) rf.valid_tuning_steps = sorted(list(TUNING_STEPS)) rf.valid_modes = list(MODES) rf.valid_skips = ["", "S", "P"] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 16 return rf
def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
def get_raw_memory(self, number): return repr(self._memobj.memory[number])
def get_memory(self, number): _mem = self._memobj.memory[number] _usd = self._memobj.used_flags[number / 8] _skp = self._memobj.skip_flags[number / 8] _psk = self._memobj.pskp_flags[number / 8]
bit = (1 << (number % 8))
if MODES[MODE_INDEX.index(_mem.mode)] == "DV": mem = chirp_common.DVMemory() else: mem = chirp_common.Memory() mem.number = number
if _usd & bit: mem.empty = True return mem
mem.freq, mem.offset = _get_freq(_mem) mem.name = str(_mem.name).rstrip() mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.tuning_step = TUNING_STEPS[_mem.tune_step] mem.mode = MODES[MODE_INDEX.index(_mem.mode)]
if mem.mode == "DV": mem.dv_urcall = _decode_call(_mem.urcall).rstrip() mem.dv_rpt1call = _decode_call(_mem.rpt1call).rstrip() mem.dv_rpt2call = _decode_call(_mem.rpt2call).rstrip()
if _psk & bit: mem.skip = "P" if _skp & bit: mem.skip = "S"
return mem
def set_memory(self, memory): _mem = self._memobj.memory[memory.number] _usd = self._memobj.used_flags[memory.number / 8] _skp = self._memobj.skip_flags[memory.number / 8] _psk = self._memobj.pskp_flags[memory.number / 8]
bit = (1 << (memory.number % 8))
if memory.empty: _usd |= bit self._set_bank(memory.number, None) return
_usd &= ~bit
_set_freq(_mem, memory.freq, memory.offset) _mem.name = memory.name.ljust(16)[:16] _mem.rtone = chirp_common.TONES.index(memory.rtone) _mem.ctone = chirp_common.TONES.index(memory.ctone) _mem.tmode = TMODES.index(memory.tmode) _mem.duplex = DUPLEX.index(memory.duplex) _mem.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs) _mem.dtcs_polarity = DTCS_POLARITY.index(memory.dtcs_polarity) _mem.tune_step = TUNING_STEPS.index(memory.tuning_step) _mem.mode = MODE_INDEX[MODES.index(memory.mode)]
if isinstance(memory, chirp_common.DVMemory): _mem.urcall = _encode_call(memory.dv_urcall.ljust(8)) _mem.rpt1call = _encode_call(memory.dv_rpt1call.ljust(8)) _mem.rpt2call = _encode_call(memory.dv_rpt2call.ljust(8)) elif memory.mode == "DV": raise Exception("BUG")
if memory.skip == "S": _skp |= bit _psk &= ~bit elif memory.skip == "P": _skp &= ~bit _psk |= bit else: _skp &= ~bit _psk &= ~bit
def get_urcall_list(self): calls = [] for i in range(0, 200): call = str(self._memobj.urcall[i].call) if call == "CALLSIGN": call = "" calls.append(call) return calls
def get_mycall_list(self): calls = [] for i in range(0, 6): calls.append(str(self._memobj.mycall[i].call)) return calls
def get_repeater_call_list(self): calls = [] for rptcall in self._memobj.rptcall: call = _decode_call(rptcall.call) if call.rstrip() and not call == "CALLSIGN": calls.append(call) for repeater in self._memobj.repeaters: call = _decode_call(repeater.call) if call == "CALLSIGN": call = "" calls.append(call.rstrip()) return calls
On Tue, Feb 19, 2013 at 1:29 PM, Dean Gibson AE7Q data@ae7q.net wrote:
The first time I ran "hg export tip", it showed changes (by Dan) to files that I hadn't touched. What's that about?
At that time, that was the most recent thing applied to your local repository. You must have done that before running hg qnew.
Subsequent invocations return my changes to two files. These two files need to be two separate patches (two separate bug #s). What the hell is "tip" ???
tip is the latest commit. Same as git's HEAD.
Multiple files can be lumped in the same commit, as long as they go with the same bug/feature.
If you need to export more than one commit at a time (two separate issues), you would first run "hg qnew" for each, with appropriate options to attach the intended files (see the man page). With multiple commits to export, we can't use the tip shortcut, we need to look up the revisions numbers with hg log. Then export as needed like "hg export -r 1897 > id31.patch", "hg export -r 1898 > id51.patch", etc.
OK, I did "hg qnew -l chirp\id51.py -ef <comment>". Then I removed it with "hg qpop". Somewhere in these few steps my changes (including all of id51.py) were deleted. Is that what you mean by "minimal learning curve" below? Fortunately (that means having some experience with the batch of new SCM packages out there), I had a complete backup elsewhere. I just now decided to have multiple backups of my changes. Perhaps I'll use CVS internally ... Another "hg qpop" also removed a "patch" named "help"; I'll let you guess as to how that got there (grin).
Yep, hg qpop removes it from your working stack, so you're back to vanilla Chirp. hg qpush puts it back.
<rant>
So far this has been all downhill. I've spent far more time screwing around with the submission process, that I did to create id51.py (and make proposed changes to id31.py).
Chirp uses industry standard SCM software and a submission process identical to a huge number of open source projects. I use very similar SCM tools to manage the code I produce for work. We're not trying to burden you, just using modern standard tools.
So, I'll try once more:
hg qnew -l chirp\id51.py -ef "[id51] Add support for Icom ID-51"
I'm supposed to enter the bug # (553), but "qnew" won't take a "#" on the command line, and up pops a NotePad window with the changed file (??? I just closed it). So, no info on that. What follows is the output from the next command. I sure don't see my comment (above), and I sure thought that almost all of the lines would be prefixed by a "+". So,, my guess is that this will be unacceptable as well. I'm sure not going to submit any changes to id31.py until I've sorted this out.
The editor opened so you could compose a commit message like the following: [id51] Add support for Icom ID-51. #553
hg export tip
# HG changeset patch # User Dean Gibson data@ae7q.net # Date 1361307603 28800 # Node ID b94ce8ef429fb5bf5750d96341c6d38354837b57 # Parent 5528bdcdc34e5966d5b7f0dbb6859f700b5f9366
Since you just closed Notepad before typing a commit message, there's no commit message on the following patch, but otherwise you have used the tools correctly. Congratulations!
# Copyright 2012 Dan Smith dsmith@danplanet.com
If you wrote the following code, it is appropriate for you to change the copyright to your name.
Tom KD7LXL
I do thank you for your help (and it was helpful). However, in the process of doing the hg stuff for id51.py for my last message, hg deleted (or hid) my changes to id31.py. I don't care "modern" the SCM tools are, any tool that deletes (or hides) my changes without warning or telling me, is "modern" in the same sense as Windows 8. This is not a guessing game for me, nor is it a major research project.
I also had to learn Python for these changes, and it was the first time in my life that I had seen Python code. It took all of about 15 minutes of code examination, a few minutes with the Python documentation, and one question (about #seekto) to Dan, and the changes were easy. Note the distinction ...
So, I'm done for today. I'm blowing away the entire @#$$%% chirp.hg repository (after saving the files I changed), and when another bad-weather day comes along, I'll reload the repository again from scratch, and try again, ONE FILE AT A TIME.
Again, I do sincerely thank you for your time in helping me.
As for the copyright, I just cloned id31.py and modified a few lines of Dan's code. Yes, the id31.py and id51.py drivers should not be separate files (the big difference is the location of some structures in the device memory map), but I'm not familiar with the apparently add-on tools that Dan uses for such purposes.
-- Dean
On 2013-02-19 14:01, Tom Hayward wrote:
On Tue, Feb 19, 2013 at 1:29 PM, Dean Gibson AE7Q data@ae7q.net wrote:
The first time I ran "hg export tip", it showed changes (by Dan) to files that I hadn't touched. What's that about?
At that time, that was the most recent thing applied to your local repository. You must have done that before running hg qnew.
Subsequent invocations return my changes to two files. These two files need to be two separate patches (two separate bug #s). What the hell is "tip" ???
tip is the latest commit. Same as git's HEAD.
Multiple files can be lumped in the same commit, as long as they go with the same bug/feature.
If you need to export more than one commit at a time (two separate issues), you would first run "hg qnew" for each, with appropriate options to attach the intended files (see the man page). With multiple commits to export, we can't use the tip shortcut, we need to look up the revisions numbers with hg log. Then export as needed like "hg export -r 1897 > id31.patch", "hg export -r 1898 > id51.patch", etc.
OK, I did "hg qnew -l chirp\id51.py -ef <comment>". Then I removed it with "hg qpop". Somewhere in these few steps my changes (including all of id51.py) were deleted. Is that what you mean by "minimal learning curve" below? Fortunately (that means having some experience with the batch of new SCM packages out there), I had a complete backup elsewhere. I just now decided to have multiple backups of my changes. Perhaps I'll use CVS internally ... Another "hg qpop" also removed a "patch" named "help"; I'll let you guess as to how that got there (grin).
Yep, hg qpop removes it from your working stack, so you're back to vanilla Chirp. hg qpush puts it back.
<rant>
So far this has been all downhill. I've spent far more time screwing around with the submission process, that I did to create id51.py (and make proposed changes to id31.py).
Chirp uses industry standard SCM software and a submission process identical to a huge number of open source projects. I use very similar SCM tools to manage the code I produce for work. We're not trying to burden you, just using modern standard tools.
So, I'll try once more:
hg qnew -l chirp\id51.py -ef "[id51] Add support for Icom ID-51"
I'm supposed to enter the bug # (553), but "qnew" won't take a "#" on the command line, and up pops a NotePad window with the changed file (??? I just closed it). So, no info on that. What follows is the output from the next command. I sure don't see my comment (above), and I sure thought that almost all of the lines would be prefixed by a "+". So,, my guess is that this will be unacceptable as well. I'm sure not going to submit any changes to id31.py until I've sorted this out.
The editor opened so you could compose a commit message like the following: [id51] Add support for Icom ID-51. #553
hg export tip
# HG changeset patch # User Dean Gibson data@ae7q.net # Date 1361307603 28800 # Node ID b94ce8ef429fb5bf5750d96341c6d38354837b57 # Parent 5528bdcdc34e5966d5b7f0dbb6859f700b5f9366
Since you just closed Notepad before typing a commit message, there's no commit message on the following patch, but otherwise you have used the tools correctly. Congratulations!
# Copyright 2012 Dan Smith dsmith@danplanet.com
If you wrote the following code, it is appropriate for you to change the copyright to your name.
Tom KD7LXL _______________________________________________ chirp_devel mailing list chirp_devel@intrepid.danplanet.com http://intrepid.danplanet.com/mailman/listinfo/chirp_devel Developer docs: http://chirp.danplanet.com/projects/chirp/wiki/Developers
On Tue, Feb 19, 2013 at 3:50 PM, Dean Gibson AE7Q data@ae7q.net wrote:
I do thank you for your help (and it was helpful). However, in the process of doing the hg stuff for id51.py for my last message, hg deleted (or hid) my changes to id31.py. I don't care "modern" the SCM tools are, any tool that deletes (or hides) my changes without warning or telling me, is "modern" in the same sense as Windows 8. This is not a guessing game for me, nor is it a major research project.
It sounds like Dean is done messing with this, but for the rest of you listening: Mercurial doesn't delete or hide files on its own. In this case, Dean issued the "hg qpop" command, instructing Mercurical to remove his changes from the code. "hg qpush" will put them back.
Tom KD7LXL
Hi,
The instructions at http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Soft-commit... this mistake. Clarifying what add_comment means and adding some explanation about the second pre block (are they commands to be entered verbatim? Are they a list of commands supported by the mq extension?) would help. Everything else on that page can be copy/pasted as is, are you meant to copy/paste those commands?
On Wed, Feb 20, 2013 at 5:25 PM, Tom Hayward esarfl@gmail.com wrote:
On Tue, Feb 19, 2013 at 3:50 PM, Dean Gibson AE7Q data@ae7q.net wrote:
I do thank you for your help (and it was helpful). However, in the process of doing the hg stuff for id51.py for my last message, hg deleted (or hid) my changes to id31.py. I don't care "modern" the SCM tools are, any tool that deletes (or hides) my changes without warning or telling me, is "modern" in the same sense as Windows 8. This is not a guessing game for me, nor is it a major research project.
It sounds like Dean is done messing with this, but for the rest of you listening: Mercurial doesn't delete or hide files on its own. In this case, Dean issued the "hg qpop" command, instructing Mercurical to remove his changes from the code. "hg qpush" will put them back.
Tom KD7LXL _______________________________________________ chirp_devel mailing list chirp_devel@intrepid.danplanet.com http://intrepid.danplanet.com/mailman/listinfo/chirp_devel Developer docs: http://chirp.danplanet.com/projects/chirp/wiki/Developers
On Wed, Feb 20, 2013 at 1:02 PM, Sean Burford sburford@google.com wrote:
Hi,
The instructions at http://chirp.danplanet.com/projects/chirp/wiki/DevelopersProcess#Soft-commit... encourage this mistake. Clarifying what add_comment means and adding some explanation about the second pre block (are they commands to be entered verbatim? Are they a list of commands supported by the mq extension?) would help. Everything else on that page can be copy/pasted as is, are you meant to copy/paste those commands?
I just changed it to table format instead of code format. Is this more intuitive?
Tom KD7LXL
P.S. You're always welcome to improve the wiki yourself. For those of you not fluent in programming, this is a great way for you to contribute.
On 2013-02-20 13:23, Tom Hayward wrote:
I just changed it to table format instead of code format. Is this more intuitive?
No, because it still appears as a sequence of operations (which it is). It's apparently an example of what you CAN do, and not what you SHOULD do, to get started. When I teach flying to a new student, I don't show them how to recover from a spin in the first lesson (some instructors do, but they don't retain many students) ...
It's raining, so I'm going to give this about an hour shot tonight. Each day I'll give it a try, until I have success, or get tired of the process.
During this journey, I may make sarcastic comments about the documentation (which is my complaint, not the actions of HG). Please don't take them personally; we are all volunteers. However, if the process of retaining volunteers is difficult, that adds to the load on the existing volunteers, so my hope is that they encourage modifications to the documentation. For I hope obvious reasons, I'm not the person to be making any documentation changes anytime soon.
So here goes:
#1. You say, "If this tool intrigues you, you can learn how to use it here: http://mercurial.selenic.com/wiki/MqTutorial". So, I guess if someone is not intrigued at the time (and thus doesn't follow the link), but just wants to submit some changes, one doesn't get to learn that you apparently need to do a "hg init --mq" at the beginning ...
-- to be continued ...
OK, I guess today was my lucky day. Attached is the test suite image for the ID-51A.
Here's what I did (it may be instructive for newbies):
=>cd [base directory] =>hg clone http://d-rats.com/hg/chirp.hg =>cd chirp.hg =>unzip ..\ChirpUpdates.zip .hg\hgrc # My backup to use after wiping =>unzip ..\ChirpUpdates.zip chirp\id51.py # Ditto
# Edit and test ...
=>hg qnew -ef id51 =>hg export tip > id51.patch # This contained nothing but the commit message, ha ha. =>hg qdel id51 # error # OK, let's try again. Oops! =>hg qunapplied id51 # Will this help ? =>hg qdel id51 # error # Nope ... =>hg qpop # Ah, the joys of experimentation =>hg qdel id51 # Ah HA!
=>hg add chirp\id51.py # Wild guess =>hg qnew -ef id51 # Once more into the breach =>hg export tip > id51.patch # Bingo! =>hg email tip this patch series consists of 1 patches.
To: chirp_devel@intrepid.danplanet.com Cc:
abort: (535, 'Error: authentication failed')
# Remove quotes around password in .hg/hgrc & try again ... # Like, you can't quote special characters in a password ? # The docs say it strips leading and trailing spaces. # OK, so I don't use a password with a leading or trailing space, # but still ...
=>hg email tip this patch series consists of 1 patches.
To: chirp_devel@intrepid.danplanet.com Cc:
sending [PATCH] [id51] Add support for Icom ID-51A #553 ...
On 2013-02-18 19:26, Dan Smith wrote:
ps: Now if someone can give me some hints as to how to add support for banks "B" thru "E" on the IC-7000, I will be really happy (# 551)
The CIV drivers are a bit messy, but it shouldn't be that hard. I'd guess one of the zero bytes is the bank number, so I'd just start incrementing them one at a time until you get back a B-bank memory :)
Questions:
1. Yes, that's what I thought I'd try as well. Does Chirp include a tool to send random CI-V commands to the IC-7000, and display the results? I thought I remembered seeing such a tool somewhere ... 2. On the Icom D-Star radios, you treat the successive 100-entry memory banks as one large contiguous bank; a good idea for those radios. However, the IC-7000 has five 99-entry banks, so I think making them contiguous might make for confusing numbering of the memory. The alternative of creating a bogus entry to make the numbers "match" (which is what I would do if it was just me using the software), would work but could introduce confusion as well. Creating a separate memory tab for each bank would be best, but I don't know how to do that, and that involves an architectural design issue that should be consistent across radios, I'd think. 3. I haven't done anything to my Chirp repository since I submitted id51.py. While I can blow away the repository and get a new copy, my guess is that's not the best way. What method do you recommend? HG "revert" or "update"? 4. [change of subject] Yes, the D-Star callsign "tag" field is missing from id31.py. I'll create a bug, fix it, and submit it.
-- Dean
- Yes, that's what I thought I'd try as well. Does Chirp include a tool to send random CI-V commands to the IC-7000, and display the results? I thought I remembered seeing such a tool somewhere ...
Nope, but I'd take it if you want to add it :)
- On the Icom D-Star radios, you treat the successive 100-entry
memory banks as one large contiguous bank; a good idea for those radios. However, the IC-7000 has five 99-entry banks, so I think making them contiguous might make for confusing numbering of the memory. The alternative of creating a bogus entry to make the numbers "match" (which is what I would do if it was just me using the software), would work but could introduce confusion as well. Creating a separate memory tab for each bank would be best, but I don't know how to do that, and that involves an architectural design issue that should be consistent across radios, I'd think.
Chirp has architectural support for devices with multiple chunks of main memory. It calls these "sub devices" as this is usually needed for sub-vfos. The way this is reflected in the UI right now is really annoying, and would be especially so if you were to add more than two for a given model. I've mostly been ignoring the problem because I hate radios that have different memories for the two VFOs and tend not to use them. However, perhaps your case here is a good reason to fix that.
If you want to expose the banks as five sub-devices, I'll commit to trying to fix the UI in the way I think should be done in hopes of ending up with something sane.
The IC9x driver behaves this way, but don't look at it as an example -- it is an embarrassing mess. The FT7800/8800/8900 driver does this as well, but it is a mess for various other reasons, so don't look at it either. Probably the best option would be the new ft350 driver, which is probably the cleanest one I can think of at the moment.
- I haven't done anything to my Chirp repository since I submitted id51.py. While I can blow away the repository and get a new copy, my guess is that's not the best way. What method do you
recommend? HG "revert" or "update"?
If you had it as a mq patch, then you can just qpop it off the stack (so that hg qapplied shows nothing) and then update your local repo from mine with "hg pull -u")
participants (4)
-
Dan Smith
-
Dean Gibson AE7Q
-
Sean Burford
-
Tom Hayward