[chirp_devel] [PATCH] [UV-5R] "Incorrect 'Model' selected." error

Jim Unroe
Sun Apr 2 08:04:56 PDT 2017


# HG changeset patch
# User Jim Unroe <rock.unroe at gmail.com>
# Date 1491143983 14400
# Node ID 0714032989d2d0ea7fa82c231e4ab374835375b4
# Parent  6ad4b478463019b1a1af7a0f7e7b3e7083994988
[UV-5R]  "Incorrect 'Model' selected." error

When Baofeng started shipping tri-power radios back in 2014, the firmware
version format could be used to identify if the detected radio had 2 power
levels (HIGH/LOW) or 3 power levels (HIGH/MID/LOW). CHIRP would then use this
firmware version to not only determine if the user had selected the correct
radio model, but also to present the only settings that were available on the
selected model.

Recently Baofeng radio models with 3 power levels have been shipping with with
the HN5RV001 firmware version. This same firmware version, as it has for the
last 2 years, continues to ship in radio models that have only 2 power levels.
This firmware version defeats CHIRP's ability to differentiate on its own
between these two model types.

This patch addresses the problem in 2 ways.

1. for radios with the HN5RV001 firmware version, CHIRP will assume that the
user has selected the correct radio model. The selected model is then appended
to the end of the image so CHIRP can identify the radio model when image is
loaded back into CHIRP at a later time.

2. the driver will now selectively uploads the image in ranges, thus bypassing
specific areas of memory that must not be overwritten by images from radios
with a different firmware version.

This patch also addresses, in a similar way, a related problem where the radio
does not report a firmware version at all to CHIRP.

releated to issue #4445 and many others

diff -r 6ad4b4784630 -r 0714032989d2 chirp/drivers/uv5r.py
--- a/chirp/drivers/uv5r.py	Thu Mar 30 12:47:43 2017 -0700
+++ b/chirp/drivers/uv5r.py	Sun Apr 02 10:39:43 2017 -0400
@@ -282,7 +282,7 @@
 
 BASETYPE_UV5R = ["BFS", "BFB", "N5R-2", "N5R2", "N5RV", "BTS", "D5R2"]
 BASETYPE_F11 = ["USA"]
-BASETYPE_UV82 = ["US2S", "B82S", "BF82", "N82-2", "N822"]
+BASETYPE_UV82 = ["US2S2", "B82S", "BF82", "N82-2", "N822"]
 BASETYPE_BJ55 = ["BJ55"]  # needed for for the Baojie UV-55 in bjuv55.py
 BASETYPE_UV6 = ["BF1", "UV6"]
 BASETYPE_KT980HP = ["BFP3V3 B"]
@@ -544,8 +544,29 @@
     radio_version = _get_radio_firmware_version(radio)
     LOG.info("Radio Version is %s" % repr(radio_version))
 
-    if not any(type in radio_version for type in radio._basetype):
+    if "HN5RV" in radio_version:
+        # A radio with HN5RV firmware has been detected. It could be a
+        # UV-5R style radio with HIGH/LOW power levels or it could be a
+        # BF-F8HP style radio with HIGH/MID/LOW power levels.
+        # We are going to count on the user to make the right choice and
+        # then append that model type to the end of the image so it can
+        # be properly detected when loaded.
+        append_model = True
+    elif "\xFF" * 14 in radio_version:
+        # A radio UV-5R style radio that reports no firmware version has
+        # been detected.
+        # We are going to count on the user to make the right choice and
+        # then append that model type to the end of the image so it can
+        # be properly detected when loaded.
+        append_model = True
+    elif not any(type in radio_version for type in radio._basetype):
+        # This radio can't be properly detected by parsing its firmware
+        # version.
         raise errors.RadioError("Incorrect 'Model' selected.")
+    else:
+        # This radio can be properly detected by parsing its firmware version.
+        # There is no need to append its model type to the end of the image.
+        append_model = False
 
     # Main block
     LOG.debug("downloading main block...")
@@ -558,6 +579,10 @@
     # Auxiliary block starts at 0x1ECO (?)
     for i in range(0x1EC0, 0x2000, 0x40):
         data += _read_block(radio, i, 0x40, False)
+
+    if append_model:
+        data += radio.MODEL.ljust(8)
+
     LOG.debug("done.")
     return memmap.MemoryMap(data)
 
@@ -586,34 +611,68 @@
     LOG.info("Image Version is %s" % repr(image_version))
     LOG.info("Radio Version is %s" % repr(radio_version))
 
-    if image_version != radio_version:
+    # default ranges
+    _ranges_main_default = [
+        (0x0008, 0x0CF8),
+        (0x0D08, 0x0DF8),
+        (0x0E08, 0x1808)
+        ]
+    _ranges_aux_default = [
+        (0x1EC0, 0x1EF0),
+        ]
+
+    # extra aux ranges
+    _ranges_aux_extra = [
+        (0x1F60, 0x1F70),
+        (0x1F80, 0x1F90),
+        (0x1FC0, 0x1FD0)
+        ]
+
+    if image_version == radio_version:
+        image_matched_radio = True
+        if image_version.startswith("HN5RV"):
+            ranges_main = _ranges_main_default
+            ranges_aux = _ranges_aux_default + _ranges_aux_extra
+        elif image_version == 0xFF * 14:
+            ranges_main = _ranges_main_default
+            ranges_aux = _ranges_aux_default + _ranges_aux_extra
+        else:
+            ranges_main = radio._ranges_main
+            ranges_aux = radio._ranges_aux
+    elif any(type in radio_version for type in radio._basetype):
+        image_matched_radio = False
+        ranges_main = _ranges_main_default
+        ranges_aux = _ranges_aux_default
+    else:
         msg = ("The upload was stopped because the firmware "
                "version of the image (%s) does not match that "
                "of the radio (%s).")
         raise errors.RadioError(msg % (image_version, radio_version))
 
     # Main block
