|
#!/usr/bin/env python
|
|
|
|
# Script to test the comms and get a dump of the
|
|
# Feidaxin FD-268A/B hand held radio memory.
|
|
#
|
|
# It works OK on windows with python 2.7.3 and pyserial 2.7
|
|
# It will try all comports from COM1 to COM10
|
|
#
|
|
# Author Pavel, CO7WT, co7wt@frcuba.co.cu
|
|
# Please send the img file to my email.
|
|
|
|
import serial
|
|
import struct
|
|
import os
|
|
import time
|
|
|
|
fpath = "c:\\"
|
|
filename = "fd-268"
|
|
|
|
def make_frame(cmd, addr, length):
|
|
"""Pack the info in the headder format"""
|
|
return struct.pack(">BHB", ord(cmd), addr, length)
|
|
|
|
def tx(radio, frame):
|
|
"""Send data to radio"""
|
|
radio.write(frame)
|
|
|
|
def rx(radio):
|
|
"""Get data from the radio"""
|
|
# 12 bytes: 4 bytes header + 8 data [MUST read it all together!!!]
|
|
rxdata = radio.read(12)
|
|
if (len(rxdata) != 12):
|
|
raise Exception, "Radio sent %i bytes, we expected 12" % (len(rxdata))
|
|
else:
|
|
cmd, addr, length = struct.unpack(">BHB", rxdata[:4])
|
|
|
|
data = rxdata[4:]
|
|
# send ACK
|
|
radio.write("\x06")
|
|
ack = radio.read(1)
|
|
if ack != "\x06" :
|
|
raise Exception, "Radio did not send ack"
|
|
|
|
return addr, data
|
|
|
|
def do_ident(radio):
|
|
"""Put the radio on PROGRAM mode"""
|
|
def do_magic():
|
|
"""Try to get the radio y program mode, this is standard
|
|
procedure of the ORIGINAL software from factory, we try
|
|
20 times to get the correct response, if not try again
|
|
manually"""
|
|
# every byte of this magic chain must be send separatedly
|
|
magic = "\x02PROGRA"
|
|
# get the buffer cleared, this leads to problems
|
|
radio.flushInput()
|
|
radio.flushOutput()
|
|
dumb = radio.read(8)
|
|
for a in range(0,20):
|
|
for i in range(0, len(magic)):
|
|
ack = radio.read(1)
|
|
radio.write(magic[i])
|
|
|
|
# Now you get a x06 of ACK
|
|
ack = radio.read(1)
|
|
if ack == "\x06":
|
|
return True
|
|
else:
|
|
print "\x0dAttempt %s didn't work, trying again..." % a,
|
|
|
|
return False
|
|
|
|
# try to get the radio in program mode
|
|
ack = do_magic()
|
|
if not ack:
|
|
raise Exception,"Radio did not accept program mode"
|
|
|
|
radio.write("M")
|
|
# now we request identification
|
|
radio.write("\x02")
|
|
ident = radio.read(8)
|
|
|
|
# final
|
|
radio.write("\x06")
|
|
ack2 = radio.read(1)
|
|
|
|
def dump_mem(radio):
|
|
"""Get the memory map"""
|
|
data = ""
|
|
for addr in range(0x0000, 0x0800, 8):
|
|
tx(radio, make_frame("R",addr,8))
|
|
_addr, _data = rx(radio)
|
|
data = data + _data
|
|
return data
|
|
|
|
# banner
|
|
banner = """############################################################################
|
|
This script will try to find a Feidaxin FD-268 A/B handheld connected to
|
|
COM1-COM10 port of this PC, then it will dump it's eeprom it to a file
|
|
in c:\\ named 'FD-268_x.img', where the 'x' is the COM port number where
|
|
it was found.
|
|
|
|
You are encouraged to send the img file to co7wt@frcuba.co.cu for
|
|
completing the development of the CHIRP driver for this radio.
|
|
|
|
Thanks, CO7WT, Pavel co7wt@frcuba.co.cu
|
|
############################################################################
|
|
|
|
"""
|
|
|
|
print(banner)
|
|
print "Last chance to quit (Ctrl-C) in "
|
|
for t in range(0, 30):
|
|
print "\x0d" + str(30 -t) + " seconds",
|
|
time.sleep(1)
|
|
|
|
print " "
|
|
|
|
# main program
|
|
for sp in range(1, 11):
|
|
# try to identify valid COM ports and use them to download img of the radio
|
|
# the IMG will be on c:\fd-268-(COMx).img
|
|
|
|
try:
|
|
radio = serial.Serial(port="COM" + str(sp)) # for windows
|
|
except Exception, e:
|
|
continue
|
|
|
|
# this port works
|
|
print " "
|
|
print("Serial por COM%s available, traying to reach radio" % sp)
|
|
|
|
try:
|
|
radio.setBaudrate(9600)
|
|
radio.setParity("N")
|
|
radio.setTimeout(0.1)
|
|
radio.flushInput()
|
|
radio.flushOutput()
|
|
except Exception, e:
|
|
print " "
|
|
print("Problem setting discipline on COM%s" % sp)
|
|
continue
|
|
|
|
# ok, will try to reach radio
|
|
print " "
|
|
do_ident(radio)
|
|
print " "
|
|
print " "
|
|
print("Radio Found!!!, downloading image to %s_%s.img" % (filename, sp) )
|
|
d = dump_mem(radio)
|
|
|
|
# save to file % dump to screen
|
|
print " "
|
|
print " "
|
|
print("Done, img file ready to send to co7wt@frcuba.co.cu")
|
|
fil = open(os.path.join(fpath, filename + "_" + str(sp) + ".img" ), 'wb')
|
|
fil.write(d)
|
|
fil.close()
|
|
|
|
# wait delay
|
|
print " "
|
|
end = """############################################################################
|
|
|
|
Done, if it don't worked, check your interface and radio and try again.
|
|
|
|
It's safe to close this windows or Ctrl-C to end, or wait one minute
|
|
until windows closes itself.
|
|
|
|
Thanks for participate.
|
|
|
|
"""
|
|
print end
|
|
time.sleep(60)
|
|
|