[chirp_devel] [PATCH] ap510: add support for 20141215 firmware version. #2095

Tom Hayward
Sun Feb 15 23:28:41 PST 2015


# HG changeset patch
# User Tom Hayward <tom at tomh.us>
# Date 1424071566 28800
#      Sun Feb 15 23:26:06 2015 -0800
# Node ID d56104c20aa5714486b509d2ffe48458bd173cfd
# Parent  f74f533828ed82b85ab08301c8e4e6ae5faf5370
ap510: add support for 20141215 firmware version. #2095

diff -r f74f533828ed -r d56104c20aa5 chirp/ap510.py
--- a/chirp/ap510.py	Mon Feb 09 12:17:50 2015 -0800
+++ b/chirp/ap510.py	Sun Feb 15 23:26:06 2015 -0800
@@ -14,12 +14,22 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import struct
+from time import sleep
+
 from chirp import chirp_common, directory, errors, util
 from chirp.settings import RadioSetting, RadioSettingGroup, \
     RadioSettingValueInteger, RadioSettingValueList, \
     RadioSettingValueBoolean, RadioSettingValueString, \
-    RadioSettingValueFloat, RadioSettingValue, InvalidValueError, \
-    RadioSettings
+    InvalidValueError, RadioSettings
+
+
+def chunks(s, t):
+    """ Yield chunks of s in sizes defined in t."""
+    i = 0
+    for n in t:
+        yield s[i:i+n]
+        i += n
+
 
 def encode_base100(v):
     return (v / 100 << 8) + (v % 100)
@@ -29,31 +39,6 @@
     return 100 * (u16 >> 8 & 0xff) + (u16 & 0xff)
 
 
-def encode_smartbeacon(d):
-    return struct.pack(
-        ">7H",
-        encode_base100(d['lowspeed']),
-        encode_base100(d['slowrate']),
-        encode_base100(d['highspeed']),
-        encode_base100(d['fastrate']),
-        encode_base100(d['turnslope']),
-        encode_base100(d['turnangle']),
-        encode_base100(d['turntime']),
-    )
-
-
-def decode_smartbeacon(smartbeacon):
-    return dict(zip((
-        'lowspeed',
-        'slowrate',
-        'highspeed',
-        'fastrate',
-        'turnslope',
-        'turnangle',
-        'turntime',
-    ), map(decode_base100, struct.unpack(">7H", smartbeacon))))
-
-
 def drain(pipe):
     """Chew up any data waiting on @pipe"""
     for x in xrange(3):
@@ -66,10 +51,15 @@
 def enter_setup(pipe):
     """Put AP510 in configuration mode."""
     for x in xrange(30):
-        pipe.write("@SETUP")
+        if x % 2:
+            pipe.write("@SETUP")
+        else:
+            pipe.write("\r\nSETUP\r\n")
         s = pipe.read(64)
-        if s and "SETUP" in s:
+        if s and "\r\nSETUP" in s:
             return True
+        elif s and "SETUP" in s:
+            return False
     raise errors.RadioError('Radio did not respond.')
 
 
@@ -79,13 +69,16 @@
 
     status.msg = " Power on AP510 now, waiting "
     radio.status_fn(status)
-    enter_setup(radio.pipe)
+    new = enter_setup(radio.pipe)
 
     status.cur = 1
     status.max = 5
     status.msg = "Downloading"
     radio.status_fn(status)
-    radio.pipe.write("@DISP")
+    if new:
+        radio.pipe.write("\r\nDISP\r\n")
+    else:
+        radio.pipe.write("@DISP")
     buf = ""
 
     for status.cur in xrange(status.cur, status.max):
@@ -109,7 +102,7 @@
 
     status.msg = " Power on AP510 now, waiting "
     radio.status_fn(status)
-    enter_setup(radio.pipe)
+    new = enter_setup(radio.pipe)
 
     status.msg = "Uploading"
     status.cur = 1
@@ -117,15 +110,20 @@
     for k, v in radio._mmap._memobj.items():
         if k == '00':
             continue
