# HG changeset patch
# User Brad Schuler <brad@schuler.ws>
# Date 1604820401 25200
# Sun Nov 08 00:26:41 2020 -0700
# Node ID de3e3a50889fde690f5f222375fa941b421f1d87
# Parent f13da43b1125af02a6dbc129a6e9e33760adc9a7
[AnyTone 5888UV] Add extra channel attributes
Related to issue 8407
Dependent upon earlier patch [AnyTone 5888UV] Add limited squelch mode & fix file identifier
Add the following channel attributes
- Tuning steps
- Duplex: off
- Busy channel lockout
- Optional signal selection (DTMF, 2-tone, 5-tone)
- Reverse
- Compander
- Talkaround
- PTT ID
- Squelch with optional signal
- Use custom CTCSS for Tx and/or Rx
diff -r f13da43b1125 -r de3e3a50889f chirp/drivers/anytone.py
--- a/chirp/drivers/anytone.py Sat Nov 07 23:27:32 2020 -0700
+++ b/chirp/drivers/anytone.py Sun Nov 08 00:26:41 2020 -0700
@@ -53,12 +53,15 @@
rxinv:1,
txinv:1,
channel_width:2,
- unknownB:2;
- u8 unknown8:3,
+ rev:1,
+ txoff:1;
+ u8 talkaround:1,
+ compander:1,
+ unknown8:1,
is_am:1,
power:2,
duplex:2;
- u8 unknown4:4,
+ u8 dtmfSlotNum:4,
rxtmode:2,
txtmode:2;
u8 unknown5:2,
@@ -67,12 +70,23 @@
rxtone:6;
u8 txcode;
u8 rxcode;
- u8 unknown7[2];
+ u8 unknown10:2,
+ pttid:2,
+ unknown11:2,
+ bclo:2;
+ u8 unknown7;
u8 unknown9:5,
sqlMode:3; // [Carrier, CTCSS/DCS Tones, Opt Sig Only, Tones & Opt Sig, Tones or Opt Sig]
- u8 unknown2[4];
+ u8 unknown21:6,
+ optsig:2;
+ u8 unknown22:3,
+ twotone:5;
+ u8 unknown23:1,
+ fivetone:7;
+ u8 unknown24:4,
+ scramble:4;
char name[7];
- u8 unknownZ[2];
+ ul16 custtone;
};
#seekto 0x0030;
@@ -320,13 +334,22 @@
TONES = [62.5] + list(chirp_common.TONES)
TMODES = ['', 'Tone', 'DTCS', '']
-DUPLEXES = ['', '-', '+', '']
+DUPLEXES = ['', '-', '+', 'off']
MODES = ["FM", "FM", "NFM"]
POWER_LEVELS = [chirp_common.PowerLevel("High", watts=50),
chirp_common.PowerLevel("Mid1", watts=25),
chirp_common.PowerLevel("Mid2", watts=10),
chirp_common.PowerLevel("Low", watts=5)]
+BCLO = ['Off', 'Repeater', 'Busy']
+DTMF_SLOTS = ['M%d' % x for x in range(1, 17)]
+# Chose not to expose SCRAMBLE_CODES = ['Off'] + ['%d' % x for x in range(1, 10)] + ['Define 1', 'Define 2']
+TONE2_SLOTS = ['%d' % x for x in range(0, 24)]
+TONE5_SLOTS = ['%d' % x for x in range(0, 100)]
SQL_MODES = ["Carrier", "CTCSS/DCS", "Opt Sig Only", "Tones AND Sig", "Tones OR Sig"]
+OPT_SIG_SQL = ["Off"] + SQL_MODES[2:]
+OPT_SIGS = ['Off', 'DTMF', '2Tone', '5Tone']
+PTT_IDS = ['Off', 'Begin', 'End', 'Begin & End']
+TUNING_STEPS = [2.5, 5, 6.25, 10, 12.5, 15, 20, 25, 30, 50]
@directory.register
@@ -356,8 +379,8 @@
rf.has_settings = True
rf.has_bank = False
rf.has_cross = True
- rf.valid_tuning_steps = [2.5, 5, 6.25, 10, 12.5, 15, 20, 25, 30, 50]
- rf.has_tuning_step = False
+ rf.valid_duplexes = DUPLEXES
+ rf.valid_tuning_steps = TUNING_STEPS
rf.has_rx_dtcs = True
rf.valid_skips = ["", "S", "P"]
rf.valid_modes = ["FM", "NFM", "AM"]
@@ -424,6 +447,10 @@
mem.name = str(_mem.name).rstrip()
mem.duplex = DUPLEXES[_mem.duplex]
mem.mode = _mem.is_am and "AM" or MODES[_mem.channel_width]
+ mem.tuning_step = TUNING_STEPS[_mem.tune_step]
+
+ if _mem.txoff:
+ mem.duplex = DUPLEXES[3]
rxtone = txtone = None
rxmode = TMODES[_mem.rxtmode]
@@ -431,12 +458,22 @@
rxmode = TMODES.index('')
txmode = TMODES[_mem.txtmode]
if txmode == "Tone":
- txtone = TONES[_mem.txtone]
+ # If custom tone is being used, show as 88.5 (and set checkbox in extras)
+ # Future: Improve chirp_common, so I can add "CUSTOM" into TONES
+ if _mem.txtone == len(TONES):
+ txtone = 88.5
+ else:
+ txtone = TONES[_mem.txtone]
elif txmode == "DTCS":
txtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem,
'tx')]
if rxmode == "Tone":
- rxtone = TONES[_mem.rxtone]
+ # If custom tone is being used, show as 88.5 (and set checkbox in extras)
+ # Future: Improve chirp_common, so I can add "CUSTOM" into TONES
+ if _mem.rxtone == len(TONES):
+ rxtone = 88.5
+ else:
+ rxtone = TONES[_mem.rxtone]
elif rxmode == "DTCS":
rxtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem,
'rx')]
@@ -451,6 +488,53 @@
mem.skip = _flg.get_skip() and "S" or _flg.get_pskip() and "P" or ""
mem.power = POWER_LEVELS[_mem.power]
+ mem.extra = RadioSettingGroup("Extra", "extra")
+
+ rs = RadioSetting("rev", "Reverse", RadioSettingValueBoolean(_mem.rev))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(_mem.compander))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("talkaround", "Talkaround", RadioSettingValueBoolean(_mem.talkaround))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTT_IDS, PTT_IDS[_mem.pttid]))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("bclo", "Busy Channel Lockout", RadioSettingValueList(BCLO, BCLO[_mem.bclo]))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("optsig", "Optional Signaling", RadioSettingValueList(OPT_SIGS, OPT_SIGS[_mem.optsig]))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("OPTSIGSQL", "Squelch w/Opt Signaling", RadioSettingValueList(OPT_SIG_SQL, SQL_MODES[_mem.sqlMode] if SQL_MODES[_mem.sqlMode] in OPT_SIG_SQL else "Off"))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("dtmfSlotNum", "DTMF", RadioSettingValueList(DTMF_SLOTS, DTMF_SLOTS[_mem.dtmfSlotNum]))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("twotone", "2-Tone", RadioSettingValueList(TONE2_SLOTS, TONE2_SLOTS[_mem.twotone]))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("fivetone", "5-Tone", RadioSettingValueList(TONE5_SLOTS, TONE5_SLOTS[_mem.fivetone]))
+ mem.extra.append(rs)
+
+ # Chose not to expose scramble
+ # rs = RadioSetting("scramble", "Scrambler Switch", RadioSettingValueList(SCRAMBLE_CODES, SCRAMBLE_CODES[_mem.scramble]))
+ # mem.extra.append(rs)
+
+ # Memory properties dialog is only capable of Boolean and List RadioSettingValue classes, so cannot configure it
+ # rs = RadioSetting("custtone", "Custom CTCSS", RadioSettingValueFloat(min(TONES), max(TONES), _mem.custtone and _mem.custtone / 10 or 151.1, 0.1, 1))
+ # mem.extra.append(rs)
+ custToneStr = chirp_common.format_freq(_mem.custtone)
+
+ rs = RadioSetting("CUSTTONETX", "Use Custom CTCSS (%s) for Tx" % custToneStr, RadioSettingValueBoolean(_mem.txtone == len(TONES)))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("CUSTTONERX", "Use Custom CTCSS (%s) for Rx" % custToneStr, RadioSettingValueBoolean(_mem.rxtone == len(TONES)))
+ mem.extra.append(rs)
+
return mem
def set_memory(self, mem):
@@ -465,7 +549,13 @@
_mem.offset = mem.offset / 100
_mem.name = mem.name.ljust(7)
_mem.is_am = mem.mode == "AM"
- _mem.duplex = DUPLEXES.index(mem.duplex)
+ _mem.tune_step = TUNING_STEPS.index(mem.tuning_step)
+ if mem.duplex == "off":
+ _mem.duplex = DUPLEXES.index("")
+ _mem.txoff = 1
+ else:
+ _mem.duplex = DUPLEXES.index(mem.duplex)
+ _mem.txoff = 0
try:
_mem.channel_width = MODES.index(mem.mode)
@@ -503,6 +593,25 @@
else:
_mem.power = 0
+ for setting in mem.extra:
+ if setting.get_name() == "ignore":
+ LOG.debug("*** ignore: %s" % str(setting.value))
+ # Future: elif setting.get_name() == "custtone":
+ # Future: setattr(_mem, "custtone", setting.value.get_value() * 10)
+ elif setting.get_name() == "OPTSIGSQL":
+ if str(setting.value) != "Off":
+ _mem.sqlMode = SQL_MODES.index(str(setting.value))
+ elif setting.get_name() == "CUSTTONETX":
+ if setting.value:
+ _mem.txtone = len(TONES)
+ elif setting.get_name() == "CUSTTONERX":
+ if setting.value:
+ _mem.rxtone = len(TONES)
+ else:
+ setattr(_mem, setting.get_name(), setting.value)
+
+ return mem
+
def get_settings(self):
_settings = self._memobj.settings
basic = RadioSettingGroup("basic", "Basic")