[chirp_devel] Fwd: [PATCH 3 of 3] [BJ-318] Add support for the Baojie BJ-318

Jim Unroe
Mon Apr 12 09:41:30 PDT 2021


Baojie BJ-318 CHIRP Radio Images (*.img) file attached.

Jim KC9HI

---------- Forwarded message ---------
From: Jim Unroe <kc9hi at comcast.net>
Date: Mon, Apr 12, 2021 at 12:29 PM
Subject: [PATCH 3 of 3] [BJ-318] Add support for the Baojie BJ-318
To: <Rock.Unroe at gmail.com>


# HG changeset patch
# User Jim Unroe <rock.unroe at gmail.com>
# Date 1618244518 14400
#      Mon Apr 12 12:21:58 2021 -0400
# Node ID d1f3307170d3c5fc1ab329cf5e20d24df8a04960
# Parent  60b475e41306144198481bc84d428ef0ca6adb5b
[BJ-318] Add support for the Baojie BJ-318

This patch adds support for the Bajoie BJ-318 mobile radio.

Research and main coding by Mark Hartong
Assistance, pep8 compliance and submission by Jim Unroe

related to #6235

diff -r 60b475e41306 -r d1f3307170d3 chirp/drivers/lt725uv.py
--- a/chirp/drivers/lt725uv.py  Sun Apr 11 21:12:34 2021 -0400
+++ b/chirp/drivers/lt725uv.py  Mon Apr 12 12:21:58 2021 -0400
@@ -1,6 +1,10 @@
 # Copyright 2016-2021:
 # * Jim Unroe KC9HI, <rock.unroe at gmail.com>
-# Modified for Baojie BJ-218: 2018 by Rick DeWitt (RJD), <aa0rd at yahoo.com>#
+# Modified for Baojie BJ-218: 2018
+#    Rick DeWitt (RJD), <aa0rd at yahoo.com>
+# Modified for Baojie BJ-318: April 2021
+#    Mark Hartong, AJ4YI <mark.hartong at verizon.net>
+#
 # 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
 # the Free Software Foundation, either version 2 of the License, or