-        if k in ('09', '10', '15'):
+        if new:
+            radio.pipe.write("%s=%s\r\n" % (k, v))
+            sleep(0.05)
+        elif k in ('09', '10', '15'):
             radio.pipe.write("@" + k + v + "\x00\r\n")
         else:
             radio.pipe.write("@" + k + v)
-        # Piece of crap acks every command except 15 with OK.
-        if radio.pipe.read(2) != "OK" and k != '15':
+        # Older firmware acks every command except 15 with OK.
+        if not new and radio.pipe.read(2) != "OK" and k != '15':
             raise errors.RadioError("Radio did not acknowledge upload: %s" % k)
         status.cur += 1
         radio.status_fn(status)
+    if new and radio.pipe.read(6) != "\r\n\r\nOK":
+        raise errors.RadioError("Radio did not acknowledge upload.")
 
 
 def strbool(s):
@@ -148,6 +146,8 @@
     01=KD7LXL7
     02=3
     03=1
+
+    This base class is compatible with firmware 20141008 (rx free).
     """
 
     ATTR_MAP = {
@@ -192,13 +192,123 @@
         print self.version
 
     def __getattr__(self, name):
-        return self._memobj[self.ATTR_MAP[name]]
+        if hasattr(self, 'get_%s' % name):
+            return getattr(self, 'get_%s' % name)()
+        try:
+            return self._memobj[self.ATTR_MAP[name]]
+        except KeyError as e:
+            raise NotImplementedError(e)
 
     def __setattr__(self, name, value):
         if name.startswith('_'):
             super(AP510Memory, self).__setattr__(name, value)
             return
-        self._memobj[self.ATTR_MAP[name]] = str(value)
+        if hasattr(self, 'set_%s' % name):
+            return getattr(self, 'set_%s' % name)(value)
+        try:
+            self._memobj[self.ATTR_MAP[name]] = str(value)
+        except KeyError as e:
+            raise NotImplementedError(e)
+
+    def get_smartbeacon(self):
+        return dict(zip((
+            'lowspeed',
+            'slowrate',
+            'highspeed',
+            'fastrate',
+            'turnslope',
+            'turnangle',
+            'turntime',
+        ), map(
+            decode_base100,
+            struct.unpack(">7H", self._memobj[self.ATTR_MAP['smartbeacon']]))
+        ))
+
+    def set_smartbeacon(self, d):
+        self._memobj[self.ATTR_MAP['smartbeacon']] = struct.pack(">7H",
+            encode_base100(d['lowspeed']),
+            encode_base100(d['slowrate']),
+            encode_base100(d['highspeed']),
+            encode_base100(d['fastrate']),
+            encode_base100(d['turnslope']),
+            encode_base100(d['turnangle']),
+            encode_base100(d['turntime']),
+        )
+
+
+class AP510Memory20141215(AP510Memory):
+    """Compatible with firmware version 20141215"""
+    ATTR_MAP = dict(AP510Memory.ATTR_MAP.items() + {
+        'tx_volume': '21',  # 1-6
+        'rx_volume': '22',  # 1-9
+        'tx_power': '23',  # 1: 1 watt,  0: 0.5 watt
+        'tx_serial_ui_out': '24',
+        'path1': '25',
+        'path2': '26',
+        'path3': '27',  # like "WIDE1 1" else "0"
+        'multiple': '28',
+        'auto_on': '29',
+    }.items())
+
+    def get_multiple(self):
+        return dict(zip((
+            'mice_message', # conveniently matches APRS spec Mic-E messages
+            'voltage',      # voltage in comment
+            'temperature',  # temperature in comment
+            'tfx',          # not sure what the TF/X toggle does
+            'squelch',      # squelch level 0-8 (0 = disabled)
+            'blueled',      # 0: squelch LED on GPS lock
+                            # 1: light LED on GPS lock
+            'telemetry',    # 1: enable
+            'telemetry_every',  # two-digit int
+            'timeslot_enable',  # 1: enable   Is this implemented in firmware?
+            'timeslot',     # int 00-59
+            'dcd',          # 0: Blue LED displays squelch,
+                            # 1: Blue LED displays software DCD
+            'tf_card'       # 0: KML,  1: WPL
+        ), map(int, chunks(
+            self._memobj[self.ATTR_MAP['multiple']],
+            (1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1)))
+        ))
+
+    def set_multiple(self, d):
+        self._memobj[self.ATTR_MAP['multiple']] = "%(mice_message)1d" \
+                                                  "%(voltage)1d" \
+                                                  "%(temperature)1d" \
+                                                  "%(tfx)1d" \
+                                                  "%(squelch)1d" \
+                                                  "%(blueled)1d" \
+                                                  "%(telemetry)1d" \
+                                                  "%(telemetry_every)02d" \
+                                                  "%(timeslot_enable)1d" \
+                                                  "%(timeslot)02d" \
+                                                  "%(dcd)1d" \
+                                                  "%(tf_card)1d" % d
+
+    def get_smartbeacon(self):
+        # raw:    18=0100300060010240028005
+        # chunks: 18=010 0300 060 010 240 028 005
+        return dict(zip((
+            'lowspeed',
+            'slowrate',
+            'highspeed',
+            'fastrate',
+            'turnslope',
+            'turnangle',
+            'turntime',
+        ), map(int, chunks(
+            self._memobj[self.ATTR_MAP['smartbeacon']],
+            (3, 4, 3, 3, 3, 3, 3)))
+        ))
+
+    def set_smartbeacon(self, d):
+        self._memobj[self.ATTR_MAP['smartbeacon']] = "%(lowspeed)03d" \
+                                                     "%(slowrate)04d" \
+                                                     "%(highspeed)03d" \
+                                                     "%(fastrate)03d" \
+                                                     "%(turnslope)03d" \
+                                                     "%(turnangle)03d" \
+                                                     "%(turntime)03d" % d
 
 
 PTT_DELAY = ['60 ms', '120 ms', '180 ms', '300 ms', '480 ms',
@@ -218,6 +328,11 @@
 BEACON = ['manual', 'auto', 'auto + manual', 'smart', 'smart + manual']
 ALIAS = ['WIDE1-N', 'WIDE2-N', 'WIDE1-N + WIDE2-N']
 CHARSET = "".join(map(chr, range(0, 256)))
+MICE_MESSAGE = ['Emergency', 'Priority', 'Special', 'Committed', 'Returning',
+    'In Service', 'En Route', 'Off Duty']
+TF_CARD = ['WPL', 'KML']
+POWER_LEVELS = [chirp_common.PowerLevel("0.5 watt", watts=0.50),
+                chirp_common.PowerLevel("1 watt", watts=1.00)]
 
 RP_IMMUTABLE = ["number", "skip", "bank", "extd_number", "name", "rtone",
                 "ctone", "dtcs", "tmode", "dtcs_polarity", "skip", "duplex",
@@ -242,6 +357,7 @@
         rf.valid_characters = ""
         rf.valid_duplexes = [""]
         rf.valid_name_length = 0
+        rf.valid_power_levels = POWER_LEVELS
         rf.valid_skips = []
         rf.valid_tuning_steps = []
         rf.has_bank = False
@@ -257,15 +373,20 @@
         return rf
 
     def sync_in(self):
-        # _mmap isn't a Chirp MemoryMap, but since AP510Memory implements
-        # get_packed(), the standard Chirp save feature works.
         try:
-            self._mmap = AP510Memory(download(self))
+            data = download(self)
         except errors.RadioError:
             raise
         except Exception, e:
             raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
+        # _mmap isn't a Chirp MemoryMap, but since AP510Memory implements
+        # get_packed(), the standard Chirp save feature works.
+        if data.startswith('\r\n00=%s 20141215' % self._model):
+            self._mmap = AP510Memory20141215(data)
+        else:
+            self._mmap = AP510Memory(data)
+
     def process_mmap(self):
         self._mmap.process_data()
 
@@ -280,7 +401,11 @@
     def load_mmap(self, filename):
         """Load the radio's memory map from @filename"""
         mapfile = file(filename, "rb")
