Update Firmware & README.md

This commit is contained in:
spm81 2023-09-28 00:58:45 +01:00
parent 9e5e9738df
commit d1f54175d2
12 changed files with 654 additions and 1 deletions

View File

@ -4,6 +4,6 @@ MCFW V0.01 - Only release on Telegram for feedback, (buggy version). <br>
MCFW V0.02 - Based on Open Spectrum Firmware - OSFW-ecd267e by fagci + Old Style Keys + RSSI + Voltage + improvement in SATCOM reception. <br>
MCFW V0.03 - Based on Open Spectrum Firmware - OSFW-40e01a6 by Tunas1337 with facgi Spectrum + New Menu + Old Style Keys + RSSI + improvement in SATCOM reception.<br>
MCFW V0.04 - Based on Open Spectrum Firmware - OSFW-502a638 by Tunas1337 with facgi Spectrum + New Menu + Old Style Keys + RSSI + Voltage + improvement in SATCOM reception.
MCFW V0.05 - Based on Open Spectrum Firmware - OSFW-7bcb669 by Tunas1337 with facgi Spectrum + New Menu + Old Style Keys + RSSI + Voltage + Unlimited Freq. Scan + improvement in SATCOM reception.
Fagci Spectrum Help (are not the "Old Style Keys" but the rest is iqual)

View File

@ -20,6 +20,12 @@ A cool achievement
<img src="image5.jpg" width="300" />
</p><br>
Video showing the AM fix working ..
<video src="AM_fix.mp4"></video>
<video src="https://github.com/OneOfEleven/uv-k5-firmware-custom/assets/51590168/2a3a9cdc-97da-4966-bf0d-1ce6ad09779c"></video>
# Matoz Add-ons
F-LOCK PMR = ( Disables TX on all bands except PMR446 )

View File

@ -0,0 +1,66 @@
import libuvk5
import sys,os
import struct
if len(sys.argv)<3: print(f'Usage: {os.path.basename(sys.argv[0])} <COMx> <read | write val0 val1 val2 val3 val4 val5 | calibrate>') ; exit(1)
arg_port = sys.argv[1]
action = sys.argv[2]
with libuvk5.uvk5(arg_port) as radio:
radio.debug=False
if radio.connect():
_=radio.get_fw_version() #mandatory before reading mem
calib_raw = radio.get_cfg_mem(0x1F40,16)
calib_data = list(struct.unpack('<8H',calib_raw))
calib_data_old = [i for i in calib_data]
if action == 'read':
def calculate_voltage(value, denominator):
if denominator != 0:
return 760 * value / denominator / 100
else:
return 0 # Handle the division by zero case
print('Level {}: [{:>4}] {:.2f} V {}'.format(0, calib_data[0], calculate_voltage(calib_data[0], calib_data[3]), '// Empty battery blinking'))
print('Level {}: [{:>4}] {:.2f} V {}'.format(1, calib_data[1], calculate_voltage(calib_data[1], calib_data[3]), '// 1 battery bar if above this value'))
print('Level {}: [{:>4}] {:.2f} V {}'.format(2, calib_data[2], calculate_voltage(calib_data[2], calib_data[3]), '// 2 battery bars if above this value'))
print('Level {}: [{:>4}] {:.2f} V {}'.format(3, calib_data[3], calculate_voltage(calib_data[3], calib_data[3]), '// 3 battery bars if above this value, also value used to calculate adc to volt'))
print('Level {}: [{:>4}] {:.2f} V {}'.format(4, calib_data[4], calculate_voltage(calib_data[4], calib_data[3]), '// 4 battery bars if above this value'))
print('Level {}: [{:>4}] {:.2f} V {}'.format(5, calib_data[5], calculate_voltage(calib_data[5], calib_data[3]), '// overwritten by radio to 2300 anyway'))
print('\nActual = {:.2f} V'.format(calculate_voltage(radio.get_adc()[0], calib_data[3])))
if action=='write':
if len(sys.argv)!=9: print(f'Usage: {os.path.basename(sys.argv[0])} <COMx> write val0 val1 val2 val3 val4 val5') ; exit(1)
calib_data[0] = int(sys.argv[3],0)
calib_data[1] = int(sys.argv[4],0)
calib_data[2] = int(sys.argv[5],0)
calib_data[3] = int(sys.argv[6],0)
calib_data[4] = int(sys.argv[7],0)
calib_data[5] = int(sys.argv[8],0)
calib_raw = struct.pack('<8H',*calib_data)
radio.set_cfg_mem(0x1F40,calib_raw)
if action=='calibrate':
while True:
actual_voltage = input("Enter voltage from multimeter and press enter: ")
try:
actual_voltage = float(actual_voltage.replace(',','.'))
except:
actual_voltage = None
if actual_voltage is not None:
break
adc_value = radio.get_adc()[0]
new_coeff = int(760*adc_value/actual_voltage/100)
print('Current battery voltage = {:.2f}'.format(760*adc_value/calib_data[3]/100))
print('Current battery ADC coefficient = {}'.format(calib_data[3]))
print('')
print('Desired battery voltage = {:.2f}'.format(actual_voltage))
print('New battery ADC coefficient = {}'.format(new_coeff))
print('Wait... ', end='')
calib_data[3] = new_coeff
calib_raw = struct.pack('<8H',*calib_data)
radio.set_cfg_mem(0x1F40,calib_raw)
print('OK. New value written to eeprom')
print('Previous calibration values:',calib_data_old[0:6])
print('Current calibration values :',struct.unpack('<8H',radio.get_cfg_mem(0x1F40,16))[0:6])
print('')
print('!!! PLEASE REBOOT RADIO FOR THE CHANGES TO TAKE EFFECT !!!')