-    for i in range(0x08, 0x1808, 0x10):
-        _send_block(radio, i - 0x08, radio.get_mmap()[i:i + 0x10])
-        _do_status(radio, i)
-    _do_status(radio, radio.get_memsize())
+    for start_addr, end_addr in ranges_main:
+        for i in range(start_addr, end_addr, 0x10):
+            _send_block(radio, i - 0x08, radio.get_mmap()[i:i + 0x10])
+            _do_status(radio, i)
+        _do_status(radio, radio.get_memsize())
 
     if len(radio.get_mmap().get_packed()) == 0x1808:
         LOG.info("Old image, not writing aux block")
         return  # Old image, no aux block
 
-    if image_version != radio_version:
+    # Auxiliary block at radio address 0x1EC0, our offset 0x1808
+    for start_addr, end_addr in ranges_aux:
+        for i in range(start_addr, end_addr, 0x10):
+            addr = 0x1808 + (i - 0x1EC0)
+            _send_block(radio, i, radio.get_mmap()[addr:addr + 0x10])
+
+    if image_matched_radio == False:
         msg = ("Upload finished, but the 'Other Settings' "
                "could not be sent because the firmware "
                "version of the image (%s) does not match "
                "that of the radio (%s).")
         raise errors.RadioError(msg % (image_version, radio_version))
 
-    # Auxiliary block at radio address 0x1EC0, our offset 0x1808
-    for i in range(0x1EC0, 0x2000, 0x10):
-        addr = 0x1808 + (i - 0x1EC0)
-        _send_block(radio, i, radio.get_mmap()[addr:addr + 0x10])
-
 UV5R_POWER_LEVELS = [chirp_common.PowerLevel("High", watts=4.00),
                      chirp_common.PowerLevel("Low",  watts=1.00)]
 
@@ -627,6 +686,20 @@
     "!@#$%^&*()+-=[]:\";'<>?,./"
 
 
+def model_match(cls, data):
+    """Match the opened/downloaded image to the correct version"""
+
+    if len(data) == 0x1950:
+        rid = data[0x1948:0x1950]
+        return rid.startswith(cls.MODEL)
+    elif len(data) == 0x1948:
+        rid = data[cls._fw_ver_file_start:cls._fw_ver_file_stop]
+        if any(type in rid for type in cls._basetype):
+            return True
+    else:
+        return False
+
+
 class BaofengUV5R(chirp_common.CloneModeRadio,
                   chirp_common.ExperimentalRadio):
 
@@ -649,6 +722,13 @@
     _fw_ver_file_start = 0x1838
     _fw_ver_file_stop = 0x1846
 
+    _ranges_main = [
+                    (0x0008, 0x1808),
+                   ]
+    _ranges_aux = [
+                   (0x1EC0, 0x2000),
+                  ]
+
     @classmethod
     def get_prompts(cls):
         rp = chirp_common.RadioPrompts()
@@ -709,13 +789,10 @@
     def match_model(cls, filedata, filename):
         match_size = False
         match_model = False
-        if len(filedata) in [0x1808, 0x1948]:
+        if len(filedata) in [0x1808, 0x1948, 0x1950]:
             match_size = True
-        fwdata = _firmware_version_from_data(filedata,
-                                             cls._fw_ver_file_start,
-                                             cls._fw_ver_file_stop)
-        if any(type in fwdata for type in cls._basetype):
-            match_model = True
+        match_model = model_match(cls, filedata)
+
         if match_size and match_model:
             return True
         else:
@@ -1189,8 +1266,9 @@
 
         if self.MODEL == "UV-82HP":
             # this is a UV-82HP only feature
-            rs = RadioSetting("vfomrlock", "VFO/MR Switching",
-                              RadioSettingValueBoolean(_settings.vfomrlock))
+            rs = RadioSetting(
+                "vfomrlock", "VFO/MR Switching (BTech UV-82HP only)",
+                RadioSettingValueBoolean(_settings.vfomrlock))
             advanced.append(rs)
 
         if self.MODEL == "UV-82":
@@ -1201,15 +1279,15 @@
 
         if self.MODEL == "UV-82HP":
             # this is an UV-82HP only feature
-            rs = RadioSetting("singleptt", "Single PTT",
+            rs = RadioSetting("singleptt", "Single PTT (BTech UV-82HP only)",
                               RadioSettingValueBoolean(_settings.singleptt))
             advanced.append(rs)
 
         if self.MODEL == "UV-82HP":
             # this is an UV-82HP only feature
-            rs = RadioSetting("tdrch", "Tone Burst Frequency",
-                              RadioSettingValueList(
-                                  RTONE_LIST, RTONE_LIST[_settings.tdrch]))
+            rs = RadioSetting(
+                "tdrch", "Tone Burst Frequency (BTech UV-82HP only)",
+                RadioSettingValueList(RTONE_LIST, RTONE_LIST[_settings.tdrch]))
             advanced.append(rs)
 
         if len(self._mmap.get_packed()) == 0x1808:



More information about the chirp_devel mailing list