-        self._mmap = AP510Memory(mapfile.read())
+        data = mapfile.read()
+        if data.startswith('\r\n00=%s 20141215' % self._model):
+            self._mmap = AP510Memory20141215(data)
+        else:
+            self._mmap = AP510Memory(data)
         mapfile.close()
 
     def get_raw_memory(self, number):
@@ -296,6 +421,10 @@
         mem.name = "TX/RX"
         mem.mode = "FM"
         mem.offset = 0.0
+        try:
+            mem.power = POWER_LEVELS[int(self._mmap.tx_power)]
+        except NotImplementedError:
+            mem.power = POWER_LEVELS[1]
         mem.immutable = RP_IMMUTABLE
 
         return mem
@@ -305,6 +434,12 @@
             raise errors.InvalidMemoryLocation("AP510 has only one slot")
 
         self._mmap.freq = "%8.4f" % (mem.freq / 1000000.0)
+        if mem.power:
+            try:
+                self._mmap.tx_power = str(POWER_LEVELS.index(mem.power))
+            except NotImplementedError:
+                pass
+
 
     def get_settings(self):
         china = RadioSettingGroup("china", "China Map Fix")
@@ -315,38 +450,80 @@
         system = RadioSettingGroup("system", "System")
         settings = RadioSettings(aprs, digipeat, system)
 
