From 2096c037c681cd170e9fc38c544b523fae18e4a1 Mon Sep 17 00:00:00 2001 From: Jim Unroe Date: Mon, 5 Aug 2024 15:40:35 -0400 Subject: [PATCH 1/2] retevis_rt21.py: fix incorrect DTCS mask - fixes #11467 Some (actually most) models use a different bit mask than the original RT21. This patch allows the mask to be specified. --- chirp/drivers/retevis_rt21.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/chirp/drivers/retevis_rt21.py b/chirp/drivers/retevis_rt21.py index 4e7b5918f..881e317bd 100644 --- a/chirp/drivers/retevis_rt21.py +++ b/chirp/drivers/retevis_rt21.py @@ -764,6 +764,7 @@ class RT21Radio(chirp_common.CloneModeRadio): _ack_1st_block = True _skipflags = True _reserved = False + _mask = 0x2000 # bit mask to identify DTCS tone decoding is used _gmrs = _frs = _pmr = False _echo = False @@ -842,7 +843,7 @@ def _get_dcs(val): return code, pol tpol = False - if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2000: + if _mem.tx_tone != 0xFFFF and _mem.tx_tone > self._mask: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" @@ -853,7 +854,7 @@ def _get_dcs(val): txmode = "" rpol = False - if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2000: + if _mem.rx_tone != 0xFFFF and _mem.rx_tone > self._mask: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" @@ -1121,7 +1122,7 @@ def get_memory(self, number): def _set_tone(self, mem, _mem): def _set_dcs(code, pol): - val = int("%i" % code, 8) + 0x2000 + val = int("%i" % code, 8) + self._mask if pol == "R": val += 0x8000 return val @@ -1894,6 +1895,7 @@ class RB26Radio(RT21Radio): _ack_1st_block = False _skipflags = True _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _gmrs = True _ranges = [ @@ -1924,6 +1926,7 @@ class RT76Radio(RT21Radio): _ack_1st_block = False _skipflags = False _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _gmrs = True _ranges = [ @@ -2005,6 +2008,7 @@ class RB23Radio(RT21Radio): _ack_1st_block = False _skipflags = True _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _gmrs = True _ranges = [ @@ -2037,6 +2041,7 @@ class RT19Radio(RT21Radio): _ack_1st_block = False _skipflags = False _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _frs = True _ranges = [ @@ -2065,6 +2070,7 @@ class RT619Radio(RT19Radio): 0x100, # memory start _upper # number of freqhops ) + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _frs = False _pmr = True @@ -2092,6 +2098,7 @@ class AR63Radio(RT21Radio): _ack_1st_block = False _skipflags = True _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _gmrs = False _ranges = [ @@ -2125,6 +2132,7 @@ class RT40BRadio(RT21Radio): _ack_1st_block = False _skipflags = True _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _gmrs = True _echo = True @@ -2156,6 +2164,7 @@ class RB28BRadio(RT21Radio): _ack_1st_block = False _skipflags = False _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _frs = True _ranges = [ @@ -2179,6 +2188,7 @@ class RB628BRadio(RB28BRadio): _magic = b"PHOGR\x09\xB2" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 16 + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _frs = False _pmr = True @@ -2203,6 +2213,7 @@ class RT86Radio(RT21Radio): _ack_1st_block = False _skipflags = True _reserved = True + _mask = 0x2800 # bit mask to identify DTCS tone decoding is used _ranges = [ (0x0000, 0x01A0), From e81cc1612459e2cce310a5e7d4a3b353d0c4e587 Mon Sep 17 00:00:00 2001 From: Jim Unroe Date: Tue, 6 Aug 2024 20:05:07 -0400 Subject: [PATCH 2/2] retevis_rt21.py: Add Retevis RB89 - fixes #11465 --- chirp/drivers/retevis_rt21.py | 60 ++++++++++++++++++++++++++++---- tests/Python3_Driver_Testing.md | 7 ++-- tests/images/Retevis_RB89.img | Bin 0 -> 1017 bytes tests/py3_driver_testers.txt | 1 + 4 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 tests/images/Retevis_RB89.img diff --git a/chirp/drivers/retevis_rt21.py b/chirp/drivers/retevis_rt21.py index 881e317bd..582c6371b 100644 --- a/chirp/drivers/retevis_rt21.py +++ b/chirp/drivers/retevis_rt21.py @@ -176,6 +176,7 @@ u8 channel_8[13]; // 0070-007C u8 unknown_8; // 007D u8 tail; // QT/DQT Tail(inverted) 007E + u8 tailmode; // QT/DQT Tail Mode 007F } settings; #seekto 0x01F0; @@ -528,6 +529,7 @@ PFKEY28B_LIST = ["None", "Scan", "Warn", "TX Power", "Monitor"] PFKEY86_LIST = ["None", "Monitor", "Lamp", "Warn", "VOX", "VOX Delay", "Key Lock", "TX Power", "Scan"] +PFKEY89_LIST = PFKEY_LIST + ["Bluetooth ON/OFF"] POT_LIST = ["Channel Type", "Volume Type"] SAVE_LIST = ["Standard", "Super"] SAVEM_LIST = ["1-5", "1-8", "1-10", "1-15"] @@ -977,8 +979,10 @@ def get_memory(self, number): mem.extra.append(rset) if self.MODEL == "RB26" or self.MODEL == "RT76" \ - or self.MODEL == "RB23" or self.MODEL == "AR-63": - if self.MODEL == "RB26" or self.MODEL == "RB23": + or self.MODEL == "RB23" or self.MODEL == "AR-63" \ + or self.MODEL == "RB89": + if self.MODEL == "RB26" or self.MODEL == "RB23" \ + or self.MODEL == "RB89": rs = RadioSettingValueBoolean(_mem.bcl) rset = RadioSetting("bcl", "Busy Channel Lockout", rs) mem.extra.append(rset) @@ -1409,8 +1413,10 @@ def apply_pfkey_listvalue(setting, obj): "RT76", "RT86", "RT619", + "RB89", ]: - if self.MODEL == "RB26" or self.MODEL == "RB23": + if self.MODEL == "RB26" or self.MODEL == "RB23" \ + or self.MODEL == "RB89": _settings2 = self._memobj.settings2 _settings3 = self._memobj.settings3 @@ -1466,7 +1472,8 @@ def apply_pfkey_listvalue(setting, obj): rset = RadioSetting("voice", "Voice Annumciation", rs) basic.append(rset) - if self.MODEL == "RB26" or self.MODEL == "RB23": + if self.MODEL == "RB26" or self.MODEL == "RB23" \ + or self.MODEL == "RB89": rs = RadioSettingValueList(VOICE_LIST2, VOICE_LIST2[_settings.voice]) rset = RadioSetting("voice", "Voice Annumciation", rs) @@ -1477,7 +1484,7 @@ def apply_pfkey_listvalue(setting, obj): rset = RadioSetting("chnumberd", "Channel Number Enable", rs) basic.append(rset) - if self.MODEL == "RT86": + if self.MODEL == "RT86" or self.MODEL == "RB89": rs = RadioSettingValueList(SPECIAL_LIST, SPECIAL_LIST[_settings.tailmode]) rset = RadioSetting("tailmode", "QT/DQT Tail Mode", rs) @@ -1494,6 +1501,7 @@ def apply_pfkey_listvalue(setting, obj): if self.MODEL in ["RB23", "RB26", "RT86", + "RB89", ]: rs = RadioSettingValueBoolean(not _settings.tail) rset = RadioSetting("tail", "QT/DQT Tail", rs) @@ -1537,7 +1545,8 @@ def apply_pfkey_listvalue(setting, obj): rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) - if self.MODEL == "RB26" or self.MODEL == "RB23": + if self.MODEL == "RB26" or self.MODEL == "RB23" \ + or self.MODEL == "RB89": rs = RadioSettingValueBoolean(_settings3.vox) rset = RadioSetting("settings3.vox", "Vox Function", rs) basic.append(rset) @@ -1693,6 +1702,17 @@ def apply_pfkey_listvalue(setting, obj): rset = RadioSetting("pf2", "PF2 Key Set", rs) basic.append(rset) + if self.MODEL == "RB89": + rs = RadioSettingValueList(PFKEY89_LIST, + PFKEY89_LIST[_settings.pf1]) + rset = RadioSetting("pf1", "PF1 Key Set", rs) + basic.append(rset) + + rs = RadioSettingValueList(PFKEY89_LIST, + PFKEY89_LIST[_settings.pf2]) + rset = RadioSetting("pf2", "PF2 Key Set", rs) + basic.append(rset) + if self.MODEL == "RB28B" or self.MODEL == "RB628B": rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) @@ -2222,3 +2242,31 @@ class RT86Radio(RT21Radio): def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT86, self._mmap) + + +@directory.register +class RB89Radio(RT21Radio): + """RETEVIS RB89""" + VENDOR = "Retevis" + MODEL = "RB89" + BLOCK_SIZE = 0x20 + BLOCK_SIZE_UP = 0x10 + + POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), + chirp_common.PowerLevel("Low", watts=0.50)] + + _magic = b"PHOGR" + b"\x01" + b"0" + _fingerprint = [b"P32073" + b"\x01\xFF", ] + _upper = 30 + _ack_1st_block = False + _skipflags = True + _reserved = True + _gmrs = False # sold as GMRS radio but supports full band TX/RX + + _ranges = [ + (0x0000, 0x0330), + ] + _memsize = 0x0340 + + def process_mmap(self): + self._memobj = bitwise.parse(MEM_FORMAT_RB26, self._mmap) diff --git a/tests/Python3_Driver_Testing.md b/tests/Python3_Driver_Testing.md index 5a9a1d77b..a341caef6 100644 --- a/tests/Python3_Driver_Testing.md +++ b/tests/Python3_Driver_Testing.md @@ -323,6 +323,7 @@ | Retevis_RB75 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.02% | | Retevis_RB85 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.02% | | Retevis_RB87 | [@KC9HI](https://github.com/KC9HI) | 10-Mar-2023 | Yes | | +| Retevis_RB89 | [@KC9HI](https://github.com/KC9HI) | 6-Aug-2024 | Yes | | | Retevis_RT1 | [@KC9HI](https://github.com/KC9HI) | 11-Dec-2022 | Yes | 0.08% | | Retevis_RT15 | [@KC9HI](https://github.com/KC9HI) | 18-Feb-2023 | Yes | 0.00% | | Retevis_RT16 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.02% | @@ -467,11 +468,11 @@ | Zastone_ZT-X6 | [Implied by Retevis_RT22](#user-content-Retevis_RT22) | 9-Dec-2022 | Yes | 0.11% | ## Stats -**Drivers:** 464 +**Drivers:** 465 -**Tested:** 87% (406/58) (93% of usage stats) +**Tested:** 87% (407/58) (93% of usage stats) -**Byte clean:** 91% (425/39) +**Byte clean:** 91% (426/39) ## Meaning of this testing diff --git a/tests/images/Retevis_RB89.img b/tests/images/Retevis_RB89.img new file mode 100644 index 0000000000000000000000000000000000000000..52050f606844cde7a357c2030a65a432d878a721 GIT binary patch literal 1017 zcmd6ju}f}xUHQmGz*p|09h%@yefLzn7h#zh@|o!_ZHp&?XU})V~fAfQ{XWTNZH-7?u!dpg*n7JC4x>xS$J}d@9Ps^vJ zoS(50mwH@0E{HWSME8|t7Yxl8^Q<0&p{w#$*<@OeF&%!LKP(@XCU#5%L-Zcxm-#V& z!J_jiKgX0md#_V|jwwIKl%HeDPjY^lpJO>gZpk?$R<`hMGA8+7uH0z<;db@YOdsEh zy$lb<>B(OajoHdU>YV%D#>np