@@ -32,12 +36,12 @@
 MEM_FORMAT = """
 #seekto 0x0200;
 struct {
-  u8  init_bank;
-  u8  volume;
-  u16 fm_freq;
-  u8  wtled;
-  u8  rxled;
-  u8  txled;
+  u8  init_bank; // determines which VFO is primary A or B
+  u8  volume;    // not used BJ-318, band volume is controlled vfo u8 bvol
+  u16 fm_freq;   // not used BJ-318, freq is controlled hello_lims u16 fm_318
+  u8  wtled;     // not used BJ-318
+  u8  rxled;     // not used BJ-318
+  u8  txled;     // not used BJ-318
   u8  ledsw;
   u8  beep;
   u8  ring;
@@ -45,7 +49,7 @@
   u8  tot;
   u16 sig_freq;
   u16 dtmf_txms;
-  u8  init_sql;
+  u8  init_sql;  // not used BJ-318, band squelch is controlled vfo u8 sql
   u8  rptr_mode;
 } settings;

@@ -92,15 +96,25 @@

 #seekto 0x02d0;
 struct {
-  u8  hello1_cnt;
-  char  hello1[7];
-  u8  hello2_cnt;
-  char  hello2[7];
+  u8  hello1_cnt;    // not used in BJ-318, is set in memory map
+  char  hello1[7];   // not used in BJ-318, is set in memory map
+  u8  hello2_cnt;    // not used in BJ-318, is set in memory map
+  char  hello2[7];   // not used in BJ-318, is set in memory map
   u32  vhf_low;
   u32  vhf_high;
   u32  uhf_low;
   u32  uhf_high;
-  u8  lims_on;
+  u8  lims_on;       // first byte @ at address 0x02f0;
+  u8 unknown_1;      // use in BJ-318 unknown
+  u8 lang;           // BJ-318 Display language
+                     // 02 = English 00 and 01 are Asian
+  u8 up_scr_color;   // BJ-318 upper screen character color
+  u8 dn_scr_color;   // BJ-318 lower screen character color
+                     // purple=00, red=01, emerald=02, blue=03,
+                     // sky_blue=04, black=05, required hex values for color
+                     // Note   sky_blue and black look the same on the
+                     // BJ-318 screen
+  u16 fm_318;        // FM stored Frequency in BJ-318
 } hello_lims;

 struct vfo {
@@ -117,14 +131,18 @@
       tx_tone:14;
   u8  launch_sig;
   u8  tx_end_sig;
-  u8  bpower;
+  u8  bpower;        // sets power Hi=02h, Medium=01h, Low=00
+                     // sets power for entire vfo band
   u8  fm_bw;
   u8  cmp_nder;
   u8  scrm_blr;
   u8  shift;
   u32 offset;
   u16 step;
-  u8  sql;
+  u8  sql;           // squelch for entire vfo band
+                     // integer values 0 (low) to 9 (high)
+  u8  bvol;          // sets volume for vfo band
+                     // integer values 0  (low) TO 10 (high)
 };

 #seekto 0x0300;
@@ -149,7 +167,11 @@
       txtone:14;
   u8  botsignal;
   u8  eotsignal;
-  u8  power:1,
+  u8  power:1,            // binary value for
+                          // indiviudal channel power
+                          // set to "High" or "Low"
+                          // BJ-318 band power overrides any
+                          // individual channel power setting
       wide:1,
       compandor:1
       scrambler:1
@@ -173,14 +195,18 @@
 MEM_SIZE = 0x1C00
 BLOCK_SIZE = 0x40
 STIMEOUT = 2
-
 LIST_RECVMODE = ["QT/DQT", "QT/DQT + Signaling"]
 LIST_SIGNAL = ["Off"] + ["DTMF%s" % x for x in range(1, 9)] + \
               ["DTMF%s + Identity" % x for x in range(1, 9)] + \
               ["Identity code"]
 # Band Power settings, can be different than channel power
 LIST_BPOWER = ["Low", "Mid", "High"]    # Tri-power models
+
+# Screen Color Settings
+# BJ-218 Colors
 LIST_COLOR = ["Off", "Orange", "Blue", "Purple"]
+# BJ-318 Colors
+LIST_COLOR318 = ["Purple", "Red", "Emerald", "Blue", "Sky_Blue", "Black"]
 LIST_LEDSW = ["Auto", "On"]
 LIST_RING = ["Off"] + ["%s" % x for x in range(1, 10)]
 LIST_TDR_DEF = ["A-Upper", "B-Lower"]
@@ -206,9 +232,9 @@
 SETTING_LISTS = {
     "init_bank": LIST_TDR_DEF,
     "tot": LIST_TIMEOUT,
-    "wtled": LIST_COLOR,
-    "rxled": LIST_COLOR,
-    "txled": LIST_COLOR,
+    "wtled": LIST_COLOR,   # not used in BJ-318, other radios use
+    "rxled": LIST_COLOR,   # not used in BJ-318, other radios use
+    "txled": LIST_COLOR,   # not used in BJ-318, other radios use
     "sig_freq": LIST_SSF,
     "dtmf_txms": LIST_DTMFTX,
     "ledsw": LIST_LEDSW,
@@ -223,7 +249,9 @@
     "shift": LIST_SHIFT,
     "step": LIST_STEPS,
     "ring": LIST_RING,
-    "state_now": LIST_STATE
+    "state_now": LIST_STATE,
+    "up_scr_color": LIST_COLOR318,  # unique to BJ-318
+    "dn_scr_color": LIST_COLOR318,  # unique to BJ-318
 }


@@ -425,7 +453,14 @@
     NAME_LENGTH = 7
     DTMF_CHARS = list("0123456789ABCD*#")

-    # Channel power: 2 levels
+    # Channel Power: 2 levels
+    # BJ-318 uses 3 power levels for each VFO "Band"
+    # Low = 5W, Med = 10W, High = 25W
+    # The band power selection in a VFO applies to the VFO and overrides
+    # the stored channel power selection
+    # The firmware chanel memory structure provides only 1 bit for
+    # individual chanel power settings, limiting potential channel
+    # power selection options to 2 levels: Low or High.
     POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5.00),
                     chirp_common.PowerLevel("High", watts=30.00)]

@@ -439,20 +474,39 @@
     @classmethod
     def get_prompts(cls):
         rp = chirp_common.RadioPrompts()
-        rp.info = \
-            ('Some notes about POWER settings:\n'
-             '- The individual channel power settings are ignored'
-             ' by the radio.\n'
-             '  They are allowed to be set (and downloaded) in hopes of'
-             ' a future firmware update.\n'
-             '- Power settings done \'Live\' in the radio apply to the'
-             ' entire upper or lower band.\n'
-             '- Tri-power radio models will set and download the three'
-             ' band-power'
-             ' levels, but they are converted to just Low and High at'
-             ' upload.'
-             ' The Mid setting reverts to Low.'
-             )
+        if cls.MODEL == "BJ-318":
+            msg = \
+                ('              BJ-318 EXPERIMENTAL\n'
+                 '            PLEASE REPORT ANY ISSUES \n'
+                 '\n'
+                 'The individual channel power settings are ignored by \n'
+                 'the radio. They are allowed to be set in hopes of a \n'
+                 'future firmware change. Changing a stored channel power \n'
+                 'setting must be done manually using the front panel menu \n'
+                 'control (or the microphone control controls while in VFO \n'
+                 'mode) to change the VFO power. The CHIRP driver will \n'
+                 'allow setting the individual VFO power to High (25W), \n'
+                 'Med (10W) or Low (5W) and setting the unused individual \n'
+                 'channel power setting to High (25W) or Low (5W)'
+                 )
+
+        else:
+            msg = \
+                ('Some notes about POWER settings:\n'
+                 '- The individual channel power settings are ignored'
+                 ' by the radio.\n'
+                 '  They are allowed to be set (and downloaded) in hopes of'
+                 ' a future firmware update.\n'
+                 '- Power settings done \'Live\' in the radio apply to the'
+                 ' entire upper or lower band.\n'
+                 '- Tri-power radio models will set and download the three'
+                 ' band-power'
+                 ' levels, but they are converted to just Low and High at'
+                 ' upload.'
+                 ' The Mid setting reverts to Low.'
+                 )
+
+        rp.info = msg

         rp.pre_download = _(dedent("""\
             Follow this instructions to download your info:
