diff --git a/chirp/drivers/mml_jc8810.py b/chirp/drivers/mml_jc8810.py
index e14ffabb..a370835b 100644
--- a/chirp/drivers/mml_jc8810.py
+++ b/chirp/drivers/mml_jc8810.py
@@ -88,10 +88,10 @@ struct {
u8 unknown_900b; // 900B
u8 unused_900c:5, // 900C
pttlt:3; // PTT Delay
- u8 unused_900d:7, // 900D
- mdfa:1; // Channel_A Display
- u8 unused_9003:7, // 900E
- mdfb:1; // Channel_B Display
+ u8 unused_900d:6, // 900D
+ mdfa:2; // Channel_A Display
+ u8 unused_9003:6, // 900E
+ mdfb:2; // Channel_B Display
u8 unknown_900f; // 900F
u8 unused_9010:4, // 9010
autolk:4; // Key Auto Lock
@@ -196,7 +196,7 @@ DTMFST_LIST = ["Off", "KeyBoard Side Tone", "ANI Side Tone", "KB ST + ANI ST"]
DUALTX_LIST = ["Off", "A", "B"]
ENCRYPT_LIST = ["Off", "DCP1", "DCP2", "DCP3"]
LANGUAGE_LIST = ["English", "Chinese"]
-MDF_LIST = ["Name", "Frequency"]
+MDF_LIST = ["Name", "Frequency", "Channel"]
MENUQUIT_LIST = ["%s seconds" % x for x in range(5, 55, 5)] + ["60 seconds"]
OFF1TO9_LIST = ["Off"] + ["%s" % x for x in range(1, 10)]
PONMSG_LIST = ["Logo", "Voltage"]
@@ -602,15 +602,24 @@ class JC8810base(chirp_common.CloneModeRadio):
mem.skip = "S"
_levels = self.POWER_LEVELS
- if _mem.txpower == TXPOWER_HIGH:
- mem.power = _levels[0]
- elif _mem.txpower == TXPOWER_MID:
- mem.power = _levels[1]
- elif _mem.txpower == TXPOWER_LOW:
- mem.power = _levels[2]
+ if self.MODEL == "UV-A37":
+ if _mem.txpower == TXPOWER_HIGH:
+ mem.power = _levels[0]
+ elif _mem.txpower == TXPOWER_LOW:
+ mem.power = _levels[1]
+ else:
+ LOG.error('%s: get_mem: unhandled power level: 0x%02x' %
+ (mem.name, _mem.txpower))
else:
- LOG.error('%s: get_mem: unhandled power level: 0x%02x' %
- (mem.name, _mem.txpower))
+ if _mem.txpower == TXPOWER_HIGH:
+ mem.power = _levels[0]
+ elif _mem.txpower == TXPOWER_MID:
+ mem.power = _levels[1]
+ elif _mem.txpower == TXPOWER_LOW:
+ mem.power = _levels[2]
+ else:
+ LOG.error('%s: get_mem: unhandled power level: 0x%02x' %
+ (mem.name, _mem.txpower))
mem.mode = _mem.narrow and "NFM" or "FM"
@@ -701,17 +710,28 @@ class JC8810base(chirp_common.CloneModeRadio):
_mem.narrow = mem.mode == "NFM"
_levels = self.POWER_LEVELS
- if mem.power is None:
- _mem.txpower = TXPOWER_HIGH
- elif mem.power == _levels[0]:
- _mem.txpower = TXPOWER_HIGH
- elif mem.power == _levels[1]:
- _mem.txpower = TXPOWER_MID
- elif mem.power == _levels[2]:
- _mem.txpower = TXPOWER_LOW
+ if self.MODEL == "UV-A37":
+ if mem.power is None:
+ _mem.txpower = TXPOWER_HIGH
+ elif mem.power == _levels[0]:
+ _mem.txpower = TXPOWER_HIGH
+ elif mem.power == _levels[1]:
+ _mem.txpower = TXPOWER_LOW
+ else:
+ LOG.error('%s: set_mem: unhandled power level: %s' %
+ (mem.name, mem.power))
else:
- LOG.error('%s: set_mem: unhandled power level: %s' %
- (mem.name, mem.power))
+ if mem.power is None:
+ _mem.txpower = TXPOWER_HIGH
+ elif mem.power == _levels[0]:
+ _mem.txpower = TXPOWER_HIGH
+ elif mem.power == _levels[1]:
+ _mem.txpower = TXPOWER_MID
+ elif mem.power == _levels[2]:
+ _mem.txpower = TXPOWER_LOW
+ else:
+ LOG.error('%s: set_mem: unhandled power level: %s' %
+ (mem.name, mem.power))
for setting in mem.extra:
if setting.get_name() == "scramble_type":
@@ -751,11 +771,12 @@ class JC8810base(chirp_common.CloneModeRadio):
rset = RadioSetting("voice", "Voice Prompts", rs)
basic.append(rset)
- # Menu 17: LANGUAGE
- rs = RadioSettingValueList(LANGUAGE_LIST,
- LANGUAGE_LIST[_settings.language])
- rset = RadioSetting("language", "Voice", rs)
- basic.append(rset)
+ if self.MODEL != "UV-A37":
+ # Menu 17: LANGUAGE
+ rs = RadioSettingValueList(LANGUAGE_LIST,
+ LANGUAGE_LIST[_settings.language])
+ rset = RadioSetting("language", "Voice", rs)
+ basic.append(rset)
# Menu 23: ABR
rs = RadioSettingValueList(ABR_LIST, ABR_LIST[_settings.abr])
@@ -821,6 +842,8 @@ class JC8810base(chirp_common.CloneModeRadio):
unwanted = [0, 7, 9]
elif self.MODEL in ["HI-8811", "RT-470L"]:
unwanted = [9]
+ elif self.MODEL in ["UV-A37"]:
+ unwanted = [0, 5, 7, 9]
else:
unwanted = []
SKEY2S_CHOICES = ALL_SKEY_CHOICES.copy()
@@ -850,6 +873,8 @@ class JC8810base(chirp_common.CloneModeRadio):
unwanted = [0, 7, 8, 9]
elif self.MODEL in ["HI-8811", "RT-470L"]:
unwanted = [8, 9]
+ elif self.MODEL in ["UV-A37"]:
+ unwanted = [0, 5, 7, 8]
else:
unwanted = []
SKEY2L_CHOICES = ALL_SKEY_CHOICES.copy()
@@ -879,6 +904,8 @@ class JC8810base(chirp_common.CloneModeRadio):
unwanted = [0, 7, 8, 9]
elif self.MODEL in ["HI-8811", "RT-470L"]:
unwanted = [8, 9]
+ elif self.MODEL in ["UV-A37"]:
+ unwanted = [0, 5, 7, 8, 9]
else:
unwanted = []
SKEY3S_CHOICES = ALL_SKEY_CHOICES.copy()
@@ -1055,11 +1082,12 @@ class JC8810base(chirp_common.CloneModeRadio):
rset = RadioSetting("beep", "Beep", rs)
basic.append(rset)
- # Menu 48: RX END TAIL
- rs = RadioSettingValueList(TONERXEND_LIST,
- TONERXEND_LIST[_settings.rxendtail])
- rset = RadioSetting("rxendtail", "Tone RX End", rs)
- basic.append(rset)
+ if self.MODEL not in ["UV-A37"]:
+ # Menu 48: RX END TAIL
+ rs = RadioSettingValueList(TONERXEND_LIST,
+ TONERXEND_LIST[_settings.rxendtail])
+ rset = RadioSetting("rxendtail", "Tone RX End", rs)
+ basic.append(rset)
dtmf = RadioSettingGroup("dtmf", "DTMF Settings")
group.append(dtmf)
@@ -1198,7 +1226,7 @@ class RT470Radio(JC8810base):
# ==========
# Notice to developers:
- # The RT-470 support in this driver is curretnly based upon v1.22 firmware.
+ # The RT-470 support in this driver is currently based upon v1.22 firmware.
# ==========
@@ -1210,7 +1238,7 @@ class RT470LRadio(JC8810base):
# ==========
# Notice to developers:
- # The RT-470 support in this driver is curretnly based upon v1.17 firmware.
+ # The RT-470 support in this driver is currently based upon v1.17 firmware.
# ==========
_fingerprint = [b"\x00\x00\x00\xfe\x00\x20\xAC\x04",
@@ -1236,6 +1264,41 @@ class HI8811Radio(RT470LRadio):
# ==========
# Notice to developers:
- # The HI-8811 support in this driver is curretnly based upon v1.17
+ # The HI-8811 support in this driver is currently based upon v1.17
# firmware.
# ==========
+
+
+@directory.register
+class UVA37Radio(JC8810base):
+ """Anysecu UV-A37"""
+ VENDOR = "Anysecu"
+ MODEL = "UV-A37"
+
+ # ==========
+ # Notice to developers:
+ # The UV-A37 support in this driver is currently based upon v1.24
+ # firmware.
+ # ==========
+
+ POWER_LEVELS = [chirp_common.PowerLevel("H", watts=5.00),
+ chirp_common.PowerLevel("L", watts=1.00)]
+
+ VALID_BANDS = [(108000000, 136000000),
+ (136000000, 174000000),
+ (200000000, 260000000),
+ (350000000, 390000000),
+ (400000000, 520000000)]
+
+ _magic = b"PROGRAMJC37U"
+ _fingerprint = [b"\x00\x00\x00\xE4\x00\x20\x94\x04",
+ b"\x00\x00\x00\xE8\x00\x20\x98\x04"]
+
+ _ranges = [
+ (0x0000, 0x2000),
+ (0x8000, 0x8040),
+ (0x9000, 0x9040),
+ (0xA000, 0xA140),
+ (0xB000, 0xB440)
+ ]
+ _memsize = 0xB440
diff --git a/tests/Python3_Driver_Testing.md b/tests/Python3_Driver_Testing.md
index 930fe18b..443d1833 100644
--- a/tests/Python3_Driver_Testing.md
+++ b/tests/Python3_Driver_Testing.md
@@ -20,6 +20,7 @@
| AnyTone_OBLTR-8R | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.02% |
| AnyTone_TERMN-8R | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.02% |
| Anysecu_AC-580 | [Implied by Radioddity_GS-5B](#user-content-Radioddity_GS-5B) | 17-Mar-2023 | Yes | |
+| Anysecu_UV-A37 | [@KC9HI](https://github.com/KC9HI) | 5-Jun-2023 | Yes | |
| Anysecu_WP-9900 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.03% |
| BTECH_FRS-A1 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.01% |
| BTECH_FRS-B1 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.04% |
@@ -408,11 +409,11 @@
| Zastone_ZT-X6 | [Implied by Retevis_RT22](#user-content-Retevis_RT22) | 9-Dec-2022 | Yes | 0.11% |
## Stats
-**Drivers:** 405
+**Drivers:** 406
-**Tested:** 86% (349/56) (93% of usage stats)
+**Tested:** 86% (350/56) (93% of usage stats)
-**Byte clean:** 89% (364/41)
+**Byte clean:** 89% (365/41)
## Meaning of this testing
diff --git a/tests/images/Anysecu_UV-A37.img b/tests/images/Anysecu_UV-A37.img
new file mode 100644
index 00000000..ecc4f5e5
Binary files /dev/null and b/tests/images/Anysecu_UV-A37.img differ
diff --git a/tests/py3_driver_testers.txt b/tests/py3_driver_testers.txt
index 38dea417..fd5238ee 100644
--- a/tests/py3_driver_testers.txt
+++ b/tests/py3_driver_testers.txt
@@ -19,6 +19,7 @@ Alinco_DR06T,+Alinco_DR235T,12-Dec-2022
Alinco_DR135T,+Alinco_DR235T,12-Dec-2022
Alinco_DR235T,@kk7ds,12-Dec-2022
Alinco_DR435T,+Alinco_DR235T,12-Dec-2022
+Anysecu_UV-A37,@KC9HI,5-Jun-2023
Anysecu_WP-9900,@KC9HI,11-Nov-2022
Anysecu_AC-580,+Radioddity_GS-5B,17-Mar-2023
AnyTone_778UV,+Retevis_RT95,13-Nov-2022