-        # The RadioSetting syntax is really verbose, iterate it.
-        fields = [
-            ("callsign", "Callsign",
-                RadioSettingValueString(0, 6, self._mmap.callsign[:6])),
-            ("ssid", "SSID", RadioSettingValueInteger(
-                0, 15, ord(self._mmap.callsign[6]) - 0x30)),
-            ("pttdelay", "PTT Delay",
+        aprs.append(RadioSetting("callsign", "Callsign",
+            RadioSettingValueString(0, 6, self._mmap.callsign[:6])))
+        aprs.append(RadioSetting("ssid", "SSID", RadioSettingValueInteger(
+            0, 15, ord(self._mmap.callsign[6]) - 0x30)))
+        aprs.append(RadioSetting("pttdelay", "PTT Delay",
+            RadioSettingValueList(
+                PTT_DELAY, PTT_DELAY[int(self._mmap.pttdelay) - 1])))
+        aprs.append(RadioSetting("output", "Output",
+            RadioSettingValueList(
+                OUTPUT, OUTPUT[int(self._mmap.output) - 1])))
+        aprs.append(RadioSetting("mice", "Mic-E",
+            RadioSettingValueBoolean(strbool(self._mmap.mice))))
+        try:
+            aprs.append(RadioSetting("mice_message", "Mic-E Message",
                 RadioSettingValueList(
-                    PTT_DELAY, PTT_DELAY[int(self._mmap.pttdelay) - 1])),
-            ("output", "Output",
-                RadioSettingValueList(
-                    OUTPUT, OUTPUT[int(self._mmap.output) - 1])),
-            ("mice", "Mic-E",
-                RadioSettingValueBoolean(strbool(self._mmap.mice))),
-            ("path", "Path",
-                RadioSettingValueList(PATH, PATH[int(self._mmap.path)])),
-            ("table", "Table or Overlay",
-                RadioSettingValueList(TABLE, self._mmap.symbol[1])),
-            ("symbol", "Symbol",
-                RadioSettingValueList(SYMBOL, self._mmap.symbol[0])),
-            ("beacon", "Beacon Mode",
-                RadioSettingValueList(
-                    BEACON, BEACON[int(self._mmap.beacon) - 1])),
-            ("rate", "Beacon Rate (seconds)",
-                RadioSettingValueInteger(10, 9999, self._mmap.rate)),
-            ("comment", "Comment", RadioSettingValueString(
-                0, 34, self._mmap.comment, autopad=False, charset=CHARSET)),
-            ("status", "Status", RadioSettingValueString(
-                0, 34, self._mmap.status, autopad=False, charset=CHARSET)),
-        ]
-        for field in fields:
-            aprs.append(RadioSetting(*field))
+                    MICE_MESSAGE,
+                    MICE_MESSAGE[int(self._mmap.multiple['mice_message'])])))
+        except NotImplementedError:
+            pass
+        try:
+            aprs.append(RadioSetting("path1", "Path 1",
+                RadioSettingValueString(0, 6, self._mmap.path1[:6],
+                    autopad=True, charset=CHARSET)))
+            aprs.append(RadioSetting("ssid1", "SSID 1",
+                RadioSettingValueInteger(
+                    0, 7, ord(self._mmap.path1[6]) - 0x30)))
+            aprs.append(RadioSetting("path2", "Path 2",
+                RadioSettingValueString(0, 6, self._mmap.path2[:6],
+                    autopad=True, charset=CHARSET)))
+            aprs.append(RadioSetting("ssid2", "SSID 2",
+                RadioSettingValueInteger(
+                    0, 7, ord(self._mmap.path2[6]) - 0x30)))
+            aprs.append(RadioSetting("path3", "Path 3",
+                RadioSettingValueString(0, 6, self._mmap.path3[:6],
+                    autopad=True, charset=CHARSET)))
+            aprs.append(RadioSetting("ssid3", "SSID 3",
+                RadioSettingValueInteger(
+                    0, 7, ord(self._mmap.path3[6]) - 0x30)))
+        except NotImplementedError:
+            aprs.append(RadioSetting("path", "Path",
+                RadioSettingValueList(PATH, PATH[int(self._mmap.path)])))
+        aprs.append(RadioSetting("table", "Table or Overlay",
+            RadioSettingValueList(TABLE, self._mmap.symbol[1])))
+        aprs.append(RadioSetting("symbol", "Symbol",
+            RadioSettingValueList(SYMBOL, self._mmap.symbol[0])))
+        aprs.append(RadioSetting("beacon", "Beacon Mode",
+            RadioSettingValueList(
+                BEACON, BEACON[int(self._mmap.beacon) - 1])))
+        aprs.append(RadioSetting("rate", "Beacon Rate (seconds)",
+            RadioSettingValueInteger(10, 9999, self._mmap.rate)))
+        aprs.append(RadioSetting("comment", "Comment", RadioSettingValueString(
+            0, 34, self._mmap.comment, autopad=False, charset=CHARSET)))
+        try:
+            aprs.append(RadioSetting("voltage", "Voltage in comment",
+                RadioSettingValueBoolean(self._mmap.multiple['voltage'])))
+            aprs.append(RadioSetting("temperature", "Temperature in comment",
+                RadioSettingValueBoolean(self._mmap.multiple['temperature'])))
+        except NotImplementedError:
+            pass
+        aprs.append(RadioSetting("status", "Status", RadioSettingValueString(
+            0, 34, self._mmap.status, autopad=False, charset=CHARSET)))
+        try:
+            aprs.append(RadioSetting("telemetry", "Telemetry",
+                RadioSettingValueBoolean(self._mmap.multiple['telemetry'])))
+            aprs.append(RadioSetting("telemetry_every", "Telemetry every",
+                RadioSettingValueInteger(
+                    1, 99, self._mmap.multiple['telemetry_every'])))
+            aprs.append(RadioSetting("timeslot_enable", "Timeslot",
+                RadioSettingValueBoolean(self._mmap.multiple['telemetry'])))
+            aprs.append(RadioSetting("timeslot", "Timeslot (second of minute)",
+                RadioSettingValueInteger(
+                    0, 59, self._mmap.multiple['timeslot'])))
+        except NotImplementedError:
+            pass
 
         fields = [
             ("chinamapfix", "China map fix",
@@ -381,7 +558,7 @@
         for field in fields:
             digipeat.append(RadioSetting(*field))
 
-        sb = decode_smartbeacon(self._mmap.smartbeacon)
+        sb = self._mmap.smartbeacon
         fields = [
             ("lowspeed", "Low Speed"),
             ("highspeed", "High Speed"),
@@ -397,20 +574,47 @@
                 RadioSettingValueInteger(0, 9999, sb[field[0]])
             ))
 
-        fields = [
-            ("version", "Version (read-only)",
-                RadioSettingValueString(0, 14, self._mmap.version)),
-            ("autooff", "Auto off (after 90 minutes)",
-                RadioSettingValueBoolean(strbool(self._mmap.autooff))),
-            ("beep", "Beep on transmit",
-                RadioSettingValueBoolean(strbool(self._mmap.beep))),
-            ("highaltitude", "High Altitude",
-                RadioSettingValueBoolean(strbool(self._mmap.highaltitude))),
-            ("busywait", "Wait for clear channel before transmit",
-                RadioSettingValueBoolean(strbool(self._mmap.busywait))),
-        ]
-        for field in fields:
-            system.append(RadioSetting(*field))
+        system.append(RadioSetting("version", "Version (read-only)",
+            RadioSettingValueString(0, 14, self._mmap.version)))
+        system.append(RadioSetting("autooff", "Auto off (after 90 minutes)",
+            RadioSettingValueBoolean(strbool(self._mmap.autooff))))
+        system.append(RadioSetting("beep", "Beep on transmit",
+            RadioSettingValueBoolean(strbool(self._mmap.beep))))
+        system.append(RadioSetting("highaltitude", "High Altitude",
+            RadioSettingValueBoolean(strbool(self._mmap.highaltitude))))
+        system.append(RadioSetting("busywait",
+            "Wait for clear channel before transmit",
+            RadioSettingValueBoolean(strbool(self._mmap.busywait))))
+        try:
+            system.append(RadioSetting("tx_volume", "Transmit volume",
+                RadioSettingValueList(
+                    map(str, range(1, 7)), self._mmap.tx_volume)))
+            system.append(RadioSetting("rx_volume", "Receive volume",
+                RadioSettingValueList(
+                    map(str, range(1, 10)), self._mmap.rx_volume)))
+            system.append(RadioSetting("squelch", "Squelch",
+                RadioSettingValueList(map(str, range(0, 9)),
+                    str(self._mmap.multiple['squelch']))))
+            system.append(RadioSetting("tx_serial_ui_out", "Tx serial UI out",
+                RadioSettingValueBoolean(
+                    strbool(self._mmap.tx_serial_ui_out))))
+            system.append(RadioSetting("auto_on", "Auto-on with 5V input",
+                RadioSettingValueBoolean(strbool(self._mmap.auto_on[0]))))
+            system.append(RadioSetting("auto_on_delay",
+                "Auto-off delay after 5V lost (seconds)",
+                RadioSettingValueInteger(0, 9999, int(self._mmap.auto_on[1:]))
+            ))
+            system.append(RadioSetting("tfx", "TF/X",
+                RadioSettingValueBoolean(self._mmap.multiple['tfx'])))
+            system.append(RadioSetting("blueled", "Light blue LED on GPS lock",
+                RadioSettingValueBoolean(self._mmap.multiple['blueled'])))
+            system.append(RadioSetting("dcd", "Blue LED shows software DCD",
+                RadioSettingValueBoolean(self._mmap.multiple['dcd'])))
+            system.append(RadioSetting("tf_card", "TF card format",
+                RadioSettingValueList(
+                    TF_CARD, TF_CARD[int(self._mmap.multiple['tf_card'])])))
+        except NotImplementedError:
+            pass
 
         return settings
 
@@ -433,10 +637,33 @@
                 elif name == "output":
                     self._mmap.output = OUTPUT.index(str(setting.value)) + 1
                 elif name in ('mice', 'autooff', 'beep', 'highaltitude',
-                              'busywait'):
+                              'busywait', 'tx_serial_ui_out'):
                     setattr(self._mmap, name, boolstr(setting.value))
