---------- Forwarded message --------- From: Jim Unroe kc9hi@comcast.net Date: Wed, Mar 17, 2021 at 4:28 PM Subject: [PATCH 2 of 2] [AT-778UV] Add support model variants that include VOX To: Rock.Unroe@gmail.com
# HG changeset patch # User Jim Unroe rock.unroe@gmail.com # Date 1616012561 14400 # Wed Mar 17 16:22:41 2021 -0400 # Node ID 9d2390ab9a62918238bd5d1b59909e23287bd8ec # Parent 975f31e5d96e0e9d35327f0e8aa0756b9fac1132 [AT-778UV] Add support model variants that include VOX
This patch adds support for the new model variants that now include VOX:
Anytone AT-778UV VOX 3.0 Retevis RT95 VOX 2.0
fixes #8859
diff -r 975f31e5d96e -r 9d2390ab9a62 chirp/drivers/anytone778uv.py --- a/chirp/drivers/anytone778uv.py Wed Mar 17 16:18:15 2021 -0400 +++ b/chirp/drivers/anytone778uv.py Wed Mar 17 16:22:41 2021 -0400 @@ -1,5 +1,5 @@ # Copyright 2020 Joe Milbourn joe@milbourn.org.uk -# Copyright 2020 Jim Unroe rock.unroe@gmail.com +# Copyright 2021 Jim Unroe rock.unroe@gmail.com # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -106,8 +106,9 @@ u8 unknown7; u8 unknown8; u8 unknown9; - u8 unknown10; - char name[5]; + char name[6]; // the VOX models have 6-character names + // the original models only have 5-character names + // the 1st byte is not used and will always be 0x00 ul16 customctcss; } memory[200]; #seekto 0x1940; @@ -204,6 +205,10 @@ powerOnReset:1, // power on reset trfEnable:1, // trf enable knobMode:1; // knob mode + u8 unk321c:7, // 0x321C + voxOnOff:1; // vox on/off + u8 voxLevel; // 0x321D vox level + u8 voxDelay; // 0x321E vox delay } settings;
#seekto 0x3240; @@ -627,6 +632,8 @@ '''AnyTone 778UV and probably Retivis RT95 and others''' BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False + NAME_LENGTH = 5 + HAS_VOX = False
@classmethod def get_prompts(cls): @@ -648,7 +655,7 @@ rf.can_odd_split = True rf.has_name = True rf.has_offset = True - rf.valid_name_length = 5 + rf.valid_name_length = self.NAME_LENGTH rf.valid_duplexes = ['', '+', '-', 'split', 'off'] rf.valid_characters = CHARSET_ASCII_PLUS
@@ -723,7 +730,14 @@ mem.skip = 'S'
# set the name - mem.name = str(_mem.name).rstrip() # Set the alpha tag + if self.NAME_LENGTH == 5: + # original models with 5-character name length + temp_name = str(_mem.name) + # Strip the first character and set the alpha tag + mem.name = str(temp_name[1:6]).rstrip() + else: + # new VOX models with 6-character name length + mem.name = str(_mem.name).rstrip() # Set the alpha tag
# Convert your low-level frequency and offset to Hertz mem.freq = int(_mem.freq) * 10 @@ -922,7 +936,15 @@ _mem.freq = int(mem.freq / 10) _mem.offset = int(mem.offset / 10)
- _mem.name = mem.name.ljust(5)[:5] # Store the alpha tag + # Store the alpha tag + if self.NAME_LENGTH == 5: + # original models with 5-character name length + temp_name = mem.name.ljust(self.NAME_LENGTH)[:self.NAME_LENGTH] + # prefix the 5-character name with 0x00 to fit structure + _mem.name = temp_name.rjust(6, chr(00)) + else: + # new VOX models with 6-character name length + _mem.name = mem.name.ljust(self.NAME_LENGTH)[:self.NAME_LENGTH]
# TODO support busy channel lockout - disabled for now _mem.busy_channel_lockout = BUSY_CHANNEL_LOCKOUT_OFF @@ -1055,7 +1077,6 @@ _mem.unknown7 = 0x00 _mem.unknown8 = 0x00 _mem.unknown9 = 0x00 - _mem.unknown10 = 0x00
def get_settings(self): """Translate the MEM_FORMAT structs into setstuf in the UI""" @@ -1171,39 +1192,42 @@ function.append(rset)
# ON/OFF SET - # Power-on Password - rs = RadioSettingValueBoolean(_settings.powerOnPasswd) - rset = RadioSetting("settings.powerOnPasswd", "Power-on Password", rs) - function.append(rset) + # The Power-on Password feature is not available on models with VOX + if not self.HAS_VOX: + # Power-on Password + rs = RadioSettingValueBoolean(_settings.powerOnPasswd) + rset = RadioSetting("settings.powerOnPasswd", "Power-on Password", + rs) + function.append(rset)
- # Password - def _char_to_str(chrx): - """ Remove ff pads from char array """ - # chrx is char array - str1 = "" - for sx in chrx: - if int(sx) > 31 and int(sx) < 127: - str1 += chr(sx) - return str1 + # Password + def _char_to_str(chrx): + """ Remove ff pads from char array """ + # chrx is char array + str1 = "" + for sx in chrx: + if int(sx) > 31 and int(sx) < 127: + str1 += chr(sx) + return str1
- def _pswd_vfy(setting, obj, atrb): - """ Verify password is 1-6 chars, numbers 1-5 """ - str1 = str(setting.value).strip() # initial - str2 = filter(lambda c: c in '0123456789', str1) # valid chars - if str1 != str2: - # Two lines due to python 73 char limit - sx = "Bad characters in Password" - raise errors.RadioError(sx) - str2 = str1.ljust(6, chr(00)) # pad to 6 with 00's - setattr(obj, atrb, str2) - return + def _pswd_vfy(setting, obj, atrb): + """ Verify password is 1-6 chars, numbers 1-5 """ + str1 = str(setting.value).strip() # initial + str2 = filter(lambda c: c in '0123456789', str1) # valid chars + if str1 != str2: + # Two lines due to python 73 char limit + sx = "Bad characters in Password" + raise errors.RadioError(sx) + str2 = str1.ljust(6, chr(00)) # pad to 6 with 00's + setattr(obj, atrb, str2) + return
- sx = _char_to_str(_password.digits).strip() - rx = RadioSettingValueString(0, 6, sx) - sx = "Password (numerals 0-9)" - rset = RadioSetting("password.digits", sx, rx) - rset.set_apply_callback(_pswd_vfy, _password, "digits") - function.append(rset) + sx = _char_to_str(_password.digits).strip() + rx = RadioSettingValueString(0, 6, sx) + sx = "Password (numerals 0-9)" + rset = RadioSetting("password.digits", sx, rx) + rset.set_apply_callback(_pswd_vfy, _password, "digits") + function.append(rset)
# Menu 9 - Auto Power On rs = RadioSettingValueBoolean(_settings.autoPowerOn) @@ -1300,6 +1324,26 @@ rset = RadioSetting("settings.trfEnable", "TRF enable", rs) function.append(rset)
+ if self.HAS_VOX: + # VOX On/Off + rs = RadioSettingValueBoolean(_settings.voxOnOff) + rset = RadioSetting("settings.voxOnOff", + "VOX", rs) + function.append(rset) + + # VOX Delay + options = ["0.5 S", "1.0 S", "1.5 S", "2.0 S", "2.5 S", + "3.0 S", "3.5 S", "4.0 S", "4.5 S"] + rs = RadioSettingValueList(options, options[_settings.voxDelay]) + rset = RadioSetting("settings.voxDelay", "VOX delay", rs) + function.append(rset) + + # VOX Level + options = ["%s" % x for x in range(1, 10)] + rs = RadioSettingValueList(options, options[_settings.voxLevel]) + rset = RadioSetting("settings.voxLevel", "VOX Level", rs) + function.append(rset) + # Key Assignment pfkeys = RadioSettingGroup("pfkeys", "Key Assignment") group.append(pfkeys) @@ -1308,6 +1352,9 @@ "CAL", "TALK", "BND", "SFT", "MON", "DIR", "TRF", "RDW", "NULL"]
+ if self.HAS_VOX: + options.insert(16, "VOX") + # Key Mode 1 # P1 rs = RadioSettingValueList(options, options[_pfkeys.keyMode1P1 - 1]) @@ -1385,6 +1432,9 @@ options = ["V/M", "SQL", "VOL", "POW", "CDT", "REV", "SCN", "CAL", "TALK", "BND", "SFT", "MON", "DIR", "TRF", "RDW"]
+ if self.HAS_VOX: + options.insert(15, "VOX") + # PA rs = RadioSettingValueList(options, options[_settings.keyPA - 2]) rset = RadioSetting("settings.keyPA", @@ -1653,6 +1703,7 @@ LOG.debug(element.get_name()) raise
+# Original non-VOX models if has_future: @directory.register class AnyTone778UV(AnyTone778UVBase): @@ -1693,3 +1744,27 @@ # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'YCM04UV': ['V100']} + + +class AnyTone778UVvoxBase(AnyTone778UVBase): + '''AnyTone 778UV VOX, Retivis RT95 VOX and others''' + NAME_LENGTH = 6 + HAS_VOX = True + +# New VOX models +if has_future: + @directory.register + class AnyTone778UVvox(AnyTone778UVvoxBase): + VENDOR = "AnyTone" + MODEL = "778UV VOX" + # Allowed radio types is a dict keyed by model of a list of version + # strings + ALLOWED_RADIO_TYPES = {'778UV-P': ['V100']} + + @directory.register + class RetevisRT95vox(AnyTone778UVvoxBase): + VENDOR = "Retevis" + MODEL = "RT95 VOX" + # Allowed radio types is a dict keyed by model of a list of version + # strings + ALLOWED_RADIO_TYPES = {'RT95-P': ['V100']}