@@ -776,19 +830,25 @@
                                                           _sets.init_bank]))
         basic.append(bnd_mode)

-        volume = RadioSetting("settings.volume", "Volume",
-                              RadioSettingValueInteger(0, 20, _sets.volume))
-        basic.append(volume)
+        # BJ-318 set by vfo, skip
+        if self.MODEL != "BJ-318":
+            rs = RadioSettingValueInteger(0, 20, _sets.volume)
+            volume = RadioSetting("settings.volume", "Volume", rs)
+            basic.append(volume)

-        val = _vfoa.bpower        # 2bits values 0,1,2= Low, Mid, High
-        rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[val])
-        powera = RadioSetting("upper.vfoa.bpower", "Power (Upper)", rx)
-        basic.append(powera)
+        # BJ-318 set by vfo, skip
+        if self.MODEL != "BJ-318":
+            vala = _vfoa.bpower        # 2bits values 0,1,2= Low, Mid, High
+            rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[vala])
+            powera = RadioSetting("upper.vfoa.bpower", "Power (Upper)", rx)
+            basic.append(powera)

-        val = _vfob.bpower
-        rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[val])
-        powerb = RadioSetting("lower.vfob.bpower", "Power (Lower)", rx)
-        basic.append(powerb)
+        # BJ-318 set by vfo, skip
+        if self.MODEL != "BJ-318":
+            valb = _vfob.bpower
+            rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[valb])
+            powerb = RadioSetting("lower.vfob.bpower", "Power (Lower)", rx)
+            basic.append(powerb)

         def my_word2raw(setting, obj, atrb, mlt=10):
             """Callback function to convert UI floating value to u16 int"""
