#!/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)