+                elif name == "mice_message":
+                    multiple = self._mmap.multiple
+                    multiple['mice_message'] = MICE_MESSAGE.index(
+                        str(setting.value))
+                    self._mmap.multiple = multiple
                 elif name == "path":
                     self._mmap.path = PATH.index(str(setting.value))
+                elif name == "path1":
+                    self._mmap.path1 = "%s%s" % (
+                        setting.value, self._mmap.path1[6])
+                elif name == "ssid1":
+                    self._mmap.path1 = "%s%s" % (
+                        self._mmap.path1[:6], setting.value)
+                elif name == "path2":
+                    self._mmap.path2 = "%s%s" % (
+                        setting.value, self._mmap.path2[6])
+                elif name == "ssid2":
+                    self._mmap.path2 = "%s%s" % (
+                        self._mmap.path2[:6], setting.value)
+                elif name == "path3":
+                    self._mmap.path3 = "%s%s" % (
+                        setting.value, self._mmap.path3[6])
+                elif name == "ssid3":
+                    self._mmap.path3 = "%s%s" % (
+                        self._mmap.path3[:6], setting.value)
                 elif name == "table":
                     self.set_symbol(table=setting.value)
                 elif name == "symbol":
@@ -447,8 +674,21 @@
                     self._mmap.rate = "%04d" % setting.value
                 elif name == "comment":
                     self._mmap.comment = str(setting.value)
