# Atmel ATSAMD21G18 core implementation.
# See chip summary at:
#   http://www.atmel.com/Images/Atmel-42181-SAM-D21_Summary.pdf
#
# Author: Tony DiCola
import os

import click

from ..core import Core
from ..programmers import JLink, STLink


class STLink_ATSAMD21G18(STLink):
    # ATSAMD21G18-specific STLink-based programmer.  Required to add custom
    # wipe function, and to use the load_image command for programming (the
    # flash write_image function doesn't seem to work because of OpenOCD bugs).

    def __init__(self):
        # Call base STLink initializer and set it up to program the ATSAMD21G18.
        super(STLink_ATSAMD21G18, self).__init__(params='-f interface/stlink-v2.cfg ' \
            '-c "set CHIPNAME at91samd21g18; set ENDIAN little; set CPUTAPID 0x0bc11477; source [find target/at91samdXX.cfg]"')

    def wipe(self):
        # Run OpenOCD command to wipe ATSAMD21G18 memory.
        commands = [
            'init',
            'reset init',
            'at91samd chip-erase',
            'exit'
        ]
        self.run_commands(commands)

    def program(self, hex_files=[], bin_files=[]):
        # Program the ATSAMD21G18 with the provided hex/bin files.
        click.echo('WARNING: Make sure the provided hex/bin files are padded with ' \
            'at least 64 bytes of blank (0xFF) data!  This will work around a cache bug with OpenOCD 0.9.0.')
        commands = [
            'init',
            'reset init'
        ]
        # Program each hex file.
        for f in hex_files:
            f = self.escape_path(os.path.abspath(f))
            commands.append('load_image {0} 0 ihex'.format(f))
        # Program each bin file.
        for f, addr in bin_files:
            f = self.escape_path(os.path.abspath(f))
            commands.append('load_image {0} 0x{1:08X} bin'.format(f, addr))
        commands.append('reset run')
        commands.append('exit')
        self.run_commands(commands)


class ATSAMD21G18(Core):
    """Atmel ATSAMD21G18 CPU."""
    # Note that the docstring will be used as the short help description.

    def __init__(self):
        # Call base class constructor--MUST be done!
        super(ATSAMD21G18, self).__init__()

    def list_programmers(self):
        """Return a list of the programmer names supported by this CPU."""
        return ['jlink', 'stlink']

    def create_programmer(self, programmer):
        """Create and return a programmer instance that will be used to program
        the core.  Must be implemented by subclasses!
        """
        if programmer == 'jlink':
            return JLink('Cortex-M0 r0p1, Little endian',
                         params='-device ATSAMD21G18 -if swd -speed 1000')
        elif programmer == 'stlink':
            return STLink_ATSAMD21G18()

    def info(self, programmer):
        """Display info about the device."""
        click.echo('Not implemented!')

@@ -194,16 +194,50 @@
 rt Core%0A
+from ..errors import AdaLinkError%0A
 from ..p
@@ -1880,103 +1880,1012 @@
     
-commands.append('reset run')%0A        commands.append('exit')%0A        self.run_commands(commands
+# Verify each hex file.%0A        for f in hex_files:%0A            f = self.escape_path(os.path.abspath(f))%0A            commands.append('verify_image %7B0%7D 0 ihex'.format(f))%0A        # Verify each bin file.%0A        for f, addr in bin_files:%0A            f = self.escape_path(os.path.abspath(f))%0A            commands.append('verify_image %7B0%7D 0x%7B1:08X%7D bin'.format(f, addr))%0A        commands.append('reset run')%0A        commands.append('exit')%0A        # Run commands.%0A        output = self.run_commands(commands)%0A        # Check that expected number of files were verified.  Look for output lines%0A        # that start with 'verified ' to signal OpenOCD output that the verification%0A        # succeeded.  Count up these lines and expect they match the number of%0A        # programmed files.%0A        verified = len(filter(lambda x: x.startswith('verified '), output.splitlines()))%0A        if verified != (len(hex_files) + len(bin_files)):%0A            raise AdaLinkError('Failed to verify all files were programmed!'
 )%0A%0A%0A

Add verification step to STLink programming for ATSAMD21G18.