コード例 #1
0
    def connect(self, port=0, baudrate=38400):
        if port.__class__ == int:
            # Port is an integer. Use as index into port list.
            ports = self.list_ports()
            if len(ports) < port or len(ports) == 0:
                raise Exception(
                    "Port index out of range - no serial port available to connect to AVR."
                )
            port = ports[port][0]

        try:
            self._serial = Serial(port, baudrate)
            self._piper = Piper(self._serial)
            self._piper.set_read_callback(AVR.INTERRUPT_PIPE,
                                          self._handleInterrupt)
        except Exception as e:
            raise Exception(
                "Could not connect to AVR on serial port {0}.".format(port))
コード例 #2
0
ファイル: avr.py プロジェクト: samuelbrian/avrpy
    def connect(self, port=0, baudrate=38400):
        if port.__class__ == int:
            # Port is an integer. Use as index into port list.
            ports = self.list_ports()
            if len(ports) < port or len(ports) == 0:
                raise Exception("Port index out of range - no serial port available to connect to AVR.")
            port = ports[port][0]

        try:
            self._serial = Serial(port, baudrate)
            self._piper = Piper(self._serial)
            self._piper.set_read_callback(AVR.INTERRUPT_PIPE, self._handleInterrupt)
        except Exception as e:
            raise Exception("Could not connect to AVR on serial port {0}.".format(port))