View File

@ -0,0 +1,234 @@
import serial
import struct
import os
Crc16Tab = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302,
37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907,
9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789,
59790, 63919, 35144, 39273, 43274, 47403, 23285, 19156, 31415, 27286, 6769, 2640,14899, 10770, 56317, 52188, 64447, 60318, 39801, 35672, 47931, 43802, 27814, 31879,
19684, 23749, 11298, 15363, 3168, 7233, 60846, 64911, 52716, 56781, 44330, 48395,36200, 40265, 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696, 65439, 61374,
57309, 53244, 48923, 44858, 40793, 36728, 37256, 33193, 45514, 41451, 53516, 49453, 61774, 57711, 4224, 161, 12482, 8419, 20484, 16421, 28742, 24679, 33721, 37784, 41979,
46042, 49981, 54044, 58239, 62302, 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270, 46570, 42443, 38312, 34185, 62830, 58703, 54572, 50445, 13538, 9411, 5280, 1153, 29798,
25671, 21540, 17413, 42971, 47098, 34713, 38840, 59231, 63358, 50973, 55100, 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22068, 55628, 51565, 63758, 59695, 39368,
35305, 47498, 43435, 22596, 18533, 30726, 26663, 6336, 2273, 14466, 10403, 52093, 56156, 60223, 64286, 35833, 39896, 43963, 48026, 19061, 23124, 27191, 31254, 2801,
6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955,
49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920]
def crc16_ccitt(data):
i2 = 0
for i3 in range(0, len(data)):
out = Crc16Tab[((i2 >> 8) ^ data[i3]) & 255]
i2 = out ^ (i2 << 8)
return 65535 & i2
def crc16_ccitt_le(data):
crc = crc16_ccitt(data)
return bytes([crc & 0xFF,]) + bytes([crc>>8,])
def firmware_xor(fwcontent):
XOR_ARRAY = bytes.fromhex('4722c0525d574894b16060db6fe34c7cd84ad68b30ec25e04cd9007fbfe35405e93a976bb06e0cfbb11ae2c9c15647e9baf142b6675f0f96f7c93c841b26e14e3b6f66e6a06ab0bfc6a5703aba189e271a535b71b1941e18f2d6810222fd5a2891dbba5d64c6fe86839c501c730311d6af30f42c77b27dbb3f29285722d6928b')
XOR_LEN = len(XOR_ARRAY)
ba=bytearray(fwcontent)
for i in range(0,len(ba)):
ba[i] ^= XOR_ARRAY[i%XOR_LEN]
return bytes(ba)
def payload_xor(payload):
XOR_ARRAY = bytes.fromhex('166c14e62e910d402135d5401303e980')
XOR_LEN = len(XOR_ARRAY)
ba=bytearray(payload)
for i in range(0,len(ba)):
ba[i] ^= XOR_ARRAY[i%XOR_LEN]
return bytes(ba)
#================================================================================================================
class uvk5:
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
pass
def __init__(self,portName='COM1'):
self.serial = serial.Serial()
self.serial.baudrate = 38400
self.serial.timeout=1
self.serial.port=portName
self.sessTimestamp = b'\x46\x9C\x6F\x64'
self.CMD_GET_FW_VER = b'\x14\x05' #0x0514 -> 0x0515
self.CMD_READ_FW_MEM = b'\x17\x05' #0x0517 -> 0x0518
self.CMD_WRITE_FW_MEM = b'\x19\x05' #0x0519 -> 0x051a //Only in bootloader
self.CMD_READ_CFG_MEM = b'\x1B\x05' #0x051B -> 0x051C
self.CMD_WRITE_CFG_MEM= b'\x1D\x05' #0x051D -> 0x051E
self.CMD_052D = b'\x2D\x05'
self.CMD_051F = b'\x1F\x05'
self.CMD_052F = b'\x2F\x05'
self.CMD_REBOOT = b'\xDD\x05' #0x05DD -> no reply
self.CMD_0530 = b'\x30\x05' #0x0530 -> no reply //Only in bootloader
self.CMD_0527 = b'\x27\x05'
self.CMD_0529 = b'\x29\x05'
self.debug = False if os.getenv('DEBUG') is None else True
def __del__(self):
self.serial.close()
return not self.serial.is_open
def connect(self):
self.serial.open()
return self.serial.is_open
def uart_send_msg(self,msg_dec):
if self.debug: print('>dec>',msg_dec.hex())
msg_raw = msg_dec[:4] + payload_xor(msg_dec[4:-2]) + msg_dec[-2:]
if self.debug: print('>raw>',msg_raw.hex())
return self.serial.write(msg_raw)
def uart_receive_msg(self,len):
msg_raw = self.serial.read(len)
if self.debug: print('<raw<',msg_raw.hex())
msg_dec = msg_raw[:4] + payload_xor(msg_raw[4:-2]) + msg_raw[-2:]
if self.debug: print('<dec<',msg_dec.hex())
return msg_dec
def build_uart_command(self, command_type, command_body=b''):
cmd = command_type + struct.pack('<H',len(command_body))+ command_body
cmd_len = struct.pack('<H',len(cmd))
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd = b'\xAB\xCD' + cmd_len + cmd + cmd_crc + b'\xDC\xBA'
return cmd
def get_fw_version(self):
cmd=self.build_uart_command(self.CMD_GET_FW_VER, self.sessTimestamp)
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[8:].split(b'\0', 1)[0].decode()
def get_cfg_mem(self,address,length):
cmd=self.build_uart_command(self.CMD_READ_CFG_MEM, struct.pack('<HH',address,length) + self.sessTimestamp)
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(length+16)
return reply[12:-4]
def set_cfg_mem(self,address,payload):
if len(payload)%8==0:
cmd=self.CMD_WRITE_CFG_MEM + struct.pack('<HHH',len(payload)+8, address, len(payload)) + self.sessTimestamp + payload
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd=b'\xAB\xCD' + struct.pack('<H',len(payload)+0xC) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(14)
return reply[12:-4]
else:
raise Exception('Payload have to be multiples of 8 bytes')
def reboot(self):
cmd = self.CMD_REBOOT + b'\x00\x00'
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',4) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
return True
def get_fw_mem(self,address,length):
cmd=self.CMD_READ_FW_MEM #+ b'\x00\x00' # struct.pack('<HH',address,length)
cmd= b'\x00\x05' #+ b'\x00\x00' # struct.pack('<HH',address,length)
cmd_crc = b'' #struct.pack('<H',crc16_ccitt(cmd))
cmd=b'\xAB\xCD' + struct.pack('<H',len(cmd)) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(1024)
return reply[12:-4]
#def set_fw_mem(self,block,payload):
# bytes_to_write = length(payload)
# padd_bytes = b'\x00'*(1000 - bytes_to_write)
# payload=payload+padd_bytes
# print(payload.hex())
# cmd=self.build_uart_command(self.CMD_WRITE_FW_MEM, struct.pack('<IIII',block,bytes_to_write,0xe6,0) + self.sessTimestamp + payload)
# self.uart_send_msg(cmd)
# reply = self.uart_receive_msg(128)
# return reply[12:-4]
def unk_fn_0530(self,text):
buff = bytes(text,'ascii') + b'\x00'*(16-len(text))
cmd = self.CMD_0530 + struct.pack('<H',16) + buff
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',20) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def unk_fn_051F(self):
# 0/1 + 2/3
cmd = self.CMD_051F + struct.pack('<H',18)+ \
struct.pack('<I',433000000) + \
struct.pack('<H',0x00) + \
struct.pack('<H',0x7F) + \
struct.pack('<H',0xFF) + \
struct.pack('<H',0x00) + \
struct.pack('<H',0x7F) + \
struct.pack('<H',0xFF) + \
struct.pack('<H',1)
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',22) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def unk_fn_052F(self):
# 0/1 + 2/3
cmd = self.CMD_052F + struct.pack('<H',4) + self.sessTimestamp
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',8) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def unk_fn_1325(self,uint1,uint2,uint3,uint4):
cmd = self.CMD_052D + struct.pack('<HIIII',16,uint1,uint2,uint3,uint4)
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',20) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def get_rssi(self):
cmd = self.CMD_0527 + struct.pack('<H',4) + self.sessTimestamp
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd = b'\xAB\xCD' + struct.pack('<H',8) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(16)
rssi,noise,glitch = struct.unpack('<HBB',reply[8:-4])
rssi = rssi / 2 - 160
return {'rssi':rssi, 'noise':noise, 'glitch':glitch, 'raw':reply[8:-4].hex()}
def get_adc(self):
cmd = self.CMD_0529 + struct.pack('<H',4) + self.sessTimestamp
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd = b'\xAB\xCD' + struct.pack('<H',8) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(16)
reply = struct.unpack('<HH',reply[8:-4])
return reply

