SHA256
7
0
forked from pool/avr-libc
Files
avr-libc/0001-Return-files-missed-in-the-release-tarball.patch
Richard Biener a6c2c6bca2 Accepting request 1247909 from home:matwey:branches:devel:gcc
- update to 2.2.1
  * General:
    - Project moved to Github
    - Support for many new devices has been added, like devices from the
      AVR 0-series, 1-series, 2-series, AVR-Dx and AVR-Ex, but also for
      some older devices.
    - Parts of the user manual have been reworked, like the inline assembly
      Cookbook and the documentation of memory sections.
    - The multilib layout of the library, and what device belongs to which
      multilib variant, is no more hard coded in AVR-LibC but follows the
      compiler's multilib layout.
  * Improvements and additions:
    - Add support to new multilib layout / 64-bit [long] double compiler
      (Issues #642, #670)
    - Added support for new devices (Issue #824):
      ATtiny202 ATtiny204 ATtiny212 ATtiny214 ATtiny402 ATtiny404
      ATtiny406 ATtiny412 ATtiny414 ATtiny416 ATtiny417 ATtiny424
      ATtiny426 ATtiny427 ATtiny804 ATtiny806 ATtiny807 ATtiny814
      ATtiny816 ATtiny817 ATtiny824 ATtiny826 ATtiny827 ATtiny1604
      ATtiny1606 ATtiny1607 ATtiny1614 ATtiny1616 ATtiny1617 ATtiny1624
      ATtiny1626 ATtiny1627 ATtiny3214 ATtiny3216 ATtiny3217 ATtiny3224
      ATtiny3226 ATtiny3227 ATmega808 ATmega809 ATmega1608 ATmega1609
      ATmega3208 ATmega3209 ATmega4808 ATmega4809
    - Added support for AVR-Dx devices (Issue #881):
      AVR16DD14 AVR16DD20 AVR16DD28 AVR16DD32 AVR32DA28 AVR32DA32
      AVR32DA48 AVR32DB28 AVR32DB32 AVR32DB48 AVR32DD14 AVR32DD20
      AVR32DD28 AVR32DD32 AVR64DA28 AVR64DA32 AVR64DA48 AVR64DA64
      AVR64DB28 AVR64DB32 AVR64DB48 AVR64DB64 AVR64DD14 AVR64DD20
      AVR64DD28 AVR64DD32 AVR128DA28 AVR128DA32 AVR128DA48 AVR128DA64
      AVR128DB28 AVR128DB32 AVR128DB48 AVR128DB64

OBS-URL: https://build.opensuse.org/request/show/1247909
OBS-URL: https://build.opensuse.org/package/show/devel:gcc/avr-libc?expand=0&rev=12
2025-02-25 13:15:08 +00:00

5726 lines
220 KiB
Diff
Raw Permalink Blame History

From 67461e97634d1f94e82d535f28b55c31398d25a3 Mon Sep 17 00:00:00 2001
From: "Matwey V. Kornilov" <matwey.kornilov@gmail.com>
Date: Sun, 23 Feb 2025 14:26:58 +0300
Subject: [PATCH 1/3] Return files missed in the release tarball
dox_latex_header.tex, filter-dox.sh and avr-libc-logo-large.png are required to
build man pages.
---
devtools/findreg.xsl | 101 ++
devtools/generate_iosym.sh | 75 +
devtools/ioreg.pl | 672 +++++++++
devtools/specs2libtree.py | 118 ++
doc/LICENSE-Changes/PERM-Bob-Paddock | 45 +
doc/LICENSE-Changes/PERM-Colin-OFlynn | 53 +
doc/LICENSE-Changes/PERM-Joerg-Wunsch | 40 +
doc/LICENSE-Changes/PERM-Juergen-Schilling | 61 +
doc/LICENSE-Changes/PERM-Keith-Gudger | 50 +
doc/LICENSE-Changes/PERM-Marek-Michalkiewicz | 69 +
doc/LICENSE-Changes/PERM-Micheal-Stumpf | 70 +
doc/LICENSE-Changes/PERM-Nils-Kristian-Strom | 31 +
doc/LICENSE-Changes/PERM-Peter-Jansen | 67 +
doc/LICENSE-Changes/PERM-Reinhard-Jessich | 47 +
doc/LICENSE-Changes/PERM-Steinar-Haugen | 50 +
doc/LICENSE-Changes/PERM-Theodore-A-Roth | 37 +
doc/api/avr-libc-logo-large.png | Bin 0 -> 18555 bytes
doc/api/avr-libc-logo.xcf.bz2 | Bin 0 -> 12098 bytes
doc/api/dox_latex_header.tex | 258 ++++
doc/api/filter-dox.sh | 14 +
doc/api/unjs.pl | 155 ++
doc/api/vect_to_desc.py | 129 ++
xml/Atmel2libc.py | 547 +++++++
xml/Descparser.py | 255 ++++
xml/Device.dtd | 148 ++
xml/Validate.py | 56 +
xml/avrgcc-header | 1354 ++++++++++++++++++
xml/patch-headers.py | 436 ++++++
28 files changed, 4938 insertions(+)
create mode 100644 devtools/findreg.xsl
create mode 100755 devtools/generate_iosym.sh
create mode 100755 devtools/ioreg.pl
create mode 100755 devtools/specs2libtree.py
create mode 100644 doc/LICENSE-Changes/PERM-Bob-Paddock
create mode 100644 doc/LICENSE-Changes/PERM-Colin-OFlynn
create mode 100644 doc/LICENSE-Changes/PERM-Joerg-Wunsch
create mode 100644 doc/LICENSE-Changes/PERM-Juergen-Schilling
create mode 100644 doc/LICENSE-Changes/PERM-Keith-Gudger
create mode 100644 doc/LICENSE-Changes/PERM-Marek-Michalkiewicz
create mode 100644 doc/LICENSE-Changes/PERM-Micheal-Stumpf
create mode 100644 doc/LICENSE-Changes/PERM-Nils-Kristian-Strom
create mode 100644 doc/LICENSE-Changes/PERM-Peter-Jansen
create mode 100644 doc/LICENSE-Changes/PERM-Reinhard-Jessich
create mode 100644 doc/LICENSE-Changes/PERM-Steinar-Haugen
create mode 100644 doc/LICENSE-Changes/PERM-Theodore-A-Roth
create mode 100644 doc/api/avr-libc-logo-large.png
create mode 100644 doc/api/avr-libc-logo.xcf.bz2
create mode 100644 doc/api/dox_latex_header.tex
create mode 100755 doc/api/filter-dox.sh
create mode 100644 doc/api/unjs.pl
create mode 100644 doc/api/vect_to_desc.py
create mode 100755 xml/Atmel2libc.py
create mode 100755 xml/Descparser.py
create mode 100644 xml/Device.dtd
create mode 100755 xml/Validate.py
create mode 100755 xml/avrgcc-header
create mode 100755 xml/patch-headers.py
diff --git a/devtools/findreg.xsl b/devtools/findreg.xsl
new file mode 100644
index 00000000..90664da7
--- /dev/null
+++ b/devtools/findreg.xsl
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding='UTF-8' ?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://www.w3.org/1999/xhtml">
+<!--
+ * Copyright (c) 2013 Joerg Wunsch
+ *
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Joerg Wunsch wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
+ *
+ * $Id$
+-->
+
+<!--
+ * Extract IO register names and offsets out of Atmel Studio 6.x device XML files.
+ *
+ * The result is one line per IO register, in the form:
+ *
+ * REGNAME<tab>BASEADDRESS<tab>OFFSET<tab>SIZE<newline>
+ *
+ * REGNAME - name of this IO register
+ * BASEADDRESS - base address of register group (IO module)
+ * always 0 for non-Xmega devices
+ * OFFSET - offset of register within group
+ * SIZE - size of register in bytes (1 or 2)
+-->
+
+<!--
+ * Usage:
+ *
+ * xsltproc findreg.xsl ATxxx.xml > ATxxx.reg.txt
+ *
+ * or:
+ *
+ * java -jar /path/to/saxon9.jar -xsl:findreg.xsl -o:ATxxx.reg.txt ATxxx.xml
+ *
+ * (The warning about Saxon being an XSL 2.0 processor processing a 1.0
+ * style sheet can be ignoroed.)
+-->
+ <xsl:output method="text"/>
+
+ <xsl:template match="//address-space[@name='eeprom']">
+ <xsl:value-of select="@name" />
+ <xsl:text>&#9;0&#9;</xsl:text>
+ <xsl:value-of select="@start" />
+ <xsl:text>&#9;</xsl:text>
+ <xsl:value-of select="@size" />
+ <xsl:text>&#10;</xsl:text>
+ </xsl:template>
+ <!--
+ Pick all register-groups which are located in the
+ address-space named "data". Lock and fuse bits are also
+ declared as register-group, but they've got their own address
+ space so we can distinguish them from the normal IO registers
+ we are interested in here.
+ -->
+ <xsl:template match="//peripherals//register-group[@address-space='data']">
+
+ <!-- remember for later, since we need the group offset later on -->
+ <xsl:variable name="group" select="current()" />
+ <xsl:variable name="registergroup"
+ select="//modules/module/register-group[@name=$group/@name-in-module]" />
+
+ <!-- now, iterate over all registers of this group -->
+ <xsl:for-each select="$registergroup/register">
+
+ <!--
+ On Xmega devices, prepend the name of the register-group
+ (aka. subsystem) to the register name, since the register
+ names are not unique across the device.
+
+ On tiny/mega AVR devices, register names are unique across
+ the entire device, so this is not needed/used.
+ -->
+ <xsl:if test="//device/@architecture='AVR8_XMEGA'">
+ <xsl:value-of select="$group/@name" />
+ <xsl:text>_</xsl:text>
+ </xsl:if>
+ <xsl:value-of select="@name" />
+ <xsl:text>&#9;</xsl:text>
+ <xsl:value-of select="$group/@offset" />
+ <xsl:text>&#9;</xsl:text>
+ <xsl:value-of select="@offset" />
+ <xsl:text>&#9;</xsl:text>
+ <xsl:value-of select="@size" />
+ <xsl:text>&#10;</xsl:text>
+ </xsl:for-each>
+
+ </xsl:template>
+
+ <xsl:template match="node()">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="/">
+ <xsl:apply-templates />
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/devtools/generate_iosym.sh b/devtools/generate_iosym.sh
new file mode 100755
index 00000000..ecdb9bb2
--- /dev/null
+++ b/devtools/generate_iosym.sh
@@ -0,0 +1,75 @@
+#! /bin/sh
+
+# Allow to only generate for selected devices by providing DEVS.
+# Only when DEVS is not defined use the devices below.
+devs=${DEVS-"at43usb320 at43usb355 at76c711 at86rf401 at90c8534 at90can128 \
+at90can32 at90can64 at90pwm1 at90pwm2 at90pwm216 at90pwm2b at90pwm3 \
+at90pwm316 at90pwm3b at90pwm81 at90s1200 at90s2313 at90s2323 at90s2333 \
+at90s2343 at90s4414 at90s4433 at90s4434 at90s8515 at90s8535 at90scr100 \
+at90usb1286 at90usb1287 at90usb162 at90usb646 at90usb647 at90usb82 \
+at94k ata6289 atmega103 atmega128 atmega1280 atmega1281 atmega1284p \
+atmega1284rfr2 atmega128rfa1 atmega128rfr2 atmega16 atmega161 \
+atmega162 atmega163 atmega164a atmega164p atmega165 atmega165a \
+atmega165p atmega168 atmega168a atmega168p atmega169 atmega169a \
+atmega169p atmega169pa atmega16a atmega16hva atmega16hva2 atmega16hvb \
+atmega16hvbrevb atmega16m1 atmega16u2 atmega16u4 atmega2560 atmega2561 \
+atmega2564rfr2 atmega256rfr2 atmega32 atmega323 atmega324a atmega324p \
+atmega324pa atmega325 atmega3250 atmega3250a atmega3250p atmega325a \
+atmega325p atmega328 atmega328p atmega329 atmega3290 atmega3290a \
+atmega3290p atmega329a atmega329p atmega329pa atmega32c1 atmega32hvb \
+atmega32hvbrevb atmega32m1 atmega32u2 atmega32u4 atmega32u6 atmega406 \
+atmega48 atmega48a atmega48p atmega64 atmega640 atmega644 atmega644a \
+atmega644p atmega644pa atmega644rfr2 atmega645 atmega6450 atmega6450a \
+atmega6450p atmega645a atmega645p atmega649 atmega6490 atmega6490a \
+atmega6490p atmega649a atmega649p atmega64c1 atmega64hve atmega64m1 \
+atmega64rfr2 atmega8 atmega8515 atmega8535 atmega88 atmega88a \
+atmega88p atmega88pa atmega8hva atmega8u2 attiny10 attiny102 attiny104 attiny11 \
+attiny12 attiny13 attiny13a attiny15 attiny167 attiny20 attiny22 attiny2313 \
+attiny2313a attiny24 attiny24a attiny25 attiny26 attiny261 attiny261a \
+attiny28 attiny4 attiny40 attiny4313 attiny43u attiny44 attiny44a attiny441 \
+attiny45 attiny461 attiny461a attiny48 attiny5 attiny84 attiny84a attiny841 \
+attiny85 attiny861 attiny861a attiny87 attiny88 attiny9 atxmega128a1 \
+attiny202 attiny204 attiny212 attiny214 attiny402 attiny404 attiny406 \
+attiny412 attiny414 attiny416 attiny417 attiny424 attiny426 attiny427 \
+attiny804 attiny806 attiny807 attiny814 attiny816 attiny817 \
+attiny824 attiny826 attiny827 attiny1604 attiny1606 attiny1607 \
+attiny1614 attiny1616 attiny1617 attiny1624 attiny1626 attiny1627 \
+attiny3214 attiny3216 attiny3217 attiny3224 attiny3226 attiny3227 \
+atmega808 atmega809 atmega1608 atmega1609 atmega3208 atmega3209 atmega4808 atmega4809 \
+atxmega128a1u atxmega128a3 atxmega128d3 atxmega16a4 atxmega16d4 \
+atxmega192a3 atxmega192d3 atxmega256a3 atxmega256a3b atxmega256d3 \
+atxmega32a4 atxmega32d4 atxmega64a1 atxmega64a1u atxmega64a3 \
+atxmega64d3 at90pwm161 ata5272 ata5505 ata5790 ata5795 ata6285 \
+ata6286 ata6616c atmega1284 atmega128a atmega164pa atmega165pa atmega168pa \
+atmega168pb atmega328pb atmega324pb \
+atmega3250pa atmega325pa atmega3290pa atmega32a atmega48pa atmega64a \
+atmega8a attiny1634 attiny828 atxmega128a3u atxmega128a4u atxmega128b1 \
+atxmega128b3 atxmega128c3 atxmega128d4 atxmega16a4u atxmega16c4 \
+atxmega192a3u atxmega192c3 atxmega256a3bu atxmega256a3u atxmega256c3 \
+atxmega32a4u atxmega32c4 atxmega384c3 atxmega384d3 atxmega64a3u \
+atxmega64a4u atxmega64b1 atxmega64b3 atxmega64c3 atxmega64d4 ata6617c \
+ata664251 ata6612c atmega48pb atmega88pb avr16dd14 avr16dd20 avr16dd28 \
+avr16dd32 avr32da28 avr32da32 avr32da48 avr32db28 avr32db32 avr32db48 \
+avr32dd14 avr32dd20 avr32dd28 avr32dd32 avr64da28 avr64da32 avr64da48 \
+avr64da64 avr64db28 avr64db32 avr64db48 avr64db64 avr64dd14 avr64dd20 \
+avr64dd28 avr64dd32 avr128da28 avr128da32 avr128da48 avr128da64 avr128db28 \
+avr128db32 avr128db48 avr128db64 avr16ea28 avr16ea32 avr16ea48 avr16eb14 \
+avr16eb20 avr16eb28 avr16eb32 avr32ea28 avr32ea32 avr32ea48 avr64ea28 avr64ea32 avr64ea48 \
+"}
+
+if [ x"$ATDFDIR" = x ]
+then
+ echo 'Please set $ATDFDIR in your environment' >&2
+ exit 64
+fi
+
+for dev in $devs
+do
+ xmldev=$(echo $dev | tr '[a-z]' '[A-Z]' |\
+ sed -e s/XMEGA/xmega/ -e s/MEGA/mega/ -e s/TINY/tiny/)
+ if [ -f "${ATDFDIR}/${xmldev}.atdf" ]
+ then
+ echo "Generating ${dev}.S"
+ ./ioreg.pl "${ATDFDIR}/${xmldev}.atdf" > ../crt1/iosym/${dev}.S
+ fi
+done
diff --git a/devtools/ioreg.pl b/devtools/ioreg.pl
new file mode 100755
index 00000000..0d2d8943
--- /dev/null
+++ b/devtools/ioreg.pl
@@ -0,0 +1,672 @@
+#!/usr/bin/perl
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Converter from Atmels Device XML-Files via stylesheet to dwarf-2(!)
+# debug information. This debug information is device specific added
+# to the gcrt1-file
+#
+# Created by Knut Schwichtenberg
+# DWARF-2 templates by Joerg Wunsch
+#
+# $Id$
+
+
+# ----------------------------------------------------------------------------
+# "THE BEER-WARE LICENSE" (Revision 42):
+# Knut Schwichtenberg wrote this file. As long as you retain this notice you
+# can do whatever you want with this stuff. If we meet some day, and you think
+# this stuff is worth it, you can buy me a beer in return.
+# ----------------------------------------------------------------------------
+
+########################################################################################
+#
+# Command line parameter
+# -V print version and exit
+# -v be verbose
+# -x path to saxon9
+# -o output file
+#
+# Return values:
+# 0 Okay
+# 1
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Perl modules to be required
+use strict;
+use warnings;
+use Getopt::Std 'getopts';
+my $ContentTmplate;
+my $StaticContent;
+my $EepromTmplate;
+my $Uint32Tmplate;
+
+my $HaveUint32t = 0;
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Static part of the DWARF file
+#
+$StaticContent = <<'EOST';
+/* This file is part of avr-libc.
+
+ Automatically created by devtools/ioreg.pl
+ DO NOT EDIT!
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include <avr/version.h>
+
+#define DW_TAG_array_type 0x01
+#define DW_TAG_compile_unit 0x11
+#define DW_TAG_typedef 0x16
+#define DW_TAG_subrange_type 0x21
+#define DW_TAG_base_type 0x24
+#define DW_TAG_variable 0x34
+
+#define DW_FORM_addr 0x01
+#define DW_FORM_block1 0x0a
+#define DW_FORM_block2 0x03
+#define DW_FORM_block4 0x04
+#define DW_FORM_data1 0x0b
+#define DW_FORM_data2 0x05
+#define DW_FORM_data4 0x06
+#define DW_FORM_data8 0x07
+#define DW_FORM_string 0x08
+#define DW_FORM_flag 0x0c
+#define DW_FORM_strp 0x0e
+#define DW_FORM_ref1 0x11
+#define DW_FORM_ref2 0x12
+#define DW_FORM_ref4 0x13
+#define DW_FORM_ref8 0x14
+
+#define DW_AT_location 0x02
+#define DW_AT_name 0x03
+#define DW_AT_byte_size 0x0b
+#define DW_AT_stmt_list 0x10
+#define DW_AT_language 0x13
+#define DW_AT_producer 0x25
+#define DW_AT_upper_bound 0x2f
+#define DW_AT_decl_file 0x3a
+#define DW_AT_decl_line 0x3b
+#define DW_AT_encoding 0x3e
+#define DW_AT_external 0x3f
+#define DW_AT_type 0x49
+
+#define DW_LANG_C89 0x0001
+
+#define DW_CHILDREN_no 0x00
+#define DW_CHILDREN_yes 0x01
+
+#define DW_ATE_unsigned 0x7
+#define DW_ATE_unsigned_char 0x8
+
+#define DW_OP_addr 0x03
+.eject
+ .section .debug_abbrev, "", @progbits
+.Ldebug_abbrev0:
+ .section .debug_info, "", @progbits
+ .section .debug_line, "", @progbits
+.Ldebug_line0:
+ .section .debug_str, "", @progbits
+
+ .section .debug_info, "", @progbits
+ ;; compilation unit header
+.Lssinfo:
+ .long .Leinfo - .Lsinfo
+.Lsinfo:
+ .word 2 ; DWARF-2
+ .long .Ldebug_abbrev0
+ .byte 4 ; sizeof(address)
+
+
+ ;; DIE #1: compilation unit
+ .section .debug_info
+ .uleb128 1 ; ref to abbrev 1
+ .section .debug_abbrev
+ .uleb128 1
+ .uleb128 DW_TAG_compile_unit
+ .byte DW_CHILDREN_yes
+
+ .uleb128 DW_AT_producer
+ .uleb128 DW_FORM_strp
+ .section .debug_str
+.Lproducer:
+ .ascii "avr-libc "
+ .asciz __AVR_LIBC_VERSION_STRING__
+ .section .debug_info
+ .long .Lproducer
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_stmt_list
+ .uleb128 DW_FORM_data4
+ .section .debug_info
+ .long .Ldebug_line0
+
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+ ;; DIE #2: base type uint8_t
+ .section .debug_info
+.Luint8_t:
+ .uleb128 2 ; ref to abbrev 2
+ .section .debug_abbrev
+ .uleb128 2
+ .uleb128 DW_TAG_base_type
+ .byte DW_CHILDREN_no
+
+ .uleb128 DW_AT_name
+ .uleb128 DW_FORM_strp
+ .section .debug_str
+.Luint8_t_name:
+ .string "uint8_t"
+ .section .debug_info
+ .long .Luint8_t_name
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_byte_size
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte 1
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_encoding
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte DW_ATE_unsigned_char
+
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+ ;; DIE #3: base type uint16_t
+ .section .debug_info
+.Luint16_t:
+ .uleb128 3 ; ref to abbrev 3
+ .section .debug_abbrev
+ .uleb128 3
+ .uleb128 DW_TAG_base_type
+ .byte DW_CHILDREN_no
+
+ .uleb128 DW_AT_name
+ .uleb128 DW_FORM_strp
+ .section .debug_str
+.Luint16_t_name:
+ .string "uint16_t"
+ .section .debug_info
+ .long .Luint16_t_name
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_byte_size
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte 2
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_encoding
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte DW_ATE_unsigned
+
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+EOST
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+#
+$Uint32Tmplate = <<'EOU32';
+;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ ;; DIE #%No: base type uint32_t
+ .section .debug_info
+.Luint32_t:
+ .uleb128 %No ; ref to abbrev %No
+ .section .debug_abbrev
+ .uleb128 %No
+ .uleb128 DW_TAG_base_type
+ .byte DW_CHILDREN_no
+
+ .uleb128 DW_AT_name
+ .uleb128 DW_FORM_strp
+ .section .debug_str
+.Luint32_t_name:
+ .string "uint32_t"
+ .section .debug_info
+ .long .Luint32_t_name
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_byte_size
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte 4
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_encoding
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte DW_ATE_unsigned
+
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+EOU32
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+#
+$ContentTmplate = <<'EODY';
+;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ ;; DIE #%No: variable %Reg
+ .section .debug_info
+ .uleb128 %No ; ref to abbrev %No
+ .section .debug_abbrev
+ .uleb128 %No
+ .uleb128 DW_TAG_variable
+ .byte DW_CHILDREN_no
+
+ .uleb128 DW_AT_name
+ .uleb128 DW_FORM_strp
+ .section .debug_str
+.Lname%No:
+ .string "%Reg"
+ .section .debug_info
+ .long .Lname%No
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_decl_file
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte 0 ; no source file information
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_decl_line
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte 0 ; no source line information
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_type
+ .uleb128 DW_FORM_ref4
+ .section .debug_info
+ .long .Luint%Si_t - .Lssinfo
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_external
+ .uleb128 DW_FORM_flag
+ .section .debug_info
+ .byte 1
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_location
+ .uleb128 DW_FORM_block1
+ .section .debug_info
+ .byte 5 ; length of block
+ .byte DW_OP_addr
+ .long 0x800000 + %Ba + %Of
+
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+EODY
+
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+#
+$EepromTmplate = <<'EOEE';
+;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ ;; DIE #%No1: EEPROM array base type: uint8_t
+ .section .debug_info
+.Leeprom_t:
+ .uleb128 %No1 ; ref to abbrev %No1
+ .section .debug_abbrev
+ .uleb128 %No1
+ .uleb128 DW_TAG_array_type
+ .byte DW_CHILDREN_yes
+
+ .uleb128 DW_AT_type
+ .uleb128 DW_FORM_ref4
+ .section .debug_info
+ .long .Luint8_t - .Lssinfo
+
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+ ;; DIE #%No2: EEPROM array subtype (index type/bounds): uint16_t
+ .section .debug_info
+ .uleb128 %No2 ; ref to abbrev %No2
+ .section .debug_abbrev
+ .uleb128 %No2
+ .uleb128 DW_TAG_subrange_type
+ .byte DW_CHILDREN_no
+
+ .uleb128 DW_AT_type
+ .uleb128 DW_FORM_ref4
+ .section .debug_info
+ .long .Luint16_t - .Lssinfo
+ .section .debug_abbrev
+ .uleb128 DW_AT_upper_bound
+ .uleb128 DW_FORM_data2
+ .section .debug_info
+ .word %Eesize - 1
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+ .section .debug_info
+ .byte 0 ; end of DIE #%No1 children
+
+ ;; DIE #%No3: EEPROM array variable (name)
+ .section .debug_info
+ .uleb128 %No3 ; ref to abbrev %No3
+ .section .debug_abbrev
+ .uleb128 %No3
+ .uleb128 DW_TAG_variable
+ .byte DW_CHILDREN_no
+
+ .uleb128 DW_AT_name
+ .uleb128 DW_FORM_strp
+ .section .debug_str
+.Lname%No3:
+ .string "__eeprom"
+ .section .debug_info
+ .long .Lname%No3
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_decl_file
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte 0 ; no source file information
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_decl_line
+ .uleb128 DW_FORM_data1
+ .section .debug_info
+ .byte 0 ; no source line information
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_type
+ .uleb128 DW_FORM_ref4
+ .section .debug_info
+ .long .Leeprom_t - .Lssinfo
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_external
+ .uleb128 DW_FORM_flag
+ .section .debug_info
+ .byte 1
+
+ .section .debug_abbrev
+ .uleb128 DW_AT_location
+ .uleb128 DW_FORM_block1
+ .section .debug_info
+ .byte 5 ; length of block
+ .byte DW_OP_addr
+ .long 0x810000 + %Of
+
+ .section .debug_abbrev
+ .uleb128 0
+ .uleb128 0
+
+EOEE
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# trailing part of the dwarf Info
+#
+my $trailer = <<'EOT';
+ ;; trailer
+ .section .debug_abbrev
+ .uleb128 0
+
+ .section .debug_info
+ .uleb128 0
+.Leinfo:
+EOT
+
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# All variables need have to be defined -> see "use strict"
+#
+my @allRegister;
+my $staticCmd;
+my $OneRegister;
+my @RegisterParameter;
+my $DIE_No; # Number of the Dwarf-DIE
+my $DynDIE;
+my ( $options, %opts ); # for the command line interpretation
+my $outfile = undef;
+my $XSLPath;
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# $Revision is a RCS Key-Word any other revision system will provide another key-word
+my $VERSION = sprintf("%s",('$Revision: 1.0 $' =~ /(\d*\.\d*[\.\d*]*)/));
+
+sub VERS_MESSAGE(){
+ print STDERR "$0 version: $VERSION Copyright (c) by Knut Schwichtenberg\n";
+ exit(0);
+ die;
+}
+
+sub HELPMESSAGE(){
+ print STDERR "$0 version: $VERSION Copyright (c) by Knut Schwichtenberg\n";
+ print STDERR "Usage: $0\ [switches] AVR_XML_file\n";
+ print STDERR " -h This message\n";
+ print STDERR " -V Version\n";
+ print STDERR " -v Verbose\n";
+ print STDERR " -x path to saxon9\n";
+ print STDERR " -o output file otherwise STDOUT \n";
+}
+
+#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Handle the command line
+
+#$Getopt::Std::STANDARD_HELP_VERSION=1;
+$options = 'hVvx:o:';
+getopts( $options, \%opts );
+if( defined $opts{'h'} ){
+ HELPMESSAGE();
+ exit (0);
+}
+if( defined $opts{'V'} ){
+ VERS_MESSAGE();
+}
+if(! @ARGV ){
+ print "$0: missing file name\n";
+ HELPMESSAGE();
+ exit(-1);
+}
+if( defined $opts{'o'} ){
+ $outfile = $opts{'o'}; #
+ open STDOUT,">$outfile" || die "can't open $_[0]: $!\n";
+}
+if( defined $opts{'x'} ){
+ $XSLPath = $opts{'x'}; #
+} else {
+ $XSLPath = "/usr/share/java/";
+}
+
+# If xsltproc is around, use it. Otherwise, use Saxon9.
+$staticCmd = "java -jar " . $XSLPath . "/saxon9.jar -xsl:findreg.xsl ";
+my $dummy;
+if ($dummy = `xsltproc -V`) {
+ $staticCmd = "xsltproc findreg.xsl ";
+ print STDERR "Using xsltproc for XSL transform\n" if $opts{'v'};
+} else {
+ print STDERR "Using Saxon for XSL transform\n" if $opts{'v'};
+}
+
+#- - - - - - - - - - - - - - - - - - - -
+# Create the static part of the debug information
+my $Filename = "ioreg_static.inc";
+#$StaticContent = do{local $/; open(my $f1, '<', $Filename) or die $!; my $tmp1 = <$f1>; close $f1 or die $!; $tmp1};
+
+#- - - - - - - - - - - - - - - - - - - -
+# For each IO-register a debug-information template is used. First read the template
+$Filename = "ioreg_dyn.inc";
+#$ContentTmplate = do{local $/; open(my $f1, '<', $Filename) or die $!; my $tmp1 = <$f1>; close $f1 or die $!; $tmp1};
+
+#- - - - - - - - - - - - - - - - - - - -
+# Convert via java from XML via XSL into text and put into array
+@allRegister = `$staticCmd $ARGV[0]`;
+
+#- - - - - - - - - - - - - - - - - - - -
+# use STDOUT as output file
+#
+print $StaticContent; # Enter constants and DIE 1-3
+
+$DIE_No = 4; # DIEs 1-3 are used by file, uint8_t, uint16_t
+
+#- - - - - - - - - - - - - - - - - - - -
+# Handle each array element (each register) as a DIE
+#
+foreach $OneRegister (@allRegister) {
+ chomp @RegisterParameter;
+ @RegisterParameter = split /\s+/,$OneRegister; # Register, Base, Offset, Size
+
+ print STDERR "Adding entry for $RegisterParameter[0]\n" if $opts{'v'};
+
+ if ($RegisterParameter[0] eq "eeprom") {
+ # use EEPROM template
+ $DynDIE = $EepromTmplate;
+ $DynDIE =~ s/%No1/$DIE_No/g;
+ $DIE_No++;
+ $DynDIE =~ s/%No2/$DIE_No/g;
+ $DIE_No++;
+ $DynDIE =~ s/%No3/$DIE_No/g;
+ $DIE_No++;
+ $DynDIE =~ s/%Eesize/$RegisterParameter[3]/g;
+ $DynDIE =~ s/%Of/$RegisterParameter[2]/g;
+ } else {
+ # use IO register template
+
+ $RegisterParameter[3] *= 8; # 1 -> uint8_t, 2 -> uint16_t, 4 -> uint32_t
+ if ($RegisterParameter[3] == 32 && !$HaveUint32t) {
+ $HaveUint32t = 1;
+ $DynDIE = $Uint32Tmplate;
+ $DynDIE =~ s/%No/$DIE_No/g;
+ $DIE_No++;
+ print $DynDIE;
+ }
+
+ #- - - - - - - - - - - - - - - - - - - -
+ # Replace variables by register values
+ #
+ ($DynDIE = $ContentTmplate) =~ s/%Reg/$RegisterParameter[0]/g;
+ $DynDIE =~ s/%No/$DIE_No/g;
+ $DynDIE =~ s/%Si/$RegisterParameter[3]/g;
+ $DynDIE =~ s/%Ba/$RegisterParameter[1]/g;
+ $DynDIE =~ s/%Of/$RegisterParameter[2]/g;
+ $DIE_No++;
+ }
+ print $DynDIE;
+}
+print $trailer;
+close;
+__END__
+=head1 NAME
+
+ioreg.pl - Create debug information from Atmel XML files for IO-Ports and EEProm
+
+=head1 SYNOPSIS
+
+ perl ioreg.pl xxxxx.XML
+
+=head1 DESCRIPTION
+
+Using GDB and AVaRICE to debug AVR code requires to know the addresses of
+IO registers! The GDB command "x PORTA" leads to an unknown address
+error. Beginning with Atmel Studio 5 well formed XML file are deliverd
+as part of the installation. This script converts these XML-files using a
+stylesheet into dwarf-2 debug information. To prevent Atmel's debugger from
+crashing only dwarf-2 can be used, while GDB could use debug information
+up to dwarf-4. Similar to the handling of the IO-addresses the eeprom
+start address can be accessed by the label __eeprom. Its type is an CPU
+specific array of uint8_t.
+
+This debug information is added to the device specific start-up code of
+avr-libc and now allows debugging symbolic
+names.
+It is possible to use dwarf-4 debug information for the
+application and mix it with dwarf-2 of the start-up code.
+
+=head1 Preconditions
+
+This script relies on
+
+=over 3
+
+=item *
+Atmel's AVR XML files
+
+=item *
+Stylesheet file named "findreg.xsl". It has to be located in the same directory as ioreg.pl
+
+=item *
+XSLT processor, either xsltproc or saxon9
+
+=back
+
+If xsltproc is used, it must be in the PATH. Using saxon9 gives a runtime warning which can be ignored.
+
+=head1 Command line parameters
+
+The following command line parameters are supported
+
+=over 5
+
+=item h
+
+Print the help infomation to STDERR
+
+=item V
+
+Print the version information to STDERR
+
+=item v
+
+Print verbose information to STDERR
+
+=item x
+
+Sets the path to saxon9. Default: /usr/share/java
+
+=item o
+
+Set the output file otherwise STDOUT is used
+
+=back
+
+=head1 Authors
+
+Knut Schwichtenberg / Joerg Wunsch
diff --git a/devtools/specs2libtree.py b/devtools/specs2libtree.py
new file mode 100755
index 00000000..04696991
--- /dev/null
+++ b/devtools/specs2libtree.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+#
+# ----------------------------------------------------------------------------
+# "THE BEER-WARE LICENSE" (Revision 42):
+# <j@uriah.heep.sax.de> wrote this file. As long as you retain this notice you
+# can do whatever you want with this stuff. If we meet some day, and you think
+# this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
+# ----------------------------------------------------------------------------
+
+# Tool to extract some data out of a bunch of GCC specs files,
+# providing snippets for gen-avr-lib-tree.sh, and <avr/io.h>.
+#
+# Intended to run on specs files from Microchip "device packs", to
+# ease integration of new devices.
+
+import sys
+import re
+
+def usage():
+ print('usage: spec2libtree.py <specfiles>', file = sys.stderr)
+ sys.exit(64)
+
+def parse_specs(name):
+ mcuclass = ''
+ flashsize = ''
+ crtfile = ''
+ devname = ''
+ macro = ''
+ header = ''
+ # pre-compile regexps
+ mcu_re = re.compile('.*-mmcu=([^ ]+) ')
+ flash_re = re.compile('.*--pmem-wrap-around=([\d]+)')
+ crt_re = re.compile('.*(crt[a-z0-9]+\.o)')
+ devname_re = re.compile('.*-D(__AVR[^ ]+__).*-D__AVR_DEVICE_NAME__=([a-z0-9]+).*-D__AVR_DEV_LIB_NAME__=([A-Za-z0-9]+)')
+
+ with open(name) as f:
+ l = f.readlines()
+ i = 0
+ for line in l:
+ x = line.find('self_spec')
+ if x >= 0:
+ # next line is supposed to have the MCU group
+ m = mcu_re.match(l[i + 1])
+ if m:
+ mcuclass = m.group(1)
+ x = line.find('link_pmem_wrap')
+ if x >= 0:
+ # if next line has --pmem-wrap-around=64k this gets
+ # us the flash size; if empty, assume 128k;
+ # flash size is only used to distinguish between
+ # ${CFLAGS_SPACE} and ${CFLAGS_BIG_MEMORY}
+ m = flash_re.match(l[i + 1])
+ if m:
+ flashsize = m.group(1)
+ else:
+ flashsize = 128
+ x = line.find('avrlibc_startfile')
+ if x >= 0:
+ m = crt_re.match(l[i + 1])
+ if m:
+ crtfile = m.group(1)
+ x = line.find('cpp')
+ if x >= 0:
+ # next line has CPP macros, among them the device name
+ m = devname_re.match(l[i + 1])
+ if m:
+ devname = m.group(2)
+ macro = m.group(1)
+ header = m.group(3)
+ i = i + 1
+ return (mcuclass, flashsize, crtfile, devname, macro, header)
+ return None
+
+classes = {}
+
+if len(sys.argv) <= 1:
+ usage()
+
+# parse all input files
+for arg in sys.argv[1:]:
+ result = parse_specs(arg)
+ if result != None:
+ (mcuclass, flashsize, crtfile, devname, macro, header) = result
+ key = mcuclass.upper() + '_DEV_INFO'
+ data = devname + ':' + crtfile + ':${DEV_DEFS}:'
+ if int(flashsize) >= 64:
+ data += '${CFLAGS_BIG_MEMORY}:${DEV_ASFLAGS};\\'
+ else:
+ data += '${CFLAGS_SPACE}:${DEV_ASFLAGS};\\'
+ try:
+ classes[key].append((data, macro, header))
+ except KeyError:
+ classes[key] = [(data, macro, header)]
+
+k = list(classes.keys())
+k.sort()
+
+# output #1: gen-avr-lib-tree.sh snippets
+for key in k:
+ d = classes[key]
+ print(key + '="\\')
+ i = 0
+ for data in d:
+ data = data[0] # remove macro and header
+ if i == len(d) - 1:
+ # drop semicolon
+ print(data[:-2] + data[-1:])
+ else:
+ print(data)
+ i += 1
+ print('"')
+
+# output #2: <avr/io.h> addition
+for key in k:
+ d = classes[key]
+ for data in d:
+ print('#elif defined (' + data[1] + ')')
+ print('# include <avr/io' + data[2] + '.h>')
diff --git a/doc/LICENSE-Changes/PERM-Bob-Paddock b/doc/LICENSE-Changes/PERM-Bob-Paddock
new file mode 100644
index 00000000..f72c651f
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Bob-Paddock
@@ -0,0 +1,45 @@
+From bpaddock@csonline.net Thu Nov 11 11:54:04 2004
+Date: Mon, 1 Nov 2004 19:49:51 +0000
+From: Bob Paddock <bpaddock@csonline.net>
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] Re: avr-libc licensing audit
+
+On Monday 01 November 2004 10:30 pm, E. Weddington wrote:
+> Bob Paddock,
+>
+> I've been conducting an audit of the licenses in the files in avr-libc
+>...
+> May I have your permission to modify the licenses of all the files in
+> avr-libc where you hold the copyright, to add the missing clause
+> reproduced below?
+
+Yes you may change the file. I have been following the discussion on the
+list.
+
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+
+Just so this is clear in my own mind, is is ok to say "This product was
+developed using GCC and avr-libc" on my web site if I ever have a product to
+sell?
+
+It would be bad if I listed anyones name that I find in the code on the web
+site where trying to sell product?
+
+> If I have your permission please respond to this email that you give
+> your permission and be sure to keep the CC to the avr-libc-dev mailing
+> list where it may be archived.
+
+--
+ <20> <20> <20> http://www.softwaresafety.net/
+<2B>http://www.unusualresearch.com/ http://www.bpaddock.com/
+
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Colin-OFlynn b/doc/LICENSE-Changes/PERM-Colin-OFlynn
new file mode 100644
index 00000000..c61234c6
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Colin-OFlynn
@@ -0,0 +1,53 @@
+From coflynn@newae.com Thu Nov 11 11:55:40 2004
+Date: Fri, 29 Oct 2004 17:59:22 -0300
+From: Colin O'Flynn <coflynn@newae.com>
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] Re: avr-libc license audit
+
+Hello,
+
+Sorry about that - you have my full permission to modify those
+files to which I have a copyright to include the additional
+clause.
+
+Regards,
+
+ -Colin O'Flynn
+
+
+On October 29, 2004 5:14 pm, you wrote:
+> Hi Colin,
+>
+> I've been conducting an audit of the licenses in the files in
+> avr-libc <http://savannah.nongnu.org/projects/avr-libc/>.
+> avr-libc is supposed to be licensed with a modified BSD
+> license that contains the "no advertising" clause. I've
+> discovered a number of files that have incorrect licensing and
+> are missing the "no advertising" clause including some files
+> where you hold the copyright.
+>
+> May I have your permission to modify the licenses of all the
+> files in avr-libc where you hold the copyright, to add the
+> missing clause reproduced below?
+>
+> * Neither the name of the copyright holders nor the names
+> of contributors may be used to endorse or promote products
+> derived from this software without specific prior written
+> permission.
+>
+> If I have your permission please respond to this email that
+> you give your permission and be sure to keep the CC to the
+> avr-libc-dev mailing list where it may be archived.
+>
+> Thank you.
+> Eric Weddington
+> avr-libc developer
+
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Joerg-Wunsch b/doc/LICENSE-Changes/PERM-Joerg-Wunsch
new file mode 100644
index 00000000..3e2bb211
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Joerg-Wunsch
@@ -0,0 +1,40 @@
+From j@ida.interface-business.de Thu Nov 11 11:56:45 2004
+Date: Thu, 28 Oct 2004 23:25:05 +0200
+From: Joerg Wunsch <j@ida.interface-business.de>
+Reply-To: Joerg Wunsch <joerg_wunsch@interface-systems.de>
+To: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: Re: [avr-libc-dev] [RFC] Licensing information
+
+As E. Weddington wrote:
+
+> Attached are IMO what the LICENSING and AUTHORS file should be.
+
+Thank you!
+
+> Now to the big problem: The original license file said that avr-libc was
+> a Modified BSD License (with the No Advertising clause). However the
+> "template" that it gave for new authors, only showed the original two
+> clauses of the BSD license.
+
+The original BSD license had four clauses, where the `No advertising'
+clause was #3, and later officially dropped. Individual *BSD
+developers later on also dropped clause #4 ("name ... may not be used
+to endorse"), which led to the two-clause template we had by now.
+
+For those files where I hold the copyright, I don't mind whether it's
+the 2-clause or 3-clause version. I agree we should settle for one of
+both, and see to convert the remaining files (given author's
+permission). It seems converting everything to the 3-clause version
+is less work, so let's pick this one.
+
+Thanks again!
+--
+J"org Wunsch Unix support engineer
+joerg_wunsch@interface-systems.de http://www.interface-systems.de/~j/
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Juergen-Schilling b/doc/LICENSE-Changes/PERM-Juergen-Schilling
new file mode 100644
index 00000000..5f1f50d8
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Juergen-Schilling
@@ -0,0 +1,61 @@
+From juergen.schilling@honeywell.com Thu Nov 11 11:53:02 2004
+Date: Wed, 3 Nov 2004 00:39:00 -0700
+From: "Schilling, Juergen (GE51)" <juergen.schilling@honeywell.com>
+To: 'E. Weddington' <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] AW: avr-libc license audit
+
+Hi Eric,
+
+I don't have problems with that, so you have my permission to modify the
+files.
+
+Regards,
+Juergen
+
+
+> -----Urspr<70>ngliche Nachricht-----
+> Von: E. Weddington [mailto:ericw@evcohs.com]
+> Gesendet: Dienstag, 2. November 2004 19:46
+> An: Juergen Schilling
+> Cc: avr-libc-dev
+> Betreff: avr-libc license audit
+>
+>
+> Juergen,
+>
+> I've been conducting an audit of the licenses in the files in
+> avr-libc
+> <http://savannah.nongnu.org/projects/avr-libc/>. avr-libc is
+> supposed to
+> be licensed with a modified BSD license that contains a "no
+> endorsement"
+> clause. I've discovered a number of files that have incorrect
+> licensing
+> and are missing this clause including some files where you hold the
+> copyright.
+>
+> May I have your permission to modify the licenses of all the files in
+> avr-libc where you hold the copyright, to add the missing clause
+> reproduced below?
+>
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+>
+> If I have your permission please respond to this email that you give
+> your permission and be sure to keep the CC to the
+> avr-libc-dev mailing
+> list where it may be archived.
+>
+> Thank you.
+> Eric Weddington
+> avr-libc developer
+>
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Keith-Gudger b/doc/LICENSE-Changes/PERM-Keith-Gudger
new file mode 100644
index 00000000..152450ff
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Keith-Gudger
@@ -0,0 +1,50 @@
+From keith@atmel.com Thu Nov 11 11:55:23 2004
+Date: Fri, 29 Oct 2004 13:57:44 -0700 (PDT)
+From: Keith Gudger <keith@atmel.com>
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] Re: avr-libc license audit
+
+Eric:
+
+Yes, you have my permission to change the copyright as you mentioned in
+the text below.
+
+Keith Gudger
+29-Oct-2004
+
+On Fri, 29 Oct 2004, E. Weddington wrote:
+
+> Hi Keith,
+>
+> I've been conducting an audit of the licenses in the files in avr-libc
+> <http://savannah.nongnu.org/projects/avr-libc/>. avr-libc is supposed to
+> be licensed with a modified BSD license that contains the "no
+> advertising" clause. I've discovered a number of files that have
+> incorrect licensing and are missing the "no advertising" clause
+> including some files where you hold the copyright.
+>
+> May I have your permission to modify the licenses of all the files in
+> avr-libc where you hold the copyright, to add the missing clause
+> reproduced below?
+>
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+>
+> If I have your permission please respond to this email that you give
+> your permission and be sure to keep the CC to the avr-libc-dev mailing
+> list where it may be archived.
+>
+> Thank you.
+> Eric Weddington
+> avr-libc developer
+>
+
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Marek-Michalkiewicz b/doc/LICENSE-Changes/PERM-Marek-Michalkiewicz
new file mode 100644
index 00000000..1642a387
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Marek-Michalkiewicz
@@ -0,0 +1,69 @@
+From marekm@amelek.gda.pl Thu Nov 11 11:54:55 2004
+Date: Fri, 29 Oct 2004 23:38:08 +0200
+From: Marek Michalkiewicz <marekm@amelek.gda.pl>
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev@nongnu.org
+Subject: Re: [avr-libc-dev] avr-libc license audit
+
+On Fri, Oct 29, 2004 at 02:56:02PM -0600, E. Weddington wrote:
+>
+> The problem is that the original LICENSE file said that avr-libc is
+> licensed with
+> "Modified BSD license (no advertising clause)"
+> There are many files in there that are *not licensed this way*, only
+> having 2 clauses and not including the "no advertising" clause.
+
+Poorly defined operator precedence ;) - it was meant to be read as:
+
+(no (advertising clause))
+
+not as:
+
+((no advertising) clause)
+
+where the "advertising clause" is the one which was removed from the
+original (4-clause) BSD license. The problem (full-page ads, etc.)
+is explained in http://www.gnu.org/philosophy/bsd.html .
+
+Some time ago, I chose the 3-clause BSD license as a fairly simple,
+liberal and standard one. Later, BSD people made it even simpler by
+removing another clause (I guess it was a problem for someone again...
+licensing issues are evil), and I have no problem with that, so I
+started using the 2-clause license in newer files (and probably
+forgot to update some of the older ones).
+
+> The "no advertising" is only marginally restrictive:
+>
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+>
+> It only restricts the user of avr-libc so they don't go off and say
+> "Marek Michalkiewicz endorses the use of this product! :-) Buy it!".
+> This is a fairly reaonable restriction for users.
+
+No problem for me either way - it was never my intent to add more
+restrictions, as they only make things more complicated for everyone
+(especially if one program contains code with different licenses: you
+have to check each license if it is compatible with all others, grrr...).
+
+> So, then do I have your permission to change the files that you hold a
+> copyright on to include the "no adverstising" clause? If yes, could you
+> CC avr-libc-dev?
+
+Yes. But, you could just as well do the reverse: ask authors who
+hold copyright on files with 3-clause license if they agree to
+remove that one clause (I agree, if I forgot to remove that clause
+from any of the files I wrote). It's up to you. Sorry for not
+speaking up about this earlier (I'm overworked as usual).
+
+Thanks,
+Marek
+
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Micheal-Stumpf b/doc/LICENSE-Changes/PERM-Micheal-Stumpf
new file mode 100644
index 00000000..925d8524
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Micheal-Stumpf
@@ -0,0 +1,70 @@
+From mistumpf@de.pepperl-fuchs.com Thu Nov 11 11:50:21 2004
+Date: Wed, 10 Nov 2004 10:13:19 +0100
+From: Stumpf Michael <mistumpf@de.pepperl-fuchs.com>
+To: 'E. Weddington' <ericw@evcohs.com>,
+ Stumpf Michael <mistumpf@de.pepperl-fuchs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] AW: avr-libc license audit
+
+Hello,
+
+I never cared much about licences, so feel free to apply the
+modifications as you suggested.
+No problem with relicencing the math lib either.
+
+best regards,
+Michael Stumpf
+
+> -----Urspr<70>ngliche Nachricht-----
+> Von: E. Weddington [mailto:ericw@evcohs.com]
+> Gesendet: Dienstag, 9. November 2004 21:49
+> An: MiStumpf@de.pepperl-fuchs.com
+> Cc: avr-libc-dev
+> Betreff: avr-libc license audit
+>
+>
+> Michael Stumpf,
+>
+> I've been conducting an audit of the licenses in the files in
+> avr-libc
+> <http://savannah.nongnu.org/projects/avr-libc/>. avr-libc is
+> supposed to
+> be licensed with a modified BSD license that contains a "no
+> endorsement"
+> clause. I've discovered a number of files that have incorrect
+> licensing
+> and are missing this clause including some files where you hold the
+> copyright, specifically I am referring to include/ctype.h and
+> include/math.h, NOT the math library.
+>
+> May I have your permission to modify the licenses of the two files in
+> avr-libc listed above where you hold the copyright, to add
+> the missing
+> clause reproduced below?
+>
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+>
+> If I have your permission please respond to this email that you give
+> your permission and be sure to keep the CC to the
+> avr-libc-dev mailing
+> list where it may be archived.
+>
+> As a seperate issue, would you be willing to relicense the
+> avr-libc math
+> library functions written by you to have the Modified BSD
+> License (the
+> same as the rest of avr-libc)? This would greatly help in making the
+> licensing for all of avr-libc consistent. I also understand if you do
+> not wish to do this.
+>
+> Thank you.
+> Eric Weddington
+> avr-libc developer
+>
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Nils-Kristian-Strom b/doc/LICENSE-Changes/PERM-Nils-Kristian-Strom
new file mode 100644
index 00000000..3244d8da
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Nils-Kristian-Strom
@@ -0,0 +1,31 @@
+From nilsst@invalid.ed.ntnu.no Thu Nov 11 11:52:24 2004
+Date: Wed, 03 Nov 2004 08:12:27 +0100
+From: Nils Kristian Strom <nilsst@invalid.ed.ntnu.no>
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>,
+ Nils Kristian Strom <nilsst@omegav.ntnu.no>
+Subject: [avr-libc-dev] Re: avr-libc license audit
+
+On Tue, 2004-11-02 at 11:47 -0700, E. Weddington wrote:
+> May I have your permission to modify the licenses of all the files in
+> avr-libc where you hold the copyright, to add the missing clause
+> reproduced below?
+
+Yes, you have my permission to modify those files to which I have a
+copyright.
+
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+
+Best regards,
+Nils Strom
+
+
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Peter-Jansen b/doc/LICENSE-Changes/PERM-Peter-Jansen
new file mode 100644
index 00000000..9f98c47d
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Peter-Jansen
@@ -0,0 +1,67 @@
+From peter.jansen@aad.gov.au Thu Nov 11 11:50:50 2004
+Date: Wed, 10 Nov 2004 09:35:52 +1100
+From: Peter Jansen <peter.jansen@aad.gov.au>
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] Re: avr-libc contribution?
+
+E. Weddington wrote:
+> Peter Jansen wrote:
+>
+>> E. Weddington wrote:
+>>
+>>> Peter,
+>>>
+>>> I'm trying to find the Peter Jansen that made a contribution of the
+>>> iom128.h header file to the avr-libc project:
+>>> <http://savannah.nongnu.org/projects/avr-libc/>
+>>>
+>>> This email was suggested to me by one of the admins of that project.
+>>> Are you the original submitter of this file?
+>>
+>>
+>>
+>> Yes I think I submitted that file, I have not worked on AVR's for a
+>> while, do you have some questions?
+>>
+>>
+> Yes, I've been conducting an audit of the licenses in the files in
+> avr-libc <http://savannah.nongnu.org/projects/avr-libc/>. avr-libc is
+> supposed to be licensed with a modified BSD license that contains a "no
+> endorsement" clause. I've discovered a number of files that have
+> incorrect licensing and are missing this clause including that file
+> (iom128.h) where you hold the copyright.
+>
+> May I have your permission to modify the licenses of all the files in
+> avr-libc where you hold the copyright, to add the missing clause
+> reproduced below?
+>
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+>
+> If I have your permission please respond to this email that you give
+> your permission and be sure to keep the CC to the avr-libc-dev mailing
+> list where it may be archived.
+
+Yes you have my permission to modify the license as per your above text.
+
+Thanks it must be difficult to follow all those up.
+
+--
+Peter Jansen
+STS
+Australian Antarctic Division
+Channel Highway
+Kingston
+TAS 7050
+AUSTRALIA
+Ph (03) 62 323 533
+Fax (03) 62 323 351
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Reinhard-Jessich b/doc/LICENSE-Changes/PERM-Reinhard-Jessich
new file mode 100644
index 00000000..2fdac0bd
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Reinhard-Jessich
@@ -0,0 +1,47 @@
+From reinhard.jessich@telering.at Thu Nov 11 11:51:50 2004
+Date: Fri, 5 Nov 2004 22:28:18 +0100
+From: reinhard.jessich@telering.at
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] Re: avr-libc license audit
+
+On Wed, 03 Nov 2004, E. Weddington wrote:
+You have the permission to change what ever you want.
+BR
+ Reinhard
+
+> Reinhard,
+>
+> I've been conducting an audit of the licenses in the files in avr-libc
+> <http://savannah.nongnu.org/projects/avr-libc/>. avr-libc is supposed to
+> be licensed with a modified BSD license that contains a "no endorsement"
+> clause. I've discovered a number of files that have incorrect licensing
+> and are missing this clause including some files where you hold the
+> copyright.
+>
+> May I have your permission to modify the licenses of all the files in
+> avr-libc where you hold the copyright, to add the missing clause
+> reproduced below?
+>
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+>
+> If I have your permission please respond to this email that you give
+> your permission and be sure to keep the CC to the avr-libc-dev mailing
+> list where it may be archived.
+>
+> Thank you.
+> Eric Weddington
+> avr-libc developer
+--
+ Ing. Reinhard Jessich mailto: reinhard.jessich@telering.at
+ A-1190 Vienna, Goergengasse 2/2/1 phone: +43/1/3692600
+ http://members.telering.at/jessich mobile: +43/664/1735439
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Steinar-Haugen b/doc/LICENSE-Changes/PERM-Steinar-Haugen
new file mode 100644
index 00000000..5610ae90
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Steinar-Haugen
@@ -0,0 +1,50 @@
+From xoplanet@msn.com Thu Nov 11 11:53:40 2004
+Date: Tue, 02 Nov 2004 19:32:35 +0100
+From: Stone Hill <xoplanet@msn.com>
+To: ericw@evcohs.com
+Cc: avr-libc-dev@nongnu.org
+Subject: [avr-libc-dev] RE: avr-libc license audit
+
+Yes, You have my permission to modify those
+files to which I have a copyright.
+
+Best regards,
+Steinar Haugen
+
+
+>From: "E. Weddington" <ericw@evcohs.com>
+>To: Steinar Haugen <xoplanet@msn.com>
+>CC: avr-libc-dev <avr-libc-dev@nongnu.org>
+>Subject: avr-libc license audit
+>Date: Mon, 01 Nov 2004 15:28:25 -0700
+>
+>I've been conducting an audit of the licenses in the files in avr-libc
+><http://savannah.nongnu.org/projects/avr-libc/>. avr-libc is supposed to be
+>licensed with a modified BSD license that contains a "no endorsement"
+>clause. I've discovered a number of files that have incorrect licensing and
+>are missing this clause including some files where you hold the copyright.
+>
+>May I have your permission to modify the licenses of all the files in
+>avr-libc where you hold the copyright, to add the missing clause reproduced
+>below?
+>
+> * Neither the name of the copyright holders nor the names of
+> contributors may be used to endorse or promote products derived
+> from this software without specific prior written permission.
+>
+>If I have your permission please respond to this email that you give your
+>permission and be sure to keep the CC to the avr-libc-dev mailing list
+>where it may be archived.
+>
+>Thank you.
+>Eric Weddington
+>avr-libc developer
+
+
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/LICENSE-Changes/PERM-Theodore-A-Roth b/doc/LICENSE-Changes/PERM-Theodore-A-Roth
new file mode 100644
index 00000000..64b3b3b0
--- /dev/null
+++ b/doc/LICENSE-Changes/PERM-Theodore-A-Roth
@@ -0,0 +1,37 @@
+From troth@openavr.org Thu Nov 11 11:57:48 2004
+Date: Tue, 2 Nov 2004 08:56:48 -0800 (PST)
+From: Theodore A. Roth <troth@openavr.org>
+To: E. Weddington <ericw@evcohs.com>
+Cc: avr-libc-dev <avr-libc-dev@nongnu.org>
+Subject: [avr-libc-dev] Re: Missing copyrights?
+
+On Tue, 2 Nov 2004, E. Weddington wrote:
+
+> Theodore A. Roth wrote:
+>
+> >I have just added copyrights to the files I wrote in CVS HEAD. [See
+> >attached patch.]
+> >
+> >
+> >
+> Thanks. One note though: acconfig.h just has the two-clause license.
+> While I'm at it, can I have your permission to fix all of your
+> copyrighted files in avr-libc to add the missing clause?
+
+Pooh. I tried to add all those with the 3 clause, but looks like
+copy-paste got me again. ;-)
+
+Yes, got ahead and add the 3rd clause on any of my files that are
+missing it.
+
+---
+Ted Roth
+PGP Key ID: 0x18F846E9
+Jabber ID: troth@jabber.org
+
+
+_______________________________________________
+AVR-libc-dev mailing list
+AVR-libc-dev@nongnu.org
+http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
+
diff --git a/doc/api/avr-libc-logo-large.png b/doc/api/avr-libc-logo-large.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb8e7dba7ea33a03c073af46369f5b4f77cc694d
GIT binary patch
literal 18555
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
literal 0
HcmV?d00001
diff --git a/doc/api/avr-libc-logo.xcf.bz2 b/doc/api/avr-libc-logo.xcf.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..0510002ee974eee36cf5eded389f5c83931a319f
GIT binary patch
literal 12098
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
literal 0
HcmV?d00001
diff --git a/doc/api/dox_latex_header.tex b/doc/api/dox_latex_header.tex
new file mode 100644
index 00000000..2d1ae938
--- /dev/null
+++ b/doc/api/dox_latex_header.tex
@@ -0,0 +1,258 @@
+% Latex header for doxygen 1.9.6
+ % Handle batch mode
+%%BEGIN LATEX_BATCHMODE
+ \batchmode
+%%END LATEX_BATCHMODE
+
+ % to overcome problems with too many open files
+ \let\mypdfximage\pdfximage\def\pdfximage{\immediate\mypdfximage}
+
+ % Set document class depending on configuration
+%%BEGIN COMPACT_LATEX
+ \documentclass[twoside]{article}
+%%END COMPACT_LATEX
+%%BEGIN !COMPACT_LATEX
+ \documentclass[twoside]{book}
+%%END !COMPACT_LATEX
+
+ %% moved from doxygen.sty due to workaround for LaTex 2019 version and unmaintained tabu package
+ \usepackage{ifthen}
+ \ifx\requestedLaTeXdate\undefined
+ \usepackage{array}
+ \else
+ \usepackage{array}[=2016-10-06]
+ \fi
+ %%
+
+ % Packages required by doxygen
+ \usepackage{fixltx2e} % for \textsubscript
+ \usepackage{doxygen}
+
+ $extralatexstylesheet
+
+ \usepackage{graphicx}
+ \usepackage[utf8]{inputenc}
+ \usepackage{makeidx}
+ \PassOptionsToPackage{warn}{textcomp}
+ \usepackage{textcomp}
+ \usepackage[nointegrals]{wasysym}
+ \usepackage{ifxetex}
+
+ % NLS support packages
+ $languagesupport
+
+ % Define default fonts
+ % Font selection
+%%BEGIN LATEX_FONTENC
+ \usepackage[$latexfontenc]{fontenc}
+%%END LATEX_FONTENC
+
+ % set main and monospaced font
+ $latexfont
+
+ \usepackage{sectsty}
+ \allsectionsfont{%
+ \fontseries{bc}\selectfont%
+ \color{darkgray}%
+ }
+ \renewcommand{\DoxyLabelFont}{%
+ \fontseries{bc}\selectfont%
+ \color{darkgray}%
+ }
+ \newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}}
+
+ % Arguments of doxygenemoji:
+ % 1) ':<text>:' form of the emoji, already LaTeX-escaped
+ % 2) file with the name of the emoji without the .png extension
+ % in case image exist use this otherwise use the ':<text>:' form
+ \newcommand{\doxygenemoji}[2]{%
+ \IfFileExists{$latexemojidirectory/#2.png}{\raisebox{-0.1em}{\includegraphics[height=0.9em]{$latexemojidirectory/#2.png}}}{#1}%
+ }
+
+ % Page & text layout
+ \usepackage{geometry}
+ \geometry{%
+ $papertype,%
+ top=2.5cm,%
+ bottom=2.5cm,%
+ left=2.5cm,%
+ right=2.5cm%
+ }
+ \usepackage{changepage}
+
+ % Allow a bit of overflow to go unnoticed by other means
+ \tolerance=750
+ \hfuzz=15pt
+ \hbadness=750
+ \setlength{\emergencystretch}{15pt}
+ \setlength{\parindent}{0cm}
+ \newcommand{\doxynormalparskip}{\setlength{\parskip}{3ex plus 2ex minus 2ex}}
+ \newcommand{\doxytocparskip}{\setlength{\parskip}{1ex plus 0ex minus 0ex}}
+ \doxynormalparskip
+ % Redefine paragraph/subparagraph environments, using sectsty fonts
+ \makeatletter
+ \renewcommand{\paragraph}{%
+ \@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%
+ \normalfont\normalsize\bfseries\SS@parafont%
+ }%
+ }
+ \renewcommand{\subparagraph}{%
+ \@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%
+ \normalfont\normalsize\bfseries\SS@subparafont%
+ }%
+ }
+ \makeatother
+
+ \makeatletter
+ \newcommand\hrulefilll{\leavevmode\leaders\hrule\hskip 0pt plus 1filll\kern\z@}
+ \makeatother
+
+ % Headers & footers
+ \usepackage{fancyhdr}
+ \pagestyle{fancyplain}
+ \renewcommand{\footrulewidth}{0.4pt}
+
+ \fancypagestyle{fancyplain}{
+ \fancyhf{}
+ \fancyhead[LE, RO]{\bfseries\thepage}
+ \fancyhead[LO]{\bfseries\rightmark}
+ \fancyhead[RE]{\bfseries\leftmark}
+ \fancyfoot[LO, RE]{\bfseries\scriptsize $generatedby Doxygen }
+ }
+
+ \fancypagestyle{plain}{
+ \fancyhf{}
+ \fancyfoot[LO, RE]{\bfseries\scriptsize $generatedby Doxygen }
+ \renewcommand{\headrulewidth}{0pt}
+ }
+
+ \pagestyle{fancyplain}
+
+
+%%BEGIN !COMPACT_LATEX
+ \renewcommand{\chaptermark}[1]{%
+ \markboth{#1}{}%
+ }
+%%END !COMPACT_LATEX
+ \renewcommand{\sectionmark}[1]{%
+ \markright{\thesection\ #1}%
+ }
+
+ % ToC, LoF, LoT, bibliography, and index
+ % Indices & bibliography
+ \usepackage{natbib}
+ \usepackage[titles]{tocloft}
+ \setcounter{tocdepth}{3}
+ \setcounter{secnumdepth}{5}
+
+ % creating indexes
+ $makeindex
+
+ $extralatexpackages
+
+ $latexspecialformulachars
+
+%%BEGIN FORMULA_MACROFILE
+ \input{$formulamacrofile}
+%%END FORMULA_MACROFILE
+
+ % Hyperlinks
+%%BEGIN PDF_HYPERLINKS
+ % Hyperlinks (required, but should be loaded last)
+ \ifpdf
+ \usepackage[pdftex,pagebackref=true]{hyperref}
+ \else
+ \ifxetex
+ \usepackage[pagebackref=true]{hyperref}
+ \else
+ \usepackage[ps2pdf,pagebackref=true]{hyperref}
+ \fi
+ \fi
+
+ \hypersetup{%
+ colorlinks=true,%
+ linkcolor=blue,%
+ citecolor=blue,%
+ unicode,%
+ pdftitle={$projectname},%
+ pdfsubject={$projectbrief}%
+ }
+
+%%END PDF_HYPERLINKS
+
+ % Custom commands used by the header
+ % Custom commands
+ \newcommand{\clearemptydoublepage}{%
+ \newpage{\pagestyle{empty}\cleardoublepage}%
+ }
+
+ % caption style definition
+ \usepackage{caption}
+ \captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top}
+
+
+ % in page table of contents
+ \usepackage{etoc}
+ \etocsettocstyle{\doxytocparskip}{\doxynormalparskip}
+
+ % prevent numbers overlap the titles in toc
+ \renewcommand{\numberline}[1]{#1~}
+
+% End of preamble, now comes the document contents
+%===== C O N T E N T S =====
+
+\begin{document}
+ \raggedbottom
+
+ $latexdocumentpre
+
+ % Titlepage & ToC
+%%BEGIN PDF_HYPERLINKS
+%%BEGIN USE_PDFLATEX
+ % To avoid duplicate page anchors due to reuse of same numbers for
+ % the index (be it as roman numbers)
+ \hypersetup{pageanchor=false,
+ bookmarksnumbered=true,
+ pdfencoding=unicode
+ }
+%%END USE_PDFLATEX
+%%END PDF_HYPERLINKS
+ \pagenumbering{alph}
+ \begin{titlepage}
+ \vspace*{4cm}
+ \begin{center}%
+ \includegraphics*[width=6cm]{avr-libc-logo-large.png}\\
+ \vspace*{3cm}
+ {\Huge $title}\\
+%%BEGIN PROJECT_NUMBER
+ [1ex]\Large $projectnumber \\
+%%END PROJECT_NUMBER
+ \vspace*{1cm}
+ {\large $generatedby Doxygen $doxygenversion}\\
+%%BEGIN LATEX_TIMESTAMP
+ \vspace*{0.5cm}
+ {\large $datetime}
+%%END LATEX_TIMESTAMP
+ \end{center}
+ \end{titlepage}
+
+%%BEGIN !COMPACT_LATEX
+ \clearemptydoublepage
+%%END !COMPACT_LATEX
+ \pagenumbering{roman}
+
+ \tableofcontents
+%%BEGIN !COMPACT_LATEX
+ \clearemptydoublepage
+%%END !COMPACT_LATEX
+ \pagenumbering{arabic}
+
+%%BEGIN PDF_HYPERLINKS
+%%BEGIN USE_PDFLATEX
+ % re-enable anchors again
+ \hypersetup{pageanchor=true}
+%%END USE_PDFLATEX
+%%END PDF_HYPERLINKS
+
+%--- Begin generated contents ---
+
diff --git a/doc/api/filter-dox.sh b/doc/api/filter-dox.sh
new file mode 100755
index 00000000..886f1338
--- /dev/null
+++ b/doc/api/filter-dox.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# Used per doc/api/doxygen.config[.in]'s INPUT_FILTER.
+# Prune some identifiers so that the generated documentation
+# looks nicer and avoids internal stuff like __ATTR_PURE__.
+
+sed -e 's:__ATTR_ALWAYS_INLINE__:inline:g' \
+ -e 's:__ATTR_CONST__::g' \
+ -e 's:__ATTR_PURE__::g' \
+ -e 's:__ATTR_NORETURN__::g' \
+ -e 's:__ATTR_MALLOC__::g' \
+ -e 's:__extension__::g' \
+ -e 's:__inline__:inline:g' \
+ $1
diff --git a/doc/api/unjs.pl b/doc/api/unjs.pl
new file mode 100644
index 00000000..70666d5e
--- /dev/null
+++ b/doc/api/unjs.pl
@@ -0,0 +1,155 @@
+#!/usr/bin/perl
+# ----------------------------------------------------------------------------
+# "THE BEER-WARE LICENSE" (Revision 42):
+# <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you
+# can do whatever you want with this stuff. If we meet some day, and you think
+# this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
+# ----------------------------------------------------------------------------
+#
+# Parse the generated tree.js file, and insert a <noscript> tree into the
+# HTML source.
+#
+# $Id$
+#
+
+die "usage: unjs tree.js tree.html index.html" unless $#ARGV == 2;
+
+$treejs = $ARGV[0];
+$treehtml = $ARGV[1];
+$indexhtml = $ARGV[2];
+
+parsejs($treejs) || exit 1;
+
+open(HTML, $treehtml) || die "Cannot open $treehtml: $!\n";
+open(NEW, ">${treehtml}.new") ||
+ die "Cannot create ${treehtml}.new: $!\n";
+
+while (<HTML>) {
+ print NEW;
+ if (/^<\/script>$/) {
+ print NEW "<noscript>\n";
+ print NEW $nojs;
+ print NEW "</noscript>\n";
+ }
+}
+close(NEW);
+close(HTML);
+rename($treehtml, "${treehtml}.bak") &&
+ rename("${treehtml}.new", $treehtml);
+
+open(HTML, $indexhtml) || die "Cannot open $indexhtml: $!\n";
+open(NEW, ">${indexhtml}.new") ||
+ die "Cannot create ${indexhtml}.new: $!\n";
+
+while (<HTML>) {
+ print NEW;
+ if (/^<\/frameset>$/) {
+ print NEW "<noframes>\n";
+ print NEW $nojs;
+ print NEW "</noframes>\n";
+ }
+}
+close(NEW);
+close(HTML);
+rename($indexhtml, "${indexhtml}.bak") &&
+ rename("${indexhtml}.new", $indexhtml);
+exit(0);
+
+sub parsejs
+{
+ my ($f) = @_;
+ my ($i, $err);
+
+ open(JS, $f) || die "Cannot open $f: $!\n";
+
+ while ($l = <JS>) {
+ chomp $l;
+
+ $resvar = undef;
+ $insvar = undef;
+
+ $l =~ s/^\s+//;
+ if ($l =~ /^([A-Za-z][A-Za-z0-9]*)\s*=\s*/) {
+ # variable assignment
+ $resvar = $1;
+ $l = $';
+ }
+ $i = parsefun($l);
+ if ($i == 0) {
+ $errs++;
+ next;
+ }
+ }
+ close(JS);
+ return $errs == 0;
+}
+
+sub parsefun
+{
+ my ($line) = @_;
+ my $fun, $arg;
+
+ if ($line !~ /^([A-Za-z]+)[(](.*)[)]$/) {
+ warn "item ignored: $line\n";
+ return 0;
+ }
+ $fun = $1;
+ $arg = $2;
+ if ($fun ne "gFld" && $fun ne "gLnk" &&
+ $fun ne "insFld" && $fun ne "insDoc") {
+ warn "function $fun unknown\n";
+ return 0;
+ }
+ if ($fun =~ /^ins(.*)/) {
+ parseins($1, $arg) || return 0;
+ } elsif ($fun =~ /^g(.*)/) {
+ parseg($1, $arg) || return 0;
+ }
+
+ return 1;
+}
+
+sub parseg
+{
+ my ($name, $line) = @_;
+
+ if ($line !~ /^["](.*)["],\s*["](.*)["],\s*["](.*)["]/) {
+ warn "arglist expected: $line\n";
+ return 0;
+ }
+ $text = $1;
+ $tag = $2;
+ $lnk = $3;
+
+ if ($name eq "Fld") {
+ if ($lnk ne "") {
+ $nojs .= "<a href=\"$lnk\" target=\"basefrm\"><b>$text</b></a><br>\n";
+ } else {
+ $nojs .= "$text<br>\n";
+ }
+ } else {
+ # gLnk
+ if ($lnk ne "") {
+ $nojs .= "<a href=\"$lnk\" target=\"basefrm\">$text</a><br>\n";
+ } else {
+ # Huh, link without target?
+ $nojs .= "$text<br>\n";
+ }
+ }
+}
+
+sub parseins
+{
+ my ($name, $line) = @_;
+
+ if ($line !~ /^([A-Za-z][A-Za-z0-9]*),\s*/) {
+ warn "variable expected: $line\n";
+ return;
+ }
+ $insvar = $1;
+
+ parsefun($') || return 0;
+
+ return 1;
+}
+
diff --git a/doc/api/vect_to_desc.py b/doc/api/vect_to_desc.py
new file mode 100644
index 00000000..14696466
--- /dev/null
+++ b/doc/api/vect_to_desc.py
@@ -0,0 +1,129 @@
+# This mapping was extracted from an older version of
+# vectortable.dox and is used by ./isrs-to-dox.py to get
+# ISR descriptions when the script couldn't find one in avr/io*.h
+
+vect_to_desc = {
+ "ADC_vect" : "ADC Conversion Complete",
+ "ANALOG_COMP_0_vect" : "Analog Comparator 0",
+ "ANALOG_COMP_1_vect" : "Analog Comparator 1",
+ "ANALOG_COMP_2_vect" : "Analog Comparator 2",
+ "ANALOG_COMP_vect" : "Analog Comparator",
+ "ANA_COMP_vect" : "Analog Comparator",
+ "CANIT_vect" : "CAN Transfer Complete or Error",
+ "EEPROM_READY_vect" : "EEPROM Ready",
+ "EE_RDY_vect" : "EEPROM Ready",
+ "EE_READY_vect" : "EEPROM Ready",
+ "EXT_INT0_vect" : "External Interrupt Request 0",
+ "INT0_vect" : "External Interrupt 0",
+ "INT1_vect" : "External Interrupt Request 1",
+ "INT2_vect" : "External Interrupt Request 2",
+ "INT3_vect" : "External Interrupt Request 3",
+ "INT4_vect" : "External Interrupt Request 4",
+ "INT5_vect" : "External Interrupt Request 5",
+ "INT6_vect" : "External Interrupt Request 6",
+ "INT7_vect" : "External Interrupt Request 7",
+ "IO_PINS_vect" : "External Interrupt Request 0",
+ "LCD_vect" : "LCD Start of Frame",
+ "LOWLEVEL_IO_PINS_vect" : "Low-level Input on Port B",
+ "OVRIT_vect" : "CAN Timer Overrun",
+ "PCINT0_vect" : "Pin Change Interrupt Request 0",
+ "PCINT1_vect" : "Pin Change Interrupt Request 1",
+ "PCINT2_vect" : "Pin Change Interrupt Request 2",
+ "PCINT3_vect" : "Pin Change Interrupt Request 3",
+ "PCINT_vect" : "Pin Change Interrupt Request",
+ "PSC0_CAPT_vect" : "PSC0 Capture Event",
+ "PSC0_EC_vect" : "PSC0 End Cycle",
+ "PSC1_CAPT_vect" : "PSC1 Capture Event",
+ "PSC1_EC_vect" : "PSC1 End Cycle",
+ "PSC2_CAPT_vect" : "PSC2 Capture Event",
+ "PSC2_EC_vect" : "PSC2 End Cycle",
+ "SPI_STC_vect" : "Serial Transfer Complete",
+ "SPM_RDY_vect" : "Store Program Memory Ready",
+ "SPM_READY_vect" : "Store Program Memory Read",
+ "TIM0_COMPA_vect" : "Timer/Counter Compare Match A",
+ "TIM0_COMPB_vect" : "Timer/Counter Compare Match B",
+ "TIM0_OVF_vect" : "Timer/Counter0 Overflow",
+ "TIM1_CAPT_vect" : "Timer/Counter1 Capture Event",
+ "TIM1_COMPA_vect" : "Timer/Counter1 Compare Match A",
+ "TIM1_COMPB_vect" : "Timer/Counter1 Compare Match B",
+ "TIM1_OVF_vect" : "Timer/Counter1 Overflow",
+ "TIMER0_CAPT_vect" : "ADC Conversion Complete",
+ "TIMER0_COMPA_vect" : "TimerCounter0 Compare Match A",
+ "TIMER0_COMPB_vect" : "Timer Counter 0 Compare Match B",
+ "TIMER0_COMP_A_vect" : "Timer/Counter0 Compare Match A",
+ "TIMER0_COMP_vect" : "Timer/Counter0 Compare Match",
+ "TIMER0_OVF0_vect" : "Timer/Counter0 Overflow",
+ "TIMER0_OVF_vect" : "Timer/Counter0 Overflow",
+ "TIMER1_CAPT1_vect" : "Timer/Counter1 Capture Event",
+ "TIMER1_CAPT_vect" : "Timer/Counter Capture Event",
+ "TIMER1_CMPA_vect" : "Timer/Counter1 Compare Match 1A",
+ "TIMER1_CMPB_vect" : "Timer/Counter1 Compare Match 1B",
+ "TIMER1_COMP1_vect" : "Timer/Counter1 Compare Match",
+ "TIMER1_COMPA_vect" : "Timer/Counter1 Compare Match A",
+ "TIMER1_COMPB_vect" : "Timer/Counter1 Compare MatchB",
+ "TIMER1_COMPC_vect" : "Timer/Counter1 Compare Match C",
+ "TIMER1_COMPD_vect" : "Timer/Counter1 Compare Match D",
+ "TIMER1_COMP_vect" : "Timer/Counter1 Compare Match",
+ "TIMER1_OVF1_vect" : "Timer/Counter1 Overflow",
+ "TIMER1_OVF_vect" : "Timer/Counter1 Overflow",
+ "TIMER2_COMPA_vect" : "Timer/Counter2 Compare Match A",
+ "TIMER2_COMPB_vect" : "Timer/Counter2 Compare Match A",
+ "TIMER2_COMP_vect" : "Timer/Counter2 Compare Match",
+ "TIMER2_OVF_vect" : "Timer/Counter2 Overflow",
+ "TIMER3_CAPT_vect" : "Timer/Counter3 Capture Event",
+ "TIMER3_COMPA_vect" : "Timer/Counter3 Compare Match A",
+ "TIMER3_COMPB_vect" : "Timer/Counter3 Compare Match B",
+ "TIMER3_COMPC_vect" : "Timer/Counter3 Compare Match C",
+ "TIMER3_OVF_vect" : "Timer/Counter3 Overflow",
+ "TIMER4_CAPT_vect" : "Timer/Counter4 Capture Event",
+ "TIMER4_COMPA_vect" : "Timer/Counter4 Compare Match A",
+ "TIMER4_COMPB_vect" : "Timer/Counter4 Compare Match B",
+ "TIMER4_COMPC_vect" : "Timer/Counter4 Compare Match C",
+ "TIMER4_OVF_vect" : "Timer/Counter4 Overflow",
+ "TIMER5_CAPT_vect" : "Timer/Counter5 Capture Event",
+ "TIMER5_COMPA_vect" : "Timer/Counter5 Compare Match A",
+ "TIMER5_COMPB_vect" : "Timer/Counter5 Compare Match B",
+ "TIMER5_COMPC_vect" : "Timer/Counter5 Compare Match C",
+ "TIMER5_OVF_vect" : "Timer/Counter5 Overflow",
+ "TWI_vect" : "2-wire Serial Interface",
+ "TXDONE_vect" : "Transmission Done, Bit Timer Flag 2 Interrupt",
+ "TXEMPTY_vect" : "Transmit Buffer Empty, Bit Itmer Flag 0 Interrupt",
+ "UART0_RX_vect" : "UART0, Rx Complete",
+ "UART0_TX_vect" : "UART0, Tx Complete",
+ "UART0_UDRE_vect" : "UART0 Data Register Empty",
+ "UART1_RX_vect" : "UART1, Rx Complete",
+ "UART1_TX_vect" : "UART1, Tx Complete",
+ "UART1_UDRE_vect" : "UART1 Data Register Empty",
+ "UART_RX_vect" : "UART, Rx Complete",
+ "UART_TX_vect" : "UART, Tx Complete",
+ "UART_UDRE_vect" : "UART Data Register Empty",
+ "USART0_RXC_vect" : "USART0, Rx Complete",
+ "USART0_RX_vect" : "USART0, Rx Complete",
+ "USART0_TXC_vect" : "USART0, Tx Complete",
+ "USART0_TX_vect" : "USART0, Tx Complete",
+ "USART0_UDRE_vect" : "USART0 Data Register Empty",
+ "USART1_RXC_vect" : "USART1, Rx Complete",
+ "USART1_RX_vect" : "USART1, Rx Complete",
+ "USART1_TXC_vect" : "USART1, Tx Complete",
+ "USART1_TX_vect" : "USART1, Tx Complete",
+ "USART1_UDRE_vect" : "USART1, Data Register Empty",
+ "USART2_RX_vect" : "USART2, Rx Complete",
+ "USART2_TX_vect" : "USART2, Tx Complete",
+ "USART2_UDRE_vect" : "USART2 Data register Empty",
+ "USART3_RX_vect" : "USART3, Rx Complete",
+ "USART3_TX_vect" : "USART3, Tx Complete",
+ "USART3_UDRE_vect" : "USART3 Data register Empty",
+ "USART_RXC_vect" : "USART, Rx Complete",
+ "USART_RX_vect" : "USART, Rx Complete",
+ "USART_TXC_vect" : "USART, Tx Complete",
+ "USART_TX_vect" : "USART, Tx Complete",
+ "USART_UDRE_vect" : "USART Data Register Empty",
+ "USI_OVERFLOW_vect" : "USI Overflow",
+ "USI_OVF_vect" : "USI Overflow",
+ "USI_START_vect" : "USI Start Condition",
+ "USI_STRT_vect" : "USI Start",
+ "USI_STR_vect" : "USI START",
+ "WATCHDOG_vect" : "Watchdog Time-out",
+ "WDT_OVERFLOW_vect" : "Watchdog Timer Overflow",
+ "WDT_vect" : "Watchdog Timeout Interrupt",
+}
diff --git a/xml/Atmel2libc.py b/xml/Atmel2libc.py
new file mode 100755
index 00000000..d7922c88
--- /dev/null
+++ b/xml/Atmel2libc.py
@@ -0,0 +1,547 @@
+#! /usr/bin/env python
+#
+# Copyright (c) 2004,2005 Theodore A. Roth
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the copyright holders nor the names of
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# $Id$
+#
+
+import string
+import re
+from xml.parsers import expat
+
+class Element:
+ 'A parsed XML element'
+
+ def __init__(self,name,attributes,depth=0):
+ 'Element constructor'
+ # The element's tag name
+ self.name = name
+ # The element's attribute dictionary
+ self.attributes = attributes
+ # The element's cdata
+ self.cdata = ''
+ # The element's child element list (sequence)
+ self.children = []
+
+ self.depth = depth
+
+ def AddChild(self, element, depth=0):
+ 'Add a reference to a child element'
+ element.depth = depth
+ self.children.append(element)
+
+ def getAttribute(self,key):
+ 'Get an attribute value'
+ return self.attributes.get(key)
+
+ def getData(self):
+ 'Get the cdata'
+ return self.cdata
+
+ def getElements(self,name=''):
+ 'Get a list of child elements'
+ #If no tag name is specified, return the all children
+ if not name:
+ return self.children
+ else:
+ # else return only those children with a matching tag name
+ elements = []
+ for element in self.children:
+ if element.name == name:
+ elements.append(element)
+ return elements
+
+ def getSubTree (self, path):
+ '''Path is a list of element names.
+ The last element of the path is returned or None if the element is
+ not found. The first name in path, should match self.name.
+
+ This does not work if there are many children with the same name.
+ '''
+ if self.name != path[0]:
+ return None
+
+ if len (path) == 1:
+ # We're are the last element in the path.
+ return self
+
+ for child in self.children:
+ if child.name == path[1]:
+ return child.getSubTree (path[1:])
+
+ return None
+
+ def __repr__(self):
+ indent = ' ' * self.depth
+ s ='%s[ %s, %s, "%s", {' % (indent, self.name, self.attributes,
+ self.cdata)
+ cs = ''
+ for c in self.children:
+ cs += '\n%s' % (c)
+
+ if len (cs):
+ s += '%s\n%s}]' % (cs,indent)
+ else:
+ s += '}]'
+
+ return s
+
+class Xml2Obj:
+ 'XML to Object'
+
+ encoding = 'utf-8'
+
+ def __init__(self):
+ self.root = None
+ self.nodeStack = []
+
+ def StartElement(self,name,attributes):
+ 'SAX start element even handler'
+ # Instantiate an Element object
+ element = Element(name.encode(Xml2Obj.encoding),attributes)
+
+ # Push element onto the stack and make it a child of parent
+ if len(self.nodeStack) > 0:
+ parent = self.nodeStack[-1]
+ parent.AddChild(element, parent.depth+1)
+ else:
+ self.root = element
+ self.nodeStack.append(element)
+
+ def EndElement(self,name):
+ 'SAX end element event handler'
+ self.nodeStack = self.nodeStack[:-1]
+
+ def CharacterData(self,data):
+ 'SAX character data event handler'
+ if string.strip(data):
+ data = data.replace('&', '&amp;')
+ data = data.encode(Xml2Obj.encoding)
+ element = self.nodeStack[-1]
+ element.cdata += data
+ return
+
+ def Parse(self,filename):
+ # Create a SAX parser
+ Parser = expat.ParserCreate()
+
+ # SAX event handlers
+ Parser.StartElementHandler = self.StartElement
+ Parser.EndElementHandler = self.EndElement
+ Parser.CharacterDataHandler = self.CharacterData
+
+ # Parse the XML File
+ ParserStatus = Parser.Parse(open(filename,'r').read(), 1)
+
+ return self.root
+
+def convert_vect_addr (addr):
+ """Atmel defines vector addresses as 16-bits wide words in the atmel files
+ while avr-libc defines them as byte addresses.
+
+ The incoming addr is a string that looks like this: '$0034'
+
+ We will convert that into a number and store it internally as such.
+ """
+ if addr[0] != '$':
+ raise NotHexNumberErr, addr
+
+ return int (addr[1:], 16) * 2
+
+def print_wrapped (indent, line):
+ ilen = len (indent)
+ llen = len (line)
+ print indent[:-1],
+ if ilen + llen > 78:
+ i = 78 - ilen
+ while i:
+ if line[i] == ' ':
+ print line[:i]
+ print_wrapped (indent+' ', line[i+1:])
+ break
+ i -= 1
+ else:
+ # Couldn't find a place to wrap before col 78, try to find one
+ # after.
+ i = 79 - ilen
+ while i < llen:
+ if line[i] == ' ':
+ print line[:i]
+ print_wrapped (indent+' ', line[i+1:])
+ break
+ i += 1
+ else:
+ # Give up and just print the line.
+ print line
+ else:
+ print line
+
+def dump_header (root, depth=0):
+ name = root.getSubTree (['AVRPART', 'ADMIN', 'PART_NAME']).getData()
+ print '<?xml version="1.0"?>'
+ print '<!DOCTYPE device SYSTEM "Device.dtd">'
+ print '<device name="%s">' % (name)
+
+ # Avoid CVS changing ID in python script.
+ print ' <version>%s</version>' % ('$'+'Id$')
+ print ' <description></description>'
+
+def dump_footer (root):
+ print '</device>'
+
+def dump_memory_sizes (root):
+ path = ['AVRPART', 'MEMORY']
+ mem = root.getSubTree (path)
+
+ flash_size = int (mem.getElements ('PROG_FLASH')[0].getData ())
+ eep_size = int (mem.getElements ('EEPROM')[0].getData ())
+
+ isram = mem.getSubTree (['MEMORY', 'INT_SRAM'])
+ isram_size = int (isram.getElements ('SIZE')[0].getData ())
+ isram_start = isram.getElements ('START_ADDR')[0].getData ()[1:]
+
+ xsram = mem.getSubTree (['MEMORY', 'EXT_SRAM'])
+ try:
+ xsram_size = int (xsram.getElements ('SIZE')[0].getData ())
+ except ValueError:
+ # Some XSRAM entries come with just "NA" as the value
+ xsram_size = 0
+ xsram_start = xsram.getElements ('START_ADDR')[0].getData ()[1:]
+
+ print ' <memory_sizes>'
+ print ' <flash_size>0x%x</flash_size>' % (flash_size)
+ print ' <eeprom_size>0x%x</eeprom_size>' % (eep_size)
+ print ' <int_sram_size start_addr="0x%s">0x%x</int_sram_size>' % (
+ isram_start, isram_size)
+ print ' <ext_sram_size start_addr="0x%s">0x%x</ext_sram_size>' % (
+ xsram_start, xsram_size)
+ print ' </memory_sizes>'
+
+def dump_vectors (root, tradnames):
+ """Get the interupt vectors.
+ """
+
+ path = [ 'AVRPART', 'INTERRUPT_VECTOR' ]
+
+ irqs = root.getSubTree (path)
+
+ nvects = int (irqs.getElements ('NMB_VECTORS')[0].getData ())
+
+ vectors = []
+ for i in range (1, nvects+1):
+ try:
+ vect = irqs.getElements ('VECTOR%d' % (i))[0]
+ except IndexError:
+ # some devices have holes in the vector table =:-)
+ vectors.append(())
+ continue
+
+ name = vect.getElements ('SOURCE')[0].getData ()
+ saddr = vect.getElements ('PROGRAM_ADDRESS')[0].getData ()
+ desc = vect.getElements ('DEFINITION')[0].getData ()
+
+ addr = convert_vect_addr (saddr)
+
+ vectors.append ((addr, name, desc))
+
+ # Determine the size of the vector insn from the address of the 2nd vector.
+ insn_size = vectors[1][0]
+
+ print ' <interrupts insn_size="%d" num_vects="%d">' % (insn_size,
+ nvects)
+ n = 0
+ for v in vectors:
+ # we are not really interested in the reset vector
+ if n == 0:
+ n += 1
+ continue
+ try:
+ name = re.sub('[/-]', '', v[1].upper())
+ name = re.sub(',', ' ', name)
+ # The ATmega16HVA file has a silly SPI;STC vector name
+ name = re.sub(';', '_', name)
+ name = re.sub(r'\s+', '_', name)
+ if re.match('^[A-Z0-9_]+$', name):
+ pass
+ else:
+ raise 'Invalid characters in vector name even after substitution', name
+
+ print ' <vector addr="0x%04x" num="%d" name="%s">' % (v[0], n, v[1])
+ print_wrapped (' ', '<description>%s</description>' % (v[2]))
+ print ' <sig_name>%s_vect</sig_name>' % name
+ for altname in tradnames.Vecname(n):
+ print ' <alt_name>%s</alt_name>' % altname
+ print ' </vector>'
+ except IndexError:
+ # this catches holes in the vector table
+ pass
+ n += 1
+ print ' </interrupts>'
+
+def gather_io_info (root):
+ """
+ The bit information may be spread across multiple IO_MODULES.
+
+ Man that sucks. :-(
+
+ Oh, and it gets worse. They have duplicate bit elements, but the
+ duplicates are not quite complete (see SFIOR in the mega128 file). Now,
+ why couldn't they just list all the register info in a single linear
+ table, then in the modules, just list the registers used by the module and
+ look up the register info in the linear table?
+
+ So what we will do is walk all modules the extract register info and put
+ that info into a dictionary so we can look it up later.
+ """
+ io_reg_info = {}
+
+ path = ['AVRPART', 'IO_MODULE']
+ io_module = root.getSubTree (path)
+
+ # Get the list of all modules.
+ mod_list = io_module.getElements ('MODULE_LIST')[0].getData ()
+ mod_list = mod_list[1:-1].split (':')
+
+ for mod in mod_list:
+ # Get the list of registers for the module.
+ path = ['IO_MODULE', mod, 'LIST']
+ reg_list = io_module.getSubTree (path).getData ()
+ reg_list = reg_list[1:-1].split (':')
+ for reg in reg_list:
+ path[2] = reg
+ element = io_module.getSubTree (path)
+ if io_reg_info.has_key (reg):
+ # NOTE: The ATtiny2313.xml has a bug (There's 2 'ICR1H'
+ # entries in the reg list) that causes the following for loop
+ # to go infinite. Argh! Removing the extra entry seems to get
+ # things working again.
+ for child in element.getElements ():
+ io_reg_info[reg].AddChild (child, element.depth+1)
+ else:
+ io_reg_info[reg] = element
+
+ return io_reg_info
+
+def dump_ioregs (root):
+ path = ['AVRPART', 'MEMORY', 'IO_MEMORY']
+ io_mem = root.getSubTree (path)
+ ioregs = io_mem.getElements ()
+
+ ioreg_info_dict = gather_io_info (root)
+
+ print ' <ioregisters>'
+
+ # Skip the first 6 elements since they are just give start and stop
+ # addresses.
+
+ for ioreg in ioregs[6:]:
+ name = ioreg.name
+ try:
+ reg_info = ioreg_info_dict[name]
+ try:
+ reg_desc = reg_info.getElements ('DESCRIPTION')[0].getData ()
+ except IndexError:
+ reg_desc = ''
+ except KeyError:
+ reg_info = None
+ reg_desc = ''
+
+ addr = ioreg.getElements ('IO_ADDR')[0].getData ()
+ try:
+ if addr[0] == '$':
+ addr = '0x' + addr[1:]
+ if addr == "NA":
+ addr = ioreg.getElements ('MEM_ADDR')[0].getData ()
+ else:
+ # Add 0x20 so all addresses are memory mapped.
+ addr = '0x%02x' % (int (addr, 16) + 0x20)
+
+ print ' <ioreg name="%s" addr="%s">' % (name, addr)
+ print_wrapped (' ','<description>%s</description>' % (reg_desc))
+ print ' <alt_name></alt_name>'
+ for i in range (8):
+ if reg_info is None:
+ continue
+ bit = 'BIT%d' % (i)
+ bit_el = reg_info.getSubTree ([name, bit])
+ if bit_el is None:
+ continue
+ bit_name = bit_el.getElements ('NAME')[0].getData ()
+ try:
+ bit_desc = bit_el.getElements ('DESCRIPTION')[0].getData ()
+ except IndexError:
+ bit_desc = ''
+ try:
+ bit_access = bit_el.getElements ('ACCESS')[0].getData ()
+ except IndexError:
+ bit_access = 'FIXME!'
+ bit_init_val = bit_el.getElements ('INIT_VAL')[0].getData ()
+ print ' <bit_field name="%s"' % (bit_name),
+ print 'bit="%d"' % (i),
+ print 'access="%s"' % (bit_access),
+ print 'init="%s">' % (bit_init_val)
+ if bit_desc:
+ print_wrapped (' ',
+ '<description>%s</description>' % (bit_desc))
+ print ' <alt_name></alt_name>'
+ print ' </bit_field>'
+ print ' </ioreg>'
+ except IndexError: # empty register declaration
+ pass
+
+ print ' </ioregisters>'
+
+def dump_boot_info (root):
+ path = ['AVRPART', 'MEMORY', 'BOOT_CONFIG']
+
+ info = root.getSubTree (path)
+ if info:
+ # The device has bootloader support.
+ try:
+ data = info.getElements ('NRWW_START_ADDR')[0].getData ()
+ if data[0] == '$':
+ data = '0x' + data[1:]
+ if data == 'x':
+ nrww_start = ''
+ else:
+ nrww_start = ' nrww_start="0x%x"' % (int (data, 16))
+ except IndexError:
+ nrww_start = ''
+
+ try:
+ data = info.getElements ('NRWW_STOP_ADDR')[0].getData ()
+ if data[0] == '$':
+ data = '0x' + data[1:]
+ if data == 'x':
+ nrww_end = ''
+ else:
+ nrww_end = ' nrww_end="0x%x"' % (int (data, 16))
+ except IndexError:
+ nrww_end = ''
+
+ try:
+ data = info.getElements ('RWW_START_ADDR')[0].getData ()
+ if data[0] == '$':
+ data = '0x' + data[1:]
+ try:
+ rww_start = ' rww_start="0x%x"' % (int (data, 16))
+ except ValueError:
+ rww_start = ''
+ except IndexError:
+ rww_start = ''
+
+ try:
+ data = info.getElements ('RWW_STOP_ADDR')[0].getData ()
+ if data[0] == '$':
+ data = '0x' + data[1:]
+ try:
+ rww_end = ' rww_end="0x%x"' % (int (data, 16))
+ except ValueError:
+ rww_end = ''
+ except IndexError:
+ rww_end = ''
+
+ # The Atmel files give the pagesize in words, we need it in bytes.
+
+ pagesize = 'pagesize="%d"' % ( \
+ 2 * int (info.getElements ('PAGESIZE')[0].getData ()))
+
+ rww = '%s%s' % (rww_start, rww_end)
+ nrww = '%s%s' % (nrww_start, nrww_end)
+ print ' <bootloader %s%s%s>' % (pagesize, rww, nrww)
+
+ for i in range (8):
+ try:
+ mode = info.getElements ('BOOTSZMODE%d' % (i))[0]
+ except IndexError:
+ continue
+
+ data = mode.getElements ('PAGES')[0].getData ()
+ if data == 'x':
+ data = 'FIXME!'
+ pages = 'pages="%s"' % (data)
+
+ data = mode.getElements ('BOOTSTART')[0].getData ()
+ if data[0] == '$':
+ data = '0x' + data[1:]
+ if data == 'x':
+ start = 'start="FIXME: Broken xml from Atmel!"'
+ else:
+ start = 'start="0x%x"' % (int (data,16))
+
+ print ' <mode num="%d" %s %s />' % (i, pages, start)
+
+ print ' </bootloader>'
+
+class HeaderToVec:
+ 'Parse header file for traditional vector names'
+
+ def __init__(self):
+ self.vects = {}
+
+ def Read(self, fname):
+ 'Read header file'
+ f = open(fname)
+ r = re.compile(r'#\s*define\s+(SIG_[A-Z0-9_]+)\s+_VECTOR[(](\d+)[)]')
+ for line in f:
+ m = r.match(line)
+ if m != None:
+ intno = int(m.group(2))
+ try:
+ x = self.vects[intno]
+ except KeyError:
+ x = []
+ x.append(m.group(1))
+ self.vects[intno] = x
+ f.close()
+
+ def Vecname(self, idx):
+ try:
+ return self.vects[idx]
+ except KeyError:
+ return ''
+
+
+if __name__ == '__main__':
+ import sys
+
+ parser = Xml2Obj()
+ root = parser.Parse(sys.argv[1])
+
+ tradheader = HeaderToVec()
+ tradheader.Read(sys.argv[2])
+
+ dump_header (root)
+ dump_memory_sizes (root)
+ dump_vectors (root, tradheader)
+ dump_ioregs (root)
+ dump_boot_info (root)
+ dump_footer (root)
diff --git a/xml/Descparser.py b/xml/Descparser.py
new file mode 100755
index 00000000..86322cc1
--- /dev/null
+++ b/xml/Descparser.py
@@ -0,0 +1,255 @@
+#! /usr/bin/env python
+#
+# Copyright (c) 2004 Theodore A. Roth
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the copyright holders nor the names of
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# $Id$
+#
+
+import os, sys, types
+
+from xml.sax import make_parser
+from xml.sax.handler import ContentHandler
+
+class XML_Mixin:
+ children = {}
+ def __init__ (self, attrs):
+ self.xml_members = []
+ for name in attrs.getNames ():
+ if attrs.getType (name) == 'CDATA':
+ self.xml_members.append (name)
+ setattr (self, name, attrs.getValue (name))
+ self.data = ''
+
+ def create_child (self, name, attrs):
+ return self.children[name] (attrs)
+
+ def add_child (self, name, obj):
+ self.xml_members.append (name)
+ setattr (self, name, obj)
+
+ def characters (self, ch):
+ self.data += ch
+
+ def __str__ (self):
+ s = '[ data = "%s"; ' % (self.data)
+ for member in self.xml_members:
+ s += '%s = %s; ' % (member, str (getattr (self, member)))
+ s += ']\n'
+ return s
+
+class PCData (XML_Mixin):
+ def __repr__ (self):
+ return '"%s"' % (self.data)
+
+class MemorySizes (XML_Mixin):
+ children = {
+ 'flash_size': PCData,
+ 'eeprom_size': PCData,
+ 'int_sram_size': PCData,
+ 'ext_sram_size': PCData
+ }
+
+class Vector (XML_Mixin):
+ children = {
+ 'description': PCData,
+ 'sig_name': PCData,
+ 'alt_name': PCData
+ }
+ def add_child (self, name, obj):
+ if name == "alt_name":
+ try:
+ x = getattr (self, name)
+ x.data.append(obj.data)
+ setattr (self, name, x)
+ except AttributeError:
+ x = obj.data
+ obj.data = [x]
+ self.xml_members.append (name)
+ setattr (self, name, obj)
+ else:
+ self.xml_members.append (name)
+ setattr (self, name, obj)
+
+
+class Interrupts (dict, XML_Mixin):
+ children = {
+ 'vector': Vector
+ }
+
+ def __init__ (self, attrs):
+ dict.__init__ (self)
+ XML_Mixin.__init__ (self, attrs)
+
+ def add_child (self, name, obj):
+ # Use the Vector 'num' attr as the key for the child object.
+ if self.has_key (obj.num):
+ raise 'Duplicate vector entry', obj
+ self[obj.num] = obj
+
+class BitField (XML_Mixin):
+ children = {
+ 'description': PCData,
+ 'alt_name': PCData
+ }
+
+class IORegister (XML_Mixin):
+ children = {
+ 'description': PCData,
+ 'alt_name': PCData,
+ 'bit_field': BitField,
+ }
+
+ def add_child (self, name, obj):
+ if name == 'bit_field':
+ if not hasattr (self, name):
+ setattr (self, name, {})
+ # Use the BitField 'bit' attr as the key for the child object.
+ self.bit_field[obj.bit] = obj
+ else:
+ XML_Mixin.add_child (self, name, obj)
+
+class IORegisterDict (dict, XML_Mixin):
+ children = {
+ 'ioreg': IORegister
+ }
+
+ def __init__ (self, attrs):
+ dict.__init__ (self)
+ XML_Mixin.__init__ (self, attrs)
+
+ def add_child (self, name, obj):
+ # Use the IORegister 'name' attr as the key for the child object.
+ if self.has_key (obj.name):
+ raise 'Duplicate io register entry', obj
+ self[obj.name] = obj
+
+class BootMode (XML_Mixin):
+ pass
+
+class BootLoader (dict, XML_Mixin):
+ children = {
+ 'mode': BootMode
+ }
+
+ def __init__ (self, attrs):
+ dict.__init__ (self)
+ XML_Mixin.__init__ (self, attrs)
+
+ def add_child (self, name, obj):
+ # Use the BootMode 'num' attr as the key for the child object.
+ if self.has_key (obj.num):
+ raise 'Duplicate boot mode entry', obj
+
+ self[obj.num] = obj
+
+class Device (XML_Mixin):
+ children = {
+ 'version': PCData,
+ 'description': PCData,
+ 'memory_sizes': MemorySizes,
+ 'interrupts': Interrupts,
+ 'ioregisters': IORegisterDict,
+ 'bootloader': BootLoader
+ }
+
+class DescHandler (ContentHandler):
+ """Content Handler for the device description xml files.
+ """
+
+ def __init__ (self):
+ self.depth = 0
+ self.stack = []
+
+ def push (self, name, obj):
+ self.stack.append ([name, obj])
+
+ def pop (self):
+ return self.stack.pop ()
+
+ def get_curr_obj (self):
+ return self.stack[-1][1]
+
+ def startElement (self, name, attrs):
+ if self.depth == 0:
+ obj = Device (attrs)
+ self.dev = obj
+ else:
+ # Look up the elements class in the parent's children dict.
+ parent = self.get_curr_obj ()
+ obj = parent.create_child (name, attrs)
+
+ self.push (name, obj)
+ self.depth += 1
+
+ def endElement (self, name):
+ self.depth -= 1
+
+ # Pull the current element off the stack and add it to the parent.
+ (cname, cobj) = self.pop ()
+
+ cobj.data = ' '.join (cobj.data.split ())
+
+ try:
+ parent = self.get_curr_obj ()
+ parent.add_child (cname, cobj)
+ except IndexError:
+ # We're back at the root element, so we're done.
+ pass
+
+ #print '%s%s %s' % (' '*self.depth, cname, cobj)
+
+ def characters (self, ch):
+ self.get_curr_obj().characters (ch)
+
+ def endDocument (self):
+ #print self.dev
+ pass
+
+if __name__ == '__main__':
+ parser = make_parser ()
+
+ handler = DescHandler ()
+ parser.setContentHandler (handler)
+
+ if len(sys.argv) > 1:
+ parser.parse (open (sys.argv[1]))
+ else:
+ parser.parse (open ('desc-90s1200.xml'))
+
+ l = parser.getContentHandler().dev.interrupts.keys()
+ l.sort(lambda x, y: cmp(int(x), int(y)))
+ for key in l:
+ ele = parser.getContentHandler().dev.interrupts[key]
+ print "/* " + ele.description.data + " */"
+ print "#define " + ele.sig_name.data + "\t_VECTOR(" + key + ")"
+ for x in ele.alt_name.data:
+ print "#define " + x + "\t_VECTOR(" + key + ")"
+ print ""
diff --git a/xml/Device.dtd b/xml/Device.dtd
new file mode 100644
index 00000000..e8535111
--- /dev/null
+++ b/xml/Device.dtd
@@ -0,0 +1,148 @@
+<!--
+Copyright (c) 2004, Theodore A. Roth
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<!-- $Id$ -->
+
+<!--
+
+This file provides a Document Type Definition (DTD) for XML data files which
+describe everything thing we need to generate the <avr/io*.h> header files.
+
+Although ATMEL supplies XML device files already with AvrStudio >= 4.x, they
+contain far more data than we need. In addition, there is information that we
+need which they do not provide. Also, it may not be legal for us to include
+those files with avr-libc.
+
+I have written a python program (Atmel2libc.py) which will read ATMEL's XML
+files and spit out a file which will validate against this DTD so that we can
+leverage the data in those files. We will still have to manually add some data
+to our generated xml files before we can use them to generate our headers.
+
+-->
+
+<!ELEMENT device (
+ version,
+ description?,
+ memory_sizes,
+ interrupts,
+ ioregisters,
+ bootloader?
+)>
+ <!ATTLIST device
+ name CDATA #REQUIRED
+ >
+
+ <!ELEMENT version (#PCDATA)>
+ <!ELEMENT description (#PCDATA)>
+
+ <!ELEMENT memory_sizes (
+ flash_size,
+ eeprom_size,
+ int_sram_size,
+ ext_sram_size
+ )>
+ <!ELEMENT flash_size (#PCDATA)>
+ <!ELEMENT eeprom_size (#PCDATA)>
+ <!ELEMENT int_sram_size (#PCDATA)>
+ <!ATTLIST int_sram_size start_addr CDATA #REQUIRED>
+ <!ELEMENT ext_sram_size (#PCDATA)>
+ <!ATTLIST ext_sram_size start_addr CDATA #REQUIRED>
+
+ <!ELEMENT interrupts (vector+)>
+ <!-- insn_size in bytes -->
+ <!ATTLIST interrupts
+ insn_size (2 | 4) #REQUIRED
+ num_vects CDATA #REQUIRED
+ >
+ <!ELEMENT vector (
+ description?,
+ sig_name,
+ alt_name*
+ )>
+ <!ATTLIST vector
+ addr CDATA #REQUIRED
+ num CDATA #REQUIRED
+ name CDATA #REQUIRED
+ >
+ <!ELEMENT sig_name (#PCDATA)>
+
+ <!ELEMENT ioregisters (ioreg+)>
+ <!ELEMENT ioreg (
+ description?,
+ alt_name*,
+ bit_field*
+ )>
+ <!ATTLIST ioreg
+ name CDATA #REQUIRED
+ addr CDATA #REQUIRED
+ >
+
+ <!ELEMENT alt_name (#PCDATA)>
+
+ <!ELEMENT bit_field (
+ description?,
+ alt_name*
+ )>
+ <!ATTLIST bit_field
+ name CDATA #REQUIRED
+ bit CDATA #REQUIRED
+ access CDATA #REQUIRED
+ init CDATA #REQUIRED
+ >
+
+ <!-- If the is no bootloader element in the XML file, the device does not
+ have bootloader support. -->
+
+ <!-- The pagesize value is in bytes. Atmel's datasheets give it in
+ words. -->
+
+ <!-- Some recent ATtiny devices have boot loader support, but only
+ have non-read while write (NRWW) behaviour throughout the
+ entire flash, and no separate bootloader area. So do not
+ insist on getting mode elements. -->
+ <!ELEMENT bootloader (mode*)>
+ <!ATTLIST bootloader
+ pagesize CDATA #REQUIRED
+ rww_start CDATA #IMPLIED
+ rww_end CDATA #IMPLIED
+ nrww_start CDATA #IMPLIED
+ nrww_end CDATA #IMPLIED
+ >
+
+ <!-- The boot mode size is (pagesize * pages). -->
+
+ <!ELEMENT mode EMPTY>
+ <!ATTLIST mode
+ num CDATA #REQUIRED
+ pages CDATA #REQUIRED
+ start CDATA #REQUIRED
+ >
diff --git a/xml/Validate.py b/xml/Validate.py
new file mode 100755
index 00000000..b7ec36d2
--- /dev/null
+++ b/xml/Validate.py
@@ -0,0 +1,56 @@
+#! /usr/bin/env python
+#
+# Copyright (c) 2004 Theodore A. Roth
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the copyright holders nor the names of
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# $Id$
+#
+
+#
+# Simple script for validating xml files.
+#
+# Usage: ./Validate.py foo.xml bar.xml ...
+#
+
+import os
+import sys
+import glob
+
+from xml.parsers.xmlproc import xmlval
+from xml.parsers.xmlproc.utils import ErrorPrinter
+
+for arg in sys.argv[1:]:
+ for filename in glob.glob (arg):
+ print 'Validating %s' % (arg)
+
+ parser = xmlval.XMLValidator()
+ parser.set_error_handler(ErrorPrinter(parser, out=sys.stdout))
+
+ parser.parse_resource (arg)
diff --git a/xml/avrgcc-header b/xml/avrgcc-header
new file mode 100755
index 00000000..ed404087
--- /dev/null
+++ b/xml/avrgcc-header
@@ -0,0 +1,1354 @@
+#! /bin/sh
+# Copyright (c) 2008 Atmel Corporation
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the copyright holders nor the names of
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+# $Id$
+
+# Convert Atmel XML Device file to AVR GCC I/O header file.
+# Needs: xmlstarlet (executable: xml), sed, grep, uniq, mv, rm, echo, sort.
+
+usage() {
+cat << EOF
+usage: $0 -d <xml device file> -h <io header file> [-x]
+ -d <xml device file> XML Device File (Input)
+ -h <io header file> I/O Header File (Output).
+ If file exists, it will be overwritten.
+ -x Optional XMEGA header file output
+EOF
+}
+
+
+abort() {
+ echo $@
+ exec /bin/false
+}
+
+
+# Get options
+devicefile=
+headerfile=
+xmega=
+while test $# -gt 0
+do
+ case "$1" in
+ -d) devicefile="$2"; shift;;
+ -h) headerfile="$2"; shift;;
+ -x) xmega="1";;
+ --) shift; break;;
+ -*) usage; exit 1;;
+ *) break;; # terminate while loop
+ esac
+ shift
+done
+# all command line switches are processed,
+
+
+# Test parameters.
+if test "$devicefile" = ""; then
+ usage
+ abort "Error: No device file specified."
+fi
+if test "$headerfile" = ""; then
+ usage
+ abort "Error: No header file specified."
+fi
+
+
+set -x
+
+
+if test -e "$headerfile"; then rm "$headerfile"; fi
+
+
+# Header
+#-------------------
+
+# Get device name.
+DEVICE=$(xml sel -T -t -v /AVRPART/ADMIN/PART_NAME $devicefile)
+
+# todo: upper-case function not found. Use this value in idempotent guard.
+#DEVICEUPPER=$(xml sel -T -t -v "upper-case(/AVRPART/ADMIN/PART_NAME)" $devicefile)
+
+# Get the current year to place in copyright statement.
+YEAR=$(date --rfc-3339=date | cut -d '-' -f 1)
+
+cat << eof > $headerfile
+/* Copyright (c) $YEAR Atmel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* \$Id\$ */
+
+/* avr/$headerfile - definitions for ${DEVICE} */
+
+/* This file should only be included from <avr/io.h>, never directly. */
+
+#ifndef _AVR_IO_H_
+# error "Include <avr/io.h> instead of this file."
+#endif
+
+#ifndef _AVR_IOXXX_H_
+# define _AVR_IOXXX_H_ "$headerfile"
+#else
+# error "Attempt to include more than one <avr/ioXXX.h> file."
+#endif
+
+
+#ifndef _AVR_${DEVICE}_H_
+#define _AVR_${DEVICE}_H_ 1
+
+
+eof
+
+
+
+if test -n "$xmega" ; then
+
+# XMEGA AVR
+#==================
+
+
+# Build IO groups temporary XML file
+#------------------------------------
+if test -e $headerfile-iogroups.xml; then
+ rm -f $headerfile-iogroups.xml
+fi
+
+# Get set of register group names.
+GROUP_NAMES=$(xml sel -T -t -m /AVRPART/V2/modules/module/registers -s "A:T:-" "@offset" -v "concat(@name,' ')" $devicefile)
+
+# Create base iogroups temporary xml file.
+echo "<AVRPART>" | sed "s,>,>\r,g" >> $headerfile-iogroups.xml
+for i in $GROUP_NAMES ; do \
+ xml sel -t -m '/AVRPART/V2/modules/module/registers[@name='\'${i}\'']' -c . $devicefile | sed s,registers,group,g | sed "s,/>,>,g" >> $headerfile-iogroups.xml
+ TYPE=$(xml sel -T -t -m '/AVRPART/V2/modules/module/registers[@name='\'${i}\'']' -v "@implements" $devicefile)
+ xml sel -t -m '/AVRPART/V2/templates/module/registers[@name='\'${TYPE}\'']' -c . $devicefile >> $headerfile-iogroups.xml
+ echo "</group>" | sed "s,>,>\r,g" >> $headerfile-iogroups.xml
+done
+echo "</AVRPART>" | sed "s,>,>\r,g" >> $headerfile-iogroups.xml
+
+# Make all groups have consistent width of offset address.
+for i in $GROUP_NAMES ; do \
+ value=$(printf "0x%04X" $(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']' -v "@offset" $headerfile-iogroups.xml))
+ xml ed -O -u '/AVRPART/group[@name='\'${i}\'']/@offset' -v "$value" $headerfile-iogroups.xml > $headerfile-temp.xml
+ mv -f $headerfile-temp.xml $headerfile-iogroups.xml
+done
+
+# Re-sort iogroups temporary XML file.
+xml sel -t -e AVRPART -m "/AVRPART/group" -s "A:T:-" "@offset" -c . $headerfile-iogroups.xml > $headerfile-temp.xml
+mv -f $headerfile-temp.xml $headerfile-iogroups.xml
+
+# Re-get set of register group names.
+GROUP_NAMES=$(xml sel -T -t -m /AVRPART/group -s "A:T:-" "@offset" -v "concat(@name,' ')" $headerfile-iogroups.xml)
+
+# Add absolute address to registers.
+for i in $GROUP_NAMES ; do \
+ GROUP_OFFSET=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']' -v "@offset" $headerfile-iogroups.xml)
+ REG_NAMES=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers/child::*' -v "concat(@name,' ')" $headerfile-iogroups.xml)
+ for j in $REG_NAMES ; do \
+ value=$(printf "0x%04X" $(($GROUP_OFFSET + $(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers/child::*[@name='\'${j}\'']' -v "@offset" $headerfile-iogroups.xml))))
+ xml ed -O -a '/AVRPART/group[@name='\'${i}\'']/registers/child::*[@name='\'${j}\'']' -t attr -n "address" -v "$value" $headerfile-iogroups.xml > $headerfile-temp.xml
+ mv -f $headerfile-temp.xml $headerfile-iogroups.xml
+ done
+done
+
+
+
+# XMEGA Global Registers
+#---------------------------
+echo "/* Ungrouped common registers */" >> $headerfile
+for i in $GROUP_NAMES ; do
+ REGISTERS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@globalregs='\'true\'']' -v "concat(@name,' ')" $headerfile-iogroups.xml)
+ for j in $REGISTERS ; do
+ REG_OFFSETS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@globalregs='\'true\''][@name='\'${j}\'']/child::*' -v "concat(@offset,' ')" $headerfile-iogroups.xml | sort)
+ for k in $REG_OFFSETS ; do
+ REG_NAME=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@globalregs='\'true\''][@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@name" $headerfile-iogroups.xml)
+ if test -n "$REG_NAME" ; then
+ REG_SIZE=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@size" $headerfile-iogroups.xml)
+ REG_ADDRESS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@address" $headerfile-iogroups.xml)
+ REG_TEXT=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@text" $headerfile-iogroups.xml)
+ if test -n "$REG_SIZE" ; then
+ if test "$REG_SIZE" = "1" ; then
+ echo "#define ${REG_NAME} _SFR_MEM8(${REG_ADDRESS}) /* ${REG_TEXT} */" >> $headerfile
+ fi
+ if test "$REG_SIZE" = "2" ; then
+ echo "#define ${REG_NAME} _SFR_MEM16(${REG_ADDRESS}) /* ${REG_TEXT} */" >> $headerfile
+ fi
+ fi
+ fi
+ done
+ echo "" >> $headerfile
+ done
+done
+echo "" >> $headerfile
+
+
+
+# XMEGA types
+#-----------------
+cat << eof >> $headerfile
+/* C Language Only */
+#if !defined (__ASSEMBLER__)
+
+#include <stdint.h>
+
+typedef volatile uint8_t register8_t;
+typedef volatile uint16_t register16_t;
+typedef volatile uint32_t register32_t;
+
+
+#ifdef _WORDREGISTER
+#undef _WORDREGISTER
+#endif
+#define _WORDREGISTER(regname) \\
+ __extension__ union \\
+ { \\
+ register16_t regname; \\
+ struct \\
+ { \\
+ register8_t regname ## L; \\
+ register8_t regname ## H; \\
+ }; \\
+ }
+
+#ifdef _DWORDREGISTER
+#undef _DWORDREGISTER
+#endif
+#define _DWORDREGISTER(regname) \\
+ __extension__ union \\
+ { \\
+ register32_t regname; \\
+ struct \\
+ { \\
+ register8_t regname ## 0; \\
+ register8_t regname ## 1; \\
+ register8_t regname ## 2; \\
+ register8_t regname ## 3; \\
+ }; \\
+ }
+
+
+eof
+
+
+# XMEGA Register and Enumerator Structures
+#-----------------------------------------
+
+echo "/*" >> $headerfile
+echo "==========================================================================" >> $headerfile
+echo "IO Module Structures" >> $headerfile
+echo "==========================================================================" >> $headerfile
+echo "*/" >> $headerfile
+echo "" >> $headerfile
+
+MODULES=$(xml sel -T -t -m "/AVRPART/V2/templates/module" -v "concat(@class,' ')" $devicefile)
+for i in $MODULES ; do
+ MODULE_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']' -v "@text" $devicefile)
+
+ # Generate register structures.
+ REGISTERS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers' -v "concat(@name,' ')" $devicefile)
+ for j in $REGISTERS ; do
+ GLOBALREGS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']' -v "@globalregs" $devicefile)
+
+ if test "$GLOBALREGS" != "true" ; then
+
+ echo "/*" >> $headerfile
+ echo "--------------------------------------------------------------------------" >> $headerfile
+ echo "$i - $MODULE_TEXT" >> $headerfile
+ echo "--------------------------------------------------------------------------" >> $headerfile
+ echo "*/" >> $headerfile
+ echo "" >> $headerfile
+
+ REGISTERS_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']' -v "@text" $devicefile)
+ echo "/* ${REGISTERS_TEXT} */" >> $headerfile
+ echo "typedef struct ${j}_struct" >> $headerfile
+ echo "{" >> $headerfile
+
+ REG_OFFSETS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*' -v "concat(@offset,' ')" $devicefile | sort)
+ for k in $REG_OFFSETS ; do
+ REG_NAME=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@name" $devicefile)
+ REG_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@text" $devicefile)
+ REG_SIZE=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@size" $devicefile)
+
+ if test -z "$REG_NAME" ; then
+ echo " register8_t reserved_${k};" >> $headerfile
+ else
+ if test -n "$REG_SIZE" ; then
+ if test "$REG_SIZE" = "1" ; then
+ echo " register8_t ${REG_NAME}; /* ${REG_TEXT} */" >> $headerfile
+ elif test "$REG_SIZE" = "2" ; then
+ echo " _WORDREGISTER(${REG_NAME}); /* ${REG_TEXT} */" >> $headerfile
+ fi
+ else
+ REG_IMPLEMENTS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@implements" $devicefile)
+ echo " ${REG_IMPLEMENTS}_t ${REG_NAME}; /* ${REG_TEXT} */" >> $headerfile
+ fi
+ fi
+ done
+
+ echo "} ${j}_t;" >> $headerfile
+ echo "" >> $headerfile
+
+ fi
+ done
+
+ # Generate enumerator structures.
+ ENUMERATORS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/enumerator' -v "concat(@name,' ')" $devicefile)
+ for j in $ENUMERATORS ; do
+ ENUMERATOR_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/enumerator[@name='\'${j}\'']' -v "@text" $devicefile)
+ echo "/* ${ENUMERATOR_TEXT} */" >> $headerfile
+ echo "typedef enum ${j}_enum" >> $headerfile
+ echo "{" >> $headerfile
+
+ # Get enum shift value from bitfield data in a different part of the V2 data.
+ ENUM_SHIFT=
+ for m in $REGISTERS ; do
+ REG_OFFSETS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${m}\'']/child::*' -v "concat(@offset,' ')" $devicefile | sort)
+ for n in $REG_OFFSETS ; do
+ BITFIELD_NAMES=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${m}\'']/child::*[@offset='\'${n}\'']/bitfield' -v "concat(@name,' ')" $devicefile)
+ for p in $BITFIELD_NAMES ; do
+ BITFIELD_ENUM=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${m}\'']/child::*[@offset='\'${n}\'']/bitfield[@name='\'${p}\'']' -v "@enum" $devicefile)
+ if test "$BITFIELD_ENUM" = "$j" ; then
+
+ # The enum shift value is equal to the number of lsb 0 bits
+ # in the mask value of the bitfield that has a matching enum name.
+ ENUM_SHIFT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${m}\'']/child::*[@offset='\'${n}\'']/bitfield[@name='\'${p}\'']' \
+ -v "@mask" $devicefile | \
+ sed "s,0x.2,1,g" | \
+ sed "s,0x.4,2,g" | \
+ sed "s,0x.6,1,g" | \
+ sed "s,0x.8,3,g" | \
+ sed "s,0x.C,2,g" | \
+ sed "s,0x.E,1,g" | \
+ sed "s,0x10,4,g" | \
+ sed "s,0x30,4,g" | \
+ sed "s,0x70,4,g" | \
+ sed "s,0xF0,4,g" | \
+ sed "s,0x20,5,g" | \
+ sed "s,0x60,5,g" | \
+ sed "s,0xE0,5,g" | \
+ sed "s,0x40,6,g" | \
+ sed "s,0xC0,6,g" | \
+ sed "s,0x80,7,g" | \
+ sed "s,0x..,0,g" )
+
+ # Match only the first enum value found so break out.
+ break 3
+ fi
+ done
+ done
+ done
+
+ ENUMS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/enumerator[@name='\'${j}\'']/enum' -v "concat(@name,' ')" $devicefile)
+ for k in $ENUMS ; do
+ ENUM_VALUE=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/enumerator[@name='\'${j}\'']/enum[@name='\'${k}\'']' -v "@val" $devicefile)
+ ENUM_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/enumerator[@name='\'${j}\'']/enum[@name='\'${k}\'']' -v "@text" $devicefile)
+ echo " ${j}_${k}_gc = (${ENUM_VALUE}<<${ENUM_SHIFT}), /* ${ENUM_TEXT} */" >> $headerfile
+ done
+
+ echo "} ${j}_t;" >> $headerfile
+ echo "" >> $headerfile
+ done
+ echo "" >> $headerfile
+done
+echo "" >> $headerfile
+
+
+
+
+# XMEGA Register Structure Instances
+#--------------------------------------
+echo "/*" >> $headerfile
+echo "==========================================================================" >> $headerfile
+echo "IO Module Instances. Mapped to memory." >> $headerfile
+echo "==========================================================================" >> $headerfile
+echo "*/" >> $headerfile
+echo "" >> $headerfile
+for i in $(xml sel -T -t -m /AVRPART/group -s "A:T:-" "@offset" -v "concat(@name,' ')" $headerfile-iogroups.xml | sed "s,GPIO ,,g" | sed "s,CPU ,,g") ; do
+ IMPLEMENTS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']' -v @implements $headerfile-iogroups.xml)
+ OFFSET=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']' -v @offset $headerfile-iogroups.xml)
+ TEXT=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']' -v @text $headerfile-iogroups.xml)
+ echo "#define ${i} (*(${IMPLEMENTS}_t *) ${OFFSET}) /* ${TEXT} */" >> $headerfile
+done
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+
+echo "#endif /* !defined (__ASSEMBLER__) */" >> $headerfile
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+
+
+# XMEGA Flattened fully qualified IO register names
+#---------------------------------------------------
+
+echo "/* ========== Flattened fully qualified IO register names ========== */" >> $headerfile
+echo "" >> $headerfile
+
+for i in $GROUP_NAMES ; do
+ GROUP_TEXT=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']' -v "@text" $headerfile-iogroups.xml)
+ echo "/* ${i} - ${GROUP_TEXT} */" >> $headerfile
+
+ REGISTERS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers' -v "concat(@name,' ')" $headerfile-iogroups.xml)
+ for j in $REGISTERS ; do
+
+ REG_OFFSETS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*' -v "concat(@offset,' ')" $headerfile-iogroups.xml | sort)
+ for k in $REG_OFFSETS ; do
+ REG_NAME=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@name" $headerfile-iogroups.xml)
+ if test -n "$REG_NAME" ; then
+ REG_SIZE=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@size" $headerfile-iogroups.xml)
+ REG_ADDRESS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@address" $headerfile-iogroups.xml)
+ if test -n "$REG_SIZE" ; then
+ if test "$REG_SIZE" = "1" ; then
+ echo "#define ${i}_${REG_NAME} _SFR_MEM8(${REG_ADDRESS})" >> $headerfile
+ fi
+ if test "$REG_SIZE" = "2" ; then
+ echo "#define ${i}_${REG_NAME} _SFR_MEM16(${REG_ADDRESS})" >> $headerfile
+ fi
+ else
+ REG_IMPLEMENTS=$(xml sel -T -t -m '/AVRPART/group[@name='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@implements" $headerfile-iogroups.xml)
+
+
+ MODULES=$(xml sel -T -t -m "/AVRPART/V2/templates/module" -v "concat(@class,' ')" $devicefile)
+ for m in $MODULES ; do
+ REGISTERS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${m}\'']/registers' -v "concat(@name,' ')" $devicefile)
+ for n in $REGISTERS ; do
+ if test "$n" = "$REG_IMPLEMENTS" ; then
+ REG_OFFSETS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${m}\'']/registers[@name='\'${n}\'']/child::*' -v "concat(@offset,' ')" $devicefile | sort)
+ for p in $REG_OFFSETS ; do
+ SUBREG_NAME=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${m}\'']/registers[@name='\'${n}\'']/child::*[@offset='\'${p}\'']' -v "@name" $devicefile)
+ SUBREG_SIZE=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${m}\'']/registers[@name='\'${n}\'']/child::*[@offset='\'${p}\'']' -v "@size" $devicefile)
+ SUBREG_OFFSET=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${m}\'']/registers[@name='\'${n}\'']/child::*[@offset='\'${p}\'']' -v "@offset" $devicefile)
+ if test -n "$SUBREG_NAME" ; then
+ ADDRESS=$(printf "0x%04X" $(($REG_ADDRESS + $SUBREG_OFFSET)))
+ if test "$SUBREG_SIZE" = "1" ; then
+ echo "#define ${i}_${REG_NAME}_${SUBREG_NAME} _SFR_MEM8(${ADDRESS})" >> $headerfile
+ fi
+ if test "$SUBREG_SIZE" = "2" ; then
+ echo "#define ${i}_${REG_NAME}_${SUBREG_NAME} _SFR_MEM16(${ADDRESS})" >> $headerfile
+ fi
+ fi
+ done
+ break 2
+ fi
+ done
+ done
+ fi
+ fi
+ done
+ done
+ echo "" >> $headerfile
+done
+echo "" >> $headerfile
+
+
+
+#echo "#endif /* !defined (__ASSEMBLER__) */" >> $headerfile
+#echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+# XMEGA Bitfield definitions
+#---------------------------------------------------
+
+echo "/*================== Bitfield Definitions ================== */" >> $headerfile
+echo "" >> $headerfile
+MODULE_NAMES=$(xml sel -T -t -m /AVRPART/V2/templates/module -v "concat(@class,' ')" $devicefile)
+for i in $MODULE_NAMES ; do
+ PREV_MODULE_NAME=
+ MODULE_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']' -v "@text" $devicefile)
+
+ REGISTER_GROUPS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers' -v "concat(@name,' ')" $devicefile)
+ for j in $REGISTER_GROUPS ; do
+
+ REG_OFFSETS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*' -v "concat(@offset,' ')" $devicefile | sort)
+ for k in $REG_OFFSETS ; do
+ REGNAME=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']' -v "@name" $devicefile)
+ BITFIELDS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']/bitfield' -v "concat(@name,' ')" $devicefile)
+
+ if test -n "$BITFIELDS" ; then
+ if test -z $PREV_MODULE_NAME ; then
+ echo "/* ${i} - ${MODULE_TEXT} */" >> $headerfile
+ PREV_MODULE_NAME=$i
+ fi
+
+ echo "/* ${j}.${REGNAME} bit masks and bit positions */" >> $headerfile
+
+ for m in $BITFIELDS ; do
+ BITFIELD_GROUP_MASK=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']/bitfield[@name='\'${m}\'']' -v "@mask" $devicefile)
+ BITFIELD_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'${i}\'']/registers[@name='\'${j}\'']/child::*[@offset='\'${k}\'']/bitfield[@name='\'${m}\'']' -v "@text" $devicefile)
+ BITFIELD_GROUP_POSITION=$(echo $BITFIELD_GROUP_MASK | \
+ sed "s,0x.2,1,g" | \
+ sed "s,0x.4,2,g" | \
+ sed "s,0x.6,1,g" | \
+ sed "s,0x.8,3,g" | \
+ sed "s,0x.C,2,g" | \
+ sed "s,0x.E,1,g" | \
+ sed "s,0x10,4,g" | \
+ sed "s,0x30,4,g" | \
+ sed "s,0x70,4,g" | \
+ sed "s,0xF0,4,g" | \
+ sed "s,0x20,5,g" | \
+ sed "s,0x60,5,g" | \
+ sed "s,0xE0,5,g" | \
+ sed "s,0x40,6,g" | \
+ sed "s,0xC0,6,g" | \
+ sed "s,0x80,7,g" | \
+ sed "s,0x..,0,g" )
+
+ BITFIELD_MASK=$(($BITFIELD_GROUP_MASK >> $BITFIELD_GROUP_POSITION))
+ if test $(( $BITFIELD_MASK )) -gt 1 ; then
+ DEFINITION=" ${j}_${m}_gm "
+ grep "${DEFINITION}" $headerfile
+ if test $? -eq 0 ; then
+ echo "/*${DEFINITION} Predefined. */" >> $headerfile
+ else
+ echo "#define ${j}_${m}_gm ${BITFIELD_GROUP_MASK} /* ${BITFIELD_TEXT} group mask. */" >> $headerfile
+ fi
+
+ DEFINITION=" ${j}_${m}_gp "
+ grep "${DEFINITION}" $headerfile
+ if test $? -eq 0 ; then
+ echo "/*${DEFINITION} Predefined. */" >> $headerfile
+ else
+ echo "#define ${j}_${m}_gp ${BITFIELD_GROUP_POSITION} /* ${BITFIELD_TEXT} group position. */" >> $headerfile
+ fi
+
+ BITNUM="0"
+ while test $(($BITFIELD_MASK & 0x01)) -eq 1 ; do
+ DEFINITION=" ${j}_${m}${BITNUM}_bm "
+ grep "${DEFINITION}" $headerfile
+ if test $? -eq 0 ; then
+ echo "/*${DEFINITION} Predefined. */" >> $headerfile
+ else
+ echo "#define ${j}_${m}${BITNUM}_bm (1<<${BITFIELD_GROUP_POSITION}) /* ${BITFIELD_TEXT} bit ${BITNUM} mask. */" >> $headerfile
+ fi
+
+ DEFINITION=" ${j}_${m}${BITNUM}_bp "
+ grep "${DEFINITION}" $headerfile
+ if test $? -eq 0 ; then
+ echo "/*${DEFINITION} Predefined. */" >> $headerfile
+ else
+ echo "#define ${j}_${m}${BITNUM}_bp ${BITFIELD_GROUP_POSITION} /* ${BITFIELD_TEXT} bit ${BITNUM} position. */" >> $headerfile
+ fi
+
+ BITFIELD_GROUP_POSITION=$(($BITFIELD_GROUP_POSITION + 1))
+ BITFIELD_MASK=$(($BITFIELD_MASK >> 1))
+ BITNUM=$(($BITNUM + 1))
+ done
+ else
+ DEFINITION=" ${j}_${m}_bm "
+ grep "${DEFINITION}" $headerfile
+ if test $? -eq 0 ; then
+ echo "/*${DEFINITION} Predefined. */" >> $headerfile
+ else
+ echo "#define ${j}_${m}_bm ${BITFIELD_GROUP_MASK} /* ${BITFIELD_TEXT} bit mask. */" >> $headerfile
+ fi
+
+ DEFINITION=" ${j}_${m}_bp "
+ grep "${DEFINITION}" $headerfile
+ if test $? -eq 0 ; then
+ echo "/*${DEFINITION} Predefined. */" >> $headerfile
+ else
+ echo "#define ${j}_${m}_bp ${BITFIELD_GROUP_POSITION} /* ${BITFIELD_TEXT} bit position. */" >> $headerfile
+ fi
+ fi
+ echo "" >> $headerfile
+
+ done
+ echo "" >> $headerfile
+ fi
+ done
+ done
+done
+echo "" >> $headerfile
+
+
+# XMEGA Generic Port Pin definitions
+#---------------------------------------------------
+cat << eof >> $headerfile
+// Generic Port Pins
+
+#define PIN0_bm 0x01
+#define PIN0_bp 0
+#define PIN1_bm 0x02
+#define PIN1_bp 1
+#define PIN2_bm 0x04
+#define PIN2_bp 2
+#define PIN3_bm 0x08
+#define PIN3_bp 3
+#define PIN4_bm 0x10
+#define PIN4_bp 4
+#define PIN5_bm 0x20
+#define PIN5_bp 5
+#define PIN6_bm 0x40
+#define PIN6_bp 6
+#define PIN7_bm 0x80
+#define PIN7_bp 7
+
+
+eof
+
+
+
+# XMEGA Interrupt Vector definitions
+#---------------------------------------------------
+echo "/* ========== Interrupt Vector Definitions ========== */" >> $headerfile
+echo "/* Vector 0 is the reset vector */" >> $headerfile
+echo "" >> $headerfile
+INTERRUPT_MODULES=$(xml sel -T -t -m /AVRPART/V2/interrupts/interrupt-group -v "concat(@module,' ')" $devicefile)
+for i in $INTERRUPT_MODULES ; do
+ echo "/* ${i} interrupt vectors */" >> $headerfile
+ MODULE_REF=$(xml sel -T -t -m '/AVRPART/V2/interrupts/interrupt-group[@module='\'${i}\'']' -v "@ref" $devicefile)
+ MODULE_OFFSET=$(xml sel -T -t -m '/AVRPART/V2/interrupts/interrupt-group[@module='\'${i}\'']' -v "@offset" $devicefile)
+
+ INTERRUPTS=$(xml sel -T -t -m '/AVRPART/V2/templates/module/interrupt-group[@name='\'${MODULE_REF}\'']/int' -s "A:T:-" "@offset" -v "concat(@name,' ')" $devicefile)
+ for j in $INTERRUPTS ; do
+ INT_OFFSET=$(xml sel -T -t -m '/AVRPART/V2/templates/module/interrupt-group[@name='\'${MODULE_REF}\'']/int[@name='\'${j}\'']' -v "@offset" $devicefile)
+ INT_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module/interrupt-group[@name='\'${MODULE_REF}\'']/int[@name='\'${j}\'']' -v "@text" $devicefile)
+ VECTOR_NUM=$(($MODULE_OFFSET + $INT_OFFSET))
+ echo "#define ${i}_${j}_vect_num ${VECTOR_NUM}" >> $headerfile
+ echo "#define ${i}_${j}_vect _VECTOR(${VECTOR_NUM}) /* ${INT_TEXT} */" >> $headerfile
+ done
+ echo "" >> $headerfile
+done
+echo "" >> $headerfile
+
+# todo: Remove hard-coded vector size.
+echo "#define _VECTOR_SIZE 4 /* Size of individual vector. */" >> $headerfile
+VECTOR_NUM=$(($VECTOR_NUM + 1))
+echo "#define _VECTORS_SIZE (${VECTOR_NUM} * _VECTOR_SIZE)" >> $headerfile
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+
+# XMEGA Constant definitions
+#---------------------------------------------------
+echo "/* ========== Constants ========== */" >> $headerfile
+echo "" >> $headerfile
+
+MEMSPACE_NAMES=$(xml sel -T -t -m "/AVRPART/V2/memspaces/memspace" -v "concat(@name,' ')" $devicefile)
+for i in $MEMSPACE_NAMES ; do
+ MEMSPACE_START=$(xml sel -T -t -m '/AVRPART/V2/memspaces/memspace[@name='\'${i}\'']' -v "@start" $devicefile)
+ MEMSPACE_SIZE=$(( $(xml sel -T -t -m '/AVRPART/V2/memspaces/memspace[@name='\'${i}\'']' -v "@size" $devicefile) ))
+ MEMSPACE_PAGE_SIZE=$(( $(xml sel -T -t -m '/AVRPART/V2/memspaces/memspace[@name='\'${i}\'']' -v "@pagesize" $devicefile) ))
+ echo "#define ${i}_START (${MEMSPACE_START})" >> $headerfile
+ echo "#define ${i}_SIZE (${MEMSPACE_SIZE})" >> $headerfile
+ echo "#define ${i}_PAGE_SIZE (${MEMSPACE_PAGE_SIZE})" >> $headerfile
+ echo "#define ${i}_END (${i}_START + ${i}_SIZE - 1)" >> $headerfile
+ echo "" >> $headerfile
+done
+
+echo "#define FLASHEND PROGMEM_END" >> $headerfile
+echo "#define SPM_PAGESIZE PROGMEM_PAGE_SIZE" >> $headerfile
+echo "#define RAMSTART INTERNAL_SRAM_START" >> $headerfile
+echo "#define RAMSIZE INTERNAL_SRAM_SIZE" >> $headerfile
+echo "#define RAMEND INTERNAL_SRAM_END" >> $headerfile
+echo "#define XRAMSTART EXTERNAL_SRAM_START" >> $headerfile
+echo "#define XRAMSIZE EXTERNAL_SRAM_SIZE" >> $headerfile
+if test $(( $(xml sel -T -t -m "/AVRPART/V2/memspaces/memspace[@name='EXTERNAL_SRAM']" -v "@size" $devicefile) )) -gt 0 ; then
+ echo "#define XRAMEND EXTERNAL_SRAM_END" >> $headerfile
+else
+ echo "#define XRAMEND INTERNAL_SRAM_END" >> $headerfile
+fi
+echo "#define E2END EEPROM_END" >> $headerfile
+echo "#define E2PAGESIZE EEPROM_PAGE_SIZE" >> $headerfile
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+
+# XMEGA Fuse information
+#---------------------------------------------------
+FUSECOUNT=$(xml sel -T -t -v 'count(/AVRPART/V2/templates/module/registers[@memspace='\'FUSE\'']/reg)' $devicefile)
+echo "/* ========== Fuses ========== */" >> $headerfile
+echo "#define FUSE_MEMORY_SIZE ${FUSECOUNT}" >> $headerfile
+echo "" >> $headerfile
+FUSEBYTES=$(xml sel -T -t -m '/AVRPART/V2/templates/module/registers[@memspace='\'FUSE\'']/reg' -s "A:T:-" "@offset" -v "concat(@offset,' ')" $devicefile)
+FUSEBYTENUM=0
+for i in $FUSEBYTES ; do
+ FUSEBYTENAME=$(xml sel -T -t -m '/AVRPART/V2/templates/module/registers[@memspace='\'FUSE\'']/reg[@offset='\'${i}\'']' -v "@name" $devicefile)
+ if test -z "$FUSEBYTENAME" ; then
+ echo "/* Fuse Byte ${FUSEBYTENUM} Reserved */" >> $headerfile
+ else
+ echo "/* Fuse Byte ${FUSEBYTENUM} */" >> $headerfile
+ FUSEBITFIELDS=$(xml sel -T -t -m '/AVRPART/V2/templates/module/registers[@memspace='\'FUSE\'']/reg[@offset='\'${i}\'']/bitfield' -s "A:T:-" "@mask" -v "concat(@name,' ')" $devicefile)
+ for j in $FUSEBITFIELDS ; do
+ FUSEBITFIELD_TEXT=$(xml sel -T -t -m '/AVRPART/V2/templates/module/registers[@memspace='\'FUSE\'']/reg[@offset='\'${i}\'']/bitfield[@name='\'${j}\'']' \
+ -v "@text" $devicefile)
+ FUSEBITFIELD_MASK=$(xml sel -T -t -m '/AVRPART/V2/templates/module/registers[@memspace='\'FUSE\'']/reg[@offset='\'${i}\'']/bitfield[@name='\'${j}\'']' \
+ -v "@mask" $devicefile)
+ FUSEBITFIELD_SHIFT=$(echo "$FUSEBITFIELD_MASK" | \
+ sed "s,0x.2,1,g" | \
+ sed "s,0x.4,2,g" | \
+ sed "s,0x.6,1,g" | \
+ sed "s,0x.8,3,g" | \
+ sed "s,0x.C,2,g" | \
+ sed "s,0x.E,1,g" | \
+ sed "s,0x10,4,g" | \
+ sed "s,0x30,4,g" | \
+ sed "s,0x70,4,g" | \
+ sed "s,0xF0,4,g" | \
+ sed "s,0x20,5,g" | \
+ sed "s,0x60,5,g" | \
+ sed "s,0xE0,5,g" | \
+ sed "s,0x40,6,g" | \
+ sed "s,0xC0,6,g" | \
+ sed "s,0x80,7,g" | \
+ sed "s,0x..,0,g" )
+ FUSEBITFIELD_MASK=$(( $FUSEBITFIELD_MASK >> $FUSEBITFIELD_SHIFT ))
+ if test $(( $FUSEBITFIELD_MASK )) -gt 1 ; then
+ BITNUM=0
+ while test $(($FUSEBITFIELD_MASK & 0x01)) -eq 1 ; do
+ echo "#define FUSE_${j}${BITNUM} (unsigned char)~_BV(${FUSEBITFIELD_SHIFT}) /* ${FUSEBITFIELD_TEXT} Bit ${BITNUM} */" >> $headerfile
+ FUSEBITFIELD_MASK=$(($FUSEBITFIELD_MASK >> 1))
+ BITNUM=$(($BITNUM + 1))
+ FUSEBITFIELD_SHIFT=$(($FUSEBITFIELD_SHIFT + 1))
+ done
+ else
+ echo "#define FUSE_${j} (unsigned char)~_BV(${FUSEBITFIELD_SHIFT}) /* ${FUSEBITFIELD_TEXT} */" >> $headerfile
+ fi
+ done
+ echo "#define FUSE${FUSEBYTENUM}_DEFAULT (0xFF)" >> $headerfile
+ fi
+ echo "" >> $headerfile
+ FUSEBYTENUM=$((FUSEBYTENUM + 1))
+done
+echo "" >> $headerfile
+# todo: Default XMEGA fuse values are currently hardcoded to 0xFF.
+
+
+
+# XMEGA Lockbit information
+#---------------------------------------------------
+echo "/* ========== Lock Bits ========== */" >> $headerfile
+LOCK_BITS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'NVM\'']/registers/reg[@name='\'LOCKBITS\'']/bitfield[@name='\'LB\'']' -v "@name" $devicefile)
+if test -n "$LOCK_BITS" ; then
+ echo "#define __LOCK_BITS_EXIST" >> $headerfile
+fi
+
+BOOT_LOCK_APPLICATION_TABLE_BITS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'NVM\'']/registers/reg[@name='\'LOCKBITS\'']/bitfield[@name='\'BLBAT\'']' -v "@name" $devicefile)
+if test -n "$BOOT_LOCK_APPLICATION_TABLE_BITS" ; then
+ echo "#define __BOOT_LOCK_APPLICATION_TABLE_BITS_EXIST" >> $headerfile
+fi
+
+BOOT_LOCK_APPLICATION_BITS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'NVM\'']/registers/reg[@name='\'LOCKBITS\'']/bitfield[@name='\'BLBA\'']' -v "@name" $devicefile)
+if test -n "$BOOT_LOCK_APPLICATION_BITS" ; then
+ echo "#define __BOOT_LOCK_APPLICATION_BITS_EXIST" >> $headerfile
+fi
+
+BOOT_LOCK_BOOT_BITS=$(xml sel -T -t -m '/AVRPART/V2/templates/module[@class='\'NVM\'']/registers/reg[@name='\'LOCKBITS\'']/bitfield[@name='\'BLBB\'']' -v "@name" $devicefile)
+if test -n "$BOOT_LOCK_BOOT_BITS" ; then
+ echo "#define __BOOT_LOCK_BOOT_BITS_EXIST" >> $headerfile
+fi
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+# XMEGA Signature information
+#----------------------------------------------
+SIGNATURE_0=$(xml sel -T -t -m "/AVRPART/ADMIN/SIGNATURE" -v "ADDR000" $devicefile | sed "s,\\$,0x,g")
+SIGNATURE_1=$(xml sel -T -t -m "/AVRPART/ADMIN/SIGNATURE" -v "ADDR001" $devicefile | sed "s,\\$,0x,g")
+SIGNATURE_2=$(xml sel -T -t -m "/AVRPART/ADMIN/SIGNATURE" -v "ADDR002" $devicefile | sed "s,\\$,0x,g")
+echo "/* ========== Signature ========== */" >> $headerfile
+echo "#define SIGNATURE_0 ${SIGNATURE_0}" >> $headerfile
+echo "#define SIGNATURE_1 ${SIGNATURE_1}" >> $headerfile
+echo "#define SIGNATURE_2 ${SIGNATURE_2}" >> $headerfile
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+else
+
+
+# Classic AVR
+#==================
+
+# Registers and bit numbers.
+#-----------------------------
+
+# Get register section from input file and remove some unused elements.
+xml sel -t -c /AVRPART/MEMORY/IO_MEMORY $devicefile | \
+ xml ed -O \
+ -d /IO_MEMORY/IO_START_ADDR \
+ -d /IO_MEMORY/IO_STOP_ADDR \
+ -d /IO_MEMORY/EXT_IO_START_ADDR \
+ -d /IO_MEMORY/EXT_IO_STOP_ADDR \
+ -d /IO_MEMORY/MEM_START_ADDR \
+ -d /IO_MEMORY/MEM_STOP_ADDR > $headerfile-iomemory.xml
+
+# Get list of register names.
+REGNAMES=$(xml el $headerfile-iomemory.xml | sed "s,IO_MEMORY$,,g" | cut -d '/' -f 2 | sed "s,\r,,g" | uniq)
+
+# Convert temporary working XML file to PYX.
+xml pyx $headerfile-iomemory.xml > $headerfile-iomemory.pyx
+
+# For each register...
+MAX_ADDRESS_WIDTH=0
+for i in $REGNAMES ; do \
+
+ # Get IO address.
+ IOADDR=$(xml sel -t -v /IO_MEMORY/$i/IO_ADDR $headerfile-iomemory.xml | sed "s,\r,," | sed "s,NA,," | sed "s,\\$,0x,g")
+
+ # Get Memory address.
+ MEMADDR=$(xml sel -t -v /IO_MEMORY/$i/MEM_ADDR $headerfile-iomemory.xml | sed "s,\r,," | sed "s,\\$,0x,g")
+
+ # Check for max width of address
+ WIDTH=$(( $(echo "$IOADDR" | wc -m) ))
+ if test $WIDTH -gt $MAX_ADDRESS_WIDTH ; then
+ MAX_ADDRESS_WIDTH=$WIDTH
+ fi
+ WIDTH=$(( $(echo "$MEMADDR" | wc -m) ))
+ if test $WIDTH -gt $MAX_ADDRESS_WIDTH ; then
+ MAX_ADDRESS_WIDTH=$WIDTH
+ fi
+
+ # Get initialization value (if exists).
+ INIT=$(xml sel -t -v /IO_MEMORY/$i/INIT $headerfile-iomemory.xml | sed "s,\r,,")
+
+ # Determine type of address.
+ if test -z "$IOADDR"; then
+ TYPE="mem"
+ else
+ TYPE="io"
+ fi
+
+ # Convert named register element to REGISTER element with attributes in the PYX file.
+ sed -i "s,(${i}$,(REGISTER\nAname $i\nAtype $TYPE\nAio_addr $IOADDR\nAmem_addr $MEMADDR\nAsize 8\nAinit $INIT," $headerfile-iomemory.pyx
+ sed -i "s,)${i}$,)REGISTER," $headerfile-iomemory.pyx
+done
+# Subtract 3 from max address width: 2 for "0x" and 1 for line feed when echoing to wc.
+MAX_ADDRESS_WIDTH=$(( $MAX_ADDRESS_WIDTH - 3 ))
+
+
+# - Convert temporary PYX file back to temporary XML file.
+# - Remove unused (previously converted) elements, and common registers we won't keep.
+# - Convert named bit mask elements to BIT elements with attributes
+# - Sort the register names based on the memory address element.
+# - Save it to the temporary XML file.
+xml depyx $headerfile-iomemory.pyx | \
+ xml ed -O \
+ -d "/IO_MEMORY/REGISTER/IO_ADDR" \
+ -d "/IO_MEMORY/REGISTER/MEM_ADDR" \
+ -d "/IO_MEMORY/REGISTER/INIT" \
+ -d "/IO_MEMORY/REGISTER[@name='SREG']" \
+ -d "/IO_MEMORY/REGISTER[@name='SP']" \
+ -d "/IO_MEMORY/REGISTER[@name='SPL']" \
+ -d "/IO_MEMORY/REGISTER[@name='SPH']" | \
+ sed 's,<.*_MASK>0x01</,<BIT value="0" name=",g' | \
+ sed 's,<.*_MASK>0x02</,<BIT value="1" name=",g' | \
+ sed 's,<.*_MASK>0x04</,<BIT value="2" name=",g' | \
+ sed 's,<.*_MASK>0x08</,<BIT value="3" name=",g' | \
+ sed 's,<.*_MASK>0x10</,<BIT value="4" name=",g' | \
+ sed 's,<.*_MASK>0x20</,<BIT value="5" name=",g' | \
+ sed 's,<.*_MASK>0x40</,<BIT value="6" name=",g' | \
+ sed 's,<.*_MASK>0x80</,<BIT value="7" name=",g' | \
+ sed 's,_MASK>$,"/>,g' | \
+ xml sel -t -e IO_MEMORY -n -m "/IO_MEMORY/REGISTER" -s "A:T:-" "@mem_addr" -c . -n > $headerfile-iomemory.xml
+
+# Remove temporary PYX file.
+rm $headerfile-iomemory.pyx
+
+# Calculate the set of word size register names needed.
+# - Get list of all register names, each name followed by an EOL.
+# - Convert to Unix line endings (for sed patterns to work).
+# - Cut off ending '_L' of register names.
+# - Cut off ending '_H' of register names.
+# - Cut off ending 'L' of register names.
+# - Cut off ending 'H' of register names.
+# - Get list of only duplicate register names.
+# - Remove duplicates.
+REGNAMES_WORD=$(xml sel -T -t -m "/IO_MEMORY/REGISTER" -v "@name" -n $headerfile-iomemory.xml | \
+ sed "s,\r\n,\n,g" | \
+ sed "s,_L$,,g" | \
+ sed "s,_H$,,g" | \
+ sed "s,L$,,g" | \
+ sed "s,H$,,g" | \
+ uniq -d | \
+ uniq)
+
+# Add word registers to temporary working XML file.
+# - For each word register...
+for i in $REGNAMES_WORD ; do \
+
+ # Get the register type from the Low register,
+ # convert to Unix line endings.
+ TYPE=$(xml sel -t -m '/IO_MEMORY/REGISTER[@name='\'${i}L\'']' -v "@type" $headerfile-iomemory.xml | sed "s,\r,,")
+
+ # Get the io address from the Low register,
+ # convert to Unix line endings.
+ IOADDR=$(xml sel -t -m '/IO_MEMORY/REGISTER[@name='\'${i}L\'']' -v "@io_addr" $headerfile-iomemory.xml | sed "s,\r,,")
+
+ # Get the memory address from the Low register,
+ # convert to Unix line endings.
+ MEMADDR=$(xml sel -t -m '/IO_MEMORY/REGISTER[@name='\'${i}L\'']' -v "@mem_addr" $headerfile-iomemory.xml | sed "s,\r,,")
+
+ # - Insert a new element before the Low register, name it as the word register
+ # - Append a 'name' attribute
+ # - Append a 'type' attribute
+ # - Append a 'io_addr' attribute
+ # - Append a 'mem_addr' attribute
+ # - Append a 'size' attribute
+ # - Rename the element to REGISTER
+ # - Save to a 2nd temporary XML file.
+ xml ed -O -i '/IO_MEMORY/REGISTER[@name='\'${i}L\'']' --type "elem" -n "$i" -v "" \
+ -a '/IO_MEMORY/'${i} --type "attr" -n "name" -v "$i" \
+ -a '/IO_MEMORY/'${i} --type "attr" -n "type" -v "$TYPE" \
+ -a '/IO_MEMORY/'${i} --type "attr" -n "io_addr" -v "$IOADDR" \
+ -a '/IO_MEMORY/'${i} --type "attr" -n "mem_addr" -v "$MEMADDR" \
+ -a '/IO_MEMORY/'${i} --type "attr" -n "size" -v "16" \
+ -r '/IO_MEMORY/'${i} -v "REGISTER" $headerfile-iomemory.xml > $headerfile-iomem2.xml
+
+ # Move 2nd temporary XML file to first.
+ mv $headerfile-iomem2.xml $headerfile-iomemory.xml
+done
+
+
+# Fix width of all addresses.
+ALLREGS=$(xml sel -T -t -m "/IO_MEMORY/REGISTER" -v "concat(@name,' ')" $headerfile-iomemory.xml)
+for i in $ALLREGS ; do
+ MEM_ADDR=$(xml sel -T -t -m '/IO_MEMORY/REGISTER[@name='\'${i}\'']' -v "@mem_addr" $headerfile-iomemory.xml)
+ if test -n "$MEM_ADDR" ; then
+ NEW_MEM_ADDR=$(printf "0x%0${MAX_ADDRESS_WIDTH}X" $(( $MEM_ADDR )) )
+ xml ed -O -u '/IO_MEMORY/REGISTER[@name='\'${i}\'']/@mem_addr' -v "$NEW_MEM_ADDR" $headerfile-iomemory.xml > $headerfile-tmp.xml
+ mv $headerfile-tmp.xml $headerfile-iomemory.xml
+ fi
+ IO_ADDR=$(xml sel -T -t -m '/IO_MEMORY/REGISTER[@name='\'${i}\'']' -v "@io_addr" $headerfile-iomemory.xml)
+ if test -n "$IO_ADDR" ; then
+ NEW_IO_ADDR=$(printf "0x%0${MAX_ADDRESS_WIDTH}X" $(( $IO_ADDR )) )
+ xml ed -O -u '/IO_MEMORY/REGISTER[@name='\'${i}\'']/@io_addr' -v "$NEW_IO_ADDR" $headerfile-iomemory.xml > $headerfile-tmp.xml
+ mv $headerfile-tmp.xml $headerfile-iomemory.xml
+ fi
+done
+
+
+# Output data from temporary working XML file to avr-libc I/O header file.
+# Replace hyphens with underscores.
+echo "/* Registers and associated bit numbers. */" >> $headerfile
+xml sel -T \
+ -t -m "/IO_MEMORY/REGISTER[@type='io']" -s "A:T:-" "@io_addr" -n -v "concat('#define ',@name,' _SFR_IO',@size,'(',@io_addr,')')" -n \
+ -m "BIT[@value]" -s "A:T:-" "@value" -v "concat('#define ',@name,' ',@value)" -n \
+ -t -m "/IO_MEMORY/REGISTER[@type='mem']" -s "A:T:-" "@mem_addr" -n -v "concat('#define ',@name,' _SFR_MEM',@size,'(',@mem_addr,')')" -n \
+ -m "BIT[@value]" -s "A:T:-" "@value" -v "concat('#define ',@name,' ',@value)" -n \
+ -t -n -n $headerfile-iomemory.xml | \
+sed "s,-,_,g" >> $headerfile
+
+
+# Check for ADC 16-bit register and create ADCW with guard for assembly.
+ADC=$(grep "#define ADC " $headerfile | cut -d ' ' -f 3)
+if test -n "$ADC" ; then
+ sed -i "s,#define ADC ,#ifndef __ASSEMBLER__\\n#define ADC $ADC\\n#endif\\n#define ADCW ,g" $headerfile
+fi
+
+# Create list of 8-bit registers that have no associated bit names.
+REGS_NO_BITNAMES=$(xml sel -T -t -m "/IO_MEMORY/REGISTER[@size='8']" \
+ -i "count(BIT)=0" -v "@name" -n $headerfile-iomemory.xml | sed "s,\r\n,\n,g")
+
+# Create list of 8-bit registers in the XML file that have hyphens in the names.
+REGS_WITH_HYPHENS=$(xml sel -T -t -m "/IO_MEMORY/REGISTER[@size='8']" \
+ -i "contains(@name, '-')" -v "@name" -n \
+ -b -m "BIT" \
+ -i "contains(@name, '-')" -v "@name" -n \
+ $headerfile-iomemory.xml | sed "s,\r\n,\n,g")
+
+
+# Interrupt vectors.
+#----------------------
+NMB_VECTORS=$(xml sel -T -t -v /AVRPART/INTERRUPT_VECTOR/NMB_VECTORS $devicefile | sed "s,\r,,g")
+VECTOR_SIZE=$(( $(xml sel -T -t -v /AVRPART/INTERRUPT_VECTOR/VECTOR2/PROGRAM_ADDRESS $devicefile | sed "s,\\$,0x,g" | sed "s,\r,,g") * 2 ))
+echo "/* Interrupt vectors */" >> $headerfile
+echo "/* Vector 0 is the reset vector */" >> $headerfile
+VECTORS=$(xml sel -T -t -m "/AVRPART/INTERRUPT_VECTOR/*[PROGRAM_ADDRESS]" -s "A:T:-" "PROGRAM_ADDRESS" -v "concat(name(),' ')" $devicefile)
+for i in $VECTORS ; do
+ if test "$i" != "VECTOR1" ; then
+ VECTOR_SOURCE=$(xml sel -T -t -m "/AVRPART/INTERRUPT_VECTOR/$i" -v "SOURCE" $devicefile | \
+ sed "s,Reserved.*,Reserved,g" | \
+ sed "s/,//g" | \
+ sed "s, ,_,g")
+ if test "$VECTOR_SOURCE" != "Reserved" ; then
+ VECTOR_NUM=$(( $(echo $i | sed "s,VECTOR,,g") - 1))
+ VECTOR_DESC=$(xml sel -T -t -m "/AVRPART/INTERRUPT_VECTOR/$i" -v "DEFINITION" $devicefile)
+ echo "#define ${VECTOR_SOURCE}_vect_num ${VECTOR_NUM}" >> $headerfile
+ echo "#define ${VECTOR_SOURCE}_vect _VECTOR(${VECTOR_NUM}) /* ${VECTOR_DESC} */" >> $headerfile
+ fi
+ fi
+done
+echo "" >> $headerfile
+echo "#define _VECTOR_SIZE ${VECTOR_SIZE} /* Size of individual vector. */" >> $headerfile
+echo "#define _VECTORS_SIZE (${NMB_VECTORS} * _VECTOR_SIZE)" >> $headerfile
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+
+# Constants
+#-------------
+echo "/* Constants */" >> $headerfile
+
+# SPM_PAGESIZE
+SPM_PAGESIZE=$(( $(xml sel -T -t -v "/AVRPART/MEMORY/BOOT_CONFIG/PAGESIZE" $devicefile) * 2))
+echo "#define SPM_PAGESIZE (${SPM_PAGESIZE})" >> $headerfile
+
+# RAMSTART
+RAMSTART=$(xml sel -T -t -v "/AVRPART/MEMORY/INT_SRAM/START_ADDR" $devicefile | sed "s,\\$,0x,g")
+echo "#define RAMSTART (${RAMSTART})" >> $headerfile
+
+# RAMSIZE
+RAMSIZE=$(xml sel -T -t -v "/AVRPART/MEMORY/INT_SRAM/SIZE" $devicefile)
+echo "#define RAMSIZE (${RAMSIZE})" >> $headerfile
+
+# RAMEND
+echo "#define RAMEND (RAMSTART + RAMSIZE - 1)" >> $headerfile
+
+# XRAMSTART
+XRAMSTART=$(xml sel -T -t -v "/AVRPART/MEMORY/EXT_SRAM/START_ADDR" $devicefile | sed "s,\\$,0x,g")
+echo "#define XRAMSTART (${XRAMSTART})" >> $headerfile
+
+# XRAMSIZE
+XRAMSIZE=$(xml sel -T -t -v "/AVRPART/MEMORY/EXT_SRAM/SIZE" $devicefile)
+echo "#define XRAMSIZE (${XRAMSIZE})" >> $headerfile
+
+# XRAMEND
+if test $XRAMSIZE -gt 0 ; then
+ echo "#define XRAMEND (XRAMSIZE - 1)" >> $headerfile
+else
+ echo "#define XRAMEND (RAMEND)" >> $headerfile
+fi
+
+# E2END
+EEPROM_SIZE=$(( $(xml sel -T -t -v "/AVRPART/MEMORY/EEPROM" $devicefile) ))
+if test $EEPROM_SIZE -gt 0 ; then
+ EEPROM_LAST=$(( $EEPROM_SIZE - 1 ))
+else
+ EEPROM_LAST=0
+fi
+E2END=$(printf "0x%X" $EEPROM_LAST)
+echo "#define E2END (${E2END})" >> $headerfile
+
+# E2PAGESIZE
+E2PAGESIZE=$(xml sel -T -t -v "/AVRPART/PROGRAMMING/EepromPageSize" $devicefile)
+echo "#define E2PAGESIZE (${E2PAGESIZE})" >> $headerfile
+
+# FLASHEND
+FLASHEND=$(printf "0x%X" $(( $(xml sel -T -t -v "/AVRPART/MEMORY/PROG_FLASH" $devicefile) - 1)) )
+echo "#define FLASHEND (${FLASHEND})" >> $headerfile
+
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+
+# Fuse information
+#---------------------
+xml sel -T -t -o "/* Fuses */" -n $devicefile >> $headerfile
+
+# Certain XML files have "templates", others do not. Use V1 information.
+NUM_FUSE_BYTES=$(xml sel -T -t -m /AVRPART/FUSE -v "count(LOW) + count(HIGH) + count(EXTENDED)" $devicefile)
+echo "#define FUSE_MEMORY_SIZE ${NUM_FUSE_BYTES}" >> $headerfile
+echo "" >> $headerfile
+
+if test $NUM_FUSE_BYTES -eq 1 ; then
+ # Single Fuse Byte
+ xml sel -t -e AVRPART -m /AVRPART/FUSE/LOW -c . $devicefile | \
+ xml pyx | \
+ sed "s,(FUSE,(FUSE\nAbitnum ,g" | \
+ sed "s,)FUSE.*,)FUSE,g" | \
+ sed "s,-\\$,-,g" | \
+ xml depyx | \
+ xml sel -T \
+ -t -i "count(/AVRPART/LOW)" -o "/* Fuse Byte */" -n \
+ -t -m "/AVRPART/LOW/FUSE[@bitnum]" -s "A:T:-" "@bitnum" -v "concat('#define FUSE_',NAME,' (unsigned char)~_BV(',@bitnum,') /* ',TEXT,' */')" -n \
+ -t -i "count(/AVRPART/LOW)" -o "#define FUSE_DEFAULT (" \
+ -m "/AVRPART/LOW/FUSE" -i "DEFAULT=0" -v "concat('FUSE_',NAME,' &amp; ')" \
+ -t -i "count(/AVRPART/LOW)" -o ")" -n -n | \
+ sed "s, \& ),)," | \
+ sed "s,DEFAULT (),DEFAULT (0xFF)," >> $headerfile
+else
+ # Low Fuse Byte
+ xml sel -t -e AVRPART -m /AVRPART/FUSE/LOW -c . $devicefile | \
+ xml pyx | \
+ sed "s,(FUSE,(FUSE\nAbitnum ,g" | \
+ sed "s,)FUSE.*,)FUSE,g" | \
+ sed "s,-\\$,-,g" | \
+ xml depyx | \
+ xml sel -T \
+ -t -i "count(/AVRPART/LOW)" -o "/* Low Fuse Byte */" -n \
+ -t -m "/AVRPART/LOW/FUSE[@bitnum]" -s "A:T:-" "@bitnum" -v "concat('#define FUSE_',NAME,' (unsigned char)~_BV(',@bitnum,') /* ',TEXT,' */')" -n \
+ -t -i "count(/AVRPART/LOW)" -o "#define LFUSE_DEFAULT (" \
+ -m "/AVRPART/LOW/FUSE" -i "DEFAULT=0" -v "concat('FUSE_',NAME,' &amp; ')" \
+ -t -i "count(/AVRPART/LOW)" -o ")" -n -n | \
+ sed "s, \& ),)," | \
+ sed "s,DEFAULT (),DEFAULT (0xFF)," >> $headerfile
+
+ # High Fuse Byte
+ xml sel -t -e AVRPART -m /AVRPART/FUSE/HIGH -c . $devicefile | \
+ xml pyx | \
+ sed "s,(FUSE,(FUSE\nAbitnum ,g" | \
+ sed "s,)FUSE.*,)FUSE,g" | \
+ sed "s,-\\$,-,g" | \
+ xml depyx | \
+ xml sel -T \
+ -t -i "count(/AVRPART/HIGH)" -o "/* High Fuse Byte */" -n \
+ -t -m "/AVRPART/HIGH/FUSE[@bitnum]" -s "A:T:-" "@bitnum" -v "concat('#define FUSE_',NAME,' (unsigned char)~_BV(',@bitnum,') /* ',TEXT,' */')" -n \
+ -t -i "count(/AVRPART/HIGH)" -o "#define HFUSE_DEFAULT (" \
+ -m "/AVRPART/HIGH/FUSE" -i "DEFAULT=0" -v "concat('FUSE_',NAME,' &amp; ')" \
+ -t -i "count(/AVRPART/HIGH)" -o ")" -n -n | \
+ sed "s, \& ),)," | \
+ sed "s,DEFAULT (),DEFAULT (0xFF)," >> $headerfile
+
+ # Extended Fuse Byte
+ xml sel -t -e AVRPART -m /AVRPART/FUSE/EXTENDED -c . $devicefile | \
+ xml pyx | \
+ sed "s,(FUSE,(FUSE\nAbitnum ,g" | \
+ sed "s,)FUSE.*,)FUSE,g" | \
+ sed "s,-\\$,-,g" | \
+ xml depyx | \
+ xml sel -T \
+ -t -i "count(/AVRPART/EXTENDED)" -o "/* Extended Fuse Byte */" -n \
+ -t -m "/AVRPART/EXTENDED/FUSE[@bitnum]" -s "A:T:-" "@bitnum" -v "concat('#define FUSE_',NAME,' (unsigned char)~_BV(',@bitnum,') /* ',TEXT,' */')" -n \
+ -t -i "count(/AVRPART/EXTENDED)" -o "#define EFUSE_DEFAULT (" \
+ -m "/AVRPART/EXTENDED/FUSE" -i "DEFAULT=0" -v "concat('FUSE_',NAME,' &amp; ')" \
+ -t -i "count(/AVRPART/EXTENDED)" -o ")" -n -n | \
+ sed "s, \& ),)," | \
+ sed "s,DEFAULT (),DEFAULT (0xFF)," >> $headerfile
+fi
+echo "" >> $headerfile
+
+
+
+# Lockbit information
+#-----------------------
+xml sel -T -t -o "/* Lock Bits */" -n $devicefile >> $headerfile
+
+# Normal V2 information location.
+xml sel -T -t -i "count(/AVRPART/V2/templates/module[@class='LOCKBIT']/registers/reg/bitfield[@name='LB'])" -o "#define __LOCK_BITS_EXIST" -n \
+ -i "count(/AVRPART/V2/templates/module[@class='LOCKBIT']/registers/reg/bitfield[@name='BLB0'])" -o "#define __BOOT_LOCK_BITS_0_EXIST" -n \
+ -i "count(/AVRPART/V2/templates/module[@class='LOCKBIT']/registers/reg/bitfield[@name='BLB1'])" -o "#define __BOOT_LOCK_BITS_1_EXIST" -n $devicefile >> $headerfile
+
+# Certain XML files have "templates", others do not. Use alternate XPath.
+xml sel -T -t -i "count(/AVRPART/LOCKBIT/V2/module[@class='LOCKBIT']/registers/reg/bitfield[@name='LB'])" -o "#define __LOCK_BITS_EXIST" -n \
+ -i "count(/AVRPART/LOCKBIT/V2/module[@class='LOCKBIT']/registers/reg/bitfield[@name='BLB0'])" -o "#define __BOOT_LOCK_BITS_0_EXIST" -n \
+ -i "count(/AVRPART/LOCKBIT/V2/module[@class='LOCKBIT']/registers/reg/bitfield[@name='BLB1'])" -o "#define __BOOT_LOCK_BITS_1_EXIST" -n $devicefile >> $headerfile
+
+xml sel -T -t -n -n $devicefile >> $headerfile
+
+
+
+# Signature information
+#--------------------------
+SIGNATURE_0=$(xml sel -T -t -m "/AVRPART/ADMIN/SIGNATURE" -v "ADDR000" $devicefile | sed "s,\\$,0x,g")
+SIGNATURE_1=$(xml sel -T -t -m "/AVRPART/ADMIN/SIGNATURE" -v "ADDR001" $devicefile | sed "s,\\$,0x,g")
+SIGNATURE_2=$(xml sel -T -t -m "/AVRPART/ADMIN/SIGNATURE" -v "ADDR002" $devicefile | sed "s,\\$,0x,g")
+echo "/* Signature */" >> $headerfile
+echo "#define SIGNATURE_0 ${SIGNATURE_0}" >> $headerfile
+echo "#define SIGNATURE_1 ${SIGNATURE_1}" >> $headerfile
+echo "#define SIGNATURE_2 ${SIGNATURE_2}" >> $headerfile
+echo "" >> $headerfile
+echo "" >> $headerfile
+
+
+
+# Device Pin information
+#---------------------------
+# Only available in AVR Studio 4 XML V1 information. V2 does not have this data.
+echo "/* Device Pin Definitions */" >> $headerfile
+# Get all package types.
+PACKAGE_TYPES=$(xml sel -T -t -v '/AVRPART/PACKAGE/PACKAGES' $devicefile | cut -d '[' -f 2 | cut -d ']' -f 1 | cut -d ':' -f 1- --output-delimiter=' ')
+# Determine which package has the most number of pins.
+PACKAGE_MAX=0
+PACKAGE_SELECTED=
+for i in $PACKAGE_TYPES ; do
+ PACKAGE_SIZE=$(xml sel -T -t -v /AVRPART/PACKAGE/${i}/NMB_PIN $devicefile | sed "s,\r,,g")
+ if test $PACKAGE_SIZE -gt $PACKAGE_MAX ; then
+ PACKAGE_MAX=$PACKAGE_SIZE
+ PACKAGE_SELECTED=$i
+ fi
+done
+# Check to make sure that package information is included in the XML file.
+if test -n $PACKAGE_SELECTED ; then
+ # Get list of pins from selected package, and check each pin.
+ PINS=$(xml sel -T -t -m /AVRPART/PACKAGE/$PACKAGE_SELECTED/* -v "name()" -o ' ' $devicefile | sed "s,\r,,g" | sed "s,NMB_PIN,,g")
+ for i in $PINS ; do
+ TARGET=
+ MAP_LIST=
+
+ # The XML files are inconsistent in their format. Try several options.
+
+ # Check for NAME tag.
+ NAME=$(xml sel -T -t -m /AVRPART/PACKAGE/$PACKAGE_SELECTED/${i}/NAME -v . -o ' ' $devicefile | sed "s,\r,,g")
+ if test $NAME ; then
+ # Get list of mappings. Inside brackets, colon delimited. The first one in the list is the target information.
+ TARGET=$(echo $NAME | cut -d '[' -f 2 | cut -d ']' -f 1 | cut -d ':' -f 1 --output-delimiter=' ')
+ MAP_LIST=$(echo $NAME | cut -d '[' -f 2 | cut -d ']' -f 1 | cut -d ':' -f 2- --output-delimiter=' ')
+ else
+ # Check for PIN_NAME and ALT_NAME tags.
+ PIN_NAME=$(xml sel -T -t -m /AVRPART/PACKAGE/$PACKAGE_SELECTED/${i}/PIN_NAME -v . -o ' ' $devicefile | sed "s,\r,,g")
+ ALT_NAME=$(xml sel -T -t -m /AVRPART/PACKAGE/$PACKAGE_SELECTED/${i}/ALT_NAME -v . -o ' ' $devicefile | sed "s,\r,,g")
+
+ if test -n "$PIN_NAME" -a -n "$ALT_NAME" ; then
+ # Determine which field has the target and which has the mappings.
+ TARGET=$ALT_NAME
+ MAP_LIST=$(echo $PIN_NAME | sed "s,^[*]$,&,")
+ if test -z $MAP_LIST ; then
+ MAP_LIST=$ALT_NAME
+ TARGET=$PIN_NAME
+ fi
+
+ # Get list of mappings. Inside brackets, colon delimited.
+ MAP_LIST=$(echo $MAP_LIST | cut -d '[' -f 2 | cut -d ']' -f 1 | cut -d ':' -f 1- --output-delimiter=' ')
+
+ # Make sure target isn't just a blank character.
+ TARGET=$(echo $TARGET | sed "s, ,,g")
+ fi
+ fi
+
+ if test -n "$TARGET" -a -n "$MAP_LIST" ; then
+ # Make transformations on map list.
+ # Remove active low character signified by single quote
+ # Replace '+' with "_P"
+ # Replace '-' with "_N"
+ MAP_LIST=$(echo $MAP_LIST | sed "s,',,g" | sed "s,+,_P,g" | sed "s,-,_N,g")
+
+ # Remove these pin mappings because they cannot be manipulated by software.
+ for j in TOSC1 TOSC2 PDI PDO TCK TMS TDO TDI AVCC AREF AGND HWB RESET XTAL1 XTAL2 VCC GND NC; do
+ MAP_LIST=$(echo $MAP_LIST | sed "s,${j},,g")
+ done
+
+ TARGET_LETTER=$(echo $TARGET | sed "s,^P,,g" | sed "s,[0-9]$,,g")
+ TARGET_NUMBER=$(echo $TARGET | sed "s,^P[A-Z],,g")
+
+ # Add definitions to map alternate pin names to register definitions.
+ for j in $MAP_LIST ; do
+ echo "#define ${j}_DDR DDR${TARGET_LETTER}" >> $headerfile
+ echo "#define ${j}_PORT PORT${TARGET_LETTER}" >> $headerfile
+ echo "#define ${j}_PIN PIN${TARGET_LETTER}" >> $headerfile
+ echo "#define ${j}_BIT ${TARGET_NUMBER}" >> $headerfile
+ echo "" >> $headerfile
+ done
+ fi
+ done
+fi
+
+
+# End of XMEGA/Classic
+fi
+
+
+# Ending idempotent guard.
+#--------------------------
+echo "#endif /* _AVR_${DEVICE}_H_ */" >> $headerfile
+echo "" >> $headerfile
+
+# Convert to Unix line endings.
+#-------------------------------
+sed -i "s,\r\n,\n,g" $headerfile
+
+
+# Set permissions on the file
+#------------------------------
+chmod 644 $headerfile
+
+
+# I/O Header File and XML Device File Verification
+#--------------------------------------------------
+LOGFILE=$headerfile.log
+# Turn off printing of commands for the verification.
+set +ex
+
+if test -e $LOGFILE ; then
+ rm -f $LOGFILE
+fi
+
+echo Checking for package information in XML file... | tee -a $LOGFILE
+PACKAGE_TYPES=$(xml sel -t -v '/AVRPART/PACKAGE/PACKAGES' $devicefile | cut -d ']' -f 1 | cut -d ':' -f 1- --output-delimiter=' ')
+if test -z "$PACKAGE_TYPES" ; then
+ echo "Package types missing from XML file." | tee -a $LOGFILE
+fi
+echo | tee -a $LOGFILE
+
+echo Checking for misspelled preprocessor directives in header file... | tee -a $LOGFILE
+grep "#" $headerfile | cut -d '#' -f 2 | cut -d ' ' -f 1 | sort | uniq | tee -a $LOGFILE
+echo | tee -a $LOGFILE
+
+echo Checking for duplicate definitions in header file... | tee -a $LOGFILE
+grep "#define" $headerfile | cut -d '#' -f 2 | cut -d ' ' -f 2 | sort | uniq -d | uniq | tee -a $LOGFILE
+echo | tee -a $LOGFILE
+
+echo Checking for hyphens in defined names in header file... | tee -a $LOGFILE
+grep "#define" $headerfile | cut -d '#' -f 2 | cut -d ' ' -f 2 | grep '-' | tee -a $LOGFILE
+echo | tee -a $LOGFILE
+
+echo Checking for hyphens in register and bit names in XML device file... | tee -a $LOGFILE
+echo "$REGS_WITH_HYPHENS" | tee -a $LOGFILE
+echo | tee -a $LOGFILE
+
+echo Checking for invalid signature... | tee -a $LOGFILE
+if test "$SIGNATURE_0" = "0x0" -a "$SIGNATURE_1" = "0x0" -a "$SIGNATURE_2" = "0x0" ; then
+ echo " Invalid signature: ${SIGNATURE_0} ${SIGNATURE_1} ${SIGNATURE_2}" | tee -a $LOGFILE
+fi
+echo | tee -a $LOGFILE
+
+echo Checking for registers that have no associated bit names... | tee -a $LOGFILE
+echo "$REGS_NO_BITNAMES" | tee -a $LOGFILE
+echo | tee -a $LOGFILE
+
+# todo:
+# Properly get all preprocessor directives
+# Check directives against a known dictionary.
diff --git a/xml/patch-headers.py b/xml/patch-headers.py
new file mode 100755
index 00000000..06439779
--- /dev/null
+++ b/xml/patch-headers.py
@@ -0,0 +1,436 @@
+#! /usr/bin/env python
+#
+# Copyright (c) 2005,2006,2007 Joerg Wunsch
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the copyright holders nor the names of
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# $Id$
+#
+
+import os, sys, time, types, re
+
+from types import *
+
+from xml.sax import make_parser
+from xml.sax.handler import ContentHandler
+
+from Descparser import *
+from Atmel2libc import *
+
+home = os.environ['HOME']
+
+xmls = home + "/src/jtagII/xml/Partdescriptionfiles"
+headers = home + "/src/avr-libc/include/avr"
+
+docfilename = "vectortable.dox"
+
+# Mapping between header name and device name. In case of a header
+# name that covers more than one device, the device names form a tuple
+# where the device with the largest feature set is listed as the first
+# one.
+table = {
+ "io1200.h": "AT90S1200",
+ "io2313.h": "AT90S2313",
+ "io2323.h": "AT90S2323",
+ "io2333.h": "AT90S2333",
+ "io2343.h": "AT90S2343",
+ # no XML files
+ #"io43u32x.h": "AT43USB320",
+ #"io43u35x.h": "AT43USB355",
+ "io4414.h": "AT90S4414",
+ "io4433.h": "AT90S4433",
+ "io4434.h": "AT90S4434",
+ # no XML file
+ #"io76c711.h": "AT76C711",
+ "io8515.h": "AT90S8515",
+ # no XML file
+ #"io8534.h": "AT90C8534",
+ "io8535.h": "AT90S8535",
+ "io86r401.h": "AT86RF401",
+ # still no XML file
+ #"io90pwm1.h": "AT90PWM1",
+ "io90pwm216.h": "AT90PWM216",
+ "io90pwm2b.h": "AT90PWM2B",
+ "io90pwm316.h": "AT90PWM316",
+ "io90pwm3b.h": "AT90PWM3B",
+ "io90pwmx.h": ("AT90PWM3", "AT90PWM2", "AT90PWM1"),
+ # no XML file
+ #"ioat94k.h": "AT94k",
+ "iocanxx.h": ("AT90CAN128", "AT90CAN32", "AT90CAN64"),
+ "iom103.h": "ATmega103",
+ "iom128.h": "ATmega128",
+ #"iom1280.h" => "iomxx0_1.h"
+ #"iom1281.h" => "iomxx0_1.h"
+ "iom1284p.h": "ATmega1284P",
+ "iom16.h": "ATmega16",
+ "iom161.h": "ATmega161",
+ "iom162.h": "ATmega162",
+ "iom163.h": "ATmega163",
+ #"iom164.h" => "iomxx4.h"
+ "iom165.h": "ATmega165",
+ "iom165p.h": "ATmega165P",
+ #"iom168.h" => "iomx8.h"
+ "iom168p.h": "ATmega168P",
+ "iom169.h": "ATmega169",
+ "iom169p.h": "ATmega169P",
+ #"iom16hva.h" => "iomxxhva.h"
+ #"iom2560.h" => "iomxx0_1.h"
+ #"iom2561.h" => "iomxx0_1.h"
+ "iom32.h": "ATmega32",
+ "iom323.h": "ATmega323",
+ "iom325.h": "ATmega325",
+ "iom3250.h": ("ATmega3250", "ATmega3250P"),
+ "iom328p.h": "ATmega328P",
+ "iom329.h": "ATmega329",
+ "iom3290.h": ("ATmega3290", "ATmega3290P"),
+ "iom32hvb.h": "ATmega32HVB",
+ "iom406.h": "ATmega406",
+ #"iom48.h" => "iomx8.h"
+ "iom48p.h": "ATmega48P",
+ "iom64.h": "ATmega64",
+ #"iom640.h" => "iomxx0_1.h"
+ #"iom644.h" => "iomxx4.h"
+ "iom645.h": "ATmega645",
+ "iom6450.h": "ATmega6450",
+ "iom649.h": "ATmega649",
+ "iom6490.h": "ATmega6490",
+ "iom8.h": "ATmega8",
+ "iom8515.h": "ATmega8515",
+ "iom8535.h": "ATmega8535",
+ #"iom88.h" => "iomx8.h"
+ "iom88p.h": "ATmega88P",
+ #"iom8hva.h" => "iomxxhva.h"
+ "iomx8.h": ("ATmega168", "ATmega48", "ATmega88"),
+ "iomxx0_1.h": ("ATmega640", "ATmega1280", "ATmega1281", "ATmega2560", "ATmega2561"),
+ "iomxx4.h": ("ATmega324P", "ATmega164P", "ATmega644P", "ATmega644"),
+ # ATmega8HVA XML still missing
+ #"iomxxhva.h": ("ATmega8HVA", "ATmega16HVA"),
+ "iomxxhva.h": ("ATmega16HVA"),
+ "iotn11.h": "ATtiny11",
+ "iotn12.h": "ATtiny12",
+ "iotn13.h": "ATtiny13",
+ "iotn15.h": "ATtiny15",
+ "iotn22.h": "ATtiny22",
+ "iotn2313.h": "ATtiny2313",
+ #"iotn24.h" => "iotnx4.h"
+ #"iotn25.h" => "iotnx5.h"
+ "iotn26.h": "ATtiny26",
+ #"iotn261.h" => "iotnx61.h"
+ "iotn28.h": "ATtiny28",
+ "iotn43u.h": "ATtiny43U",
+ #"iotn44.h" => "iotnx4.h"
+ #"iotn45.h" => "iotnx5.h"
+ #"iotn461.h" => "iotnx61.h"
+ "iotn48.h": "ATtiny48",
+ #"iotn84.h" => "iotnx4.h"
+ #"iotn85.h" => "iotnx5.h"
+ #"iotn861.h" => "iotnx61.h"
+ # No XML file (yet)
+ #"iotn88.h": "ATtiny88",
+ "iotnx4.h": ("ATtiny24", "ATtiny44", "ATtiny84"),
+ "iotnx5.h": ("ATtiny45", "ATtiny25", "ATtiny85"),
+ "iotnx61.h": ("ATtiny261", "ATtiny461", "ATtiny861"),
+ #"iousb1286.h" => "iousbxx6_7.h"
+ #"iousb1287.h" => "iousbxx6_7.h"
+ #"iousb162.h" => "iousbxx2.h"
+ #"iousb646.h" => "iousbxx6_7.h"
+ #"iousb647.h" => "iousbxx6_7.h"
+ #"iousb82.h" => "iousbxx2.h"
+ "iousbxx2.h": ("AT90USB162", "AT90USB82"),
+ "iousbxx6_7.h": ("AT90USB1287", "AT90USB1286", "AT90USB647", "AT90USB646"),
+}
+
+def create_tabs (string):
+ "Create a number of tabs according to the length of string"
+ x = ''
+ lim = (32 - len(string) + 7) / 8
+ if lim <= 0:
+ lim = 1
+ for i in range(0, lim):
+ x += "\t"
+ return x
+
+
+parser = make_parser ()
+
+handler = DescHandler ()
+parser.setContentHandler (handler)
+
+print "Converting XML files:"
+for header in table.keys():
+ try:
+ xmlfile = table[header] + ".xml"
+ basedev = table[header]
+ except TypeError:
+ # in case we've got a tuple of device names
+ xmlfile = table[header][0] + ".xml"
+ basedev = ", ".join(table[header])
+ inputxml = xmls + "/" + xmlfile
+ outputxml = xmlfile
+
+ if os.access(xmlfile, os.F_OK):
+ continue
+
+ sys.stdout.write(basedev + "... ")
+
+ parser1 = Xml2Obj()
+ root = parser1.Parse(inputxml)
+
+ tradheader = HeaderToVec()
+ tradheader.Read(headers + "/" + header)
+
+ savedstdout = sys.stdout
+ sys.stdout = open(outputxml, "w")
+ dump_header (root)
+ dump_memory_sizes (root)
+ dump_vectors (root, tradheader)
+ dump_ioregs (root)
+ dump_boot_info (root)
+ dump_footer (root)
+ sys.stdout.close()
+ sys.stdout = savedstdout
+
+ print "done."
+
+r = re.compile(r'#\s*define\s+((SIG_)?[A-Z0-9_]+(_vect)?)\s+_VECTOR[(](\d+)[)]')
+
+print "Patching headers:"
+docs = {}
+nlist = table.keys()
+nlist.sort()
+for header in nlist:
+ devname = table[header]
+ try:
+ xmlfile = devname + ".xml"
+ basedev = devname
+ except TypeError:
+ # in case we've got a tuple of device names
+ xmlfile = devname[0] + ".xml"
+ basedev = ", ".join(devname)
+ hfile = headers + "/" + header
+
+ sys.stdout.write(basedev + "... ")
+
+ #parser = Xml2Obj()
+ parser.parse (open (xmlfile))
+
+ h = open(hfile)
+ lines = h.readlines()
+ h.close()
+
+ parseddev = parser.getContentHandler().dev
+
+ # Find any interrupt vector definitions, and rewrite them.
+ endcount = len(lines)
+ idx = 0
+ while idx < endcount:
+ line = lines[idx]
+ try:
+ m = r.match(line)
+ except TypeError:
+ print line
+ exit(0)
+ if m != None:
+ firstidx = idx
+ key = m.group(4) # this is the vector number
+ ele = parseddev.interrupts[key]
+
+ if lines[idx - 1].find(ele.description.data) >= 0:
+ # there is a /* description */ comment in the previous line,
+ # drop it
+ if idx - 1 < firstidx:
+ firstidx = idx - 1
+
+ lastidx = idx + 1
+ while r.match(lines[lastidx]) and r.match(lines[lastidx]).group(4) == key:
+ # more vector definitions follow, skip them
+ lastidx += 1
+
+ while re.match('^$', lines[lastidx]):
+ # blank lines follow, skip them, too
+ lastidx += 1
+
+ # Now, lastidx points to the first line not belonging
+ # to our current vector definition. lastidx - firtidx
+ # is the number of lines affected.
+
+ count = lastidx - firstidx
+ del lines[firstidx:lastidx]
+
+ # now, build a new vector entry
+ vecttext = []
+ newcount = 0
+ if len(ele.description.data) > 0:
+ vecttext.append("/* " + ele.description.data + " */\n")
+ newcount += 1
+ vecttext.append("#define " + ele.sig_name.data +
+ create_tabs(ele.sig_name.data) +
+ "_VECTOR(" + key + ")\n")
+ newcount += 1
+ try:
+ for x in ele.alt_name.data:
+ vecttext.append("#define " + x +
+ create_tabs(x) + "_VECTOR(" + key + ")\n")
+ newcount += 1
+ except AttributeError:
+ # no alt_name present
+ pass
+ vecttext.append('\n')
+ newcount += 1
+
+ # insert new vector entry
+ lines[firstidx:firstidx] = vecttext
+
+ endcount += newcount - count
+ # back off beyond what we've just been working on
+ idx = firstidx + newcount
+
+ # collect documentation for this vector
+ try:
+ if type(devname) is TupleType:
+ for d in devname:
+ docs[ele.sig_name.data][2].append(d)
+ else:
+ docs[ele.sig_name.data][2].append(devname)
+ except KeyError:
+ try:
+ if type(devname) is TupleType:
+ docs[ele.sig_name.data] = (ele.alt_name.data,
+ ele.description.data,
+ [])
+ for d in devname:
+ docs[ele.sig_name.data][2].append(d)
+ else:
+ docs[ele.sig_name.data] = (ele.alt_name.data,
+ ele.description.data,
+ [devname])
+ except AttributeError:
+ # no alt name
+ pass
+ else:
+ # no match, increment index
+ idx += 1
+
+ newh = open(header, "w")
+ for line in lines:
+ newh.writelines(line)
+ newh.close()
+ print "done."
+
+# Try to find the name of the person running this script.
+user = 'The avr-libc developer group.'
+if os.name == 'posix':
+ import pwd
+ gecos=pwd.getpwnam(os.getlogin())[4]
+ x = gecos.split(',')[0]
+ if re.match('^[A-Z][a-z]* [A-Z][a-z]*', x):
+ # if at least two capitalized words are present, trust that
+ user = x
+
+sys.stdout.write("Writing documentation to " + docfilename + "... ")
+savedstdout = sys.stdout
+sys.stdout = open(docfilename, "w")
+
+print """/* Note: this file has been automatically generated. */
+/* DO NOT EDIT, or your changes WILL BE LOST! */
+
+/* Copyright (c) %d %s
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+""" % (time.localtime()[0], user)
+
+# avoid CVS munging with this here in the script
+print '/* $Id' + '$ */\n'
+
+print '''
+/** \\addtogroup avr_interrupts
+
+@{
+
+\\anchor avr_signames
+<small>
+<table>
+ <tr>
+ <th width="15%">Vector Name</th>
+ <th width="15%">Deprecated</th>
+ <th width="20%">Description</th>
+ <th width="50%">Applicable for Device</th>
+ </tr>'''
+
+vecs = docs.keys()
+vecs.sort()
+for vecname in vecs:
+ x = docs[vecname]
+ nlines = len(x[2])
+ print ' <tr>'
+ print ' <td>' + vecname + '</td>'
+ try:
+ print ' <td>' + x[0] + '</td>'
+ except TypeError:
+ print ' <td>' + ', '.join(x[0]) + '</td>'
+ print ' <td>' + x[1] + '</td>'
+ print ' <td>' + ', '.join(x[2]) + '</td>'
+ print ' </tr>'
+
+print """</table>
+</small>
+
+@}*/
+"""
+
+sys.stdout.close()
+sys.stdout = savedstdout
+
+print "done."
--
2.43.0