コード例 #3
0
ファイル: avr.py プロジェクト: samuelbrian/avrpy
class AVR:

    # Pipe addresses
    REGISTER_PIPE   = 0x00
    INTERRUPT_PIPE  = 0x01

    # Operation tokens
    READ_IO8        = 0x01
    READ_IO16       = 0x02
    READ_MEM8       = 0x03
    READ_MEM16      = 0x04
    WRITE_IO8       = 0xF1
    WRITE_IO16      = 0xF2
    WRITE_MEM8      = 0xF3
    WRITE_MEM16     = 0xF4
    INT_ENABLE      = 0x01
    INT_DISABLE     = 0x00

    def __init__(self):
        self._frozen = False    # flag to allow/disallow setting attributes
        self._SFR_IO8 = {}      # IO8 register map
        self._SFR_IO16 = {}     # IO16 register map
        self._SFR_MEM8 = {}     # MEM8 register map
        self._SFR_MEM16 = {}    # MEM16 register map
        self._constants = {}     # other numerical constants
        self._vect = {}         # map vector names to callback functions
        self._vector_indices = {} # map vector names to indices
        self._int_enabled = True
        self._aliases = {}
        self._serial = None
        self._piper = None
        self._frozen = True

    def connect(self, port=0, baudrate=38400):
        if port.__class__ == int:
            # Port is an integer. Use as index into port list.
            ports = self.list_ports()
            if len(ports) < port or len(ports) == 0:
                raise Exception("Port index out of range - no serial port available to connect to AVR.")
            port = ports[port][0]

        try:
            self._serial = Serial(port, baudrate)
            self._piper = Piper(self._serial)
            self._piper.set_read_callback(AVR.INTERRUPT_PIPE, self._handleInterrupt)
        except Exception as e:
            raise Exception("Could not connect to AVR on serial port {0}.".format(port))

    def list_ports(self):
        return list(comports())

    def disconnect(self):
        self._piper.close()
        self._piper = None

    ## Parse an AVR register header (e.g. iom32u4.h for the ATmega32U4).
    def parse(self, header_filename):
        import re
        with open(header_filename, "r") as file:
            for line in file:

                #if not line.startswith("#define "): continue
                matches = re.search("#\s*define\s+", line)
                if matches is None: continue
                spl = line.replace(matches.group(0), "")
                same = False
                while same:
                    pspl = spl
                    spl = spl.replace("  ", " ")
                    same = pspl == spl
                spl = spl.strip().split(" ")

                # Constants with no value
                if len(spl) < 2:
                    self._constants[spl[0]] = None
                    continue

                # IO8 registers
                matches = re.search("_SFR_IO8\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_IO8[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # IO16 registers
                matches = re.search("_SFR_IO16\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_IO16[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # MEM8 registers
                matches = re.search("_SFR_MEM8\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_MEM8[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # MEM16 registers
                matches = re.search("_SFR_MEM16\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_MEM16[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # Interrupt vectors
                matches = re.search("_VECTOR\((.+)\)", line)
                if matches is not None:
                    index = _to_int(matches.groups()[0])
                    self._vector_indices[spl[0]] = index
                    self._vect[index] = None
                    continue

                # Other constants
                try:
                    self._constants[spl[0]] = _to_int(spl[1])
                    continue
                except:
                    pass

                # Unhandled: FUSE_*, RAM*, XRAM*, _VECTOR_SIZE, and some others.
                #print(line)

    def __setattr__(self, item, value):
        if hasattr(self, "_frozen") and self._frozen and not hasattr(self, item):
            raise AttributeError("'{0}' object has no attribute '{1}'".format(self.__class__.__name__, item))
        if not hasattr(self, "_frozen") or (hasattr(self, "_frozen") and not self._frozen):
            object.__setattr__(self, item, value)
            return

        if item in object.__getattribute__(self, "_SFR_IO8"):
            self._set_value(self._SFR_IO8[item], value, AVR.WRITE_IO8)
        elif item in object.__getattribute__(self, "_SFR_IO16"):
            self._set_value(self._SFR_IO16[item], value, AVR.WRITE_IO16)
        elif item in object.__getattribute__(self, "_SFR_MEM8"):
            self._set_value(self._SFR_MEM8[item], value, AVR.WRITE_MEM8)
        elif item in object.__getattribute__(self, "_SFR_MEM16"):
            self._set_value(self._SFR_MEM16[item], value, AVR.WRITE_MEM16)
        elif item in object.__getattribute__(self, "_aliases"):
            self._set_value(self._aliases[item][0], value, self._aliases[item][2])
        elif item in object.__getattribute__(self, "_constants"):
            raise AttributeError("Constants are read-only attributes.")
        elif item in object.__getattribute__(self, "_vector_indices"):
            index = self._vector_indices[item]
            if callable(value):
                self._vect[index] = value
                self.enableInterrupt(index)
            elif value is None:
                self._vect[index] = None
                self.disableInterrupt(index)
            else:
                raise AttributeError("Interrupt vectors must be assigned a callable object or None.")
        else:
            object.__setattr__(self, item, value)

    def __getattr__(self, item):
        if self._piper == None: raise Exception("Not connected to an AVR.")
        if item in object.__getattribute__(self, "_SFR_IO8"):
            return self._get_value(self._SFR_IO8[item], AVR.READ_IO8)
        if item in object.__getattribute__(self, "_SFR_IO16"):
            return self._get_value(self._SFR_IO16[item], AVR.READ_IO16)
        if item in object.__getattribute__(self, "_SFR_MEM8"):
            return self._get_value(self._SFR_MEM8[item], AVR.READ_MEM8)
        if item in object.__getattribute__(self, "_SFR_MEM16"):
            return self._get_value(self._SFR_MEM16[item], AVR.READ_MEM16)
        if item in object.__getattribute__(self, "_aliases"):
            return self._get_value(self._aliases[item][0], self._aliases[item][1])
        if item in object.__getattribute__(self, "_constants"):
            return self._constants[item]
        if item in object.__getattribute__(self, "_vector_indices"):
            raise AttributeError("Interrupt vectors are write-only attributes.")
        else:
            return object.__getattribute__(self, item)

    def __hasattr__(self, item):
        # The built-in hasattr() checks if getattr() throws an exception or not. This will cause unnecessary serial
        # communication. This overridden hasattr() does not do this.
        try:
            return self.defined(item) or item in object.__getattribute__(self, "_vector_indices") or item in self.__dict__
        except:
            return item in self.__dict__

    def _get_value(self, address, read_token):
        self._piper.write_packet(AVR.REGISTER_PIPE, _uint8(address) + _uint8(read_token))
        value = self._piper.read_packet(AVR.REGISTER_PIPE)
        if len(value) == 2:   return _uint16R(value)
        elif len(value) == 1: return _uint8R(value)
        return -1

    def _set_value(self, address, value, write_token):
        packet = _uint8(address) + _uint8(write_token)
        if write_token == AVR.WRITE_IO8 or write_token == AVR.WRITE_MEM8: packet += _uint8(value)
        elif write_token == AVR.WRITE_IO16 or write_token == AVR.WRITE_MEM16: packet += _uint16(value)
        self._piper.write_packet(AVR.REGISTER_PIPE, packet)

    # Replacement for #define macro
    def define(self, name, value=None):
        if value in object.__getattribute__(self, "_SFR_IO8"):
            self._aliases[name] = (self._SFR_IO8[value], AVR.READ_IO8, AVR.WRITE_IO8)
        elif value in object.__getattribute__(self, "_SFR_IO16"):
            self._aliases[name] = (self._SFR_IO16[value], AVR.READ_IO16, AVR.WRITE_IO16)
        elif value in object.__getattribute__(self, "_SFR_MEM8"):
            self._aliases[name] = (self._SFR_MEM8[value], AVR.READ_MEM8, AVR.WRITE_MEM8)
        elif value in object.__getattribute__(self, "_SFR_MEM16"):
            self._aliases[name] = (self._SFR_MEM16[value], AVR.READ_MEM16, AVR.WRITE_MEM16)
        else:
            self._constants[name] = value

    # Replacement for #undef macro
    def undef(self, name):
        try: del self._constants[name]
        except: pass
        try: del self._aliases[name]
        except: pass

    # Replacement for #defined macro
    def defined(self, item):
        return self.is_register(item) or self.is_constant(item)

    def is_register(self, name):
        return name in object.__getattribute__(self, "_SFR_IO8") \
                    or name in object.__getattribute__(self, "_SFR_IO16") \
                    or name in object.__getattribute__(self, "_SFR_MEM8") \
                    or name in object.__getattribute__(self, "_SFR_MEM16") \
                    or name in object.__getattribute__(self, "_aliases")

    def is_constant(self, name):
        return name in object.__getattribute__(self, "_constants")

    def is_vect(self, name):
        return name in object.__getattribute__(self, "_vect")

    # Enable global interrupts. Handles incoming interrupt packets. Doesn't actually change AVR's SREG.
    def sei(self):
        self._int_enabled = True

    # Disable global interrupts. Ignores incoming interrupt packets. Doesn't actually change AVR's SREG.
    def cli(self):
        self._int_enabled = False

    # Useful but obsolete macros from http://www.nongnu.org/avr-libc/user-manual/group__deprecated__items.html
    ## Set bit.
    def sbi(self, sfr, bit):
        self.__setattr__(sfr, self.__getattr__(sfr) | (1 << bit))

    ## Clear bit.
    def cbi(self, sfr, bit):
        self.__setattr__(sfr, self.__getattr__(sfr) & invert(1 << bit))

    def bit_is_set(self, sfr, bit):
        return bool(self.__getattr__(sfr) & (1 << bit))

    def bit_is_clear(self, sfr, bit):
        return not self.bit_is_set(sfr, bit)

    def ptr(self, register_name):
        return Register(self, register_name)

    ## Enable the interrupt packet being sent from the microcontroller.
    def enableInterrupt(self, index):
        if isinstance(index, str): index = self._vector_indices[index]
        self._piper.write_packet(AVR.INTERRUPT_PIPE, _uint8(index) + _uint8(AVR.INT_ENABLE))

    ## Disable the interrupt packet being sent from the microcontroller.
    def disableInterrupt(self, index):
        if isinstance(index, str): index = self._vector_indices[index]
        self._piper.write_packet(AVR.INTERRUPT_PIPE, _uint8(index) + _uint8(AVR.INT_DISABLE))

    def _handleInterrupt(self, index):
        if not self._int_enabled: return
        index = _uint8R(index)
        if index in self._vect and self._vect[index] is not None: self._vect[index]()

    # Generate a string of all the ISRs for copying into the Arduino firmware.
    def generateFirmwareISRs(self):
        s = ""
        for interrupt_name in sorted(self._vector_indices, key=self._vector_indices.get):
            s += "ISR({0}) {{ triggerInterrupt({1}); }}\n".format(interrupt_name, self._vector_indices[interrupt_name])
        return s

    # Generate a string of Python code containing all the definitions that have been parsed.
    # This can be used e.g. in Arduino board definitions so the headers don't have to be parsed at runtime.
    def generateDefsCode(self, varname):
        s = ""
        s += "{0}._SFR_IO8 = {1}\n".format(varname, str(self._SFR_IO8))
        s += "{0}._SFR_IO16 = {1}\n".format(varname, str(self._SFR_IO16))
        s += "{0}._SFR_MEM8 = {1}\n".format(varname, str(self._SFR_MEM8))
        s += "{0}._SFR_MEM16 = {1}\n".format(varname, str(self._SFR_MEM16))
        s += "{0}._constants = {1}\n".format(varname, str(self._constants))
        vect = self._vect
        self._vect = {}
        for key in vect.keys(): self._vect[key] = None
        s += "{0}._vect = {1}\n".format(varname, str(self._vect))
        self._vect = vect
        s += "{0}._vector_indices = {1}\n".format(varname, str(self._vector_indices))
        s += "{0}._aliases = {1}\n".format(varname, str(self._aliases))
        return s
コード例 #4
0
class AVR:

    # Pipe addresses
    REGISTER_PIPE = 0x00
    INTERRUPT_PIPE = 0x01

    # Operation tokens
    READ_IO8 = 0x01
    READ_IO16 = 0x02
    READ_MEM8 = 0x03
    READ_MEM16 = 0x04
    WRITE_IO8 = 0xF1
    WRITE_IO16 = 0xF2
    WRITE_MEM8 = 0xF3
    WRITE_MEM16 = 0xF4
    INT_ENABLE = 0x01
    INT_DISABLE = 0x00

    def __init__(self):
        self._frozen = False  # flag to allow/disallow setting attributes
        self._SFR_IO8 = {}  # IO8 register map
        self._SFR_IO16 = {}  # IO16 register map
        self._SFR_MEM8 = {}  # MEM8 register map
        self._SFR_MEM16 = {}  # MEM16 register map
        self._constants = {}  # other numerical constants
        self._vect = {}  # map vector names to callback functions
        self._vector_indices = {}  # map vector names to indices
        self._int_enabled = True
        self._aliases = {}
        self._serial = None
        self._piper = None
        self._frozen = True

    def connect(self, port=0, baudrate=38400):
        if port.__class__ == int:
            # Port is an integer. Use as index into port list.
            ports = self.list_ports()
            if len(ports) < port or len(ports) == 0:
                raise Exception(
                    "Port index out of range - no serial port available to connect to AVR."
                )
            port = ports[port][0]

        try:
            self._serial = Serial(port, baudrate)
            self._piper = Piper(self._serial)
            self._piper.set_read_callback(AVR.INTERRUPT_PIPE,
                                          self._handleInterrupt)
        except Exception as e:
            raise Exception(
                "Could not connect to AVR on serial port {0}.".format(port))

    def list_ports(self):
        return list(comports())

    def disconnect(self):
        self._piper.close()
        self._piper = None

    ## Parse an AVR register header (e.g. iom32u4.h for the ATmega32U4).
    def parse(self, header_filename):
        import re
        with open(header_filename, "r") as file:
            for line in file:

                #if not line.startswith("#define "): continue
                matches = re.search("#\s*define\s+", line)
                if matches is None: continue
                spl = line.replace(matches.group(0), "")
                same = False
                while same:
                    pspl = spl
                    spl = spl.replace("  ", " ")
                    same = pspl == spl
                spl = spl.strip().split(" ")

                # Constants with no value
                if len(spl) < 2:
                    self._constants[spl[0]] = None
                    continue

                # IO8 registers
                matches = re.search("_SFR_IO8\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_IO8[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # IO16 registers
                matches = re.search("_SFR_IO16\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_IO16[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # MEM8 registers
                matches = re.search("_SFR_MEM8\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_MEM8[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # MEM16 registers
                matches = re.search("_SFR_MEM16\((.+)\)", spl[1])
                if matches is not None:
                    self._SFR_MEM16[spl[0]] = _to_int(matches.groups()[0])
                    continue

                # Interrupt vectors
                matches = re.search("_VECTOR\((.+)\)", line)
                if matches is not None:
                    index = _to_int(matches.groups()[0])
                    self._vector_indices[spl[0]] = index
                    self._vect[index] = None
                    continue

                # Other constants
                try:
                    self._constants[spl[0]] = _to_int(spl[1])
                    continue
                except:
                    pass

                # Unhandled: FUSE_*, RAM*, XRAM*, _VECTOR_SIZE, and some others.
                #print(line)

    def __setattr__(self, item, value):
        if hasattr(self,
                   "_frozen") and self._frozen and not hasattr(self, item):
            raise AttributeError("'{0}' object has no attribute '{1}'".format(
                self.__class__.__name__, item))
        if not hasattr(self, "_frozen") or (hasattr(self, "_frozen")
                                            and not self._frozen):
            object.__setattr__(self, item, value)
            return

        if item in object.__getattribute__(self, "_SFR_IO8"):
            self._set_value(self._SFR_IO8[item], value, AVR.WRITE_IO8)
        elif item in object.__getattribute__(self, "_SFR_IO16"):
            self._set_value(self._SFR_IO16[item], value, AVR.WRITE_IO16)
        elif item in object.__getattribute__(self, "_SFR_MEM8"):
            self._set_value(self._SFR_MEM8[item], value, AVR.WRITE_MEM8)
        elif item in object.__getattribute__(self, "_SFR_MEM16"):
            self._set_value(self._SFR_MEM16[item], value, AVR.WRITE_MEM16)
        elif item in object.__getattribute__(self, "_aliases"):
            self._set_value(self._aliases[item][0], value,
                            self._aliases[item][2])
        elif item in object.__getattribute__(self, "_constants"):
            raise AttributeError("Constants are read-only attributes.")
        elif item in object.__getattribute__(self, "_vector_indices"):
            index = self._vector_indices[item]
            if callable(value):
                self._vect[index] = value
                self.enableInterrupt(index)
            elif value is None:
                self._vect[index] = None
                self.disableInterrupt(index)
            else:
                raise AttributeError(
                    "Interrupt vectors must be assigned a callable object or None."
                )
        else:
            object.__setattr__(self, item, value)

    def __getattr__(self, item):
        if self._piper == None: raise Exception("Not connected to an AVR.")
        if item in object.__getattribute__(self, "_SFR_IO8"):
            return self._get_value(self._SFR_IO8[item], AVR.READ_IO8)
        if item in object.__getattribute__(self, "_SFR_IO16"):
            return self._get_value(self._SFR_IO16[item], AVR.READ_IO16)
        if item in object.__getattribute__(self, "_SFR_MEM8"):
            return self._get_value(self._SFR_MEM8[item], AVR.READ_MEM8)
        if item in object.__getattribute__(self, "_SFR_MEM16"):
            return self._get_value(self._SFR_MEM16[item], AVR.READ_MEM16)
        if item in object.__getattribute__(self, "_aliases"):
            return self._get_value(self._aliases[item][0],
                                   self._aliases[item][1])
        if item in object.__getattribute__(self, "_constants"):
            return self._constants[item]
        if item in object.__getattribute__(self, "_vector_indices"):
            raise AttributeError(
                "Interrupt vectors are write-only attributes.")
        else:
            return object.__getattribute__(self, item)

    def __hasattr__(self, item):
        # The built-in hasattr() checks if getattr() throws an exception or not. This will cause unnecessary serial
        # communication. This overridden hasattr() does not do this.
        try:
            return self.defined(item) or item in object.__getattribute__(
                self, "_vector_indices") or item in self.__dict__
        except:
            return item in self.__dict__

    def _get_value(self, address, read_token):
        self._piper.write_packet(AVR.REGISTER_PIPE,
                                 _uint8(address) + _uint8(read_token))
        value = self._piper.read_packet(AVR.REGISTER_PIPE)
        if len(value) == 2: return _uint16R(value)
        elif len(value) == 1: return _uint8R(value)
        return -1

    def _set_value(self, address, value, write_token):
        packet = _uint8(address) + _uint8(write_token)
        if write_token == AVR.WRITE_IO8 or write_token == AVR.WRITE_MEM8:
            packet += _uint8(value)
        elif write_token == AVR.WRITE_IO16 or write_token == AVR.WRITE_MEM16:
            packet += _uint16(value)
        self._piper.write_packet(AVR.REGISTER_PIPE, packet)

    # Replacement for #define macro
    def define(self, name, value=None):
        if value in object.__getattribute__(self, "_SFR_IO8"):
            self._aliases[name] = (self._SFR_IO8[value], AVR.READ_IO8,
                                   AVR.WRITE_IO8)
        elif value in object.__getattribute__(self, "_SFR_IO16"):
            self._aliases[name] = (self._SFR_IO16[value], AVR.READ_IO16,
                                   AVR.WRITE_IO16)
        elif value in object.__getattribute__(self, "_SFR_MEM8"):
            self._aliases[name] = (self._SFR_MEM8[value], AVR.READ_MEM8,
                                   AVR.WRITE_MEM8)
        elif value in object.__getattribute__(self, "_SFR_MEM16"):
            self._aliases[name] = (self._SFR_MEM16[value], AVR.READ_MEM16,
                                   AVR.WRITE_MEM16)
        else:
            self._constants[name] = value

    # Replacement for #undef macro
    def undef(self, name):
        try:
            del self._constants[name]
        except:
            pass
        try:
            del self._aliases[name]
        except:
            pass

    # Replacement for #defined macro
    def defined(self, item):
        return self.is_register(item) or self.is_constant(item)

    def is_register(self, name):
        return name in object.__getattribute__(self, "_SFR_IO8") \
                    or name in object.__getattribute__(self, "_SFR_IO16") \
                    or name in object.__getattribute__(self, "_SFR_MEM8") \
                    or name in object.__getattribute__(self, "_SFR_MEM16") \
                    or name in object.__getattribute__(self, "_aliases")

    def is_constant(self, name):
        return name in object.__getattribute__(self, "_constants")

    def is_vect(self, name):
        return name in object.__getattribute__(self, "_vect")

    # Enable global interrupts. Handles incoming interrupt packets. Doesn't actually change AVR's SREG.
    def sei(self):
        self._int_enabled = True

    # Disable global interrupts. Ignores incoming interrupt packets. Doesn't actually change AVR's SREG.
    def cli(self):
        self._int_enabled = False

    # Useful but obsolete macros from http://www.nongnu.org/avr-libc/user-manual/group__deprecated__items.html
    ## Set bit.
    def sbi(self, sfr, bit):
        self.__setattr__(sfr, self.__getattr__(sfr) | (1 << bit))

    ## Clear bit.
    def cbi(self, sfr, bit):
        self.__setattr__(sfr, self.__getattr__(sfr) & invert(1 << bit))

    def bit_is_set(self, sfr, bit):
        return bool(self.__getattr__(sfr) & (1 << bit))

    def bit_is_clear(self, sfr, bit):
        return not self.bit_is_set(sfr, bit)

    def ptr(self, register_name):
        return Register(self, register_name)

    ## Enable the interrupt packet being sent from the microcontroller.
    def enableInterrupt(self, index):
        if isinstance(index, str): index = self._vector_indices[index]
        self._piper.write_packet(AVR.INTERRUPT_PIPE,
                                 _uint8(index) + _uint8(AVR.INT_ENABLE))

    ## Disable the interrupt packet being sent from the microcontroller.
    def disableInterrupt(self, index):
        if isinstance(index, str): index = self._vector_indices[index]
        self._piper.write_packet(AVR.INTERRUPT_PIPE,
                                 _uint8(index) + _uint8(AVR.INT_DISABLE))

    def _handleInterrupt(self, index):
        if not self._int_enabled: return
        index = _uint8R(index)
        if index in self._vect and self._vect[index] is not None:
            self._vect[index]()

    # Generate a string of all the ISRs for copying into the Arduino firmware.
    def generateFirmwareISRs(self):
        s = ""
        for interrupt_name in sorted(self._vector_indices,
                                     key=self._vector_indices.get):
            s += "ISR({0}) {{ triggerInterrupt({1}); }}\n".format(
                interrupt_name, self._vector_indices[interrupt_name])
        return s

    # Generate a string of Python code containing all the definitions that have been parsed.
    # This can be used e.g. in Arduino board definitions so the headers don't have to be parsed at runtime.
    def generateDefsCode(self, varname):
        s = ""
        s += "{0}._SFR_IO8 = {1}\n".format(varname, str(self._SFR_IO8))
        s += "{0}._SFR_IO16 = {1}\n".format(varname, str(self._SFR_IO16))
        s += "{0}._SFR_MEM8 = {1}\n".format(varname, str(self._SFR_MEM8))
        s += "{0}._SFR_MEM16 = {1}\n".format(varname, str(self._SFR_MEM16))
        s += "{0}._constants = {1}\n".format(varname, str(self._constants))
        vect = self._vect
        self._vect = {}
        for key in vect.keys():
            self._vect[key] = None
        s += "{0}._vect = {1}\n".format(varname, str(self._vect))
        self._vect = vect
        s += "{0}._vector_indices = {1}\n".format(varname,
                                                  str(self._vector_indices))
        s += "{0}._aliases = {1}\n".format(varname, str(self._aliases))
        return s