+                elif name == "voltage":
+                    multiple = self._mmap.multiple
+                    multiple['voltage'] = int(setting.value)
+                    self._mmap.multiple = multiple
+                elif name == "temperature":
+                    multiple = self._mmap.multiple
+                    multiple['temperature'] = int(setting.value)
+                    self._mmap.multiple = multiple
                 elif name == "status":
                     self._mmap.status = str(setting.value)
+                elif name in ("telemetry", "telemetry_every",
+                    "timeslot_enable", "timeslot", "tfx", "blueled", "dcd"):
+                    multiple = self._mmap.multiple
+                    multiple[name] = int(setting.value)
+                    self._mmap.multiple = multiple
                 elif name == "chinamapfix":
                     self.set_chinamapfix(enable=setting.value)
                 elif name == "chinalat":
@@ -478,7 +718,20 @@
                     self.set_smartbeacon(turnangle=int(setting.value))
                 elif name == "turntime":
                     self.set_smartbeacon(turntime=int(setting.value))
-            except Exception, e:
+                elif name in ("tx_volume", "rx_volume", "squelch"):
+                    setattr(self._mmap, name, "%1d" % setting.value)
+                elif name == "auto_on":
+                    self._mmap.auto_on = "%s%05d" % (
+                        bool(setting.value) and '1' or 'i',
+                        int(self._mmap.auto_on[1:]))
+                elif name == "auto_on_delay":
+                    self._mmap.auto_on = "%s%05d" % (
+                        self._mmap.auto_on[0], setting.value)
+                elif name == "tf_card":
+                    multiple = self._mmap.multiple
+                    multiple['tf_card'] = TF_CARD.index(str(setting.value))
+                    self._mmap.multiple = multiple
+            except:
                 print setting.get_name()
                 raise
 
@@ -520,13 +773,13 @@
         self._mmap.virtualgps = boolstr(enable) + btext
 
     def set_smartbeacon(self, **kwargs):
-        sb = decode_smartbeacon(self._mmap.smartbeacon)
+        sb = self._mmap.smartbeacon
         sb.update(kwargs)
         if sb['lowspeed'] > sb['highspeed']:
             raise InvalidValueError("Low speed must be less than high speed")
         if sb['slowrate'] < sb['fastrate']:
             raise InvalidValueError("Slow rate must be greater than fast rate")
-        self._mmap.smartbeacon = encode_smartbeacon(sb)
+        self._mmap.smartbeacon = sb
 
     @classmethod
     def match_model(cls, filedata, filename):



More information about the chirp_devel mailing list