[chirp_devel] [FT-90] add initial support for FT-90R. #1087
Initial support for Yaesu FT-90R. Probably a bit buggy. #1087
diff -r 86910885e998 -r 98bdf0cae780 chirp/ft90.py --- /dev/nullThu Jan 01 00:00:00 1970 +0000 +++ b/chirp/ft90.pySat Aug 24 19:31:50 2013 -0500 @@ -0,0 +1,317 @@ +# Copyright 2011 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 chirp_common, memmap, directory, errors, util, yaesu_clone +from chirp import bitwise +import time, os, traceback + +CHIRP_DEBUG=True +CMD_ACK = chr(0x06) + +@directory.register +class FT90Radio(yaesu_clone.YaesuCloneModeRadio): + VENDOR = "Yaesu" + MODEL = "FT-90" + ID = "ft90" + + STEPS = [5, 10, 12.5, 15, 20, 25, 50] + MODES = ["AM", "FM", "Auto"] + TMODES = ["", "Tone", "TSQL", "Bell", "DTCS"] + TONES = [ 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5, + 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5, + 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, + 131.8, 136.5, 141.3, 146.2, 151.4, 156.7, + 159.8, 162.2, 167.9, 173.8, 179.9, 183.5, + 186.2, 189.9, 192.8, 196.6, 199.5, 203.5, + 206.5, 210.7, 218.1, 225.7, 229.1, 233.6, + 241.8, 250.3, 254.1, + ] + + POWER_LEVELS = ["Hi","Mid1","Mid2","Low"] + #DUPLEX = ["", "-", "+", "split", "Auto"] + DUPLEX = ["", "-", "+", "split"] + + _memsize = 4063 + # block 03 (200 Bytes long) repeats 18 times; channel memories + _block_lengths = [ 2, 232, 24, 200, 205] + + mem_format = """ + #seekto 0x102; + struct { + u8 mode:2, + isUhf1:1, + unknown1:2, + step:3; + u8 artsmode:2, + unknown2:1, + isUhf2:1 + power:2, + shift:2; + u8 skip:1, + showname:1, + unknown3:1, + isUhfHi:1, + unknown4:1, + tmode:3; + u32 rxfreq; + u32 txfreqoffset; + u8 UseDefaultName:1, + ars:1, + tone:6; + u8 packetmode:1, + unknown5:1, + dcstone:6; + char name[7]; + } memory[180]; + """ + + @classmethod + def match_model(cls, filedata, filename): + return len(filedata) == cls._memsize + + def get_features(self): + rf = chirp_common.RadioFeatures() + rf.has_ctone = False + rf.has_bank = False + rf.has_dtcs_polarity = False + rf.valid_modes = list(set(self.MODES)) + rf.valid_tmodes = list(self.TMODES) + rf.valid_duplexes = list(self.DUPLEX) + rf.valid_tuning_steps = list(self.STEPS) + rf.valid_power_levels = self.POWER_LEVELS + rf.valid_name_length = 7 + rf.valid_characters = chirp_common.CHARSET_ASCII + rf.valid_skips = ["", "S"] + rf.memory_bounds = (1, 180) + rf.valid_bands = [(100000000, 230000000), + (300000000, 530000000), (810000000, 999975000)] + + return rf + + def _read(self, blocksize, blocknum): + data = self.pipe.read(blocksize+2) + + # chew echo'd ack + self.pipe.write(CMD_ACK) + time.sleep(0.02) + self.pipe.read(1) # chew echoed ACK from 1-wire serial + + if len(data) == blocksize+2 and data[0] == chr(blocknum): + checksum = yaesu_clone.YaesuChecksum(1, blocksize) + if checksum.get_existing(data) != checksum.get_calculated(data): + raise Exception("Checksum Failed [%02X<>%02X] block %02X, data len: %i" % + (checksum.get_existing(data), + checksum.get_calculated(data), blocknum, len(data) )) + data = data[1:blocksize+1] # Chew blocknum and checksum + + else: + raise Exception("Unable to read blocknum %02X expected blocksize %i got %i." % + (blocknum, blocksize+2, len(data))) + + return data + + def _clone_in(self): + # Be very patient with the radio + self.pipe.setTimeout(4) + start = time.time() + + data = "" + blocknum = 0 + status = chirp_common.Status() + status.msg = "Cloning from radio.\nPut radio into clone mode then\npress SET to send" + self.status_fn(status) + status.max = len(self._block_lengths) + 18 + for blocksize in self._block_lengths: + if blocksize == 200: + # repeated read of 200 block same size (memory area) + repeat = 18 + else: + repeat = 1 + for _i in range(0, repeat): + data += self._read(blocksize, blocknum) + + blocknum += 1 + status.cur = blocknum + self.status_fn(status) + + status.msg = "Clone completed." + self.status_fn(status) + + print "Clone completed in %i seconds, blocks read: %i" % (time.time() - start, blocknum) + + return memmap.MemoryMap(data) + + def _clone_out(self): + delay = 0.2 + start = time.time() + + blocknum = 0 + pos = 0 + status = chirp_common.Status() + status.msg = "Cloning to radio.\nPut radio into clone mode and press DISP/SS\n to start receive within 3 secs..." + self.status_fn(status) + # radio likes to have port open + self.pipe.open() + time.sleep(3) + status.max = len(self._block_lengths) + 18 + + + for blocksize in self._block_lengths: + if blocksize == 200: + # repeat channel blocks + repeat = 18 + else: + repeat = 1 + for _i in range(0, repeat): + time.sleep(0.1) + checksum = yaesu_clone.YaesuChecksum(pos, pos+blocksize-1) + blocknumbyte = chr(blocknum) + payloadbytes = self.get_mmap()[pos:pos+blocksize] + checksumbyte = chr(checksum.get_calculated(self.get_mmap())) + if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG: + print "Block %i - will send from %i to %i byte " % \ + (blocknum, pos, pos + blocksize) + print util.hexprint(blocknumbyte) + print util.hexprint(payloadbytes) + print util.hexprint(checksumbyte) + # send wrapped bytes + self.pipe.write(blocknumbyte) + self.pipe.write(payloadbytes) + self.pipe.write(checksumbyte) + tmp = self.pipe.read(blocksize+2) #chew echo + if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG: + print "bytes echoed: " + print util.hexprint(tmp) + # radio is slow to write/ack: + time.sleep(0.9) + buf = self.pipe.read(1) + if os.getenv("CHIRP_DEBUG") or CHIRP_DEBUG: + print "ack recd:" + print util.hexprint(buf) + if buf != CMD_ACK: + raise Exception("Radio did not ack block %i" % blocknum) + pos += blocksize + blocknum += 1 + status.cur = blocknum + self.status_fn(status) + + print "Clone completed in %i seconds" % (time.time() - start) + + def sync_in(self): + try: + self._mmap = self._clone_in() + except errors.RadioError: + raise + except Exception, e: + trace = traceback.format_exc() + raise errors.RadioError("Failed to communicate with radio: %s" % trace) + self.process_mmap() + + def sync_out(self): + try: + self._clone_out() + except errors.RadioError: + raise + except Exception, e: + trace = traceback.format_exc() + raise errors.RadioError("Failed to communicate with radio: %s" % trace) + + def process_mmap(self): + self._memobj = bitwise.parse(self.mem_format, self._mmap) + + def get_memory(self, number): + _mem = self._memobj.memory[number-1] + + mem = chirp_common.Memory() + mem.number = number + mem.freq = _mem.rxfreq * 10 + mem.offset = _mem.txfreqoffset * 10 + if not _mem.tmode < len(self.TMODES): + _mem.tmode = 0 + mem.tmode = self.TMODES[_mem.tmode] + mem.rtone = self.TONES[_mem.tone] + mem.mode = self.MODES[_mem.mode] + + ''' + # ars mode note yet working... + # ARS mode: + if _mem.ars and _mem.shift == 0: + mem.duplex = self.DUPLEX[4] + else: + mem.duplex = self.DUPLEX[_mem.shift] + ''' + mem.duplex = self.DUPLEX[_mem.shift] + mem.power = self.POWER_LEVELS[_mem.power] + # radio has a known bug with 5khz step and squelch + if _mem.step == 0: + _mem.step = 2 + mem.tuning_step = self.STEPS[_mem.step] + mem.skip = _mem.skip and "S" or "" + mem.name = _mem.name + return mem + + def get_raw_memory(self, number): + return repr(self._memobj.memory[number-1]) + + def set_memory(self, mem): + + _mem = self._memobj.memory[mem.number - 1] + _mem.skip = mem.skip == "S" + # radio has a known bug with 5khz step and dead squelch + if mem.tuning_step == self.STEPS[0]: + _mem.step = 2 + else: + _mem.step = self.STEPS.index(mem.tuning_step) + _mem.rxfreq = mem.freq / 10 + # vfo will unlock if not in right band? + if mem.freq > 300000000: + # uhf + _mem.isUhf1 = 1 + _mem.isUhf2 = 1 + if mem.freq > 810000000: + # uhf hiband + _mem.isUhfHi = 1 + else: + _mem.isUhfHi = 0 + else: + # vhf + _mem.isUhf1 = 0 + _mem.isUhf2 = 0 + _mem.isUhfHi = 0 + _mem.txfreqoffset = mem.offset / 10 + _mem.tone = self.TONES.index(mem.rtone) + _mem.tmode = self.TMODES.index(mem.tmode) + _mem.mode = self.MODES.index(mem.mode) + ''' + # ars not yet working + # ARS mode: + if mem.duplex == 4: + _mem.shift = 0 + _mem.ars = 1 + else: + _mem.shift = self.DUPLEX.index(mem.duplex) + ''' + _mem.shift = self.DUPLEX.index(mem.duplex) + #_mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) + if self.get_features().has_tuning_step: + _mem.step = self.STEPS.index(mem.tuning_step) + _mem.shift = self.DUPLEX.index(mem.duplex) + if mem.power: + _mem.power = self.POWER_LEVELS.index(mem.power) + else: + _mem.power = 3 # default to low power + _mem.name = mem.name.ljust(7) + +
Initial support for Yaesu FT-90R. Probably a bit buggy. #1087
Do you want this to go into the tree, or are you just floating it for comments?
+# Copyright 2011 Dan Smith dsmith@danplanet.com
Be sure to add your copyright here.
- STEPS = [5, 10, 12.5, 15, 20, 25, 50]
Steps are floats, so these will cause issues during import from something else, I think.
- MODES = ["AM", "FM", "Auto"]
- TMODES = ["", "Tone", "TSQL", "Bell", "DTCS"]
Auto and Bell aren't allowed, so memories that resolve to these are going to break, right?
- TONES = [ 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5,
- 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5,
- 107.2, 110.9, 114.8, 118.8, 123.0, 127.3,
- 131.8, 136.5, 141.3, 146.2, 151.4, 156.7,
- 159.8, 162.2, 167.9, 173.8, 179.9, 183.5,
- 186.2, 189.9, 192.8, 196.6, 199.5, 203.5,
- 206.5, 210.7, 218.1, 225.7, 229.1, 233.6,
- 241.8, 250.3, 254.1,
- ]
Is this list different than the main one in chirp_common? While it's a little messy, I think it would be better to stick with the convention of copying the main list and adding/removing tones to get to the supported list. At the very least, it makes it easyier to come back and figure out what the deltas are.
- POWER_LEVELS = ["Hi","Mid1","Mid2","Low"]
Need spaces after the commas
- #DUPLEX = ["", "-", "+", "split", "Auto"]
- DUPLEX = ["", "-", "+", "split"]
I like to avoid commented-out code whenever possible. Perhaps just a comment above that says "Duplex index 4 is auto mode". Will memories with auto set create an IndexError trying to look their value up in this list?
- def get_memory(self, number):
- _mem = self._memobj.memory[number-1]
- mem = chirp_common.Memory()
- mem.number = number
- mem.freq = _mem.rxfreq * 10
- mem.offset = _mem.txfreqoffset * 10
- if not _mem.tmode < len(self.TMODES):
- _mem.tmode = 0
- mem.tmode = self.TMODES[_mem.tmode]
- mem.rtone = self.TONES[_mem.tone]
- mem.mode = self.MODES[_mem.mode]
- '''
- # ars mode note yet working...
- # ARS mode:
- if _mem.ars and _mem.shift == 0:
- mem.duplex = self.DUPLEX[4]
This will fail, right?
- else:
- mem.duplex = self.DUPLEX[_mem.shift]
- '''
- mem.duplex = self.DUPLEX[_mem.shift]
- mem.power = self.POWER_LEVELS[_mem.power]
- # radio has a known bug with 5khz step and squelch
- if _mem.step == 0:
- _mem.step = 2
- mem.tuning_step = self.STEPS[_mem.step]
- mem.skip = _mem.skip and "S" or ""
- mem.name = _mem.name
- return mem
I don't see the DCS code being decoded anywhere. IIRC, that was the thing I could never figure out.
Thanks!
Yeah, belay this for another round. I'm currently working on mapping out the special channels (vfos, calls, u/l scan limits) as well as the some of the global settings. I'm not sure exactly how those special channels are dealt with, as I didnt see a sample implementation in template, just an actual implementation like ft-857, etc.
How can I solve the issues with importing from floats that dont match (i.e., 6.25)? do I need to bracket them into my list at get_memory or set_memory time?
On the ToneSql type, how do I preserve a channel setting for Bell or Auto, if chirp doesnt support it. Do I have to be destructive and box all channels into one of the supported types? It's totally possible to have set Bell or Auto in memory on the radio. What happens when I import this now? How should I deal with this, if I cant tell chirp what are possible/legal values for my radio?
I commented out the ARS code, but now if I can do custom fields (i'll see how it's done with uv-5r) then I may be able to make this a bool field, and deal with the logic of ignoring/setting duplex field in get/set memory members.
I'll check the DCS values, probably differs from chirp_common list, but it has a field for it in radio memory. I'll do what you suggest, i.e., import chirp_common tones/dcs tones list, and remove unsupported tones. I understand it is semantics and style, but since these allowed tone values for this particular radio will NEVER change, I don't want to be dependent upon chirp_common tones never changing. It would be a long shot that they ever do change, but if they do, it would be more difficult to determine which tones are now supported/unsupported, since the "source of truth" gets altered. Anyhow, as I do doubt they will change upstream, I'll go with the subtractive pattern you suggest.
________________________________ From: Dan Smith dsmith@danplanet.com To: chirp_devel@intrepid.danplanet.com Sent: Sunday, August 25, 2013 3:19 PM Subject: Re: [chirp_devel] [FT-90] add initial support for FT-90R. #1087
Initial support for Yaesu FT-90R. Probably a bit buggy. #1087
Do you want this to go into the tree, or are you just floating it for comments?
+# Copyright 2011 Dan Smith dsmith@danplanet.com
Be sure to add your copyright here.
- STEPS = [5, 10, 12.5, 15, 20, 25, 50]
Steps are floats, so these will cause issues during import from something else, I think.
- MODES = ["AM", "FM", "Auto"]
- TMODES = ["", "Tone", "TSQL", "Bell", "DTCS"]
Auto and Bell aren't allowed, so memories that resolve to these are going to break, right?
- TONES = [ 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5,
- 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5,
- 107.2, 110.9, 114.8, 118.8, 123.0, 127.3,
- 131.8, 136.5, 141.3, 146.2, 151.4, 156.7,
- 159.8, 162.2, 167.9, 173.8, 179.9, 183.5,
- 186.2, 189.9, 192.8, 196.6, 199.5, 203.5,
- 206.5, 210.7, 218.1, 225.7, 229.1, 233.6,
- 241.8, 250.3, 254.1,
- ]
Is this list different than the main one in chirp_common? While it's a little messy, I think it would be better to stick with the convention of copying the main list and adding/removing tones to get to the supported list. At the very least, it makes it easyier to come back and figure out what the deltas are.
- POWER_LEVELS = ["Hi","Mid1","Mid2","Low"]
Need spaces after the commas
- #DUPLEX = ["", "-", "+", "split", "Auto"]
- DUPLEX = ["", "-", "+", "split"]
I like to avoid commented-out code whenever possible. Perhaps just a comment above that says "Duplex index 4 is auto mode". Will memories with auto set create an IndexError trying to look their value up in this list?
- def get_memory(self, number):
- _mem = self._memobj.memory[number-1]
- mem = chirp_common.Memory()
- mem.number = number
- mem.freq = _mem.rxfreq * 10
- mem.offset = _mem.txfreqoffset * 10
- if not _mem.tmode < len(self.TMODES):
- _mem.tmode = 0
- mem.tmode = self.TMODES[_mem.tmode]
- mem.rtone = self.TONES[_mem.tone]
- mem.mode = self.MODES[_mem.mode]
- '''
- # ars mode note yet working...
- # ARS mode:
- if _mem.ars and _mem.shift == 0:
- mem.duplex = self.DUPLEX[4]
This will fail, right?
- else:
- mem.duplex = self.DUPLEX[_mem.shift]
- '''
- mem.duplex = self.DUPLEX[_mem.shift]
- mem.power = self.POWER_LEVELS[_mem.power]
- # radio has a known bug with 5khz step and squelch
- if _mem.step == 0:
- _mem.step = 2
- mem.tuning_step = self.STEPS[_mem.step]
- mem.skip = _mem.skip and "S" or ""
- mem.name = _mem.name
- return mem
I don't see the DCS code being decoded anywhere. IIRC, that was the thing I could never figure out.
Thanks!
I'm currently working on mapping out the special channels (vfos, calls, u/l scan limits) as well as the some of the global settings. I'm not sure exactly how those special channels are dealt with, as I didnt see a sample implementation in template, just an actual implementation like ft-857, etc.
Yeah, that's unfortunately pretty ugly right now. Looking at one of the other implementations will get you there.
How can I solve the issues with importing from floats that dont match (i.e., 6.25)? do I need to bracket them into my list at get_memory or set_memory time?
What do you mean? If you don't declare that you support 6.25kHz splits then CHIRP won't ask your driver to attempt to set one.
On the ToneSql type, how do I preserve a channel setting for Bell or Auto, if chirp doesnt support it. Do I have to be destructive and box all channels into one of the supported types? It's totally possible to have set Bell or Auto in memory on the radio. What happens when I import this now? How should I deal with this, if I cant tell chirp what are possible/legal values for my radio?
Right now, we just coerce those to supported values, which ends up losing the bell setting if the user attempts to write to that memory channel. You could, I suppose, detect and preserve that bit prior to setting it if you want, but then the user would have to disable an errant bell bit on the radio itself. You could expose that in the extra settings...
I commented out the ARS code, but now if I can do custom fields (i'll see how it's done with uv-5r) then I may be able to make this a bool field, and deal with the logic of ignoring/setting duplex field in get/set memory members.
Cool.
I understand it is semantics and style, but since these allowed tone values for this particular radio will NEVER change, I don't want to be dependent upon chirp_common tones never changing.
I understand it's a bit icky, but we've done okay for five years on this model.
It would be a long shot that they ever do change, but if they do, it would be more difficult to determine which tones are now supported/unsupported, since the "source of truth" gets altered.
I understand. The reason we started with this pattern pre-dates CHIRP supporting anything but Icom radios, and a few other things. It's all in git history and the subtractive model makes it easier to eye-parse the differences.
Thanks!
So maybe you can help me clear up the setting logic. Is set_memory called for every channel at some point, or only when channels are "touched" (i.e., some control event fired in ui)?
How exactly would chirp deal with a channel imported w/ 6.25 step, if it is not in my valid_tuning_steps? Would it leave tuning_step empty?
So i fixed my tones with this: TONES = list(chirp_common.TONES) for tone in [ 165.5, 171.3, 177.3 ]: TONES.remove(tone)
But I dont see anywhere to tell chirp about this new list, such returning a RadioFeatures.valid_tones, etc in get_features. Should I be mutating chirp_commons.TONES directly?
________________________________ From: Dan Smith dsmith@danplanet.com To: chirp_devel@intrepid.danplanet.com Sent: Sunday, August 25, 2013 5:24 PM Subject: Re: [chirp_devel] [FT-90] add initial support for FT-90R. #1087
I'm currently working on mapping out the special channels (vfos, calls, u/l scan limits) as well as the some of the global settings. I'm not sure exactly how those special channels are dealt with, as I didnt see a sample implementation in template, just an actual implementation like ft-857, etc.
Yeah, that's unfortunately pretty ugly right now. Looking at one of the other implementations will get you there.
How can I solve the issues with importing from floats that dont match (i.e., 6.25)? do I need to bracket them into my list at get_memory or set_memory time?
What do you mean? If you don't declare that you support 6.25kHz splits then CHIRP won't ask your driver to attempt to set one.
On the ToneSql type, how do I preserve a channel setting for Bell or Auto, if chirp doesnt support it. Do I have to be destructive and box all channels into one of the supported types? It's totally possible to have set Bell or Auto in memory on the radio. What happens when I import this now? How should I deal with this, if I cant tell chirp what are possible/legal values for my radio?
Right now, we just coerce those to supported values, which ends up losing the bell setting if the user attempts to write to that memory channel. You could, I suppose, detect and preserve that bit prior to setting it if you want, but then the user would have to disable an errant bell bit on the radio itself. You could expose that in the extra settings...
I commented out the ARS code, but now if I can do custom fields (i'll see how it's done with uv-5r) then I may be able to make this a bool field, and deal with the logic of ignoring/setting duplex field in get/set memory members.
Cool.
I understand it is semantics and style, but since these allowed tone values for this particular radio will NEVER change, I don't want to be dependent upon chirp_common tones never changing.
I understand it's a bit icky, but we've done okay for five years on this model.
It would be a long shot that they ever do change, but if they do, it would be more difficult to determine which tones are now supported/unsupported, since the "source of truth" gets altered.
I understand. The reason we started with this pattern pre-dates CHIRP supporting anything but Icom radios, and a few other things. It's all in git history and the subtractive model makes it easier to eye-parse the differences.
Thanks!
Is set_memory called for every channel at some point, or only when channels are "touched" (i.e., some control event fired in ui)?
Only when touched.
How exactly would chirp deal with a channel imported w/ 6.25 step, if it is not in my valid_tuning_steps? Would it leave tuning_step empty?
Imported from another radio you mean? If you radio doesn't declare 6.25 step support, then it will tell the user that such a memory is unsettable or unimportable to your radio and you will never see it.
But I dont see anywhere to tell chirp about this new list, such returning a RadioFeatures.valid_tones, etc in get_features.
Right, we don't currently export a list of supported tones, so you need to maintain your list for indexing purposes and fail in some reasonable way if a memory is attempted with a tone you don't support. This is probably something we need to improve going forward.
Should I be mutating chirp_commons.TONES directly?
No, definitely not. That will cause it to change for other drivers in the same session.
Thanks Dan. Corrected patch attached.
________________________________ From: Dan Smith dsmith@danplanet.com To: chirp_devel@intrepid.danplanet.com Sent: Monday, August 26, 2013 8:50 AM Subject: Re: [chirp_devel] [FT-90] add initial support for FT-90R. #1087
Is set_memory called for every channel at some point, or only when channels are "touched" (i.e., some control event fired in ui)?
Only when touched.
How exactly would chirp deal with a channel imported w/ 6.25 step, if it is not in my valid_tuning_steps? Would it leave tuning_step empty?
Imported from another radio you mean? If you radio doesn't declare 6.25 step support, then it will tell the user that such a memory is unsettable or unimportable to your radio and you will never see it.
But I dont see anywhere to tell chirp about this new list, such returning a RadioFeatures.valid_tones, etc in get_features.
Right, we don't currently export a list of supported tones, so you need to maintain your list for indexing purposes and fail in some reasonable way if a memory is attempted with a tone you don't support. This is probably something we need to improve going forward.
Should I be mutating chirp_commons.TONES directly?
No, definitely not. That will cause it to change for other drivers in the same session.
- STEPS = [5, 10, 12.5, 15, 20, 25, 50]
While I understand this works, it's not what the other drivers do. Please make these floats:
STEPS = [5.0, 10.0, ...]
Just for consistency, if you don't mind.
- MODES = ["AM", "FM", "Auto"]
- TMODES = ["", "Tone", "TSQL", "", "DTCS"] # idx 3 (Bell) not ...
- TONES = list(chirp_common.TONES)
- for tone in [ 165.5, 171.3, 177.3 ]:
TONES.remove(tone)
- POWER_LEVELS = ["Hi", "Mid1", "Mid2", "Low"]
- DUPLEX = ["", "-", "+", "split"]
- mem_format = """
Sorry, I didn't notice this before, but I would really prefer that these be module-level and not public class-level variables. Is there some reason you moved these into the class, contrary to the pattern used everywhere else? Class variables with mutable types are pretty dangerous in Python...
I'm not trying to be overly pedantic here, just trying to keep consistency with everything else. You're *really* close; thanks for your work and patience on this :)
Ok, thanks for pointers on type consistency in the steps list. (I missed your point from an earlier email.) No good reason other than than being new to python development ;)
I would point out in the spirit of constructive criticism, that a. there is some inconsistency in this and other regards amongst various modules, and b. there is a lack clear developer documentation on style (such as "please follow PEP8 when reasonable") guidelines, and project-level conventions, etc. I do understand the need for consistency, and that this is a community project, so that's why I would suggest some and even be willing to help with this on the twiki (although my available time is about to plummet due to school semester starting). With all of that aside, changes made - please review latest version of the patch. :) Jens
________________________________ From: Dan Smith dsmith@danplanet.com To: chirp_devel@intrepid.danplanet.com Sent: Monday, August 26, 2013 9:34 AM Subject: Re: [chirp_devel] [FT-90] add initial support for FT-90R. #1087
+ STEPS = [5, 10, 12.5, 15, 20, 25, 50]
While I understand this works, it's not what the other drivers do. Please make these floats:
STEPS = [5.0, 10.0, ...]
Just for consistency, if you don't mind.
+ MODES = ["AM", "FM", "Auto"] + TMODES = ["", "Tone", "TSQL", "", "DTCS"] # idx 3 (Bell) not ... + TONES = list(chirp_common.TONES) + for tone in [ 165.5, 171.3, 177.3 ]: + TONES.remove(tone) + POWER_LEVELS = ["Hi", "Mid1", "Mid2", "Low"] + DUPLEX = ["", "-", "+", "split"] + mem_format = """
Sorry, I didn't notice this before, but I would really prefer that these be module-level and not public class-level variables. Is there some reason you moved these into the class, contrary to the pattern used everywhere else? Class variables with mutable types are pretty dangerous in Python...
I'm not trying to be overly pedantic here, just trying to keep consistency with everything else. You're *really* close; thanks for your work and patience on this :)
participants (2)
-
Dan Smith
-
Jens J.