[chirp_devel] [PATCH 1 of 5] [ft4] whitespace cleanup [#4787]
# HG changeset patch # User DanClemmensen DanClemmensen@gmail.com # Date 1551138396 28800 # Mon Feb 25 15:46:36 2019 -0800 # Node ID 6e6bbf78e059ff0fdfa1de7fcf0f9af09b7c49c5 # Parent 2513b6da29c39aa92e8df3c7468949d479e8a984 [ft4] whitespace cleanup [#4787] first of several patches. the next patches fix tone support, improve FT-65 support, fix a py3 upload failure, and improve version matching.
diff -r 2513b6da29c3 -r 6e6bbf78e059 chirp/drivers/ft4.py --- a/chirp/drivers/ft4.py Thu Feb 21 13:47:30 2019 -0800 +++ b/chirp/drivers/ft4.py Mon Feb 25 15:46:36 2019 -0800 @@ -23,11 +23,9 @@ """ import logging import struct -from chirp import chirp_common, directory, memmap, bitwise, errors, util +from chirp import chirp_common, directory, memmap, bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ - RadioSettingValueList, \ - RadioSettingValueString, \ - RadioSettings + RadioSettingValueList, RadioSettingValueString, RadioSettings
LOG = logging.getLogger(__name__)
@@ -39,7 +37,7 @@ # each with a different purpose and format. Five groups consist of slots. # A slot describes a radio channel, and all slots have the same internal # format. Three of the groups consist of bitmaps, which all have the same -# internal mapping. Name group, misc group, and DTMF digit group, +# internal mapping. also groups for Name, misc, DTMF digits, and prog, # plus some unused groups.
# Define the structures for each type of group here, but do not associate them @@ -75,8 +73,9 @@ bbcd freq[4]; };
-//miscellaneous params. One 4-block group. (could be treated as 4 separate.) +//miscellaneous params. One 4-block group. //"SMI": "Set Mode Index" of the radio keypad function used to set a parameter. +//"SMI numbers on the FT-65 are different but the names in mem are the same. struct misc { u8 apo; //SMI 01. 0==off, (1-24) is the number of half-hours. u8 arts_beep; //SMI 02. 0==off, 1==inrange, 2==always @@ -103,7 +102,7 @@ u8 scan_lamp; //SMI 33 0==off,1==on u8 unknown2; u8 use_cwid; //SMI 7. 0==no, 1==yes - u8 unused1; // possibly compander on FT_65 + u8 compander; // compander on FT_65 // addr 2020 u8 unknown3; u8 tx_save; //SMI 41. 0==off, 1==on (addr==2021) @@ -126,12 +125,13 @@ };
struct dtmfset { - u8 digit[16]; //ASCII (*,#,0-9,A-D). (null terminated??) + u8 digit[16]; //ASCII (*,#,-,0-9,A-D). (dash-filled) };
//one block with stuff for the programmable keys +//supports 4 keys. FT-4 has only 2 keys. FT-65 has all 4. struct progs { - u8 modes[8]; //should be array of 2-byte structs, but bitwise.py objects + u8 modes[8]; //should be array of 2-byte structs, but bitwise.py refuses u8 ndx[4]; u8 unused[8]; }; @@ -234,7 +234,7 @@
def getblock(pipe, addr, _mmap): """ - read a single 16-byte block from the radio + read a single 16-byte block from the radio. send the command and check the response returns the 16-byte bytearray """ @@ -403,10 +403,6 @@ STEPS = [0, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] TONE_MODES = ["", "Tone", "TSQL", "DTCS", "DTCS-R", "TSQL-R", "Cross"] CROSS_MODES = ["DTCS->", "DTCS->DTCS"] # only the extras we need -# The radio and the code support the additional cross modes, but -# they are redundant with the extended tone modes, and they cause -# the "BruteForce" unit test to fail. -# CROSS_MODES += ["Tone->Tone", "->DTCS", "->Tone", "DTCS->DTCS", "Tone->"]
DTMF_CHARS = "0123456789ABCD*#- " CW_ID_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " @@ -484,7 +480,7 @@ def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ( - 'Tested only by the developer and only on a single radio.' + 'Tested only by the developer and only on a single radio.\n' ' Proceed at your own risk!' )
@@ -548,8 +544,10 @@ def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
- # functions to handle complicated settings. - # callback for settng byte arrays (DTMF[0-9], passwd, and CW_ID) + # There are about 40 settings and most are handled generically below. + # The few that are more complicated use these handlers instead. + + # callback for setting byte arrays (DTMF[0-9], passwd, and CW_ID) def apply_str_to_bytearray(self, element, obj): lng = len(obj) strng = (element.value.get_value() + " ")[:lng] @@ -558,7 +556,7 @@ obj[x] = bytes[x] return
- def get_string_setting(self, obj, valid_chars, desc1, desc2, group): + def get_string_setting(self, obj, valid_chars, desc1, desc2, group): content = '' maxlen = len(obj) for x in range(0, maxlen): @@ -568,8 +566,8 @@ rs.set_apply_callback(self.apply_str_to_bytearray, obj) group.append(rs)
- def get_strset(self, group, parm): - # parm =(paramname, paramtitle,( handler,[handler params])). + def get_strset(self, group, parm): + # parm =(paramname, paramtitle,(handler,[handler params])). objname, title, fparms = parm myparms = fparms[1] obj = getattr(self._memobj.settings, objname) @@ -585,36 +583,34 @@ "dtmf_%i" % i, "DTMF Autodialer Memory %i" % i, group)
def apply_P(self, element, pnum): - value = element.value - self.memobj.progkeys.modes[pnum * 2] = [0, 2][value] + self.memobj.progkeys.modes[pnum * 2] = [0, 2][element.value]
def apply_Pmode(self, element, pnum): - value = element.value - self.memobj.progkeys.modes[pnum * 2 + 1] = value + self.memobj.progkeys.modes[pnum * 2 + 1] = element.value
def apply_Pmem(self, element, pnum): - value = element.value - self.memobj.progkeys.ndx[pnum].func = value + self.memobj.progkeys.ndx[pnum] = element.value
MEMLIST = ["%d" % i for i in range(1, MAX_MEM_SLOT)] + PMSNAMES
- # return the setting for the programmable keys (P1 or P2) + # return the setting for the programmable keys (P1-P4) def get_progs(self, group, parm): _progkeys = self._memobj.progkeys
- def get_prog(i, val_list, valndx, sname, longname, apply): + def get_prog(i, val_list, valndx, sname, longname, apply): val = val_list[valndx] valuelist = RadioSettingValueList(val_list, val) - rs = RadioSetting(sname + str(i), longname + str(i), valuelist) + rs = RadioSetting(sname + str(i), longname + str(i), valuelist) rs.set_apply_callback(apply, i) group.append(rs) for i in range(0, self.Pkeys): - get_prog(i + 1, ["unused", "in use"], _progkeys.modes[i * 2], + get_prog(i + 1, ["unused", "in use"], _progkeys.modes[i * 2], "P", "Programmable key ", self.apply_P) get_prog(i + 1, SETMODES, _progkeys.modes[i * 2 + 1], "modeP", "mode for Programmable key", self.apply_Pmode) get_prog(i + 1, self.MEMLIST, _progkeys.ndx[i], "memP", "mem for Programmable key", self.apply_Pmem) + # ------------ End of special settings handlers.
# list of group description tuples: (groupame,group title, [param list]). # A param is a tuple: @@ -680,10 +676,10 @@ ] # ----------------end of group_descriptions
- # returns the current values of all the settings in the radio memory image, - # in the form of a RadioSettings list. First, use the group_descriptions - # list to create the groups and most of the params. Then, add params that - # require extra stuff. + # list of group description tuples: (groupame,group title, [param list]). + # A param is a tuple: + # for a simple param: (paramname, paramtitle,[valuename list]) + # for a handler param: (paramname, paramtitle,( handler,[handler params])) def get_settings(self): _settings = self._memobj.settings groups = RadioSettings() @@ -815,7 +811,7 @@
def encode_sql(self, mem, chan): """ - examine CHIRP CSV columns tmode, cross_mode, and dcts_polarity + examine CHIRP CSV columns tmode and cross_mode and set the correct values for the radio sql_type, dcs codes, and ctcss codes. We set all four codes, and then zero out a code if needed when Tone or DCS is one-way
# HG changeset patch # User DanClemmensen DanClemmensen@gmail.com # Date 1551143488 28800 # Mon Feb 25 17:11:28 2019 -0800 # Node ID d34d952552de214669f517c3aa0a1a0474236dcf # Parent 6e6bbf78e059ff0fdfa1de7fcf0f9af09b7c49c5 [ft4] improve serial i/o [#4787] improved version ID checking code (more general, and uses a radio type-specific id). Also, a bug that prevented upload on the py3 branch is fixed
diff -r 6e6bbf78e059 -r d34d952552de chirp/drivers/ft4.py --- a/chirp/drivers/ft4.py Mon Feb 25 15:46:36 2019 -0800 +++ b/chirp/drivers/ft4.py Mon Feb 25 17:11:28 2019 -0800 @@ -74,7 +74,7 @@ };
//miscellaneous params. One 4-block group. -//"SMI": "Set Mode Index" of the radio keypad function used to set a parameter. +//"SMI": "Set Mode Index" of the FT-4 radio keypad function to set parameter. //"SMI numbers on the FT-65 are different but the names in mem are the same. struct misc { u8 apo; //SMI 01. 0==off, (1-24) is the number of half-hours. @@ -193,6 +193,21 @@ # constructs could be better optimized for one or the other, but not both.
+def get_mmap_data(radio): + """ + horrible kludge needed until we convert entirely to Python 3 OR we add a + slightly less horrible kludge to the Py2 or Py3 versions of memmap.py. + The minimal change have Py3 code return a bytestring instead of a string. + This is the only function in this module that must explicitly test for the + data string type. It is used only in the do_upload function. + returns the memobj data as a byte-like object. + """ + data = radio.get_mmap().get_packed() + if isinstance(data, bytes): + return data + return bytearray(radio.get_mmap()._data) + + def checkSum8(data): """ Calculate the 8 bit checksum of buffer @@ -202,13 +217,34 @@ return sum(x for x in bytearray(data)) & 0xFF
+def variable_len_resp(pipe): + """ + when length of expected reply is not known, read byte at a time + until the ack character is found. + """ + response = b"" + i = 0 + toolong = 256 # arbitrary + while True: + b = pipe.read(1) + if b == b'\x06': + break + else: + response += b + i += 1 + if i > toolong: + LOG.debug("Response too long. got" + util.hexprint(response)) + raise errors.RadioError("Response too long.") + return(response) + + def sendcmd(pipe, cmd, response_len): """ send a command bytelist to radio,receive and return the resulting bytelist. Input: pipe - serial port object to use cmd - bytes to send response_len - number of bytes of expected response, - not including the ACK. + not including the ACK. (if None, read until ack) This cable is "two-wire": The TxD and RxD are "or'ed" so we receive whatever we send and then whatever response the radio sends. We check the echo and strip it, returning only the radio's response. @@ -221,6 +257,8 @@ msg += "Received:" + util.hexprint(echo) LOG.debug(msg) raise errors.RadioError("Incorrect echo on serial port.") + if response_len is None: + return variable_len_resp(pipe) if response_len > 0: response = pipe.read(response_len) else: @@ -232,11 +270,35 @@ return response
-def getblock(pipe, addr, _mmap): +def startcomms(radio): + """ + For either upload or download, put the radio into PROGRAM mode + and check the radio's id. In this preliminary version of the driver, + the exact nature of the ID has been inferred from a single test case. + send "PROGRAM" to command the radio into clone mode + read the initial string (version?) + """ + if b"QX" != sendcmd(radio.pipe, b"PROGRAM", 2): + raise errors.RadioError("expected QX from radio.") + id_response = sendcmd(radio.pipe, b'\x02', None) + if id_response != radio.id_str: + substr0=radio.id_str[:radio.id_str.find('\x00')] + if id_response[:id_response.find('\x00')] != substr0: + msg = "ID mismatch. Expected" + util.hexprint(radio.id_str) + msg += ", Received:" + util.hexprint(id_response) + LOG.warning(msg) + raise errors.RadioError("Incorrect ID.") + else: + msg = "ID suspect. Expected" + util.hexprint(radio.id_str) + msg += ", Received:" + util.hexprint(id_response) + LOG.warning(msg) + + +def getblock(pipe, addr, image): """ read a single 16-byte block from the radio. send the command and check the response - returns the 16-byte bytearray + places the response into the correct offset in the supplied bytearray """ cmd = struct.pack(">cHb", b"R", addr, 16) response = sendcmd(pipe, cmd, 21) @@ -248,41 +310,24 @@ if checkSum8(response[1:20]) != bytearray(response)[20]: LOG.debug(b"Bad checksum: " + util.hexprint(response)) raise errors.RadioError("bad block checksum.") - _mmap[addr:addr+16] = response[4:20] - - -expected_id = b'IFT-35R\x00\x00V100\x00\x00' + image[addr:addr+16] = response[4:20]
def do_download(radio): """ Read memory from the radio. - send "PROGRAM" to command the radio into clone mode, - read the initial string (version?) + call startcomms to go into program mode and check version create an mmap read the memory blocks and place the data into the mmap send "END" """ - _mmap = bytearray(radio.get_memsize()) + image = bytearray(radio.get_memsize()) pipe = radio.pipe # Get the serial port connection - - if b"QX" != sendcmd(pipe, b"PROGRAM", 2): - raise errors.RadioError("expected QX from radio.") - id_response = sendcmd(pipe, b'\x02', 15) - if id_response != expected_id: - if id_response[0:8] != expected_id[0:8]: - msg = "ID mismatch. Expected" + util.hexprint(expected_id) - msg += ", Received:" + util.hexprint(id_response) - LOG.debug(msg) - raise errors.RadioError("Incorrect ID.") - else: - msg = "ID suspect. Expected" + util.hexprint(expected_id) - msg += ", Received:" + util.hexprint(id_response) - LOG.debug(msg) + startcomms(radio) for _i in range(radio.numblocks): - getblock(pipe, 16 * _i, _mmap) + getblock(pipe, 16 * _i, image) sendcmd(pipe, b"END", 0) - return memmap.MemoryMap(bytes(_mmap)) + return memmap.MemoryMap(bytes(image))
def putblock(pipe, addr, data): @@ -298,16 +343,13 @@ def do_upload(radio): """ Write memory image to radio - send "PROGRAM" to command the radio into clone mode, + call startcomms to go into program mode and check version write the memory blocks. Skip the first block send "END" """ pipe = radio.pipe # Get the serial port connection - - if b"QX" != sendcmd(pipe, b"PROGRAM", 2): - raise errors.RadioError("expected QX from radio.") - data = radio.get_mmap() - sendcmd(pipe, b'\x02', 15) + startcomms(radio) + data = get_mmap_data(radio) for _i in range(1, radio.numblocks): putblock(pipe, 16*_i, data[16*_i:16*(_i+1)]) sendcmd(pipe, b"END", 0) @@ -907,7 +949,7 @@ self.decode_sql(mem, _mem) mem.power = POWER_LEVELS[_mem.tx_pwr] mem.mode = ["FM", "NFM"][_mem.tx_width] - mem.tuning_step = STEPS[_mem.step] + mem.tuning_step = STEP_CODE[_mem.step]
if regtype == "pms": mem.extd_number = sname @@ -941,7 +983,7 @@ if mem.power: _mem.tx_pwr = POWER_LEVELS.index(mem.power) _mem.tx_width = mem.mode == "NFM" - _mem.step = STEPS.index(mem.tuning_step) + _mem.step = STEP_CODE.index(mem.tuning_step)
_mem.offset = mem.offset / 25000 duplex = mem.duplex @@ -980,6 +1022,7 @@ MAX_MEM_SLOT = 200 Pkeys = 2 # number of programmable keys on the FT-4 namelen = 6 # length of the mem name display on the FT-4 front-panel + id_str = b'IFT-35R\x00\x00V100\x00\x00'
# don't register the FT-65 in the production version until it is tested @@ -1002,3 +1045,5 @@ MAX_MEM_SLOT = 200 Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front panel + id_str=b'IH-420\x00\x00\x00V100\x00\x00' +
+def variable_len_resp(pipe):
- """
- when length of expected reply is not known, read byte at a time
- until the ack character is found.
- """
- response = b""
- i = 0
- toolong = 256 # arbitrary
- while True:
b = pipe.read(1)
if b == b'\x06':
break
else:
response += b
i += 1
if i > toolong:
LOG.debug("Response too long. got" + util.hexprint(response))
raise errors.RadioError("Response too long.")
Did you have a response to my comments in this part of the first patch?
--Dan
I missed it in this patch, so I stuck it in the last patch when I reviewed your e-mail one last time. I am just now beginning to understand the mq patch "stack" concept, so I now realize that I should have popped the later patches, made this fix in the early patch, and then pushed the later patches back on the stack. I had not figured that out.
On Thu, Feb 28, 2019 at 6:48 AM Dan Smith via chirp_devel < chirp_devel@intrepid.danplanet.com> wrote:
+def variable_len_resp(pipe):
- """
- when length of expected reply is not known, read byte at a time
- until the ack character is found.
- """
- response = b""
- i = 0
- toolong = 256 # arbitrary
- while True:
b = pipe.read(1)
if b == b'\x06':
break
else:
response += b
i += 1
if i > toolong:
LOG.debug("Response too long. got" +
util.hexprint(response))
raise errors.RadioError("Response too long.")
Did you have a response to my comments in this part of the first patch?
--Dan _______________________________________________ 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
# HG changeset patch # User DanClemmensen DanClemmensen@gmail.com # Date 1551145350 28800 # Mon Feb 25 17:42:30 2019 -0800 # Node ID b5d1b0e834e6e5fe6ed9b592d68979738fbea404 # Parent d34d952552de214669f517c3aa0a1a0474236dcf [ft4] compander, 6.25 suppress, freq range fix [#4787] a few fixups that dont fall into other categories. the US fersons (FT-4XR and FT65R) don't allow the 6.25 KHz frequency step. The FT-65 has a feature the FT-4 lacks (compander). The code had a leftover "valid_frequencies statement.
diff -r d34d952552de -r b5d1b0e834e6 chirp/drivers/ft4.py --- a/chirp/drivers/ft4.py Mon Feb 25 17:11:28 2019 -0800 +++ b/chirp/drivers/ft4.py Mon Feb 25 17:42:30 2019 -0800 @@ -442,7 +442,11 @@ POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.0), chirp_common.PowerLevel("Mid", watts=2.5), chirp_common.PowerLevel("Low", watts=0.5)] -STEPS = [0, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] + +# these steps encode to 0-9 on all radios, but encoding #2 is disallowed +# on the US versions (FT-4XR) +STEP_CODE = [0, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] + TONE_MODES = ["", "Tone", "TSQL", "DTCS", "DTCS-R", "TSQL-R", "Cross"] CROSS_MODES = ["DTCS->", "DTCS->DTCS"] # only the extras we need
@@ -489,21 +493,6 @@ ] EPCS_CODES = [format(flt) for flt in [0] + TONE_MAP[1:]]
-# names for the setmode function for the programmable keys. Mode zero means -# that the key is programmed for a memory not a setmode. -SETMODES = [ - "mem", "apo", "ar bep", "ar int", "beclo", - "beep", "bell", "cw id", "cw wrt", "de vlt", - "dcs cod", "dtc dly", "dtc_set", "dtc spd", "edg bep", - "lamp", "ledbsy", "led tx", "lock", "m/t-cl", - "mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", - "pri rvt", "pswd.on", "pswdwt", "rf sql", "rpt ars", - "rpt frq", "rpt sft", "rxsave", "scan.lamp", "scan.rs", - "skip", "sql.typ", "step", "tn freq", "tot", - "tx pwr", "tx save", "vfo spl", "vox", "wfm.rcv", - "wx.alert" - ] -
class YaesuSC35GenericRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): @@ -523,7 +512,7 @@ rp = chirp_common.RadioPrompts() rp.experimental = ( 'Tested only by the developer and only on a single radio.\n' - ' Proceed at your own risk!' + 'Proceed at your own risk!' )
rp.pre_download = "".join([ @@ -548,7 +537,7 @@ rf.valid_tmodes = TONE_MODES rf.valid_cross_modes = CROSS_MODES rf.valid_power_levels = POWER_LEVELS - rf.valid_tuning_steps = STEPS + rf.valid_tuning_steps = self.legal_steps rf.valid_skips = SKIPS rf.valid_characters = CHARSET rf.valid_name_length = self.namelen @@ -578,8 +567,6 @@ def sync_out(self): try: do_upload(self) - except errors.RadioError: - raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e)
@@ -590,7 +577,7 @@ # The few that are more complicated use these handlers instead.
# callback for setting byte arrays (DTMF[0-9], passwd, and CW_ID) - def apply_str_to_bytearray(self, element, obj): + def apply_str_to_bytearray(self, element, obj): lng = len(obj) strng = (element.value.get_value() + " ")[:lng] bytes = bytearray(strng, "ascii") @@ -646,12 +633,13 @@ rs.set_apply_callback(apply, i) group.append(rs) for i in range(0, self.Pkeys): - get_prog(i + 1, ["unused", "in use"], _progkeys.modes[i * 2], + i1 = i + 1 + get_prog(i1, ["unused", "in use"], _progkeys.modes[i * 2], "P", "Programmable key ", self.apply_P) - get_prog(i + 1, SETMODES, _progkeys.modes[i * 2 + 1], "modeP", - "mode for Programmable key", self.apply_Pmode) - get_prog(i + 1, self.MEMLIST, _progkeys.ndx[i], "memP", - "mem for Programmable key", self.apply_Pmem) + get_prog(i1, self.SETMODES, _progkeys.modes[i * 2 + 1], "modeP", + "mode for Programmable key ", self.apply_Pmode) + get_prog(i1, self.MEMLIST, _progkeys.ndx[i], "memP", + "mem for Programmable key ", self.apply_Pmem) # ------------ End of special settings handlers.
# list of group description tuples: (groupame,group title, [param list]). @@ -718,10 +706,18 @@ ] # ----------------end of group_descriptions
- # list of group description tuples: (groupame,group title, [param list]). - # A param is a tuple: - # for a simple param: (paramname, paramtitle,[valuename list]) - # for a handler param: (paramname, paramtitle,( handler,[handler params])) + # allow a child class to add a param. + def add_paramdesc(self,group, param): + for description in self.group_descriptions: + groupname, title, parms = description + if group == groupname: + description[2] += param + return + + # returns the current values of all the settings in the radio memory image, + # in the form of a RadioSettings list. Uses the group_descriptions + # list to create the groups and params. Simple valuelist params are handled + # inline. More complex params are built by calling the special handlers. def get_settings(self): _settings = self._memobj.settings groups = RadioSettings() @@ -1015,7 +1011,6 @@ # VHF, RX (136000000, 174000000) # UHF, RX (400000000, 480000000) ] - valid_bands = [(108000000, 520000000), (700000000, 999990000)] _valid_chars = chirp_common.CHARSET_ASCII numblocks = 0x215 # number of 16-byte blocks in the radio _memsize = 16 * numblocks # used by CHIRP file loader to guess radio type @@ -1023,7 +1018,22 @@ Pkeys = 2 # number of programmable keys on the FT-4 namelen = 6 # length of the mem name display on the FT-4 front-panel id_str = b'IFT-35R\x00\x00V100\x00\x00' - + # names for the setmode function for the programmable keys. Mode zero means + # that the key is programmed for a memory not a setmode. + SETMODES = [ + "mem", "apo", "ar bep", "ar int", "beclo", #00-04 + "beep", "bell", "cw id", "cw wrt", "dc vlt", #05-09 + "dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", #10-14 + "lamp", "led.bsy", "led.tx", "lock", "m/t-cl", #15-19 + "mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", #20-24 + "pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", #25-29 + "rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", #30-34 + "skip", "sql.typ", "step", "tn frq", "tot", #35-39 + "tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44 + "w/n.dev", "wx.alert" #45-46 + ] + legal_steps = list(STEP_CODE) + legal_steps.remove(6.25) #should not remove if euro version
# don't register the FT-65 in the production version until it is tested # @directory.register @@ -1038,7 +1048,6 @@ # VHF, RX (136000000, 174000000) # UHF, RX (400000000, 480000000) ] - valid_bands = [(108000000, 520000000), (700000000, 999990000)] _valid_chars = chirp_common.CHARSET_ASCII numblocks = 0x215 # number of 16-byte blocks in the radio _memsize = 16 * numblocks # used by CHIRP file loader to guess radio type @@ -1046,4 +1055,20 @@ Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front panel id_str=b'IH-420\x00\x00\x00V100\x00\x00' + # names for the setmode function for the programmable keys. Mode zero means + # that the key is programmed for a memory not a setmode. + SETMODES = [ + "mem", "apo", "arts", "battsave", "b-ch.l/o", # 00-04 + "beep", "bell", "compander", "ctcss", "cw id", # 05-09 + "dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", # 10-14 + "key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", # 15-19 + "name tag", "pager", "password", "pri.rvt", "repeater", # 20-24 + "resume", "rf.sql", "scn.lamp", "skip", "sql type", # 25-29 + "step", "tot", "tx pwr", "tx save", "vfo.spl", # 30-34 + "vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" # 35-39 + ] + legal_steps = list(STEP_CODE) + legal_steps.remove(6.25) #should not remove if euro version + def __init__(self): + self.add_paramdesc("misc", ("compander", "Compander", ["ON", "OFF"]))
@@ -1023,7 +1018,22 @@ Pkeys = 2 # number of programmable keys on the FT-4 namelen = 6 # length of the mem name display on the FT-4 front-panel id_str = b'IFT-35R\x00\x00V100\x00\x00'
- # names for the setmode function for the programmable keys. Mode zero means
- # that the key is programmed for a memory not a setmode.
- SETMODES = [
"mem", "apo", "ar bep", "ar int", "beclo", #00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", #05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", #10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", #15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", #20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", #25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", #30-34
"skip", "sql.typ", "step", "tn frq", "tot", #35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44
"w/n.dev", "wx.alert" #45-46
]
- legal_steps = list(STEP_CODE)
- legal_steps.remove(6.25) #should not remove if euro version
# don't register the FT-65 in the production version until it is tested # @directory.register @@ -1038,7 +1048,6 @@ # VHF, RX (136000000, 174000000) # UHF, RX (400000000, 480000000) ]
- valid_bands = [(108000000, 520000000), (700000000, 999990000)] _valid_chars = chirp_common.CHARSET_ASCII numblocks = 0x215 # number of 16-byte blocks in the radio _memsize = 16 * numblocks # used by CHIRP file loader to guess radio type
@@ -1046,4 +1055,20 @@ Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front panel id_str=b'IH-420\x00\x00\x00V100\x00\x00'
- # names for the setmode function for the programmable keys. Mode zero means
- # that the key is programmed for a memory not a setmode.
- SETMODES = [
"mem", "apo", "arts", "battsave", "b-ch.l/o", # 00-04
"beep", "bell", "compander", "ctcss", "cw id", # 05-09
"dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", # 10-14
"key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", # 15-19
"name tag", "pager", "password", "pri.rvt", "repeater", # 20-24
"resume", "rf.sql", "scn.lamp", "skip", "sql type", # 25-29
"step", "tot", "tx pwr", "tx save", "vfo.spl", # 30-34
"vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" # 35-39
]
This list is the same as the one above, right? Can we define that in one place and use it in both?
--Dan
There are only the two lists so far and there may never be another, so I suppose we could. However, it's not the same for all radio variants. I wanted to make this explicit, so I built the "legal" list on a radio-by-radio basis to make it clear that each new variant will need to decide on its own list. the It's a stylistic choice, but I thought the "remove" construct was better as a self-documenting way to make it clear that the legal list must be a subset of the coded list.
On Thu, Feb 28, 2019 at 6:52 AM Dan Smith via chirp_devel < chirp_devel@intrepid.danplanet.com> wrote:
@@ -1023,7 +1018,22 @@ Pkeys = 2 # number of programmable keys on the FT-4 namelen = 6 # length of the mem name display on the FT-4
front-panel
id_str = b'IFT-35R\x00\x00V100\x00\x00'
- # names for the setmode function for the programmable keys. Mode
zero means
- # that the key is programmed for a memory not a setmode.
- SETMODES = [
"mem", "apo", "ar bep", "ar int", "beclo", #00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", #05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", #10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", #15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", #20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", #25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", #30-34
"skip", "sql.typ", "step", "tn frq", "tot", #35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44
"w/n.dev", "wx.alert" #45-46
]
- legal_steps = list(STEP_CODE)
- legal_steps.remove(6.25) #should not remove if euro version
# don't register the FT-65 in the production version until it is tested # @directory.register @@ -1038,7 +1048,6 @@ # VHF, RX (136000000, 174000000) # UHF, RX (400000000, 480000000) ]
- valid_bands = [(108000000, 520000000), (700000000, 999990000)] _valid_chars = chirp_common.CHARSET_ASCII numblocks = 0x215 # number of 16-byte blocks in the radio _memsize = 16 * numblocks # used by CHIRP file loader to guess
radio type
@@ -1046,4 +1055,20 @@ Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front
panel
id_str=b'IH-420\x00\x00\x00V100\x00\x00'
- # names for the setmode function for the programmable keys. Mode
zero means
- # that the key is programmed for a memory not a setmode.
- SETMODES = [
"mem", "apo", "arts", "battsave", "b-ch.l/o", #
00-04
"beep", "bell", "compander", "ctcss", "cw id", #
05-09
"dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", #
10-14
"key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", #
15-19
"name tag", "pager", "password", "pri.rvt", "repeater", #
20-24
"resume", "rf.sql", "scn.lamp", "skip", "sql type", #
25-29
"step", "tot", "tx pwr", "tx save", "vfo.spl", #
30-34
"vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" #
35-39
]
This list is the same as the one above, right? Can we define that in one place and use it in both?
--Dan
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
# HG changeset patch # User DanClemmensen DanClemmensen@gmail.com # Date 1551145390 28800 # Mon Feb 25 17:43:10 2019 -0800 # Node ID 607b8b18a90e46231a2818304107f3f8d8a7173a # Parent b5d1b0e834e6e5fe6ed9b592d68979738fbea404 [ft4] programmable keys names for the FT-65 [#4787] the namelist for the FT-65 programmable keys differes for the one for the FT-4
diff -r b5d1b0e834e6 -r 607b8b18a90e chirp/drivers/ft4.py --- a/chirp/drivers/ft4.py Mon Feb 25 17:42:30 2019 -0800 +++ b/chirp/drivers/ft4.py Mon Feb 25 17:43:10 2019 -0800 @@ -1003,7 +1003,6 @@ class YaesuFT4Radio(YaesuSC35GenericRadio): MODEL = "FT-4XR" _basetype = BASETYPE_FT4 -# _idents = [FT4_MODEL_FT4XR, FT4XE] fixme:ignore validation check for now valid_bands = [ (65000000, 108000000), # broadcast FM, receive only (144000000, 148000000), # VHF, US version, TX and RX @@ -1018,6 +1017,8 @@ Pkeys = 2 # number of programmable keys on the FT-4 namelen = 6 # length of the mem name display on the FT-4 front-panel id_str = b'IFT-35R\x00\x00V100\x00\x00' + legal_steps = list(STEP_CODE) + legal_steps.remove(6.25) #should not remove if euro version # names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [ @@ -1032,15 +1033,12 @@ "tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44 "w/n.dev", "wx.alert" #45-46 ] - legal_steps = list(STEP_CODE) - legal_steps.remove(6.25) #should not remove if euro version
# don't register the FT-65 in the production version until it is tested # @directory.register class YaesuFT65Radio(YaesuSC35GenericRadio): MODEL = "FT-65R" _basetype = BASETYPE_FT65 -# _idents = [] fixme:ignore validation check for now valid_bands = [ (65000000, 108000000), # broadcast FM, receive only (144000000, 148000000), # VHF, US version, TX and RX @@ -1055,6 +1053,8 @@ Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front panel id_str=b'IH-420\x00\x00\x00V100\x00\x00' + legal_steps = list(STEP_CODE) + legal_steps.remove(6.25) #should not remove if euro version # names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [ @@ -1067,8 +1067,6 @@ "step", "tot", "tx pwr", "tx save", "vfo.spl", # 30-34 "vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" # 35-39 ] - legal_steps = list(STEP_CODE) - legal_steps.remove(6.25) #should not remove if euro version def __init__(self): self.add_paramdesc("misc", ("compander", "Compander", ["ON", "OFF"]))
# HG changeset patch # User DanClemmensen DanClemmensen@gmail.com # Date 1551210139 28800 # Tue Feb 26 11:42:19 2019 -0800 # Node ID b0ed770692e8e00ea9d3cec5bf9cf58c3f7367da # Parent 607b8b18a90e46231a2818304107f3f8d8a7173a [ft4] rework tones [#4787] cleanup last tone bugs and slightly refactor to remove redundant lists. There is some minor cosmetic stuff also
diff -r 607b8b18a90e -r b0ed770692e8 chirp/drivers/ft4.py --- a/chirp/drivers/ft4.py Mon Feb 25 17:43:10 2019 -0800 +++ b/chirp/drivers/ft4.py Tue Feb 26 11:42:19 2019 -0800 @@ -192,7 +192,6 @@ # the serial port. The code runs on either Python 2 or Python3, so some # constructs could be better optimized for one or the other, but not both.
- def get_mmap_data(radio): """ horrible kludge needed until we convert entirely to Python 3 OR we add a @@ -217,7 +216,7 @@ return sum(x for x in bytearray(data)) & 0xFF
-def variable_len_resp(pipe): +def variable_len_resp(pipe, cmd): """ when length of expected reply is not known, read byte at a time until the ack character is found. @@ -233,8 +232,11 @@ response += b i += 1 if i > toolong: - LOG.debug("Response too long. got" + util.hexprint(response)) - raise errors.RadioError("Response too long.") + msg = "received too many bytes from radio before ACK. " + msg += "Sent " + util.hexprint(cmd) + msg += ". Got " + util.hexprint(response) + LOG.debug(msg) + raise errors.RadioError(msg) return(response)
@@ -253,19 +255,19 @@ pipe.write(cmd) echo = pipe.read(len(cmd)) if echo != cmd: - msg = "Bad echo. Sent:" + util.hexprint(cmd) + ", " + msg = "Bad echo on serial port. Sent:" + util.hexprint(cmd) + ", " msg += "Received:" + util.hexprint(echo) LOG.debug(msg) - raise errors.RadioError("Incorrect echo on serial port.") + raise errors.RadioError(msg) if response_len is None: - return variable_len_resp(pipe) + return variable_len_resp(pipe, cmd) if response_len > 0: response = pipe.read(response_len) else: response = b"" ack = pipe.read(1) if ack != b'\x06': - LOG.debug("missing ack: expected 0x06, got" + util.hexprint(ack)) + LOG.debug("missing ACK: expected 0x06, got" + util.hexprint(ack)) raise errors.RadioError("Incorrect ACK on serial port.") return response
@@ -282,12 +284,13 @@ raise errors.RadioError("expected QX from radio.") id_response = sendcmd(radio.pipe, b'\x02', None) if id_response != radio.id_str: - substr0=radio.id_str[:radio.id_str.find('\x00')] + substr0 = radio.id_str[:radio.id_str.find('\x00')] if id_response[:id_response.find('\x00')] != substr0: - msg = "ID mismatch. Expected" + util.hexprint(radio.id_str) + msg = "Unknown ID string received from radio" + msg += "Expected:" + util.hexprint(radio.id_str) msg += ", Received:" + util.hexprint(id_response) LOG.warning(msg) - raise errors.RadioError("Incorrect ID.") + raise errors.RadioError(msg) else: msg = "ID suspect. Expected" + util.hexprint(radio.id_str) msg += ", Received:" + util.hexprint(id_response) @@ -447,8 +450,59 @@ # on the US versions (FT-4XR) STEP_CODE = [0, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0]
-TONE_MODES = ["", "Tone", "TSQL", "DTCS", "DTCS-R", "TSQL-R", "Cross"] -CROSS_MODES = ["DTCS->", "DTCS->DTCS"] # only the extras we need +# Yaesu sql_type field codes +SQL_TYPE = ["off", "R-TONE", "T-TONE", "TSQL", "REV-TN", "DCS", "PAGER"] + +# map a CHIRP tone mode to a FT-4 sql and which if any code to set to 0. +# The keys are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.tmode. This map as the identical +# structure as the one below to simplify the code. It permits stricter +# zeroing of the unused fields later if we find that it is needed, +# but the CHIRP unit tests want us to leave them alone. +MODES_TONE = { + "": ("off", None), + "Tone": ("T-TONE", None), # chirp means "xmit, not rcv" + "TSQL": ("TSQL", None), # chirp means "xmit and rcv, tx==rx" + "DTCS": ("DCS", None), # chirp means "xmt and rcv, tx==rx" + "TSQL-R": ("REV-TN", None), # chirp means reverse R-Tone + "Cross": () # not used in lookup, needed in list + } + +# Map a CHIRP Cross type if the CHIRP mem.tmode is "Cross". The keys +# are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.cross. +MODES_CROSS = { + "DTCS->": ("DCS", "rx_dcs"), + "->DTCS": ("DCS", "tx_dcs"), + "DTCS->DTCS": ("DCS", None), + "->Tone": ("R-TONE", None), + "Tone->Tone": ("TSQL", None) + } + +# Map the radio image sql_type (0-6) back to the CHIRP mem values +# Types "TSQL" and "DCS" each map to different CHIRP values depending +# on the radio values on the tx and rx tone codes. +RADIO_TMODES = [ + ("(None)", ["", ""]), # sql_type= 0. off + ("(None)", ["Cross", "->Tone"]), # sql_type= 1. R-TONE + ("(None)", ["Tone", ""]), # sql_type= 2. T-TONE + ("(None)", None, "tx_ctcss", "rx_ctcss", [ # sql_type= 3. TSQL + ["", None], # tx==0, rx==0 : not valid + ["TSQL", ""], # tx==0 + ["Tone", ""], # rx==0 + ["Cross", "Tone->Tone"], # tx!=rx + ["TSQL", ""] # tx==rx + ]), + ("(None)", ["TSQL-R", ""]), # sql_type= 4. REV TN + ("(None)", None, "tx_dcs", "rx_dcs", [ # sql_type= 5.DCS + ["", None], # tx==0, rx==0 : not valid + ["Cross", "->DTCS"], # tx==0 + ["Cross", "DTCS->"], # rx==0 + ["Cross", "DTCS->DTCS"], # tx!=rx + ["DTCS", ""] # tx==rx + ]), + ("PAGER", ["", None]) # sql_type= 6. handled as a CHIRP "extra" + ]
DTMF_CHARS = "0123456789ABCD*#- " CW_ID_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " @@ -491,6 +545,9 @@ 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754 ] + +# The legal PAGER codes are exactly the same as the CTCSS codes, +# but we pass them to the UI as a lsit of strings to display. EPCS_CODES = [format(flt) for flt in [0] + TONE_MAP[1:]]
@@ -534,8 +591,8 @@ rf.valid_special_chans = specials rf.memory_bounds = (1, self.MAX_MEM_SLOT) rf.valid_duplexes = DUPLEX - rf.valid_tmodes = TONE_MODES - rf.valid_cross_modes = CROSS_MODES + rf.valid_tmodes = list(MODES_TONE.keys()) + rf.valid_cross_modes = list(MODES_CROSS.keys()) rf.valid_power_levels = POWER_LEVELS rf.valid_tuning_steps = self.legal_steps rf.valid_skips = SKIPS @@ -559,6 +616,8 @@ def sync_in(self): try: self._mmap = do_download(self) + except errors.RadioError: + raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() @@ -567,6 +626,8 @@ def sync_out(self): try: do_upload(self) + except errors.RadioError: + raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e)
@@ -707,7 +768,7 @@ # ----------------end of group_descriptions
# allow a child class to add a param. - def add_paramdesc(self,group, param): + def add_paramdesc(self, group, param): for description in self.group_descriptions: groupname, title, parms = description if group == groupname: @@ -770,35 +831,14 @@ LOG.debug(element.get_name()) raise
- RADIO_TMODES = [ - ("(None)", ["", ""]), # off - ("(None)", ["TSQL-R", ""]), # R-TONE - ("(None)", ["Tone", ""]), # T-TONE - ("(None)", None, "tx_ctcss", "rx_ctcss", [ # TSQL - ["", None], # x==0, r==0 : not valid - ["TSQL-R", ""], # x==0 - ["Tone", ""], # r==0 - ["TSQL", ""], # x!=r - ["TSQL", ""] # x==r - ]), - ("REV-TN", ["TSQL-R", ""]), - ("(None)", None, "tx_dcs", "rx_dcs", [ # DCS - ["", None], # x==0, r==0 : not valid - ["DTCS-R", ""], # x==0 - ["Cross", "DTCS->"], # r==0 - ["Cross", "DTCS->DTCS"], # x!=r - ["DTCS", ""] # x==r - ]), - ("PAGER", ["", None]) # handled as a CHIRP "extra" - ] LOOKUP = [[True, True], [True, False], [False, True], [False, False]]
def decode_sql(self, mem, chan): """ examine the radio channel fields and determine the correct - CHIRP CSV values for tmode, cross_mode, and dcts_polarity + CHIRP CSV values for tmode, cross_mode, and sql_override """ - mode = self.RADIO_TMODES[chan.sql_type] + mode = RADIO_TMODES[chan.sql_type] chirpvals = mode[1] if not chirpvals: x = getattr(chan, mode[2]) @@ -820,32 +860,10 @@ mem.rx_dtcs = DTCS_MAP[chan.rx_dcs] LOG.debug(" setting sql_override to <%s>" % mode[0]) mem.extra = RadioSettingGroup("Extra", "extra") - extra_modes = ["(None)", "REV-TN", "PAGER"] + extra_modes = ["(None)", "PAGER"] valuelist = RadioSettingValueList(extra_modes, mode[0]) rs = RadioSetting("sql_override", "Squelch override", valuelist) mem.extra.append(rs) - # Yaesu sql_type field codes - SQL_TYPE = ["off", "R-TONE", "T-TONE", "TSQL", "REV-TN", "DCS", "PAGER"] - # map a CHIRP tone mode to a FT-4 sql and which if any code to set to 0. - MODE_TONE = { - "": ("off", None), - "Tone": ("T-TONE", "rx_ctcss"), - "TSQL": ("TSQL", None), - "DTCS": ("DCS", None), # must set rx_dcs to tx_dcs? - "DTCS-R": ("DCS", "tx_dcs"), - "TSQL-R": ("R-TONE", "tx_ctcss"), # not documented on wiki - "Cross": () # not used in lookup - } - - # map a CHIRP Cross type if the CHIRP sql type is "cross" - MODE_CROSS = { - "DTCS->": ("DCS", "rx_dcs"), - "DTCS->DTCS": ("DCS", None) - # "Tone->Tone": ("TSQL", None), - # "->DTCS": ("DCS", "tx_dcs"), - # "->Tone": ("R-TONE", None), - # "Tone->": ("T-Tone", None) - }
def encode_sql(self, mem, chan): """ @@ -858,22 +876,23 @@ chan.tx_dcs = DTCS_MAP.index(mem.dtcs) chan.rx_ctcss = TONE_MAP.index(mem.ctone) chan.rx_dcs = DTCS_MAP.index(mem.rx_dtcs) + if mem.tmode == "TSQL": + chan.tx_ctcss = chan.rx_ctcss # CHIRP uses ctone for TSQL + if mem.tmode == "DTCS": + chan.tx_dcs = chan.rx_dcs # CHIRP uses rx_dtcs for DTCS tbl, ndx = [ - (self.MODE_TONE, mem.tmode), - (self.MODE_CROSS, mem.cross_mode) + (MODES_TONE, mem.tmode), + (MODES_CROSS, mem.cross_mode) ][mem.tmode == "Cross"] - row = tbl[ndx] - if ndx == "DTCS": - chan.rx_dcs = chan.tx_dcs - chan.sql_type = self.SQL_TYPE.index(row[0]) - if row[1]: - setattr(chan, row[1], 0) + sql_type, suppress = tbl[ndx] + chan.sql_type = SQL_TYPE.index(sql_type) + if suppress: + setattr(chan, suppress, 0) for setting in mem.extra: if (setting.get_name() == 'sql_override'): value = str(setting.value) if value != "(None)": - chan.sql_type = self.SQL_TYPE.index(value) - + chan.sql_type = SQL_TYPE.index(value) return
# given a CHIRP memory ref, get the radio memobj for it. @@ -962,7 +981,6 @@ mem.empty = False mem.extd_number = sname mem.immutable = ["number", "extd_number", "name", "skip"] - return mem
# modify a radio channel in memobj based on info in CHIRP canonical form @@ -995,7 +1013,6 @@ duplex = "off" # radio ignores when tx != rx self._memobj.txfreqs[num-1].freq = txfreq _mem.duplex = DUPLEX.index(duplex) - return
@@ -1018,22 +1035,23 @@ namelen = 6 # length of the mem name display on the FT-4 front-panel id_str = b'IFT-35R\x00\x00V100\x00\x00' legal_steps = list(STEP_CODE) - legal_steps.remove(6.25) #should not remove if euro version + legal_steps.remove(6.25) # should not remove if euro version # names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [ - "mem", "apo", "ar bep", "ar int", "beclo", #00-04 - "beep", "bell", "cw id", "cw wrt", "dc vlt", #05-09 - "dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", #10-14 - "lamp", "led.bsy", "led.tx", "lock", "m/t-cl", #15-19 - "mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", #20-24 - "pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", #25-29 - "rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", #30-34 - "skip", "sql.typ", "step", "tn frq", "tot", #35-39 - "tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44 - "w/n.dev", "wx.alert" #45-46 + "mem", "apo", "ar bep", "ar int", "beclo", # 00-04 + "beep", "bell", "cw id", "cw wrt", "dc vlt", # 05-09 + "dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", # 10-14 + "lamp", "led.bsy", "led.tx", "lock", "m/t-cl", # 15-19 + "mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", # 20-24 + "pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", # 25-29 + "rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", # 30-34 + "skip", "sql.typ", "step", "tn frq", "tot", # 35-39 + "tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", # 40-44 + "w/n.dev", "wx.alert" # 45-46 ]
+ # don't register the FT-65 in the production version until it is tested # @directory.register class YaesuFT65Radio(YaesuSC35GenericRadio): @@ -1052,9 +1070,9 @@ MAX_MEM_SLOT = 200 Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front panel - id_str=b'IH-420\x00\x00\x00V100\x00\x00' + id_str = b'IH-420\x00\x00\x00V100\x00\x00' legal_steps = list(STEP_CODE) - legal_steps.remove(6.25) #should not remove if euro version + legal_steps.remove(6.25) # should not remove if euro version # names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [ @@ -1063,10 +1081,10 @@ "dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", # 10-14 "key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", # 15-19 "name tag", "pager", "password", "pri.rvt", "repeater", # 20-24 - "resume", "rf.sql", "scn.lamp", "skip", "sql type", # 25-29 + "resume", "rf.sql", "scn.lamp", "skip", "sql type", # 25-29 "step", "tot", "tx pwr", "tx save", "vfo.spl", # 30-34 "vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" # 35-39 ] + def __init__(self): self.add_paramdesc("misc", ("compander", "Compander", ["ON", "OFF"])) -
@@ -217,7 +216,7 @@ return sum(x for x in bytearray(data)) & 0xFF
-def variable_len_resp(pipe): +def variable_len_resp(pipe, cmd): """ when length of expected reply is not known, read byte at a time until the ack character is found. @@ -233,8 +232,11 @@ response += b i += 1 if i > toolong:
LOG.debug("Response too long. got" + util.hexprint(response))
raise errors.RadioError("Response too long.")
msg = "received too many bytes from radio before ACK. "
msg += "Sent " + util.hexprint(cmd)
msg += ". Got " + util.hexprint(response)
LOG.debug(msg)
raise errors.RadioError(msg)
Heh, okay, I see I jumped the gun here. However, hexprinted debug is way too much info to show to the user too. Somewhere in the middle please. I'm sure I'm seeming overly picky here, but we have some variety in the error messages that people get since they're all defined by the deep internals of the drivers, so I'm trying to steer this somewhere towards the center.
I can also change this up to be what I think it should be (like the examples I gave earlier) if you want.
+# map a CHIRP tone mode to a FT-4 sql and which if any code to set to 0. +# The keys are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.tmode. This map as the identical +# structure as the one below to simplify the code. It permits stricter +# zeroing of the unused fields later if we find that it is needed, +# but the CHIRP unit tests want us to leave them alone. +MODES_TONE = {
- "": ("off", None),
- "Tone": ("T-TONE", None), # chirp means "xmit, not rcv"
- "TSQL": ("TSQL", None), # chirp means "xmit and rcv, tx==rx"
- "DTCS": ("DCS", None), # chirp means "xmt and rcv, tx==rx"
- "TSQL-R": ("REV-TN", None), # chirp means reverse R-Tone
- "Cross": () # not used in lookup, needed in list
- }
+# Map a CHIRP Cross type if the CHIRP mem.tmode is "Cross". The keys +# are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.cross. +MODES_CROSS = {
- "DTCS->": ("DCS", "rx_dcs"),
- "->DTCS": ("DCS", "tx_dcs"),
- "DTCS->DTCS": ("DCS", None),
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
Tone->Tone is only for when the tones are different, which is not what TSQL means...
# names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [
"mem", "apo", "ar bep", "ar int", "beclo", #00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", #05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", #10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", #15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", #20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", #25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", #30-34
"skip", "sql.typ", "step", "tn frq", "tot", #35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44
"w/n.dev", "wx.alert" #45-46
"mem", "apo", "ar bep", "ar int", "beclo", # 00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", # 05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", # 10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", # 15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", # 20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", # 25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", # 30-34
"skip", "sql.typ", "step", "tn frq", "tot", # 35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", # 40-44
"w/n.dev", "wx.alert" # 45-46
Did this change or did you just reformat it? What about the other copy of this you have in the file?
class YaesuFT65Radio(YaesuSC35GenericRadio): @@ -1052,9 +1070,9 @@ MAX_MEM_SLOT = 200 Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front panel
- id_str=b'IH-420\x00\x00\x00V100\x00\x00'
- id_str = b'IH-420\x00\x00\x00V100\x00\x00' legal_steps = list(STEP_CODE)
- legal_steps.remove(6.25) #should not remove if euro version
- legal_steps.remove(6.25) # should not remove if euro version # names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [
@@ -1063,10 +1081,10 @@ "dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", # 10-14 "key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", # 15-19 "name tag", "pager", "password", "pri.rvt", "repeater", # 20-24
"resume", "rf.sql", "scn.lamp", "skip", "sql type", # 25-29
"resume", "rf.sql", "scn.lamp", "skip", "sql type", # 25-29 "step", "tot", "tx pwr", "tx save", "vfo.spl", # 30-34 "vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" # 35-39 ]
- def __init__(self): self.add_paramdesc("misc", ("compander", "Compander", ["ON", "OFF"]))
Looks like some whitespace changes jumped in here :)
I've applied the first four in this set and would like to see some discussion of the previous items I have before we proceed on this one.
I snuck a change in between these to add ft4.py to the cpep8.manifest so that style checks always run on the file, and it looks like there are still a bunch of offenses in there. Maybe we can get that fixed up shortly in follow-up?
Thanks!
--Dan
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
These are two mappings from the CHIRP definitions to the Yaesu definitions. Yaesu uses "TSQL" to mean "send and receive ctcss tones, and the toned do jot need to be identical. thus we must map to "Yaesu TSQL" on both cases. I chose to use the name "TSQL" for to this Yaseu value because it's in the Yasu documentation and it's what you see on the radio's screen. I could have renamed it in the ptyhon code, but the other drivers seem to adhere to the manufacturer's documentation.
Sinmilarly, Yaesu "R-TONE" is the name for "don't send a tone, but do receive a tone." The Yaseu name for reverse polarity tone squelch is "REV TN".
About the use of a single table: I have been thinking about that a lot. It's not really a trivial problem, but I think that may be a reasonable solution. the underlying problem is that an abstract radio can perform some or all of 15 combinations of tone handling. : Tx (none, ctcss,dcs) x Rx (none, ctcss,dcs,ctcss-R, dcs-R) and of these two two are split (ctcss==, ctcss!=) and (dcs==, dcs!=). The CHIRP mem structure uses two fields to represent this and each radio uses its own strange multi-field encoding.
To complicate this, I originally thought that the CHIRP unit tests require that we preserve tone fields even some cases where a given tone field is clearly a "don't care" as far as the radio is concerned. This is a burden on the code and on the approach we must take. I now think I was not quite right about this,and it turns out that could simply not put any value into the mem structure for these cases.
None of the other drives I looked at even attempt to create an explicit two-way mapping. Instead, they they use one if-test chain for encode and a second if-test chain for decode. When I originally wrote my code by example, I simply converted each of these if-chains into a separate table. The code has substantially different requirements for the two tables, so Idon't think that there is a single table that is both comprehensible and has simple lookups for both directions. a simplified table will complicate the code. I'll give this another try today.
On Thu, Feb 28, 2019 at 7:12 AM Dan Smith via chirp_devel < chirp_devel@intrepid.danplanet.com> wrote:
@@ -217,7 +216,7 @@ return sum(x for x in bytearray(data)) & 0xFF
-def variable_len_resp(pipe): +def variable_len_resp(pipe, cmd): """ when length of expected reply is not known, read byte at a time until the ack character is found. @@ -233,8 +232,11 @@ response += b i += 1 if i > toolong:
LOG.debug("Response too long. got" +
util.hexprint(response))
raise errors.RadioError("Response too long.")
msg = "received too many bytes from radio before ACK. "
msg += "Sent " + util.hexprint(cmd)
msg += ". Got " + util.hexprint(response)
LOG.debug(msg)
raise errors.RadioError(msg)
Heh, okay, I see I jumped the gun here. However, hexprinted debug is way too much info to show to the user too. Somewhere in the middle please. I'm sure I'm seeming overly picky here, but we have some variety in the error messages that people get since they're all defined by the deep internals of the drivers, so I'm trying to steer this somewhere towards the center.
I can also change this up to be what I think it should be (like the examples I gave earlier) if you want.
+# map a CHIRP tone mode to a FT-4 sql and which if any code to set to
+# The keys are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.tmode. This map as the identical +# structure as the one below to simplify the code. It permits stricter +# zeroing of the unused fields later if we find that it is needed, +# but the CHIRP unit tests want us to leave them alone. +MODES_TONE = {
- "": ("off", None),
- "Tone": ("T-TONE", None), # chirp means "xmit, not rcv"
- "TSQL": ("TSQL", None), # chirp means "xmit and rcv,
tx==rx"
- "DTCS": ("DCS", None), # chirp means "xmt and rcv,
tx==rx"
- "TSQL-R": ("REV-TN", None), # chirp means reverse R-Tone
- "Cross": () # not used in lookup, needed in
list
- }
+# Map a CHIRP Cross type if the CHIRP mem.tmode is "Cross". The keys +# are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.cross. +MODES_CROSS = {
- "DTCS->": ("DCS", "rx_dcs"),
- "->DTCS": ("DCS", "tx_dcs"),
- "DTCS->DTCS": ("DCS", None),
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
Tone->Tone is only for when the tones are different, which is not what TSQL means...
# names for the setmode function for the programmable keys. Mode
zero means
# that the key is programmed for a memory not a setmode. SETMODES = [
"mem", "apo", "ar bep", "ar int", "beclo", #00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", #05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", #10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", #15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", #20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", #25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", #30-34
"skip", "sql.typ", "step", "tn frq", "tot", #35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44
"w/n.dev", "wx.alert" #45-46
"mem", "apo", "ar bep", "ar int", "beclo", # 00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", # 05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", # 10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", # 15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", # 20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", # 25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", # 30-34
"skip", "sql.typ", "step", "tn frq", "tot", # 35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", # 40-44
"w/n.dev", "wx.alert" # 45-46
Did this change or did you just reformat it? What about the other copy of this you have in the file?
class YaesuFT65Radio(YaesuSC35GenericRadio): @@ -1052,9 +1070,9 @@ MAX_MEM_SLOT = 200 Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front
panel
- id_str=b'IH-420\x00\x00\x00V100\x00\x00'
- id_str = b'IH-420\x00\x00\x00V100\x00\x00' legal_steps = list(STEP_CODE)
- legal_steps.remove(6.25) #should not remove if euro version
- legal_steps.remove(6.25) # should not remove if euro version # names for the setmode function for the programmable keys. Mode
zero means
# that the key is programmed for a memory not a setmode. SETMODES = [
@@ -1063,10 +1081,10 @@ "dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", #
10-14
"key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", #
15-19
"name tag", "pager", "password", "pri.rvt", "repeater", #
20-24
"resume", "rf.sql", "scn.lamp", "skip", "sql type", #
25-29
"resume", "rf.sql", "scn.lamp", "skip", "sql type", #
25-29
"step", "tot", "tx pwr", "tx save", "vfo.spl", #
30-34
"vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" #
35-39
]
- def __init__(self): self.add_paramdesc("misc", ("compander", "Compander", ["ON",
"OFF"]))
Looks like some whitespace changes jumped in here :)
I've applied the first four in this set and would like to see some discussion of the previous items I have before we proceed on this one.
I snuck a change in between these to add ft4.py to the cpep8.manifest so that style checks always run on the file, and it looks like there are still a bunch of offenses in there. Maybe we can get that fixed up shortly in follow-up?
Thanks!
--Dan
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
I thought that I had run cpep8 after the last patch, at least., made changes to eliminate all cpep8 errors.
On Thu, Feb 28, 2019 at 8:27 AM Dan Clemmensen danclemmensen@gmail.com wrote:
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
These are two mappings from the CHIRP definitions to the Yaesu definitions. Yaesu uses "TSQL" to mean "send and receive ctcss tones, and the toned do jot need to be identical. thus we must map to "Yaesu TSQL" on both cases. I chose to use the name "TSQL" for to this Yaseu value because it's in the Yasu documentation and it's what you see on the radio's screen. I could have renamed it in the ptyhon code, but the other drivers seem to adhere to the manufacturer's documentation.
Sinmilarly, Yaesu "R-TONE" is the name for "don't send a tone, but do receive a tone." The Yaseu name for reverse polarity tone squelch is "REV TN".
About the use of a single table: I have been thinking about that a lot. It's not really a trivial problem, but I think that may be a reasonable solution. the underlying problem is that an abstract radio can perform some or all of 15 combinations of tone handling. : Tx (none, ctcss,dcs) x Rx (none, ctcss,dcs,ctcss-R, dcs-R) and of these two two are split (ctcss==, ctcss!=) and (dcs==, dcs!=). The CHIRP mem structure uses two fields to represent this and each radio uses its own strange multi-field encoding.
To complicate this, I originally thought that the CHIRP unit tests require that we preserve tone fields even some cases where a given tone field is clearly a "don't care" as far as the radio is concerned. This is a burden on the code and on the approach we must take. I now think I was not quite right about this,and it turns out that could simply not put any value into the mem structure for these cases.
None of the other drives I looked at even attempt to create an explicit two-way mapping. Instead, they they use one if-test chain for encode and a second if-test chain for decode. When I originally wrote my code by example, I simply converted each of these if-chains into a separate table. The code has substantially different requirements for the two tables, so Idon't think that there is a single table that is both comprehensible and has simple lookups for both directions. a simplified table will complicate the code. I'll give this another try today.
On Thu, Feb 28, 2019 at 7:12 AM Dan Smith via chirp_devel < chirp_devel@intrepid.danplanet.com> wrote:
@@ -217,7 +216,7 @@ return sum(x for x in bytearray(data)) & 0xFF
-def variable_len_resp(pipe): +def variable_len_resp(pipe, cmd): """ when length of expected reply is not known, read byte at a time until the ack character is found. @@ -233,8 +232,11 @@ response += b i += 1 if i > toolong:
LOG.debug("Response too long. got" +
util.hexprint(response))
raise errors.RadioError("Response too long.")
msg = "received too many bytes from radio before ACK. "
msg += "Sent " + util.hexprint(cmd)
msg += ". Got " + util.hexprint(response)
LOG.debug(msg)
raise errors.RadioError(msg)
Heh, okay, I see I jumped the gun here. However, hexprinted debug is way too much info to show to the user too. Somewhere in the middle please. I'm sure I'm seeming overly picky here, but we have some variety in the error messages that people get since they're all defined by the deep internals of the drivers, so I'm trying to steer this somewhere towards the center.
I can also change this up to be what I think it should be (like the examples I gave earlier) if you want.
+# map a CHIRP tone mode to a FT-4 sql and which if any code to set to
+# The keys are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.tmode. This map as the identical +# structure as the one below to simplify the code. It permits stricter +# zeroing of the unused fields later if we find that it is needed, +# but the CHIRP unit tests want us to leave them alone. +MODES_TONE = {
- "": ("off", None),
- "Tone": ("T-TONE", None), # chirp means "xmit, not rcv"
- "TSQL": ("TSQL", None), # chirp means "xmit and rcv,
tx==rx"
- "DTCS": ("DCS", None), # chirp means "xmt and rcv,
tx==rx"
- "TSQL-R": ("REV-TN", None), # chirp means reverse R-Tone
- "Cross": () # not used in lookup, needed in
list
- }
+# Map a CHIRP Cross type if the CHIRP mem.tmode is "Cross". The keys +# are provided to RadioFeatures as a list, so these are the +# only values we expect to see in mem.cross. +MODES_CROSS = {
- "DTCS->": ("DCS", "rx_dcs"),
- "->DTCS": ("DCS", "tx_dcs"),
- "DTCS->DTCS": ("DCS", None),
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
Tone->Tone is only for when the tones are different, which is not what TSQL means...
# names for the setmode function for the programmable keys. Mode
zero means
# that the key is programmed for a memory not a setmode. SETMODES = [
"mem", "apo", "ar bep", "ar int", "beclo", #00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", #05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", #10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", #15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", #20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", #25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", #30-34
"skip", "sql.typ", "step", "tn frq", "tot", #35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", #40-44
"w/n.dev", "wx.alert" #45-46
"mem", "apo", "ar bep", "ar int", "beclo", # 00-04
"beep", "bell", "cw id", "cw wrt", "dc vlt", # 05-09
"dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", # 10-14
"lamp", "led.bsy", "led.tx", "lock", "m/t-cl", # 15-19
"mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", # 20-24
"pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", # 25-29
"rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", # 30-34
"skip", "sql.typ", "step", "tn frq", "tot", # 35-39
"tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", # 40-44
"w/n.dev", "wx.alert" # 45-46
Did this change or did you just reformat it? What about the other copy of this you have in the file?
class YaesuFT65Radio(YaesuSC35GenericRadio): @@ -1052,9 +1070,9 @@ MAX_MEM_SLOT = 200 Pkeys = 4 # number of programmable keys on the FT-65 namelen = 8 # length of the mem name display on the FT-65 front
panel
- id_str=b'IH-420\x00\x00\x00V100\x00\x00'
- id_str = b'IH-420\x00\x00\x00V100\x00\x00' legal_steps = list(STEP_CODE)
- legal_steps.remove(6.25) #should not remove if euro version
- legal_steps.remove(6.25) # should not remove if euro version # names for the setmode function for the programmable keys. Mode
zero means
# that the key is programmed for a memory not a setmode. SETMODES = [
@@ -1063,10 +1081,10 @@ "dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", #
10-14
"key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", #
15-19
"name tag", "pager", "password", "pri.rvt", "repeater", #
20-24
"resume", "rf.sql", "scn.lamp", "skip", "sql type", #
25-29
"resume", "rf.sql", "scn.lamp", "skip", "sql type", #
25-29
"step", "tot", "tx pwr", "tx save", "vfo.spl", #
30-34
"vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" #
35-39
]
- def __init__(self): self.add_paramdesc("misc", ("compander", "Compander", ["ON",
"OFF"]))
Looks like some whitespace changes jumped in here :)
I've applied the first four in this set and would like to see some discussion of the previous items I have before we proceed on this one.
I snuck a change in between these to add ft4.py to the cpep8.manifest so that style checks always run on the file, and it looks like there are still a bunch of offenses in there. Maybe we can get that fixed up shortly in follow-up?
Thanks!
--Dan
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
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
These are two mappings from the CHIRP definitions to the Yaesu definitions. Yaesu uses "TSQL" to mean "send and receive ctcss tones, and the toned do jot need to be identical. thus we must map to "Yaesu TSQL" on both cases. I chose to use the name "TSQL" for to this Yaseu value because it's in the Yasu documentation and it's what you see on the radio's screen. I could have renamed it in the ptyhon code, but the other drivers seem to adhere to the manufacturer's documentation.
Sinmilarly, Yaesu "R-TONE" is the name for "don't send a tone, but do receive a tone." The Yaseu name for reverse polarity tone squelch is "REV TN".
Okay, to my skimming eyes, it looked like equating Tone->Tone with TSQL (chirp's definition) which is not right.
The code has substantially different requirements for the two tables, so Idon't think that there is a single table that is both comprehensible and has simple lookups for both directions. a simplified table will complicate the code. I'll give this another try today.
FWIW, I don't think that it's particularly comprehensible today, but more importantly, it's really hard to look at them and tell if they're doing the same (but inverted) translation.
Maybe I should stew on it a little more and look deeper into how you're using these.
--Dan
give me another 30 minutes.
On Thu, Feb 28, 2019 at 8:54 AM Dan Smith via chirp_devel < chirp_devel@intrepid.danplanet.com> wrote:
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
These are two mappings from the CHIRP definitions to the Yaesu
definitions. Yaesu uses "TSQL" to mean "send and receive ctcss tones,
and the toned do jot need to be identical. thus we must map to "Yaesu
TSQL" on both cases. I chose to use the name "TSQL" for to this
Yaseu value because it's in the Yasu documentation and it's what you see
on the radio's screen. I could have renamed it in the ptyhon
code, but the other drivers seem to adhere to the manufacturer's
documentation.
Sinmilarly, Yaesu "R-TONE" is the name for "don't send a tone, but do
receive a tone." The Yaseu name for reverse polarity tone squelch is "REV TN".
Okay, to my skimming eyes, it looked like equating Tone->Tone with TSQL (chirp's definition) which is not right.
The code has substantially different requirements for the two tables, so
Idon't think that there is a single table that is both comprehensible and
has simple lookups for both directions. a simplified table will
complicate the code. I'll give this another try today.
FWIW, I don't think that it's particularly comprehensible today, but more importantly, it's really hard to look at them and tell if they're doing the same (but inverted) translation.
Maybe I should stew on it a little more and look deeper into how you're using these.
--Dan _______________________________________________ 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
I have not tested this yet, and I want to remove the first column of the table, but I have a critical meeting to attend immediately (3-year-old grandchild has demanded my presence.) This is not yet a patch. It is a request for comment: is this roughly what you are looking for?
On Thu, Feb 28, 2019 at 9:08 AM Dan Clemmensen danclemmensen@gmail.com wrote:
give me another 30 minutes.
On Thu, Feb 28, 2019 at 8:54 AM Dan Smith via chirp_devel < chirp_devel@intrepid.danplanet.com> wrote:
- "->Tone": ("R-TONE", None),
I had a question about this in the previous patch.
- "Tone->Tone": ("TSQL", None)
- }
These are two mappings from the CHIRP definitions to the Yaesu
definitions. Yaesu uses "TSQL" to mean "send and receive ctcss tones,
and the toned do jot need to be identical. thus we must map to "Yaesu
TSQL" on both cases. I chose to use the name "TSQL" for to this
Yaseu value because it's in the Yasu documentation and it's what you
see on the radio's screen. I could have renamed it in the ptyhon
code, but the other drivers seem to adhere to the manufacturer's
documentation.
Sinmilarly, Yaesu "R-TONE" is the name for "don't send a tone, but do
receive a tone." The Yaseu name for reverse polarity tone squelch is "REV TN".
Okay, to my skimming eyes, it looked like equating Tone->Tone with TSQL (chirp's definition) which is not right.
The code has substantially different requirements for the two tables,
so Idon't think that there is a single table that is both comprehensible and
has simple lookups for both directions. a simplified table will
complicate the code. I'll give this another try today.
FWIW, I don't think that it's particularly comprehensible today, but more importantly, it's really hard to look at them and tell if they're doing the same (but inverted) translation.
Maybe I should stew on it a little more and look deeper into how you're using these.
--Dan _______________________________________________ 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
This is not yet a patch. It is a request for comment: is this roughly what you are looking for?
I think generating all the permutations of what you need from the same set of source data is better, yeah. Ideally that means if you had to tweak the source, the permuted list (i.e. MODES_TONE, etc) would change accordingly.
--Dan
participants (3)
-
Dan Clemmensen
-
Dan Smith
-
DanClemmensen