#!/usr/bin/env python

# Copyright (c) 2016-2017 Satlab Aps <satlab@satlab.com>
# All rights reserved. Do not distribute without permission.

from __future__ import print_function

import argparse
import subprocess


def msg(string, **kwargs):
    print('\033[1m[+] ' + str(string) + '\033[0m', **kwargs)


def execute(cmd):
    popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
    for stdout_line in iter(popen.stdout.readline, ""):
        yield stdout_line 
    popen.stdout.close()
    return_code = popen.wait()
    if return_code:
        raise subprocess.CalledProcessError(return_code, cmd)


def main():
    VERSION = '1.0.0'

    parser = argparse.ArgumentParser()

    parser.add_argument('binary', help='Binary image to flash')
    parser.add_argument('--adapter-khz', default=1800, type=int, help='Set programming adapter speed')

    args = parser.parse_args()

    openocd_cmd = ['openocd',
                   '-f', 'satlab-jtag.cfg',
                   '-f', 'interface/ftdi/swd-resistor-hack.cfg',
                   '-c', 'set CHIPNAME atsame70q21',
                   '-f', 'target/atsamv.cfg',
                   '-c', 'adapter_khz {}'.format(args.adapter_khz),
                   '-c', 'init',
                   '-c', 'halt',
                   '-c', 'flash protect 0 0 last off',
                   '-c', 'program {} verify reset exit 0x400000'.format(args.binary)]

    msg('Satlab Polaris firmware flash tool v' + VERSION)
    try:
        msg('Calling OpenOCD to flash {}:'.format(args.binary))
        for path in execute(openocd_cmd):
            print(path, end="")
    except Exception as e:
        msg('Could not flash firmware, please ensure that:')
        msg('  1) OpenOCD is installed from https://github.com/satlab/openocd')
        msg('  2) The JTAG adapter is connected to the board')
        msg('  3) You supply the correct filename for the firmware image')
        msg('This error could provide a clue:')
        msg(e)
    else:
        msg('Succesfully flashed the firmare to the board')


if __name__ == '__main__':
    main()