View File

@ -0,0 +1,234 @@
import serial
import struct
import os
Crc16Tab = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302,
37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907,
9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789,
59790, 63919, 35144, 39273, 43274, 47403, 23285, 19156, 31415, 27286, 6769, 2640,14899, 10770, 56317, 52188, 64447, 60318, 39801, 35672, 47931, 43802, 27814, 31879,
19684, 23749, 11298, 15363, 3168, 7233, 60846, 64911, 52716, 56781, 44330, 48395,36200, 40265, 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696, 65439, 61374,
57309, 53244, 48923, 44858, 40793, 36728, 37256, 33193, 45514, 41451, 53516, 49453, 61774, 57711, 4224, 161, 12482, 8419, 20484, 16421, 28742, 24679, 33721, 37784, 41979,
46042, 49981, 54044, 58239, 62302, 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270, 46570, 42443, 38312, 34185, 62830, 58703, 54572, 50445, 13538, 9411, 5280, 1153, 29798,
25671, 21540, 17413, 42971, 47098, 34713, 38840, 59231, 63358, 50973, 55100, 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22068, 55628, 51565, 63758, 59695, 39368,
35305, 47498, 43435, 22596, 18533, 30726, 26663, 6336, 2273, 14466, 10403, 52093, 56156, 60223, 64286, 35833, 39896, 43963, 48026, 19061, 23124, 27191, 31254, 2801,
6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955,
49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920]
def crc16_ccitt(data):
i2 = 0
for i3 in range(0, len(data)):
out = Crc16Tab[((i2 >> 8) ^ data[i3]) & 255]
i2 = out ^ (i2 << 8)
return 65535 & i2
def crc16_ccitt_le(data):
crc = crc16_ccitt(data)
return bytes([crc & 0xFF,]) + bytes([crc>>8,])
def firmware_xor(fwcontent):
XOR_ARRAY = bytes.fromhex('4722c0525d574894b16060db6fe34c7cd84ad68b30ec25e04cd9007fbfe35405e93a976bb06e0cfbb11ae2c9c15647e9baf142b6675f0f96f7c93c841b26e14e3b6f66e6a06ab0bfc6a5703aba189e271a535b71b1941e18f2d6810222fd5a2891dbba5d64c6fe86839c501c730311d6af30f42c77b27dbb3f29285722d6928b')
XOR_LEN = len(XOR_ARRAY)
ba=bytearray(fwcontent)
for i in range(0,len(ba)):
ba[i] ^= XOR_ARRAY[i%XOR_LEN]
return bytes(ba)
def payload_xor(payload):
XOR_ARRAY = bytes.fromhex('166c14e62e910d402135d5401303e980')
XOR_LEN = len(XOR_ARRAY)
ba=bytearray(payload)
for i in range(0,len(ba)):
ba[i] ^= XOR_ARRAY[i%XOR_LEN]
return bytes(ba)
#================================================================================================================
class uvk5:
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
pass
def __init__(self,portName='COM1'):
self.serial = serial.Serial()
self.serial.baudrate = 38400
self.serial.timeout=1
self.serial.port=portName
self.sessTimestamp = b'\x46\x9C\x6F\x64'
self.CMD_GET_FW_VER = b'\x14\x05' #0x0514 -> 0x0515
self.CMD_READ_FW_MEM = b'\x17\x05' #0x0517 -> 0x0518
self.CMD_WRITE_FW_MEM = b'\x19\x05' #0x0519 -> 0x051a //Only in bootloader
self.CMD_READ_CFG_MEM = b'\x1B\x05' #0x051B -> 0x051C
self.CMD_WRITE_CFG_MEM= b'\x1D\x05' #0x051D -> 0x051E
self.CMD_052D = b'\x2D\x05'
self.CMD_051F = b'\x1F\x05'
self.CMD_052F = b'\x2F\x05'
self.CMD_REBOOT = b'\xDD\x05' #0x05DD -> no reply
self.CMD_0530 = b'\x30\x05' #0x0530 -> no reply //Only in bootloader
self.CMD_0527 = b'\x27\x05'
self.CMD_0529 = b'\x29\x05'
self.debug = False if os.getenv('DEBUG') is None else True
def __del__(self):
self.serial.close()
return not self.serial.is_open
def connect(self):
self.serial.open()
return self.serial.is_open
def uart_send_msg(self,msg_dec):
if self.debug: print('>dec>',msg_dec.hex())
msg_raw = msg_dec[:4] + payload_xor(msg_dec[4:-2]) + msg_dec[-2:]
if self.debug: print('>raw>',msg_raw.hex())
return self.serial.write(msg_raw)
def uart_receive_msg(self,len):
msg_raw = self.serial.read(len)
if self.debug: print('<raw<',msg_raw.hex())
msg_dec = msg_raw[:4] + payload_xor(msg_raw[4:-2]) + msg_raw[-2:]
if self.debug: print('<dec<',msg_dec.hex())
return msg_dec
def build_uart_command(self, command_type, command_body=b''):
cmd = command_type + struct.pack('<H',len(command_body))+ command_body
cmd_len = struct.pack('<H',len(cmd))
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd = b'\xAB\xCD' + cmd_len + cmd + cmd_crc + b'\xDC\xBA'
return cmd
def get_fw_version(self):
cmd=self.build_uart_command(self.CMD_GET_FW_VER, self.sessTimestamp)
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[8:].split(b'\0', 1)[0].decode()
def get_cfg_mem(self,address,length):
cmd=self.build_uart_command(self.CMD_READ_CFG_MEM, struct.pack('<HH',address,length) + self.sessTimestamp)
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(length+16)
return reply[12:-4]
def set_cfg_mem(self,address,payload):
if len(payload)%8==0:
cmd=self.CMD_WRITE_CFG_MEM + struct.pack('<HHH',len(payload)+8, address, len(payload)) + self.sessTimestamp + payload
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd=b'\xAB\xCD' + struct.pack('<H',len(payload)+0xC) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(14)
return reply[12:-4]
else:
raise Exception('Payload have to be multiples of 8 bytes')
def reboot(self):
cmd = self.CMD_REBOOT + b'\x00\x00'
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',4) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
return True
def get_fw_mem(self,address,length):
cmd=self.CMD_READ_FW_MEM #+ b'\x00\x00' # struct.pack('<HH',address,length)
cmd= b'\x00\x05' #+ b'\x00\x00' # struct.pack('<HH',address,length)
cmd_crc = b'' #struct.pack('<H',crc16_ccitt(cmd))
cmd=b'\xAB\xCD' + struct.pack('<H',len(cmd)) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(1024)
return reply[12:-4]
#def set_fw_mem(self,block,payload):
# bytes_to_write = length(payload)
# padd_bytes = b'\x00'*(1000 - bytes_to_write)
# payload=payload+padd_bytes
# print(payload.hex())
# cmd=self.build_uart_command(self.CMD_WRITE_FW_MEM, struct.pack('<IIII',block,bytes_to_write,0xe6,0) + self.sessTimestamp + payload)
# self.uart_send_msg(cmd)
# reply = self.uart_receive_msg(128)
# return reply[12:-4]
def unk_fn_0530(self,text):
buff = bytes(text,'ascii') + b'\x00'*(16-len(text))
cmd = self.CMD_0530 + struct.pack('<H',16) + buff
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',20) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def unk_fn_051F(self):
# 0/1 + 2/3
cmd = self.CMD_051F + struct.pack('<H',18)+ \
struct.pack('<I',433000000) + \
struct.pack('<H',0x00) + \
struct.pack('<H',0x7F) + \
struct.pack('<H',0xFF) + \
struct.pack('<H',0x00) + \
struct.pack('<H',0x7F) + \
struct.pack('<H',0xFF) + \
struct.pack('<H',1)
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',22) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def unk_fn_052F(self):
# 0/1 + 2/3
cmd = self.CMD_052F + struct.pack('<H',4) + self.sessTimestamp
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',8) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def unk_fn_1325(self,uint1,uint2,uint3,uint4):
cmd = self.CMD_052D + struct.pack('<HIIII',16,uint1,uint2,uint3,uint4)
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd= b'\xAB\xCD' + struct.pack('<H',20) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(128)
return reply[12:-4]
def get_rssi(self):
cmd = self.CMD_0527 + struct.pack('<H',4) + self.sessTimestamp
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd = b'\xAB\xCD' + struct.pack('<H',8) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(16)
rssi,noise,glitch = struct.unpack('<HBB',reply[8:-4])
rssi = rssi / 2 - 160
return {'rssi':rssi, 'noise':noise, 'glitch':glitch, 'raw':reply[8:-4].hex()}
def get_adc(self):
cmd = self.CMD_0529 + struct.pack('<H',4) + self.sessTimestamp
cmd_crc = struct.pack('<H',crc16_ccitt(cmd))
cmd = b'\xAB\xCD' + struct.pack('<H',8) + cmd + cmd_crc + b'\xDC\xBA'
self.uart_send_msg(cmd)
reply = self.uart_receive_msg(16)
reply = struct.unpack('<HH',reply[8:-4])
return reply