@@ -874,28 +934,48 @@
             setattr(obj, tone_atr, tonx)
             return

-        val = _sets.fm_freq / 10.0
-        if val == 0:
-            val = 88.9            # 0 is not valid
-        rx = RadioSettingValueFloat(65, 108.0, val, 0.1, 1)
-        rs = RadioSetting("settings.fm_freq", "FM Broadcast Freq (MHz)", rx)
-        rs.set_apply_callback(my_word2raw, _sets, "fm_freq")
-        basic.append(rs)
+        # not used by BJ-318 skip
+        if self.MODEL != "BJ-318":
+            val = _sets.fm_freq / 10.0
+            if val == 0:
+                val = 88.9            # 0 is not valid
+            rx = RadioSettingValueFloat(65, 108.0, val, 0.1, 1)
+            rs = RadioSetting("settings.fm_freq",
+                              "FM Broadcast Freq (MHz)", rx)
+            rs.set_apply_callback(my_word2raw, _sets, "fm_freq")
+            basic.append(rs)

-        wtled = RadioSetting("settings.wtled", "Standby LED Color",
-                             RadioSettingValueList(LIST_COLOR, LIST_COLOR[
-                                 _sets.wtled]))
-        basic.append(wtled)
+        # BJ-318 fm frequency
+        if self.MODEL == "BJ-318":
+            val = _lims.fm_318 / 10.0
+            if val == 0:
+                val = 88.9            # 0 is not valid
+            rx = RadioSettingValueFloat(65, 108.0, val, 0.1, 1)
+            rs = RadioSetting("hello_lims.fm_318",
+                              "FM Broadcast Freq (MHz)", rx)
+            rs.set_apply_callback(my_word2raw, _lims, "fm_318")
+            basic.append(rs)

-        rxled = RadioSetting("settings.rxled", "RX LED Color",
-                             RadioSettingValueList(LIST_COLOR, LIST_COLOR[
-                                 _sets.rxled]))
-        basic.append(rxled)
+        # not used in BJ-318, skip
+        if self.MODEL != "BJ-318":
+            rs = RadioSettingValueList(LIST_COLOR,
+                                       LIST_COLOR[_sets.wtled])
+            wtled = RadioSetting("settings.wtled", "Standby LED Color", rs)
+            basic.append(wtled)

