diff --git a/chirp/drivers/baofeng_uv17.py b/chirp/drivers/baofeng_uv17.py index 09b7da0ec..52cd3219a 100644 --- a/chirp/drivers/baofeng_uv17.py +++ b/chirp/drivers/baofeng_uv17.py @@ -196,7 +196,7 @@ class UV17(baofeng_uv17Pro.UV17Pro): LIST_MODE = ["Name", "Frequency"] CHANNELS = 999 - MEM_DEFS = """ + CHANNEL_DEF = """ struct channel { lbcd rxfreq[4]; lbcd txfreq[4]; @@ -215,6 +215,8 @@ class UV17(baofeng_uv17Pro.UV17Pro): scan:1; u8 unknown4; }; + """ + MEM_DEFS = """ struct channelname { char name[11]; }; @@ -320,7 +322,7 @@ class UV17(baofeng_uv17Pro.UV17Pro): struct ani ani; """ - MEM_FORMAT = MEM_DEFS + MEM_LAYOUT + MEM_FORMAT = CHANNEL_DEF + MEM_DEFS + MEM_LAYOUT def _make_frame(self, cmd, addr, length, data=""): """Pack the info in the header format""" diff --git a/chirp/drivers/baofeng_uv17Pro.py b/chirp/drivers/baofeng_uv17Pro.py index 99e7af1ed..c2cdf78c7 100644 --- a/chirp/drivers/baofeng_uv17Pro.py +++ b/chirp/drivers/baofeng_uv17Pro.py @@ -361,7 +361,7 @@ class UV17Pro(bfc.BaofengCommonHT): u8 rpttailclear; u8 rpttaildet; u8 roger; - u8 unknown2; + u8 a_or_b_selected; // a=0, b=1 u8 fmenable; u8 chbworkmode:4, chaworkmode:4; diff --git a/chirp/drivers/btech.py b/chirp/drivers/btech.py index d40017538..f5a384881 100644 --- a/chirp/drivers/btech.py +++ b/chirp/drivers/btech.py @@ -2548,12 +2548,16 @@ def apply_dmtf_listvalue(setting, obj): val])) dtmf_dec_settings.append(line) else: + if _mem.dtmf_settings.resettime > 0x4F: + val = 0x4F + else: + val = _mem.dtmf_settings.resettime line = RadioSetting( "dtmf_settings.resettime", "Reset time", RadioSettingValueList(LIST_5TONE_RESET, LIST_5TONE_RESET[ - _mem.dtmf_settings.resettime])) + val])) dtmf_dec_settings.append(line) if _mem.dtmf_settings.delayproctime > 0x27: diff --git a/chirp/drivers/ga510.py b/chirp/drivers/ga510.py index 13d426e8f..1642a9011 100644 --- a/chirp/drivers/ga510.py +++ b/chirp/drivers/ga510.py @@ -1141,6 +1141,26 @@ class RadioddityGA510v2(baofeng_uv17.UV17): LIST_MODE = ["Name", "Frequency"] CHANNELS = 128 + CHANNEL_DEF = """ + struct channel { + lbcd rxfreq[4]; + lbcd txfreq[4]; + u8 unused1; + ul16 rxtone; + ul16 txtone; + u8 unknown1:1, + bcl:1, + pttid:2, + unknown2:1, + wide:1, + lowpower:2; + u8 scode:4, + unknown3:3, + scan:1; + u8 unknown4; + }; + """ + MEM_LAYOUT = """ #seekto 0x1000; struct settings settings; @@ -1157,6 +1177,6 @@ class RadioddityGA510v2(baofeng_uv17.UV17): #seekto 0x400B; struct channelname names1[128]; """ - MEM_FORMAT = baofeng_uv17.UV17.MEM_DEFS + MEM_LAYOUT + MEM_FORMAT = CHANNEL_DEF + baofeng_uv17.UV17.MEM_DEFS + MEM_LAYOUT _has_workmode_support = False diff --git a/chirp/drivers/icf.py b/chirp/drivers/icf.py index c0acbd668..843204dfe 100644 --- a/chirp/drivers/icf.py +++ b/chirp/drivers/icf.py @@ -1034,7 +1034,7 @@ def get_bank_model(self): return None -def warp_byte_size(inbytes, obw=8, ibw=8): +def warp_byte_size(inbytes, obw=8, ibw=8, iskip=0, opad=0): """Convert between "byte sizes". This will pack N-bit characters into a sequence of 8-bit bytes, @@ -1042,17 +1042,23 @@ def warp_byte_size(inbytes, obw=8, ibw=8): ibw (input bit width) is the width of the storage obw (output bit width) is the width of the characters to extract + iskip is the number of input padding bits to skip + opad is the number of output zero padding bits to add ibw=8,obw=7 will pull seven-bit characters from a sequence of bytes ibw=7,obw=8 will pack seven-bit characters into a sequence of bytes """ if isinstance(inbytes, str): inbytes = [ord(x) for x in inbytes] - outbit = 0 + outbit = opad tmp = 0 stripmask = 1 << (ibw - 1) for byte in inbytes: inbit = 0 + while iskip: + byte = (byte << 1) & 0xFF + inbit += 1 + iskip -= 1 for i in range(0, max(obw, ibw - inbit)): if inbit == ibw: # Move to next char diff --git a/chirp/drivers/tdh8.py b/chirp/drivers/tdh8.py index c2adf7cce..1d44e9159 100644 --- a/chirp/drivers/tdh8.py +++ b/chirp/drivers/tdh8.py @@ -741,14 +741,12 @@ # AB CHANNEL A_OFFSET = ["Off", "-", "+"] -A_TX_POWER = ["Low", "Mid", "High"] A_BAND = ["Wide", "Narrow"] A_BUSYLOCK = ["Off", "On"] A_SPEC_QTDQT = ["Off", "On"] A_WORKMODE = ["VFO", "VFO+CH", "CH Mode"] B_OFFSET = ["Off", "-", "+"] -B_TX_POWER = ["Low", "Mid", "High"] B_BAND = ["Wide", "Narrow"] B_BUSYLOCK = ["Off", "On"] B_SPEC_QTDQT = ["Off", "On"] @@ -1719,9 +1717,15 @@ def _filter(name): A_OFFSET, A_OFFSET[_vfoa.offset])) abblock.append(rs) + try: + self._tx_power[_vfoa.lowpower] + cur_a_power = _vfoa.lowpower + except IndexError: + cur_a_power = 0 rs = RadioSetting("lowpower", "A TX Power", RadioSettingValueList( - A_TX_POWER, A_TX_POWER[_vfoa.lowpower])) + [str(x) for x in self._tx_power], + str(self._tx_power[cur_a_power]))) abblock.append(rs) rs = RadioSetting("wide", "A Band", @@ -1781,9 +1785,15 @@ def _filter(name): B_OFFSET, B_OFFSET[_vfob.offsetb])) abblock.append(rs) + try: + self._tx_power[_vfob.lowpowerb] + cur_b_power = _vfob.lowpowerb + except IndexError: + cur_b_power = 0 rs = RadioSetting("lowpowerb", "B TX Power", RadioSettingValueList( - B_TX_POWER, B_TX_POWER[_vfob.lowpowerb])) + [str(x) for x in self._tx_power], + str(self._tx_power[cur_b_power]))) abblock.append(rs) rs = RadioSetting("wideb", "B Band", @@ -2465,8 +2475,17 @@ class TDH8_HAM(TDH8): MODEL = "TD-H8-HAM" ident_mode = b'P31185\xff\xff' _ham = True + _rxbands = [(136000000, 143999000), (149000001, 174000000), + (400000000, 419999000), (451000001, 521000000)] _txbands = [(144000000, 149000000), (420000000, 451000000)] + def check_set_memory_immutable_policy(self, existing, new): + # Immutable duplex handling is done in set_memory, so no need + # to ever obsess over it here. + if 'duplex' in existing.immutable: + existing.immutable.remove('duplex') + super().check_set_memory_immutable_policy(existing, new) + @directory.register @directory.detected_by(TDH8) diff --git a/chirp/share/model_alias_map.yaml b/chirp/share/model_alias_map.yaml index 2b1bdd2a0..cde22e1d9 100644 --- a/chirp/share/model_alias_map.yaml +++ b/chirp/share/model_alias_map.yaml @@ -227,6 +227,8 @@ R&L Electronics: Radioddity: - alt: Radioddity UV-5G model: UV-5X +- alt: AnyTone 5888UV + model: DB50 Radtel: - alt: Retevis RT22 model: RT-10 diff --git a/tests/unit/test_chirp_common.py b/tests/unit/test_chirp_common.py index c0dd4ecd4..60f068d36 100644 --- a/tests/unit/test_chirp_common.py +++ b/tests/unit/test_chirp_common.py @@ -769,6 +769,7 @@ class TestOverrideRules(base.BaseTest): 'Baofeng_5RM', 'Baofeng_K5-Plus', 'Radtel_RT-730', + 'TIDRADIO_TD-H8-HAM', ] def _test_radio_override_immutable_policy(self, rclass): diff --git a/tests/unit/test_icf.py b/tests/unit/test_icf.py index 08bd74d04..cc30ee23b 100644 --- a/tests/unit/test_icf.py +++ b/tests/unit/test_icf.py @@ -159,3 +159,32 @@ def test_pack(self): f = icf.IcfFrame(icf.ADDR_PC, icf.ADDR_RADIO, icf.CMD_CLONE_ID) f.payload = b'\x01\x02' self.assertEqual(b'\xfe\xfe\xee\xef\xe0\x01\x02\xfd', f.pack()) + + +class TestICFUtil(unittest.TestCase): + def test_warp_byte_size(self): + # 4-bit chars to 8-bit bytes + input = bytes([0x12, 0x34]) + output = bytes(icf.warp_byte_size(input, obw=4)) + self.assertEqual(b'\x01\x02\x03\x04', output) + + def test_warp_byte_size_skip(self): + # 4-bit chars to 8-bit bytes with 4 bits of padding ignored + input = bytes([0x12, 0x34]) + output = bytes(icf.warp_byte_size(input, obw=4, iskip=4)) + self.assertEqual(b'\x02\x03\x04', output) + + def test_warp_byte_size_pad(self): + # 8-bit bytes to 4-bit chars, with 4 bits of padding added + input = bytes([2, 3, 4]) + output = bytes(icf.warp_byte_size(input, ibw=4, opad=4)) + self.assertEqual(b'\x02\x34', output) + + def test_warp_byte_size_symmetric_padded(self): + # Make sure we can go from 8->4-> with padding and get back what we + # put in + ref = bytes([1, 2, 3, 4, 5, 6]) + stored = bytes(icf.warp_byte_size(bytes(ref), ibw=6, opad=4)) + self.assertEqual(5, len(bytes(stored))) + self.assertEqual(ref, + bytes(icf.warp_byte_size(stored, obw=6, iskip=4)))