# $Id: wibo_gen_py.tpl,v 1.7 2010/11/05 21:39:30 awachtler Exp $
# This file is generated automatically from wibo_gen_py.tpl
#
"""
Dumps a intel hex file for a node config structure.

    python %(filename)s.py [OPTIONS]

    Options:
     -p PANID
        Default pan id (16 bit value).
     -a SHORTADDR
        Fixed node short source address (16 bit value).
     -A LONGADDR
        Fixed node short source address (64 bit value).
     -f HEXFILE
        Name of alternative IHEX file to patch.
     -o NEWHEXFILE
        Name of the outputfile, if '-' stdout is used.
     -c CHANNEL
        A Channel hint for applications.
     -h
        Display help and exit.
     -V
        Show version and exit.

Example:
   python wibo_funkomat.hex.py -a 1 | avrdude -P usb -p m1281 -c jtag2 -V -D -U fl:w:-:i

   Writes source address 1 into the device via a pipe to avrdude.

""" #%% "%(filename)s".replace("hex","py")




# === import ==================================================================
import struct, getopt, sys

# === globals =================================================================
VERSION = "%(version)s"
INFILE = "%(filename)s"
MMCU = "%(mmcu)s"
PANID = 0xffff
SADDR = 0xffff
LADDR = 0xffffffffffffffffL
CHAN  = 0xff
OUTFILE = sys.stdout
# This a workaround for obtaining the flashends for the current used MCU's.
# avr-gcc is used to extract the address.
# for i in $(awk -F'=' '/^cpu/{print $2}' Src/Lib/Inc/boards/board.cfg|sort|uniq);do x=$(echo "#include <avr/io.h>"|avr-gcc -mmcu=$i -E -dM -|awk '/FLASHEND/{print  $NF}');echo "\"$i\" : $x,"; done
#
FLASHEND = {
    "at90usb1287" : 0x1FFFF,
    "atmega1281" : 0x1FFFF,
    "atmega1284p" : 0x1FFFF,
    "atmega128rfa1" : (0x1ffff),
    "atmega16" : 0x3FFF,
    "atmega644" : 0xFFFF,
    "atmega8" : 0x1FFF,
    "atmega88" : 0x1FFF,
    "attiny84" : 0x1FFF,
}

# === functions ===============================================================
##
# Format an intel hex record
# For a description of the intel hex format see:
#  http://en.wikipedia.org/wiki/Intel_HEX
#
# @param rtype
#        record type
#          00 	Data Record
#          01 	End of File Record
#          02 	Extended Segment Address Record
#          03 	Start Segment Address Record
#          04 	Extended Linear Address Record
#          05 	Start Linear Address Record
# @param addr
#           16 bit address value
# @param data
#           list with 8 bit values.
# @return string of the formated record.
#
def ihex_record(rtype, addr,data = []):

    dlen = len(data) & 0xff
    darr  = [ dlen,
             (addr >> 8) & 0xff,
             (addr & 0xff) ,
              rtype & 0xff]
    darr.extend(data)
    crc = 0
    for d in darr:
        crc += d
    crc = ((crc &0xff)^0xff) + 1
    darr.append(crc & 0xff)
    return ":"+"".join(["%%02X" %%d  for d in darr])


##
# Generating the node config structure.
#
# The format of the structure node_config_t is defined in board.h.
#
def generate_nodecfg_record():
    ret = []
    struct_fmt ="@HHQ3xB"
    memaddr = (FLASHEND[MMCU] - struct.calcsize(struct_fmt) + 1)
    extaddr = (memaddr >> 16)
    if (extaddr > 0):
        # is extended addr record needed ?
        #  a  b    c  d    e
        # :02 0000 02 1000 EC
        data = map(ord, struct.pack("<H",extaddr<<4))
        ret.append(ihex_record(2, 0, data))

    data = map(ord,struct.pack(struct_fmt, SADDR, PANID, LADDR, 42))
    ret.append(ihex_record(0, memaddr, data))
    return ret

##
# add a node cofg structure at the end of the flash.
#
def patch_hexfile(ifile, fo):
    ret = -1
    fi = open(ifile,"r")
    for l in fi.xreadlines():
        if l.find(":00000001FF") == 0:
            # end record found
            nodecfg = generate_nodecfg_record()
            fo.write( "\n".join(nodecfg)+"\n")
        # write regular record
        fo.write(l)
    fi.close()
    fo.close()
    return ret

# === classes =================================================================



if __name__ == "__main__":
    try:
        opts,args = getopt.getopt(sys.argv[1:],"a:p:A:f:hVo:c:")
    except:
        opts = (('-h',''),('-V',''))

    #test vectors
    #x = ":1001600060E070E000E010E020E030E00E94D705A1"
    #addr = 0x0160
    #data = [ 0x60, 0xE0, 0x70, 0xE0, 0x00, 0xE0, 0x10, 0xE0,
    #         0x20, 0xE0, 0x30, 0xE0, 0x0E, 0x94, 0xD7, 0x05 ]
    #y = ihex_record(0,addr, data)
    doexit = False
    for o,v in opts:
        if o == "-a":
            SADDR = eval(v)
        elif o == "-A":
            LADDR = eval(v)
        elif o == "-p":
            PANID = eval(v)
        elif o == "-c":
            CHAN = eval(v)
        elif o == "-f":
            INFILE = v
        elif o == "-h":
            print __doc__
            doexit = True
        elif o == "-V":
            print "Version",VERSION
            doexit = True
        elif o == "-o":
            if v != '-':
                x = open(v,'w')
                OUTFILE = x
            sys.stderr.write("Outfile %%s\n" %% OUTFILE.name)

    if doexit:
        sys.exit(0)

    sys.stderr.write("convert %%s to %%s\n" %%(INFILE, OUTFILE.name))

    patch_hexfile(INFILE, OUTFILE)
