[chirp_devel] New TH-UV8000 Driver
Fixed typos in previous release, changed info prompt. Manifest is updated.
(Jim, question for you below)
diff -r 3f9d47c26743 -r 251bf9ab9b14 chirp/drivers/th_uv8000.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chirp/drivers/th_uv8000.py Sun Jun 30 05:35:16 2019 -0700 @@ -0,0 +1,1568 @@ +# Copyright 2019: Rick DeWitt (RJD), aa0rd@yahoo.com +# Version 1.0 for TYT-UV8000D/
Remove trailing slash here?
+# Thanks to Damon Schaefer (K9CQB)and the Loudoun County, VA ARES
Needs a space after the close paren and "and".
+def _clean_buffer(radio):
- radio.pipe.timeout = 0.005
- junk = radio.pipe.read(256)
- radio.pipe.timeout = STIMEOUT
- if junk:
Log.debug("Got %i bytes of junk before starting" % len(junk))
"Log" is undefined and you will crash with NameError here.
+def _download(radio):
- """Get the memory map"""
- # Put radio in program mode and identify it
- _do_ident(radio)
- # UI progress
- status = chirp_common.Status()
- status.cur = 0
- status.max = MEM_SIZE / BLOCK_SIZE
- status.msg = "Cloning from radio..."
- radio.status_fn(status)
- data = ""
- for addr in range(0, MEM_SIZE, BLOCK_SIZE):
frame = _make_frame("R", addr, BLOCK_SIZE)
# DEBUG
LOG.info("Request sent:")
LOG.debug("Frame=" + util.hexprint(frame))
# Sending the read request
_rawsend(radio, frame)
dx = _rawrecv(radio, 4)
# Now we read data
d = _recv(radio, addr, BLOCK_SIZE)
# LOG.warning("Data= " + util.hexprint(d))
# Aggregate the data
data += d
# UI Update
status.cur = addr / BLOCK_SIZE
status.msg = "Cloning from radio..."
radio.status_fn(status)
- _exit_program_mode(radio)
- # Append the model number to the downloaded memory
- data += radio.MODEL.ljust(9)
Why are you doing this? Modern chirp will keep track of which model an image was created from, making it unnecessary to do this sort of thing for file identification...
+def force_odd(fmfrq):
- """Force FM Broadcast Frequency to have odd KHz """
- oddfrq = int(fmfrq / 100000) # remove 10Khz and lower
- if (oddfrq % 2) == 0: # increment to odd
oddfrq += 1
- return (oddfrq * 100000)
Can you explain this a little more? This doesn't seem to make sense to me and more comments about *why* you're doing it would be good.
+def model_match(cls, data):
- """Match the opened/downloaded image to the correct version"""
- val = MEM_SIZE + len(cls.MODEL)
- if len(data) == val:
rid = data[MEM_SIZE:val]
return rid.startswith(cls.MODEL)
As above, I think this is probably unnecessary now.
+@directory.register +class tyt_uv8000d(chirp_common.CloneModeRadio):
This is not a conventional Python class name. Please capitalize it and make it consistent with the rest of the code.
rp.info = \
('Click on the "Special Channels" tab of the layout '
'screen to see/set the upper and lower frequency-mode values, '
'as well as the 25 FM broadcast radio station channels.\n\n')
If you're going to do this, please at least make it correct. It's not a "tab" it's a button (actually a toggle-button which shows a little differently), but it's very distinct from the tabs on the top and left. Also, nothing else in chirp mentions the "layout screen" and if you said this to me with no context, I wouldn't know what you meant. I would suggest "memory editor" or "memories" to be consistent with the left-side tab under which the button actually exists.
rp.pre_download = _(dedent("""\
Follow these instructions to download your config:
Please choose something other than "your config" here. Nothing else in chirp calls the contents of a radio's memory its "config".
1 - Turn off your radio
2 - Connect your interface cable
3 - Turn on your radio, volume @ 50%
4 - Radio > Download from radio
"""))
rp.pre_upload = _(dedent("""\
Follow this instructions to upload your config:
s/this/these/
- def _get_fm_memory(self, mem, _mem):
mem.name = "----"
rx = self._memobj.fm_stations[mem.number + 2].rxfreq
if rx == 0xFFFF:
mem.empty = True
return mem
else:
mem.freq = (float(int(rx)) / 40) * 1000000
mem.empty = False
mem.offset = 0.0
mem.power = 0
mem.duplex = "off" # inhibits tx
mem.mode = self.MODES[1]
dtcs_pol = ["N", "N"]
mem.ctone = 88.5
mem.rtone = 88.5
mem.tmode = ""
mem.cross_mode = "Tone->Tone"
mem.skip = ""
mem.comment = ""
return mem
I'm not really sure how I feel about this. I think the other radios that support editing the (broadcast) FM presets do so via RadioSetting values instead of calling them channels. Doing this makes editing them a little more like regular channels, but they include a bunch of other gorp (like tones) that will never apply, and they involve the usual band checking for the radio which defeats the ability of the memory editor UI being able to range check things properly.
Jim, any opinions here? For consistency I'd tend to lean towards just putting these into RadioSettings to be consistent with the other radios.
- def _set_memory(self, mem, _mem):
"""Convert UI column data (mem) into MEM_FORMAT memory (_mem)."""
# At this point mem points to either normal, fm or Freq chans
# These first attributes are common to all types
if mem.empty:
if mem.number > 0:
_mem.rxfreq = 0xffffffff
# Set 'empty' and 'skip' bits
_do_map(mem.number, 1, self._memobj.chnmap.map)
_do_map(mem.number, 1, self._memobj.skpchns.map)
elif mem.number == -2: # upper VFO Freq
_mem.rxfreq = 14652000 # VHF National Calling freq
elif mem.number == -1: # lower VFO
_mem.rxfreq = 44600000 # UHF National Calling freq
else: # FM stations, mem.number -3 to -27
_mem.rxfreq = 0xffff
_do_map(mem.number + 28, 1, self._memobj.fmmap.fmset)
return
_mem.rxfreq = mem.freq / 10
if mem.number < -2: # FM stations, only rxfreq
_mem.rxfreq = (force_odd(mem.freq) * 40) / 1000000
_do_map(mem.number + 28, 0, self._memobj.fmmap.fmset)
return
It looks like this will let me set something like 146.52 into the FM preset memories, right? What happens if I do? What happens if I try to set 89.1MHz into one of the regular channels?
if False: # Skip these unknowns
# FM Scan Range lo and Hi ??? MEM
val = 87.5
rx = RadioSettingValueFloat(87.5, 107.9, val, 0.1, 1)
rset = RadioSetting("setstuf.fmsclo",
"Low FM Scan Bound (MHz)", rx)
rset.set_apply_callback(myset_freq, _sets, "fmsclo", 40)
fmb.append(rset)
val = 107.9 # ??? @@@ where
rx = RadioSettingValueFloat(87.5, 107.9, val, 0.1, 1)
rset = RadioSetting("setstuf.fmschi",
"High FM Scan Freq (MHz)", rx)
rset.set_apply_callback(myset_freq, _sets, "fmschi", 40)
fmb.append(rset)
I would really prefer that you not add dead code like this. Commented out code is also pretty smelly, so I would rather just mention in a comment that you don't know what "fmsclo" and "fmschi" do and that they're unimplemented or something like that. A person could look at this (especially via grep or in a diff) for a while wondering why this isn't showing up in the UI, before noticing that it's dead.
diff -r 3f9d47c26743 -r 251bf9ab9b14 tools/cpep8.manifest --- a/tools/cpep8.manifest Wed Jun 26 08:00:02 2019 -0700 +++ b/tools/cpep8.manifest Sun Jun 30 05:35:16 2019 -0700 @@ -74,6 +74,7 @@ ./chirp/drivers/th9800.py ./chirp/drivers/th_uv3r.py ./chirp/drivers/th_uv3r25.py +./chirp/drivers/th_uv8000.py
Good man :)
--Dan
participants (2)
-
Dan Smith
-
Rick DeWitt AA0RD