# HG changeset patch # User K. Arvanitis kosta@alumni.uvic.ca # Date 1421911819 28800 # Wed Jan 21 23:30:19 2015 -0800 # Node ID a14b91de7d5390bad00ec450f0546531b6bb268d # Parent 9ca5e99e7552a667b362e6f6dac67212fbbc6a34 [FT-60] Adding Support for Settings to Yaesu FT-60 Added support for most of the basic (but not all) settings avail. on the FT-60. Note: some settings map to the memory bank and are therefore not included in this list. Note: the list of settings and categories was taken from the user manual for this radio. Tested against the specific revision model no. FT-60R. Feature #1759 diff -r 9ca5e99e7552 -r a14b91de7d53 chirp/ft60.py --- a/chirp/ft60.py Sat Jan 17 10:10:54 2015 -0600 +++ b/chirp/ft60.py Wed Jan 21 23:30:19 2015 -0800 @@ -13,9 +13,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/.
-import time +import time, os from chirp import chirp_common, yaesu_clone, memmap, bitwise, directory from chirp import errors +from chirp.settings import RadioSetting, RadioSettingGroup, \ + RadioSettingValueInteger, RadioSettingValueList, \ + RadioSettingValueBoolean, RadioSettingValueString, \ + RadioSettingValueFloat from textwrap import dedent
ACK = "\x06" @@ -128,6 +132,78 @@
MEM_FORMAT = """ +#seekto 0x0024; +struct { + u8 apo; + u8 x25:3, + tot:5; + u8 x26; + u8 x27; + u8 x28:4, + rf_sql:4; + u8 x29:4, + int_cd:4; + u8 x2A:4, + int_mr:4; + u8 x2B:5, + lock:3; + u8 x2C:5, + dt_dly:3; + u8 x2D:7, + dt_spd:1; + u8 ar_bep; + u8 x2F:6, + lamp:2; + u8 x30:5, + bell:3; + u8 x31:5, + rxsave:3; + u8 x32; + u8 x33; + u8 x34; + u8 x35; + u8 x36; + u8 x37; + u8 wx_alt:1, + x38_1:3, + ar_int:1, + x38_5:3; + u8 x39:3, + ars:1, + vfo_bnd:1, + dcs_nr:2, + ssrch:1; + u8 pri_rvt:1, + x3A_1:1, + beep_sc:1, + edg_bep:1, + beep_key:1, + inet:2, + x3A_7:1; + u8 x3B_0:5, + scn_md:1, + x3B_6:2; + u8 x3C_0:2, + rev_hm:1, + mt_cl:1 + resume:2, + txsave:1, + pag_abk:1; + u8 x3D_0:1, + scn_lmp:1, + x3D_2:1, + bsy_led:1, + x3D_4:1, + tx_led:1, + x3D_6:2; + u8 x3E_0:2, + bclo:1, + x3E_3:5; +} settings; + +#seekto 0x09E; +ul16 mbs; + #seekto 0x0248; struct { u8 used:1, @@ -198,6 +274,10 @@ bank = chirp_common.Bank(self, "%i" % (i + 1), "Bank %i" % (i + 1)) bank.index = i banks.append(bank) + + #mbs = (self._radio._memobj.mbs >> i) & 1 + #print "Bank %i: mbs: %i " % (i, mbs) + return banks
def add_memory_to_mapping(self, memory, bank): @@ -277,6 +357,7 @@ rf.can_odd_split = True rf.has_ctone = False rf.has_bank = True + rf.has_settings = True rf.has_dtcs_polarity = False
return rf @@ -309,6 +390,229 @@ def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
+ def get_settings(self): + _settings = self._memobj.settings + + repeater = RadioSettingGroup("repeater", "Repeater Settings") + ctcss = RadioSettingGroup("ctcss", "CTCSS/DSC/DTMF Settings") + arts = RadioSettingGroup("arts", "ARTS Settings") + scan = RadioSettingGroup("scan", "Scan Settings") + power = RadioSettingGroup("power", "Power Saver Settings") + wires = RadioSettingGroup("wires", "WiRES(tm) Settings") + eai = RadioSettingGroup("eai", "EAI/EPCS Settings") + switch = RadioSettingGroup("switch", "Switch/Knob Settings") + misc = RadioSettingGroup("misc", "Miscellaneous Settings") + + setmode = RadioSettingGroup("top", "Set Mode", + repeater, ctcss, arts, scan, power, wires, eai, switch, misc) + + # APO + opts = [ "OFF" ] + [ "%0.1f" % (x * 0.5) for x in range(1, 24+1) ] + misc.append( RadioSetting("apo", "Automatic Power Off", + RadioSettingValueList(opts, opts[_settings.apo]))) + + # AR.BEP + opts = [ "OFF" ] + [ "INRANG" ] + [ "ALWAYS" ] + arts.append( RadioSetting("ar_bep", "ARTS Beep", + RadioSettingValueList(opts, opts[_settings.ar_bep]))) + + # AR.INT + opts = ["25 SEC"] + [ "15 SEC" ] + arts.append( RadioSetting("ar_int", "ARTS Polling Interval", + RadioSettingValueList(opts, opts[_settings.ar_int]))) + + # ARS + opts = [ "OFF" ] + [ "ON" ] + repeater.append( RadioSetting("ars", "Automatic Repeater Shift", + RadioSettingValueList(opts, opts[_settings.ars]))) + + # BCLO + opts = [ "OFF" ] + [ "ON" ] + misc.append( RadioSetting("bclo", "Bush Channel Lock-Out", + RadioSettingValueList(opts, opts[_settings.bclo]))) + + # BEEP + opts = [ "OFF" ] + [ "KEY" ] + [ "KEY+SC" ] + rs = RadioSetting("beep_key", "Enable the Beeper", + RadioSettingValueList(opts, opts[_settings.beep_key + _settings.beep_sc])) + def apply_beep(s, obj): + setattr(obj, "beep_key", (int(s.value) & 1) or ((int(s.value) >> 1) & 1)) + setattr(obj, "beep_sc", (int(s.value) >> 1) & 1) + rs.set_apply_callback(apply_beep, self._memobj.settings); + switch.append(rs) + + # BELL + opts = [ "OFF" ] + [ "1T" ] + [ "3T" ] + [ "5T" ] + [ "8T" ] + [ "CONT" ] + ctcss.append( RadioSetting("bell", "Bell Repetitions", + RadioSettingValueList(opts, opts[_settings.bell]))) + + # BSY.LED + opts = [ "ON" ] + [ "OFF" ] + misc.append( RadioSetting("bsy_led", "Busy LED", + RadioSettingValueList(opts, opts[_settings.bsy_led]))) + + # DCS.NR + opts = [ "TR/X N" ] + [ "RX R" ] + [ "TX R" ] + [ "T/RX R" ] + ctcss.append( RadioSetting("dcs_nr", ""Inverted" DCS Code Decoding", + RadioSettingValueList(opts, opts[_settings.dcs_nr]))) + + # DT.DLY + opts = [ "50 MS" ] + [ "100 MS" ] + [ "250 MS" ] + [ "450 MS" ] + \ + [ "750 MS" ]+ [ "1000 MS" ] + ctcss.append( RadioSetting("dt_dly", "DTMF Autodialer Delay Time", + RadioSettingValueList(opts, opts[_settings.dt_dly]))) + + # DT.SPD + opts = [ "50 MS" ] + [ "100 MS" ] + ctcss.append( RadioSetting("dt_spd", "DTMF Autodialer Sending Speed", + RadioSettingValueList(opts, opts[_settings.dt_spd]))) + + # EDG.BEP + opts = [ "OFF" ] + [ "ON" ] + misc.append( RadioSetting("edg_bep", "Band Edge Beeper", + RadioSettingValueList(opts, opts[_settings.edg_bep]))) + + # I.NET + opts = [ "OFF" ] + [ "COD" ]+ [ "MEM" ] + rs = RadioSetting("inet", "Internet Link Connection", + RadioSettingValueList(opts, opts[_settings.inet - 1])) + def apply_inet(s, obj): + setattr(obj, s.get_name(), int(s.value) + 1) + rs.set_apply_callback(apply_inet, self._memobj.settings); + wires.append(rs) + + # INT.CD + opts = [ "CODE 0" ] + [ "CODE 1" ] + [ "CODE 2" ] + [ "CODE 3" ] + [ "CODE 4" ] + \ + [ "CODE 5" ] + [ "CODE 6" ] + [ "CODE 7" ] + [ "CODE 8" ] + [ "CODE 9" ] + \ + [ "CODE A" ] + [ "CODE B" ] + [ "CODE C" ] + [ "CODE D" ] + [ "CODE E" ] + [ "CODE F" ] + wires.append( RadioSetting("int_cd", "Access Number for WiRES(TM)", + RadioSettingValueList(opts, opts[_settings.int_cd]))) + + # INT.MR + opts = [ "d1" ] + [ "d2" ] + [ "d3" ] + [ "d4" ] + [ "d5" ] + \ + [ "d6" ] + [ "d7" ] + [ "d8" ] + [ "d9" ] + wires.append( RadioSetting("int_mr", "Access Number (DTMF) for Non-WiRES(TM)", + RadioSettingValueList(opts, opts[_settings.int_mr]))) + + # LAMP + opts = [ "KEY" ] + [ "5SEC" ] + [ "TOGGLE" ] + switch.append( RadioSetting("lamp", "Lamp Mode", + RadioSettingValueList(opts, opts[_settings.lamp]))) + + # LOCK + opts = [ "LK KEY" ] + [ "LKDIAL" ] + [ "LK K+D" ] + [ "LK PTT" ] + [ "LP P+K" ] + \ + [ "LK P+D" ] + [ "LK ALL" ] + rs = RadioSetting("lock", "Control Locking", + RadioSettingValueList(opts, opts[_settings.lock - 1])) + def apply_lock(s, obj): + setattr(obj, s.get_name(), int(s.value) + 1) + rs.set_apply_callback(apply_lock, self._memobj.settings); + switch.append(rs) + + # M/T-CL + opts = [ "MONI" ] + [ "T-CALL" ] + switch.append( RadioSetting("mt_cl", "MONI Switch Function", + RadioSettingValueList(opts, opts[_settings.mt_cl]))) + + # PAG.ABK + opts = [ "OFF" ] + [ "ON" ] + eai.append( RadioSetting("pag_abk", "Paging Answer Back", + RadioSettingValueList(opts, opts[_settings.pag_abk]))) + + # RESUME + opts = [ "TIME" ] + [ "HOLD" ] + [ "BUSY" ] + scan.append( RadioSetting("resume", "Scan Resume Mode", + RadioSettingValueList(opts, opts[_settings.resume]))) + + # REV/HM + opts = [ "REV" ] + [ "HOME" ] + switch.append( RadioSetting("rev_hm", "HM/RV Key Function", + RadioSettingValueList(opts, opts[_settings.rev_hm]))) + + # RF.SQL + opts = [ "OFF" ] + [ "S-1" ] + [ "S-2" ] + [ "S-3" ] + [ "S-4" ] + \ + [ "S-5" ] + [ "S-6" ] + [ "S-8" ] + [ "S-FULL" ] + misc.append( RadioSetting("rf_sql", "RF Squelch Threshold", + RadioSettingValueList(opts, opts[_settings.rf_sql]))) + + # PRI.RVT + opts = [ "OFF" ] + [ "ON" ] + scan.append( RadioSetting("pri_rvt", "Priority Revert", + RadioSettingValueList(opts, opts[_settings.pri_rvt]))) + + # RXSAVE + opts = [ "OFF" ] + [ "200 MS" ] + [ "300 MS" ] + [ "500 MS" ] + [ "1 S" ] + [ "2 S" ] + power.append( RadioSetting("rxsave", "Receive Mode Batery Savery Interval", + RadioSettingValueList(opts, opts[_settings.rxsave]))) + + # S.SRCH + opts = [ "SINGLE" ] + [ "CONT" ] + misc.append( RadioSetting("ssrch", "Smart Search Sweep Mode", + RadioSettingValueList(opts, opts[_settings.ssrch]))) + + # SCN.MD + opts = [ "MEM" ] + [ "ONLY" ] + scan.append( RadioSetting("scn_md", "Memory Scan Channel Selection Mode", + RadioSettingValueList(opts, opts[_settings.scn_md]))) + + # SCN.LMP + opts = [ "OFF" ] + [ "ON" ] + scan.append( RadioSetting("scn_lmp", "Scan Lamp", + RadioSettingValueList(opts, opts[_settings.scn_lmp]))) + + # TOT + opts = [ "OFF" ] + [ "%dMIN" % (x) for x in range(1, 30+1) ] + misc.append( RadioSetting("tot", "Timeout Timer", + RadioSettingValueList(opts, opts[_settings.tot]))) + + # TX.LED + opts = [ "ON" ] + [ "OFF" ] + misc.append( RadioSetting("tx_led", "TX LED", + RadioSettingValueList(opts, opts[_settings.tx_led]))) + + # TXSAVE + opts = [ "OFF" ] + [ "ON" ] + power.append( RadioSetting("txsave", "Transmitter Battery Saver", + RadioSettingValueList(opts, opts[_settings.txsave]))) + + # VFO.BND + opts = [ "BAND" ] + [ "ALL" ] + misc.append( RadioSetting("vfo_bnd", "VFO Band Edge Limiting", + RadioSettingValueList(opts, opts[_settings.vfo_bnd]))) + + # WX.ALT + opts = [ "OFF" ] + [ "ON" ] + scan.append( RadioSetting("wx_alt", "Weather Alert Scan", + RadioSettingValueList(opts, opts[_settings.wx_alt]))) + + return setmode + + def set_settings(self, uisettings): + _settings = self._memobj.settings + for element in uisettings: + if not isinstance(element, RadioSetting): + self.set_settings(element) + continue + if not element.changed(): + continue + + try: + name = element.get_name() + value = element.value + obj = getattr(_settings, name) + + if element.has_apply_callback(): + print "Using apply callback" + element.run_apply_callback() + else: + setattr(_settings, name, value) + + if os.getenv("CHIRP_DEBUG"): + print "Setting %s: %s <= %s" % (name, obj, element.value) + except Exception, e: + print element.get_name() + raise + def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) + \ repr(self._memobj.flags[(number - 1) / 4]) + \ diff -r 9ca5e99e7552 -r a14b91de7d53 chirpui/settingsedit.py --- a/chirpui/settingsedit.py Sat Jan 17 10:10:54 2015 -0600 +++ b/chirpui/settingsedit.py Wed Jan 21 23:30:19 2015 -0800 @@ -45,6 +45,7 @@ self._table.show()
sw = gtk.ScrolledWindow() + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.add_with_viewport(self._table) sw.show()
@@ -144,9 +145,9 @@ if isinstance(element.value, list) and \ isinstance(element.value[0], settings.RadioSettingValueInteger): - arraybox = gtk.HBox(3, True) + arraybox = gtk.HBox(True, 3) else: - arraybox = gtk.VBox(3, True) + arraybox = gtk.VBox(True, 3) pack(arraybox, 1) arraybox.show()