From ba7e43c6653ac3a4b464caf7384260eaef5bf4fd Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 9 Jul 2013 22:47:06 +0000 Subject: moved downloader to bootloader dir git-svn-id: https://svn.spreadspace.org/pic/trunk@63 a09c6847-51d9-44de-8ef2-e725cf50f3c7 --- downloader/downloader.py | 353 ----------------------------------------------- 1 file changed, 353 deletions(-) delete mode 100755 downloader/downloader.py (limited to 'downloader/downloader.py') diff --git a/downloader/downloader.py b/downloader/downloader.py deleted file mode 100755 index 459e0d2..0000000 --- a/downloader/downloader.py +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/python -# -# spreadspace pic utils -# -# -# Copyright (C) 2011 Christian Pointner -# -# This file is part of spreadspace pic utils. -# -# spreadspace pic utils 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 3 of the License, or -# any later version. -# -# spreadspace pic utils is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with spreadspace pic utils. If not, see . -# - -'''spreadspace simple pic downloader.''' - -VERSION_MAJ = 0 -VERSION_MIN = 1 - -### HEX File Magic - -def load_hex(file): - from intelhex import IntelHex - - fin = file - if fin == '-': - fin = sys.stdin - elif not os.path.isfile(fin): - print >> sys.stderr, "ERROR: File not found: %s" % fin - sys.exit(1) - - codedata = {} - ih = IntelHex(fin) - for a in ih.addresses(): - if a/2 not in codedata.keys(): - codedata[a/2] = 0 - if a%2 == 0: - codedata[a/2] += ih[a] - else: - codedata[a/2] += (ih[a] << 8) - - return codedata - -def write_hex(file, codedata): - from intelhex import IntelHex - - fin = file - if fin == '-': - fin = sys.stdout - - hexdata = {} - for a in codedata: - hexdata[2*a] = codedata[a] & 0xFF - hexdata[2*a+1] = codedata[a] >> 8 - - ih = IntelHex() - ih.fromdict(hexdata) - ih.write_hex_file(fin) - - -def get_lowest_flash_addr(codedata, fss): - lowest_code_addr = sorted(codedata.keys())[0] - return lowest_code_addr - (lowest_code_addr%fss) - -def get_highest_flash_addr(codedata, fss): - highest_code_addr = sorted(codedata.keys())[-1] - return highest_code_addr + (fss - highest_code_addr%fss) - -def create_flash_image(codedata, fss, sa, ea): - img = ( sa, [0xFFFF]*(ea-sa) ) - for a,d in codedata.items(): - if a < ea: - img[1][a-sa] = d - return img - -def create_flash_segments(codedata, fs, fss): - sa = get_lowest_flash_addr(codedata, fss) - ea = get_highest_flash_addr(codedata, fss) - if ea >= fs: - print >> sys.stderr, "WARNING: the hex file contains data after end of flash, these words will be ignored" - ea = fs - - img = create_flash_image(codedata, fss, sa, ea) - for i in xrange(0, ea, fss): - slice = tuple(img[1][i:i+fss]) - if not all( (elem == 0xFFFF) for elem in slice): - yield (i + img[0], slice) - - -### Interface to Bootloader - -def open_serial(device, baud): - import os - import tty - import termios - import serial - - print >> sys.stderr, "opening %s (%s Baud)" % (device, baud) - - try: - dev = serial.Serial(port=device, baudrate=baud, timeout=3) - dev.flushInput() - dev.flushOutput() - return dev - - except (ValueError, serial.SerialException), msg: - print >> sys.stderr, "ERROR: opening serial device: %s" % msg - sys.exit(3) - -def calc_csum(str): - cs = 0 - for c in str: - cs ^= c - return cs - -def exec_command(dev, cmd, param, answer): - import struct - - return_codes = { 0: "OK", 1: "invalid command", 2: "bad checksum", - 3: "not implemented", 4: "flash write error", - 5: "address invalid", 6: "address prohibited", - 7: "value out of bounds" } - - dev.flushInput() - dev.flushOutput() - - cstr = bytearray(struct.pack('> sys.stderr, "ERROR: timeout while reading response header (expected %d bytes, got %d)" % (4, len(astr)) - sys.exit(4) - - if astr[0] != cstr[0]: - print >> sys.stderr, "ERROR: bootloader returned wrong command code" - sys.exit(4) - - ret = astr[2] - if ret != 0: - rstr = "invalid return code" - try: - rstr = return_codes[ret] - except KeyError: - pass - print >> sys.stderr, "ERROR: bootloader returned %d: %s" % (ret, rstr) - sys.exit(4) - - answer_len = astr[1] - 4 - if answer_len < struct.calcsize(answer): - print >> sys.stderr, "ERROR: short answer %d bytes received: expected %s bytes" % (answer_len, struct.calcsize(answer)) - sys.exit(4) - - if answer_len > 0: - tmp = bytearray() - tmp += dev.read(answer_len) - if len(tmp) < answer_len: - print >> sys.stderr, "ERROR: timeout while reading response (expected %d bytes, got %d)" % (answer_len, len(tmp)) - sys.exit(4) - - astr += tmp - - if 0 != calc_csum(astr): - print >> sys.stderr, "ERROR: checksum error" - sys.exit(4) - - return struct.unpack_from(answer, astr, 3) - -### low level commands - -def cmd_identify(dev, name): - data = exec_command(dev, 1, '', '> sys.stderr, "incompatible protocol version, expected: %d, got: %d" % (VERSION_MAJ, id['ver_maj']) - sys.exit(4) - if name and id['name'] != name: - print >> sys.stderr, "ERROR: the bootloaders name '%s' differs from the one supplied via" % id['name'] - print >> sys.stderr, " command line option '%s'. Are sure you are connected to the" % name - print >> sys.stderr, " right device?" - sys.exit(4) - - print >> sys.stderr, "connected with Bootloader '%s' Version %d.%d, (ID=%04X, %d words Flash, FSS=%d, %d bytes EEPROM, MESS=%d)" % \ - (id['name'], id['ver_maj'], id['ver_min'], id['devid'], id['fs'], id['fss'], id['es'], id['mess']) - return id - -def cmd_boot(dev): - exec_command(dev, 2, '', '<') - -def cmd_reset(dev, id): - exec_command(dev, 3, '', '<') - -def cmd_read_flash_segment(dev, id, addr): - param = struct.pack('> sys.stderr, "%05X: %s" % (segment[0], ''.join('%04X '%i for i in segment[1])) - cmd_write_flash_segment(dev, id, segment[0], segment[1]) - -def read_flash(dev, id, file): - codedata = {} - for addr in xrange(0, id['fs'], id['fss']): - data = cmd_read_flash_segment(dev, id, addr) -# print >> sys.stderr, "%05X: %s" % (addr, ''.join('%04X '%i for i in data)) - a = addr - for d in data: - codedata[a] = d - a += 1 - - write_hex(file, codedata) - -def verify_flash(dev, id, file): - codedata = load_hex(file) - err = 0 - for segment in create_flash_segments(codedata, id['fs'], id['fss']): - flashdata = cmd_read_flash_segment(dev, id, segment[0]) - for file,flash in zip(segment[1] , flashdata): - if flash == 0x3FFF: - flash = 0xFFFF - if flash != file: - err = 1 - break - - if err !=0: - break - - if err != 0: - print >> sys.stderr, "ERROR: verify failed!" - sys.exit(-1) - else: - print >> sys.stderr, "verify ok!" - sys.exit(0) - -commands = { - 'boot': boot, - 'write': write_flash, - 'read': read_flash, - 'verify': verify_flash -} - -### Main - -if __name__ == '__main__': - import getopt - import sys - import os - import struct - - usage = '''spreadspace simple pic downloader. -Usage: - python downloader.py [options] INFILE - -Arguments: - INFILE name of hex file for downloading. - Use '-' for reading from stdin. - -Options: - -h, --help this help message. - -v, --version version info. - --cmd=N the command to execute, one out of: "boot,read,write,verify" - --device=N the serial port to use (default: /dev/ttyUSB0). - --baud=N baudrate to use (default: 57600). - --name=N the expected name of the bootloader. -''' - - device = "/dev/ttyUSB0" - baudrate = 57600 - name = None - cmd = None - - try: - opts, args = getopt.getopt(sys.argv[1:], "hv", - ["help", "version", "cmd=", "device=", "baud=", "name="]) - - for o, a in opts: - if o in ("-h", "--help"): - print >> sys.stderr, usage - sys.exit(0) - elif o in ("-v", "--version"): - print >> sys.stderr, "Version %d.%d" % (VERSION_MAJ, VERSION_MIN) - sys.exit(0) - elif o in ("--cmd"): - cmd = a - elif o in ("--device"): - device = a - elif o in ("--baud"): - baudrate = a - elif o in ("--name"): - name = a - - if not args: - raise getopt.GetoptError('Hex file is not specified') - - if len(args) > 1: - raise getopt.GetoptError('Too many arguments') - - if not cmd: - raise getopt.GetoptError('You have to supply a command (boot,read,write,verify)') - - except getopt.GetoptError, msg: - print >> sys.stderr, "ERROR: %s" % msg - print >> sys.stderr, usage - sys.exit(2) - - dev = open_serial(device, baudrate) - id = cmd_identify(dev, name) - - try: - commands[cmd](dev, id, args[0]) - except KeyError: - print >> sys.stderr, "ERROR: unkown command '%s'" % cmd -- cgit v1.2.3