View File

@ -0,0 +1,68 @@
import libuvk5
import sys
import os
# Handle arguments
# if len(sys.argv) not in [4,5]: print(f'Usage: {os.path.basename(sys.argv[0])} <COMx> <address> <len> [dest_file.bin]') ; exit(1)
arg_port = sys.argv[1]
if len(sys.argv)==5:
arg_file=sys.argv[4]
else:
arg_file=None
# SquelchOpenRSSIThreshold,
# SquelchCloseRSSIThreshold,
# SquelchOpenNoiseThreshold,
# SquelchCloseNoiseThreshold,
# SquelchCloseGlitchThreshold,
# SquelchOpenGlitchThreshold
# Connect and read
with libuvk5.uvk5(arg_port) as radio:
if radio.connect():
_=radio.get_fw_version() #mandatory before reading mem
# print radio.get_cfg_mem(0x1e00,10).hex() but in comma separated hex digits
# for i in range(12):
# print(str(0x1e00+i*0x10) + ": ", end='')
# temp = radio.get_cfg_mem(0x1e00+i*0x10,10).hex()
# temp = ','.join([f'0x{temp[i:i+2]}' for i in range(0,len(temp),2)])
# print(temp)
# sys.exit(0)
print("UHF Squelch Open RSSI Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e00+i,1).hex(),16)/2-160))
print("UHF Squelch Close RSSI Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e10+i,1).hex(),16)/2-160))
print("UHF Squelch Open Noise Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e20+i,1).hex(),16)))
print("UHF Squelch Close Noise Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e30+i,1).hex(),16)))
print("UHF Squelch Close Glitch Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e40+i,1).hex(),16)))
print("UHF Squelch Open Glitch Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e50+i,1).hex(),16)))
print("VHF Squelch Open RSSI Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e60+i,1).hex(),16)/2-160))
print("VHF Squelch Close RSSI Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e70+i,1).hex(),16)/2-160))
print("VHF Squelch Open Noise Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e80+i,1).hex(),16)))
print("VHF Squelch Close Noise Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1e90+i,1).hex(),16)))
print("VHF Squelch Close Glitch Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1ea0+i,1).hex(),16)))
print("VHF Squelch Open Glitch Thresholds:")
for i in range(10):
print("SQL " + str(i) + ": " + str(int(radio.get_cfg_mem(0x1eb0+i,1).hex(),16)))

View File

@ -0,0 +1,45 @@
import libuvk5
import sys
import os
# Handle arguments
if len(sys.argv) not in [2,3]: print(f'Usage: {os.path.basename(sys.argv[0])} <COMx> <address> <hex_payload>') ; exit(1)
arg_port = sys.argv[1]
# Defaults taken from my radio
# To get from RSSI to the byte value, use the following formula:
# byte_value = (rssi + 160) / 2
uhf_squelch_open_rssi = bytearray([0x0a,0x35,0x53,0x56,0x59,0x5c,0x5f,0x62,0x64,0x66,0xff,0xff,0xff,0xff,0xff,0xff])
uhf_squelch_close_rssi = bytearray([0x05,0x30,0x50,0x53,0x56,0x59,0x5c,0x5f,0x62,0x64,0xff,0xff,0xff,0xff,0xff,0xff])
uhf_squelch_open_noise = bytearray([0x5a,0x2a,0x29,0x26,0x23,0x20,0x1d,0x1a,0x17,0x14,0xff,0xff,0xff,0xff,0xff,0xff])
uhf_squelch_close_noise = bytearray([0x64,0x2f,0x2d,0x29,0x26,0x23,0x20,0x1d,0x1a,0x17,0xff,0xff,0xff,0xff,0xff,0xff])
uhf_squelch_close_glitch = bytearray([0x5a,0x12,0x11,0x0e,0x0b,0x08,0x03,0x02,0x02,0x02,0xff,0xff,0xff,0xff,0xff,0xff])
uhf_squelch_open_glitch = bytearray([0x64,0x10,0x0e,0x0b,0x08,0x05,0x05,0x04,0x04,0x04,0xff,0xff,0xff,0xff,0xff,0xff])
vhf_squelch_open_rssi = bytearray([0x32,0x58,0x6b,0x6e,0x6f,0x72,0x75,0x77,0x79,0x7b,0xff,0xff,0xff,0xff,0xff,0xff])
vhf_squelch_close_rssi = bytearray([0x28,0x54,0x67,0x6a,0x6c,0x6e,0x71,0x73,0x76,0x78,0xff,0xff,0xff,0xff,0xff,0xff])
vhf_squelch_open_noise = bytearray([0x41,0x32,0x2d,0x28,0x24,0x21,0x1e,0x1a,0x17,0x16,0xff,0xff,0xff,0xff,0xff,0xff])
vhf_squelch_close_noise = bytearray([0x46,0x39,0x32,0x2d,0x28,0x25,0x22,0x1e,0x1b,0x19,0xff,0xff,0xff,0xff,0xff,0xff])
vhf_squelch_close_glitch = bytearray([0x5a,0x12,0x0f,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0xff,0xff,0xff,0xff,0xff,0xff])
vhf_squelch_open_glitch = bytearray([0x64,0x1e,0x14,0x0f,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0xff,0xff,0xff,0xff,0xff,0xff])
# Connect and read
with libuvk5.uvk5(arg_port) as radio:
if radio.connect():
_=radio.get_fw_version() #mandatory before reading mem
radio.set_cfg_mem(0x1e00,uhf_squelch_open_rssi).hex()
radio.set_cfg_mem(0x1e10,uhf_squelch_close_rssi).hex()
radio.set_cfg_mem(0x1e20,uhf_squelch_open_noise).hex()
radio.set_cfg_mem(0x1e30,uhf_squelch_close_noise).hex()
radio.set_cfg_mem(0x1e40,uhf_squelch_close_glitch).hex()
radio.set_cfg_mem(0x1e50,uhf_squelch_open_glitch).hex()
radio.set_cfg_mem(0x1e60,vhf_squelch_open_rssi).hex()
radio.set_cfg_mem(0x1e70,vhf_squelch_close_rssi).hex()
radio.set_cfg_mem(0x1e80,vhf_squelch_open_noise).hex()
radio.set_cfg_mem(0x1e90,vhf_squelch_close_noise).hex()
radio.set_cfg_mem(0x1ea0,vhf_squelch_close_glitch).hex()
radio.set_cfg_mem(0x1eb0,vhf_squelch_open_glitch).hex()