From b142a6faee251d0716b93bf73f7bb628cfefbf2c Mon Sep 17 00:00:00 2001 From: Jim Unroe Date: Mon, 12 Dec 2022 13:38:10 -0500 Subject: [PATCH] Fixes and testing: retevis_rt98.py & update Python3 Driver Testing matrix --- chirp/drivers/retevis_rt98.py | 140 ++++++++++++++++++-------------- tests/Python3_Driver_Testing.md | 6 +- tests/py3_driver_testers.txt | 1 + 3 files changed, 82 insertions(+), 65 deletions(-) diff --git a/chirp/drivers/retevis_rt98.py b/chirp/drivers/retevis_rt98.py index 6520a990..284d925f 100644 --- a/chirp/drivers/retevis_rt98.py +++ b/chirp/drivers/retevis_rt98.py @@ -538,7 +538,7 @@ def _echo_write(radio, data): def _checksum(data): cs = 0 for byte in data: - cs += ord(byte) + cs += byte return cs % 256 @@ -598,13 +598,13 @@ def check_ver(ver_response, allowed_types): def _ident(radio): radio.pipe.timeout = 1 - _echo_write(radio, "PROGRAM") + _echo_write(radio, b"PROGRAM") response = radio.pipe.read(3) - if response != "QX\06": + if response != b"QX\06": _finish(radio) LOG.debug("Response was :\n%s" % util.hexprint(response)) raise errors.RadioError("Radio did not respond. Check connection.") - _echo_write(radio, "\x02") + _echo_write(radio, b"\x02") ver_response = radio.pipe.read(16) LOG.debug(util.hexprint(ver_response)) @@ -623,13 +623,13 @@ def _send(radio, cmd, addr, length, data=None): frame = struct.pack(">cHb", cmd, addr, length) if data: frame += data - frame += chr(_checksum(frame[1:])) - frame += "\x06" + frame += bytes([_checksum(frame[1:])]) + frame += b"\x06" _echo_write(radio, frame) LOG.debug("Sent:\n%s" % util.hexprint(frame)) if data: result = radio.pipe.read(1) - if result != "\x06": + if result != b"\x06": _finish(radio) LOG.debug("Ack was: %s" % repr(result)) raise errors.RadioError("Radio did not accept block at %04x" @@ -637,10 +637,10 @@ def _send(radio, cmd, addr, length, data=None): return result = _read(radio, length + 6) LOG.debug("Got:\n%s" % util.hexprint(result)) - header = result[0:4] + header = result[:4] data = result[4:-2] - ack = result[-1] - if ack != "\x06": + ack = result[-1:] + if ack != b"\x06": _finish(radio) LOG.debug("Ack was: %s" % repr(ack)) raise errors.RadioError("Radio NAK'd block at %04x" % addr) @@ -652,19 +652,19 @@ def _send(radio, cmd, addr, length, data=None): LOG.debug(" Addr: %04x/%04x" % (addr, _addr)) raise errors.RadioError("Radio send unexpected block") cs = _checksum(result[1:-2]) - if cs != ord(result[-2]): + if cs != result[-2]: _finish(radio) LOG.debug("Calculated: %02x" % cs) - LOG.debug("Actual: %02x" % ord(result[-2])) + LOG.debug("Actual: %02x" % result[-2]) raise errors.RadioError("Block at 0x%04x failed checksum" % addr) return data def _finish(radio): - endframe = "\x45\x4E\x44" + endframe = b"\x45\x4E\x44" _echo_write(radio, endframe) result = radio.pipe.read(1) - if result != "\x06": + if result != b"\x06": LOG.error("Got:\n%s" % util.hexprint(result)) raise errors.RadioError("Radio did not finish cleanly") @@ -674,10 +674,10 @@ def do_download(radio): _ident(radio) _memobj = None - data = "" + data = b"" for addr in range(0, radio._memsize, 0x10): - block = _send(radio, 'R', addr, 0x10) + block = _send(radio, b'R', addr, 0x10) data += block status = chirp_common.Status() status.cur = len(data) @@ -687,7 +687,7 @@ def do_download(radio): _finish(radio) - return memmap.MemoryMap(data) + return memmap.MemoryMapBytes(data) def do_upload(radio): @@ -711,9 +711,9 @@ def do_upload(radio): image_band_limits = LIST_RT98U_FREQS[int(_embedded.mode)] if str(_embedded.radio_type).rstrip("\00") in ["RT98V", "AT-779V"]: image_band_limits = LIST_RT98V_FREQS[int(_embedded.mode)] - if model in ["RT98U", "AT-779U"]: + if str(model).rstrip("\00") in ["RT98U", "AT-779U"]: radio_band_limits = LIST_RT98U_FREQS[int(bandlimit)] - if model in ["RT98V", "AT-779V"]: + if str(model).rstrip("\00") in ["RT98V", "AT-779V"]: radio_band_limits = LIST_RT98V_FREQS[int(bandlimit)] LOG.warning('radio and image band limits differ') @@ -731,7 +731,7 @@ def do_upload(radio): for start, end in radio._ranges: for addr in range(start, end, 0x10): block = radio._mmap[addr:addr+0x10] - _send(radio, 'W', addr, len(block), block) + _send(radio, b'W', addr, len(block), block) status = chirp_common.Status() status.cur = addr status.max = end @@ -754,6 +754,7 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, VENDOR = "Retevis" MODEL = "RT98 Base" BAUD_RATE = 9600 + NEEDS_COMPAT_SERIAL = False _memsize = 0x3E00 _ranges = [(0x0000, 0x3310), @@ -796,7 +797,7 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, rf.memory_bounds = (1, 199) rf.valid_name_length = 6 if _embedded.mode == 0: # PMR or FreeNet - rf.valid_duplexes = [''] + rf.valid_duplexes = ['', 'off'] else: rf.valid_duplexes = DUPLEXES + ['split', 'off'] rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "- " @@ -829,31 +830,6 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, rf.valid_tuning_steps = TUNING_STEPS return rf - def validate_memory(self, mem): - _embedded = self._memobj.embedded_msg - msgs = "" - msgs = chirp_common.CloneModeRadio.validate_memory(self, mem) - - # FreeNet and PMR radio types - if _embedded.mode == 0: # PMR or FreeNet - freq = float(mem.freq) / 1000000 - - # FreeNet - if str(_embedded.radio_type).rstrip("\00") == "RT98V": - if freq not in FREENET_FREQS: - _msg_freq = 'Memory location not a valid FreeNet frequency' - # warn user invalid frequency - msgs.append(chirp_common.ValidationError(_msg_freq)) - - # PMR - if str(_embedded.radio_type).rstrip("\00") == "RT98U": - if freq not in PMR_FREQS: - _msg_freq = 'Memory location not a valid PMR frequency' - # warn user invalid frequency - msgs.append(chirp_common.ValidationError(_msg_freq)) - - return msgs - # Do a download of the radio from the serial port def sync_in(self): self._mmap = do_download(self) @@ -920,7 +896,9 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, mem.offset = int(_mem.offset) * 10 # Set the duplex flags - if _mem.duplex == DUPLEX_POSSPLIT: + if _mem.tx_off: # handle tx off + mem.duplex = 'off' + elif _mem.duplex == DUPLEX_POSSPLIT: mem.duplex = '+' elif _mem.duplex == DUPLEX_NEGSPLIT: mem.duplex = '-' @@ -932,10 +910,6 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, LOG.error('%s: get_mem: unhandled duplex: %02x' % (mem.name, _mem.duplex)) - # handle tx off - if _mem.tx_off: - mem.duplex = 'off' - # Set the channel width if _mem.channel_width == CHANNEL_WIDTH_12d5kHz: mem.mode = 'NFM' @@ -1042,10 +1016,37 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, if mem.empty: self._memobj.csetflag[cbyte].c[cbit] = 0 self._memobj.cskipflag[cbyte].c[cbit] = 0 - _mem.set_raw('\xff' * (_mem.size() / 8)) + _mem.set_raw("\xff" * 32) return - _mem.set_raw('\x00' * (_mem.size() / 8)) + _mem.set_raw("\x00" * 32) + + # FreeNet and PMR radio types + if _embedded.mode == 0: # PMR or FreeNet + + # FreeNet + if str(_embedded.radio_type).rstrip("\00") == "RT98V": + mem.duplex = '' + mem.offset = 0 + if mem.number >= 1 and mem.number <= 6: + FREENET_FREQ = int(FREENET_FREQS[mem.number - 1] * 1000000) + mem.freq = FREENET_FREQ + else: + _mem.tx_off = 1 + mem.duplex = 'off' + mem.offset = 0 + + # PMR + if str(_embedded.radio_type).rstrip("\00") == "RT98U": + if mem.number >= 1 and mem.number <= 6: + PMR_FREQ = int(PMR_FREQS[mem.number - 1] * 1000000) + mem.freq = PMR_FREQ + mem.duplex = '' + mem.offset = 0 + else: + _mem.tx_off = 1 + mem.duplex = 'off' + mem.offset = 0 # set the occupied bitfield self._memobj.csetflag[cbyte].c[cbit] = 1 @@ -1059,7 +1060,10 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, _mem.name = mem.name.ljust(6)[:6] # Store the alpha tag # Set duplex bitfields - if mem.duplex == '+': + _mem.tx_off = 0 + if mem.duplex == 'off': # handle tx off + _mem.tx_off = 1 + elif mem.duplex == '+': _mem.duplex = DUPLEX_POSSPLIT elif mem.duplex == '-': _mem.duplex = DUPLEX_NEGSPLIT @@ -1074,11 +1078,6 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, LOG.error('%s: set_mem: unhandled duplex: %s' % (mem.name, mem.duplex)) - # handle tx off - _mem.tx_off = 0 - if mem.duplex == 'off': - _mem.tx_off = 1 - # Set the channel width - remember we promote 20kHz channels to FM # on import, so don't handle them here if mem.mode == 'FM': @@ -1116,11 +1115,28 @@ class Rt98BaseRadio(chirp_common.CloneModeRadio, _mem.rxinv = rxpol == "R" # set the power level - if mem.power == POWER_LEVELS[0]: + if _embedded.mode == 0: # PMR or FreeNet + if str(_embedded.radio_type).rstrip("\00") == "RT98U": + LOG.info('using PMR power levels') + _levels = PMR_POWER_LEVELS + if str(_embedded.radio_type).rstrip("\00") == "RT98V": + LOG.info('using FreeNet power levels') + _levels = FREENET_POWER_LEVELS + else: # COM or COMII + LOG.info('using general power levels') + _levels = POWER_LEVELS + + if mem.power is None: + _mem.txpower = TXPOWER_HIGH + elif mem.power == _levels[0]: _mem.txpower = TXPOWER_LOW - elif mem.power == POWER_LEVELS[1]: + elif _embedded.mode == 0: # PMR or FreeNet + LOG.info('FreeNet or PMR channel is not set to TX Power Low') + LOG.info('Setting channel to TX Power Low') + _mem.txpower = TXPOWER_LOW + elif mem.power == _levels[1]: _mem.txpower = TXPOWER_MED - elif mem.power == POWER_LEVELS[2]: + elif mem.power == _levels[2]: _mem.txpower = TXPOWER_HIGH else: LOG.error('%s: set_mem: unhandled power level: %s' % diff --git a/tests/Python3_Driver_Testing.md b/tests/Python3_Driver_Testing.md index 1cd21506..e39a3c78 100644 --- a/tests/Python3_Driver_Testing.md +++ b/tests/Python3_Driver_Testing.md @@ -273,7 +273,7 @@ | Retevis_RT9000D_66-88 | [@KC9HI](https://github.com/KC9HI) | 8-Dec-2022 | Yes | 0.00% | | Retevis_RT95 | [@KC9HI](https://github.com/KC9HI) | 13-Nov-2022 | Yes | 0.08% | | Retevis_RT95_VOX | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.15% | -| Retevis_RT98 | | | | 0.05% | +| Retevis_RT98 | [@KC9HI](https://github.com/KC9HI) | 14-Dec-2022 | Yes | 0.05% | | Rugged_RH5R-V2 | | | | 0.05% | | Sainsonic_AP510 | | | | 0.00% | | TDXone_TD-Q8A | | | | 0.02% | @@ -360,9 +360,9 @@ **Drivers:** 355 -**Tested:** 70% (249/106) (88% of usage stats) +**Tested:** 70% (250/105) (88% of usage stats) -**Byte clean:** 80% (284/71) +**Byte clean:** 80% (285/70) ## Meaning of this testing diff --git a/tests/py3_driver_testers.txt b/tests/py3_driver_testers.txt index 975d15e6..a920c697 100644 --- a/tests/py3_driver_testers.txt +++ b/tests/py3_driver_testers.txt @@ -216,6 +216,7 @@ Retevis_RT76,@KC9HI,30-Nov-2022 Retevis_RT85,@KC9HI,5-Dec-2022 Retevis_RT95,@KC9HI,13-Nov-2022 Retevis_RT95_VOX,+Retevis_RT95,13-Nov-2022 +Retevis_RT98,@KC9HI,14-Dec-2022 Retevis_RT9000D_136-174,@KC9HI,8-Dec-2022 Retevis_RT9000D_220-260,@KC9HI,8-Dec-2022 Retevis_RT9000D_400-490,@KC9HI,8-Dec-2022