-        txled = RadioSetting("settings.txled", "TX LED Color",
-                             RadioSettingValueList(LIST_COLOR, LIST_COLOR[
-                                 _sets.txled]))
-        basic.append(txled)
+        # not used in BJ-318, skip
+        if self.MODEL != "BJ-318":
+            rs = RadioSettingValueList(LIST_COLOR,
+                                       LIST_COLOR[_sets.rxled])
+            rxled = RadioSetting("settings.rxled", "RX LED Color", rs)
+            basic.append(rxled)
+
+        # not used in BJ-318, skip
+        if self.MODEL != "BJ-318":
+            rs = RadioSettingValueList(LIST_COLOR,
+                                       LIST_COLOR[_sets.txled])
+            txled = RadioSetting("settings.txled", "TX LED Color", rs)
+            basic.append(txled)

         ledsw = RadioSetting("settings.ledsw", "Back light mode",
                              RadioSettingValueList(LIST_LEDSW, LIST_LEDSW[
@@ -915,21 +995,24 @@
                            RadioSettingValueBoolean(bool(_sets.bcl)))
         basic.append(bcl)

-        if _vfoa.sql == 0xFF:
-            val = 0x04
-        else:
-            val = _vfoa.sql
-        sqla = RadioSetting("upper.vfoa.sql", "Squelch (Upper)",
-                            RadioSettingValueInteger(0, 9, val))
-        basic.append(sqla)
+        # squelch for non-BJ-318 models
+        # BJ-318 squelch set by VFO basis
+        if self.MODEL != "BJ-318":
+            if _vfoa.sql == 0xFF:
+                val = 0x04
+            else:
+                val = _vfoa.sql
+            sqla = RadioSetting("upper.vfoa.sql", "Squelch (Upper)",
+                                RadioSettingValueInteger(0, 9, val))
+            basic.append(sqla)

-        if _vfob.sql == 0xFF:
-            val = 0x04
-        else:
-            val = _vfob.sql
-        sqlb = RadioSetting("lower.vfob.sql", "Squelch (Lower)",
-                            RadioSettingValueInteger(0, 9, val))
-        basic.append(sqlb)
+            if _vfob.sql == 0xFF:
+                val = 0x04
+            else:
+                val = _vfob.sql
+            sqlb = RadioSetting("lower.vfob.sql", "Squelch (Lower)",
+                                RadioSettingValueInteger(0, 9, val))
+            basic.append(sqlb)

         tmp = str(int(_sets.tot) * 30)     # 30 sec step counter
         rs = RadioSetting("settings.tot", "Transmit Timeout (Secs)",
@@ -1034,6 +1117,38 @@
         rs.set_apply_callback(my_word2raw, _vfoa, "step", 100)
         a_band.append(rs)

+        # BJ-318 upper band squelch
+        if self.MODEL == "BJ-318":
+            if _vfoa.sql == 0xFF:
+                valq = 0x04    # setting default squelch to 04
+            else:
+                valq = _vfoa.sql
+                sqla = RadioSetting("upper.vfoa.sql", "Squelch",
+                                    RadioSettingValueInteger(0, 9, valq))
+            a_band.append(sqla)
+
+        # BJ-318 upper band volume
+        if self.MODEL == "BJ-318":
+            bvolume_u = RadioSetting("upper.vfoa.bvol",
+                                     "Volume", RadioSettingValueInteger(
+                                         0, 10, _vfoa.bvol))
+            a_band.append(bvolume_u)
+
+        # BJ-318 Upper Screen Color
+        if self.MODEL == "BJ-318":
+            rs_u = RadioSettingValueList(LIST_COLOR318,
+                                         LIST_COLOR318[_lims.up_scr_color])
+            up_scr_color = RadioSetting("hello_lims.up_scr_color",
+                                        "Screen Color", rs_u)
+            a_band.append(up_scr_color)
+
+        # BJ-318 Upper band power
+        if self.MODEL == "BJ-318":
+            val_b = _vfoa.bpower        # 2bits values 0,1,2= Low, Mid, High
+            rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[val_b])
+            power_u = RadioSetting("upper.vfoa.bpower", "Power", rx)
+            a_band.append(power_u)
+
         # LOWER BAND SETTINGS

         val = _vfob.frq_chn_mode / 2
@@ -1110,8 +1225,39 @@
         rs.set_apply_callback(my_word2raw, _vfob, "step", 100)
         b_band.append(rs)

+        # BJ-318 lower band squelch
+        if self.MODEL == "BJ-318":
+            if _vfob.sql == 0xFF:
+                val_l = 0x04    # setting default squelch to 04
+            else:
+                val_l = _vfob.sql
+                sql_b = RadioSetting("lower.vfob.sql", "Squelch",
+                                     RadioSettingValueInteger(0, 9, val_l))
+                b_band.append(sql_b)
+
+        # BJ-318 lower band volume
+        if self.MODEL == "BJ-318":
+            bvolume_l = RadioSetting("lower.vfob.bvol",
+                                     "Volume", RadioSettingValueInteger(
+                                         0, 10, _vfob.bvol))
+            b_band.append(bvolume_l)
+
+        # BJ-318 Lower Screen Color
+        if self.MODEL == "BJ-318":
+            rs_l = RadioSettingValueList(LIST_COLOR318,
+                                         LIST_COLOR318[_lims.dn_scr_color])
+            dn_scr_color = RadioSetting("hello_lims.dn_scr_color",
+                                        "Screen Color", rs_l)
+            b_band.append(dn_scr_color)
+
+        # BJ-318 lower band power
+        if self.MODEL == "BJ-318":
+            val_l = _vfoa.bpower        # 2bits values 0,1,2= Low, Mid, High
+            rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[val_l])
+            powera = RadioSetting("lower.vfob.bpower", "Power", rx)
+            b_band.append(powera)
+
         # PowerOn & Freq Limits Settings
-
         def chars2str(cary, knt):
             """Convert raw memory char array to a string: NOT a callback."""
             stx = ""
@@ -1137,17 +1283,21 @@
             setattr(obj, atrbc, knt)
             return

-        tmp = chars2str(_lims.hello1, _lims.hello1_cnt)
-        rs = RadioSetting("hello_lims.hello1", "Power-On Message 1",
-                          RadioSettingValueString(0, 7, tmp))
-        rs.set_apply_callback(my_str2ary, _lims, "hello1", "hello1_cnt")
-        lims.append(rs)
+        # not used in BJ-318 startup screen
+        if self.MODEL != "BJ-318":
+            tmp = chars2str(_lims.hello1, _lims.hello1_cnt)
+            rs = RadioSetting("hello_lims.hello1", "Power-On Message 1",
+                              RadioSettingValueString(0, 7, tmp))
+            rs.set_apply_callback(my_str2ary, _lims, "hello1", "hello1_cnt")
+            lims.append(rs)

-        tmp = chars2str(_lims.hello2, _lims.hello2_cnt)
-        rs = RadioSetting("hello_lims.hello2", "Power-On Message 2",
-                          RadioSettingValueString(0, 7, tmp))
-        rs.set_apply_callback(my_str2ary, _lims, "hello2", "hello2_cnt")
-        lims.append(rs)
+        # not used in BJ-318 startup screen
+        if self.MODEL != "BJ-318":
+            tmp = chars2str(_lims.hello2, _lims.hello2_cnt)
+            rs = RadioSetting("hello_lims.hello2", "Power-On Message 2",
+                              RadioSettingValueString(0, 7, tmp))
+            rs.set_apply_callback(my_str2ary, _lims, "hello2", "hello2_cnt")
+            lims.append(rs)

         # VALID_BANDS = [(136000000, 176000000),400000000, 480000000)]

@@ -1460,3 +1610,23 @@

     def get_sub_devices(self):
         return [Baojie218Upper(self._mmap), Baojie218Lower(self._mmap)]
+
+
+class Baojie318Upper(LT725UVUpper):
+    VENDOR = "Baojie"
+    MODEL = "BJ-318"
+
+
+class Baojie318Lower(LT725UVLower):
+    VENDOR = "Baojie"
+    MODEL = "BJ-318"
+
+
+ at directory.register
+class Baojie318(LT725UV):
+    """Baojie BJ-318"""
+    VENDOR = "Baojie"
+    MODEL = "BJ-318"
+
+    def get_sub_devices(self):
+        return [Baojie318Upper(self._mmap), Baojie318Lower(self._mmap)]
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Baojie_BJ-318.img
Type: application/octet-stream
Size: 7341 bytes
Desc: not available
Url : http://intrepid.danplanet.com/pipermail/chirp_devel/attachments/20210412/752d351f/attachment-0001.img 


More information about the chirp_devel mailing list