diff --git a/boards/LICENSE b/boards/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..f99be76ab3d5259224b83f13e6a3fae0287eabe4
--- /dev/null
+++ b/boards/LICENSE
@@ -0,0 +1,454 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
diff --git a/boards/Makefile b/boards/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..7a3c9d345b5d49f74d5e989363073f64cdc5b11c
--- /dev/null
+++ b/boards/Makefile
@@ -0,0 +1,5 @@
+all:
+	"$(MAKE)" -C $(BOARD)
+
+clean:
+	"$(MAKE)" -C $(BOARD) clean
diff --git a/boards/Makefile.base b/boards/Makefile.base
new file mode 100644
index 0000000000000000000000000000000000000000..0b860294f92223e0dcab82095c26972c7b4a00e1
--- /dev/null
+++ b/boards/Makefile.base
@@ -0,0 +1,30 @@
+ifeq ($(BOARD),msba2)
+ INCLUDES += -I$(RIOTBOARD)/msba2/include/
+ INCLUDES += -I$(RIOTBOARD)/msba2-common/include/
+ INCLUDES += -I$(RIOTBOARD)/msba2-common/drivers/include/
+endif
+ifeq ($(BOARD),msb-430)
+ INCLUDES += -I$(RIOTBOARD)/msb-430/include/
+ INCLUDES += -I$(RIOTBOARD)/msb-430-common/include/
+ INCLUDES += -I$(RIOTBOARD)/msb-430-common/drivers/include/
+endif
+ifeq ($(BOARD),msb-430h)
+ INCLUDES += -I$(RIOTBOARD)/msb-430h/include/
+ INCLUDES += -I$(RIOTBOARD)/msb-430-common/include/
+ INCLUDES += -I$(RIOTBOARD)/msb-430-common/drivers/include/
+endif
+ifeq ($(BOARD),wsn430-v1_3b)
+ INCLUDES += -I$(RIOTBOARD)/wsn430-v1_3b/include/
+ INCLUDES += -I$(RIOTBOARD)/wsn430-common/include/
+endif
+ifeq ($(BOARD),wsn430-v1_4)
+ INCLUDES += -I$(RIOTBOARD)/wsn430-v1_4/include/
+ INCLUDES += -I$(RIOTBOARD)/wsn430-common/include/
+endif
+ifeq ($(BOARD),chronos)
+ INCLUDES += -I$(RIOTBOARD)/chronos/include/
+ INCLUDES += -I$(RIOTBOARD)/chronos/drivers/include/
+endif
+ifeq ($(BOARD),native)
+ INCLUDES += -I$(RIOTBOARD)/native/include/
+endif
diff --git a/boards/README.md b/boards/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..cda1a563ead96ac3287e3a2e77f8ba9e61d40528
--- /dev/null
+++ b/boards/README.md
@@ -0,0 +1,6 @@
+Platform configurations for RIOT-OS
+====================================
+This repository contains existing configuration and initialization files for platforms supported by RIOT-OS.
+
+RIOT's kernel, system libraries, and drivers can be found here:
+https://github.com/RIOT-OS/RIOT
diff --git a/boards/avsextrem/Makefile b/boards/avsextrem/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3597e18c735c0d7e314ddde169b283e9e6ba2ffa
--- /dev/null
+++ b/boards/avsextrem/Makefile
@@ -0,0 +1,38 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+export ARCH = avsextrem_base.a
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBOARD)/msba2-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/arm_common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/lpc2387/include/
+INCLUDES += -I$(RIOTBASE)/drivers/cc110x
+
+all: $(BINDIR)$(ARCH)
+	"$(MAKE)" -C ../msba2-common
+	"$(MAKE)" -C drivers
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	mkdir -p $(BINDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	"$(MAKE)" -C ../msba2-common clean
+	"$(MAKE)" -C drivers clean
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	@if [ -d $(BINDIR) ] ; \
+	then rmdir $(BINDIR) ; \
+	fi
+
diff --git a/boards/avsextrem/Makefile.include b/boards/avsextrem/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..741b952a92424157d0623685e826be5a976f8da8
--- /dev/null
+++ b/boards/avsextrem/Makefile.include
@@ -0,0 +1,3 @@
+export INCLUDES += -I$(RIOTBOARD)/msba2-common/include
+
+include $(RIOTBOARD)/msba2-common/Makefile.include
diff --git a/boards/avsextrem/board_init.c b/boards/avsextrem/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..419198da9ad4a95a1c2e1894f675afd5078a0b50
--- /dev/null
+++ b/boards/avsextrem/board_init.c
@@ -0,0 +1,202 @@
+/*
+* board_init.c - initialization of the AVSEXTREM-BOARD.
+* Copyright (C) 2013 Heiko Will <hwill@inf.fu-berlin.de>
+*
+* This source code is licensed under the LGPLv2 license,
+* See the file LICENSE for more details.
+*
+*/
+
+
+/**
+ * @file
+ * @brief       avsextrem board initialization
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      Heiko Will
+ * @author      Kaspar Schleise
+ * @author      Michael Baar
+ * @author      Zakaria Kasmi
+ * @author      Marco Ziegert
+ * @author      Stefan Pfeiffer
+ *
+ * @note        $Id: board_init.c 1071 2013-09-19 16:50:56 kasmi $
+ */
+#include "lpc23xx.h"
+#include "VIC.h"
+#include "cpu.h"
+#include "gpioint.h"
+
+#define PCRTC         BIT9
+#define CL_CPU_DIV    4
+
+
+/*---------------------------------------------------------------------------*/
+static inline void
+pllfeed(void)
+{
+    PLLFEED = 0xAA;
+    PLLFEED = 0x55;
+}
+
+/*---------------------------------------------------------------------------*/
+void init_clks1(void)
+{
+    // Disconnect PLL
+    PLLCON &= ~0x0002;
+    pllfeed();
+
+    while (PLLSTAT & BIT25);  /* wait until PLL is disconnected before
+                               * disabling - deadlock otherwise */
+
+    // Disable PLL
+    PLLCON &= ~0x0001;
+    pllfeed();
+
+    while (PLLSTAT & BIT24); // wait until PLL is disabled
+
+    SCS |= 0x10;    // main OSC between 15MHz and 24MHz (more stable in tests)
+    SCS |= 0x20;     // Enable main OSC
+
+    while (!(SCS & 0x40));   // Wait until main OSC is usable
+
+    /* select main OSC, 16MHz, as the PLL clock source */
+    CLKSRCSEL = 0x0001;
+
+    // Setting Multiplier and Divider values
+    PLLCFG = 0x0008;	      // M=9 N=1 Fcco = 288 MHz
+    pllfeed();
+
+    // Enabling the PLL */
+    PLLCON = 0x0001;
+    pllfeed();
+
+    /* Set clock divider to 4 (value+1) */
+    CCLKCFG = CL_CPU_DIV - 1; // Fcpu = 72 MHz
+
+#if USE_USB
+    USBCLKCFG = USBCLKDivValue;	/* usbclk = 288 MHz/6 = 48 MHz */
+#endif
+}
+
+/*---------------------------------------------------------------------------*/
+void bl_init_ports(void)
+{
+    SCS |= BIT0;              // Set IO Ports to fast switching mode
+
+    /* UART0 */
+    PINSEL0 |= BIT4 + BIT6;   // RxD0 and TxD0
+    PINSEL0 &= ~(BIT5 + BIT7);
+
+    //PTTU:
+
+    /*Turn Board on*/
+    //	PINMODE0 |= BIT1;
+    //	FIO0DIR |= BIT27;
+    //	FIO0CLR = BIT27;
+    //	0.27
+
+    /* 5V*/
+    //	FIO1DIR |= BIT28; // Synch
+    //	FIO1SET = BIT28;  // No Powersave
+    //	1.28
+
+    //	FIO1DIR |= BIT27; // 5V off
+    //	FIO1CLR = BIT27;
+    //	1.27
+
+    /* Disable Resistors on Buttons */
+    //	PINMODE4 |= BIT9 + BIT11;
+    //
+
+    /* Disable Resistors on LED - and Ports to output*/
+    PINMODE7 |= BIT19 + BIT21; //3.25 + 3.26
+    PINMODE2 |= BIT1;	       //1.0
+    FIO1DIR |= BIT0;
+    FIO3DIR |= BIT25 + BIT26;
+    FIO1SET = BIT0;	       //all off
+    FIO3SET = BIT25 + BIT26;
+
+    // Config and Disable PA
+    //	FIO1DIR |= BIT25 + BIT26 + BIT22;
+    //	FIO1SET = BIT26;
+    //	FIO1CLR = BIT25;
+    //	FIO1CLR = BIT22;  // PA /Shutdown
+    // Important: First put this Port as DA 2.0V and then turn on PA!!
+    //	FIO0DIR |= BIT26;
+    //	FIO0SET = BIT26;
+    //	1.22 + 1.25 + 1.26
+
+    // Configure GPS
+    PINMODE3 |= BIT3 + BIT7;   // No Pullup on 1.17 & 1.19
+    PINMODE9 |= BIT27 + BIT25; // No Pullup for Uart
+    FIO1DIR |= BIT17;
+    FIO1CLR = BIT17;           // Turn off GPS
+    FIO1DIR |= BIT19;
+    FIO1CLR = BIT19;           // Hold in Reset
+    PINSEL9 |= BIT24 + BIT25 + BIT26 + BIT27; //4.28 & 4.29 as Uart3
+
+    // Nanotron
+    FIO2DIR &= ~BIT8;	// nanotron uC IRQ as input
+    FIO1DIR |= BIT15;	// nanotron power on reset
+    FIO1DIR &= ~BIT14;	// nanotron uC RESET as input
+    FIO1DIR &= ~BIT10;	// nanotron uC Vcc as input
+    FIO1DIR |= BIT9;	// nanotron ENABLE as output
+    FIO1DIR &= ~BIT4;	// nanotron Rx/Tx as input
+
+    FIO1CLR = BIT15;
+    FIO1CLR = BIT9;	// Enable power
+
+    PINMODE1 |= BIT1;   // No Pullup for CS
+    FIO0DIR |= BIT16;   // CS as output
+    FIO0SET = BIT16;	// drive cs inactive
+    FIO0DIR |= BIT18 + BIT15;   // SPi Output
+
+    // RFID
+    //	FIO1DIR |= BIT1;    // RFID Power
+    //	FIO1CLR = BIT1;
+    //
+    //	FIO0DIR |= BIT1;    // RFID Reset
+    //	FIO0SET = BIT1;     // Hold in Reset
+    //
+    //	FIO0DIR &= ~BIT10;  // LED as INPUT
+    //	FIO0DIR &= ~BIT11;  // DATA as INPUT
+    //	PINMODE0 |= BIT19 + BIT21; // No Pullups
+    //	1.1 + 0.1 + 0.10 + 0.11
+
+    // LTC4150 ARM
+    FIO0DIR |= BIT5;
+    FIO0CLR = BIT5;
+
+    // LTC4150 System
+    //	FIO0DIR |= BIT24;
+    //	FIO0CLR = BIT24;
+    //	0.23 + 0.24
+
+    // Battery Voltage (AD)
+    PINMODE1 |= BIT19;	      //0.25
+    PINSEL1 &= ~BIT19;
+    PINSEL1 |= BIT18;
+
+    //cc1100
+    FIO0DIR |= BIT6 + BIT7 + BIT9;
+    FIO0SET = BIT6;
+    FIO0SET = BIT7 + BIT9;
+
+    //SMB380
+    FIO1DIR |= BIT20 + BIT21 + BIT24; //SCK + CSB + SDI
+    FIO1SET = BIT21;
+    FIO1SET = BIT20 + 24;
+
+    //SHT11
+    FIO1DIR |= BIT25;		     //1.25
+    PINSEL3 &= ~(BIT12 | BIT13 | BIT18 | BIT19);
+
+    //SD
+    FIO0DIR &= ~(BIT19 | BIT20 | BIT21 | BIT22) ; //0.19 0.20 0.21 0.22 as input
+    PINMODE1 |= (BIT7) | (BIT9) | (BIT11) | (BIT13); // no resistors
+    FIO2DIR &= ~(BIT11 + BIT12 + BIT13); //2.11 2.12 2.13 as input
+    PINMODE4 |= (BIT23) | (BIT25) | (BIT27); // no resistors
+
+}
+
diff --git a/boards/avsextrem/drivers/Makefile b/boards/avsextrem/drivers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..71736befcce42345865842285e74dc3c77272574
--- /dev/null
+++ b/boards/avsextrem/drivers/Makefile
@@ -0,0 +1,24 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBASE)/sys/include/ -I$(RIOTBASE)/drivers/cc110x_ng/include/ -I$(RIOTBOARD)/$(BOARD)/include
+
+$(BINDIR)avsextrem_base.a: $(OBJ)
+	$(AR) rcs $(BINDIR)${ARCH} $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+
+clean:
+	rm -f $(BINDIR)$(MODULE).a $(OBJ) $(DEP) $(ASMOBJ)
+
diff --git a/boards/avsextrem/drivers/avsextrem-cc1100.c b/boards/avsextrem/drivers/avsextrem-cc1100.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee83ebbd900683443a30f3ef1b9f6c4c3758feae
--- /dev/null
+++ b/boards/avsextrem/drivers/avsextrem-cc1100.c
@@ -0,0 +1,257 @@
+/*
+* avsextrem-cc1100.c - CC100 Transceiver Driver for the AVSEXTREM-BOARD.
+* Copyright (C) 2013 Heiko Will <hwill@inf.fu-berlin.de>
+*
+* This source code is licensed under the LGPLv2 license,
+* See the file LICENSE for more details.
+*
+*/
+
+
+/**
+ * @file
+ * @ingroup	LPC2387
+ * @brief	CC1100 LPC2387 dependend functions
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      Heiko Will <hwill@inf.fu-berlin.de>
+ * @author      Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ *
+ * @version     $Revision: 1781 $
+ *
+ * @note        $Id: avsextrem-cc1100.c 1781 2013-08-14 13:39:36Z kasmi $
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+// cpu
+#include "cpu.h"
+// sys
+#include "cc1100.h"
+#include "arch_cc1100.h"
+#include "cc1100_spi.h"
+#include "gpioint.h"
+
+#define CC1100_GDO0   (FIO2PIN & BIT6)  // read serial I/O (GDO0)
+#define CC1100_GDO1   (FIO0PIN & BIT8)  // read serial I/O (GDO1)
+#define CC1100_GDO2   (FIO0PIN & BIT28)	// read serial I/O (GDO2)
+
+#define SPI_TX_EMPTY  (SSP1SR & SSPSR_TFE)
+#define SPI_BUSY      (SSP1SR & SSPSR_BSY)
+#define SPI_RX_AVAIL  (SSP1SR & SSPSR_RNE)
+
+#define CC1100_GDO1_LOW_RETRY   (100)   // max. retries for GDO1 to go low
+#define CC1100_GDO1_LOW_COUNT   (2700)  // loop count (timeout ~ 500 us) to wait
+// for GDO1 to go low when CS low
+
+//#define DEBUG
+#ifdef DEBUG
+
+#include "stdio.h"
+
+static unsigned long time_value;
+
+static void set_time(void)
+{
+    time_value = 0;
+}
+
+static int test_time(int code)
+{
+    time_value++;
+
+    if (time_value > 10000000) {
+        printf("CC1100 SPI alarm: %u!\n", code);
+        time_value = 0;
+        return 1;
+    }
+
+    return 0;
+}
+#endif
+
+int cc1100_get_gdo0(void)
+{
+    return CC1100_GDO0;
+}
+
+int cc1100_get_gdo1(void)
+{
+    return CC1100_GDO1;
+}
+
+int cc1100_get_gdo2(void)
+{
+    return CC1100_GDO2;
+}
+
+void cc1100_spi_init(void)
+{
+    // configure chip-select
+    FIO0DIR |= BIT6;
+    FIO0SET = BIT6;
+
+    // Power
+    PCONP |= PCSSP1;    // Enable power for SSP1 (default is on)
+
+    // PIN Setup
+    PINSEL0 |= BIT15;   // Set CLK function to SSP1
+    PINSEL0 &= ~BIT14;
+    PINSEL0 |= BIT17 ;  // Set MISO function to SSP1
+    PINSEL0 &= ~BIT16;
+    PINSEL0 |= BIT19;   // Set MOSI function to SSP1
+    PINSEL0 &= ~BIT18;
+    // Interface Setup
+    SSP1CR0 = 7;
+
+    // Clock Setup
+    uint32_t pclksel;
+    uint32_t cpsr;
+    lpc2387_pclk_scale(F_CPU / 1000, 6000, &pclksel, &cpsr);
+    PCLKSEL0 &= ~(BIT21 | BIT20);   // CCLK to PCLK divider
+    PCLKSEL0 |= pclksel << 20;
+    SSP1CPSR = cpsr;
+
+    // Enable
+    SSP1CR1 |= BIT1;    // SSP-Enable
+    int dummy;
+
+    // Clear RxFIFO:
+    while (SPI_RX_AVAIL) {   // while RNE (Receive FIFO Not Empty)...
+        dummy = SSP1DR;	     // read data
+    }
+}
+
+uint8_t
+cc1100_txrx(uint8_t c)
+{
+    uint8_t result;
+    SSP1DR = c;
+#ifdef DEBUG
+    set_time();
+#endif
+
+    while (!SPI_TX_EMPTY) {
+#ifdef DEBUG
+        test_time(0);
+#endif
+    }
+
+#ifdef DEBUG
+    set_time();
+#endif
+
+    while (SPI_BUSY) {
+#ifdef DEBUG
+        test_time(1);
+#endif
+    }
+
+#ifdef DEBUG
+    set_time();
+#endif
+
+    while (!SPI_RX_AVAIL) {
+#ifdef DEBUG
+        test_time(2);
+#endif
+    }
+
+    result = (uint8_t)SSP1DR;
+    return result;
+}
+
+void cc1100_spi_cs(void)
+{
+    FIO0CLR = BIT6;
+}
+
+void
+cc1100_spi_select(void)
+{
+    volatile int retry_count = 0;
+    volatile int abort_count;
+    // Switch to GDO mode input
+    PINSEL0 &= ~(BIT17 + BIT16);   // Set MISO function to GPIO
+    FIO0DIR &= ~BIT8;
+cs_low:
+    // CS to low
+    abort_count = 0;
+    FIO0CLR = BIT6;
+    // Wait for SO to go low (voltage regulator
+    // has stabilized and the crystal is running)
+loop:
+    asm volatile("nop");
+
+    if (CC1100_GDO1) {
+        abort_count++;
+
+        if (abort_count > CC1100_GDO1_LOW_COUNT) {
+            retry_count++;
+
+            if (retry_count > CC1100_GDO1_LOW_RETRY) {
+                puts("[CC1100 SPI] fatal error\n");
+                goto final;
+            }
+
+            FIO0SET = BIT6;   // CS to high
+            goto cs_low;      // try again
+        }
+
+        goto loop;
+    }
+
+final:
+    // Switch to SPI mode
+    PINSEL0 |= BIT17;   // Set MISO function to SSP1
+    PINSEL0 &= ~BIT16;
+}
+
+void
+cc1100_spi_unselect(void)
+{
+    FIO0SET = BIT6;
+}
+
+void cc1100_gdo2_disable(void)
+{
+    gpioint_set(0, BIT28, GPIOINT_DISABLE, NULL);
+}
+
+void cc1100_gdo2_enable(void)
+{
+    gpioint_set(0, BIT28, GPIOINT_FALLING_EDGE, &cc1100_gdo2_irq);
+}
+
+void cc1100_before_send(void)
+{
+    // Disable GDO2 interrupt before sending packet
+    cc1100_gdo2_disable();
+}
+
+void cc1100_after_send(void)
+{
+    // Enable GDO2 interrupt after sending packet
+    cc1100_gdo2_enable();
+}
+
+void cc1100_gdo0_enable(void)
+{
+    gpioint_set(2, BIT6, GPIOINT_RISING_EDGE, &cc1100_gdo0_irq);
+}
+
+void cc1100_gdo0_disable(void)
+{
+    gpioint_set(2, BIT6, GPIOINT_DISABLE, NULL);
+}
+
+void cc1100_init_interrupts(void)
+{
+    // Enable external interrupt on low edge (for GDO2)
+    FIO0DIR &= ~BIT28;
+    cc1100_gdo2_enable();
+    // Enable external interrupt on low edge (for GDO0)
+    FIO2DIR &= ~BIT6;
+}
+
diff --git a/boards/avsextrem/drivers/avsextrem-smb380.c b/boards/avsextrem/drivers/avsextrem-smb380.c
new file mode 100644
index 0000000000000000000000000000000000000000..5cc084f73d29e78b0ddcfc1f82bac244220e5c04
--- /dev/null
+++ b/boards/avsextrem/drivers/avsextrem-smb380.c
@@ -0,0 +1,1338 @@
+/*
+ * msba2acc-smb380.c - implementation of the Driver for the SMB380 acceleration
+ * sensor on the AVSEXTREM board.
+ * Copyright (C) 2013 Freie Universität Berlin
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ *
+ */
+
+/**
+ * @file
+ * @internal
+ * @brief       SMB380 acceleration sensor driver for the LPC2387 on the
+ *              AVSEXTREM board.
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      Marco Ziegert <ziegert@inf.fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @version     $Revision: 3854 $
+ *
+ * @note        $Id:  msba2acc-smb380.c 3854 2010-01-18 15:27:01Z zkasmi $
+ */
+
+
+#include "lpc23xx.h"   /* LPC23XX/24xx Peripheral Registers */
+#include "cpu.h"
+#include "lpm.h"
+//#include "PatrecInit.h"
+#include "VIC.h"
+#include "kernel.h"
+#include "ssp0-board.h"
+#include "smb380-board.h"
+#include "hwtimer.h"
+#include <stdio.h>
+#include <malloc.h>
+// for fk_thread:
+#include "sched.h"
+#include "msg.h"
+#include "irq.h"
+
+//#include "hal-board.h"
+#include "gpioint.h"
+#include "stdlib.h"
+#include "math.h"
+#include "lpc2387.h"
+
+
+uint8_t simple_pid;
+int16_t simple_buffer[4];
+
+volatile int16_t *ringBuff_X = NULL;
+volatile int16_t *ringBuff_Y = NULL;
+volatile int16_t *ringBuff_Z = NULL;
+volatile int16_t *ringBuff_T = NULL;
+uint16_t readPointerPos[SMB380_RING_BUFF_MAX_THREADS];
+u_char PointerList[SMB380_RING_BUFF_MAX_THREADS];
+static msg_t wakeupmessage;
+
+/*
+ * pointer to a user-defined function which is called during a writepointer
+ * action
+ */
+uint8_t (*smb380function)(int16_t *);
+uint16_t sampleRateSMB380;  // condition if range-check should be done
+bool dynRange = false;
+uint8_t counter_Decreasing = 0;
+
+volatile uint16_t interruptTicksSMB380;
+
+typedef struct {
+    u_int writePointerPos;  //Writepointer position
+    /*
+     * check value for updated range settings (only needed for multiplication
+     * in Float-mode
+     */
+    uint8_t countRange;
+    uint8_t range;	    //current range
+} settingsSMB380;
+
+settingsSMB380 settings;
+
+// measuring temperature dependent internal sample rate of SMB380
+static volatile uint32_t tickStart = 0;
+static volatile uint32_t tickLastSample = 0;
+static volatile uint32_t tickCurrentSamples = 0;
+
+uint8_t initRingReadPointerforCurrentThread(void);
+uint8_t getRingReadPointerforCurrentThread(void);
+void wakeUpRegisteredProcesses(void);
+uint8_t smb380emptyfunction(int16_t *);
+static void SMB380_extIntHandler(void);
+
+extern unsigned long ktimer_now(void);
+
+float SMB380_getSampleRatio(void)
+{
+    return ((1.0 / ((float)(tickLastSample - tickStart) / tickCurrentSamples)) *
+            100000);
+}
+
+uint8_t smb380emptyfunction(int16_t *value)
+{
+    return 1;
+}
+
+uint8_t SMB380_HystereseFunctionSample(int16_t *value)
+{
+    static int16_t x = 0, y = 0, z = 0;
+    static uint8_t counter = 0;
+    int16_t delta = abs(value[0] - x) + abs(value[1] - y) + abs(value[2] - z);
+
+    if (delta < 40) { //TODO: delta and counter are constant values, change it!
+        counter++;
+    }
+    else {
+        counter = 0;
+    }
+
+    x = value[0];
+    y = value[1];
+    z = value[2];
+
+    if (smb380_mode == SMB380_THRESHOLD) {
+        SMB380_disableAnyMotionLimit();
+        SMB380_enableNewDataInt();
+        smb380_mode = SMB380_CONTINOUS;
+        printf("Threshold: x=%i, y=%i, z=%i\n\r", value[0], value[1], value[2]);
+    }
+
+    if ((counter == 100) && (smb380_mode == SMB380_POLL)) {
+        //MZ SMB380_disableNewDataInt();
+        //SMB380_setAnyMotionLimit(100,0);
+        SMB380_enableAnyMotionLimit();
+        smb380_mode = SMB380_THRESHOLD;
+        counter = 0;
+    }
+    else if (counter == 100) {
+        SMB380_disableNewDataInt();
+        //SMB380_setAnyMotionLimit(100,0);
+        SMB380_enableAnyMotionLimit();
+        smb380_mode = SMB380_FALSEALERT;
+        counter = 0;
+        return 0;
+    }
+
+
+    return 1;
+}
+
+static void SMB380_simple_interrupthandler(void)
+{
+    lpm_awake();
+
+    SMB380_getAcceleration(SMB380_X_AXIS, NULL, &simple_buffer[0]);
+    SMB380_getAcceleration(SMB380_Y_AXIS, NULL, &simple_buffer[1]);
+    SMB380_getAcceleration(SMB380_Z_AXIS, NULL, &simple_buffer[2]);
+    simple_buffer[3] = SMB380_getTemperature();
+
+    if (interruptTicksSMB380 >= sampleRateSMB380 - 1) {
+        interruptTicksSMB380 = 0;
+        wakeupmessage.type = MSG_TYPE_SMB380_WAKEUP;
+        msg_send(&wakeupmessage, simple_pid, 0);
+    }
+    else {
+        interruptTicksSMB380++;
+    }
+
+    return;
+}
+
+// enables simple Interrupt driven Mode
+uint8_t SMB380_init_simple(uint16_t samplerate, uint8_t bandwidth, uint8_t
+                           range)
+{
+    SSP0Init();
+    interruptTicksSMB380 = 0;
+    simple_pid = active_thread->pid;
+    gpioint_set(0, BIT1, GPIOINT_RISING_EDGE, &SMB380_simple_interrupthandler);
+    SMB380_softReset();
+    hwtimer_wait(HWTIMER_TICKS(100000));
+    SMB380_disableUpperLimit();
+    SMB380_disableLowerLimit();
+    SMB380_setSampleRate(samplerate);
+    SMB380_setBandWidth(bandwidth);
+    SMB380_setRange(range);
+
+    return 0;
+}
+
+uint8_t SMB380_init(uint8_t (*func)(int16_t *))
+{
+    SSP0Init();
+
+#if SMB380_EXTINT_MODE
+
+    if (gpioint_set(0, BIT1, GPIOINT_RISING_EDGE, &SMB380_extIntHandler));
+
+#endif
+
+    interruptTicksSMB380 = 0;
+
+    if (func != NULL) {
+        smb380function = func;
+    }
+    else {
+        smb380function = smb380emptyfunction;
+    }
+
+    //smb380function = SMB380_HystereseFunctionSample;	//placeholder
+
+    SMB380_softReset();
+    hwtimer_wait(HWTIMER_TICKS(100000));
+    SMB380_disableUpperLimit();
+    SMB380_disableLowerLimit();
+
+    smb380_mode = SMB380_POLL;
+    SMB380_setSampleRate(SMB380_SAMPLE_RATE_MAX);  //set output to 3000 Hz
+
+    settings.writePointerPos = 0;
+    settings.range = 0;
+    settings.countRange = 0;
+
+    for (int i = 0; i < SMB380_RING_BUFF_MAX_THREADS; i++) {
+        readPointerPos[i] = 0;
+        PointerList[i] = 0;
+    }
+
+    ringBuff_X = (int16_t *)malloc(SMB380_RING_BUFF_SIZE * sizeof(int16_t));
+    ringBuff_Y = (int16_t *)malloc(SMB380_RING_BUFF_SIZE * sizeof(int16_t));
+    ringBuff_Z = (int16_t *)malloc(SMB380_RING_BUFF_SIZE * sizeof(int16_t));
+    ringBuff_T = (int16_t *)malloc(SMB380_RING_BUFF_SIZE * sizeof(int16_t));
+
+    if ((ringBuff_X == NULL) | (ringBuff_Y == NULL) | (ringBuff_Z == NULL) |
+        (ringBuff_T == NULL)) {
+        if (ringBuff_X != NULL) {
+            free((int16_t *)ringBuff_X);
+        }
+
+        if (ringBuff_Y != NULL) {
+            free((int16_t *)ringBuff_Y);
+        }
+
+        if (ringBuff_Z != NULL) {
+            free((int16_t *)ringBuff_Z);
+        }
+
+        if (ringBuff_T != NULL) {
+            free((int16_t *)ringBuff_T);
+        }
+
+        return 0;
+    }
+
+    return 1;
+}
+
+static void SMB380_extIntHandler(void)
+{
+    int16_t accInt[4];
+
+    lpm_awake(); //initializes clock
+
+    SMB380_getAcceleration(SMB380_X_AXIS, NULL, &accInt[0]);
+    SMB380_getAcceleration(SMB380_Y_AXIS, NULL, &accInt[1]);
+    SMB380_getAcceleration(SMB380_Z_AXIS, NULL, &accInt[2]);
+    accInt[3] = SMB380_getTemperature();
+
+
+    writeRingBuff(accInt);
+
+    //	printf("SMB380 acc x,y,z: [%i|%i|%i|%2.3f]\r\n", accInt[0], accInt[1],
+    //         accInt[2], acc[3]);
+    //	printf("SMB380 acc x,y,z: [%2.3f|%2.3f|%2.3f|%2.3f]\r\n\n\n", acc[0],
+    //         acc[1], acc[2], acc[3]);
+    //	printf("Nach Interrupt Reset:\n");
+    //	SMB380_ShowMemory();
+}
+
+void SMB380_setSampleRate(uint16_t rate)
+{
+    if (rate > 0 && rate <= SMB380_SAMPLE_RATE_MAX) {
+        sampleRateSMB380 = SMB380_SAMPLE_RATE_MAX / rate;
+    }
+    else {
+        sampleRateSMB380 = 1;
+    }
+}
+
+uint16_t SMB380_getSampleRate(void)
+{
+    return SMB380_SAMPLE_RATE_MAX / sampleRateSMB380;
+}
+
+uint8_t SMB380_Prepare(void)
+{
+    return SSP0Prepare(SMB380_ACC, 16, 1, 1, 8000);
+}
+
+uint8_t SMB380_Unprepare(void)
+{
+    return SSP0Unprepare(SMB380_ACC);
+}
+
+// return the pointerNo related with the current thread
+uint8_t getRingReadPointerforCurrentThread(void)
+{
+    uint8_t pointerNo = 0;
+
+    while ((PointerList[pointerNo] != active_thread->pid) &&
+           (pointerNo < SMB380_RING_BUFF_MAX_THREADS)) {
+        pointerNo++;
+    }
+
+    return pointerNo;
+}
+
+uint8_t initRingReadPointerforCurrentThread(void)
+{
+    //TODO: make it Threadsafe
+    uint8_t pointerNo = 0;
+
+    while ((PointerList[pointerNo] > 0) &&
+           (pointerNo < SMB380_RING_BUFF_MAX_THREADS)) {
+        pointerNo++;
+    }
+
+    if (pointerNo == SMB380_RING_BUFF_MAX_THREADS) {
+        return 0;
+    }
+    else {
+        PointerList[pointerNo] = active_thread->pid;
+        readPointerPos[pointerNo] = settings.writePointerPos;
+        return 1;
+    }
+}
+
+void freeRingReadPointer(void)
+{
+    //Should be Threadsafe
+    uint8_t pointerNo = getRingReadPointerforCurrentThread();
+
+    if (pointerNo != SMB380_RING_BUFF_MAX_THREADS) {
+        PointerList[pointerNo] = 0;
+    }
+}
+
+void actualizeRingReadPointer(void)
+{
+    uint8_t pointerNo = getRingReadPointerforCurrentThread();
+
+    if (pointerNo != SMB380_RING_BUFF_MAX_THREADS) {
+        readPointerPos[pointerNo] = settings.writePointerPos;
+    }
+}
+
+//TODO: more read-pointer
+uint8_t readRingBuff(int16_t *value)
+{
+
+    uint8_t pointerNo = getRingReadPointerforCurrentThread();
+
+    /*
+     * If thread is not known to read on the ringbuffer, try adding him to the
+     * list of known threads, otherwise exit with error
+     */
+
+    if (pointerNo == SMB380_RING_BUFF_MAX_THREADS) {
+        if (!initRingReadPointerforCurrentThread()) {
+            //printf("%sNo Readpointer left, maximum of %u is reached!\n\r",
+            //       SMB380_DEBUG_MESSAGE, SMB380_RING_BUFF_MAX_THREADS);
+            return 0;
+        }
+        else {
+            pointerNo = getRingReadPointerforCurrentThread();
+        }
+    }
+
+    if (readPointerPos[pointerNo] == settings.writePointerPos) {
+        value[0] = 0;
+        value[1] = 0;
+        value[2] = 0;
+        value[3] = 0;
+        return 0;
+    }
+
+    value[0] = ringBuff_X[readPointerPos[pointerNo]];
+    value[1] = ringBuff_Y[readPointerPos[pointerNo]];
+    value[2] = ringBuff_Z[readPointerPos[pointerNo]];
+    value[3] = ringBuff_T[readPointerPos[pointerNo]];
+    readPointerPos[pointerNo] += 1;
+
+    if (readPointerPos[pointerNo] == SMB380_RING_BUFF_SIZE) {
+        readPointerPos[pointerNo] = 0;
+    }
+
+    return 1;
+}
+
+//TODO: more read-pointer
+uint8_t writeRingBuff(int16_t *value)
+{
+    if (smb380_mode == SMB380_FALSEALERT)	{
+        smb380_mode = SMB380_THRESHOLD;
+        return 0;
+    }
+
+    if ((interruptTicksSMB380 >= sampleRateSMB380 - 1) ||
+        (smb380_mode == SMB380_THRESHOLD)) {
+        interruptTicksSMB380 = 0;
+
+        /* measuring temperature dependent internal sample rate of SMB380 */
+        if (smb380_mode == SMB380_CONTINOUS) {
+            tickLastSample = ktimer_now();
+            tickCurrentSamples++;
+        }
+
+        ringBuff_X[settings.writePointerPos] = value[0];
+        ringBuff_Y[settings.writePointerPos] = value[1];
+        ringBuff_Z[settings.writePointerPos] = value[2];
+        ringBuff_T[settings.writePointerPos] = value[3];
+
+        /* check for increasing range if dynRange is true */
+        if (dynRange) {
+            smb380function = checkRange;
+        }
+        else {
+            smb380function = smb380emptyfunction;
+        }
+
+        smb380function(value);
+
+        //printf("Werte: x=%i, y=%i, z=%i\n\r",value[0], value[1], value[2]);
+        //vgpio_toggle(&gpio_led_green);
+
+        settings.writePointerPos += 1;
+
+        if (settings.writePointerPos == SMB380_RING_BUFF_SIZE) {
+            settings.writePointerPos = 0;
+        }
+
+        wakeUpRegisteredProcesses();
+        return 1;
+    }
+    else {
+        interruptTicksSMB380++;
+        return 0;
+    }
+}
+
+void SMB380_activateDynRangeSet(uint8_t activate)
+{
+    switch (activate) {
+        case 0:
+            dynRange = false ;
+            break;
+
+        case 1:
+            dynRange = true ;
+            break;
+    }
+}
+
+/*
+ * checking for in-/decreasing range
+ */
+uint8_t checkRange(int16_t *value)
+{
+    bool increased = false;
+
+    // printf("CurrentValues:  %i %i %i \r\n", xyzTMP[0], xyzTMP[1], xyzTMP[2]);
+
+    // determination of max and min value
+    int16_t maxValue = value[0]; // max(xValue, max(yValue, zValue));
+    int16_t minValue = value[0]; // min(xValue, min(yValue, zValue));
+
+    for (int i = 1; i < 3; i++) {
+        if (value[i] > maxValue) {
+            maxValue = value[i];
+        }
+
+        if (value[i] < minValue) {
+            minValue = value[i];
+        }
+    }
+
+    int8_t isRange = SMB380_getRange();
+
+    //increase range immediately
+    switch (isRange) {
+        case 2:
+            if ((maxValue > 1800) || (minValue < -1800)) {
+                SMB380_setRange(SMB380_RANGE_4G);
+                increased = true;
+                printf("=== Set range from 2 g to 4 g ===\r\n");
+            }
+
+            break;
+
+        case 4:
+            if ((maxValue > 3800) || (minValue < -3800)) {
+                SMB380_setRange(SMB380_RANGE_8G);
+                increased = true;
+                printf("=== Set range from 4 g to 8 g ===\r\n");
+            }
+
+            break;
+
+        case 8:
+            break;
+    }
+
+    /* check for decreasing range */
+    if (increased) {
+        counter_Decreasing = 0;
+    }
+    else {
+        //decrease range after 10 consecutive relevant values
+        switch (isRange) {
+            case 2:
+                break;
+
+            case 4:
+                if ((maxValue < 2000) && (minValue > -2000)) {
+                    if (counter_Decreasing >= 9) {
+                        SMB380_setRange(SMB380_RANGE_2G);
+                        printf("=== Set range from 4 g to 2 g ===\r\n");
+                        counter_Decreasing = 0;
+                    }
+                    else {
+                        counter_Decreasing++;
+                    }
+                }
+                else {
+                    counter_Decreasing = 0;
+                }
+
+                break;
+
+            case 8:
+                if ((maxValue < 4000) && (minValue > -4000)) {
+                    if (counter_Decreasing >= 9) {
+                        SMB380_setRange(SMB380_RANGE_4G);
+                        printf("=== Set range from 8 g to 4 g ===\r\n");
+                        counter_Decreasing = 0;
+                    }
+                    else {
+                        counter_Decreasing++;
+                    }
+                }
+                else {
+                    counter_Decreasing = 0;
+                }
+
+                break;
+        }
+    }
+
+    return 0;
+}
+
+
+void wakeUpRegisteredProcesses(void)
+{
+    uint8_t pointerNo = 0;
+    //wake up waiting processes
+    wakeupmessage.type = MSG_TYPE_SMB380_WAKEUP;
+
+    while ((PointerList[pointerNo] > 0) &&
+           (pointerNo < SMB380_RING_BUFF_MAX_THREADS)) {
+        msg_send(&wakeupmessage, PointerList[pointerNo], false);
+        pointerNo++;
+    }
+}
+
+int16_t SMB380_getTemperature(void)
+{
+    int16_t t = 0;
+
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_TEMP, 0, SMB380_READ_REGISTER);
+
+    //	t = (SMB380_ssp_read() & 0xFF) / 2.0 + SMB380_TEMP_OFFSET;
+    t = (SMB380_ssp_read() & 0xFF);
+    t = (t >> 1) + SMB380_TEMP_OFFSET;
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+
+    return t;
+}
+
+void SMB380_getAcceleration(unsigned char axis, int16_t *pAbs, int16_t *pMg)
+{
+    unsigned short ur;
+
+    if (!settings.countRange && (pMg != NULL)) {
+        settings.countRange = 1;
+        settings.range = SMB380_getRange();
+    }
+
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+
+    switch (axis) {
+        case SMB380_X_AXIS:
+            SMB380_ssp_write(SMB380_ACC_X_MSB, 0, SMB380_READ_REGISTER);
+            SMB380_ssp_write(SMB380_ACC_X_LSB_NEWDATA, 0, SMB380_READ_REGISTER);
+            break;
+
+        case SMB380_Y_AXIS:
+            SMB380_ssp_write(SMB380_ACC_Y_MSB, 0, SMB380_READ_REGISTER);
+            SMB380_ssp_write(SMB380_ACC_Y_LSB_NEWDATA, 0, SMB380_READ_REGISTER);
+            break;
+
+        default:
+            SMB380_ssp_write(SMB380_ACC_Z_MSB, 0, SMB380_READ_REGISTER);
+            SMB380_ssp_write(SMB380_ACC_Z_LSB_NEWDATA, 0, SMB380_READ_REGISTER);
+    }
+
+    ur = (SMB380_ssp_read() & SMB380_ACC_MSB_MASK) << 2;
+    ur |= (SMB380_ssp_read() & SMB380_ACC_LSB_MASK) >> 6;
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+
+    if (pAbs != NULL) {
+        if (ur & BIT9) {  //ur<0
+            *pAbs = ur | 0xFC00;
+        }
+        else {
+            *pAbs = ur & 0x03FF;
+        }
+    }
+
+    if (pMg != NULL) {
+        if (ur & BIT9) {  //ur<0
+            *pMg = -(((settings.range * (512 - (ur & 0x1FF))) * 2000) / 1024);
+        }
+        else {
+            *pMg = ((settings.range * ur) * 2000) / 1024;
+        }
+    }
+
+}
+
+unsigned char SMB380_getChipID(void)
+{
+    unsigned char ur = 0;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CHIP_ID, 0, 0);
+    ur = (unsigned char)(SMB380_ssp_read() & SMB380_CHIP_ID_MASK);
+    restoreIRQ(cpsr);
+    return ur;
+}
+
+void SMB380_setWakeUpPause(unsigned char duration)
+{
+    unsigned char utemp;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL4, 0, SMB380_READ_REGISTER);
+    utemp = SMB380_ssp_read();
+    utemp &= ~SMB380_CONTROL4_WAKEUP_PAUSE_MASK;
+    utemp |= (duration & (0x3) << 1);//+1;
+    SMB380_ssp_write(SMB380_CONTROL4, utemp, SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+unsigned char SMB380_getWakeUpPause(void)
+{
+    unsigned char up;
+
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL4, 0, SMB380_READ_REGISTER);
+    up = (unsigned char)SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+    up &= SMB380_CONTROL4_WAKEUP_PAUSE_MASK;
+    up = up >> 1;
+
+    return up;
+}
+
+void SMB380_setBandWidth(unsigned char bandWidth)
+{
+    unsigned char utemp;
+
+    if ((bandWidth == SMB380_BAND_WIDTH_100HZ) |
+        (bandWidth == SMB380_BAND_WIDTH_1500HZ) |
+        (bandWidth == SMB380_BAND_WIDTH_190HZ) |
+        (bandWidth == SMB380_BAND_WIDTH_25HZ) |
+        (bandWidth == SMB380_BAND_WIDTH_375HZ) |
+        (bandWidth == SMB380_BAND_WIDTH_50HZ) |
+        (bandWidth == SMB380_BAND_WIDTH_750HZ)) {
+        unsigned long cpsr = disableIRQ();
+        SMB380_Prepare();
+        SMB380_ssp_write(SMB380_CONTROL3, 0, SMB380_READ_REGISTER);
+        utemp = SMB380_ssp_read();
+        utemp &= ~SMB380_CONTROL3_BANDWITH_MASK;
+        utemp |= (bandWidth & 0x7);
+        SMB380_ssp_write(SMB380_CONTROL3, utemp, SMB380_WRITE_REGISTER);
+        SMB380_ssp_read();
+        SMB380_Unprepare();
+        restoreIRQ(cpsr);
+    }
+}
+
+void SMB380_setRange(unsigned char range)
+{
+    unsigned char utemp = 0;
+
+    if (range != 0x3) {
+        unsigned long cpsr = disableIRQ();
+        SMB380_Prepare();
+        SMB380_ssp_write(SMB380_CONTROL3, 0, SMB380_READ_REGISTER);
+        utemp = (unsigned char)SMB380_ssp_read();
+        utemp &= ~SMB380_CONTROL3_RANGE_MASK;
+        utemp |= (range & 0x3) << 3;
+        SMB380_ssp_write(SMB380_CONTROL3, utemp, SMB380_WRITE_REGISTER);
+        SMB380_ssp_read();
+        SMB380_Unprepare();
+        restoreIRQ(cpsr);
+        settings.countRange = 0;
+    }
+
+}
+
+unsigned char SMB380_getRange(void)
+{
+    unsigned char ur;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL3, 0, SMB380_READ_REGISTER);
+    ur = (SMB380_ssp_read() & SMB380_CONTROL3_RANGE_MASK) >> 3;
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+
+    switch (ur) {
+        case SMB380_RANGE_2G:
+            return 2;
+
+        case SMB380_RANGE_4G:
+            return 4;
+
+        case SMB380_RANGE_8G:
+            return 8;
+
+        default:
+            return 4;
+    }
+}
+
+unsigned char SMB380_getBandWidth(void)
+{
+    unsigned char uBand;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL3, 0, SMB380_READ_REGISTER);
+    uBand = SMB380_ssp_read() & SMB380_CONTROL3_BANDWITH_MASK;
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+    return uBand;
+}
+
+int16_t SMB380_getBandWidthAbs(void)
+{
+    unsigned char uBand;
+    uBand = SMB380_getBandWidth();
+
+    switch (uBand) {
+        case SMB380_BAND_WIDTH_25HZ:
+            return 25;
+
+        case SMB380_BAND_WIDTH_50HZ:
+            return 50;
+
+        case SMB380_BAND_WIDTH_100HZ:
+            return 100;
+
+        case SMB380_BAND_WIDTH_190HZ:
+            return 190;
+
+        case SMB380_BAND_WIDTH_375HZ:
+            return 375;
+
+        case SMB380_BAND_WIDTH_750HZ:
+            return 750;
+
+        case SMB380_BAND_WIDTH_1500HZ:
+            return 1500;
+
+        default:
+            return uBand;
+    }
+}
+
+void SMB380_softReset(void)
+{
+    unsigned char ur;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL1, SMB380_CONTROL1_SOFT_RESET_MASK,
+                     SMB380_WRITE_REGISTER);
+    ur = ((unsigned char)SMB380_ssp_read()) & SMB380_CONTROL1_SOFT_RESET_MASK;
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+    ur = ur >> 1;
+}
+
+void SMB380_setCustomerReg(unsigned char data)
+{
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CUST1, data, SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+unsigned char SMB380_getCustomerReg(void)
+{
+    unsigned uReg = 0;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CUST1, 0, SMB380_READ_REGISTER);
+    uReg = (unsigned char)SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+    return uReg;
+}
+
+// Selftest
+void SMB380_Selftest_1(void)
+{
+    unsigned char uReg = 0;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_LG_THRES, 6, SMB380_WRITE_REGISTER);
+    //SSP0Init();
+    SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_LG_DUR, 0, SMB380_WRITE_REGISTER);
+    //SSP0Init();
+    SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL1, 0, SMB380_READ_REGISTER);
+
+    uReg = (unsigned char)SMB380_ssp_read();
+    uReg &= ~SMB380_CONTROL1_SELF_TEST_1_MASK;
+    uReg |= 0x01 << 3;
+    SMB380_ssp_write(SMB380_CONTROL1, uReg, SMB380_WRITE_REGISTER);
+    //	SSP0Init();
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_ShowMemory(void)
+{
+    uint16_t uReg = 0;
+    uint8_t bitMask[16];
+    printf("SMB380 Speicher\n\r");
+    unsigned long cpsr;
+
+    for (unsigned char regAd = 0x16; regAd > 0; regAd--) {
+        cpsr = disableIRQ();
+        SMB380_Prepare();
+        SMB380_ssp_write(regAd - 1, 0, SMB380_READ_REGISTER);
+        uReg = SMB380_ssp_read();
+        SMB380_Unprepare();
+        restoreIRQ(cpsr);
+        printf("Register: = %X: 0x%X = ", regAd - 1, uReg);
+
+        for (int pos = 0; pos < 16; pos++) { //uReg != 0)
+            bitMask[15 - pos] = uReg % 2;
+
+            uReg = uReg / 2;
+        }
+
+        for (int pos = 8; pos < 16; pos++) { //uReg != 0)
+            printf("%d", bitMask[pos]);
+
+            if ((pos % 4) == 0) {
+                printf(" ");
+            }
+        }
+
+        printf("\n");
+    }
+}
+
+void SMB380_setUpperLimit(void)
+{
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_HG_THRES, 128, SMB380_WRITE_REGISTER); //1g
+    SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_HG_DUR, 0, SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_enableUpperLimit(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL2, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL2, uReg | SMB380_CONTROL2_ENABLE_HG_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_disableUpperLimit(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL2, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL2, uReg & ~SMB380_CONTROL2_ENABLE_HG_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_enableLowerLimit(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL2, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL2, uReg | SMB380_CONTROL2_ENABLE_LG_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_disableLowerLimit(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL2, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL2, uReg & ~SMB380_CONTROL2_ENABLE_LG_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+/* @param gvaluefloat - value is in mg
+ * @param gvalueint - value in range of 0 to 512
+ * Choose one of them, set the other to zero
+ */
+uint8_t SMB380_setAnyMotionLimit(uint16_t mg, uint16_t gvalueint)
+{
+
+    uint8_t threshold = 0;
+
+    if (mg != 0) {
+        threshold = mg / (15.6 * (SMB380_getRange() / 2));
+    }
+    else if (gvalueint != 0) {
+        /* Scaling for different gRanges is not needed */
+        threshold = ceil(((gvalueint * 2000) / 512.0) / 15.6);
+    }
+    else {
+        return 0;
+    }
+
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    /* 0,3g = 300 / 15,6mg = 19 */
+    SMB380_ssp_write(SMB380_ANY_MOTION_THRES, threshold, SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    //Set duration at this point
+    SMB380_ssp_write(SMB380_ANY_MOTION_DUR_HYST, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+    return 1;
+}
+
+void SMB380_enableAnyMotionLimit(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL4, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL4, uReg | SMB380_CONTROL4_ENABLE_ADV_INT_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL2, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL2, uReg | SMB380_CONTROL2_ANY_MOTION_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_disableAnyMotionLimit(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL2, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL2,
+                     uReg & ~SMB380_CONTROL2_ANY_MOTION_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL4, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL4,
+                     uReg & ~SMB380_CONTROL4_ENABLE_ADV_INT_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_enableNewDataInt(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    /*
+     * prevent deep sleep, reason: 400 µs wake-up time is to long for 3kHz
+     * interrupts
+     */
+    SETBIT(lpm_prevent_sleep, LPM_PREVENT_SLEEP_ACCSENSOR);
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL4, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL4, uReg | SMB380_CONTROL4_NEW_DATA_INT_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    // measuring temperature dependent internal sample rate of SMB380
+    tickStart = ktimer_now();
+    tickCurrentSamples = 0;
+    restoreIRQ(cpsr);
+}
+
+void SMB380_disableNewDataInt(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL4, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL4, uReg & ~SMB380_CONTROL4_NEW_DATA_INT_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    /*
+     * enable deep sleep, reason: 400 µs wake-up time was to long for 3kHz
+     * interrupts
+     */
+    CLRBIT(lpm_prevent_sleep, LPM_PREVENT_SLEEP_ACCSENSOR);
+    restoreIRQ(cpsr);
+}
+
+void SMB380_resetInterruptFlags(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL1, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL1, uReg | SMB380_CONTROL1_RESET_INT_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_enableEEPROM(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL1, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL1, uReg | SMB380_CONTROL1_EE_W_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+void SMB380_disableEEPROM(void)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+    SMB380_ssp_write(SMB380_CONTROL1, 0, SMB380_READ_REGISTER);
+    uReg = SMB380_ssp_read();
+    SMB380_ssp_write(SMB380_CONTROL1, uReg & ~SMB380_CONTROL1_EE_W_MASK,
+                     SMB380_WRITE_REGISTER);
+    SMB380_ssp_read();
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+}
+
+/*
+ * Return offsets from offset registers,
+ * remove xyz afterwards because it is useless
+ */
+unsigned char SMB380_readOffset(uint16_t *offset)
+{
+    if (sizeof(offset) < 3) {
+        return false;
+    }
+
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_X, 0, SMB380_READ_REGISTER);
+    uReg = ((SMB380_ssp_read() & SMB380_ACC_LSB_MASK) >> 6);
+    SMB380_ssp_write(SMB380_OFFSET_MSB_X, 0, SMB380_READ_REGISTER);
+    uReg |= (SMB380_ssp_read() & SMB380_ACC_MSB_MASK) << 2;
+
+
+    offset[0] = uReg;
+    printf("Offset X: %u ", uReg);
+
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Y, 0, SMB380_READ_REGISTER);
+    uReg = (SMB380_ssp_read() & SMB380_ACC_LSB_MASK) >> 6;
+    SMB380_ssp_write(SMB380_OFFSET_MSB_Y, 0, SMB380_READ_REGISTER);
+    uReg |= (SMB380_ssp_read() & SMB380_ACC_MSB_MASK) << 2;
+
+    offset[1] = uReg;
+    printf("Offset Y: %u ", uReg);
+
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Z, 0, SMB380_READ_REGISTER);
+    uReg = (SMB380_ssp_read() & SMB380_ACC_LSB_MASK) >> 6;
+    SMB380_ssp_write(SMB380_OFFSET_MSB_Z, 0, SMB380_READ_REGISTER);
+    uReg |= (SMB380_ssp_read() & SMB380_ACC_MSB_MASK) << 2;
+
+    offset[2] = uReg;
+    printf("Offset Z: %u \r\n", uReg);
+
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+
+    return true;
+}
+
+unsigned char SMB380_readOffsetTemp(uint16_t *offset)
+{
+    unsigned short uReg;
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_T, 0, SMB380_READ_REGISTER);
+    uReg = ((SMB380_ssp_read() & SMB380_ACC_LSB_MASK) >> 6);
+    SMB380_ssp_write(SMB380_OFFSET_MSB_T, 0, SMB380_READ_REGISTER);
+    uReg |= (SMB380_ssp_read() & SMB380_ACC_MSB_MASK) << 2;
+
+
+    offset[0] = uReg;
+    printf("Offset T: %u ", uReg);
+
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+
+    return true;
+}
+
+/*
+ * EEPROM = 1 if data has to be written in EEPROM and not only in image
+ */
+void SMB380_writeOffset(uint16_t *offset, uint8_t EEPROM)
+{
+    printf("Writing Offset X: %u Y: %u Z: %u\r\n", offset[0], offset[1], offset[2]);
+
+    if (sizeof(offset) >= 3) {
+        uint16_t eeoffset = 0;
+
+        if (EEPROM) {
+            //create offset if saving to EEPROM is needed
+            eeoffset = SMB380_EEPROM_OFFSET;
+        }
+
+        unsigned short uReg;
+        unsigned long cpsr = disableIRQ();
+        SMB380_Prepare();
+
+        //x-Axis
+        uReg = (offset[0] & 0x03) << 6; //get both LSB Bits
+        //write them to image or eeprom
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_X, 0, SMB380_READ_REGISTER);
+        uReg |= (SMB380_ssp_read() & 0x3F); //saves gain from same register
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_X + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        uReg = (offset[0] & 0x3FC) >> 2; //get MSB Bits
+        SMB380_ssp_write(SMB380_OFFSET_MSB_X + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        //y-Axis
+        uReg = (offset[1] & 0x03) << 6; //get both LSB Bits
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Y, 0, SMB380_READ_REGISTER);
+        uReg |= (SMB380_ssp_read() & 0x3F); //saves gain from same register
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Y + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        uReg = (offset[1] & 0x3FC) >> 2; //get MSB Bits
+        SMB380_ssp_write(SMB380_OFFSET_MSB_Y + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        //z-Axis
+        uReg = (offset[2] & 0x03) << 6; //get both LSB Bits
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Z, 0,
+                         SMB380_READ_REGISTER); //write them to image or eeprom
+        uReg |= (SMB380_ssp_read() & 0x3F); //saves gain from same register
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Z + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        uReg = (offset[2] & 0x3FC) >> 2; //get MSB Bits
+        SMB380_ssp_write(SMB380_OFFSET_MSB_Z + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        SMB380_Unprepare();
+        restoreIRQ(cpsr);
+
+    }
+}
+
+void SMB380_writeOffsetTemp(uint16_t *offset, uint8_t EEPROM)
+{
+    printf("Writing Offset Temp: %u\r\n", offset[0]);
+
+    if (sizeof(offset) >= 1) {
+        uint16_t eeoffset = 0;
+
+        if (EEPROM) {
+            //create offset if saving to EEPROM is needed
+            eeoffset = SMB380_EEPROM_OFFSET;
+        }
+
+        unsigned short uReg;
+        unsigned long cpsr = disableIRQ();
+        SMB380_Prepare();
+
+        //T-Axis
+        uReg = (offset[0] & 0x03) << 6; //get both LSB Bits
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_T, 0,
+                         SMB380_READ_REGISTER); //write them to image or eeprom
+        uReg |= (SMB380_ssp_read() & 0x3F); //saves gain from same register
+        SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_T + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        uReg = (offset[0] & 0x3FC) >> 2; //get MSB Bits
+        SMB380_ssp_write(SMB380_OFFSET_MSB_T + eeoffset, (uint8_t)uReg,
+                         SMB380_WRITE_REGISTER); //write them to image or eeprom
+        SMB380_ssp_read();
+        hwtimer_wait(HWTIMER_TICKS(50000));
+
+        SMB380_Unprepare();
+        restoreIRQ(cpsr);
+    }
+}
+
+unsigned char SMB380_readGain(uint16_t *gain)
+{
+    if (sizeof(gain) < 3) {
+        return false;
+    }
+
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+
+    //x-gain
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_X, 0, SMB380_READ_REGISTER);
+    gain[0] = (SMB380_ssp_read() & SMB380_OFFSET_GAIN_MASK);
+    //y-gain
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Y, 0, SMB380_READ_REGISTER);
+    gain[1] = (SMB380_ssp_read() & SMB380_OFFSET_GAIN_MASK);
+    //z-gain
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_Z, 0, SMB380_READ_REGISTER);
+    gain[2] = (SMB380_ssp_read() & SMB380_OFFSET_GAIN_MASK);
+
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+
+    return true;
+}
+
+unsigned char SMB380_readGainTemp(uint16_t *gain)
+{
+    if (sizeof(gain) < 1) {
+        return false;
+    }
+
+    unsigned long cpsr = disableIRQ();
+    SMB380_Prepare();
+
+    //T-gain
+    SMB380_ssp_write(SMB380_OFFSET_LSB_GAIN_T, 0, SMB380_READ_REGISTER);
+    gain[0] = (SMB380_ssp_read() & SMB380_OFFSET_GAIN_MASK);
+
+    SMB380_Unprepare();
+    restoreIRQ(cpsr);
+
+    return true;
+}
+
+
diff --git a/boards/avsextrem/drivers/avsextrem-ssp0.c b/boards/avsextrem/drivers/avsextrem-ssp0.c
new file mode 100644
index 0000000000000000000000000000000000000000..e396e5dddbe5015cf619d977120ab0457013fcb5
--- /dev/null
+++ b/boards/avsextrem/drivers/avsextrem-ssp0.c
@@ -0,0 +1,425 @@
+/*
+ * avsextrem-ssp0.c - implementation of the SPI0 interface for the LPC2387,
+ * and the AVSESTREM board.
+ * Copyright (C) 2013 Freie Universität Berlin
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @file
+ * @internal
+ * @brief       Implements the SPI0 interface for the LPC2387
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      Marco Ziegert <ziegert@inf.fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @version     $Revision: 3854 $
+ *
+ * @note        $Id:  avsextrem-ssp0.c  3854 2013-08-14 15:27:01Z zkasmi $
+ */
+
+#include "lpc23xx.h"   /* LPC23XX/24xx Peripheral Registers */
+#include "cpu.h"
+#include "VIC.h"
+#include "ssp0-board.h"
+#include "smb380-board.h"
+//#include "mma7455l-board.h"
+#include "gpioint.h"
+#include "hwtimer.h"
+#include <stdio.h>
+#include "lpm.h"
+
+//uint16_t sampleRateMMA7455L;
+//uint16_t interruptTicksMMA7455L;
+//
+//static void MMA7455L_extIntHandler(void);
+
+uint32_t SSP0Init(void)
+{
+
+    /*
+     * enable clock to SSP0 for security reason.
+     * By default, it's enabled already
+     */
+    PCONP |= PCSSP0;
+    //TODO: configure CLK, MISO, MOSI by default as  GPIOs.
+#if USE_CS
+    //  P1.20 1.21 1.23 1.24
+    //	PINSEL3 |= BIT8 | BIT9 | BIT10 | BIT11 | BIT14 | BIT15 | BIT16 | BIT17;
+#else
+    //  No SSEL0
+    //	PINSEL3 |= BIT8 | BIT9 | BIT14 | BIT15 | BIT16 | BIT17; //1.20 1.23 1.24
+#endif
+
+#if SSP1_INTERRUPT_MODE
+
+    if (install_irq(SSP1_INT, (void *)SSP0Handler, HIGHEST_PRIORITY) == FALSE) {
+        return (FALSE);
+    }
+
+    /*
+     * Set SSPINMS registers to enable interrupts,
+     * enable all error related interrupts
+     */
+
+    SSP1IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;
+#endif
+
+    return (1);
+}
+
+/*
+ * datasize (wordsize) in decimal (4-16), cpol&cpha =(0/1) and frequency divided
+ * by 1000 (e.g. 8 MHz = 8000)
+ */
+uint8_t SSP0Prepare(uint8_t chip, uint8_t datasize, uint8_t cpol, uint8_t cpha,
+                    uint16_t freq)
+{
+    switch (chip) {
+        case BMA180_INTERN:
+        case SMB380_ACC: {
+#if USE_CS
+            PINSEL3 |= BIT8 | BIT9 | BIT10 | BIT11 | BIT14 | BIT15 | BIT16 |
+                       BIT17;	//P1.20 1.21 1.23 1.24
+#else
+            // 1.20 1.23 1.24 are not configured as SSEL0
+            PINSEL3 |= BIT8 | BIT9 | BIT14 | BIT15 | BIT16 | BIT17;
+#endif
+            break;
+        }
+
+        case BMA180_EXTERN:
+        case L3G_EXTERN:
+        case NANOPAN:
+        case ACAMDMS: {
+#if USE_CS
+            PINSEL0 |= BIT31;
+            PINSEL1 |= BIT1 | BIT3 | BIT5;  // P0.15 0.16 0.17 0.18
+#else
+            // Turn on NanoPAN
+            PINSEL0 |= BIT31;
+            // 0.15 0.17 0.18 are not configured as SSEL0
+            PINSEL1 |= BIT3 | BIT5;
+#endif
+            break;
+        }
+
+        case NORDIC: {
+            PINSEL0 |= BIT31;
+            PINSEL1 |= BIT3 | BIT5; // 0.15 0.17 0.18 SSEL0 (No)
+            break;
+        }
+
+        default: {
+            printf("wrong CHIP selected\n");
+            return 0;
+        }
+    }
+
+    uint32_t SSP0CR0tmp = 0;
+
+    switch (datasize) {
+        case 4:
+            SSP0CR0tmp = BIT0 | BIT1;
+            break;
+
+        case 5:
+            SSP0CR0tmp = BIT2;
+            break;
+
+        case 6:
+            SSP0CR0tmp = BIT0 | BIT2;
+            break;
+
+        case 7:
+            SSP0CR0tmp = BIT1 | BIT2;
+            break;
+
+        case 8:
+            SSP0CR0tmp = BIT0 | BIT1 | BIT2;
+            break;
+
+        case 9:
+            SSP0CR0tmp = BIT3;
+            break;
+
+        case 10:
+            SSP0CR0tmp = BIT0 | BIT3;
+            break;
+
+        case 11:
+            SSP0CR0tmp = BIT1 | BIT3;
+            break;
+
+        case 12:
+            SSP0CR0tmp = BIT0 | BIT1 | BIT3;
+            break;
+
+        case 13:
+            SSP0CR0tmp = BIT2 | BIT3;
+            break;
+
+        case 14:
+            SSP0CR0tmp = BIT0 | BIT2 | BIT3;
+            break;
+
+        case 15:
+            SSP0CR0tmp = BIT1 | BIT2 | BIT3;
+            break;
+
+        case 16:
+            SSP0CR0tmp = BIT0 | BIT1 | BIT2 | BIT3;
+            break;
+
+        default:
+            return 0;
+    }
+
+    if (cpol) {
+        SSP0CR0tmp |= BIT6;
+    }
+
+    if (cpha) {
+        SSP0CR0tmp |= BIT7;
+    }
+
+    SSP0CR1 = 0x00; // SSP0 disabled
+
+    // Setting	xx-Bit Datasize, CPOL and CPHA
+    SSP0CR0 = SSP0CR0tmp;
+
+    // Clock Setup
+    uint32_t pclksel;
+    uint32_t cpsr;
+    lpc2387_pclk_scale(F_CPU / 1000, freq, &pclksel, &cpsr);
+    PCLKSEL1 &= ~(BIT10 | BIT11); // CCLK to PCLK divider ???
+    PCLKSEL1 |= pclksel << 10;
+    SSP0CPSR = cpsr;
+
+    // Enable
+    SSP0CR1 |= BIT1; // SSP0 enabled
+
+    uint32_t Dummy;
+
+    for (uint32_t i = 0; i < FIFOSIZE; i++) {
+        Dummy = SSP0DR; // clear the RxFIFO
+    }
+
+    return 1;
+}
+
+uint8_t SSP0Unprepare(uint8_t chip)
+{
+    switch (chip) {
+        case BMA180_INTERN:
+        case SMB380_ACC: {
+            // Turn off Acceleration Sensor
+            PINSEL3 &= ~(BIT8 | BIT9 | BIT10 | BIT11 | BIT14 | BIT15 | BIT16 |
+                         BIT17);
+            FIO1DIR |= BIT20 | BIT21 | BIT24;
+            FIO1DIR &= ~BIT23;		 // MISO as Input
+            FIO1SET = BIT20 | BIT24;	 /*
+                                          * CLK + SSEL + MOSI GPIO as Output
+                                          * TODO: depends on CPOL+CPHA Settings
+                                          */
+            FIO1CLR = BIT21;
+            break;
+        }
+
+        case BMA180_EXTERN:
+        case L3G_EXTERN:
+        case NORDIC:
+        case NANOPAN:
+        case ACAMDMS: {
+            // Turn off Nanopan (Pins to GPIO)
+            PINSEL0 &= ~(BIT30 | BIT31); //CLK to GPIO
+            PINSEL1 &= ~(BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5);
+            FIO0DIR |= BIT15 | BIT16 | BIT18; //CLK + SSEL + MOSI GPIO as Output
+            FIO0DIR &= ~BIT17; // MISO as Input
+            FIO0SET = BIT15 | BIT16; /*
+                           * CLK + SSEL + MOSI GPIO as Output
+      * TODO: depends on CPOL+CPHA Settings
+      */
+            FIO0CLR = BIT18;
+            break;
+        }
+
+        default: {
+            printf("wrong CHIP selected\n");
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+unsigned char SMB380_ssp_write(const unsigned char regAddr,
+                               const unsigned char data, unsigned char flag)
+{
+
+    uint16_t temp = 0;
+
+    if (flag) {
+        temp = (unsigned int)(((regAddr & 0xFF7F) << 8) | data);
+
+    }
+    else {
+        temp = (((unsigned int)(regAddr | 0x80) << 8) | 0xFF);
+    }
+
+    return SSP0_write(temp, SMB380_ACC);
+}
+
+unsigned char SSP0_write(const uint16_t data, uint8_t device)
+{
+    unsigned char ret = 1;
+
+    while ((SSP0SR & (SSPSR_TNF | SSPSR_BSY)) != SSPSR_TNF)
+        ;
+
+    if (!USE_CS) {
+        switch (device) {
+            case BMA180_INTERN:
+            case SMB380_ACC: {
+                FIO1CLR = SSP0_SEL;
+                break;
+            }
+
+            case BMA180_EXTERN:
+            case L3G_EXTERN:
+            case NANOPAN: {
+                printf("[%s] line: %d\n", __FUNCTION__, __LINE__);
+                FIO0CLR = SSP0_SELN;
+                break;
+            }
+
+            case ACAMDMS:
+            case NORDIC:
+                // Chip Select is done in Nordic driver
+                break;
+
+            default:
+                ret = 0;
+                goto ret;
+        }
+    }
+
+    SSP0DR = data;
+
+    if (!USE_CS) {
+        while (SSP0SR & SSPSR_BSY)
+            ;
+
+        switch (device) {
+            case BMA180_INTERN:
+            case SMB380_ACC: {
+                FIO1SET = SSP0_SEL;
+                break;
+            }
+
+            case BMA180_EXTERN:
+            case L3G_EXTERN:
+            case NANOPAN: {
+                FIO0SET = SSP0_SELN;
+                break;
+            }
+
+            case ACAMDMS:
+            case NORDIC:
+                // Chip Select is done in Nordic driver
+                break;
+
+            default:
+                ret = 0;
+                goto ret;
+        }
+    }
+
+ret:
+    return ret;
+}
+
+unsigned short SSP0_read(uint8_t device)
+{
+    uint16_t data;
+
+    while (!(SSP0SR & SSPSR_RNE))
+        ;
+
+    if (!USE_CS) {
+        switch (device) {
+            case BMA180_INTERN:
+            case SMB380_ACC: {
+                FIO1CLR = SSP0_SEL;
+                break;
+            }
+
+            case BMA180_EXTERN:
+            case L3G_EXTERN:
+            case NANOPAN: {
+                FIO0CLR = SSP0_SELN;
+                break;
+            }
+
+            case NORDIC:
+            case ACAMDMS:
+                // Chip Select is done in Nordic driver
+                break;
+
+            default:
+                data = 0xFFFF;
+                goto ret;
+        }
+    }
+
+    data = SSP0DR;
+
+    if (!USE_CS) {
+        switch (device) {
+            case BMA180_INTERN:
+            case SMB380_ACC: {
+                FIO1SET = SSP0_SEL;
+                break;
+            }
+
+            case BMA180_EXTERN:
+            case L3G_EXTERN:
+            case NANOPAN: {
+                FIO0SET = SSP0_SELN;
+                break;
+            }
+
+            case ACAMDMS:
+            case NORDIC:
+                // Chip Select is done in Nordic driver
+                break;
+
+            default:
+                data = 0xFFFF;
+                goto ret;
+        }
+    }
+
+ret:
+    return data;
+}
+
+unsigned short SMB380_ssp_read(void)
+{
+    return SSP0_read(SMB380_ACC);
+}
+
+unsigned short nrf24l01_ssp_read_write(const uint8_t data)
+{
+    SSP0_write(data, NORDIC);
+    return SSP0_read(NORDIC);
+}
+
+unsigned short acam_trx(const uint8_t data)
+{
+    SSP0_write(data, ACAMDMS);
+    return SSP0_read(ACAMDMS);
+}
+
diff --git a/boards/avsextrem/include/board.h b/boards/avsextrem/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..43703829425a786110b24847b07c6119c281842d
--- /dev/null
+++ b/boards/avsextrem/include/board.h
@@ -0,0 +1,66 @@
+/*
+* board.h - Definitions for the AVSEXTREM board configuration.
+* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+*
+* This source code is licensed under the LGPLv2 license,
+* See the file LICENSE for more details.
+*
+*/
+
+
+/**
+ * @file
+ * @brief       avsextrem board configuration
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      Heiko Will
+ * @author      Zakaria Kasmi
+ * @version     $Revision: 1127 $
+ *
+ * @note        $Id: board-conf.h 1127 2013-06-13 08:48:29Z kasmi$
+ */
+
+
+#ifndef BOARDCONF_H_
+#define BOARDCONF_H_
+#include <bitarithm.h>
+#include "msba2_common.h"
+
+#define FEUERWARE_CONF_BOARD_NAME	      "FU Berlin AVSEXTREM BOARD"
+
+#define LED_RED_PIN (BIT25)
+#define LED_GREEN_PIN (BIT26)
+
+#define LED_GREEN_OFF (FIO3SET = LED_GREEN_PIN)
+#define LED_GREEN_ON (FIO3CLR = LED_GREEN_PIN)
+#define LED_GREEN_TOGGLE (FIO3PIN ^= LED_GREEN_PIN)
+
+#define LED_RED_OFF (FIO3SET = LED_RED_PIN)
+#define LED_RED_ON (FIO3CLR = LED_RED_PIN)
+#define LED_RED_TOGGLE (FIO3PIN ^= LED_RED_PIN)
+
+
+
+#ifdef MODULE_CC110X
+#define FEUERWARE_CONF_NUM_RADIOS	      1
+#else
+#define FEUERWARE_CONF_NUM_RADIOS	      0
+#endif
+
+// if FAT is enabled this board supports files
+#define FEUERWARE_CONF_CORE_SUPPORTS_FILES    defined(MODULE_FAT)
+
+#ifdef MODULE_FAT
+#define CFG_CONF_MEM_SIZE		      0x7FFFFFFF
+#define SYSLOG_CONF_NUM_INTERFACES	      2
+#else
+#define SYSLOG_CONF_NUM_INTERFACES	      1
+#endif
+
+void init_clks1(void);
+
+typedef uint8_t radio_packet_length_t;
+
+/** @} */
+#endif /* BOARDCONF_H_ */
+
diff --git a/boards/avsextrem/include/configure.h b/boards/avsextrem/include/configure.h
new file mode 100644
index 0000000000000000000000000000000000000000..5ca52843a1195060c091a2033afe1495a089663f
--- /dev/null
+++ b/boards/avsextrem/include/configure.h
@@ -0,0 +1,77 @@
+/*
+* configure.h - Configuration file for the avsextrem board.
+* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+*
+* This source code is licensed under the LGPLv2 license,
+* See the file LICENSE for more details.
+*
+*/
+
+/**
+ * @file
+ * @brief       definitions for the avsextrem board configuration
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      baar
+ * @author      Zakaria Kasmi
+ * @version     $Revision: 1127 $
+ *
+ * @note        $Id: board-conf.h 1127 2013-08-20 17:15:29 kasmi $
+ */
+
+#ifndef CONFIGURE_H_
+#define CONFIGURE_H_
+
+/**
+ *
+ * The offline configuration file "configure.h" is automatically
+ * included in every file by the build system and allows to configure
+ * all neccessary defines on cpu, board and project level.
+ *
+ * The configuration is built of
+ * \li a project specific file (project-conf.h)
+ * \li a board specific file (board-conf.h) and
+ * \li a cpu specific file (cpu-conf.h).
+ * All of which are chosen by the build system depending on your arguments.
+ *
+ * @{
+ */
+
+//#include "project-conf.h"
+//#include "board-conf.h"
+#include "cpu-conf.h"
+
+#ifdef MODULE_SYSMON
+#ifndef TRACELOG_CONF_NUM_ENTRIES
+#define TRACELOG_CONF_NUM_ENTRIES	10
+#endif
+#else
+#undef TRACELOG_CONF_NUM_ENTRIES
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+/*
+ * documentation of defines that do not belong to a specific module:
+ */
+
+/**
+ * @def FEUERWARE_CONF_BOARD_NAME
+ * @brief	Defines the name of the board as a string
+ */
+
+/**
+ * @def FEUERWARE_CONF_CPU_NAME
+ * @brief	Defines the name of the cpu as a string
+ */
+
+/**
+ * @def FEUERWARE_CONF_SUPPORTS_FILES
+ * @brief	Defines if standard library file functions are available
+ */
+#ifndef FEUERWARE_CONF_SUPPORTS_FILES
+#define FEUERWARE_CONF_SUPPORTS_FILES 0
+#endif
+
+/** @} */
+#endif /* CONFIGURE_H_ */
diff --git a/boards/avsextrem/include/smb380-board.h b/boards/avsextrem/include/smb380-board.h
new file mode 100644
index 0000000000000000000000000000000000000000..218f724f4938ceaf0c006a42a8f1d39f3d0beb71
--- /dev/null
+++ b/boards/avsextrem/include/smb380-board.h
@@ -0,0 +1,254 @@
+/*
+ * msba2acc-smb380.h - Definitions of the Driver for the SMB380 acceleration
+ * sensor.
+ * Copyright (C) 2013 Freie Universität Berlin
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ **/
+
+/**
+ * @file
+ * @internal
+ * @brief   SMB380 acceleration sensor definitions for the LPC2387
+ *
+ * @author  Freie Universität Berlin, Computer Systems & Telematics
+ * @author  Marco Ziegert <ziegert@inf.fu-berlin.de>
+ * @author  Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @version $Revision: 3854 $
+ *
+ * @note    $Id: msba2acc-smb380.h 3854 2010-01-18 15:27:01 kasmi $
+ *
+ */
+
+#ifndef SMB380_H_
+#define SMB380_H_
+#include <stdint.h>
+#include <bitarithm.h>
+
+#define SMB380_DEBUG_MESSAGE "SMB380 Driver Error: "
+
+#define MSG_TYPE_SMB380_WAKEUP			814
+
+#define SMB380_X_AXIS 				0   //X Axis-Name
+#define SMB380_Y_AXIS				1   //Y Axis-Name
+#define SMB380_Z_AXIS				2   //Z Axis-Name
+
+#define LPM_PREVENT_SLEEP_ACCSENSOR		BIT2
+
+enum SMB380_MODE {
+    SMB380_POLL,
+    SMB380_POLL_AFTER_CONTINOUS,
+    SMB380_CONTINOUS,
+    SMB380_THRESHOLD,
+    SMB380_FALSEALERT
+};
+//volatile enum SMB380_MODE
+volatile enum SMB380_MODE smb380_mode;// = SMB380_POLL;
+
+/* Writeable values to EEPROM: from 0x0A (control1) to 0x1D (offset_T).
+   For writing enable ... flag and add eeprom_offset_address.
+
+   Generally it is a good idea to read out shared register addresses before writing,
+   registers 0x14 and 34h are especially critical.
+*/
+
+#define SMB380_EEPROM_OFFSET	 		0x20
+//Chip-ID Bit0-2, default: 010b
+#define SMB380_CHIP_ID   			0x00
+//Chip-ID mask
+#define SMB380_CHIP_ID_MASK			0x07
+//ml_version Bit0-3 ; al_version Bit4-7
+#define SMB380_AL_ML_VERSION			0x01
+#define SMB380_AL_MASK				0xF0
+#define SMB380_ML_MASK				0x0F
+//LSB_acc_x Bit6-7; new_data_x Bit0
+#define SMB380_ACC_X_LSB_NEWDATA		0x02
+//MSB_acc_x Bit0-7
+#define SMB380_ACC_X_MSB    			0x03
+//LSB_acc_y Bit6-7; new_data_y Bit0
+#define SMB380_ACC_Y_LSB_NEWDATA		0x04
+//MSB_acc_y Bit0-7
+#define SMB380_ACC_Y_MSB    			0x05
+//LSB_acc_z Bit6-7; new_data_z Bit0
+#define SMB380_ACC_Z_LSB_NEWDATA		0x06
+//MSB_acc_z Bit0-7
+#define SMB380_ACC_Z_MSB    			0x07
+#define SMB380_ACC_LSB_MASK			0xC0
+#define SMB380_ACC_MSB_MASK			0xFF
+#define SMB380_ACC_NEWDATA_MASK			0x01
+//Temperature Bit0-7
+#define SMB380_TEMP     			0x08
+//Status register, contains six flags
+#define SMB380_STATUS     			0x09
+#define SMB380_STATUS_ST_RESULT_MASK		0x80
+#define SMB380_STATUS_ALERT_PHASE_MASK		0x10
+#define SMB380_STATUS_LG_LATCHED_MASK		0x08
+#define SMB380_STATUS_HG_LATCHED_MASK		0x04
+#define SMB380_STATUS_STATUS_LG_MASK		0x02
+#define SMB380_STATUS_STATUS_HG_MASK		0x01
+//Control register - contains seven values, default: x000 0000b
+#define SMB380_CONTROL1     			0x0A
+#define SMB380_CONTROL1_RESET_INT_MASK		0x40
+#define SMB380_CONTROL1_UPDATE_MASK		0x20
+#define SMB380_CONTROL1_EE_W_MASK		0x10
+#define SMB380_CONTROL1_SELF_TEST_1_MASK	0x08
+#define SMB380_CONTROL1_SELF_TEST_0_MASK	0x04
+#define SMB380_CONTROL1_SOFT_RESET_MASK	    	0x02
+#define SMB380_CONTROL1_SLEEP_MASK		0x01
+//Control register - contains six values, default: x000 0011b
+#define SMB380_CONTROL2     			0x0B
+#define SMB380_CONTROL2_ALERT_MASK		0x80
+#define SMB380_CONTROL2_ANY_MOTION_MASK	    	0x40
+#define SMB380_CONTROL2_COUNTER_HG_MASK	    	0x30
+#define SMB380_CONTROL2_COUNTER_LG_MASK	    	0x0C
+#define SMB380_CONTROL2_ENABLE_HG_MASK	    	0x02
+#define SMB380_CONTROL2_ENABLE_LG_MASK	    	0x01
+//default: 20
+#define SMB380_LG_THRES     			0x0C
+//default: 150
+#define SMB380_LG_DUR     			0x0D
+//default: 160
+#define SMB380_HG_THRES     			0x0E
+//default: 150
+#define SMB380_HG_DUR     			0x0F
+//default: 0
+#define SMB380_ANY_MOTION_THRES   		0x10
+//default: 0000 0000b
+#define SMB380_ANY_MOTION_DUR_HYST		0x1
+#define SMB380_ANY_MOTION_DUR_MASK		0xC0
+#define SMB380_ANY_MOTION_DUR_HG_HYST_MASK	0x38
+#define SMB380_ANY_MOTION_DUR_LG_HYST_MASK	0x07
+//default: 162
+#define SMB380_CUST1     			0x12
+//default: 13
+#define SMB380_CUST2     			0x13
+//default: xxx0 1110b
+#define SMB380_CONTROL3     			0x14
+#define SMB380_CONTROL3_RANGE_MASK     	   	0x18
+#define SMB380_CONTROL3_BANDWITH_MASK       	0x07
+//default: 1000 0000b
+#define SMB380_CONTROL4     			0x15
+#define SMB380_CONTROL4_SPI4_MASK		0x80
+#define SMB380_CONTROL4_ENABLE_ADV_INT_MASK	0x40
+#define SMB380_CONTROL4_NEW_DATA_INT_MASK	0x20
+#define SMB380_CONTROL4_LATCH_INT_MASK	    	0x10
+#define SMB380_CONTROL4_SHADOW_DIS_MASK	    	0x08
+#define SMB380_CONTROL4_WAKEUP_PAUSE_MASK	0x06
+#define SMB380_CONTROL4_WAKEUP_MASK		0x01
+
+#define SMB380_OFFSET_LSB_GAIN_X  		0x16
+#define SMB380_OFFSET_LSB_GAIN_Y  		0x17
+#define SMB380_OFFSET_LSB_GAIN_Z  		0x18
+#define SMB380_OFFSET_LSB_GAIN_T  		0x19
+#define SMB380_OFFSET_LSB_MASK  		0xC0
+#define SMB380_OFFSET_GAIN_MASK  		0x3F
+
+#define SMB380_OFFSET_MSB_X  			0x1A
+#define SMB380_OFFSET_MSB_Y  			0x1B
+#define SMB380_OFFSET_MSB_Z  			0x1C
+#define SMB380_OFFSET_MSB_T  			0x1D
+
+#define SMB380_TEMP_OFFSET			-30
+#define SMB380_DEFAULT_MAXG 			4.0f
+#define SMB380_READ_REGISTER			0x00
+#define SMB380_WRITE_REGISTER			0x01
+#define SMB380_WAKE_UP_PAUSE_20MS		0x00
+#define SMB380_WAKE_UP_PAUSE_80MS		0x01
+#define SMB380_WAKE_UP_PAUSE_320MS		0x02
+#define SMB380_WAKE_UP_PAUSE_2560MS		0x03
+#define SMB380_RANGE_2G				0x00
+#define SMB380_RANGE_4G				0x01
+#define SMB380_RANGE_8G				0x02
+#define SMB380_BAND_WIDTH_25HZ			0x00
+#define SMB380_BAND_WIDTH_50HZ			0x01
+#define SMB380_BAND_WIDTH_100HZ			0x02
+#define SMB380_BAND_WIDTH_190HZ			0x03
+#define SMB380_BAND_WIDTH_375HZ			0x04
+#define SMB380_BAND_WIDTH_750HZ			0x05
+#define SMB380_BAND_WIDTH_1500HZ		0x06
+//SMB380_RING_BUFF_SIZE * int16_t (2Byte) * 4 (x,y,z,Temp) = 512 Byte (for 64)
+#define SMB380_RING_BUFF_SIZE 			256
+//TODO chsnge size to 2048
+#define SMB380_RING_BUFF_MAX_THREADS 		10
+#define SMB380_SAMPLE_RATE_MAX			3000
+
+/*
+ * change from Header (public) to internal use (private)
+ * (use it after every write to EEPROM).
+ * set update_image Bit in control1 to
+ * copie content from EEPROM (0x2B to 0x3D) to Image (0x0B to 0x1D)
+ **/
+void SMB380_update_image(void);
+
+/*
+ * change from Header (public) to internal use (private)
+ * set ee_w Bit in control1 to
+ * enable read to 0x16 to 0x22	and
+ * enable write to 0x16 to 0x3D
+ **/
+void SMB380_enable_eeprom_default(void);
+//Example Hysterese function
+uint8_t SMB380_HystereseFunctionSample(int16_t *value);
+
+//Simple api for single-sample, single thread interrupt mode
+uint8_t SMB380_init_simple(uint16_t samplerate, uint8_t bandwidth,
+                           uint8_t range);
+
+
+//Enables Interrupts (normally only once called)
+uint8_t SMB380_init(uint8_t (*func)(int16_t *));
+void SMB380_setSampleRate(uint16_t rate);
+uint16_t SMB380_getSampleRate(void);
+void freeRingReadPointer(void);
+void actualizeRingReadPointer(void);
+uint8_t readRingBuff(int16_t *value);
+uint8_t writeRingBuff(int16_t *value);
+void SMB380_activateDynRangeSet(uint8_t activate);
+uint8_t checkRange(int16_t *value);
+
+void SMB380_enableEEPROM(void);
+void SMB380_disableEEPROM(void);
+
+// getter
+float SMB380_getSampleRatio(void);
+void SMB380_getAcceleration(unsigned char axis, int16_t *pAbs, int16_t *pMg);
+int16_t SMB380_getTemperature(void);
+unsigned char SMB380_getChipID(void);
+unsigned char SMB380_getWakeUpPause(void);
+unsigned char SMB380_getBandWidth(void);
+int16_t SMB380_getBandWidthAbs(void);
+unsigned char SMB380_getRange(void);
+unsigned char SMB380_getCustomerReg(void);
+unsigned char SMB380_readOffset(uint16_t *offset);
+unsigned char SMB380_readOffsetTemp(uint16_t *offset);
+unsigned char SMB380_readGain(uint16_t *gain);
+unsigned char SMB380_readGainTemp(uint16_t *gain);
+
+// setter
+void SMB380_setTempOffset(uint16_t offset, uint8_t EEPROM);
+void SMB380_setWakeUpPause(unsigned char duration);
+void SMB380_setBandWidth(unsigned char bandWidth);
+void SMB380_setRange(unsigned char range);
+void SMB380_softReset(void);
+void SMB380_setCustomerReg(unsigned char data);
+void SMB380_setUpperLimit(void);
+void SMB380_enableUpperLimit(void);
+void SMB380_disableUpperLimit(void);
+void SMB380_enableLowerLimit(void);
+void SMB380_disableLowerLimit(void);
+uint8_t SMB380_setAnyMotionLimit(uint16_t mg, uint16_t gvalueint);
+void SMB380_enableAnyMotionLimit(void);
+void SMB380_disableAnyMotionLimit(void);
+void SMB380_enableNewDataInt(void);
+void SMB380_disableNewDataInt(void);
+void SMB380_resetInterruptFlags(void);
+void SMB380_writeOffset(uint16_t *offset, uint8_t EEPROM);
+void SMB380_writeOffsetTemp(uint16_t *offset, uint8_t EEPROM);
+
+// stats
+void SMB380_ShowMemory(void);
+void SMB380_Selftest_1(void);
+
+
+#endif   /* SMB380_H_ */
diff --git a/boards/avsextrem/include/ssp0-board.h b/boards/avsextrem/include/ssp0-board.h
new file mode 100644
index 0000000000000000000000000000000000000000..ffcc5356ee8cd3fa531f8a3e23eba7e0e8c492dc
--- /dev/null
+++ b/boards/avsextrem/include/ssp0-board.h
@@ -0,0 +1,118 @@
+/*
+ * ssp0-borad.h - header file of the SPI interface for the LPC2387.
+ * Copyright (C) 2013 Freie Universität Berlin
+ *
+ * This source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ *
+ */
+
+/**
+ * @file
+ * @internal
+ * @brief       SPI interface definitions for the LPC2387
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics
+ * @author      Marco Ziegert <ziegert@inf.fu-berlin.de>
+ * @author      Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @version     $Revision: 3854 $
+ *
+ * @note        $Id:  avsextrem-ssp0.c  3854 2010-01-18 15:27:01Z zkasmi $
+ */
+#ifndef __SSP_H__
+#define __SSP_H__
+
+#include "stdint.h"
+
+#define DMA_ENABLED		0
+
+/*
+ * if USE_CS is zero, set SSEL as GPIO that you have total control of the
+ * sequence
+ **/
+#define USE_CS			0
+
+/*
+ * if 1, use driver for onboard BMA180, otherwise for external BMA180 utilizing
+ * Nanopan Connector
+ **/
+#define BMA180_ONBOARD		1
+
+#define SMB380_ACC		0
+#define NANOPAN			1
+#define NORDIC			2
+#define BMA180_EXTERN		3
+#define BMA180_INTERN		4
+#define L3G_EXTERN		5
+#define L3G_INTERN		6
+#define ACAMDMS			7
+
+/* SPI read and write buffer size */
+#define BUFSIZE			256
+#define FIFOSIZE		8
+
+/* SSP select pin */
+#define SSP0_SEL		1 << 21	//P1.21	SMB380
+
+#define SSP0_SELN		1 << 16 //P0.16 Nanotron
+
+/* SSP1 external interrupt Pin (SMB380 specific) */
+#define SMB380_INT1		1 << 1	//P0.1
+#define BMA180_INT1		1 << 8	//P2.8
+
+
+
+/* SSP1 CR0 register */
+#define SSPCR0_DSS		1 << 0
+#define SSPCR0_FRF		1 << 4
+#define SSPCR0_SPO		1 << 6
+#define SSPCR0_SPH		1 << 7
+#define SSPCR0_SCR		1 << 8
+
+/* SSP1 CR1 register */
+#define SSPCR1_LBM		1 << 0
+#define SSPCR1_SSE		1 << 1
+#define SSPCR1_MS		1 << 2
+#define SSPCR1_SOD		1 << 3
+
+/* SSP1 Interrupt Mask Set/Clear register */
+#define SSPIMSC_RORIM		1 << 0
+#define SSPIMSC_RTIM		1 << 1
+#define SSPIMSC_RXIM		1 << 2
+#define SSPIMSC_TXIM		1 << 3
+
+/* SSP1 Interrupt Status register */
+#define SSPRIS_RORRIS		1 << 0
+#define SSPRIS_RTRIS		1 << 1
+#define SSPRIS_RXRIS		1 << 2
+#define SSPRIS_TXRIS		1 << 3
+
+/* SSP1 Masked Interrupt register */
+#define SSPMIS_RORMIS		1 << 0
+#define SSPMIS_RTMIS		1 << 1
+#define SSPMIS_RXMIS		1 << 2
+#define SSPMIS_TXMIS		1 << 3
+
+/* SSP1 Interrupt clear register */
+#define SSPICR_RORIC		1 << 0
+#define SSPICR_RTIC		1 << 1
+
+#define SSP1_INTERRUPT_MODE	0
+#define SMB380_EXTINT_MODE  	1
+#define BMA180_EXTINT_MODE  	1
+
+uint32_t SSP0Init(void);
+uint8_t SSP0Prepare(uint8_t chip, uint8_t datasize, uint8_t cpol, uint8_t cpha,
+                    uint16_t freq);
+uint8_t SSP0Unprepare(uint8_t chip);
+unsigned char SSP0_write(const uint16_t data, uint8_t device);
+unsigned short SSP0_read(uint8_t device);
+unsigned char SMB380_ssp_write(const unsigned char regAddr,
+                               const unsigned char data, unsigned char flag);
+unsigned short SMB380_ssp_read(void);
+unsigned short nrf24l01_ssp_read_write(const uint8_t data);
+unsigned short acam_trx(const uint8_t data);
+void SSP0Handler(void);
+
+#endif  /* __SSP_H__ */
+
diff --git a/boards/chronos/Makefile b/boards/chronos/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1b8144cb49ebcceba14ad3110e439e67d3ed7acf
--- /dev/null
+++ b/boards/chronos/Makefile
@@ -0,0 +1,35 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -Iinclude -I$(RIOTBASE)/sys/lib -I$(RIOTBASE)/sys/drivers/include
+INCLUDES += -I$(RIOTBASE)/sys/drivers/cc110x_ng/include
+INCLUDES += -I$(RIOTBASE)/core/include
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/cc430/include/
+#INCLUDES += -I/usr/msp430/include/
+
+all: $(BINDIR)chronos_base.a 
+	$(MAKE) -C drivers
+
+$(BINDIR)chronos_base.a: $(OBJ)
+	$(AR) rcs $(BINDIR)chronos_base.a $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/fw_out && mv /tmp/fw_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	rm -f $(BINDIR)chronos_base.a $(OBJ) $(DEP)
+	$(MAKE) -C drivers clean
+
+
+
diff --git a/boards/chronos/Makefile.include b/boards/chronos/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..04b77c5d4c70caebea91b8da797c8a4199b44dec
--- /dev/null
+++ b/boards/chronos/Makefile.include
@@ -0,0 +1,22 @@
+## the cpu to build for
+export CPU = cc430
+export MCU = cc430f6137
+
+# toolchain config
+export PREFIX = @msp430-
+export CC = @$(PREFIX)gcc
+export AR = @$(PREFIX)ar
+export CFLAGS += -std=gnu99 -Wstrict-prototypes -gdwarf-2 -Os -Wall -mmcu=$(MCU) -D CC430
+export ASFLAGS += -mmcu=$(MCU) --defsym $(MCU)=1 --gdwarf-2
+export AS = $(PREFIX)as
+export LINK = $(PREFIX)gcc
+export SIZE = $(PREFIX)size
+export OBJCOPY = $(PREFIX)objcopy
+export LINKFLAGS = -mmcu=$(MCU) -lgcc $(RIOTBASE)/bin/startup.o
+export FLASHER = mspdebug
+ifeq ($(strip $(PORT)),)
+	export PORT = /dev/ttyUSB0
+endif
+export HEXFILE = bin/$(PROJECT).hex
+export FFLAGS = -d $(PORT) -j uif "prog $(HEXFILE)"
+export OFLAGS = -O ihex
diff --git a/boards/chronos/board_init.c b/boards/chronos/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..db2326701f25caab99f79886b223e828204dfb7b
--- /dev/null
+++ b/boards/chronos/board_init.c
@@ -0,0 +1,76 @@
+#include <stdint.h>
+#include <board.h>
+#include <cpu.h>
+#include <irq.h>
+
+void cc430_cpu_init(void)
+{
+    volatile uint16_t i;
+    volatile unsigned char *ptr;
+
+    /* disable watchdog */
+    WDTCTL = WDTPW + WDTHOLD;
+
+    // ---------------------------------------------------------------------
+    // Enable 32kHz ACLK
+    P5SEL |= 0x03;                            // Select XIN, XOUT on P5.0 and P5.1
+    UCSCTL6 &= ~XT1OFF;                       // XT1 On, Highest drive strength
+    UCSCTL6 |= XCAP_3;                        // Internal load cap
+
+    UCSCTL3 = SELA__XT1CLK;                   // Select XT1 as FLL reference
+    UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV;
+
+    // ---------------------------------------------------------------------
+    // Configure CPU clock for 12MHz
+    _BIS_SR(SCG0);                  // Disable the FLL control loop
+    UCSCTL0 = 0x0000;          // Set lowest possible DCOx, MODx
+    UCSCTL1 = DCORSEL_5;       // Select suitable range
+    UCSCTL2 = FLLD_1 + 0x16E;  // Set DCO Multiplier
+    _BIC_SR(SCG0);                  // Enable the FLL control loop
+
+    // Worst-case settling time for the DCO when the DCO range bits have been
+    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
+    // UG for optimization.
+    // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
+    for (i = 0xFF; i > 0; i--); // Time for flag to set
+
+    // Loop until XT1 & DCO stabilizes, use do-while to insure that
+    // body is executed at least once
+    do {
+        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
+        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
+    }
+    while ((SFRIFG1 & OFIFG));
+
+    // Disable all interrupts
+    __disable_interrupt();
+    // Get write-access to port mapping registers:
+    PMAPPWD = 0x02D52;
+    // Allow reconfiguration during runtime:
+    PMAPCTL = PMAPRECFG;
+
+    // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output)
+    ptr  = &P2MAP0;
+    *(ptr + 7) = PM_TA1CCR0A;
+    P2OUT &= ~BIT7;
+    P2DIR |= BIT7;
+
+    // P1.5 = SPI MISO input
+    ptr  = &P1MAP0;
+    *(ptr + 5) = PM_UCA0SOMI;
+    // P1.6 = SPI MOSI output
+    *(ptr + 6) = PM_UCA0SIMO;
+    // P1.7 = SPI CLK output
+    *(ptr + 7) = PM_UCA0CLK;
+
+    // Disable write-access to port mapping registers:
+    PMAPPWD = 0;
+    // Re-enable all interrupts
+    enableIRQ();
+
+}
+
+void board_init(void)
+{
+    cc430_cpu_init();
+}
diff --git a/boards/chronos/drivers/Makefile b/boards/chronos/drivers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bf355bf8e258423c5254f880a2cc9fcfc185986e
--- /dev/null
+++ b/boards/chronos/drivers/Makefile
@@ -0,0 +1,24 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBASE)/sys/include/ -I$(RIOTBASE)/drivers/cc110x_ng/include/
+
+$(BINDIR)chronos_drivers.a: $(OBJ)
+	$(AR) rcs $(BINDIR)chronos_base.a $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+
+clean:
+	rm -f $(OBJ) $(DEP)
+
diff --git a/boards/chronos/drivers/battery.c b/boards/chronos/drivers/battery.c
new file mode 100644
index 0000000000000000000000000000000000000000..13e50dc102d5dfb3ac4667a431dd7b39e13cf399
--- /dev/null
+++ b/boards/chronos/drivers/battery.c
@@ -0,0 +1,14 @@
+#include <stdint.h>
+#include <cc430f6137.h>
+#include <cc430-adc.h>
+
+uint32_t battery_get_voltage(void)
+{
+    uint32_t voltage;
+    voltage = adc12_single_conversion(REFVSEL_1, ADC12SHT0_10, ADC12INCH_11);
+
+    /* Ideally we have A11=0->AVCC=0V ... A11=4095(2^12-1)->AVCC=4V
+     * --> (A11/4095)*4V=AVCC --> AVCC=(A11*4)/4095 */
+    voltage = (voltage * 2 * 2 * 1000) / 4095;
+    return voltage;
+}
diff --git a/boards/chronos/drivers/buzzer.c b/boards/chronos/drivers/buzzer.c
new file mode 100644
index 0000000000000000000000000000000000000000..3d4d15061dc977fa20523d46ac8a97884b167998
--- /dev/null
+++ b/boards/chronos/drivers/buzzer.c
@@ -0,0 +1,29 @@
+#include <stdint.h>
+#include <buzzer.h>
+#include <hwtimer.h>
+#include <cc430f6137.h>
+
+void buzzer_beep(uint8_t pitch, uint16_t duration)
+{
+    // Reset TA1R, set up mode, TA1 runs from 32768Hz ACLK
+    TA1CTL = TACLR | MC_1 | TASSEL__ACLK;
+
+    // Set PWM frequency
+    TA1CCR0 = pitch;
+
+    // Enable IRQ, set output mode "toggle"
+    TA1CCTL0 = OUTMOD_4;
+
+    // Allow buzzer PWM output on P2.7
+    P2SEL |= BIT7;
+
+    hwtimer_wait(duration);
+
+    // Stop PWM timer
+    TA1CTL &= ~(BIT4 | BIT5);
+
+    // Reset and disable buzzer PWM output
+    P2OUT &= ~BIT7;
+    P2SEL &= ~BIT7;
+    TA1CCTL0 &= ~CCIE;
+}
diff --git a/boards/chronos/drivers/cc430-cc110x.c b/boards/chronos/drivers/cc430-cc110x.c
new file mode 100644
index 0000000000000000000000000000000000000000..d606d5bfd5783dffb77dc06f2d6af324ad82e9c2
--- /dev/null
+++ b/boards/chronos/drivers/cc430-cc110x.c
@@ -0,0 +1,94 @@
+#include <stdint.h>
+
+#include <cpu.h>
+#include <irq.h>
+#include <cc110x_ng.h>
+#include <cc110x-arch.h>
+
+//#include <cc430_.h>
+#include <cc430f6137.h>
+//#include <msp430/rf1a.h>
+
+#define CC1100_GDO0     (RF1AIN & BIT0)
+#define CC1100_GDO1     (RF1AIN & BIT1)
+#define CC1100_GDO2     (RF1AIN & BIT2)
+
+int cc110x_get_gdo0(void)
+{
+    return 	CC1100_GDO0;
+}
+
+int cc110x_get_gdo1(void)
+{
+    return 	CC1100_GDO1;
+}
+
+int cc110x_get_gdo2(void)
+{
+    return 	CC1100_GDO2;
+}
+
+void cc110x_before_send(void)
+{
+    // Disable GDO2 interrupt before sending packet
+    cc110x_gdo2_disable();
+}
+
+void cc110x_after_send(void)
+{
+    // Enable GDO2 interrupt after sending packet
+    cc110x_gdo2_enable();
+}
+
+void cc110x_gdo0_enable(void)
+{
+    RF1AIFG &= ~BIT0;
+    RF1AIE  |= BIT0;
+}
+
+void cc110x_gdo0_disable(void)
+{
+    RF1AIE  &= ~BIT0;
+    RF1AIFG &= ~BIT0;
+}
+
+void cc110x_gdo2_disable(void)
+{
+    RF1AIFG &= ~BIT2;                         // Clear a pending interrupt
+    RF1AIE  &= ~BIT2;                          // Disable the interrupt
+}
+
+void cc110x_gdo2_enable(void)
+{
+    RF1AIFG &= ~BIT2;                         // Clear a pending interrupt
+    RF1AIE  |= BIT2;                          // Enable the interrupt
+}
+
+void cc110x_init_interrupts(void)
+{
+    uint8_t state = disableIRQ(); /* Disable all interrupts */
+    cc110x_gdo2_enable();
+    cc110x_gdo0_disable();
+    restoreIRQ(state);  /* Enable all interrupts */
+}
+
+interrupt(CC1101_VECTOR) __attribute__((naked)) cc110x_isr(void)
+{
+    __enter_isr();
+
+    /* Check IFG */
+    if (RF1AIV == RF1AIV_RFIFG2) {
+        while (RF1AIN & BIT2);
+
+        /* discard all further interrupts */
+        RF1AIV = 0;
+        cc110x_gdo2_irq();
+    }
+
+    if (RF1AIV == RF1AIV_RFIFG0) {
+        cc110x_gdo0_irq();
+        RF1AIE &= ~BIT0;
+    }
+
+    __exit_isr();
+}
diff --git a/boards/chronos/drivers/display.c b/boards/chronos/drivers/display.c
new file mode 100644
index 0000000000000000000000000000000000000000..b93c820e1e390423acfe05499b962285f53f6cea
--- /dev/null
+++ b/boards/chronos/drivers/display.c
@@ -0,0 +1,418 @@
+/* *************************************************************************************************
+ *
+ *	Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ *	  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 Texas Instruments Incorporated nor the names of
+ *	    its 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.
+ *
+ * *************************************************************************************************
+ * Basic display functions.
+ * ************************************************************************************************/
+
+/* *************************************************************************************************
+ * Include section
+ */
+
+/* system */
+#include <string.h>
+
+/* driver */
+#include <cc430f6137.h>
+#include <display.h>
+
+
+/**************************************************************************************************
+ * Prototypes section */
+void write_lcd_mem(uint8_t *lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state);
+void clear_line(uint8_t line);
+void display_symbol(uint8_t symbol, uint8_t mode);
+
+/* *************************************************************************************************
+ * Global Variable section */
+
+/* Display flags */
+volatile s_display_flags_t display;
+
+/* Global return string for itoa function */
+char itoa_str[8];
+
+void lcd_init(void)
+{
+    /* Clear entire display memory */
+    LCDBMEMCTL |= LCDCLRBM + LCDCLRM;
+
+    /* LCD_FREQ = ACLK/16/8 = 256Hz  */
+    /* Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on */
+    LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON;
+
+    /* LCB_BLK_FREQ = ACLK/8/4096 = 1Hz */
+    LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0;
+
+    /* I/O to COM outputs */
+    P5SEL |= (BIT5 | BIT6 | BIT7);
+    P5DIR |= (BIT5 | BIT6 | BIT7);
+
+    /* Activate LCD output */
+    LCDBPCTL0 = 0xFFFF;                         /* Select LCD segments S0-S15 */
+    LCDBPCTL1 = 0x00FF;                         /* Select LCD segments S16-S22 */
+
+#ifdef USE_LCD_CHARGE_PUMP
+    /* Charge pump voltage generated internally, internal bias (V2-V4) generation */
+    LCDBVCTL = LCDCPEN | VLCD_2_72;
+#endif
+}
+
+void clear_display_all(void)
+{
+    // Clear generic content
+    clear_line(LINE1);
+    clear_line(LINE2);
+}
+
+void clear_display(void)
+{
+    clear_line(LINE1);
+    clear_line(LINE2);
+}
+
+void clear_line(uint8_t line)
+{
+    display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_5_0), NULL, SEG_OFF);
+
+    if (line == LINE1) {
+        display_symbol(LCD_SEG_L1_DP1, SEG_OFF);
+        display_symbol(LCD_SEG_L1_DP0, SEG_OFF);
+        display_symbol(LCD_SEG_L1_COL, SEG_OFF);
+    }
+    /* line == LINE2 */
+    else  {
+        display_symbol(LCD_SEG_L2_DP, SEG_OFF);
+        display_symbol(LCD_SEG_L2_COL1, SEG_OFF);
+        display_symbol(LCD_SEG_L2_COL0, SEG_OFF);
+    }
+}
+
+void write_lcd_mem(uint8_t *lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state)
+{
+    if (state == SEG_ON) {
+        /* Clear segments before writing */
+        *lcdmem = (uint8_t)(*lcdmem & ~bitmask);
+
+        /* Set visible segments */
+        *lcdmem = (uint8_t)(*lcdmem | bits);
+    }
+    else if (state == SEG_OFF) {
+        /* Clear segments */
+        *lcdmem = (uint8_t)(*lcdmem & ~bitmask);
+    }
+    else if (state == SEG_ON_BLINK_ON) {
+        /* Clear visible / blink segments before writing */
+        *lcdmem 		= (uint8_t)(*lcdmem & ~bitmask);
+        *(lcdmem + 0x20) 	= (uint8_t)(*(lcdmem + 0x20) & ~bitmask);
+
+        /* Set visible / blink segments */
+        *lcdmem 		= (uint8_t)(*lcdmem | bits);
+        *(lcdmem + 0x20) 	= (uint8_t)(*(lcdmem + 0x20) | bits);
+    }
+    else if (state == SEG_ON_BLINK_OFF) {
+        /* Clear visible segments before writing */
+        *lcdmem = (uint8_t)(*lcdmem & ~bitmask);
+
+        /* Set visible segments */
+        *lcdmem = (uint8_t)(*lcdmem | bits);
+
+        /* Clear blink segments */
+        *(lcdmem + 0x20) 	= (uint8_t)(*(lcdmem + 0x20) & ~bitmask);
+    }
+    else if (state == SEG_OFF_BLINK_OFF) {
+        /* Clear segments */
+        *lcdmem = (uint8_t)(*lcdmem & ~bitmask);
+
+        /* Clear blink segments */
+        *(lcdmem + 0x20) 	= (uint8_t)(*(lcdmem + 0x20) & ~bitmask);
+    }
+}
+
+char *itoa(uint32_t n, uint8_t digits, uint8_t blanks)
+{
+    uint8_t i;
+    uint8_t digits1 = digits;
+
+    /* Preset result string */
+    memcpy(itoa_str, "0000000", 7);
+
+    /* Return empty string if number of digits is invalid (valid range for digits: 1-7) */
+    if ((digits == 0) || (digits > 7))  {
+        return (itoa_str);
+    }
+
+    /* Numbers 0 .. 180 can be copied from itoa_conversion_table without conversion */
+    if (n <= 180) {
+        if (digits >= 3) {
+            memcpy(itoa_str + (digits - 3), itoa_conversion_table[n], 3);
+        }
+        /* digits == 1 || 2   */
+        else {
+            memcpy(itoa_str, itoa_conversion_table[n] + (3 - digits), digits);
+        }
+    }
+    /* For n > 180 need to calculate string content */
+    else {
+        /* Calculate digits from least to most significant number */
+        do {
+            itoa_str[digits - 1] = n % 10 + '0';
+            n /= 10;
+        }
+        while (--digits > 0);
+    }
+
+    /* Remove specified number of leading '0', always keep last one */
+    i = 0;
+
+    while ((itoa_str[i] == '0') && (i < digits1 - 1))	{
+        if (blanks > 0) {
+            /* Convert only specified number of leading '0' */
+            itoa_str[i] = ' ';
+            blanks--;
+        }
+
+        i++;
+    }
+
+    return (itoa_str);
+}
+
+void display_value1(uint8_t segments, uint32_t value, uint8_t digits, uint8_t blanks, uint8_t disp_mode)
+{
+    char *str;
+
+    str = itoa(value, digits, blanks);
+
+    /* Display string in blink mode */
+    display_chars(segments, str, disp_mode);
+}
+
+void display_symbol(uint8_t symbol, uint8_t mode)
+{
+    uint8_t *lcdmem;
+    uint8_t bits;
+    uint8_t bitmask;
+
+    if (symbol <= LCD_SEG_L2_DP) {
+        /* Get LCD memory address for symbol from table */
+        lcdmem 	= (uint8_t *)segments_lcdmem[symbol];
+
+        /* Get bits for symbol from table */
+        bits 	= segments_bitmask[symbol];
+
+        /* Bitmask for symbols equals bits */
+        bitmask = bits;
+
+        /* Write LCD memory 	 */
+        write_lcd_mem(lcdmem, bits, bitmask, mode);
+    }
+}
+
+void display_char(uint8_t segment, char chr, uint8_t mode)
+{
+    uint8_t *lcdmem;			/* Pointer to LCD memory */
+    uint8_t bitmask;			/* Bitmask for character */
+    uint8_t bits, bits1;		/* Bits to write */
+
+    /* Write to single 7-segment character */
+    if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP)) {
+        /* Get LCD memory address for segment from table */
+        lcdmem = (uint8_t *)segments_lcdmem[segment];
+
+        /* Get bitmask for character from table */
+        bitmask = segments_bitmask[segment];
+
+        /* Get bits from font set */
+        if ((chr >= 0x30) && (chr <= 0x5A)) {
+            /* Use font set */
+            bits = lcd_font[chr - 0x30];
+        }
+        else if (chr == 0x2D) {
+            /* '-' not in font set */
+            bits = BIT1;
+        }
+        else {
+            /* Other characters map to ' ' (blank) */
+            bits = 0;
+        }
+
+        /* When addressing LINE2 7-segment characters need to swap high- and low-nibble, */
+        /* because LCD COM/SEG assignment is mirrored against LINE1 */
+        if (segment >= LCD_SEG_L2_5) {
+            bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F);
+            bits = bits1;
+
+            /* When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit, */
+            /* because LCD COM/SEG assignment is special for this incomplete character */
+            if (segment == LCD_SEG_L2_5) {
+                if ((chr == '1') || (chr == 'L')) {
+                    bits = BIT7;
+                }
+            }
+        }
+
+        /* Physically write to LCD memory		 */
+        write_lcd_mem(lcdmem, bits, bitmask, mode);
+    }
+}
+
+void display_chars(uint8_t segments, char *str, uint8_t mode)
+{
+    uint8_t i;
+    uint8_t length = 0;			/* Write length */
+    uint8_t char_start = 0;			/* Starting point for consecutive write */
+
+    switch (segments) {
+            /* LINE1 */
+        case LCD_SEG_L1_3_0:
+            length = 4;
+            char_start = LCD_SEG_L1_3;
+            break;
+
+        case LCD_SEG_L1_2_0:
+            length = 3;
+            char_start = LCD_SEG_L1_2;
+            break;
+
+        case LCD_SEG_L1_1_0:
+            length = 2;
+            char_start = LCD_SEG_L1_1;
+            break;
+
+        case LCD_SEG_L1_3_1:
+            length = 3;
+            char_start = LCD_SEG_L1_3;
+            break;
+
+        case LCD_SEG_L1_3_2:
+            length = 2;
+            char_start = LCD_SEG_L1_3;
+            break;
+
+            /* LINE2 */
+        case LCD_SEG_L2_5_0:
+            length = 6;
+            char_start = LCD_SEG_L2_5;
+            break;
+
+        case LCD_SEG_L2_4_0:
+            length = 5;
+            char_start = LCD_SEG_L2_4;
+            break;
+
+        case LCD_SEG_L2_3_0:
+            length = 4;
+            char_start = LCD_SEG_L2_3;
+            break;
+
+        case LCD_SEG_L2_2_0:
+            length = 3;
+            char_start = LCD_SEG_L2_2;
+            break;
+
+        case LCD_SEG_L2_1_0:
+            length = 2;
+            char_start = LCD_SEG_L2_1;
+            break;
+
+        case LCD_SEG_L2_5_4:
+            length = 2;
+            char_start = LCD_SEG_L2_5;
+            break;
+
+        case LCD_SEG_L2_5_2:
+            length = 4;
+            char_start = LCD_SEG_L2_5;
+            break;
+
+        case LCD_SEG_L2_3_2:
+            length = 2;
+            char_start = LCD_SEG_L2_3;
+            break;
+
+        case LCD_SEG_L2_4_2:
+            length = 3;
+            char_start = LCD_SEG_L2_4;
+            break;
+    }
+
+    /* Write to consecutive digits */
+    for (i = 0; i < length; i++) {
+        /* Use single character routine to write display memory */
+        display_char(char_start + i, *(str + i), mode);
+    }
+}
+
+uint8_t switch_seg(uint8_t line, uint8_t index1, uint8_t index2)
+{
+    if (line == LINE1) {
+        return index1;
+    }
+    /* line == LINE2 */
+    else {
+        return index2;
+    }
+}
+
+void start_blink(void)
+{
+    LCDBBLKCTL |= LCDBLKMOD0;
+}
+
+void stop_blink(void)
+{
+    LCDBBLKCTL &= ~LCDBLKMOD0;
+}
+
+void clear_blink_mem(void)
+{
+    LCDBMEMCTL |= LCDCLRBM;
+}
+
+void set_blink_rate(uint8_t bits)
+{
+    LCDBBLKCTL &= ~(BIT7 | BIT6 | BIT5);
+    LCDBBLKCTL |= bits;
+}
+
+void display_all_off(void)
+{
+    uint8_t *lcdptr = (uint8_t *)0x0A20;
+    uint8_t i;
+
+    for (i = 1; i <= 12; i++) {
+        *lcdptr = 0x00;
+        lcdptr++;
+    }
+}
diff --git a/boards/chronos/drivers/display1.c b/boards/chronos/drivers/display1.c
new file mode 100644
index 0000000000000000000000000000000000000000..461c0c0097d974556ee5272c643fadffb5fd7759
--- /dev/null
+++ b/boards/chronos/drivers/display1.c
@@ -0,0 +1,208 @@
+/* *************************************************************************************************
+ *
+ *	Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ *	  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 Texas Instruments Incorporated nor the names of
+ *	    its 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.
+ *
+ * ************************************************************************************************/
+
+/* Basic display functions. */
+/* ************************************************************************************************* */
+
+/* ************************************************************************************************* */
+/* Include section */
+#include <stdint.h>
+#include <cc430f6137.h>
+#include <display.h>
+
+/* ************************************************************************************************* */
+/* Global Variable section */
+
+/* Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z" */
+/*   A */
+/* F   B */
+/*   G */
+/* E   C */
+/*   D */
+const uint8_t lcd_font[] = {
+    SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F,          /* Displays "0" */
+    SEG_B + SEG_C,                                          /* Displays "1" */
+    SEG_A + SEG_B +         SEG_D + SEG_E +         SEG_G,  /* Displays "2" */
+    SEG_A + SEG_B + SEG_C + SEG_D +                 SEG_G,  /* Displays "3" */
+            SEG_B + SEG_C +                 SEG_F + SEG_G,  /* Displays "4" */
+    SEG_A +         SEG_C + SEG_D +         SEG_F + SEG_G,  /* Displays "5" */
+    SEG_A +         SEG_C + SEG_D + SEG_E + SEG_F + SEG_G,  /* Displays "6" */
+    SEG_A + SEG_B + SEG_C,                                  /* Displays "7" */
+    SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G,  /* Displays "8" */
+    SEG_A + SEG_B + SEG_C + SEG_D +         SEG_F + SEG_G,  /* Displays "9" */
+    0,                                                      /* Displays " " (:) */
+    0,                                                      /* Displays " " (;) */
+    SEG_A +                                 SEG_F + SEG_G,  /* Displays "<" as high c */
+    SEG_D +                                         SEG_G,  /* Displays "=" */
+    0,                                                      /* Displays " " (>) */
+    SEG_A + SEG_B +                 SEG_E +         SEG_G,  /* Displays "?" */
+    0,                                                      /* Displays " " (@) */
+    SEG_A + SEG_B + SEG_C +         SEG_E + SEG_F + SEG_G,  /* Displays "A" */
+                    SEG_C + SEG_D + SEG_E + SEG_F + SEG_G,  /* Displays "b" */
+                            SEG_D + SEG_E +         SEG_G,  /* Displays "c" */
+            SEG_B + SEG_C + SEG_D + SEG_E +         SEG_G,  /* Displays "d" */
+    SEG_A +                 SEG_D + SEG_E + SEG_F + SEG_G,  /* Displays "E" */
+    SEG_A +                         SEG_E + SEG_F + SEG_G,  /* Displays "f" */
+    SEG_A + SEG_B + SEG_C + SEG_D +         SEG_F + SEG_G,  /* Displays "g" same as 9 */
+    SEG_C +                         SEG_E + SEG_F + SEG_G,  /* Displays "h" */
+                                    SEG_E,                  /* Displays "i" */
+    SEG_A + SEG_B + SEG_C + SEG_D,                          /* Displays "J" */
+                            SEG_D +         SEG_F + SEG_G,  /* Displays "k" */
+                            SEG_D + SEG_E + SEG_F,          /* Displays "L" */
+    SEG_A + SEG_B + SEG_C +         SEG_E + SEG_F,          /* Displays "M" */
+                    SEG_C +         SEG_E +         SEG_G,  /* Displays "n" */
+                    SEG_C + SEG_D + SEG_E +         SEG_G,  /* Displays "o" */
+    SEG_A + SEG_B +                 SEG_E + SEG_F + SEG_G,  /* Displays "P" */
+    SEG_A + SEG_B + SEG_C +                 SEG_F + SEG_G,  /* Displays "q" */
+                                    SEG_E +         SEG_G,  /* Displays "r" */
+    SEG_A +         SEG_C + SEG_D +         SEG_F + SEG_G,  /* Displays "S" same as 5 */
+                            SEG_D + SEG_E + SEG_F + SEG_G,  /* Displays "t" */
+                    SEG_C + SEG_D + SEG_E,                  /* Displays "u" */
+                    SEG_C + SEG_D + SEG_E,                  /* Displays "v" same as u */
+            SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G,  /* Displays "W" */
+            SEG_B + SEG_C +         SEG_E + SEG_F + SEG_G,  /* Displays "X" as H */
+            SEG_B + SEG_C + SEG_D +         SEG_F + SEG_G,  /* Displays "Y" */
+    SEG_A + SEG_B +         SEG_D + SEG_E +         SEG_G,  /* Displays "Z" same as 2 */
+};
+
+/* Table with memory address for each display element  */
+const uint8_t *segments_lcdmem[] = {
+    LCD_SYMB_AM_MEM,
+    LCD_SYMB_PM_MEM,
+    LCD_SYMB_ARROW_UP_MEM,
+    LCD_SYMB_ARROW_DOWN_MEM,
+    LCD_SYMB_PERCENT_MEM,
+    LCD_SYMB_TOTAL_MEM,
+    LCD_SYMB_AVERAGE_MEM,
+    LCD_SYMB_MAX_MEM,
+    LCD_SYMB_BATTERY_MEM,
+    LCD_UNIT_L1_FT_MEM,
+    LCD_UNIT_L1_K_MEM,
+    LCD_UNIT_L1_M_MEM,
+    LCD_UNIT_L1_I_MEM,
+    LCD_UNIT_L1_PER_S_MEM,
+    LCD_UNIT_L1_PER_H_MEM,
+    LCD_UNIT_L1_DEGREE_MEM,
+    LCD_UNIT_L2_KCAL_MEM,
+    LCD_UNIT_L2_KM_MEM,
+    LCD_UNIT_L2_MI_MEM,
+    LCD_ICON_HEART_MEM,
+    LCD_ICON_STOPWATCH_MEM,
+    LCD_ICON_RECORD_MEM,
+    LCD_ICON_ALARM_MEM,
+    LCD_ICON_BEEPER1_MEM,
+    LCD_ICON_BEEPER2_MEM,
+    LCD_ICON_BEEPER3_MEM,
+    LCD_SEG_L1_3_MEM,
+    LCD_SEG_L1_2_MEM,
+    LCD_SEG_L1_1_MEM,
+    LCD_SEG_L1_0_MEM,
+    LCD_SEG_L1_COL_MEM,
+    LCD_SEG_L1_DP1_MEM,
+    LCD_SEG_L1_DP0_MEM,
+    LCD_SEG_L2_5_MEM,
+    LCD_SEG_L2_4_MEM,
+    LCD_SEG_L2_3_MEM,
+    LCD_SEG_L2_2_MEM,
+    LCD_SEG_L2_1_MEM,
+    LCD_SEG_L2_0_MEM,
+    LCD_SEG_L2_COL1_MEM,
+    LCD_SEG_L2_COL0_MEM,
+    LCD_SEG_L2_DP_MEM,
+};
+
+/* Table with bit mask for each display element  */
+const uint8_t segments_bitmask[] = {
+    LCD_SYMB_AM_MASK,
+    LCD_SYMB_PM_MASK,
+    LCD_SYMB_ARROW_UP_MASK,
+    LCD_SYMB_ARROW_DOWN_MASK,
+    LCD_SYMB_PERCENT_MASK,
+    LCD_SYMB_TOTAL_MASK,
+    LCD_SYMB_AVERAGE_MASK,
+    LCD_SYMB_MAX_MASK,
+    LCD_SYMB_BATTERY_MASK,
+    LCD_UNIT_L1_FT_MASK,
+    LCD_UNIT_L1_K_MASK,
+    LCD_UNIT_L1_M_MASK,
+    LCD_UNIT_L1_I_MASK,
+    LCD_UNIT_L1_PER_S_MASK,
+    LCD_UNIT_L1_PER_H_MASK,
+    LCD_UNIT_L1_DEGREE_MASK,
+    LCD_UNIT_L2_KCAL_MASK,
+    LCD_UNIT_L2_KM_MASK,
+    LCD_UNIT_L2_MI_MASK,
+    LCD_ICON_HEART_MASK,
+    LCD_ICON_STOPWATCH_MASK,
+    LCD_ICON_RECORD_MASK,
+    LCD_ICON_ALARM_MASK,
+    LCD_ICON_BEEPER1_MASK,
+    LCD_ICON_BEEPER2_MASK,
+    LCD_ICON_BEEPER3_MASK,
+    LCD_SEG_L1_3_MASK,
+    LCD_SEG_L1_2_MASK,
+    LCD_SEG_L1_1_MASK,
+    LCD_SEG_L1_0_MASK,
+    LCD_SEG_L1_COL_MASK,
+    LCD_SEG_L1_DP1_MASK,
+    LCD_SEG_L1_DP0_MASK,
+    LCD_SEG_L2_5_MASK,
+    LCD_SEG_L2_4_MASK,
+    LCD_SEG_L2_3_MASK,
+    LCD_SEG_L2_2_MASK,
+    LCD_SEG_L2_1_MASK,
+    LCD_SEG_L2_0_MASK,
+    LCD_SEG_L2_COL1_MASK,
+    LCD_SEG_L2_COL0_MASK,
+    LCD_SEG_L2_DP_MASK,
+};
+
+/* Quick integer to array conversion table for most common integer values
+ * discarding this would save aprox. 600 bytes codespace but increase cpu time
+ * for displaying values */
+const uint8_t itoa_conversion_table[][3] = {
+    "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015",
+    "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", "030", "031",
+    "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", "045", "046", "047",
+    "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", "061", "062", "063",
+    "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", "077", "078", "079",
+    "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", "093", "094", "095",
+    "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111",
+    "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127",
+    "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143",
+    "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
+    "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175",
+    "176", "177", "178", "179", "180",
+};
diff --git a/boards/chronos/drivers/display_putchar.c b/boards/chronos/drivers/display_putchar.c
new file mode 100644
index 0000000000000000000000000000000000000000..95498ea8e07fb19f6f9c755179436500b2beecf5
--- /dev/null
+++ b/boards/chronos/drivers/display_putchar.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <display.h>
+#include <string.h>
+
+extern int toupper(int c);
+extern void (*_putchar)(int c);
+
+static char display_buf[11];
+
+void putchar_to_display(int c);
+
+void init_display_putchar(void)
+{
+    memset(display_buf, '\0', 11);
+    _putchar = putchar_to_display;
+}
+
+void putchar_to_display(int c)
+{
+    if (c == '\n') {
+        display_buf[4] = 1;
+        return;
+    }
+
+    if (display_buf[4]) {
+        memset(display_buf, '\0', 11);
+    }
+    else {
+        display_buf[0] = display_buf[1];
+        display_buf[1] = display_buf[2];
+        display_buf[2] = display_buf[3];
+        display_buf[3] = display_buf[5];
+        display_buf[5] = display_buf[6];
+        display_buf[6] = display_buf[7];
+        display_buf[7] = display_buf[8];
+        display_buf[8] = display_buf[9];
+    }
+
+    display_buf[9] = toupper(c);
+
+    clear_display_all();
+
+    display_chars(LCD_SEG_L1_3_0, display_buf, SEG_ON);
+    display_chars(LCD_SEG_L2_5_0, display_buf + 4, SEG_ON);
+}
diff --git a/boards/chronos/drivers/include/battery.h b/boards/chronos/drivers/include/battery.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1f1569799c36e6110948f64e9281f26cf1cdc85
--- /dev/null
+++ b/boards/chronos/drivers/include/battery.h
@@ -0,0 +1,6 @@
+#ifndef BATTERY_H
+#define BATTERY_H
+
+uint32_t battery_get_voltage(void);
+
+#endif /* BATTERY_H */
diff --git a/boards/chronos/drivers/include/buzzer.h b/boards/chronos/drivers/include/buzzer.h
new file mode 100644
index 0000000000000000000000000000000000000000..47ccb81112cf720ca29ba1d4ac540819781d18ff
--- /dev/null
+++ b/boards/chronos/drivers/include/buzzer.h
@@ -0,0 +1,6 @@
+#ifndef BUZZER_H
+#define BUZZER_H
+
+void buzzer_beep(uint8_t pitch, uint16_t duration);
+
+#endif /* BUZZER_H */
diff --git a/boards/chronos/drivers/include/display.h b/boards/chronos/drivers/include/display.h
new file mode 100644
index 0000000000000000000000000000000000000000..533ce1e1db590d7832920cd673fa3118769fbe06
--- /dev/null
+++ b/boards/chronos/drivers/include/display.h
@@ -0,0 +1,458 @@
+/* *************************************************************************************************
+ *
+ *  Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ *    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 Texas Instruments Incorporated nor the names of
+ *      its 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.
+ *
+ * *************************************************************************************************
+ * Basic display functions.
+ * ************************************************************************************************/
+
+#ifndef __DISPLAY_H
+#define __DISPLAY_H
+
+#define CLOCK_24HR              (0)
+#define CLOCK_AM_PM             (1)
+#define CLOCK_DISPLAY_SELECT    (2)
+
+
+/* *************************************************************************************************
+ * Global Variable section */
+
+/* Set of display flags */
+typedef union {
+    struct {
+        /* Line1 + Line2 + Icons*/
+        uint16_t full_update            : 1;    /* 1 = Redraw all content */
+        uint16_t partial_update         : 1;    /* 1 = Update changes */
+
+        /* Line only */
+        uint16_t line1_full_update      : 1;    /* 1 = Redraw Line1 content */
+        uint16_t line2_full_update      : 1;    /* 1 = Redraw Line2 content */
+
+        /* Logic module data update flags */
+        uint16_t update_time            : 1;    /* 1 = Time was updated */
+        uint16_t update_stopwatch       : 1;    /* 1 = Stopwatch was updated */
+        uint16_t update_temperature     : 1;    /* 1 = Temperature was updated */
+        uint16_t update_battery_voltage : 1;    /* 1 = Battery voltage was updated */
+        uint16_t update_date            : 1;    /* 1 = Date was updated */
+        uint16_t update_alarm           : 1;    /* 1 = Alarm time was updated */
+        uint16_t update_acceleration    : 1;    /* 1 = Acceleration data was updated */
+    } flag;
+    uint16_t all_flags;            /* Shortcut to all display flags (for reset) */
+} s_display_flags_t;
+
+extern volatile s_display_flags_t display;
+
+/* Constants defined in library */
+extern const uint8_t lcd_font[];
+extern const uint8_t *segments_lcdmem[];
+extern const uint8_t segments_bitmask[];
+extern const uint8_t itoa_conversion_table[][3];
+
+/* ************************************************************************************************* */
+/* Defines section */
+
+/* Display function modes */
+#define DISPLAY_LINE_UPDATE_FULL        (BIT0)
+#define DISPLAY_LINE_UPDATE_PARTIAL     (BIT1)
+#define DISPLAY_LINE_CLEAR              (BIT2)
+
+/* Definitions for line view style */
+#define DISPLAY_DEFAULT_VIEW            (0u)
+#define DISPLAY_ALTERNATIVE_VIEW        (1u)
+#define DISPLAY_ALTERNATIVE2_VIEW       (2u)
+
+/* Definitions for line access */
+#define LINE1                           (1u)
+#define LINE2                           (2u)
+
+/* LCD display modes */
+#define SEG_OFF                 (0u)
+#define SEG_ON                  (1u)
+#define SEG_ON_BLINK_ON         (2u)
+#define SEG_ON_BLINK_OFF        (3u)
+#define SEG_OFF_BLINK_OFF       (4u)
+
+/* 7-segment character bit assignments */
+#define SEG_A                   (BIT4)
+#define SEG_B                   (BIT5)
+#define SEG_C                   (BIT6)
+#define SEG_D                   (BIT7)
+#define SEG_E                   (BIT2)
+#define SEG_F                   (BIT0)
+#define SEG_G                   (BIT1)
+
+/* ------------------------------------------
+ * LCD symbols for easier access
+ *
+ * xxx_SEG_xxx      = Seven-segment character (sequence 5-4-3-2-1-0)
+ * xxx_SYMB_xxx     = Display symbol, e.g. "AM" for ante meridiem
+ * xxx_UNIT_xxx     = Display unit, e.g. "km/h" for kilometers per hour
+ * xxx_ICON_xxx     = Display icon, e.g. heart to indicate reception of heart rate data
+ * xxx_L1_xxx       = Item is part of Line1 information
+ * xxx_L2_xxx       = Item is part of Line2 information
+ */
+
+//* Symbols for Line1 */
+#define LCD_SYMB_AM                 0
+#define LCD_SYMB_PM                 1
+#define LCD_SYMB_ARROW_UP           2
+#define LCD_SYMB_ARROW_DOWN         3
+#define LCD_SYMB_PERCENT            4
+
+/* Symbols for Line2 */
+#define LCD_SYMB_TOTAL              5
+#define LCD_SYMB_AVERAGE            6
+#define LCD_SYMB_MAX                7
+#define LCD_SYMB_BATTERY            8
+
+/* Units for Line1 */
+#define LCD_UNIT_L1_FT              9
+#define LCD_UNIT_L1_K               10
+#define LCD_UNIT_L1_M               11
+#define LCD_UNIT_L1_I               12
+#define LCD_UNIT_L1_PER_S           13
+#define LCD_UNIT_L1_PER_H           14
+#define LCD_UNIT_L1_DEGREE          15
+
+/* Units for Line2 */
+#define LCD_UNIT_L2_KCAL            16
+#define LCD_UNIT_L2_KM              17
+#define LCD_UNIT_L2_MI              18
+
+/* Icons */
+#define LCD_ICON_HEART              19
+#define LCD_ICON_STOPWATCH          20
+#define LCD_ICON_RECORD             21
+#define LCD_ICON_ALARM              22
+#define LCD_ICON_BEEPER1            23
+#define LCD_ICON_BEEPER2            24
+#define LCD_ICON_BEEPER3            25
+
+/* Line1 7-segments */
+#define LCD_SEG_L1_3                26
+#define LCD_SEG_L1_2                27
+#define LCD_SEG_L1_1                28
+#define LCD_SEG_L1_0                29
+#define LCD_SEG_L1_COL              30
+#define LCD_SEG_L1_DP1              31
+#define LCD_SEG_L1_DP0              32
+
+/* Line2 7-segments */
+#define LCD_SEG_L2_5                33
+#define LCD_SEG_L2_4                34
+#define LCD_SEG_L2_3                35
+#define LCD_SEG_L2_2                36
+#define LCD_SEG_L2_1                37
+#define LCD_SEG_L2_0                38
+#define LCD_SEG_L2_COL1             39
+#define LCD_SEG_L2_COL0             40
+#define LCD_SEG_L2_DP               41
+
+/* Line1 7-segment arrays */
+#define LCD_SEG_L1_3_0              70
+#define LCD_SEG_L1_2_0              71
+#define LCD_SEG_L1_1_0              72
+#define LCD_SEG_L1_3_1              73
+#define LCD_SEG_L1_3_2              74
+
+/* Line2 7-segment arrays */
+#define LCD_SEG_L2_5_0              90
+#define LCD_SEG_L2_4_0              91
+#define LCD_SEG_L2_3_0              92
+#define LCD_SEG_L2_2_0              93
+#define LCD_SEG_L2_1_0              94
+#define LCD_SEG_L2_5_2              95
+#define LCD_SEG_L2_3_2              96
+#define LCD_SEG_L2_5_4              97
+#define LCD_SEG_L2_4_2              98
+
+/* LCD controller memory map */
+#define LCD_MEM_1                   ((uint8_t*)0x0A20)
+#define LCD_MEM_2                   ((uint8_t*)0x0A21)
+#define LCD_MEM_3                   ((uint8_t*)0x0A22)
+#define LCD_MEM_4                   ((uint8_t*)0x0A23)
+#define LCD_MEM_5                   ((uint8_t*)0x0A24)
+#define LCD_MEM_6                   ((uint8_t*)0x0A25)
+#define LCD_MEM_7                   ((uint8_t*)0x0A26)
+#define LCD_MEM_8                   ((uint8_t*)0x0A27)
+#define LCD_MEM_9                   ((uint8_t*)0x0A28)
+#define LCD_MEM_10                  ((uint8_t*)0x0A29)
+#define LCD_MEM_11                  ((uint8_t*)0x0A2A)
+#define LCD_MEM_12                  ((uint8_t*)0x0A2B)
+
+/* Memory assignment */
+#define LCD_SEG_L1_0_MEM            (LCD_MEM_6)
+#define LCD_SEG_L1_1_MEM            (LCD_MEM_4)
+#define LCD_SEG_L1_2_MEM            (LCD_MEM_3)
+#define LCD_SEG_L1_3_MEM            (LCD_MEM_2)
+#define LCD_SEG_L1_COL_MEM          (LCD_MEM_1)
+#define LCD_SEG_L1_DP1_MEM          (LCD_MEM_1)
+#define LCD_SEG_L1_DP0_MEM          (LCD_MEM_5)
+#define LCD_SEG_L2_0_MEM            (LCD_MEM_8)
+#define LCD_SEG_L2_1_MEM            (LCD_MEM_9)
+#define LCD_SEG_L2_2_MEM            (LCD_MEM_10)
+#define LCD_SEG_L2_3_MEM            (LCD_MEM_11)
+#define LCD_SEG_L2_4_MEM            (LCD_MEM_12)
+#define LCD_SEG_L2_5_MEM            (LCD_MEM_12)
+#define LCD_SEG_L2_COL1_MEM         (LCD_MEM_1)
+#define LCD_SEG_L2_COL0_MEM         (LCD_MEM_5)
+#define LCD_SEG_L2_DP_MEM           (LCD_MEM_9)
+#define LCD_SYMB_AM_MEM             (LCD_MEM_1)
+#define LCD_SYMB_PM_MEM             (LCD_MEM_1)
+#define LCD_SYMB_ARROW_UP_MEM       (LCD_MEM_1)
+#define LCD_SYMB_ARROW_DOWN_MEM     (LCD_MEM_1)
+#define LCD_SYMB_PERCENT_MEM        (LCD_MEM_5)
+#define LCD_SYMB_TOTAL_MEM          (LCD_MEM_11)
+#define LCD_SYMB_AVERAGE_MEM        (LCD_MEM_10)
+#define LCD_SYMB_MAX_MEM            (LCD_MEM_8)
+#define LCD_SYMB_BATTERY_MEM        (LCD_MEM_7)
+#define LCD_UNIT_L1_FT_MEM          (LCD_MEM_5)
+#define LCD_UNIT_L1_K_MEM           (LCD_MEM_5)
+#define LCD_UNIT_L1_M_MEM           (LCD_MEM_7)
+#define LCD_UNIT_L1_I_MEM           (LCD_MEM_7)
+#define LCD_UNIT_L1_PER_S_MEM       (LCD_MEM_5)
+#define LCD_UNIT_L1_PER_H_MEM       (LCD_MEM_7)
+#define LCD_UNIT_L1_DEGREE_MEM      (LCD_MEM_5)
+#define LCD_UNIT_L2_KCAL_MEM        (LCD_MEM_7)
+#define LCD_UNIT_L2_KM_MEM          (LCD_MEM_7)
+#define LCD_UNIT_L2_MI_MEM          (LCD_MEM_7)
+#define LCD_ICON_HEART_MEM          (LCD_MEM_2)
+#define LCD_ICON_STOPWATCH_MEM      (LCD_MEM_3)
+#define LCD_ICON_RECORD_MEM         (LCD_MEM_1)
+#define LCD_ICON_ALARM_MEM          (LCD_MEM_4)
+#define LCD_ICON_BEEPER1_MEM        (LCD_MEM_5)
+#define LCD_ICON_BEEPER2_MEM        (LCD_MEM_6)
+#define LCD_ICON_BEEPER3_MEM        (LCD_MEM_7)
+
+/* Bit masks for write access */
+#define LCD_SEG_L1_0_MASK           (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
+#define LCD_SEG_L1_1_MASK           (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
+#define LCD_SEG_L1_2_MASK           (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
+#define LCD_SEG_L1_3_MASK           (BIT2+BIT1+BIT0+BIT7+BIT6+BIT5+BIT4)
+#define LCD_SEG_L1_COL_MASK         (BIT5)
+#define LCD_SEG_L1_DP1_MASK         (BIT6)
+#define LCD_SEG_L1_DP0_MASK         (BIT2)
+#define LCD_SEG_L2_0_MASK           (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
+#define LCD_SEG_L2_1_MASK           (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
+#define LCD_SEG_L2_2_MASK           (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
+#define LCD_SEG_L2_3_MASK           (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
+#define LCD_SEG_L2_4_MASK           (BIT3+BIT2+BIT1+BIT0+BIT6+BIT5+BIT4)
+#define LCD_SEG_L2_5_MASK           (BIT7)
+#define LCD_SEG_L2_COL1_MASK        (BIT4)
+#define LCD_SEG_L2_COL0_MASK        (BIT0)
+#define LCD_SEG_L2_DP_MASK          (BIT7)
+#define LCD_SYMB_AM_MASK            (BIT1+BIT0)
+#define LCD_SYMB_PM_MASK            (BIT0)
+#define LCD_SYMB_ARROW_UP_MASK      (BIT2)
+#define LCD_SYMB_ARROW_DOWN_MASK    (BIT3)
+#define LCD_SYMB_PERCENT_MASK       (BIT4)
+#define LCD_SYMB_TOTAL_MASK         (BIT7)
+#define LCD_SYMB_AVERAGE_MASK       (BIT7)
+#define LCD_SYMB_MAX_MASK           (BIT7)
+#define LCD_SYMB_BATTERY_MASK       (BIT7)
+#define LCD_UNIT_L1_FT_MASK         (BIT5)
+#define LCD_UNIT_L1_K_MASK          (BIT6)
+#define LCD_UNIT_L1_M_MASK          (BIT1)
+#define LCD_UNIT_L1_I_MASK          (BIT0)
+#define LCD_UNIT_L1_PER_S_MASK      (BIT7)
+#define LCD_UNIT_L1_PER_H_MASK      (BIT2)
+#define LCD_UNIT_L1_DEGREE_MASK     (BIT1)
+#define LCD_UNIT_L2_KCAL_MASK       (BIT4)
+#define LCD_UNIT_L2_KM_MASK         (BIT5)
+#define LCD_UNIT_L2_MI_MASK         (BIT6)
+#define LCD_ICON_HEART_MASK         (BIT3)
+#define LCD_ICON_STOPWATCH_MASK     (BIT3)
+#define LCD_ICON_RECORD_MASK        (BIT7)
+#define LCD_ICON_ALARM_MASK         (BIT3)
+#define LCD_ICON_BEEPER1_MASK       (BIT3)
+#define LCD_ICON_BEEPER2_MASK       (BIT3)
+#define LCD_ICON_BEEPER3_MASK       (BIT3)
+
+
+/* *************************************************************************************************
+ * API section
+ */
+
+/* Physical LCD memory write */
+/* *************************************************************************************************
+ * @fn          write_segment
+ * @brief       Write to one or multiple LCD segments
+ * @param       lcdmem      Pointer to LCD byte memory
+ *              bits        Segments to address
+ *              bitmask     Bitmask for particular display item
+ *              mode        On, off or blink segments
+ * @return
+ * ************************************************************************************************/
+void write_lcd_mem(uint8_t *lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state);
+
+/* Display init / clear */
+/* *************************************************************************************************
+ * @fn          lcd_init
+ * @brief       Erase LCD memory. Init LCD peripheral.
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void lcd_init(void);
+
+/* *************************************************************************************************
+ * @fn          clear_display
+ * @brief       Erase LINE1 and LINE2 segments. Keep icons.
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void clear_display(void);
+
+/* *************************************************************************************************
+ * @fn          clear_display_all
+ * @brief       Erase LINE1 and LINE2 segments. Clear also function-specific content.
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void clear_display_all(void);
+
+/* *************************************************************************************************
+ * @fn          clear_line
+ * @brief       Erase segments of a given line.
+ * @param       uint8_t line    LINE1, LINE2
+ * @return      none
+ * ************************************************************************************************/
+void clear_line(uint8_t line);
+
+/* Blinking function */
+/* *************************************************************************************************
+ * @fn          start_blink
+ * @brief       Start blinking.
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void start_blink(void);
+
+/* *************************************************************************************************
+ * @fn          stop_blink
+ * @brief       Stop blinking.
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void stop_blink(void);
+
+/* *************************************************************************************************
+ * @fn          stop_blink
+ * @brief       Clear blinking memory.
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void clear_blink_mem(void);
+
+/* *************************************************************************************************
+ * @fn          set_blink_rate
+ * @brief       Set blink rate register bits.
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void set_blink_rate(uint8_t bits);
+
+/* Character / symbol draw functions */
+/* *************************************************************************************************
+ * @fn          display_char
+ * @brief       Write to 7-segment characters.
+ * @param       uint8_t segment     A valid LCD segment
+ *              uint8_t chr         Character to display
+ *              uint8_t mode        SEG_ON, SEG_OFF, SEG_BLINK
+ * @return      none
+ * ************************************************************************************************/
+void display_char(uint8_t segment, char chr, uint8_t mode);
+
+/* *************************************************************************************************
+ * @FN          display_chars
+ * @brief       Write to consecutive 7-segment characters.
+ * @param       uint8_t segments    LCD segment array
+ *              uint8_t * str       Pointer to a string
+ *              uint8_t mode        SEG_ON, SEG_OFF, SEG_BLINK
+ * @return      none
+ * ************************************************************************************************/
+void display_chars(uint8_t segments, char *str, uint8_t mode);
+
+/* *************************************************************************************************
+ * @fn          display_symbol
+ * @brief       Switch symbol on or off on LCD.
+ * @param       uint8_t symbol      A valid LCD symbol (index 0..42)
+ *              uint8_t state       SEG_ON, SEG_OFF, SEG_BLINK
+ * @return      none
+ * ************************************************************************************************/
+void display_symbol(uint8_t symbol, uint8_t mode);
+
+/* Set_value display functions */
+/* *************************************************************************************************
+ * @fn          display_value1
+ * @brief       Generic decimal display routine. Used exclusively by set_value function.
+ * @param       uint8_t segments        LCD segments where value is displayed
+ *              uint32_t value          Integer value to be displayed
+ *              uint8_t digits          Number of digits to convert
+ *              uint8_t blanks          Number of leadings blanks in itoa result string
+ * @return      none
+ * ************************************************************************************************/
+void display_value1(uint8_t segments, uint32_t value, uint8_t digits, uint8_t blanks, uint8_t disp_mode);
+
+/* Integer to string conversion  */
+/* *************************************************************************************************
+ * @fn          itoa
+ * @brief       Generic integer to array routine. Converts integer n to string.
+ *              Default conversion result has leading zeros, e.g. "00123"
+ *              Option to convert leading '0' into whitespace (blanks)
+ * @param       uint32_t n          integer to convert
+ *              uint8_t digits      number of digits
+ *              uint8_t blanks      fill up result string with number of whitespaces instead of leading zeros
+ * @return      uint8_t             string
+ * ************************************************************************************************/
+char *itoa(uint32_t n, uint8_t digits, uint8_t blanks);
+
+/* Segment index helper function */
+/* *************************************************************************************************
+ * @fn          switch_seg
+ * @brief       Returns index of 7-segment character. Required for display routines that can draw
+ *              information on both lines.
+ * @param       uint8_t line        LINE1, LINE2
+ *              uint8_t index1      Index of LINE1
+ *              uint8_t index2      Index of LINE2
+ * @return      uint8
+ * ************************************************************************************************/
+uint8_t switch_seg(uint8_t line, uint8_t index1, uint8_t index2);
+
+/* *************************************************************************************************
+ * @fn          display_all_off
+ * @brief       Sets everything of on the display
+ * @param       none
+ * @return      none
+ * ************************************************************************************************/
+void display_all_off(void);
+
+#endif /* __DISPLAY_ */
diff --git a/boards/chronos/drivers/include/display_putchar.h b/boards/chronos/drivers/include/display_putchar.h
new file mode 100644
index 0000000000000000000000000000000000000000..b903fc1db98c4705bdddcb104517c12b9fa0360a
--- /dev/null
+++ b/boards/chronos/drivers/include/display_putchar.h
@@ -0,0 +1,6 @@
+#ifndef __DISPLAY_PUTCHAR_H
+#define __DISPLAY_PUTCHAR_H
+
+void init_display_putchar(void);
+
+#endif /* __DISPLAY_PUTCHAR_H */
diff --git a/boards/chronos/include/board.h b/boards/chronos/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..c07dd4f00e67568291fb6b740ddb235770b8efc0
--- /dev/null
+++ b/boards/chronos/include/board.h
@@ -0,0 +1,13 @@
+#ifndef _MSB_BOARD_H
+#define _MSB_BOARD_H
+
+#include <stdint.h>
+#include <cc430f6137.h>
+
+#define MSP430_INITIAL_CPU_SPEED    7372800uL
+#define MSP430_HAS_DCOR             1
+#define MSP430_HAS_EXTERNAL_CRYSTAL 1
+
+typedef uint8_t radio_packet_length_t;
+
+#endif // _MSB_BOARD_H
diff --git a/boards/chronos/include/buttons.h b/boards/chronos/include/buttons.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e7ab28dca4427551d6a6c819cbabb515b2929a7
--- /dev/null
+++ b/boards/chronos/include/buttons.h
@@ -0,0 +1,11 @@
+#ifndef BUTTONS_H
+#define BUTTONS_H
+
+// Button ports
+#define BUTTON_STAR_PIN        	(BIT2)
+#define BUTTON_NUM_PIN         	(BIT1)
+#define BUTTON_UP_PIN          	(BIT4)
+#define BUTTON_DOWN_PIN        	(BIT0)
+#define BUTTON_BACKLIGHT_PIN   	(BIT3)
+
+#endif
diff --git a/boards/chronos/putchar.c b/boards/chronos/putchar.c
new file mode 100644
index 0000000000000000000000000000000000000000..cefcb3281b806ac2cc1034724bae5553b285f277
--- /dev/null
+++ b/boards/chronos/putchar.c
@@ -0,0 +1,12 @@
+static void _dummy(int c)
+{
+}
+
+void (*_putchar)(int c) = _dummy;
+
+int putchar(int c)
+{
+    _putchar(c);
+    return c;
+}
+
diff --git a/boards/msb-430-common/Makefile b/boards/msb-430-common/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4ca6a9248b97d916f2e48882ca07b188b043988c
--- /dev/null
+++ b/boards/msb-430-common/Makefile
@@ -0,0 +1,33 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBOARD)/msb-430-common/include/ -I${RIOTBOARD}/${BOARD}/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/mspx16x/include/
+INCLUDES += -I$(RIOTBASE)/drivers/include/
+
+.PHONY: $(BINDIR)$(ARCH)
+
+all: $(BINDIR)$(ARCH) 
+	$(MAKE) -C drivers
+
+$(BINDIR)$(ARCH): $(OBJ)
+	echo $(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	$(MAKE) -C drivers clean
+	rm -f $(OBJ) $(DEP)
+	rm -f $(BINDIR)$(ARCH)
diff --git a/boards/msb-430-common/Makefile.include b/boards/msb-430-common/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..b7dd9ef3d9821a702ef072baba7095b286d2f940
--- /dev/null
+++ b/boards/msb-430-common/Makefile.include
@@ -0,0 +1,27 @@
+## the cpu to build for
+export CPU = msp430x16x
+export MCU = msp430f1612
+
+# toolchain config
+export PREFIX = @msp430-
+export CC = @$(PREFIX)gcc
+export AR = @$(PREFIX)ar
+export CFLAGS += -std=gnu99 -Wstrict-prototypes -gdwarf-2 -Os -Wall -mmcu=$(MCU)
+export ASFLAGS += -mmcu=$(MCU) --defsym $(MCU)=1 --gdwarf-2
+export AS = $(PREFIX)as
+export LINK = $(PREFIX)gcc
+export SIZE = $(PREFIX)size
+export OBJCOPY = $(PREFIX)objcopy
+export LINKFLAGS = -mmcu=$(MCU) -lgcc $(RIOTBASE)/bin/startup.o
+TERMPROG = $(RIOTBASE)/dist/tools/pyterm/pyterm.py
+export FLASHER = mspdebug
+ifeq ($(strip $(PORT)),)
+	export PORT = /dev/ttyUSB0
+endif
+export HEXFILE = bin/$(PROJECT).hex
+#export FFLAGS = -d $(PORT) -j uif "prog $(HEXFILE)"
+export FFLAGS = -j olimex "prog $(HEXFILE)"
+
+export USEMODULE += msp430_common 
+export INCLUDES += -I $(RIOTCPU)/msp430-common/include/
+export OFLAGS = -O ihex
diff --git a/boards/msb-430-common/board_config.c b/boards/msb-430-common/board_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..14b8d00e31a4d3763767ef7be9eb1865df9045ea
--- /dev/null
+++ b/boards/msb-430-common/board_config.c
@@ -0,0 +1,21 @@
+#include <stdint.h>
+#include <string.h>
+#include <board-conf.h>
+#include <config.h>
+#include <flashrom.h>
+
+void config_load(void)
+{
+    if (*((uint16_t *) INFOMEM) ==  CONFIG_KEY) {
+        memcpy(&sysconfig, (char *)(INFOMEM + sizeof(CONFIG_KEY)), sizeof(sysconfig));
+    }
+    else {
+        config_save();
+    }
+}
+
+uint8_t config_save(void)
+{
+    configmem_t mem = { CONFIG_KEY, sysconfig  };
+    return (flashrom_erase((uint8_t *) INFOMEM) && flashrom_write((uint8_t *) INFOMEM, (char *) &mem, sizeof(mem)));
+}
diff --git a/boards/msb-430-common/board_init.c b/boards/msb-430-common/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..e7d4284baac6300a46bfd0985e44f23eb88d8023
--- /dev/null
+++ b/boards/msb-430-common/board_init.c
@@ -0,0 +1,228 @@
+#include "cpu.h"
+#include "board.h"
+#include "kernel_internal.h"
+#include "msp430.h"
+#include "debug.h"
+
+static volatile uint32_t __msp430_cpu_speed = MSP430_INITIAL_CPU_SPEED;
+
+void msp430_init_dco(void);
+
+/*---------------------------------------------------------------------------*/
+static uint8_t calc_umctl(uint16_t br)
+{
+    /* from TI slaa049 */
+    register uint8_t CMOD = 256 * br - 256 * (br + 1) / 2;
+    register uint8_t c = 0;
+    register int i = 0;
+    register uint8_t a = CMOD;
+    a <<= 1;
+
+    do {
+        if (a & 0x80) {		/* Overflow to integer? */
+            a = a - 128 + CMOD;	/* Yes, subtract 1.000000 */
+            c |= 0x80;
+        }
+        else {
+            a += CMOD;			/* No, add fraction */
+        }
+
+        if (i == 7) {
+            return c;
+        }
+
+        i++;
+        c >>= 1;
+    }
+    while (1);
+}
+
+static void msb_ports_init(void)
+{
+    /* Port 1: Free port, for energy saving all outputs are set to zero. */
+    P1SEL = 0x00;	/* Port1 I/O Function */
+    P1OUT = 0x00;	/* Port1 Ausgangsregister: 00000000 = 0x00 */
+    P1DIR = 0xFF;	/* Port1 Direction: 11111111 = 0xFF */
+
+    P2SEL = 0x20;	/* Port2 I/O Function */
+    P2OUT = 0x00;	/* Port2 Output register: 00000000 = 0x00 */
+    P2DIR = 0x1C;	/* Port2 Direction: 00011010 = 0x1C */
+    /*   0 - P2.0 [IN ] - */
+    /*   0 - P2.1 [OUT] - */
+    /*   1 - P2.2 [IN ] - */
+    /*   1 - P2.3 [OUT] - */
+    /*   1 - P2.4 [OUT] - */
+    /*   0 - P2.5 [IN ] - */
+    /*   0 - P2.6 [IN ] - SDC Protect */
+    /*   0 - P2.7 [IN ] - SDC Detect */
+
+    P3SEL = 0xC0;	/* Port3 Pins 6 & 7 for USART */
+    P3OUT = 0x49;	/* Port3 Output register: 01001001: 0x49 */
+    P3DIR = 0xAB;	/* Port3 Direction: 10101011: 0xAB */
+    /*   1 - P3.0 */
+    /*   1 - P3.1 */
+    /*   0 - P3.2 */
+    /*   1 - P3.3 */
+    /*   0 - P3.4 [IN ] - SHT 11 DATA (OUT/IN) */
+    /*   1 - P3.5 [OUT] - SHT 11 CLK */
+    /*   0 - P3.6 [2-Funktion] - RS232_RxD */
+    /*   1 - P3.7 [2-Funktion] - RS232_TxD */
+
+    /* Port 4: Free port, for energy saving all outputs are set to zero. */
+    P4SEL = 0x00;	/* Port4 I/O Function */
+    P4OUT = 0x00;	/* Port4 Output register: 00000000 = 0x00 */
+    P4DIR = 0xFF;	/* Port4 Direction: 11111111 = 0xFF */
+    /*   1 - P4.0 [OUT] - unused */
+    /*   1 - P4.1 [OUT] - unused */
+    /*   1 - P4.2 [OUT] - unused */
+    /*   1 - P4.3 [OUT] - unused */
+    /*   1 - P4.4 [OUT] - unused */
+    /*   1 - P4.5 [OUT] - unused */
+    /*   1 - P4.6 [OUT] - unused */
+    /*   1 - P4.7 [OUT] - unused */
+
+    P5SEL = 0x00;	/* Port5 I/O Function: 00000000 = 0x00 */
+    P5OUT = 0x80;	/* Port5 Output register: 00001001 = 0x09 */
+    P5DIR = 0xFF;	/* Port5 Direction: 11111011 = 0xFB */
+    /*   1 - P5.0 [OUT] - SDC /CS */
+    /*   1 - P5.1 [OUT] - SDC DI */
+    /*   0 - P5.2 [IN ] - SDC DO */
+    /*   1 - P5.3 [OUT] - SDC DCLK */
+    /*   1 - P5.4 [OUT] - MMA GS1 */
+    /*   1 - P5.5 [OUT] - MMA GS2 */
+    /*   1 - P5.6 [OUT] - MMA /SLEEP */
+    /*   1 - P5.7 [OUT] - LED_RED 0-on, 1-off */
+
+    P6SEL = 0x00;	/* Port6 I/O Function = 0x07 */
+    P6OUT = 0x00;	/* Port6 Output register: 00000000 = 0x00 */
+    P6DIR = 0xFF;	/* Port6 Direction: 11111000 = 0xF8 */
+    /*   0 - P6.0 [AD-IN] - MMA X-Axis */
+    /*   0 - P6.1 [AD-IN] - MMA Y-Axis */
+    /*   0 - P6.2 [AD-IN] - MMA Z-Axis */
+    /*   1 - P6.3 [OUT] - unused */
+    /*   1 - P6.4 [OUT] - unused */
+    /*   1 - P6.5 [OUT] - unused */
+    /*   1 - P6.6 [OUT] - unused */
+    /*   1 - P6.7 [OUT] - unused */
+}
+
+void msp430_set_cpu_speed(uint32_t speed)
+{
+    dint();
+    __msp430_cpu_speed = speed;
+    msp430_init_dco();
+    uint16_t br;
+    UCTL1 = SWRST | CHAR;		/* 8-bit character */
+    UTCTL1 |= SSEL1 | URXSE;	/* UCLK = MCLK */
+    /* activate */
+    U1ME |= UTXE1 | URXE1;		/* Enable USART1 TXD/RXD */
+    br = (uint16_t)(__msp430_cpu_speed / 115200uL);
+    UBR01  = br;				/* set baudrate */
+    UBR11  = br >> 8;
+    UMCTL1 = calc_umctl(br);	/* set modulation */
+
+    ME2 |= (UTXE1 | URXE1);
+    UCTL1 &= ~SWRST;
+
+    IE2 |= URXIE1;
+    //clock_init();
+    eint();
+}
+
+/*---------------------------------------------------------------------------*/
+void msp430_init_dco(void)
+{
+#if MSP430_HAS_EXTERNAL_CRYSTAL
+    /*------------------ use external oszillator -----------------------*/
+    uint16_t i;
+
+    /* Stop watchdog */
+    WDTCTL = WDTPW + WDTHOLD;
+
+    //Init crystal for mclk
+    //XT2 = HF XTAL
+    BCSCTL1 = RSEL2;
+
+    /* Wait for xtal to stabilize */
+    do {
+        IFG1 &= ~OFIFG;				/* Clear oscillator fault flag */
+
+        for (i = 0xFF; i > 0; i--); /* Time for flag to set */
+    }
+    while ((IFG1 & OFIFG) != 0);	/* Oscillator fault flag still set? */
+
+    BCSCTL2 = SELM_2 + SELS;		/* MCLK und SMCLK = XT2 (safe) */
+#else
+    /* Thdeltais code taken from the FU Berlin sources and reformatted. */
+    int delta = __msp430_cpu_speed >> 12;
+    //#define DELTA    600
+
+    unsigned int compare, oldcapture = 0;
+    unsigned int i;
+
+
+    BCSCTL1 = 0xa4; /* ACLK is devided by 4. RSEL=6 no division for MCLK
+		     and SSMCLK. XT2 is off. */
+
+    /* Init FLL to desired frequency using the 32762Hz crystal */
+#if MSP430_HAS_DCOR
+    BCSCTL2 = 0x01;
+#else
+    BCSCTL2 = 0x00;
+#endif
+
+    WDTCTL = WDTPW + WDTHOLD;             /* Stop WDT */
+    BCSCTL1 |= DIVA1 + DIVA0;             /* ACLK = LFXT1CLK/8 */
+
+    for (i = 0xffff; i > 0; i--);         /* Delay for XTAL to settle */
+
+    CCTL2 = CCIS0 + CM0 + CAP;            /* Define CCR2, CAP, ACLK */
+    TACTL = TASSEL1 + TACLR + MC1;        /* SMCLK, continous mode */
+
+
+    while (1) {
+
+        while ((CCTL2 & CCIFG) != CCIFG);   /* Wait until capture occured! */
+
+        CCTL2 &= ~CCIFG;                    /* Capture occured, clear flag */
+        compare = CCR2;                     /* Get current captured SMCLK */
+        compare = compare - oldcapture;     /* SMCLK difference */
+        oldcapture = CCR2;                  /* Save current captured SMCLK */
+
+        if (delta == compare) {
+            break;                            /* if equal, leave "while(1)" */
+        }
+        else if (delta < compare) {         /* DCO is too fast, slow it down */
+            DCOCTL--;
+
+            if (DCOCTL == 0xFF) {             /* Did DCO role under? */
+                BCSCTL1--;
+            }
+        }
+        else {                              /* -> Select next lower RSEL */
+            DCOCTL++;
+
+            if (DCOCTL == 0x00) {             /* Did DCO role over? */
+                BCSCTL1++;
+            }
+
+            /* -> Select next higher RSEL  */
+        }
+    }
+
+    CCTL2 = 0;                            /* Stop CCR2 function */
+    TACTL = 0;                            /* Stop Timer_A */
+
+    BCSCTL1 &= ~(DIVA1 + DIVA0);          /* remove /8 divisor from ACLK again */
+#endif
+}
+
+void board_init()
+{
+    msp430_cpu_init();
+    msb_ports_init();
+
+    LED_RED_ON;
+
+    msp430_set_cpu_speed(7372800uL);
+}
diff --git a/boards/msb-430-common/drivers/Makefile b/boards/msb-430-common/drivers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d4b65dc0319c6cf99c012d9bc24c784606687598
--- /dev/null
+++ b/boards/msb-430-common/drivers/Makefile
@@ -0,0 +1,24 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBASE)/sys/include/ -I$(RIOTBASE)/drivers/cc110x_ng/include/
+
+$(BINDIR)msb-430_common_drivers.a: $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+
+clean:
+	rm -f $(OBJ) $(DEP)
+
diff --git a/boards/msb-430-common/drivers/include/sht11-board.h b/boards/msb-430-common/drivers/include/sht11-board.h
new file mode 100644
index 0000000000000000000000000000000000000000..13aeb899686a7f99d63d614d586765be5072cbbe
--- /dev/null
+++ b/boards/msb-430-common/drivers/include/sht11-board.h
@@ -0,0 +1,59 @@
+/******************************************************************************
+Copyright 2013, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+#ifndef SHT11BOARD_H_
+#define SHT11BOARD_H_
+
+/**
+ * @ingroup	    msb_430h
+ * @{
+ */
+
+/**
+ * @file
+ * @brief		SHT11 Device Driver Configuration For MSB-430 Platform
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, RIOT
+ *
+ */
+#include <msp430x16x.h>
+#include <bitarithm.h>
+
+/* SCK  = P3B5
+ * DATA = P3B4
+ */
+
+#define SHT11_SCK_LOW	P3OUT &= ~(BIT5);     /**< serial clock line low */
+#define SHT11_SCK_HIGH	P3OUT |= BIT5;      /**< serial clock line high */
+#define SHT11_DATA		(P3IN & BIT5)      /**< read serial I/O */
+#define SHT11_DATA_LOW	P3OUT &= ~(BIT5); 	/**< serial I/O line low */
+#define SHT11_DATA_HIGH	P3OUT |= BIT5;      /**< serial I/O line high */
+#define SHT11_DATA_IN	P3DIR &= ~(BIT5);      /**< serial I/O as input */
+#define SHT11_DATA_OUT	P3DIR |= BIT5;      /**< serial I/O as output */
+#define SHT11_INIT		P3DIR |= BIT5;      /* FIO1DIR |= BIT25; PINSEL3 &= ~(BIT14|BIT15 | BIT16|BIT17); */
+
+/** @} */
+#endif /* SHT11BOARD_H_ */
diff --git a/boards/msb-430-common/include/board-conf.h b/boards/msb-430-common/include/board-conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a9d5b1dd0a5cacc5911236c7ec4bab2fef56053
--- /dev/null
+++ b/boards/msb-430-common/include/board-conf.h
@@ -0,0 +1,8 @@
+#ifndef BOARD_CONF_H
+#define BOARD_CONF_H
+
+#include <stdint.h>
+
+#define INFOMEM     (0x1000)
+
+#endif /* BOARD-CONF_H */
diff --git a/boards/msb-430-common/uart1.c b/boards/msb-430-common/uart1.c
new file mode 100644
index 0000000000000000000000000000000000000000..025d09dc6e7ab61521adfe8b3d9bdb27967d992a
--- /dev/null
+++ b/boards/msb-430-common/uart1.c
@@ -0,0 +1,57 @@
+#include "board.h"
+
+#define UART1_TX                        TXBUF1
+#define UART1_WAIT_TXDONE()       while( (UTCTL1 & TXEPT) == 0 ) { _NOP(); }
+
+#include <stdio.h>
+#include <kernel.h>
+
+#include <board_uart0.h>
+
+int putchar(int c)
+{
+    UART1_TX = c;
+    UART1_WAIT_TXDONE();
+
+    if (c == 10) {
+        UART1_WAIT_TXDONE();
+    }
+
+    return c;
+}
+
+void usart0irq(void);
+/**
+ * \brief the interrupt function
+ */
+interrupt(USART1RX_VECTOR) usart0irq(void) 
+{
+    U1TCTL &= ~URXSE; /* Clear the URXS signal */
+    U1TCTL |= URXSE;  /* Re-enable URXS - needed here?*/
+    int c = 0;
+    /* Check status register for receive errors. */
+    if(U1RCTL & RXERR) {
+        if (U1RCTL & FE) {
+           puts("rx framing error");
+        }
+        if (U1RCTL & OE) {
+            puts("rx overrun error");
+        }
+        if (U1RCTL & PE) {
+            puts("rx parity error");
+        }
+        if (U1RCTL & BRK) {
+            puts("rx break error");
+        }
+        /* Clear error flags by forcing a dummy read. */
+        c = U1RXBUF;
+    }
+#ifdef MODULE_UART0
+    else if (uart0_handler_pid) {
+        c = U1RXBUF;
+        uart0_handle_incoming(c);
+        uart0_notify_thread();
+    }
+#endif
+}
+
diff --git a/boards/msb-430/Makefile b/boards/msb-430/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..66dcd277d1b99309260bf54a99d45846a8c16916
--- /dev/null
+++ b/boards/msb-430/Makefile
@@ -0,0 +1,37 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+export ARCH = msb-430_base.a
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBOARD)/msb-430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430x16x/include/
+
+all: $(BINDIR)$(ARCH)
+	$(MAKE) -C ../msb-430-common
+
+$(BINDIR)$(ARCH): $(OBJ)
+	mkdir -p $(BINDIR)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	$(MAKE) -C ../msb-430-common clean
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	@if [ -d $(BINDIR) ] ; \
+	then rmdir $(BINDIR) ; \
+	fi 
+
+
+
diff --git a/boards/msb-430/Makefile.include b/boards/msb-430/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..e2a5fb3e39f185331e1d3b6bc857baa044952f9e
--- /dev/null
+++ b/boards/msb-430/Makefile.include
@@ -0,0 +1,2 @@
+export INCLUDES += -I$(RIOTBOARD)/msb-430h/include -I$(RIOTBOARD)/msb-430-common/include
+include $(RIOTBOARD)/msb-430-common/Makefile.include
diff --git a/boards/msb-430/include/board.h b/boards/msb-430/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7968f4499b1a21a3c74f3e7bb51e63fa226dc09
--- /dev/null
+++ b/boards/msb-430/include/board.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+#ifndef _MSB_BOARD_H
+#define _MSB_BOARD_H
+
+/**
+ * @defgroup	msb_430h		ScatterWeb MSB-430H
+ * @ingroup		msp430
+ *
+<h2>Compontents</h2>
+\li MSP430
+\li CC1100
+
+* @{
+*/
+
+/**
+ * @file
+ * @brief		MSB-430H Board
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @version     $Revision$
+ *
+ * @note		$Id$
+ */
+
+#include "board-conf.h"
+
+//MSB430 core
+#define MSP430_INITIAL_CPU_SPEED 2457600uL
+#define MSP430_HAS_DCOR             1
+#define MSP430_HAS_EXTERNAL_CRYSTAL 0
+
+/* LEDs ports MSB430 */
+#define LEDS_PxDIR P5DIR
+#define LEDS_PxOUT P5OUT
+#define LEDS_CONF_RED		0x80
+#define LEDS_CONF_GREEN		0x00
+#define LEDS_CONF_YELLOW	0x00
+
+#define LED_RED_ON      LEDS_PxOUT &=~LEDS_CONF_RED
+#define LED_RED_OFF     LEDS_PxOUT |= LEDS_CONF_RED
+#define LED_RED_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_RED
+
+#include <msp430x16x.h>
+
+typedef uint8_t radio_packet_length_t;
+
+/** @} */
+#endif // _MSB_BOARD_H
diff --git a/boards/msb-430h/Makefile b/boards/msb-430h/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..2bd0f63c26c3de6866836eaee3b3c80a3afaa034
--- /dev/null
+++ b/boards/msb-430h/Makefile
@@ -0,0 +1,37 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+export ARCH = msb-430h_base.a
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I${RIOTBASE}/core/include/
+INCLUDES += -Iinclude/ -I$(RIOTBOARD)/msb-430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/ -I$(RIOTBASE)/cpu/msp430x16x/include/
+INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include/ -I$(RIOTBASE)/sys/include
+
+all: $(BINDIR)$(ARCH)
+	$(MAKE) -C ../msb-430-common
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	mkdir -p $(BINDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	$(MAKE) -C ../msb-430-common clean
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	@if [ -d $(BINDIR) ] ; \
+	then rmdir $(BINDIR) ; \
+	fi 
+
+
diff --git a/boards/msb-430h/Makefile.dep b/boards/msb-430h/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..de1d7e692ce6129db82a8d19be9ef82631a00dea
--- /dev/null
+++ b/boards/msb-430h/Makefile.dep
@@ -0,0 +1,6 @@
+ifneq (,$(findstring cc110x_ng,$(USEMODULE)))
+	ifeq (,$(findstring cc110x_spi,$(USEMODULE)))
+		USEMODULE += cc110x_spi
+	endif
+endif
+
diff --git a/boards/msb-430h/Makefile.include b/boards/msb-430h/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..166060e36fee949587776c7c0889157ca12dc68c
--- /dev/null
+++ b/boards/msb-430h/Makefile.include
@@ -0,0 +1,4 @@
+export INCLUDES += -I$(RIOTBOARD)/msb-430h/include -I$(RIOTBOARD)/msb-430-common/include
+include $(RIOTBOARD)/$(BOARD)/Makefile.dep
+
+include $(RIOTBOARD)/msb-430-common/Makefile.include
diff --git a/boards/msb-430h/driver_cc110x.c b/boards/msb-430h/driver_cc110x.c
new file mode 100644
index 0000000000000000000000000000000000000000..857bfcf1d424acb211ef63268c98723fd7488bc6
--- /dev/null
+++ b/boards/msb-430h/driver_cc110x.c
@@ -0,0 +1,359 @@
+/* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
+
+This file is part of the Micro-mesh SensorWeb Firmware.
+
+Micro-Mesh is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+Micro-Mesh is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Micro-Mesh; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include <stdio.h>
+
+#include <board.h>
+#include <cpu.h>
+#include <irq.h>
+
+#include <cc110x_ng.h>
+#include <cc110x-arch.h>
+
+#define CC1100_GDO0         (P2IN & 0x02)   // read serial I/O (GDO0)
+#define CC1100_GDO1         (P3IN & 0x04)   // read serial I/O (GDO1)
+#define CC1100_GDO2         (P2IN & 0x01)   // read serial I/O (GDO2)
+
+#define CC1100_CS_LOW       (P3OUT &= ~0x01)
+#define CC1100_CS_HIGH      (P3OUT |= 0x01)
+
+#define CC1100_GDO1_LOW_COUNT            (2700)          // loop count (timeout ~ 500 us) to wait
+#define CC1100_GDO1_LOW_RETRY             (100)          // max. retries for GDO1 to go low
+
+volatile int abort_count;
+volatile int retry_count = 0;
+
+void cc110x_gdo0_enable(void)
+{
+    P2IFG &= ~0x02;     /* Clear IFG for GDO0 */
+    P2IE |= 0x02;       /* Enable interrupt for GDO0 */
+}
+
+void cc110x_gdo0_disable(void)
+{
+    P2IE &= ~0x02;      /* Disable interrupt for GDO0 */
+    P2IFG &= ~0x02;     /* Clear IFG for GDO0 */
+}
+
+void cc110x_gdo2_enable(void)
+{
+    P2IFG &= ~0x01;     /* Clear IFG for GDO2 */
+    P2IE |= 0x01;       /* Enable interrupt for GDO2 */
+}
+
+void cc110x_gdo2_disable(void)
+{
+    P2IE &= ~0x01;      /* Disable interrupt for GDO2 */
+    P2IFG &= ~0x01;     /* Clear IFG for GDO2 */
+}
+
+void cc110x_before_send(void)
+{
+    // Disable GDO2 interrupt before sending packet
+    cc110x_gdo2_disable();
+}
+
+void cc110x_after_send(void)
+{
+    // Enable GDO2 interrupt after sending packet
+    cc110x_gdo2_enable();
+}
+
+
+int cc110x_get_gdo0(void)
+{
+    return  CC1100_GDO0;
+}
+
+int cc110x_get_gdo1(void)
+{
+    return  CC1100_GDO1;
+}
+
+int cc110x_get_gdo2(void)
+{
+    return  CC1100_GDO2;
+}
+
+void cc110x_spi_cs(void)
+{
+    CC1100_CS_LOW;
+}
+
+uint8_t cc110x_txrx(uint8_t data)
+{
+    /* Ensure TX Buf is empty */
+    long c = 0;
+    IFG1 &= ~UTXIFG0;
+    IFG1 &= ~URXIFG0;
+    TXBUF0 = data;
+
+    while (!(IFG1 & UTXIFG0)) {
+        if (c++ == 1000000) {
+            puts("cc110x_txrx alarm()");
+        }
+    }
+
+    /* Wait for Byte received */
+    c = 0;
+
+    while (!(IFG1 & URXIFG0)) {
+        if (c++ == 1000000) {
+            puts("cc110x_txrx alarm()");
+        }
+    }
+
+    return RXBUF0;
+}
+
+
+void cc110x_spi_select(void)
+{
+    // Switch to GDO mode
+    P3SEL &= ~0x04;
+    P3DIR &= ~0x04;
+cs_low:
+    // CS to low
+    abort_count = 0;
+    CC1100_CS_LOW;
+    // Wait for SO to go low (voltage regulator
+    // has stabilized and the crystal is running)
+loop:
+
+    //	asm volatile ("nop");
+    if (CC1100_GDO1) {
+        abort_count++;
+
+        if (abort_count > CC1100_GDO1_LOW_COUNT) {
+            retry_count++;
+
+            if (retry_count > CC1100_GDO1_LOW_RETRY) {
+                puts("[CC1100 SPI] fatal error\n");
+                goto final;
+            }
+
+            CC1100_CS_HIGH;
+            goto cs_low;		// try again
+        }
+
+        goto loop;
+    }
+
+final:
+    /* Switch to SPI mode */
+    P3SEL |= 0x04;
+}
+
+void cc110x_spi_unselect(void)
+{
+    CC1100_CS_HIGH;
+}
+
+void cc110x_init_interrupts(void)
+{
+    unsigned int state = disableIRQ(); /* Disable all interrupts */
+    P2SEL = 0x00;       /* must be <> 1 to use interrupts */
+    P2IES |= 0x01;      /* Enables external interrupt on low edge (for GDO2) */
+    P2IE |= 0x01;       /* Enable interrupt */
+    P2IFG &= ~0x01;     /* Clears the interrupt flag */
+    P2IE &= ~0x02;      /* Disable interrupt for GDO0 */
+    P2IFG &= ~0x02;     /* Clear IFG for GDO0 */
+    restoreIRQ(state);  /* Enable all interrupts */
+}
+
+void cc110x_spi_init(uint8_t clockrate)
+{
+    // Switch off async UART
+    while (!(UTCTL0 & TXEPT));  // Wait for empty UxTXBUF register
+
+    IE1 &= ~(URXIE0 + UTXIE0);  // Disable USART0 receive&transmit interrupt
+    ME1 &= ~(UTXE0 + URXE0);
+    P3SEL |= 0x0E;              // Set pin as SPI
+
+    // Keep peripheral in reset state
+    UCTL0  = SWRST;
+
+    // 8-bit SPI Master 3-pin mode, with SMCLK as clock source
+    // CKPL works also, but not CKPH+CKPL or none of them!!
+    UCTL0 |= CHAR + SYNC + MM;
+    UTCTL0 = CKPH + SSEL1 + SSEL0 + STC;
+
+    // Ignore clockrate argument for now, just use clock source/2
+    // SMCLK = 7,3728 MHz
+    UBR00 = 0x02;  // Ensure baud rate >= 2
+    UBR10 = 0x00;
+    UMCTL0 = 0x00; // No modulation
+    URCTL0 = 0x00; // Reset Receive Control Register
+
+    // Enable SPI mode
+    ME1 |= USPIE0;
+
+    // Release for operation
+    UCTL0  &= ~SWRST;
+}
+
+
+// #include <msp430x16x.h>
+// #include <signal.h>
+// #include "type.h"
+// #include "cc110x_defines.h"
+// #include "driver_cc110x.h"
+// #include "driver_system.h"
+// #include "spi0.h"
+//
+// static callback_t _paket_cb;
+// static callback_t _cs_cb;
+//
+// //-------------------------------------------------------------------------------------------------------
+// // Public CC1100 communication functions (SPI)
+// //-------------------------------------------------------------------------------------------------------
+//
+// //-------------------------------------------------------------------------------------------------------
+// //  void spiInitTrx(void)
+// //
+// //  DESCRIPTION:
+// //		This function puts the cc110x into spi mode. You have to call this bevore every spi transaction.
+// //
+// //-------------------------------------------------------------------------------------------------------
+//
+//
+// void drivercc110x_spiwriteburstreg(uint8_t addr, unsigned char *buffer, uint8_t count)
+// {
+// 	uint8_t i;
+// 	long c;
+// 	drivercc110x_spiinittrx();
+// 	drivercc110x_trxspi(addr | CC1100_WRITE_BURST);
+// 	for (i = 0; i < count; i++)
+// 	{
+// 		c = 0;
+// 		IFG1 &= ~UTXIFG0;
+// 		IFG1 &= ~URXIFG0;
+// 		TXBUF0 = buffer[i];
+// 		/* Wait for TX to finish */
+// 		while(!(IFG1 & UTXIFG0))
+// 		{
+// 			if (c++ == 1000000)
+// 				alarm();
+// 		}
+// 	}
+// 	/* Wait for Byte received */
+// 	c = 0;
+// 	while(!(IFG1 & URXIFG0))
+// 	{
+// 		if (c++ == 1000000)
+// 			alarm();
+// 	}
+// 	CC1100_CS_HIGH;
+// }
+//
+// void drivercc110x_spireadburstreg(uint8_t addr, char *buffer, uint8_t count)
+// {
+// 	uint8_t i;
+// 	drivercc110x_spiinittrx();
+// 	drivercc110x_trxspi(addr | CC1100_READ_BURST);
+// 	for (i = 0; i < count; i++)
+// 	{
+// 		long c = 0;
+// 		IFG1 &= ~UTXIFG0;
+// 		IFG1 &= ~URXIFG0;
+// 		TXBUF0 = NOBYTE;
+// 		while(!(IFG1 & UTXIFG0))
+// 		{
+// 			if (c++ == 1000000)
+// 				alarm();
+// 		}
+// 		/* Wait for Byte received */
+// 		c = 0;
+// 		while(!(IFG1 & URXIFG0))
+// 		{
+// 			if (c++ == 1000000)
+// 				alarm();
+// 		}
+// 		buffer[i] = RXBUF0;
+// 	}
+// 	CC1100_CS_HIGH;
+// }
+//
+// void drivercc110x_load(callback_t cs_cb,callback_t paket_cb)
+// {
+// 	_paket_cb = paket_cb;
+// 	_cs_cb = cs_cb;
+// 	spi0_init(0);
+// }
+//
+// void drivercc110x_aftersend(void)
+// {
+//     CLEAR(P2IFG, 0x01);
+// 	SET(P2IE, 0x01); /* Enable interrupts on port 2 pin 0 */
+// 	CLEAR(P4OUT, 0x08); /* Turn off Sending Led*/
+// }
+//
+// void drivercc110x_initinterrupts(void)
+// {
+// 	_DINT(); /* Disable all interrupts */
+// 	P2SEL = 0x00; /* must be <> 1 to use interrupts */
+// 	SET(P2IES, 0x01); /* Enables external interrupt on low edge (for GDO2) */
+// 	SET(P2IE, 0x01); /* Enable interrupt */
+//     CLEAR(P2IFG, 0x01); /* Clears the interrupt flag */
+// 	CLEAR(P2IE, 0x02); /* Disable interrupt for GDO0 */
+// 	CLEAR(P2IFG, 0x02); /* Clear IFG for GDO0 */
+// 	_EINT(); /* Enable all interrupts */
+// }
+//
+// void drivercc110x_beforesend(void)
+// {
+// 	/* Turn on Led while sending paket for debug reasons */
+// 	SET(P4OUT, 0x08);
+// 	/* Disable interrupts on port 2 pin 0 */
+// 	CLEAR(P2IE, 0x01);
+// }
+//
+//
+// /*
+//  * Private functions
+//  */
+//
+//
+
+/*
+ * CC1100 receive interrupt
+ */
+interrupt(PORT2_VECTOR) __attribute__((naked)) cc110x_isr(void)
+{
+    __enter_isr();
+    //	if (system_state.POWERDOWN) SPI_INIT; /* Initialize SPI after wakeup */
+    /* Check IFG */
+    if ((P2IFG & 0x01) != 0) {
+        P2IFG &= ~0x01;
+        cc110x_gdo2_irq();
+    }
+    else if ((P2IFG & 0x02) != 0) {
+        cc110x_gdo0_irq();
+        P2IE &= ~0x02;	            // Disable interrupt for GDO0
+        P2IFG &= ~0x02;	            // Clear IFG for GDO0
+    }
+    else {
+        puts("cc110x_isr(): unexpected IFG!");
+        /* Should not occur - only Port 2 Pin 0 interrupts are enabled */
+        //		CLEAR(P2IFG, 0xFF);	/* Clear all flags */
+    }
+
+    //	if (system_state.POWERDOWN != 0) END_LPM3;
+    __exit_isr();
+}
diff --git a/boards/msb-430h/include/board.h b/boards/msb-430h/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc086d53cb29fc251efa3b5924ddded769ff2b09
--- /dev/null
+++ b/boards/msb-430h/include/board.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+#ifndef _MSB_BOARD_H
+#define _MSB_BOARD_H
+
+/**
+ * @defgroup	msb_430h		ScatterWeb MSB-430H
+ * @ingroup		msp430
+ *
+<h2>Compontents</h2>
+\li MSP430
+\li CC1100
+
+* @{
+*/
+
+/**
+ * @file
+ * @brief		MSB-430H Board
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @version     $Revision$
+ *
+ * @note		$Id$
+ */
+
+//MSB430 core
+#define MSP430_INITIAL_CPU_SPEED    7372800uL
+#define MSP430_HAS_DCOR             1
+#define MSP430_HAS_EXTERNAL_CRYSTAL 1
+
+/* LEDs ports MSB430 */
+#define LEDS_PxDIR P5DIR
+#define LEDS_PxOUT P5OUT
+#define LEDS_CONF_RED		0x80
+#define LEDS_CONF_GREEN		0x00
+#define LEDS_CONF_YELLOW	0x00
+
+#define LED_RED_ON      LEDS_PxOUT &=~LEDS_CONF_RED
+#define LED_RED_OFF     LEDS_PxOUT |= LEDS_CONF_RED
+#define LED_RED_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_RED
+
+#include <msp430x16x.h>
+#include "board-conf.h"
+
+typedef uint8_t radio_packet_length_t;
+
+/** @} */
+#endif // _MSB_BOARD_H
diff --git a/boards/msba2-common/Makefile b/boards/msba2-common/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..29f64c8ecb108af9ffc9c49f57396b1f18926419
--- /dev/null
+++ b/boards/msba2-common/Makefile
@@ -0,0 +1,33 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBOARD)/msba2-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/arm_common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/lpc2387/include/
+INCLUDES += -I$(RIOTBASE)/drivers/include/
+INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include
+
+.PHONY: $(BINDIR)msba2_common_base.a
+
+all: $(BINDIR)msba2_common_base.a 
+	"$(MAKE)" -C drivers
+
+$(BINDIR)msba2_common_base.a: $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	"$(MAKE)" -C drivers clean
+	rm -f $(OBJ) $(DEP)
+
diff --git a/boards/msba2-common/Makefile.dep b/boards/msba2-common/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..bffa6c72d75820e3bfdbcf81a7a3bdca18712759
--- /dev/null
+++ b/boards/msba2-common/Makefile.dep
@@ -0,0 +1,14 @@
+ifneq (,$(findstring cc110x,$(USEMODULE)))
+	ifeq (,$(findstring gpioint,$(USEMODULE)))
+		USEMODULE += gpioint
+	endif
+endif
+
+ifneq (,$(findstring cc110x_ng,$(USEMODULE)))
+	ifeq (,$(findstring cc110x_spi,$(USEMODULE)))
+		USEMODULE += cc110x_spi
+	endif
+	ifeq (,$(findstring gpioint,$(USEMODULE)))
+		USEMODULE += gpioint
+	endif
+endif
diff --git a/boards/msba2-common/Makefile.include b/boards/msba2-common/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..5d3ba0fb0ddc9791fae6aec8f35e82006ab7150b
--- /dev/null
+++ b/boards/msba2-common/Makefile.include
@@ -0,0 +1,27 @@
+## the cpu to build for
+export CPU = lpc2387
+
+# toolchain config
+export PREFIX = @arm-none-eabi-
+#export PREFIX = @arm-elf-
+export CC = @$(PREFIX)gcc
+export AR = @$(PREFIX)ar
+export CFLAGS += -std=gnu99 -O2 -Wall -Wstrict-prototypes -mcpu=arm7tdmi-s -gdwarf-2
+export ASFLAGS = -gdwarf-2 -mcpu=arm7tdmi-s
+export AS = $(PREFIX)as
+export LINK = $(PREFIX)gcc
+export SIZE = $(PREFIX)size
+export OBJCOPY = $(PREFIX)objcopy
+FLASHER = lpc2k_pgm
+TERMPROG = $(RIOTBASE)/dist/tools/pyterm/pyterm.py
+LINKFLAGS = -gdwarf-2 -mcpu=arm7tdmi-s -static -lgcc -nostartfiles -T$(RIOTBASE)/cpu/$(CPU)/linkerscript.x
+
+ifeq ($(strip $(PORT)),)
+	export PORT = /dev/ttyUSB0
+endif
+export HEXFILE = bin/$(PROJECT).hex
+export FFLAGS = $(PORT) $(PROJBINDIR)/$(PROJECT).hex
+include $(RIOTBOARD)/msba2-common/Makefile.dep
+
+export INCLUDES += -I$(RIOTCPU)/lpc2387/include
+export OFLAGS = -O ihex
diff --git a/boards/msba2-common/board_common_init.c b/boards/msba2-common/board_common_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..4096caa9440bd575294278156129df0d1ca601ca
--- /dev/null
+++ b/boards/msba2-common/board_common_init.c
@@ -0,0 +1,96 @@
+/******************************************************************************
+Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+    http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+    scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+/**
+ * @ingroup msba2
+ * @{
+ */
+
+/**
+ * @file
+ * @brief       MSB-A2 board initialization
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author      Heiko Will
+ * @author      Kaspar Schleiser
+ * @author      Michael Baar <baar@inf.fu-berlin.de>
+ * @author 		Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ * @note        $Id$
+ */
+#include <board.h>
+#include <lpc23xx.h>
+#include <VIC.h>
+#include <cpu.h>
+#include <config.h>
+#include <string.h>
+#include <flashrom.h>
+
+#define PCRTC         BIT9
+#define CL_CPU_DIV    4
+
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief   Enabling MAM and setting number of clocks used for Flash memory fetch
+ * @internal
+ */
+static void
+init_mam(void)
+{
+    MAMCR  = 0x0000;
+    MAMTIM = 0x0003;
+    MAMCR  = 0x0002;
+}
+/*---------------------------------------------------------------------------*/
+static inline void
+pllfeed(void)
+{
+    PLLFEED = 0xAA;
+    PLLFEED = 0x55;
+}
+
+
+void init_clks2(void)
+{
+    // Wait for the PLL to lock to set frequency
+    while (!(PLLSTAT & BIT26));
+
+    // Connect the PLL as the clock source
+    PLLCON = 0x0003;
+    pllfeed();
+
+    /* Check connect bit status */
+    while (!(PLLSTAT & BIT25));
+}
+
+void bl_init_clks(void)
+{
+    PCONP = PCRTC;          // switch off everything except RTC
+    init_clks1();
+    init_clks2();
+    init_mam();
+}
+
+/*---------------------------------------------------------------------------*/
diff --git a/boards/msba2-common/board_config.c b/boards/msba2-common/board_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..496a07796173cd46f5f8d37adf42861c1b219149
--- /dev/null
+++ b/boards/msba2-common/board_config.c
@@ -0,0 +1,21 @@
+#include <stdint.h>
+#include <string.h>
+#include <config.h>
+#include <flashrom.h>
+
+void config_load(void) {
+    extern char configmem[];
+    /* cast it here for strict-aliasing */
+    uint16_t* tmp = (uint16_t*) configmem;
+    if (*tmp ==  CONFIG_KEY) {
+        memcpy(&sysconfig, (configmem + sizeof(CONFIG_KEY)), sizeof(sysconfig));
+    }
+    else {
+        config_save();
+    }
+}
+
+uint8_t config_save(void) {
+    configmem_t mem = { CONFIG_KEY, sysconfig  };
+    return (flashrom_erase((uint8_t*) &configmem) && flashrom_write((uint8_t*) &configmem, (char*) &mem, sizeof(mem)));
+}
diff --git a/boards/msba2-common/drivers/Makefile b/boards/msba2-common/drivers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c2ec59716242dd83228b34c436ba8672ae43b04b
--- /dev/null
+++ b/boards/msba2-common/drivers/Makefile
@@ -0,0 +1,24 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBASE)/sys/include/ -I$(RIOTBASE)/drivers/cc110x_ng/include/
+
+$(BINDIR)msba2_common_drivers.a: $(OBJ)
+	$(AR) rcs $(BINDIR)${ARCH} $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+
+clean:
+	rm -f $(OBJ) $(DEP)
+
diff --git a/boards/msba2-common/drivers/include/sht11-board.h b/boards/msba2-common/drivers/include/sht11-board.h
new file mode 100644
index 0000000000000000000000000000000000000000..c35fb00788bde78fde1a15b5c1cd99255cdbda7b
--- /dev/null
+++ b/boards/msba2-common/drivers/include/sht11-board.h
@@ -0,0 +1,58 @@
+/******************************************************************************
+Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+#ifndef SHT11BOARD_H_
+#define SHT11BOARD_H_
+
+/**
+ * @ingroup		lpc2387
+ * @{
+ */
+
+/**
+ * @file
+ * @brief		LPC2387 SHT11 Device Driver
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @version     $Revision$
+ *
+ * @note		$Id$
+ */
+
+#include <lpc23xx.h>
+#include <board.h>
+
+#define SHT11_SCK_LOW	FIO1CLR = BIT25;	// serial clock line low
+#define SHT11_SCK_HIGH	FIO1SET = BIT25;    // serial clock line high
+#define SHT11_DATA		((FIO1PIN & BIT26) != 0)				// read serial I/O
+#define SHT11_DATA_LOW	(FIO1CLR = BIT26); 	// serial I/O line low
+#define SHT11_DATA_HIGH	(FIO1SET = BIT26);  // serial I/O line high
+#define SHT11_DATA_IN	(FIO1DIR &= ~BIT26)						// serial I/O as input
+#define SHT11_DATA_OUT	(FIO1DIR |= BIT26)						// serial I/O as output
+#define SHT11_INIT		FIO1DIR |= BIT25; PINSEL3 &= ~(BIT14|BIT15 | BIT16|BIT17);
+
+/** @} */
+#endif /* SHT11BOARD_H_ */
diff --git a/boards/msba2-common/drivers/include/uart0.h b/boards/msba2-common/drivers/include/uart0.h
new file mode 100644
index 0000000000000000000000000000000000000000..b0861b2b15e8f0e7836201828007e7e2b3a916e8
--- /dev/null
+++ b/boards/msba2-common/drivers/include/uart0.h
@@ -0,0 +1,8 @@
+#ifndef __UART0_H
+#define __UART0_H
+
+#define UART0_BUFSIZE 32
+
+extern int uart0_handler_pid;
+
+#endif /* __UART0_H */
diff --git a/boards/msba2-common/drivers/msba2-cc110x.c b/boards/msba2-common/drivers/msba2-cc110x.c
new file mode 100644
index 0000000000000000000000000000000000000000..b5bde7cbfc8d5159a19f51c6f10eb05f5a21feff
--- /dev/null
+++ b/boards/msba2-common/drivers/msba2-cc110x.c
@@ -0,0 +1,270 @@
+/******************************************************************************
+Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+/**
+ * @file
+ * @ingroup		LPC2387
+ * @brief		CC1100 LPC2387 dependend functions
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author		Heiko Will <hwill@inf.fu-berlin.de>
+ * @author		Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
+ * @version     $Revision: 1781 $
+ *
+ * @note    	$Id: msba2-cc110x.c 1781 2010-01-26 13:39:36Z hillebra $
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+// core
+#include <cpu.h>
+#include <irq.h>
+// sys
+#include <cc110x_ng.h>
+#include <cc110x-arch.h>
+#include <cc110x_spi.h>
+#include <gpioint.h>
+
+#define CC1100_GDO0         (FIO0PIN & BIT27)	// read serial I/O (GDO0)
+#define CC1100_GDO1         (FIO1PIN & BIT23)	// read serial I/O (GDO1)
+#define CC1100_GDO2         (FIO0PIN & BIT28)	// read serial I/O (GDO2)
+
+#define SPI_TX_EMPTY				(SSP0SR & SSPSR_TFE)
+#define SPI_BUSY					(SSP0SR & SSPSR_BSY)
+#define SPI_RX_AVAIL				(SSP0SR & SSPSR_RNE)
+
+#define CC1100_GDO1_LOW_RETRY		 (100)		// max. retries for GDO1 to go low
+#define CC1100_GDO1_LOW_COUNT		(2700)		// loop count (timeout ~ 500 us) to wait
+// for GDO1 to go low when CS low
+
+//#define DEBUG
+#ifdef DEBUG
+
+#include "stdio.h"
+
+static unsigned long time_value;
+
+static void set_time(void)
+{
+    time_value = 0;
+}
+
+static int test_time(int code)
+{
+    time_value++;
+
+    if (time_value > 10000000) {
+        printf("CC1100 SPI alarm: %u!\n", code);
+        time_value = 0;
+        return 1;
+    }
+
+    return 0;
+}
+#endif
+
+int cc110x_get_gdo0(void)
+{
+    return 	CC1100_GDO0;
+}
+
+int cc110x_get_gdo1(void)
+{
+    return 	CC1100_GDO1;
+}
+
+int cc110x_get_gdo2(void)
+{
+    return 	CC1100_GDO2;
+}
+
+void cc110x_spi_init(void)
+{
+    // configure chip-select
+    FIO1DIR |= BIT21;
+    FIO1SET = BIT21;
+
+    // Power
+    PCONP |= PCSSP0;								// Enable power for SSP0 (default is on)
+
+    // PIN Setup
+    PINSEL3 |= BIT8 + BIT9; 						// Set CLK function to SPI
+    PINSEL3 |= BIT14 + BIT15;						// Set MISO function to SPI
+    PINSEL3 |= BIT16 + BIT17; 						// Set MOSI function to SPI
+
+    // Interface Setup
+    SSP0CR0 = 7;
+
+    // Clock Setup
+    uint32_t pclksel;
+    uint32_t cpsr;
+    lpc2387_pclk_scale(F_CPU / 1000, 6000, &pclksel, &cpsr);
+    PCLKSEL1 &= ~(BIT10 | BIT11);						// CCLK to PCLK divider
+    PCLKSEL1 |= pclksel << 10;
+    SSP0CPSR = cpsr;
+
+    // Enable
+    SSP0CR1 |= BIT1; 								// SSP-Enable
+    int dummy;
+
+    // Clear RxFIFO:
+    while (SPI_RX_AVAIL) {						// while RNE (Receive FIFO Not Empty)...
+        dummy = SSP0DR;							// read data
+    }
+
+    /* to suppress unused-but-set-variable */
+    (void) dummy;
+}
+
+uint8_t cc110x_txrx(uint8_t c)
+{
+    uint8_t result;
+    SSP0DR = c;
+#ifdef DEBUG
+    set_time();
+#endif
+
+    while (!SPI_TX_EMPTY) {
+#ifdef DEBUG
+        test_time(0);
+#endif
+    }
+
+#ifdef DEBUG
+    set_time();
+#endif
+
+    while (SPI_BUSY) {
+#ifdef DEBUG
+        test_time(1);
+#endif
+    }
+
+#ifdef DEBUG
+    set_time();
+#endif
+
+    while (!SPI_RX_AVAIL) {
+#ifdef DEBUG
+        test_time(2);
+#endif
+    }
+
+    result = (uint8_t)SSP0DR;
+    return result;
+}
+
+void cc110x_spi_cs(void)
+{
+    FIO1CLR = BIT21;
+}
+
+void
+cc110x_spi_select(void)
+{
+    volatile int retry_count = 0;
+    volatile int abort_count;
+    // Switch to GDO mode input
+    PINSEL3 &= ~(BIT14 + BIT15);// Set MISO function to GPIO
+    FIO1DIR &= ~BIT23;
+cs_low:
+    // CS to low
+    abort_count = 0;
+    FIO1CLR = BIT21;
+    // Wait for SO to go low (voltage regulator
+    // has stabilized and the crystal is running)
+loop:
+    asm volatile("nop");
+
+    if (CC1100_GDO1) {
+        abort_count++;
+
+        if (abort_count > CC1100_GDO1_LOW_COUNT) {
+            retry_count++;
+
+            if (retry_count > CC1100_GDO1_LOW_RETRY) {
+                puts("[CC1100 SPI] fatal error\n");
+                goto final;
+            }
+
+            FIO1SET = BIT21;	// CS to high
+            goto cs_low;		// try again
+        }
+
+        goto loop;
+    }
+
+final:
+    // Switch to SPI mode
+    PINSEL3 |= (BIT14 + BIT15);	// Set MISO function to SPI
+}
+
+void
+cc110x_spi_unselect(void)
+{
+    FIO1SET = BIT21;
+}
+
+void cc110x_before_send(void)
+{
+    // Disable GDO2 interrupt before sending packet
+    cc110x_gdo2_disable();
+}
+
+void cc110x_after_send(void)
+{
+    // Enable GDO2 interrupt after sending packet
+    cc110x_gdo2_enable();
+}
+
+void cc110x_gdo0_enable(void)
+{
+    gpioint_set(0, BIT27, GPIOINT_RISING_EDGE, &cc110x_gdo0_irq);
+}
+
+void cc110x_gdo0_disable(void)
+{
+    gpioint_set(0, BIT27, GPIOINT_DISABLE, NULL);
+}
+
+void cc110x_gdo2_disable(void)
+{
+    gpioint_set(0, BIT28, GPIOINT_DISABLE, NULL);
+}
+
+void cc110x_gdo2_enable(void)
+{
+    gpioint_set(0, BIT28, GPIOINT_FALLING_EDGE, &cc110x_gdo2_irq);
+}
+
+void cc110x_init_interrupts(void)
+{
+    // Enable external interrupt on low edge (for GDO2)
+    FIO0DIR &= ~BIT28;
+    cc110x_gdo2_enable();
+    // Enable external interrupt on low edge (for GDO0)
+    FIO0DIR &= ~BIT27;
+}
diff --git a/boards/msba2-common/drivers/msba2-ltc4150.c b/boards/msba2-common/drivers/msba2-ltc4150.c
new file mode 100644
index 0000000000000000000000000000000000000000..aba9085189ed72261a1d1237ced09aad9f066dc3
--- /dev/null
+++ b/boards/msba2-common/drivers/msba2-ltc4150.c
@@ -0,0 +1,69 @@
+/******************************************************************************
+Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+/**
+ * @ingroup		msba2
+ * @ingroup		ltc4150
+ * @{
+ */
+
+/**
+ * @file
+ * @brief		LTC4150 MSB-A2 specific implemetation
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author		Heiko Will
+ * @author		Michael Baar
+ * @author      Kaspar Schleiser <kaspar.schleiser@fu-berlin.de>
+ */
+
+#include <stdio.h>
+#include "lpc2387.h"
+#include "ltc4150_arch.h"
+#include "gpioint.h"
+
+void __attribute__((__no_instrument_function__)) ltc4150_disable_int(void)
+{
+    gpioint_set(0, BIT4, GPIOINT_DISABLE, NULL);
+}
+
+void __attribute__((__no_instrument_function__)) ltc4150_enable_int(void)
+{
+    gpioint_set(0, BIT4, GPIOINT_FALLING_EDGE, &ltc4150_interrupt);
+}
+
+void __attribute__((__no_instrument_function__)) ltc4150_sync_blocking(void)
+{
+    while (!(FIO0PIN & BIT4)) {};
+}
+
+void __attribute__((__no_instrument_function__)) ltc4150_arch_init()
+{
+    FIO0DIR |= BIT5;
+    FIO0SET = BIT5;
+}
+
+/** @} */
diff --git a/boards/msba2-common/drivers/msba2-uart0.c b/boards/msba2-common/drivers/msba2-uart0.c
new file mode 100644
index 0000000000000000000000000000000000000000..5db2ca0da92c8cb27a62ffdc180a7af4171a740c
--- /dev/null
+++ b/boards/msba2-common/drivers/msba2-uart0.c
@@ -0,0 +1,230 @@
+/******************************************************************************
+Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+    http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+    scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+/*
+ * debug_uart.c: provides initial serial debug output
+ *
+ * Copyright (C) 2008, 2009  Kaspar Schleiser <kaspar@schleiser.de>
+ *                           Heiko Will <hwill@inf.fu-berlin.de>
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "lpc23xx.h"
+#include "VIC.h"
+#include <kernel.h>
+
+#include <board_uart0.h>
+
+/**
+ * @file
+ * @ingroup     lpc2387
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @version     $Revision$
+ *
+ * @note    $Id$
+ */
+
+typedef struct toprint_t {
+    unsigned int len;
+    char content[];
+} toprint_t;
+
+#define QUEUESIZE 255
+static volatile toprint_t *queue[QUEUESIZE];
+static volatile unsigned char queue_head = 0;
+static volatile unsigned char queue_tail = 0;
+static volatile unsigned char queue_items = 0;
+
+static volatile unsigned int actual_pos = 0;
+static volatile unsigned int running = 0;
+static volatile unsigned int fifo = 0;
+
+static volatile toprint_t *actual = NULL;
+
+static inline void enqueue(void)
+{
+    queue_items++;
+    queue_tail++;
+}
+
+static inline void dequeue(void)
+{
+    actual = (queue[queue_head]);
+    queue_items--;
+    queue_head++;
+}
+
+static void  push_queue(void)
+{
+    running = 1;
+    lpm_prevent_sleep |= LPM_PREVENT_SLEEP_UART;
+start:
+
+    if (!actual) {
+        if (queue_items) {
+            dequeue();
+        }
+        else {
+            running = 0;
+            lpm_prevent_sleep &= ~LPM_PREVENT_SLEEP_UART;
+
+            if (!fifo)
+                while (!(U0LSR & BIT6)) {};
+
+            return;
+        }
+    }
+
+    while ((actual_pos < actual->len)  && (fifo++ < 16)) {
+        U0THR = actual->content[actual_pos++];
+    }
+
+    if (actual_pos == actual->len) {
+        free((void *)actual);
+        actual = NULL;
+        actual_pos = 0;
+        goto start;
+    }
+}
+
+int uart_active(void)
+{
+    return (running || fifo);
+}
+
+void stdio_flush(void)
+{
+    U0IER &= ~BIT1;                             // disable THRE interrupt
+
+    while (running) {
+        while (!(U0LSR & (BIT5 | BIT6))) {};    // transmit fifo
+
+        fifo = 0;
+
+        push_queue();                           // dequeue to fifo
+    }
+
+    U0IER |= BIT1;                              // enable THRE interrupt
+}
+
+void UART0_IRQHandler(void) __attribute__((interrupt("IRQ")));
+void UART0_IRQHandler(void)
+{
+    int iir;
+    iir = U0IIR;
+
+    switch (iir & UIIR_ID_MASK) {
+        case UIIR_THRE_INT:               // Transmit Holding Register Empty
+            fifo = 0;
+            push_queue();
+            break;
+
+        case UIIR_CTI_INT:                // Character Timeout Indicator
+        case UIIR_RDA_INT:                // Receive Data Available
+#ifdef MODULE_UART0
+            if (uart0_handler_pid) {
+                do {
+                    int c = U0RBR;
+                    uart0_handle_incoming(c);
+                }
+                while (U0LSR & ULSR_RDR);
+
+                uart0_notify_thread();
+            }
+
+#endif
+            break;
+
+        default:
+            U0LSR;
+            U0RBR;
+            break;
+    } // switch
+
+    VICVectAddr = 0;                    // Acknowledge Interrupt
+}
+
+static inline int uart0_puts(char *astring, int length)
+{
+    /*    while (queue_items == (QUEUESIZE-1)) {} ;
+        U0IER = 0;
+        queue[queue_tail] = malloc(length+sizeof(unsigned int));
+        queue[queue_tail]->len = length;
+        memcpy(&queue[queue_tail]->content,astring,length);
+        enqueue();
+        if (!running)
+            push_queue();
+        U0IER |= BIT0 | BIT1;       // enable RX irq
+    */
+    /* alternative without queue:*/
+    int i;
+
+    for (i = 0; i < length; i++) {
+        while (!(U0LSR & BIT5));
+
+        U0THR = astring[i];
+    }
+
+    /*    */
+
+    return length;
+}
+
+int fw_puts(char *astring, int length)
+{
+    return uart0_puts(astring, length);
+}
+
+int
+bl_uart_init(void)
+{
+    PCONP |= PCUART0;                               // power on
+
+    // UART0 clock divider is CCLK/8
+    PCLKSEL0 |= BIT6 + BIT7;
+
+    U0LCR = 0x83;                                   // 8 bits, no Parity, 1 Stop bit
+
+    // TODO: UART Baudrate calculation using uart->config->speed
+    /*
+     * Baudrate calculation
+     * BR = PCLK (9 MHz) / (16 x 256 x DLM + DLL) x (1/(DIVADDVAL/MULVAL))
+     */
+    U0FDR = 0x92;       // DIVADDVAL = 0010 = 2, MULVAL = 1001 = 9
+    U0DLM = 0x00;
+    U0DLL = 0x04;
+
+    U0LCR = 0x03;       // DLAB = 0
+    U0FCR = 0x07;       // Enable and reset TX and RX FIFO
+
+    /* irq */
+    install_irq(UART0_INT, UART0_IRQHandler, 6);
+    U0IER |= BIT0;       // enable only RX irq
+    return 1;
+}
+
diff --git a/boards/msba2-common/include/msba2_common.h b/boards/msba2-common/include/msba2_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e56c82ab75854e94ac9dbb514a075134967388a
--- /dev/null
+++ b/boards/msba2-common/include/msba2_common.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+#ifndef __MSBA2_COMMON_H
+#define __MSBA2_COMMON_H
+
+/**
+ * @ingroup		msb_a2
+ * @{
+ */
+
+/**
+ * @file
+ * @brief		MSB-A2 Common Board Definitions
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author		Kaspar Schleiser <kaspar@schleiser.de>
+ * @version     $Revision$
+ *
+ * @note		$Id$
+ */
+
+#include <stdint.h>
+#include "lpc2387.h"
+
+#define VICIntEnClear VICIntEnClr
+
+/** @} */
+#endif // __MSBA2_COMMON_H
diff --git a/boards/msba2-common/lpc2387-timer3.c b/boards/msba2-common/lpc2387-timer3.c
new file mode 100644
index 0000000000000000000000000000000000000000..3b404edd944815c081c0ffa53efcc07c1662c6f7
--- /dev/null
+++ b/boards/msba2-common/lpc2387-timer3.c
@@ -0,0 +1,36 @@
+/*
+ * lpc2387_timer0.c
+ *
+ *  Created on: 13.01.2009
+ *      Author: heiko
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include "lpc2387.h"
+
+void  benchmark_init(void)
+{
+	PCLKSEL1 = (PCLKSEL1 & ~(BIT14|BIT15)) | (1 << 14);	// CCLK to PCLK divider
+	PCONP |= PCTIM3;
+	T3TCR = 0;											// disable timer
+	T3MCR = 0;											// disable interrupt
+	T3CCR = 0;											// capture is disabled.
+	T3EMR = 0;											// no external match output.
+	T3PR = 0;											// set prescaler
+	T3TC = 0;											// reset counter
+}
+
+void  benchmark_reset_start(void)
+{
+	T3TCR = 0;												// disable timer
+	T3TC = 0;												// reset counter
+	T3TCR = BIT0;
+}
+
+unsigned int  benchmark_read_stop(void)
+{
+	T3TCR = 0;												// disable timer
+	return T3TC;
+}
+
diff --git a/boards/msba2-common/tools/CHANGES b/boards/msba2-common/tools/CHANGES
new file mode 100644
index 0000000000000000000000000000000000000000..dd9e6ec1eaa9f1d0143daf3c7df207124aa1931b
--- /dev/null
+++ b/boards/msba2-common/tools/CHANGES
@@ -0,0 +1,23 @@
+(heavily hacked by Heiko Will & Kaspar Schleiser since then)
+
+1.05 (9-Apr-2007)
+-----------------
+Added boot jump code specific to 2378 (and similar chips) to
+disable the PLL before jumping to the user's code.
+
+1.04 (19-Dec-2006)
+------------------
+Added 2364, 2366, 2368, 2378 & 2468 to list.  Untested.
+
+1.03 (2-Jun-2006)
+-----------------
+Added 2103 chip to chip list.  ID numbers for 2101 and 2102 unknown
+
+1.02 (31-Jul-2005)
+------------------
+Added support for other chips
+Added soft boot code
+Added user configurable crystal value (for baud sync protocol)
+
+
+
diff --git a/boards/msba2-common/tools/COPYING b/boards/msba2-common/tools/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..a43ea2126fb6b114bff5f8e003ee118e045dacf1
--- /dev/null
+++ b/boards/msba2-common/tools/COPYING
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/boards/msba2-common/tools/Makefile b/boards/msba2-common/tools/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8dbdcc242acf850d68fa9e94b799d33d80e95b55
--- /dev/null
+++ b/boards/msba2-common/tools/Makefile
@@ -0,0 +1,51 @@
+CFLAGS = -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)"
+CC = gcc
+prefix=/usr/local
+
+all: lpc2k_pgm pseudoterm
+
+SRC  = lpc2k_pgm.c download.c uuencode.c ihex.c serial.c chipinfo.c boot_2xxx.c boot_23xx.c control_2xxx.c
+OBJS = ${addprefix obj/,${patsubst %.c,%.o,$(SRC)}}
+
+PSEUDOTERM_SRC = pseudoterm.c serial.c control_2xxx.c
+PSEUDOTERM_OBJS = ${addprefix obj/,${patsubst %.c,%.o,$(PSEUDOTERM_SRC)}}
+
+TARGETDIR = bin
+
+lpc2k_pgm: $(OBJS)
+	mkdir -p $(TARGETDIR)
+	$(CC) -o $(TARGETDIR)/lpc2k_pgm $(OBJS)
+
+pseudoterm: $(PSEUDOTERM_OBJS)
+	mkdir -p $(TARGETDIR)
+	$(CC) -o $(TARGETDIR)/pseudoterm $(PSEUDOTERM_OBJS) -lpthread 
+
+chipinfo.o: boot_2xxx.h boot_23xx.h
+
+static: $(OBJS) mkstaticlist
+	$(CC) -o $(TARGETDIR)/lpc2k_pgm $(OBJS) `./mkstaticlist`
+
+obj/%.o : src/%.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+cksum_test: cksum_test.c uuencode.o cksum_test.o
+	$(CC) $(CFLAGS) -o $(TARGETDIR)/cksum_test obj/cksum_test.o obj/uuencode.o
+
+boot_2xxx.c boot_2xxx.h: boot_2xxx.armasm mkbootc
+	arm-none-eabi-as -o boot_2xxx.armobj boot_2xxx.armasm
+	arm-none-eabi-objdump -d boot_2xxx.armobj | ./mkbootc boot_2xxx
+
+boot_23xx.c boot_23xx.h: src/boot_23xx.armasm mkbootc
+	arm-none-eabi-as -o obj/boot_23xx.armobj src/boot_23xx.armasm
+	arm-none-eabi-objdump -d obj/boot_23xx.armobj | ./mkbootc boot_23xx
+
+clean:
+	rm -f bin/lpc2k_pgm cksum_test obj/*.o core core.* obj/*.armobj bin/pseudoterm
+
+install:
+	install -m 0755 bin/lpc2k_pgm $(prefix)/bin
+
+.PHONY: install
+
+obj/gui.o: src/gui.c
+	$(CC) $(CFLAGS) `gtk-config --cflags` -c src/gui.c -o obj/gui.o
diff --git a/boards/msba2-common/tools/README.txt b/boards/msba2-common/tools/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8fd6adb012b8ac424c295edecf5a8200c1c8f09f
--- /dev/null
+++ b/boards/msba2-common/tools/README.txt
@@ -0,0 +1,144 @@
+This utility downloads code to Philip LPC 2000 series chips, using the
+bootloader communication protocol documented in the LPC2106/2105/2104
+User Manual, Sept 2003 revision, pages 177 to 192.  This code has also
+been tested with LPC2131 and LPC2138 chips (thanks to New Micros for
+providing eval boards).  It may work with other Philips ARM LPC parts.
+
+
+
+Usage:
+-----
+
+When you start the program, it's small control window appears, and a
+xterm terminal window is launched.  The Xterm window allows you to
+simply leave lpc2k_pgm running and interface with the LPC uart using
+that window.  Most people configure "printf" on in their code to print
+to UART0, which will appear in this window.
+
+This program has 4 settings:
+
+Firmware:  The intel-hex file with your LPC firmware to program.
+Port:      Which serial device to use.
+Baud:      The baud rate to communicate.
+Crystal:   The speed of the crystal on your LPC board.
+
+Once you have set up these values, simply press the "Program Now"
+button to write your firmware to the LPC flash memory, and automatically
+run it.  If your firmware communicates on UART0, its messages will appear
+in the xterm window, and anything you type in that window will be
+transmitted to your board.
+
+The "Reboot" button may be used to reboot your code (assuming you have
+connected DTR appropriately).  The "Bootloader" button may be used to
+stop your code by rebooting into the bootloader, rather than your program.
+
+
+
+Hardware Requirements:
+---------------------
+
+You must have a compatible Philips LPC chip with its UART0 interfaced
+to a serial port on your PC.
+
+You must be able to reset the chip and cause it to enter bootloader mode.
+Normally, this is done by connecting the (TTL level translated) DTR signal
+to the LPC reset, so that when DTR is high (the TTL version is low), the
+Philips chip is in reset mode.  Alternately, a pushbutton may be used,
+but you will need to manually press the button every time you want to get
+back into bootloader mode (while this program attempts to sync baud rates),
+rather than letting DTR do it automatically.  A few minutes spent wiring
+up your circuit so DTR can reset the board will save you much trouble as
+you develop code.
+
+P0.14 must be connected low shortly after reset.  Normally, this pin
+is just shorted to ground using a jumper.  Starting with version 1.02,
+you can simply leave this shorted to ground.  If your design needs to
+use this pin, you may also build a simple circuit that forces this pin
+to ground when RTS is high.
+
+
+
+Software Requirements:
+---------------------
+
+You must have a Linux-based system running X Windows.  This code has
+been tested with Linux kernel 2.4.20 and 2.6.8, and should work with
+almost any linux system.
+
+You must have the "xterm" program installed.  Nearly all linux
+distrubtions provide this, and it is often installed by default.  If
+you do not have it, simply install from your linux distribution.
+
+Your serial port device file (usually /dev/ttyS0 or /dev/ttyS1) must
+allow permission for you to use the serial port.
+
+GTK 1.2 is used for the GUI.  Many newer systems only have GTK version
+2 (or higher).  If you have one of these systems, perhaps you can
+install GTK 1.2 (including the development libraries) to allow you to
+compile this code.  Alternately, you may be able to use the semi-static
+build, which includes a copy of this code built into the program.
+
+
+
+Building and Installation:
+-------------------------
+
+This software is only provided semi-static binary and source code form.
+
+To use the semi-static binary, simply copy it to a location where you
+can run it, and change the permissions if necessary:
+
+	cp lpc2k_pgm /usr/local/bin
+	chmod 755 /usr/local/bin/lpc2k_pgm
+
+The semi-static binary has all of the GTK and X11 libraries statically
+linked into it, for maximum compatibility with all linux distributions.
+The only disadvantage is, of course, that this uses an extra 1.4 megs
+of RAM, with (might) otherwise be shared with other programs.  If you
+simply want to run this program with minimal work, using the semi-static
+binary may be the easiest way.
+
+If you compile from the source code, the result should be a small
+binary that is optimal for your system.
+
+To build from source, you must have GTK+ 1.2 development libraries
+and GCC properly installed.  Nearly all linux distributions provide
+these as packages, but you may need to install them before you can
+compile the code.
+
+TODO: specific instructions for Debian stable
+TODO: specific instructions for Debian testing/unstable
+TODO: specific instructions for Fedora
+TODO: specific instructions for Suse
+
+Simply type "make" to build the code.  The resulting "lpc2k_pgm"
+program can be run from any location.  Simply copy to /usr/local/bin,
+or where ever you like.
+
+
+
+Contact Info:
+------------
+
+Paul Stoffregen
+paul@pjrc.com
+http://www.pjrc.com/arm/lpc2k_pgm
+
+If you discover a bug, you want to request a new feature, or you have
+a new Philips LPC chip which is not recognized, please attempt to
+provide COMPLETE information in your message.
+
+If you have problems building from source, please contact me with ALL
+of the following:
+
+1: Complete copy of all messages during the build.
+2: Output of "gtk-config --version"
+3: Output of "gtk-config --libs"
+4: Output of "gtk-config --cflags"
+5: Output of "uname -a"
+6: Other info... which linux distribution, version, other software
+
+If you get "Command not found" when trying to run "gtk-config", this
+is a sure sign that you do not have GTK+ 1.2 installed.
+
+
diff --git a/boards/msba2-common/tools/armtools.txt b/boards/msba2-common/tools/armtools.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c91a4853f753bc115887817bc3e57fae63c0d3b2
--- /dev/null
+++ b/boards/msba2-common/tools/armtools.txt
@@ -0,0 +1,15 @@
+This directory contains flash & terminal-utilities for use with 
+the msb_av2 platform used by the FeuerWhere-Project.
+
+Usage:
+Running "./pseudoterm /dev/ttyUSB1" will start the terminal-emulator,
+open the specified port and reset the connected msb_av2-board.
+If it receives a SIGUSR2, the terminal closes the port an waits.
+On reception of a SIGUSR1, it reopens the port and resets the ARM.
+
+"./lpc2k_pgm /dev/ttyUSB1 /path/to/firmware.ihex" will do what you
+expect, but it will additionally run "killall -SIGUSR2 pseudoterm" before
+anѕ "killall -SIGUSR1 pseudoterm" after flashing.
+
+Together, the tools enable you to have a terminal connected to the board
+at all times, but let you flash whenever you feel like.
diff --git a/boards/msba2-common/tools/flash.cmd b/boards/msba2-common/tools/flash.cmd
new file mode 100755
index 0000000000000000000000000000000000000000..e957ca2b654438739ca6903b097ac6a0502449e0
--- /dev/null
+++ b/boards/msba2-common/tools/flash.cmd
@@ -0,0 +1,2 @@
+fm.exe "COM(%1, 230400) DEVICE(LPC2387, 16.000000) HARDWARE(BOOTEXEC, 50, 100) HIGHSPEED(0, 230400) ERASEUSED(%2, PROTECTISP) HEXFILE(%2, NOCHECKSUMS, NOFILL, PROTECTISP) RESET"
+sleep 2
diff --git a/boards/msba2-common/tools/flashutil.sh b/boards/msba2-common/tools/flashutil.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c97d7c9a6322223137e3e687e546c55f5563f737
--- /dev/null
+++ b/boards/msba2-common/tools/flashutil.sh
@@ -0,0 +1,113 @@
+#/bin/bash
+
+linux_checkid() {
+    udevinfo -a -n ${1} | grep -q "ATTRS{product}==\"${2}\""
+}
+
+windows_flash_fm() {
+	echo "Checking FTDI device on COM${1}"
+	PORTINFO=`${BASEDIR}/../../../tools/windows/ftdiinfo/bin/Debug/ftdiinfo.exe /l COM${1}`
+	PORTCHECK=`echo ${PORTINFO} | awk '{ print $1 }'`
+	BOARDCHECK=`echo ${PORTINFO} | awk '{ print $3 }'`
+	SERIAL=`echo ${PORTINFO} | awk '{ print $2 }'`
+	if [ "${PORTCHECK}" != "COM${1}" ]; then
+		echo "  port mismatch / ftdiinfo failed"
+		exit 1
+	fi
+	if [ "${BOARDCHECK}" != "\"${FTDI_ID}\"" ]; then
+		echo "  target mismatch: target board is \"${FTDI_ID}\", connected is ${BOARDCHECK}"
+		exit 1
+	fi
+	
+	echo "Flashing ${HEXFILE} to COM${1} (${BOARDCHECK} serial ${SERIAL})"
+	# Using FlashMagic on Windows (in separate window)
+	cmd /C start "FlashMagic ${HEXFILE} to ${BOARDCHECK} on COM${1}" fm.exe "COM(${1}, 230400) DEVICE(LPC2387, 16.000000) HARDWARE(BOOTEXEC, 50, 100) HIGHSPEED(0, 230400) ERASEUSED(${HEXFILE}, PROTECTISP) HEXFILE(${HEXFILE}, NOCHECKSUMS, NOFILL, PROTECTISP) RESET"
+}
+
+windows_flash_openocd() {
+	echo "Flashing ${HEXFILE} through JTAG"
+	# Using OpenOcd on Windows
+	#cmd /C start "OpenOCD ${HEXFILE} to ${BOARDCHECK}"
+	bash -x ${OPENOCD} ${OPENOCD_IF} "mt_flash ${HEXFILE}; reset run; shutdown"
+}
+
+TEMP=`getopt -a -o b:i:p:f:: --long basedir:,id:,ports:,file:,openocd:,openocd-if:,xxx:: \
+     -n 'flashutil.sh' -- "$@"`
+
+if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
+
+# Note the quotes around `$TEMP': they are essential!
+eval set -- "$TEMP"
+
+while true ; do
+	echo $1: $2
+	case "$1" in
+		-b|--basedir)	BASEDIR=$2 ; shift 2 ;;
+		-i|--id)		FTDI_ID=$2; shift 2 ;;
+		-p|--ports)		PORTS=`echo $2 | sed -e 's:,: :g'`; shift 2 ;;
+		--openocd)		OPENOCD=$2; shift 2 ;;
+		--openocd-if)	OPENOCD_IF=$2; shift 2 ;;
+
+		--) HEXFILE=$2 ; shift ; break ;;
+		*) echo "Internal error!" ; exit 1 ;;
+	esac
+done
+
+if [ "${OS}" = "Windows_NT" ]; then
+	WINDOWS=1
+fi
+
+FLASHUTIL_SHELL=${FLASHUTIL_SHELL:-"xterm -e"}
+
+if [ "x${WINDOWS}x" = "xx" ]; then
+	echo Pausing terminal
+	${BASEDIR}/termctrl.sh pause
+else
+	HEXFILE=`echo ${HEXFILE} | sed -e 's:/:\\\\:g'`
+	BASEDIRWIN=`echo ${BASEDIR} | sed -e 's:/:\\\\:g'`
+fi
+
+pids=""
+
+#
+# for OpenOCD let the user verify, that the correct board is connected
+#
+if [ ${PORTS} = "openocd" ]; then
+	[ "$OPENOCD" != "" ] || exit 1
+	[ "$OPENOCD_IF" != "" ] || exit 1
+#    echo -n "Is the board connected to the JTAG a '${FTDI_ID}' (y/n)? " 
+#	read REPLY
+#	[ "$REPLY" = "y" ] || exit 1
+fi
+#
+# start a flasher for each port
+#
+for PORT in $PORTS; do
+	if [ "x${WINDOWS}x" != "xx" ]; then
+		if [ "${PORT}" = "openocd" ]; then
+			windows_flash_openocd
+		else
+			windows_flash_fm ${PORT}
+		fi
+	else
+		if [ "${PORT}" = "openocd" ]; then
+			${OPENOCD} ${OPENOCD_IF} "mt_flash ${HEXFILE}; reset run; shutdown"
+		else
+		echo Flashing ${HEXFILE} to ${PORT}
+		# using homemade lpc2k_pgm else
+	    	${FLASHUTIL_SHELL} "${BASEDIR}/bin/lpc2k_pgm ${PORT} ${HEXFILE}; sleep 2" &
+		    pids="${pids} $!"
+        fi
+	fi
+done
+
+### wait for all flasher processes to finish
+echo Waiting until all devices have been programmed...
+for pid in "${pids}"; do
+	wait ${pid}
+done
+
+if [ "x${WINDOWS}x" = "xx" ]; then
+	echo Resuming terminal
+	${BASEDIR}/termctrl.sh continue
+fi
diff --git a/boards/msba2-common/tools/mkbootc b/boards/msba2-common/tools/mkbootc
new file mode 100644
index 0000000000000000000000000000000000000000..4c0d9554dcd7432137a8ac14535b7eb5ac4ecec8
--- /dev/null
+++ b/boards/msba2-common/tools/mkbootc
@@ -0,0 +1,28 @@
+#! /usr/bin/perl
+
+$h = '[0-9A-Fa-f]';
+$n = 1;
+while (<stdin>) {
+	next unless /^\s*$h+:\s+($h{8})/;
+	$data[$n++] = "0x$1";
+}
+$data[0] = $n;
+#$size = $ARGV[0];
+#$size =~ tr/a-z/A-Z/;
+#$size .= '_SIZE';
+
+open H, ">$ARGV[0].h" or die "unable to write boot.h\n";
+print H "/* automatically generated from $ARGV[0].armasm */\n";
+#print H "#define $size $n\n";
+print H "extern const unsigned int ${ARGV[0]}[];\n";
+close H;
+
+open C, ">$ARGV[0].c" or die "unable to write boot.c\n";
+print C "/* automatically generated from $ARGV[0].armasm */\n";
+print C "#include \"$ARGV[0].h\"\n";
+print C "const unsigned int ${ARGV[0]}[] = {\n";
+print C "\t", join(', ', @data), "\n";
+print C "};\n";
+close C;
+
+
diff --git a/boards/msba2-common/tools/mkstaticlist b/boards/msba2-common/tools/mkstaticlist
new file mode 100644
index 0000000000000000000000000000000000000000..4ad31030ca512d89bce250f5fe29d162c0207e90
--- /dev/null
+++ b/boards/msba2-common/tools/mkstaticlist
@@ -0,0 +1,47 @@
+#! /usr/bin/perl
+
+@arg = split(/\s+/, `gtk-config --libs`);
+
+%liblist = (
+	'libgtk.a',	'/usr/lib/libgtk.a',
+	'libgdk.a',	'/usr/lib/libgdk.a',
+	'libgmodule.a',	'/usr/lib/libgmodule.a',
+	'libglib.a',	'/usr/lib/libglib.a',
+	'libXi.a',	'/usr/X11R6/lib/libXi.a',
+	'libXext.a',	'/usr/X11R6/lib/libXext.a',
+	'libX11.a',	'/usr/X11R6/lib/libX11.a'
+);
+
+
+for ($i=0; $i<@arg; $i++) {
+	$a = $arg[$i];
+	next if $a eq '-rdynamic';  # always delete -rdynamic
+	if (($a eq '-lm') || ($a eq '-ldl') || ($a =~ /^-L/)) {
+		# a few things we never change
+		print "$a ";
+		next;
+	}
+	if ($a =~ /^-l/) {
+		$lib = $';
+		$lib = 'lib' . $lib . '.a';
+		# first check if it's in the known location
+		if (-f $liblist{$lib}) {
+			print $liblist{$lib}, " ";
+			next;
+		}
+		# resort to trying whereis to find it
+		@source = split(/\s+/, `whereis $lib`);
+		undef($static);
+		for ($j=0; $j<@source; $j++) {
+			$static = $source[$j] if $source[$j] =~ /$lib$/;
+		}
+		# if we found a static lib, use it.
+		if ($static) {
+			print $static, " ";
+		} else {
+			print $a, " ";
+		}
+	}
+}
+print "\n";
+
diff --git a/boards/msba2-common/tools/obj/boot_23xx.d b/boards/msba2-common/tools/obj/boot_23xx.d
new file mode 100644
index 0000000000000000000000000000000000000000..e45338d65153e3ecd27597cd6542c67892c1f20d
--- /dev/null
+++ b/boards/msba2-common/tools/obj/boot_23xx.d
@@ -0,0 +1,3 @@
+obj/boot_23xx.d: src/boot_23xx.c src/boot_23xx.h
+
+src/boot_23xx.h:
diff --git a/boards/msba2-common/tools/obj/boot_2xxx.d b/boards/msba2-common/tools/obj/boot_2xxx.d
new file mode 100644
index 0000000000000000000000000000000000000000..e0e9fb40daa6b77ad8f6c2edceaf4021f75c215c
--- /dev/null
+++ b/boards/msba2-common/tools/obj/boot_2xxx.d
@@ -0,0 +1,3 @@
+obj/boot_2xxx.d: src/boot_2xxx.c src/boot_2xxx.h
+
+src/boot_2xxx.h:
diff --git a/boards/msba2-common/tools/obj/chipinfo.d b/boards/msba2-common/tools/obj/chipinfo.d
new file mode 100644
index 0000000000000000000000000000000000000000..b695e68c42cb59fc53d0b13b869d502e02d3c61c
--- /dev/null
+++ b/boards/msba2-common/tools/obj/chipinfo.d
@@ -0,0 +1,8 @@
+obj/chipinfo.d: src/chipinfo.c src/chipinfo.h src/boot_2xxx.h \
+ src/boot_23xx.h
+
+src/chipinfo.h:
+
+src/boot_2xxx.h:
+
+src/boot_23xx.h:
diff --git a/boards/msba2-common/tools/obj/control_2xxx.d b/boards/msba2-common/tools/obj/control_2xxx.d
new file mode 100644
index 0000000000000000000000000000000000000000..e9ed3f7b1b4b5d054c5ea2d80ff4aa51524fbeda
--- /dev/null
+++ b/boards/msba2-common/tools/obj/control_2xxx.d
@@ -0,0 +1,5 @@
+obj/control_2xxx.d: src/control_2xxx.c src/control_2xxx.h src/serial.h
+
+src/control_2xxx.h:
+
+src/serial.h:
diff --git a/boards/msba2-common/tools/obj/download.d b/boards/msba2-common/tools/obj/download.d
new file mode 100644
index 0000000000000000000000000000000000000000..94c10a80c529331fc0a35967d2fcc120455409ce
--- /dev/null
+++ b/boards/msba2-common/tools/obj/download.d
@@ -0,0 +1,19 @@
+obj/download.d: src/download.c src/lpc2k_pgm.h src/download.h \
+ src/serial.h src/ihex.h src/uuencode.h src/chipinfo.h src/boot.h \
+ src/control_2xxx.h
+
+src/lpc2k_pgm.h:
+
+src/download.h:
+
+src/serial.h:
+
+src/ihex.h:
+
+src/uuencode.h:
+
+src/chipinfo.h:
+
+src/boot.h:
+
+src/control_2xxx.h:
diff --git a/boards/msba2-common/tools/obj/ihex.d b/boards/msba2-common/tools/obj/ihex.d
new file mode 100644
index 0000000000000000000000000000000000000000..89b506056afdb04e30550417a430123f3c29f242
--- /dev/null
+++ b/boards/msba2-common/tools/obj/ihex.d
@@ -0,0 +1,3 @@
+obj/ihex.d: src/ihex.c src/ihex.h
+
+src/ihex.h:
diff --git a/boards/msba2-common/tools/obj/lpc2k_pgm.d b/boards/msba2-common/tools/obj/lpc2k_pgm.d
new file mode 100644
index 0000000000000000000000000000000000000000..98c82eb3289a938a95f3048440da70f9243513b1
--- /dev/null
+++ b/boards/msba2-common/tools/obj/lpc2k_pgm.d
@@ -0,0 +1,8 @@
+obj/lpc2k_pgm.d: src/lpc2k_pgm.c src/lpc2k_pgm.h src/serial.h \
+ src/download.h
+
+src/lpc2k_pgm.h:
+
+src/serial.h:
+
+src/download.h:
diff --git a/boards/msba2-common/tools/obj/pseudoterm.d b/boards/msba2-common/tools/obj/pseudoterm.d
new file mode 100644
index 0000000000000000000000000000000000000000..858fa2cba7843132f6ad70eb183404b11fc7e27e
--- /dev/null
+++ b/boards/msba2-common/tools/obj/pseudoterm.d
@@ -0,0 +1,5 @@
+obj/pseudoterm.d: src/pseudoterm.c src/serial.h src/download.h
+
+src/serial.h:
+
+src/download.h:
diff --git a/boards/msba2-common/tools/obj/serial.d b/boards/msba2-common/tools/obj/serial.d
new file mode 100644
index 0000000000000000000000000000000000000000..ebabf01ecfb88fdf130d46a2803e5a06c7c11957
--- /dev/null
+++ b/boards/msba2-common/tools/obj/serial.d
@@ -0,0 +1,3 @@
+obj/serial.d: src/serial.c src/serial.h
+
+src/serial.h:
diff --git a/boards/msba2-common/tools/obj/uuencode.d b/boards/msba2-common/tools/obj/uuencode.d
new file mode 100644
index 0000000000000000000000000000000000000000..548a00f642204f08ba47be798af4e35dcde63c14
--- /dev/null
+++ b/boards/msba2-common/tools/obj/uuencode.d
@@ -0,0 +1,3 @@
+obj/uuencode.d: src/uuencode.c src/uuencode.h
+
+src/uuencode.h:
diff --git a/boards/msba2-common/tools/src/boot.h b/boards/msba2-common/tools/src/boot.h
new file mode 100644
index 0000000000000000000000000000000000000000..ebca675db19e84706b81fe156c6073ebdd57ab2b
--- /dev/null
+++ b/boards/msba2-common/tools/src/boot.h
@@ -0,0 +1,9 @@
+
+typedef struct {
+    int size;
+    const int *prog;
+} boot_t;
+
+
+
+
diff --git a/boards/msba2-common/tools/src/boot_23xx.armasm b/boards/msba2-common/tools/src/boot_23xx.armasm
new file mode 100644
index 0000000000000000000000000000000000000000..50e29957ff41a27b43daf1273cce9e61fc009bb9
--- /dev/null
+++ b/boards/msba2-common/tools/src/boot_23xx.armasm
@@ -0,0 +1,32 @@
+	/* ARM code to run user code */
+	/* on the LPC23xx chips, the bootloader defaults to using the RC */
+	/* osciallator and it activates the PLL to create 14.78 MHz, even */
+	/* if there is no crystal.  However, when we use try to jump to */
+	/* the user's code, their startup routine may (incorrectly) assume */
+	/* the PLL is not enabled and crash if it is.  So in addition to */
+	/* remapping the reset vector to flash, we have to shut off the */
+	/* PLL so the user's startup code sees the same conditions as it */
+	/* would following a hard reset */
+begin:
+	adr	r0, const
+	ldr	r1, [r0]	/* r1 points to MEMMAP register */
+	ldr	r2, [r0,#4]	/* r2 points to PLLCON */
+	ldr	r3, [r0,#8]	/* r3 points to PLLFEED */
+	mov	r0, #1
+	str	r0, [r1]	/* remap interrupt vectors to flash */
+	mov	r4, #0xAA
+	mov	r5, #0x55
+	str	r0, [r2]	/* disconnect the PLL, PLLCON = 1 */
+	str	r4, [r3]
+	str	r5, [r3]
+	mov	r0, #0
+	str	r0, [r2]	/* disable the PLL, PLLCON = 0 */
+	str	r4, [r3]
+	str	r5, [r3]
+	mov	pc, #0		/* and then jump to the user's code */
+const:
+	.int	0xE01FC040	/* MEMMAP register */
+	.int	0xE01FC080	/* PLLCON */
+	.int	0xE01FC08C	/* PLLFEED */
+
+
diff --git a/boards/msba2-common/tools/src/boot_23xx.c b/boards/msba2-common/tools/src/boot_23xx.c
new file mode 100644
index 0000000000000000000000000000000000000000..80fcb399d0cbf32af60660a78e8d8d342b3c430c
--- /dev/null
+++ b/boards/msba2-common/tools/src/boot_23xx.c
@@ -0,0 +1,5 @@
+/* automatically generated from boot_23xx.armasm */
+#include "boot_23xx.h"
+const unsigned int boot_23xx[] = {
+    20, 0xe28f0038, 0xe5901000, 0xe5902004, 0xe5903008, 0xe3a00001, 0xe5810000, 0xe3a040aa, 0xe3a05055, 0xe5820000, 0xe5834000, 0xe5835000, 0xe3a00000, 0xe5820000, 0xe5834000, 0xe5835000, 0xe3a0f000, 0xe01fc040, 0xe01fc080, 0xe01fc08c
+};
diff --git a/boards/msba2-common/tools/src/boot_23xx.h b/boards/msba2-common/tools/src/boot_23xx.h
new file mode 100644
index 0000000000000000000000000000000000000000..0696a2931223ddbce61cb8f59a01d454b3652eaa
--- /dev/null
+++ b/boards/msba2-common/tools/src/boot_23xx.h
@@ -0,0 +1,2 @@
+/* automatically generated from boot_23xx.armasm */
+extern const unsigned int boot_23xx[];
diff --git a/boards/msba2-common/tools/src/boot_2xxx.armasm b/boards/msba2-common/tools/src/boot_2xxx.armasm
new file mode 100644
index 0000000000000000000000000000000000000000..38e171520acd6bd40619fa4e790a5ee8758fd3a6
--- /dev/null
+++ b/boards/msba2-common/tools/src/boot_2xxx.armasm
@@ -0,0 +1,15 @@
+	/* ARM code to run user code */
+	/* This allows us to jump to the user's code in flash.  We have */
+	/* to remap the flash before jumping. */
+begin:
+	adr	r0, const
+	ldr	r1, [r0]	/* r1 points to MEMMAP register */
+	mov	r0, #1
+	str	r0, [r1]	/* remap interrupt vectors to flash */
+	mov	pc, #0		/* and then jump to the user's code */
+const:
+	.int	0xE01FC040	/* MEMMAP register */
+
+
+
+
diff --git a/boards/msba2-common/tools/src/boot_2xxx.c b/boards/msba2-common/tools/src/boot_2xxx.c
new file mode 100644
index 0000000000000000000000000000000000000000..060db403543db6be7d961a434d9c21b3ded2de4c
--- /dev/null
+++ b/boards/msba2-common/tools/src/boot_2xxx.c
@@ -0,0 +1,5 @@
+/* automatically generated from boot_2xxx.armasm */
+#include "boot_2xxx.h"
+const unsigned int boot_2xxx[] = {
+    7, 0xe28f000c, 0xe5901000, 0xe3a00001, 0xe5810000, 0xe3a0f000, 0xe01fc040
+};
diff --git a/boards/msba2-common/tools/src/boot_2xxx.h b/boards/msba2-common/tools/src/boot_2xxx.h
new file mode 100644
index 0000000000000000000000000000000000000000..333188def24e98fd38565ba64b59c176caae802a
--- /dev/null
+++ b/boards/msba2-common/tools/src/boot_2xxx.h
@@ -0,0 +1,2 @@
+/* automatically generated from boot_2xxx.armasm */
+extern const unsigned int boot_2xxx[];
diff --git a/boards/msba2-common/tools/src/chipinfo.c b/boards/msba2-common/tools/src/chipinfo.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c418379b8653e1b80f8bd811658791f259209b1
--- /dev/null
+++ b/boards/msba2-common/tools/src/chipinfo.c
@@ -0,0 +1,156 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+#include "chipinfo.h"
+#include "boot_2xxx.h"
+#include "boot_23xx.h"
+
+
+struct sector_info_struct lpc2106_layout[] = {
+    {0x00000000, 0x2000},
+    {0x00002000, 0x2000},
+    {0x00004000, 0x2000},
+    {0x00006000, 0x2000},
+    {0x00008000, 0x2000},
+    {0x0000A000, 0x2000},
+    {0x0000C000, 0x2000},
+    {0x0000E000, 0x2000},
+    {0x00010000, 0x2000},
+    {0x00012000, 0x2000},
+    {0x00014000, 0x2000},
+    {0x00016000, 0x2000},
+    {0x00018000, 0x2000},
+    {0x0001A000, 0x2000},
+    {0x0001C000, 0x2000}
+};
+
+struct sector_info_struct lpc2214_layout[] = {
+    {0x00000000, 0x2000},
+    {0x00002000, 0x2000},
+    {0x00004000, 0x2000},
+    {0x00006000, 0x2000},
+    {0x00008000, 0x2000},
+    {0x0000A000, 0x2000},
+    {0x0000C000, 0x2000},
+    {0x0000E000, 0x2000},
+    {0x00010000, 0x10000},
+    {0x00020000, 0x10000},
+    {0x00030000, 0x2000},
+    {0x00032000, 0x2000},
+    {0x00034000, 0x2000},
+    {0x00036000, 0x2000},
+    {0x00038000, 0x2000},
+    {0x0003A000, 0x2000},
+    {0x0003C000, 0x2000}
+};
+
+struct sector_info_struct lpc2138_layout[] = {
+    {0x00000000, 0x1000},
+    {0x00001000, 0x1000},
+    {0x00002000, 0x1000},
+    {0x00003000, 0x1000},
+    {0x00004000, 0x1000},
+    {0x00005000, 0x1000},
+    {0x00006000, 0x1000},
+    {0x00007000, 0x1000},
+    {0x00008000, 0x8000},
+    {0x00010000, 0x8000},
+    {0x00018000, 0x8000},
+    {0x00020000, 0x8000},
+    {0x00028000, 0x8000},
+    {0x00030000, 0x8000},
+    {0x00038000, 0x8000},
+    {0x00040000, 0x8000},
+    {0x00048000, 0x8000},
+    {0x00050000, 0x8000},
+    {0x00058000, 0x8000},
+    {0x00060000, 0x8000},
+    {0x00068000, 0x8000},
+    {0x00070000, 0x8000},
+    {0x00078000, 0x1000},
+    {0x00079000, 0x1000},
+    {0x0007A000, 0x1000},
+    {0x0007B000, 0x1000},
+    {0x0007C000, 0x1000}
+};
+
+
+
+/* chunk_size is the number of bytes that will be sent with each */
+/* "C" (Copy RAM to Flash) command.  This must be one of the sizes */
+/* supported by that command.  Beware that different chips support */
+/* different sets of sizes, so check the user manual specific to */
+/* the chip.  You must choose a chunk_size which is an an integer */
+/* multiple of all the sector sizes, and it must be able to fit */
+/* entirely within the RAM (allowing for the bootloader memory and */
+/* stack usage).  Currently, all available chunk sizes meet these */
+/* requirements, but who knows what Philips will do in the future? */
+//
+/* ram_addr is the location in RAM where the chunks are sent by the */
+/* "W" (Write to RAM) command. */
+
+
+struct chip_info_struct chip_info[] = {
+    /* part_number     id_string     ram_addr    _size   sec  sector layout  boot code */
+    {"LPC2104 (120k)", "4293984018", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
+    {"LPC2105 (120k)", "4293984034", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
+    {"LPC2106 (120k)", "4293984050", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
+    {"LPC2114 (120k)", "16908050",	 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
+    {"LPC2119 (120k)", "33685266",	 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
+    {"LPC2124 (120k)", "16908051",	 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx},
+    {"LPC2129 (248k)", "33685267",	 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
+    {"LPC2131 (32k)",  "196353",	 0x40000200, 0x1000,  8, lpc2138_layout, boot_2xxx},
+    {"LPC2132 (64k)",  "196369",	 0x40000200, 0x1000,  9, lpc2138_layout, boot_2xxx},
+    {"LPC2134 (128k)", "196370",	 0x40000200, 0x1000, 11, lpc2138_layout, boot_2xxx},
+    {"LPC2136 (256k)", "196387",	 0x40000200, 0x1000, 15, lpc2138_layout, boot_2xxx},
+    {"LPC2138 (500k)", "196389",	 0x40000200, 0x1000, 27, lpc2138_layout, boot_2xxx},
+    {"LPC2141 (32k)",  "67305217",	 0x40000200, 0x1000,  8, lpc2138_layout, boot_2xxx},
+    {"LPC2142 (64k)",  "67305233",	 0x40000200, 0x1000,  9, lpc2138_layout, boot_2xxx},
+    {"LPC2144 (128k)", "67305234",	 0x40000200, 0x1000, 11, lpc2138_layout, boot_2xxx},
+    {"LPC2146 (256k)", "67305251",	 0x40000200, 0x1000, 15, lpc2138_layout, boot_2xxx},
+    {"LPC2148 (500k)", "67305253",	 0x40000200, 0x1000, 27, lpc2138_layout, boot_2xxx},
+    {"LPC2194 (248k)", "50462483",	 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
+    {"LPC2212 (248k)", "67239698",	 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
+    {"LPC2214 (248k)", "100794131",	 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
+    {"LPC2292 (248k)", "67239699",	 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
+    {"LPC2294 (248k)", "84016915",	 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx},
+    {"LPC2103 (32k)",  "327441",	 0x40000200, 0x1000,  8, lpc2138_layout, boot_2xxx},
+    {"LPC2364 (128k)", "100924162",	 0x40000200, 0x1000, 11, lpc2138_layout, boot_23xx},
+    {"LPC2366 (256k)", "100924195",	 0x40000200, 0x1000, 15, lpc2138_layout, boot_23xx},
+    {"LPC2368 (500k)", "100924197",	 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
+    {"LPC2378 (500k)", "117702437",	 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
+    {"LPC2387 (500k)", "402716981",	 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
+    {"LPC2387 (500k)", "385941301",	 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
+    {"LPC2468 (500k)", "100925237",	 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx},
+    {NULL, NULL, 0, 0, 0, NULL}
+};
+
+
+
+char *lpc_return_strings[] = {
+    "CMD_SUCCESS", "INVALID_COMMAND", "SRC_ADDR_ERROR", "DST_ADDR_ERROR",
+    "SRC_ADDR_NOT_MAPPED", "DST_ADDR_NOT_MAPPED", "COUNT_ERROR", "INVALID_SECTOR",
+    "SECTOR_NOT_BLANK", "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION", "COMPARE_ERROR",
+    "BUSY", "PARAM_ERROR", "ADDR_ERROR", "ADDR_NOT_MAPPED", "CMD_LOCKED",
+    "INVALID_CODE", "INVALID_BAUD_RATE", "INVALID_STOP_BIT",
+    "CODE_READ_PROTECTION_ENABLED"
+};
+
diff --git a/boards/msba2-common/tools/src/chipinfo.h b/boards/msba2-common/tools/src/chipinfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c49593296c955ffb16f6118ed05638ee79fb2c5
--- /dev/null
+++ b/boards/msba2-common/tools/src/chipinfo.h
@@ -0,0 +1,20 @@
+extern char *lpc_return_strings[];
+
+struct sector_info_struct {	// an array of
+    int address;		// where each sector is located
+    int size;		// and how big it is
+};
+
+struct chip_info_struct {
+    char *part_number;	// human readable part number
+    char *id_string;	// id string sent by "J" command
+    unsigned int ram_addr;	// where to download into RAM
+    int chunk_size;		// download to ram chunk size
+    int num_sector;		// number of flash sectors
+    struct sector_info_struct *layout;  // layout of sectors
+    const unsigned int *bootprog;	// code that boots into user program (NULL = DTR/RTS only)
+};
+
+extern struct chip_info_struct chip_info[];
+
+
diff --git a/boards/msba2-common/tools/src/cksum_test.c b/boards/msba2-common/tools/src/cksum_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..facd6a1f3a9fdd8a9161860d81628ab3e43edcb7
--- /dev/null
+++ b/boards/msba2-common/tools/src/cksum_test.c
@@ -0,0 +1,85 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "uuencode.h"
+
+
+unsigned int sum = 0;
+
+
+
+void cksum(const char *str)
+{
+    int num, i;
+    unsigned char data[256];
+
+    if (str == NULL) {
+        return;
+    }
+
+    num = uudecode(str, data, sizeof(data));
+
+    for (i = 0; i < num; i++) {
+        sum += data[i];
+    }
+
+}
+
+
+int main()
+{
+    char buf[4096];
+
+    while (!feof(stdin)) {
+        fgets(buf, sizeof(buf), stdin);
+
+        if (strcmp(buf, "\n") == 0) {
+            break;
+        }
+
+        cksum(buf);
+    }
+
+    printf("sum = %u\n", sum);
+
+    return 0;
+}
+
+
+
+
+
diff --git a/boards/msba2-common/tools/src/control_2xxx.c b/boards/msba2-common/tools/src/control_2xxx.c
new file mode 100644
index 0000000000000000000000000000000000000000..581dd8e202948c8d5912a542e0095cd0b933cc80
--- /dev/null
+++ b/boards/msba2-common/tools/src/control_2xxx.c
@@ -0,0 +1,40 @@
+#include "control_2xxx.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "serial.h"
+
+void hard_reset_to_bootloader(void)
+{
+    /*	Use this lines for flashing a node with interrupted DTR line */
+    /*	printf("Press Reset - confirm with anykey\n");
+    getchar();
+    */
+    printf("Reset CPU (into bootloader)\r\n");
+    set_rts(1);		// RTS (ttl level) connects to P0.14
+    /* the next two lines should be commented for the prepared node */
+    set_dtr(1);		// DTR (ttl level) connects to RST
+    send_break_signal();	// or break detect circuit to RST
+    usleep(75000);
+    /*	Use this lines for flashing a node with interrupted DTR line */
+    /* printf("Release Reset - confirm with anykey\n");
+    getchar();
+    */
+    set_dtr(0);		// allow the CPU to run:
+    set_baud(baud_rate);
+    set_rts(1);		// set RTS again (as it has been reset by set_baudrate)
+    usleep(40000);
+}
+
+void hard_reset_to_user_code(void)
+{
+    printf("Reset CPU (into user code)\r\n");
+    set_rts(0);		// RTS (ttl level) connects to P0.14
+    set_dtr(1);		// DTR (ttl level) connects to RST
+    send_break_signal();	// or break detect circuit to RST
+    usleep(75000);
+    set_dtr(0);		// allow the CPU to run
+    usleep(40000);
+}
diff --git a/boards/msba2-common/tools/src/control_2xxx.h b/boards/msba2-common/tools/src/control_2xxx.h
new file mode 100644
index 0000000000000000000000000000000000000000..e37e2e29d506b8ee4303ff6b391467b94d973130
--- /dev/null
+++ b/boards/msba2-common/tools/src/control_2xxx.h
@@ -0,0 +1,8 @@
+#ifndef CONTROL_2XXXX_H
+#define CONTROL_2XXXX_H
+
+void hard_reset_to_bootloader(void);
+void hard_reset_to_user_code(void);
+
+#endif // ..._H
+
diff --git a/boards/msba2-common/tools/src/download.c b/boards/msba2-common/tools/src/download.c
new file mode 100644
index 0000000000000000000000000000000000000000..c7aab543a8174e4b38aef9d9c90f0cb1be0c39a0
--- /dev/null
+++ b/boards/msba2-common/tools/src/download.c
@@ -0,0 +1,1193 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "lpc2k_pgm.h"
+#include "download.h"
+#include "serial.h"
+#include "ihex.h"
+#include "uuencode.h"
+//#include "gui.h"
+#include "chipinfo.h"
+#include "boot.h"
+#include "control_2xxx.h"
+
+
+// This will cause all bytes send and received to be printed as hex.
+// It's a LOT of extra output, but useful for difficult debugging
+// of what's _really_ being sent and received.
+//#define PRINT_TX_RX_BYTES
+
+
+static void download_main(int event);
+static void xmit_cmd(const char *cmd, int max_time);
+static void mk_valid_code_vector(void);
+static unsigned int sum(unsigned char *data, int num);
+
+
+static int state = 0;
+static int reboot_only = 0;
+static char expected_echo_buf[4096];
+static char *expected_echo_ptr = NULL;
+static char parsed_response_buf[4096];
+static char *parsed_response_ptr = NULL;
+static int response_timer = 0;
+
+extern int programming_done;
+extern int done_program(int);
+
+
+char *port_name = "/dev/ttyUSB1";
+char *file_name = "";
+char *crystal = "16";
+
+/****************************************************************/
+/*								*/
+/*		     Main Download Section			*/
+/*								*/
+/****************************************************************/
+
+// possible states
+#define SYNC_1			1
+#define SYNC_2			2
+#define SYNC_3			3
+#define CHIP_ID			4
+#define UNLOCK			5
+#define BLANK_CHECK_SECTOR	6
+#define ERASE_PREPARE		7
+#define ERASE_SECTOR		8
+#define DOWNLOAD_CODE		9
+#define XMIT_DATA		10
+#define XMIT_CKSUM		11
+#define WRITE_PREPARE		12
+#define WRITE_SECTOR		13
+#define BOOT_HARD		14
+#define BOOT_SOFT		15
+#define BOOT_XMIT_DATA		16
+#define BOOT_XMIT_CKSUM		17
+#define BOOT_RUN_CODE		18
+
+
+// possible input values for "event"
+#define BEGIN 1
+#define RESPONSE 2
+#define TIMEOUT 3
+#define RETRY 4
+
+
+
+
+int download_begin(char *file)
+{
+    int r;
+
+    file_name = file;
+
+    printf("\r\nEntering Bootloader Mode\r\n");
+    hard_reset_to_bootloader();
+    printf("Read \"%s\"", file_name);
+    r = read_intel_hex(file_name);
+
+    if (r < 0) {
+        /* abort on ioerror */
+        return 0;
+    }
+
+    printf(": %d bytes\r\n", r);
+    mk_valid_code_vector();
+    state = SYNC_1;
+    reboot_only = 0;
+    download_main(BEGIN);
+    return 1;
+}
+
+
+void soft_reboot_begin(void)
+{
+    printf("\r\nEntering Bootloader Mode\r\n");
+    hard_reset_to_bootloader();
+    state = SYNC_1;
+    reboot_only = 1;
+    download_main(BEGIN);
+}
+
+static void mk_valid_code_vector(void)
+{
+    unsigned char b[4];
+    unsigned int sum = 0;
+    int addr;
+
+    for (addr = 0; addr < 0x20; addr += 4) {
+        if (addr != 0x14) {
+            get_ihex_data(addr, 4, b);
+            sum += (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24));
+        }
+    }
+
+    sum ^= 0xFFFFFFFF;
+    sum++;
+    b[0] = (sum >> 0) & 255;
+    b[1] = (sum >> 8) & 255;
+    b[2] = (sum >> 16) & 255;
+    b[3] = (sum >> 24) & 255;
+    put_ihex_data(0x14, 4, b);
+}
+
+
+static unsigned int sum(unsigned char *data, int num)
+{
+    unsigned int sum = 0;
+
+    while (num > 0) {
+        sum += *data++;
+        num--;
+    }
+
+    return sum;
+}
+
+
+static int num_lines(const char *buf)
+{
+    const char *p;
+    int count = 0;
+
+    p = buf;
+
+    while (p != NULL) {
+        p = strstr(p, "\r\n");
+
+        if (p != NULL) {
+            count++;
+            p += 2;
+        }
+    }
+
+    return count;
+}
+
+void trim_crlf(char *str)
+{
+    char *p;
+    p = strstr(str, "\r\n");
+
+    if (p != NULL) {
+        *p = '\0';
+    }
+}
+
+void copy_boot_code_to_memory(struct chip_info_struct *chip)
+{
+    int i;
+    unsigned char c[4];
+
+    for (i = 0; i < chip->bootprog[0]; i++) {
+        c[3] = (chip->bootprog[i + 1] >> 24) & 255;
+        c[2] = (chip->bootprog[i + 1] >> 16) & 255;
+        c[1] = (chip->bootprog[i + 1] >> 8) & 255;
+        c[0] = (chip->bootprog[i + 1]) & 255;
+        put_ihex_data(i * 4, 4, c);
+    }
+}
+
+
+#define NO_SYNC_ERR "\r\n\
+ERROR: Unable to sync to baud rate.\r\n\
+This probably means the LPC2xxx chip is not connected\r\n\
+or it is not being reset, or P0.14 is not low after\r\n\
+reset to cause it to enter the bootloader mode.\r\n\r\n\
+Please check the serial port connection, make sure\r\n\
+pin P0.14 is low (or tied to RTS via RS-232 level\r\n\
+translator), and the chip has been reset (or reset\r\n\
+is tied to DTR via RS-232 level translator).\r\n"
+
+#define UNKNOWN_CHIP_ERROR "\r\n\
+Unknown chip ID: \"%s\".\r\n\r\n\
+Perhaps you have a new Philips LPC chip which does not\r\n\
+have its ID string and sector map defined in this program?\r\n\
+Please contact paul@pjrc.com.  Please include an exact copy\r\n\
+of this message and any info about the chip and other\r\n\
+hardware you may be using.  Thanks :-)\r\n"
+
+
+static void download_main(int event)
+{
+    char buf[4096];
+    unsigned char bytes[256];
+    double xtal;
+    int n;
+    static unsigned int cksum;
+    static int retry = 0;
+    static int sector;		// current sector we're doing
+    static int sector_offset;
+    static struct chip_info_struct *chip;	// which chip
+    static int current_addr, num_to_xmit, linecount;
+
+
+    while (1) {
+        switch (state) {
+            case SYNC_1:
+                switch (event) {
+                    case BEGIN:
+                        printf("Attempting baud sync");
+                        retry = 0;
+
+                    case RETRY:
+                        printf(".");
+                        fflush(stdout);
+                        xmit_cmd("?", 2);
+                        return;
+
+                    case RESPONSE:
+                        if (strcmp(parsed_response_buf, "Synchronized\r\n") == 0) {
+                            //printf("response: sync'd\n");
+                            state = SYNC_2;
+                            event = BEGIN;
+                            break;
+                        }
+
+                        if (strcmp(parsed_response_buf, "?") == 0) {
+                            //printf("response: echo only\n");
+                            retry++;
+
+                            if (retry > 150) {
+                                download_cancel(NO_SYNC_ERR);
+                                return;
+                            }
+
+                            event = RETRY;
+                            usleep(30000);
+                            break;
+                        }
+
+                        snprintf(buf, sizeof(buf), "Unexpected response to sync, \"%s\"",
+                                 parsed_response_buf);
+                        download_cancel(buf);
+                        return;
+
+                    case TIMEOUT:
+                        if (retry < 100) {
+                            retry++;
+                            event = RETRY;
+                            break;
+                        }
+
+                        download_cancel(NO_SYNC_ERR);
+                        return;
+                }
+
+                break;
+
+
+            case SYNC_2:
+                switch (event) {
+                    case BEGIN:
+                        xmit_cmd("Synchronized\r\n", 3);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
+                            state = SYNC_3;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            snprintf(buf, sizeof(buf), "Unable to complete baud sync, %s",
+                                     parsed_response_buf);
+                            download_cancel(buf);
+                            return;
+                        }
+
+                        return;
+
+                    case TIMEOUT:
+                        download_cancel("No response to complete baud sync");
+                        return;
+                }
+
+                break;
+
+
+            case SYNC_3:
+                switch (event) {
+                    case BEGIN:
+                        if (sscanf(crystal, "%lf", &xtal) != 1) {
+                            printf("\r\n");
+                            download_cancel("Crystal frequency is required for 3rd step of baud rate sync");
+                            return;
+                        }
+
+                        if (xtal < 10.0 || xtal > 25.0) {
+                            printf("\r\n");
+                            printf("Warning: crystal frequency out of range (10.0 to 25.0), continuing anyway! (hope you know what you're doing)\r\n");
+                        }
+
+                        snprintf(buf, sizeof(buf), "%d\r\n", (int)(xtal * 1000.0 + 0.5));
+                        xmit_cmd(buf, 3);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
+                            printf("Baud sync sucessful\r\n");
+                            state = CHIP_ID;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            snprintf(buf, sizeof(buf), "wrong response to crystal: %s",
+                                     parsed_response_buf);
+                            download_cancel(buf);
+                            return;
+                        }
+
+                        return;
+
+                    case TIMEOUT:
+                        download_cancel("No response to crystal speed");
+                        return;
+                }
+
+                break;
+
+
+            case CHIP_ID:
+                switch (event) {
+                    case BEGIN:
+                        xmit_cmd("J\r\n", 3);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) < 2) {
+                            return;
+                        }
+
+                        if (strncmp(parsed_response_buf, "0\r\n", 3) == 0) {
+                            trim_crlf(parsed_response_buf + 3);
+
+                            for (chip = chip_info; chip->part_number != NULL; chip++) {
+                                if (strcmp(parsed_response_buf + 3, chip->id_string) == 0) {
+                                    break;
+                                }
+                            }
+
+                            if (chip->part_number == NULL) {
+                                snprintf(buf, sizeof(buf), UNKNOWN_CHIP_ERROR,
+                                         parsed_response_buf + 3);
+                                download_cancel(buf);
+                                break;
+                            }
+
+                            printf("Found chip: \"%s\"\r\n", chip->part_number);
+                            //download_cancel("stop here, remove this later");
+                            state = UNLOCK;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            snprintf(buf, sizeof(buf), "wrong response to ID: %s",
+                                     parsed_response_buf);
+                            download_cancel(buf);
+                            return;
+                        }
+
+                        return;
+
+                    case TIMEOUT:
+                        download_cancel("No response to unlock command");
+                        return;
+                }
+
+                break;
+
+
+            case UNLOCK:
+                switch (event) {
+                    case BEGIN:
+                        xmit_cmd("U 23130\r\n", 3);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            printf("Device Unlocked\r\n");
+
+                            if (reboot_only) {
+                                state = BOOT_SOFT;
+                            }
+                            else {
+                                state = BLANK_CHECK_SECTOR;
+                                printf("Erasing....\r\n");
+                                sector = 0;
+                            }
+
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            snprintf(buf, sizeof(buf), "wrong response unlock: %s",
+                                     parsed_response_buf);
+                            download_cancel(buf);
+                            return;
+                        }
+
+                        return;
+
+                    case TIMEOUT:
+                        download_cancel("No response to unlock command");
+                        return;
+                }
+
+                break;
+
+
+            case BLANK_CHECK_SECTOR:
+                switch (event) {
+                    case BEGIN:
+                        if (sector >= chip->num_sector) {
+                            printf("Programming....\r\n");
+                            state = DOWNLOAD_CODE;
+                            sector = sector_offset = 0;
+                            event = BEGIN;
+                            break;
+                        }
+
+                        printf("  Sector %2d: ", sector);
+                        fflush(stdout);
+
+                        if (!bytes_within_range(chip->layout[sector].address,
+                                                chip->layout[sector].address + chip->layout[sector].size - 1)) {
+                            printf("not used\r\n");
+                            sector++;
+                            break;
+                        }
+
+                        if (sector == 0) {
+                            // can't blank check sector 0, so always erase it
+                            state = ERASE_PREPARE;
+                            break;
+                        }
+
+                        snprintf(buf, sizeof(buf), "I %d %d\r\n", sector, sector);
+                        xmit_cmd(buf, 5);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) == 1 &&
+                            strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            printf("already blank\r\n");
+                            sector++;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            if (num_lines(parsed_response_buf) < 3) {
+                                return;
+                            }
+
+                            state = ERASE_PREPARE;
+                            event = BEGIN;
+                            break;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response to blank check");
+                        return;
+                }
+
+                break;
+
+
+
+            case ERASE_PREPARE:
+                switch (event) {
+                    case BEGIN:
+                        printf("prep, ");
+                        fflush(stdout);
+                        snprintf(buf, sizeof(buf), "P %d %d\r\n", sector, sector);
+                        xmit_cmd(buf, 8);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            state = ERASE_SECTOR;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            download_cancel("Unable to prep for write");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+
+            case ERASE_SECTOR:
+                switch (event) {
+                    case BEGIN:
+                        printf("erase... ");
+                        fflush(stdout);
+                        snprintf(buf, sizeof(buf), "E %d %d\r\n", sector, sector);
+                        xmit_cmd(buf, 25);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) < 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            printf("Ok\r\n");
+                            sector++;
+                            state = BLANK_CHECK_SECTOR;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            printf("Error\r\n");
+                            download_cancel("Unable to erase flash");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+
+            case DOWNLOAD_CODE:
+                switch (event) {
+                    case BEGIN:
+                        if (sector >= chip->num_sector) {
+                            state = BOOT_HARD;
+                            sector = 0;
+                            event = BEGIN;
+                            break;
+                        }
+
+                        printf("  Sector %2d (0x%08X-0x%08X): ", sector,
+                               chip->layout[sector].address + sector_offset,
+                               chip->layout[sector].address + sector_offset + chip->chunk_size - 1);
+                        fflush(stdout);
+
+                        if (!bytes_within_range(chip->layout[sector].address + sector_offset,
+                                                chip->layout[sector].address + sector_offset + chip->chunk_size - 1)) {
+                            printf("not used\r\n");
+                            sector_offset += chip->chunk_size;
+
+                            if (sector_offset >= chip->layout[sector].size) {
+                                sector_offset = 0;
+                                sector++;
+                            }
+
+                            break;
+                        }
+
+                        snprintf(buf, sizeof(buf), "W %d %d\r\n", chip->ram_addr, chip->chunk_size);
+                        xmit_cmd(buf, 4);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            state = XMIT_DATA;
+                            printf("xmit");
+                            current_addr = chip->layout[sector].address + sector_offset;
+                            num_to_xmit = chip->chunk_size;
+                            linecount = 0;
+                            cksum = 0;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            download_cancel("can't xmit to ram");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case XMIT_DATA:
+                switch (event) {
+                    case BEGIN:
+                        n = num_to_xmit;
+
+                        if (n > 45) {
+                            n = 45;
+                        }
+
+                        get_ihex_data(current_addr, n, bytes);
+                        cksum += sum(bytes, n);
+                        uuencode(buf, bytes, n);
+                        current_addr += n;
+                        num_to_xmit -= n;
+                        linecount++;
+                        xmit_cmd(buf, 5);
+                        write_serial_port("\r\n", 2);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "\r\n") == 0) {
+                            if (linecount >= 20 || num_to_xmit <= 0) {
+                                state = XMIT_CKSUM;
+                            }
+
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            download_cancel("data xmit did not echo");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case XMIT_CKSUM:
+                switch (event) {
+                    case BEGIN:
+                        snprintf(buf, sizeof(buf), "%d\r\n", cksum);
+                        xmit_cmd(buf, 3);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
+                            if (num_to_xmit > 0) {
+                                printf(".");
+                                fflush(stdout);
+                                state = XMIT_DATA;
+                                event = BEGIN;
+                                linecount = 0;
+                                cksum = 0;
+                                break;
+                            }
+
+                            state = WRITE_PREPARE;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            download_cancel("bad checksum");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case WRITE_PREPARE:
+                switch (event) {
+                    case BEGIN:
+                        printf("prep, ");
+                        fflush(stdout);
+                        snprintf(buf, sizeof(buf), "P %d %d\r\n", sector, sector);
+                        xmit_cmd(buf, 5);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            state = WRITE_SECTOR;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            download_cancel("Unable to prep for write");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case WRITE_SECTOR:
+                switch (event) {
+                    case BEGIN:
+                        printf("write, ");
+                        fflush(stdout);
+                        snprintf(buf, sizeof(buf), "C %d %d %d\r\n",
+                                 chip->layout[sector].address + sector_offset,
+                                 chip->ram_addr, chip->chunk_size);
+                        xmit_cmd(buf, 5);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            printf("Ok\r\n");
+                            sector_offset += chip->chunk_size;
+
+                            if (sector_offset >= chip->layout[sector].size) {
+                                sector_offset = 0;
+                                sector++;
+                            }
+
+                            state = DOWNLOAD_CODE;
+                            event = BEGIN;
+                        }
+                        else {
+                            download_cancel("Unable to prep for write");
+                            return;
+                        }
+
+                        break;
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case BOOT_HARD:
+                //	if (chip->bootprog) {
+                //		state = BOOT_SOFT;
+                //		break;
+                //	} else {
+                printf("Booting (hardware reset)...\r\n\r\n");
+                hard_reset_to_user_code();
+                done_program(0);
+                return;
+                //	}
+
+            case BOOT_SOFT:
+                switch (event) {
+                    case BEGIN:
+                        printf("Booting (soft jump)...\r\n");
+                        printf("loading jump code\r\n");
+                        // would be nice if we could simply jump to the user's code, but
+                        // Philips didn't think of that.  The interrupt vector table stays
+                        // mapped to the bootloader, so jumping to zero only runs the
+                        // bootloader again.  Intead, we need to download a tiny ARM
+                        // program that reconfigures the hardware and then jumps to zero.
+                        //snprintf(buf, sizeof(buf), "G %d A\r\n", 0);
+                        snprintf(buf, sizeof(buf), "W %d %d\r\n", chip->ram_addr, chip->bootprog[0] * 4);
+                        xmit_cmd(buf, 4);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) < 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            current_addr = 0;
+                            num_to_xmit = chip->bootprog[0] * 4;
+                            copy_boot_code_to_memory(chip);
+                            linecount = 0;
+                            cksum = 0;
+                            state = BOOT_XMIT_DATA;
+                            event = BEGIN;
+                        }
+                        else {
+                            download_cancel("can't xmit to ram");
+                            return;
+                        }
+
+                        break;
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case BOOT_XMIT_DATA:
+                switch (event) {
+                    case BEGIN:
+                        n = num_to_xmit;
+
+                        if (n > 45) {
+                            n = 45;
+                        }
+
+                        get_ihex_data(current_addr, n, bytes);
+                        cksum += sum(bytes, n);
+                        uuencode(buf, bytes, n);
+                        current_addr += n;
+                        num_to_xmit -= n;
+                        linecount++;
+                        //printf("send: %s\r\n", buf);
+                        xmit_cmd(buf, 5);
+                        write_serial_port("\r\n", 2);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "\r\n") == 0) {
+                            if (linecount >= 20 || num_to_xmit <= 0) {
+                                state = BOOT_XMIT_CKSUM;
+                            }
+
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            download_cancel("data xmit did not echo");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case BOOT_XMIT_CKSUM:
+                switch (event) {
+                    case BEGIN:
+                        snprintf(buf, sizeof(buf), "%d\r\n", cksum);
+                        //printf("send: %s", buf);
+                        xmit_cmd(buf, 3);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) != 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "OK\r\n") == 0) {
+                            if (num_to_xmit > 0) {
+                                printf(".");
+                                fflush(stdout);
+                                state = BOOT_XMIT_DATA;
+                                event = BEGIN;
+                                linecount = 0;
+                                cksum = 0;
+                                break;
+                            }
+
+                            state = BOOT_RUN_CODE;
+                            event = BEGIN;
+                            break;
+                        }
+                        else {
+                            download_cancel("bad checksum");
+                            return;
+                        }
+
+                    case TIMEOUT:
+                        download_cancel("No response");
+                        return;
+                }
+
+                break;
+
+
+            case BOOT_RUN_CODE:
+                switch (event) {
+                    case BEGIN:
+                        printf("jumping now!\r\n");
+                        snprintf(buf, sizeof(buf), "G %d A\r\n", chip->ram_addr);
+                        xmit_cmd(buf, 4);
+                        return;
+
+                    case RESPONSE:
+                        if (num_lines(parsed_response_buf) < 1) {
+                            return;
+                        }
+
+                        if (strcmp(parsed_response_buf, "0\r\n") == 0) {
+                            done_program(0);
+                            return;
+                        }
+                        else {
+                            printf("response = %s", parsed_response_buf);
+                            download_cancel("couldn't run program");
+                            return;
+                        }
+
+                        break;
+
+                    case TIMEOUT:
+                        done_program(0);
+                        return;
+                        // Philips user name says it responds, but it does not.
+                        // It seems to just immediately jump to the code without
+                        // any "0" response.
+                        //download_cancel("No response"); return;
+                }
+
+                break;
+
+
+
+            default:
+                snprintf(buf, sizeof(buf), "unknown state %d\r\n", state);
+                download_cancel(buf);
+                return;
+        }
+    }
+}
+
+
+void download_cancel(const char *mesg)
+{
+    printf("\r\nDownload Canceled");
+
+    if (mesg && *mesg) {
+        printf(": %s", mesg);
+    }
+
+    printf("\r\n");
+    // need to do some cleanup for various states???
+    done_program(1);
+}
+
+
+/****************************************************************/
+/*								*/
+/*		Transmit Commands to Bootloader			*/
+/*								*/
+/****************************************************************/
+
+
+
+static void xmit_cmd(const char *cmd, int max_time)
+{
+    int len;
+
+    if (cmd == NULL || *cmd == '\0') {
+        return;
+    }
+
+    len = strlen(cmd);
+
+#ifdef PRINT_TX_RX_BYTES
+    printf("tx %d bytes: %s\n", len, cmd);
+#endif
+
+    input_flush_serial_port();
+
+    write_serial_port(cmd, len);
+
+    snprintf(expected_echo_buf, sizeof(expected_echo_buf), "%s", cmd);
+
+    if (state == SYNC_1) {
+        // special case, baud sync doesn't echo
+        expected_echo_buf[0] = '\0';
+    }
+
+    expected_echo_ptr = expected_echo_buf;
+    parsed_response_ptr = parsed_response_buf;
+
+    response_timer = max_time;
+}
+
+
+
+/****************************************************************/
+/*								*/
+/*		Handlers that respond to input			*/
+/*								*/
+/****************************************************************/
+
+
+/*
+Whenever the main gtk event loop detects more input has arrived from the
+serial port, and we're in the process of a download, it calls here to
+hand off the data.  We're supposed to match it up to the echo buffer,
+and then store it into the parsed response buffer and if it looks like
+this might be a complete response, call download_main with a response
+event.
+*/
+void download_rx_port(const unsigned char *buf, int num)
+{
+    int i = 0;
+
+    if (num <= 0) {
+        return;
+    }
+
+    // echo the data
+    //write(term_fd, buf, num);
+
+#ifdef PRINT_TX_RX_BYTES
+    printf("rx %d bytes:", num);
+
+    for (i = 0; i < num; i++) {
+        printf(" %02X", *(buf + i));
+    }
+
+    printf("\r\n");
+#endif
+
+    // ignore extra incoming garbage we didn't expect
+    if (expected_echo_ptr == NULL) {
+        return;
+    }
+
+    // special case, echo of '?' during unsuccessful sync
+    if (state == SYNC_1 && num == 1 && buf[0] == '?') {
+        *parsed_response_ptr++ = '?';
+        *parsed_response_ptr = '\0';
+        response_timer = 0;
+        download_main(RESPONSE);
+        return;
+    }
+
+    // parse it
+    for (i = 0; i < num; i++) {
+        // if we're still expecting the echo, gobble it up
+        if (*expected_echo_ptr) {
+            if (buf[i] != *expected_echo_ptr) {
+#ifdef PRINT_TX_RX_BYTES
+                printf("  <echo_err>  ");
+#endif
+                // ignore incorrect echo (will timeout)
+                expected_echo_ptr = NULL;
+                return;
+            }
+
+            expected_echo_ptr++;
+            continue;
+        }
+
+        // store this into a parsed response buffer
+        *parsed_response_ptr++ = buf[i];
+    }
+
+    // if the last two characters of the response are "\r\n",
+    // then it's likely we've got a complete response.
+    *parsed_response_ptr = '\0';
+
+    if (parsed_response_ptr > parsed_response_buf + 1
+        && *(parsed_response_ptr - 2) == '\r'
+        && *(parsed_response_ptr - 1) == '\n') {
+        //response_timer = 0;
+        download_main(RESPONSE);
+    }
+}
+
+
+
+/*
+During a download, this is supposed to get called at 100 Hz.  Whenever
+something is transmitted and we expect a response, the response_timer
+is initialized to the maximum time we will wait.
+*/
+void download_timer(void)
+{
+    if (response_timer > 0) {
+        response_timer--;
+
+        if (response_timer == 0) {
+            expected_echo_ptr = NULL;
+            download_main(TIMEOUT);
+        }
+    }
+}
+
+/*
+During a download, all input the user types into the terminal is sent
+to this function, instead of passing it to xterm for display
+*/
+void download_rx_term(const unsigned char *buf, int num)
+{
+    // discard anything the user types into the terminal
+    // while we are in the middle of downloading.  Maybe
+    // we should look for CTRL-C and abort??
+}
+
+
diff --git a/boards/msba2-common/tools/src/download.h b/boards/msba2-common/tools/src/download.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6b961049f224822dd021d8b8ff987049c7e519b
--- /dev/null
+++ b/boards/msba2-common/tools/src/download.h
@@ -0,0 +1,8 @@
+extern int download_begin(char *file);
+extern void soft_reboot_begin(void);
+extern void hard_reset_to_bootloader(void);
+extern void hard_reset_to_user_code(void);
+extern void download_cancel(const char *mesg);
+extern void download_rx_term(const unsigned char *buf, int num);
+extern void download_rx_port(const unsigned char *buf, int num);
+extern void download_timer(void);
diff --git a/boards/msba2-common/tools/src/gui.c b/boards/msba2-common/tools/src/gui.c
new file mode 100644
index 0000000000000000000000000000000000000000..0d4b18d8da3a7ff882eb1d0cc9c977cc7d9dd419
--- /dev/null
+++ b/boards/msba2-common/tools/src/gui.c
@@ -0,0 +1,422 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <gtk/gtk.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gui.h"
+#include "settings.h"
+#include "serial.h"
+#include "lpc2k_pgm.h"
+#include "download.h"
+
+
+static GtkWidget *firmware_label, *firmware_entry, *program_button;
+static GtkWidget *port_label, *port_entry, *baud_label, *baud_combo;
+static GtkWidget *crystal_label, *crystal_entry, *mhz_label;
+static GtkWidget *reboot_button, *bootloader_button, *quit_button;
+static GtkWidget *line1_hbox, *line2_hbox, *line3_hbox, *line4_hbox;
+static GtkWidget *main_vbox, *main_window;
+
+static int port_timeout = 0;
+static int baud_timeout = 0;
+static int download_in_progress = 0;
+
+gint do_quit(GtkWidget *widget, gpointer *data)
+{
+    gtk_main_quit();
+    return FALSE;
+}
+
+gint do_program(GtkWidget *widget, gpointer *data)
+{
+    if (download_in_progress) {
+        // error... not supposed to get here
+        gtk_widget_set_sensitive(program_button, FALSE);
+        return FALSE;
+    }
+
+    download_in_progress = 1;
+    gtk_widget_set_sensitive(program_button, FALSE);
+    gtk_widget_set_sensitive(reboot_button, FALSE);
+    gtk_widget_set_sensitive(bootloader_button, TRUE);
+    download_begin();
+    return FALSE;
+}
+
+int file_exists(const char *filename)
+{
+    struct stat file_stats;
+    int r;
+
+    r = stat(filename, &file_stats);
+
+    if (r != 0) {
+        return 0;
+    }
+
+    if (!S_ISREG(file_stats.st_mode)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+void done_program(int still_in_bootloader)
+{
+    download_in_progress = 0;
+
+    if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) {
+        gtk_widget_set_sensitive(program_button, TRUE);
+    }
+    else {
+        gtk_widget_set_sensitive(program_button, FALSE);
+    }
+
+    gtk_widget_set_sensitive(bootloader_button, TRUE);
+    gtk_widget_set_sensitive(reboot_button, TRUE);
+}
+
+gint do_reboot(GtkWidget *widget, gpointer *data)
+{
+    if (download_in_progress) {
+        download_cancel(NULL);
+        gtk_widget_set_sensitive(program_button, FALSE);
+        gtk_widget_set_sensitive(reboot_button, FALSE);
+        gtk_widget_set_sensitive(bootloader_button, FALSE);
+    }
+
+    gtk_widget_set_sensitive(program_button, FALSE);
+    gtk_widget_set_sensitive(reboot_button, FALSE);
+    gtk_widget_set_sensitive(bootloader_button, FALSE);
+
+    hard_reset_to_user_code();
+
+#if 0
+    download_in_progress = 1;
+    soft_reboot_begin();
+#endif
+
+    if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) {
+        gtk_widget_set_sensitive(program_button, TRUE);
+    }
+    else {
+        gtk_widget_set_sensitive(program_button, FALSE);
+    }
+
+    gtk_widget_set_sensitive(bootloader_button, TRUE);
+    return FALSE;
+}
+
+gint do_bootloader(GtkWidget *widget, gpointer *data)
+{
+    if (download_in_progress) {
+        download_cancel(NULL);
+        gtk_widget_set_sensitive(program_button, FALSE);
+        gtk_widget_set_sensitive(reboot_button, FALSE);
+        gtk_widget_set_sensitive(bootloader_button, FALSE);
+    }
+
+    hard_reset_to_bootloader();
+
+    if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) {
+        gtk_widget_set_sensitive(program_button, TRUE);
+    }
+    else {
+        gtk_widget_set_sensitive(program_button, FALSE);
+    }
+
+    gtk_widget_set_sensitive(reboot_button, TRUE);
+    gtk_widget_set_sensitive(bootloader_button, TRUE);
+    return FALSE;
+}
+
+gint do_new_port(GtkWidget *widget, gpointer *data)
+{
+    port_timeout = 12;
+    return FALSE;
+}
+
+gint do_new_baud(GtkWidget *widget, gpointer *data)
+{
+    baud_timeout = 7;
+    return FALSE;
+}
+
+gint do_new_file(GtkWidget *widget, gpointer *data)
+{
+    const char *filename;
+
+    filename = gtk_entry_get_text(GTK_ENTRY(firmware_entry));
+
+    if (file_exists(filename)) {
+        new_file_setting(filename);
+
+        if (download_in_progress) {
+            gtk_widget_set_sensitive(program_button, FALSE);
+        }
+        else {
+            gtk_widget_set_sensitive(program_button, TRUE);
+        }
+    }
+    else {
+        gtk_widget_set_sensitive(program_button, FALSE);
+    }
+
+    return FALSE;
+}
+
+gint do_new_crystal(GtkWidget *widget, gpointer *data)
+{
+    const char *xtal;
+
+    xtal = gtk_entry_get_text(GTK_ENTRY(crystal_entry));
+    new_crystal_setting(xtal);
+    return FALSE;
+}
+
+
+gint do_timer(gpointer data)
+{
+    if (port_timeout && --port_timeout == 0) {
+        open_serial_port(gtk_entry_get_text(GTK_ENTRY(port_entry)));
+    }
+
+    if (baud_timeout && --baud_timeout == 0) {
+        change_baud(gtk_entry_get_text(GTK_ENTRY(
+                                           GTK_COMBO(baud_combo)->entry)));
+    }
+
+    if (download_in_progress) {
+        download_timer();
+    }
+
+    return TRUE;
+}
+
+void do_term_input(gpointer data, int fd, GdkInputCondition cond)
+{
+    char buf[256];
+    int num, flags;
+
+    flags = fcntl(term_fd, F_GETFL);
+    fcntl(term_fd, F_SETFL, flags | O_NONBLOCK);
+    num = read(term_fd, buf, sizeof(buf));
+    fcntl(term_fd, F_SETFL, flags);
+
+    if (num > 0) {
+        if (download_in_progress) {
+            download_rx_term(buf, num);
+        }
+        else {
+            write_serial_port(buf, num);
+        }
+    }
+}
+
+void do_port_input(gpointer data, int fd, GdkInputCondition cond)
+{
+    char buf[256];
+    int num;
+
+    num = read_serial_port_nb((unsigned char *)buf, sizeof(buf));
+
+    if (num > 0) {
+        if (download_in_progress) {
+            download_rx_port(buf, num);
+        }
+        else {
+            write(term_fd, buf, num);
+        }
+    }
+}
+
+
+void run_gui(void)
+{
+    gtk_signal_connect(GTK_OBJECT(main_window), "delete_event",
+                       GTK_SIGNAL_FUNC(do_quit), NULL);
+    gtk_signal_connect(GTK_OBJECT(quit_button), "pressed",
+                       GTK_SIGNAL_FUNC(do_quit), NULL);
+    gtk_signal_connect(GTK_OBJECT(port_entry), "changed",
+                       GTK_SIGNAL_FUNC(do_new_port), NULL);
+    gtk_signal_connect(GTK_OBJECT(GTK_COMBO(baud_combo)->entry), "changed",
+                       GTK_SIGNAL_FUNC(do_new_baud), NULL);
+    gtk_signal_connect(GTK_OBJECT(firmware_entry), "changed",
+                       GTK_SIGNAL_FUNC(do_new_file), NULL);
+    gtk_signal_connect(GTK_OBJECT(crystal_entry), "changed",
+                       GTK_SIGNAL_FUNC(do_new_crystal), NULL);
+    gtk_signal_connect(GTK_OBJECT(program_button), "pressed",
+                       GTK_SIGNAL_FUNC(do_program), NULL);
+    gtk_signal_connect(GTK_OBJECT(reboot_button), "pressed",
+                       GTK_SIGNAL_FUNC(do_reboot), NULL);
+    gtk_signal_connect(GTK_OBJECT(bootloader_button), "pressed",
+                       GTK_SIGNAL_FUNC(do_bootloader), NULL);
+
+    gtk_timeout_add(100, do_timer, NULL);
+    gdk_input_add(term_fd, GDK_INPUT_READ, do_term_input, NULL);
+    gdk_input_add(serial_port_fd(), GDK_INPUT_READ, do_port_input, NULL);
+
+    gtk_main();
+}
+
+
+void create_window(int *argc, char ***argv)
+{
+    GList *gtk_baud_list = NULL;
+    int i;
+
+    gtk_init(argc, argv);
+
+    firmware_label = gtk_label_new("Firmware:");
+    gtk_label_set_justify(GTK_LABEL(firmware_label), GTK_JUSTIFY_RIGHT);
+    gtk_widget_show(firmware_label);
+
+    firmware_entry = gtk_entry_new();
+    gtk_widget_set_usize(firmware_entry, 110, 0);
+    gtk_entry_set_text(GTK_ENTRY(firmware_entry), file_setting());
+    gtk_widget_show(firmware_entry);
+
+    program_button = gtk_button_new_with_label("Program Now");
+
+    if (file_exists(file_setting())) {
+        gtk_widget_set_sensitive(program_button, TRUE);
+    }
+    else {
+        gtk_widget_set_sensitive(program_button, FALSE);
+    }
+
+    gtk_widget_show(program_button);
+
+    line1_hbox = gtk_hbox_new(FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(line1_hbox), firmware_label, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(line1_hbox), firmware_entry, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(line1_hbox), program_button, FALSE, FALSE, 2);
+    gtk_widget_show(line1_hbox);
+
+
+    port_label = gtk_label_new("Port:");
+    gtk_label_set_justify(GTK_LABEL(port_label), GTK_JUSTIFY_RIGHT);
+    gtk_widget_show(port_label);
+
+    port_entry = gtk_entry_new();
+    gtk_widget_set_usize(port_entry, 80, 0);
+    gtk_entry_set_text(GTK_ENTRY(port_entry), port_setting());
+    open_serial_port(port_setting());
+    gtk_widget_show(port_entry);
+
+    baud_label = gtk_label_new("Baud:");
+    gtk_label_set_justify(GTK_LABEL(baud_label), GTK_JUSTIFY_RIGHT);
+    gtk_widget_show(baud_label);
+
+    baud_combo = gtk_combo_new();
+
+    for (i = 0; baud_list[i] != NULL; i++) {
+        gtk_baud_list = g_list_append(gtk_baud_list, baud_list[i]);
+    }
+
+    gtk_combo_set_popdown_strings(GTK_COMBO(baud_combo), gtk_baud_list);
+    gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(baud_combo)->entry), FALSE);
+    gtk_widget_set_usize(baud_combo, 75, 0);
+
+    for (i = 0; baud_list[i] != NULL; i++) {
+        if (strcmp(baud_list[i], baud_setting()) == 0) {
+            gtk_list_select_item(GTK_LIST(GTK_COMBO(baud_combo)->list), i);
+            break;
+        }
+    }
+
+    gtk_widget_show(baud_combo);
+
+    line2_hbox = gtk_hbox_new(FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(line2_hbox), port_label, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(line2_hbox), port_entry, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(line2_hbox), baud_label, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(line2_hbox), baud_combo, FALSE, FALSE, 2);
+    gtk_widget_show(line2_hbox);
+
+
+    crystal_label = gtk_label_new("Crystal:");
+    gtk_label_set_justify(GTK_LABEL(crystal_label), GTK_JUSTIFY_RIGHT);
+    gtk_widget_show(crystal_label);
+
+    crystal_entry = gtk_entry_new();
+    gtk_widget_set_usize(crystal_entry, 80, 0);
+    gtk_entry_set_text(GTK_ENTRY(crystal_entry), crystal_setting());
+    gtk_widget_show(crystal_entry);
+
+    mhz_label = gtk_label_new("(MHz)");
+    gtk_label_set_justify(GTK_LABEL(mhz_label), GTK_JUSTIFY_LEFT);
+    gtk_widget_show(mhz_label);
+
+    line3_hbox = gtk_hbox_new(FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(line3_hbox), crystal_label, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(line3_hbox), crystal_entry, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(line3_hbox), mhz_label, FALSE, FALSE, 2);
+    gtk_widget_show(line3_hbox);
+
+
+    reboot_button = gtk_button_new_with_label("Reboot");
+    gtk_widget_set_sensitive(reboot_button, TRUE);
+    gtk_widget_show(reboot_button);
+
+    bootloader_button = gtk_button_new_with_label("Booloader");
+    gtk_widget_show(bootloader_button);
+
+    quit_button = gtk_button_new_with_label("Quit");
+    gtk_widget_show(quit_button);
+
+    line4_hbox = gtk_hbox_new(TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(line4_hbox), reboot_button, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(line4_hbox), bootloader_button, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(line4_hbox), quit_button, TRUE, TRUE, 2);
+    gtk_widget_show(line4_hbox);
+
+    main_vbox = gtk_vbox_new(FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(main_vbox), line1_hbox, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(main_vbox), line2_hbox, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(main_vbox), line3_hbox, TRUE, TRUE, 2);
+    gtk_box_pack_start(GTK_BOX(main_vbox), line4_hbox, TRUE, TRUE, 2);
+    gtk_widget_show(main_vbox);
+
+    main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_container_add(GTK_CONTAINER(main_window), main_vbox);
+    gtk_widget_show(main_window);
+}
diff --git a/boards/msba2-common/tools/src/gui.h b/boards/msba2-common/tools/src/gui.h
new file mode 100644
index 0000000000000000000000000000000000000000..fadde6db6d99bfa9cde2b8f9aabf8ab31d68d67a
--- /dev/null
+++ b/boards/msba2-common/tools/src/gui.h
@@ -0,0 +1,3 @@
+extern void create_window(int *argc, char ***argv);
+extern void run_gui(void);
+extern void done_program(int still_in_bootloader);
diff --git a/boards/msba2-common/tools/src/ihex.c b/boards/msba2-common/tools/src/ihex.c
new file mode 100644
index 0000000000000000000000000000000000000000..d5865a569a0b312195b1d55f649eb9c701a2bf70
--- /dev/null
+++ b/boards/msba2-common/tools/src/ihex.c
@@ -0,0 +1,314 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+
+// the maximum flash image size we can support
+// chips with larger memory may be used, but only this
+// much intel-hex data can be loaded into memory!
+#define MAX_MEMORY_SIZE 0x80000
+
+
+#include "ihex.h"
+
+
+static unsigned char firmware_image[MAX_MEMORY_SIZE];
+static unsigned char firmware_mask[MAX_MEMORY_SIZE];
+static int end_record_seen = 0;
+static int byte_count;
+static unsigned int extended_addr = 0;
+
+
+static int parse_hex_line(char *line);
+
+
+/****************************************************************/
+/*								*/
+/*		      Read Intel Hex File			*/
+/*								*/
+/****************************************************************/
+
+
+
+int read_intel_hex(const char *filename)
+{
+    FILE *fp;
+    int i, lineno = 0;
+    char buf[1024];
+
+    byte_count = 0;
+    end_record_seen = 0;
+
+    for (i = 0; i < MAX_MEMORY_SIZE; i++) {
+        firmware_image[i] = 0xFF;
+        firmware_mask[i] = 0;
+    }
+
+    extended_addr = 0;
+
+    fp = fopen(filename, "r");
+
+    if (fp == NULL) {
+        printf("Unable to read file %s\n", filename);
+        return -1;
+    }
+
+    while (!feof(fp)) {
+        *buf = '\0';
+        fgets(buf, sizeof(buf), fp);
+        lineno++;
+
+        if (*buf) {
+            if (parse_hex_line(buf) == 0) {
+                printf("Warning, parse error line %d\n", lineno);
+                return -2;
+            }
+        }
+
+        if (end_record_seen) {
+            break;
+        }
+
+        if (feof(stdin)) {
+            break;
+        }
+    }
+
+    fclose(fp);
+    return byte_count;
+}
+
+
+/* from ihex.c, at http://www.pjrc.com/tech/8051/pm2_docs/intel-hex.html */
+
+/* parses a line of intel hex code, stores the data in bytes[] */
+/* and the beginning address in addr, and returns a 1 if the */
+/* line was valid, or a 0 if an error occured.  The variable */
+/* num gets the number of bytes that were stored into bytes[] */
+
+
+int
+parse_hex_line(char *line)
+{
+    int addr, code, num;
+    int sum, len, cksum, i;
+    char *ptr;
+
+    num = 0;
+
+    if (line[0] != ':') {
+        return 0;
+    }
+
+    if (strlen(line) < 11) {
+        return 0;
+    }
+
+    ptr = line + 1;
+
+    if (!sscanf(ptr, "%02x", &len)) {
+        return 0;
+    }
+
+    ptr += 2;
+
+    if (strlen(line) < (11 + (len * 2))) {
+        return 0;
+    }
+
+    if (!sscanf(ptr, "%04x", &addr)) {
+        return 0;
+    }
+
+    ptr += 4;
+
+    /* printf("Line: length=%d Addr=%d\n", len, addr); */
+    if (!sscanf(ptr, "%02x", &code)) {
+        return 0;
+    }
+
+    if (addr + extended_addr + len >= MAX_MEMORY_SIZE) {
+        return 0;
+    }
+
+    ptr += 2;
+    sum = (len & 255) + ((addr >> 8) & 255) + (addr & 255) + (code & 255);
+
+    if (code != 0) {
+        if (code == 1) {
+            end_record_seen = 1;
+            return 1;
+        }
+
+        if (code == 2 && len == 2) {
+            if (!sscanf(ptr, "%04x", &i)) {
+                return 1;
+            }
+
+            ptr += 4;
+            sum += ((i >> 8) & 255) + (i & 255);
+
+            if (!sscanf(ptr, "%02x", &cksum)) {
+                return 1;
+            }
+
+            if (((sum & 255) + (cksum & 255)) & 255) {
+                return 1;
+            }
+
+            extended_addr = i << 4;
+            //printf("ext addr = %05X\n", extended_addr);
+        }
+
+        if (code == 4 && len == 2) {
+            if (!sscanf(ptr, "%04x", &i)) {
+                return 1;
+            }
+
+            ptr += 4;
+            sum += ((i >> 8) & 255) + (i & 255);
+
+            if (!sscanf(ptr, "%02x", &cksum)) {
+                return 1;
+            }
+
+            if (((sum & 255) + (cksum & 255)) & 255) {
+                return 1;
+            }
+
+            extended_addr = i << 16;
+            //printf("ext addr = %08X\n", extended_addr);
+        }
+
+        return 1;	// non-data line
+    }
+
+    byte_count += len;
+
+    while (num != len) {
+        if (sscanf(ptr, "%02x", &i) != 1) {
+            return 0;
+        }
+
+        i &= 255;
+        firmware_image[addr + extended_addr + num] = i;
+        firmware_mask[addr + extended_addr + num] = 1;
+        ptr += 2;
+        sum += i;
+        (num)++;
+
+        if (num >= 256) {
+            return 0;
+        }
+    }
+
+    if (!sscanf(ptr, "%02x", &cksum)) {
+        return 0;
+    }
+
+    if (((sum & 255) + (cksum & 255)) & 255) {
+        return 0;    /* checksum error */
+    }
+
+    return 1;
+}
+
+
+int bytes_within_range(int begin, int end)
+{
+    int i;
+
+    if (begin < 0 || begin >= MAX_MEMORY_SIZE ||
+        end < 0 || end >= MAX_MEMORY_SIZE) {
+        return 0;
+    }
+
+    for (i = begin; i <= end; i++) {
+        if (firmware_mask[i]) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+void get_ihex_data(int addr, int len, unsigned char *bytes)
+{
+    int i;
+
+    if (addr < 0 || len < 0 || addr + len >= MAX_MEMORY_SIZE) {
+        for (i = 0; i < len; i++) {
+            bytes[i] = 255;
+        }
+
+        return;
+    }
+
+    for (i = 0; i < len; i++) {
+        if (firmware_mask[addr]) {
+            bytes[i] = firmware_image[addr];
+        }
+        else {
+            bytes[i] = 255;
+        }
+
+        addr++;
+    }
+}
+
+void put_ihex_data(int addr, int len, const unsigned char *bytes)
+{
+    int i;
+
+    if (addr < 0 || len < 0 || addr + len >= MAX_MEMORY_SIZE) {
+        return;
+    }
+
+    for (i = 0; i < len; i++) {
+        firmware_image[addr] = bytes[i];
+        firmware_mask[addr] = 1;
+        addr++;
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/boards/msba2-common/tools/src/ihex.h b/boards/msba2-common/tools/src/ihex.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6892381f519ffa44d5c439c3afc65243d02fd2c
--- /dev/null
+++ b/boards/msba2-common/tools/src/ihex.h
@@ -0,0 +1,7 @@
+extern int read_intel_hex(const char *filename);
+extern int bytes_within_range(int begin, int end);
+extern void get_ihex_data(int addr, int len, unsigned char *bytes);
+extern void put_ihex_data(int addr, int len, const unsigned char *bytes);
+
+
+
diff --git a/boards/msba2-common/tools/src/lpc2k_pgm.c b/boards/msba2-common/tools/src/lpc2k_pgm.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c74429887ab526516e5feaf1fa8eafa4eae9b76
--- /dev/null
+++ b/boards/msba2-common/tools/src/lpc2k_pgm.c
@@ -0,0 +1,101 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include "lpc2k_pgm.h"
+#include "serial.h"
+#include "download.h"
+
+int programming_done = 0;
+
+int done_program(int i)
+{
+    printf("Programming done.\n");
+    programming_done = 1;
+    return 0;
+}
+
+void handle_port_input()
+{
+    unsigned char buf[256];
+    int num;
+
+    num = read_serial_port(buf, sizeof(buf));
+
+    if (num > 0) {
+        download_rx_port(buf, num);
+    }
+}
+
+void usage()
+{
+    printf("usage: lpc2k_pgm <port> <ihex-file>\n");
+}
+
+int main(int argc, char **argv)
+{
+    if (argc < 3) {
+        usage();
+        exit(1);
+    }
+
+    char *port_name = argv[1];
+    char *file_name = argv[2];
+
+    if (open_serial_port(port_name) < 0) {
+        return (1);
+    }
+
+    if (!download_begin(file_name)) {
+        return 1;
+    }
+
+    while (!programming_done) {
+        handle_port_input();
+    }
+
+    close_serial_port();
+
+    return 0;
+}
+
diff --git a/boards/msba2-common/tools/src/lpc2k_pgm.h b/boards/msba2-common/tools/src/lpc2k_pgm.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a5f5a7eebc3032eba5b1e74bf0a6118b25690b1
--- /dev/null
+++ b/boards/msba2-common/tools/src/lpc2k_pgm.h
@@ -0,0 +1,12 @@
+#ifndef LPC2K_PGM
+#define LPC2K_PGM
+
+/* gets a name like "115200", sets baudrate accordingly. */
+void change_baud(const char *baud_name);
+
+/* called before/after using serial device, used to have terminal
+ * close the device.
+*/
+void signal_terminal();
+
+#endif // LPC2K_PGM
diff --git a/boards/msba2-common/tools/src/pseudoterm.c b/boards/msba2-common/tools/src/pseudoterm.c
new file mode 100644
index 0000000000000000000000000000000000000000..24b2d33cb06b1b43ebe15b712002d50fd2222ae4
--- /dev/null
+++ b/boards/msba2-common/tools/src/pseudoterm.c
@@ -0,0 +1,181 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+
+#include "serial.h"
+#include "pthread.h"
+#include "download.h"
+
+int tty_fd;
+int stopped = 0;
+char *port_name = "/dev/ttyUSB1";
+pthread_t serial_reader;
+
+void *serial_reader_func(void *arg)
+{
+    unsigned char buf[255];
+
+    while (1) {
+        int n = read_serial_port(buf, sizeof(buf));
+
+        if (n > 0) {
+            write(tty_fd, buf, n);
+        }
+    }
+}
+
+int init()
+{
+    int result = open_serial_port(port_name);
+    pthread_create(&serial_reader, NULL, serial_reader_func, NULL);
+    hard_reset_to_user_code();
+    return result;
+}
+
+struct termios old_term_setting;
+
+void close_tty()
+{
+    tcsetattr(tty_fd, TCSANOW, &old_term_setting);
+}
+
+void sig_handler(int signal)
+{
+    if (signal == SIGUSR1) {
+        if (stopped) {
+            stopped = 0;
+            printf("\nSignal received, opening port.\r\n");
+
+            if (init() < 0) {
+                printf("Cannot open port.\r\n");
+                close_tty();
+                exit(1);
+            }
+        }
+    }
+    else if (signal == SIGUSR2) {
+        if (!stopped) {
+            stopped = 1;
+            printf("\nSignal received, closing port. \r\n");
+            pthread_cancel(serial_reader);
+            close_serial_port();
+        }
+    }
+    else if (signal == SIGINT) {
+        printf("SIGINT received, exiting...\n");
+        pthread_cancel(serial_reader);
+        close_serial_port();
+        close_tty();
+        exit(0);
+    }
+}
+
+int open_tty(void)
+{
+    int r, fd;
+    struct termios term_setting;
+
+    fd = open("/dev/tty", O_RDWR);
+
+    if (fd < 0) {
+        return -1;
+    }
+
+    r = tcgetattr(fd, &term_setting);
+
+    if (r != 0) {
+        return -2;
+    }
+
+    old_term_setting = term_setting;
+
+    term_setting.c_oflag |= (ONLRET);
+    term_setting.c_iflag |= (/*IGNBRK |*/ BRKINT | IGNPAR);
+    term_setting.c_iflag &= ~(ISTRIP);
+    term_setting.c_lflag &= ~(ICANON |/* ISIG |*/ ECHO);
+    term_setting.c_lflag |= (ISIG);
+    term_setting.c_cflag |= CREAD;
+    term_setting.c_cc[VMIN] = 1;
+    term_setting.c_cc[VTIME] = 1;
+    r = tcsetattr(fd, TCSANOW, &term_setting);
+
+    if (r != 0) {
+        return -3;
+    }
+
+    return fd;
+}
+
+void install_sighandler()
+{
+    struct sigaction action;
+    sigemptyset(&action.sa_mask);
+    sigaddset(&action.sa_mask, SIGINT);
+    sigaddset(&action.sa_mask, SIGUSR1);
+    sigaddset(&action.sa_mask, SIGUSR2);
+    action.sa_flags = 0;
+    action.sa_handler = sig_handler;
+    sigaction(SIGINT, &action, NULL);
+    sigaction(SIGUSR1, &action, NULL);
+    sigaction(SIGUSR2, &action, NULL);
+}
+
+int main(int argc, char **argv)
+{
+    if (argc == 2) {
+        port_name = argv[1];
+    }
+
+    printf("Using %s as serial device.\n", port_name);
+
+    char ttybuf[255];
+    tty_fd = open_tty();
+
+    if (tty_fd < 0) {
+        printf("Error opening terminal.\n");
+        return (1);
+    }
+
+    install_sighandler();
+
+    if (init() < 0) {
+        printf("Cannot open port.\r\n");
+        exit(1);
+    }
+
+    while (1) {
+        int n = read(tty_fd, ttybuf, sizeof(ttybuf));
+        int i;
+
+        /* check for 0x3 (ctrl-c), clean exit */
+        for (i = 0; i < n; i++) {
+            if (ttybuf[i] == 0x3) {
+                if (i > 0) {
+                    write_serial_port(ttybuf, i);
+                }
+
+                close_serial_port();
+                close_tty();
+                system("tset -c");
+                return 0;
+            }
+
+        }
+
+        write_serial_port(ttybuf, n);
+    }
+
+    close_tty();
+    close_serial_port();
+    return 0;
+}
+
+
diff --git a/boards/msba2-common/tools/src/serial.c b/boards/msba2-common/tools/src/serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e7fee25f8d367d1522983ae75b556fe5befc525
--- /dev/null
+++ b/boards/msba2-common/tools/src/serial.c
@@ -0,0 +1,452 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#ifdef LINUX
+#include <linux/serial.h>
+#endif
+
+#include "serial.h"
+
+static int port_fd = -1;
+
+static tcflag_t baud_name_to_flags(const char *baud_name);
+static void report_open_error(const char *filename, int err);
+
+char *baud_rate = "115200";
+
+int open_serial_port(const char *port_name)
+{
+    int r;
+    struct termios term_setting;
+
+    if (port_fd >= 0) {
+        close(port_fd);
+    }
+
+    port_fd = open(port_name, O_RDWR);
+
+    if (port_fd < 0) {
+        report_open_error(port_name, errno);
+        return -1;
+    }
+
+    bzero(&term_setting, sizeof(term_setting));
+    term_setting.c_cflag = (CS8 | CREAD);
+    term_setting.c_cc[VMIN] = 1;
+    term_setting.c_cc[VTIME] = 1;
+    r = tcsetattr(port_fd, TCSANOW, &term_setting);
+
+    if (r != 0) {
+        return -1;
+    }
+
+    r = set_baud(baud_rate);
+
+    if (r == 0) {
+        printf("Port \"%s\" opened at %s baud\r\n",
+               port_name, baud_rate);
+    }
+    else {
+        printf("Port \"%s\" opened, unable to set baud to %s\r\n",
+               port_name, baud_rate);
+    }
+
+#ifdef LINUX
+    {
+        struct serial_struct kernel_serial_settings;
+        /* attempt to set low latency mode, but don't worry if we can't */
+        r = ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings);
+
+        if (r < 0) {
+            return 0;
+        }
+
+        kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
+        ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
+    }
+#endif
+    return 0;
+}
+
+
+/* if the port can't be opened, try to print as much info as
+ * possible, so the problem can be resolved (usually permissions)
+ */
+static void report_open_error(const char *filename, int err)
+{
+    struct stat info;
+    uid_t my_uid;
+    gid_t my_gid;
+    char my_uname[64], my_gname[64], file_uname[64], file_gname[64];
+    struct passwd *p;
+    struct group *g;
+    mode_t perm;
+    int r, perm_ok = 0;
+
+    printf("\r\n");
+    printf("Unable to open \"%s\"\r\n", filename);
+
+    if (err == EACCES) {
+        printf("You don't have permission to access %s\r\n", filename);
+    }
+
+    //printf("Attemping to find more information about %s....\r\n", filename);
+    r = stat(filename, &info);
+
+    if (r < 0) {
+        if (errno == ENOENT) {
+            printf("file %s does not exist\r\n", filename);
+        }
+        else if (errno == ELOOP) {
+            printf("too many symbolic links\r\n");
+        }
+        else if (errno == EACCES) {
+            printf("permission denied to get file status\r\n");
+        }
+        else {
+            printf("Unable to get file status, err%d\r\n", errno);
+        }
+
+        return;
+    }
+
+    my_uid = getuid();
+    my_gid = getgid();
+
+    p = getpwuid(my_uid);
+
+    if (p) {
+        snprintf(my_uname, sizeof(my_uname),
+                 "\"%s\" (gid=%d)", p->pw_name, (int)my_uid);
+    }
+    else {
+        snprintf(my_uname, sizeof(my_uname),
+                 "(gid=%d)", (int)my_uid);
+    }
+
+    p = getpwuid(info.st_uid);
+
+    if (p) {
+        snprintf(file_uname, sizeof(file_uname),
+                 "\"%s\" (uid=%d)", p->pw_name, (int)info.st_uid);
+    }
+    else {
+        snprintf(file_uname, sizeof(file_uname),
+                 "(uid=%d)", (int)info.st_uid);
+    }
+
+    g = getgrgid(my_gid);
+
+    if (g) {
+        snprintf(my_gname, sizeof(my_gname),
+                 "\"%s\" (gid=%d)", g->gr_name, (int)my_gid);
+    }
+    else {
+        snprintf(my_gname, sizeof(my_gname),
+                 "(gid=%d)", (int)my_gid);
+    }
+
+    g = getgrgid(info.st_gid);
+
+    if (g) {
+        snprintf(file_gname, sizeof(file_gname),
+                 "\"%s\" (uid=%d)", g->gr_name, (int)info.st_gid);
+    }
+    else {
+        snprintf(file_gname, sizeof(file_gname),
+                 "(uid=%d)", (int)info.st_gid);
+    }
+
+    /* printf("%s is owned by: user %s, group %s\r\n",
+    	filename, file_uname, file_gname); */
+
+    perm = info.st_mode;
+
+    if ((perm & S_IROTH) && (perm & S_IWOTH)) {
+        printf("%s has read/write permission for everybody\r\n",
+               filename);
+    }
+    else {
+        printf("%s is not read/write for everybody, so\r\n", filename);
+        printf("  you must match either user or group permission\r\n");
+
+        if ((perm & S_IRUSR) && (perm & S_IWUSR)) {
+            printf("%s has read/write permission for user %s\r\n",
+                   filename, file_uname);
+            perm_ok = 1;
+        }
+
+        if ((perm & S_IRGRP) && (perm & S_IWGRP)) {
+            printf("%s has read/write permission for group %s\r\n",
+                   filename, file_gname);
+            perm_ok = 1;
+        }
+
+        if (perm_ok == 0) {
+            printf("%s does not read/write permission for user or group!\r\n",
+                   filename);
+        }
+        else {
+            printf("Your access privs: user %s, group %s\r\n",
+                   my_uname, my_gname);
+        }
+    }
+
+    printf("\r\n");
+}
+
+
+
+int write_serial_port(const void *buf, int num)
+{
+    return (write(port_fd, buf, num));
+}
+
+
+void input_flush_serial_port(void)
+{
+    tcflush(port_fd, TCIFLUSH);
+}
+
+
+int read_serial_port_nb(unsigned char *buf, int bufsize)
+{
+    int num, flags;
+
+    flags = fcntl(port_fd, F_GETFL);
+    fcntl(port_fd, F_SETFL, flags | O_NONBLOCK);
+    num = read(port_fd, buf, bufsize);
+    fcntl(port_fd, F_SETFL, flags);
+    return num;
+}
+
+int read_serial_port(unsigned char *buf, int bufsize)
+{
+    int num;
+
+    num = read(port_fd, buf, bufsize);
+
+    return num;
+}
+
+
+void send_break_signal(void)
+{
+    tcsendbreak(port_fd, 0);
+}
+
+
+void close_serial_port(void)
+{
+    if (port_fd >= 0) {
+        close(port_fd);
+        port_fd = -1;
+    }
+}
+
+
+tcflag_t baud_name_to_flags(const char *baud_name)
+{
+    if (strcmp(baud_name, "230400") == 0) {
+        return B230400;
+    }
+
+    if (strcmp(baud_name, "115200") == 0) {
+        return B115200;
+    }
+
+    if (strcmp(baud_name, "57600") == 0) {
+        return B57600;
+    }
+
+    if (strcmp(baud_name, "38400") == 0) {
+        return B38400;
+    }
+
+    if (strcmp(baud_name, "19200") == 0) {
+        return B19200;
+    }
+
+    if (strcmp(baud_name, "9600") == 0) {
+        return B9600;
+    }
+
+    if (strcmp(baud_name, "4800") == 0) {
+        return B4800;
+    }
+
+    if (strcmp(baud_name, "2400") == 0) {
+        return B2400;
+    }
+
+    if (strcmp(baud_name, "1200") == 0) {
+        return B1200;
+    }
+
+    if (strcmp(baud_name, "300") == 0) {
+        return B300;
+    }
+
+    return B0;
+}
+
+
+int set_baud(const char *baud_name)
+{
+    struct termios port_setting;
+    tcflag_t baud;
+    int r;
+
+    if (port_fd < 0) {
+        return -1;
+    }
+
+    baud = baud_name_to_flags(baud_name);
+
+    if (baud == B0) {
+        return -2;
+    }
+
+    r = tcgetattr(port_fd, &port_setting);
+
+    if (r != 0) {
+        return -3;
+    }
+
+#ifdef __APPLE__
+    cfsetspeed(&port_setting, baud);
+    port_setting.c_iflag = IGNBRK | IGNPAR;
+    port_setting.c_cflag =  CS8 | CREAD | HUPCL | CLOCAL;
+#else
+    port_setting.c_iflag = IGNBRK | IGNPAR;
+    port_setting.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
+#endif
+
+    port_setting.c_oflag = 0;
+    port_setting.c_lflag = 0;
+    r = tcsetattr(port_fd, TCSAFLUSH, &port_setting);
+
+    if (r != 0) {
+        return -4;
+    }
+
+    return 0;
+}
+
+
+// Normally this should never be used... except to pass the port
+// file descriptor to the GTK event monitoring loop.  All other
+// use of the serial port is supposed to happen in the file.
+int serial_port_fd(void)
+{
+    return port_fd;
+}
+
+
+
+void set_rts(int val)
+{
+    int flags;
+    int result;
+
+    result = ioctl(port_fd, TIOCMGET, &flags);
+
+    if (result == -1) {
+        printf("Error %i while reading port io flags\n", errno);
+        return;
+    }
+
+    if (val) {
+        flags |= TIOCM_RTS;
+    }
+    else {
+        flags &= ~(TIOCM_RTS);
+    }
+
+    result = ioctl(port_fd, TIOCMSET, &flags);
+
+    if (result == -1) {
+        printf("Error %i while setting port io flags\n", errno);
+    }
+}
+
+
+
+
+
+
+
+void set_dtr(int val)
+{
+    int flags;
+    int result;
+
+    result = ioctl(port_fd, TIOCMGET, &flags);
+
+    if (result == -1) {
+        printf("Error %i while reading port io flags\n", errno);
+        return;
+    }
+
+    if (val) {
+        flags |= TIOCM_DTR;
+    }
+    else {
+        flags &= ~(TIOCM_DTR);
+    }
+
+    result = ioctl(port_fd, TIOCMSET, &flags);
+
+    if (result == -1) {
+        printf("Error %i while setting port io flags\n", errno);
+    }
+}
+
+
+
+
+
+
diff --git a/boards/msba2-common/tools/src/serial.h b/boards/msba2-common/tools/src/serial.h
new file mode 100644
index 0000000000000000000000000000000000000000..3887a189473d1b0d8640474aa8e96c4380c095e2
--- /dev/null
+++ b/boards/msba2-common/tools/src/serial.h
@@ -0,0 +1,19 @@
+#ifndef SERIAL_H
+#define SERIAL_H
+
+extern char *baud_rate;
+
+int open_serial_port(const char *port_name);
+int write_serial_port(const void *buf, int num);
+void input_flush_serial_port(void);
+int read_serial_port_nb(unsigned char *buf, int bufsize);
+int read_serial_port(unsigned char *buf, int bufsize);
+void close_serial_port(void);
+void send_break_signal(void);
+int set_baud(const char *baud_name);
+int serial_port_fd(void);
+void set_rts(int val);
+void set_dtr(int val);
+void change_baud(const char *baud_name);
+
+#endif // SERIAL_H
diff --git a/boards/msba2-common/tools/src/settings.c b/boards/msba2-common/tools/src/settings.c
new file mode 100644
index 0000000000000000000000000000000000000000..405d648e1a1113ba8f7b8faa623bfe631e39184b
--- /dev/null
+++ b/boards/msba2-common/tools/src/settings.c
@@ -0,0 +1,209 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "settings.h"
+
+#define DEFAULT_FILE ""
+#define DEFAULT_PORT "/dev/ttyS0"
+#define DEFAULT_BAUD "115200"
+#define DEFAULT_CRYSTAL "16"
+
+char *baud_list[] = {"115200", "57600", "38400",
+                     "19200", "9600", "4800", "2400", "1200", "300", NULL
+                    };
+
+static char file[128] = {DEFAULT_FILE};
+static char port[64] = {DEFAULT_PORT};
+static char baud[64] = {DEFAULT_BAUD};
+static char crystal[64] = {DEFAULT_CRYSTAL};
+
+static char settings_file[256] = {'\0'};
+
+
+void init_settings(void)
+{
+    const char *home_dir;
+    FILE *fp;
+    char buf[1024], *p, *q;
+
+    home_dir = getenv("HOME");
+
+    if (home_dir && *home_dir) {
+        snprintf(settings_file, sizeof(settings_file),
+                 "%s/.lpc2k_pgm", home_dir);
+        fp = fopen(settings_file, "r");
+
+        if (fp == NULL) {
+            return;
+        }
+
+        while (!feof(fp)) {
+            buf[0] = '\0';
+            fgets(buf, sizeof(buf), fp);
+
+            if (strncmp(buf, "file:", 5) == 0) {
+                for (p = buf + 5; isspace(*p); p++);
+                q = rindex(p, '\n');
+                if (q) {
+                    *q = '\0';
+                }
+                q = rindex(p, '\r');
+                if (q) {
+                    *q = '\0';
+                }
+                snprintf(file, sizeof(file), "%s", p);
+            }
+
+            if (strncmp(buf, "port:", 5) == 0) {
+                for (p = buf + 5; isspace(*p); p++);
+                q = rindex(p, '\n');
+                if (q) {
+                    *q = '\0';
+                }
+                q = rindex(p, '\r');
+                if (q) {
+                    *q = '\0';
+                }
+                snprintf(port, sizeof(port), "%s", p);
+            }
+
+            if (strncmp(buf, "baud:", 5) == 0) {
+                for (p = buf + 5; isspace(*p); p++);
+                q = rindex(p, '\n');
+                if (q) {
+                    *q = '\0';
+                }
+                q = rindex(p, '\r');
+                if (q) {
+                    *q = '\0';
+                }
+                snprintf(baud, sizeof(baud), "%s", p);
+            }
+
+            if (strncmp(buf, "xtal:", 5) == 0) {
+                for (p = buf + 5; isspace(*p); p++) ;
+                q = rindex(p, '\n');
+                if (q) {
+                    *q = '\0';
+                }
+                q = rindex(p, '\r');
+                if (q) {
+                    *q = '\0';
+                }
+                snprintf(crystal, sizeof(crystal), "%s", p);
+            }
+        }
+
+        fclose(fp);
+    }
+}
+
+void write_settings_file(void)
+{
+    FILE *fp;
+
+    if (settings_file[0] == '\0') {
+        return;
+    }
+
+    fp = fopen(settings_file, "w");
+
+    if (fp == NULL) {
+        return;
+    }
+
+    fprintf(fp, "file: %s\n", file);
+    fprintf(fp, "port: %s\n", port);
+    fprintf(fp, "baud: %s\n", baud);
+    fprintf(fp, "xtal: %s\n", crystal);
+    fflush(fp);
+    fclose(fp);
+}
+
+const char *file_setting(void)
+{
+    return file;
+}
+
+const char *port_setting(void)
+{
+    return port;
+}
+
+const char *baud_setting(void)
+{
+    return baud;
+}
+
+const char *crystal_setting(void)
+{
+    return crystal;
+}
+
+void new_file_setting(const char *new_file)
+{
+    if (strcmp(file, new_file)) {
+        snprintf(file, sizeof(file), "%s", new_file);
+        write_settings_file();
+    }
+}
+
+void new_port_setting(const char *new_port)
+{
+    if (strcmp(port, new_port)) {
+        snprintf(port, sizeof(port), "%s", new_port);
+        write_settings_file();
+    }
+}
+
+void new_baud_setting(const char *new_baud)
+{
+    if (strcmp(baud, new_baud)) {
+        snprintf(baud, sizeof(baud), "%s", new_baud);
+        write_settings_file();
+    }
+}
+
+void new_crystal_setting(const char *new_xtal)
+{
+    if (strcmp(crystal, new_xtal)) {
+        snprintf(crystal, sizeof(crystal), "%s", new_xtal);
+        write_settings_file();
+    }
+}
+
diff --git a/boards/msba2-common/tools/src/settings.h b/boards/msba2-common/tools/src/settings.h
new file mode 100644
index 0000000000000000000000000000000000000000..47356be96cef2869e7bbeecdeca44eb5a97dd13c
--- /dev/null
+++ b/boards/msba2-common/tools/src/settings.h
@@ -0,0 +1,12 @@
+
+extern void init_settings(void);
+extern const char *file_setting(void);
+extern const char *port_setting(void);
+extern const char *baud_setting(void);
+extern const char *crystal_setting(void);
+extern void new_file_setting(const char *new_file);
+extern void new_port_setting(const char *new_port);
+extern void new_baud_setting(const char *new_baud);
+extern void new_crystal_setting(const char *new_xtal);
+
+extern char *baud_list[];
diff --git a/boards/msba2-common/tools/src/uuencode.c b/boards/msba2-common/tools/src/uuencode.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b6856ab6408a4f824bef170776ac353d940f9b8
--- /dev/null
+++ b/boards/msba2-common/tools/src/uuencode.c
@@ -0,0 +1,123 @@
+/*
+ * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm
+ * Copyright (c) 2004, PJRC.COM, LLC, <paul@pjrc.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* If this code fails to build, please provide at least the following
+ * information when requesting (free) technical support.
+ *
+ * 1: Complete copy of all messages during the build.
+ * 2: Output of "gtk-config --version"
+ * 3: Output of "gtk-config --libs"
+ * 4: Output of "gtk-config --cflags"
+ * 5: Output of "uname -a"
+ * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk*
+ * 7: Other info... which linux distribution, version, other software
+ */
+
+#include "uuencode.h"
+
+static char uuchar(unsigned int val);
+
+
+void uuencode(char *str, const unsigned char *data, int num)
+{
+    int i, n;
+    unsigned int val;
+
+    *str++ = uuchar(num);
+
+    n = (num + 2) / 3;
+
+    for (i = 0; i < n; i++) {
+        val = ((data[0] & 0xFF) << 16)
+              | ((data[1] & 0xFF) << 8)
+              | ((data[2] & 0xFF) << 0);
+        *str++ = uuchar(val >> 18);
+        *str++ = uuchar(val >> 12);
+        *str++ = uuchar(val >>  6);
+        *str++ = uuchar(val >>  0);
+        data += 3;
+    }
+
+    *str = '\0';
+}
+
+int uudecode(const char *str, unsigned char *data, int max)
+{
+    int num = 0;
+    int i, n;
+    unsigned int val;
+
+    if (*str == '\0') {
+        return 0;
+    }
+
+    num = *str++ - 32;
+
+    if (num < 1 || num > 45) {
+        return 0;
+    }
+
+    n = (num + 2) / 3;
+
+    for (i = 0; i < n; i++) {
+        if (str[0] < 32 || str[0] > 96) {
+            return 0;
+        }
+
+        if (str[1] < 32 || str[1] > 96) {
+            return 0;
+        }
+
+        if (str[2] < 32 || str[2] > 96) {
+            return 0;
+        }
+
+        if (str[3] < 32 || str[3] > 96) {
+            return 0;
+        }
+
+        val = (((str[0] - 32) & 0x3F) << 18)
+              | (((str[1] - 32) & 0x3F) << 12)
+              | (((str[2] - 32) & 0x3F) << 6)
+              | (((str[3] - 32) & 0x3F) << 0);
+        *data++ = (val >> 16) & 0xFF;
+        *data++ = (val >> 8) & 0xFF;
+        *data++ = (val >> 0) & 0xFF;
+        str += 4;
+    }
+
+    return num;
+}
+
+
+static char uuchar(unsigned int val)
+{
+    val &= 0x3F;
+    val += 0x20;
+
+    if (val == 0x20) {
+        val = 0x60;
+    }
+
+    return val;
+}
+
+
+
diff --git a/boards/msba2-common/tools/src/uuencode.h b/boards/msba2-common/tools/src/uuencode.h
new file mode 100644
index 0000000000000000000000000000000000000000..92fecb7d33c3f391f9e9724436396cf89ff2c5ad
--- /dev/null
+++ b/boards/msba2-common/tools/src/uuencode.h
@@ -0,0 +1,3 @@
+extern void uuencode(char *str, const unsigned char *data, int num);
+extern int uudecode(const char *str, unsigned char *data, int max);
+
diff --git a/boards/msba2-common/tools/termctrl.sh b/boards/msba2-common/tools/termctrl.sh
new file mode 100755
index 0000000000000000000000000000000000000000..75e87ab21e336d0562e7dd4aaa8caa9abf0bce43
--- /dev/null
+++ b/boards/msba2-common/tools/termctrl.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+pid=`pgrep pseudoterm`
+
+if test "$pid" = "" ; then
+
+	echo "   Pseudoterm not running."
+
+else
+
+	if test "$1" = "continue" ; then
+		kill -s USR1 $pid;
+	elif test "$1" = "pause" ; then
+		kill -s USR2 $pid ;
+	elif test "$1" = "stop" ; then
+		kill $pid ;
+	else
+		echo "Usage:";
+		echo "termctrl.sh continue/pause/stop";
+	fi
+	
+fi
diff --git a/boards/msba2/Makefile b/boards/msba2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0aff0df0b14cb786c255ac89d8461d5718813bf2
--- /dev/null
+++ b/boards/msba2/Makefile
@@ -0,0 +1,37 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+export ARCH = msba2_base.a
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBOARD)/msba2/include/
+INCLUDES += -I$(RIOTBOARD)/msba2-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/arm_common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/lpc2387/include/
+
+all: $(BINDIR)$(ARCH) 
+	$(MAKE) -C ../msba2-common
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	mkdir -p $(BINDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	$(MAKE) -C ../msba2-common clean
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	@if [ -d $(BINDIR) ] ; \
+	then rmdir $(BINDIR) ; \
+	fi 
+
+
diff --git a/boards/msba2/Makefile.include b/boards/msba2/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..80751c020ac0a95cf54ae8a9adb23083d0d5dce3
--- /dev/null
+++ b/boards/msba2/Makefile.include
@@ -0,0 +1,3 @@
+export INCLUDES += -I$(RIOTBOARD)/msba2/include -I$(RIOTBOARD)/msba2-common/include
+
+include $(RIOTBOARD)/msba2-common/Makefile.include
diff --git a/boards/msba2/board_init.c b/boards/msba2/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..427d563e1bc33561054d746bbd6edfcdfdd62d63
--- /dev/null
+++ b/boards/msba2/board_init.c
@@ -0,0 +1,109 @@
+/*
+ * main.c - Main function of the SRF02 ultrasonic sensor project.
+ * Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ *
+ * The source code is licensed under the LGPLv2 license,
+ * See the file LICENSE for more details.
+ */
+
+/**
+ * @ingroup msba2
+ * @{
+ */
+
+/**
+ * @file
+ * @brief       MSB-A2 board initialization
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author      Heiko Will
+ * @author      Kaspar Schleiser
+ * @author      Michael Baar <baar@inf.fu-berlin.de>
+ * @author		Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
+ *
+ * @note        $Id$
+ */
+
+
+#include <board.h>
+#include <cpu.h>
+
+void loop_delay(void)
+{
+    volatile uint16_t i, j;
+
+    for (i = 1; i < 30; i++) {
+        for (j = 1; j != 0; j++) {
+            asm volatile(" nop ");
+        }
+    }
+}
+
+void bl_blink(void)
+{
+    LED_RED_ON;
+    LED_GREEN_ON;
+
+    loop_delay();
+
+    LED_RED_OFF;
+    LED_GREEN_OFF;
+}
+
+void bl_init_ports(void)
+{
+    SCS |= BIT0;                                            // Set IO Ports to fast switching mode
+
+    /* UART0 */
+    PINSEL0 |= BIT4 + BIT6;                                 // RxD0 and TxD0
+    PINSEL0 &= ~(BIT5 + BIT7);
+
+    /* LEDS */
+    FIO3DIR |= LED_RED_PIN;
+    FIO3DIR |= LED_GREEN_PIN;
+    LED_RED_OFF;
+    LED_GREEN_OFF;
+
+    /* short blinking of both of the LEDs on startup */
+    bl_blink();
+}
+
+static inline void
+pllfeed(void)
+{
+    PLLFEED = 0xAA;
+    PLLFEED = 0x55;
+}
+
+void init_clks1(void)
+{
+    // Disconnect PLL
+    PLLCON &= ~0x0002;
+    pllfeed();
+
+    // Disable PLL
+    PLLCON &= ~0x0001;
+    pllfeed();
+
+    SCS |= 0x20;                        // Enable main OSC
+
+    while (!(SCS & 0x40));              // Wait until main OSC is usable
+
+    /* select main OSC, 16MHz, as the PLL clock source */
+    CLKSRCSEL = 0x0001;
+
+    // Setting Multiplier and Divider values
+    PLLCFG = 0x0008;                    // M=9 N=1 Fcco = 288 MHz
+    pllfeed();
+
+    // Enabling the PLL */
+    PLLCON = 0x0001;
+    pllfeed();
+
+    /* Set clock divider to 4 (value+1) */
+    CCLKCFG = CL_CPU_DIV - 1;           // Fcpu = 72 MHz
+
+#if USE_USB
+    USBCLKCFG = USBCLKDivValue;     /* usbclk = 288 MHz/6 = 48 MHz */
+#endif
+}
diff --git a/boards/msba2/include/board.h b/boards/msba2/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..829715b3c250cc824c48c72698b0951cb774c9b9
--- /dev/null
+++ b/boards/msba2/include/board.h
@@ -0,0 +1,22 @@
+#ifndef __BOARD_H
+#define __BOARD_H
+
+#include "msba2_common.h"
+#include "bitarithm.h"
+
+#define LED_RED_PIN (BIT25)
+#define LED_GREEN_PIN (BIT26)
+
+#define LED_GREEN_OFF (FIO3SET = LED_GREEN_PIN)
+#define LED_GREEN_ON (FIO3CLR = LED_GREEN_PIN)
+#define LED_GREEN_TOGGLE (FIO3PIN ^= LED_GREEN_PIN)
+
+#define LED_RED_OFF (FIO3SET = LED_RED_PIN)
+#define LED_RED_ON (FIO3CLR = LED_RED_PIN)
+#define LED_RED_TOGGLE (FIO3PIN ^= LED_RED_PIN)
+
+void init_clks1(void);
+
+typedef uint8_t radio_packet_length_t;
+
+#endif /* __BOARD_H */
diff --git a/boards/native/Makefile b/boards/native/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..ded96b6cf2f0b6228ff2daacd5866086a9d51e5e
--- /dev/null
+++ b/boards/native/Makefile
@@ -0,0 +1,31 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+export ARCH = native_base.a
+
+INCLUDES += -I$(RIOTBASE)/cpu/native/include/
+INCLUDES += -I$(RIOTBOARD)/native/include/
+
+all: $(BINDIR)$(ARCH)
+	$(MAKE) -C drivers
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	-mkdir -p $(BINDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	${MAKE} -C drivers clean
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	-rmdir -p $(BINDIR)
+
diff --git a/boards/native/Makefile.dep b/boards/native/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..fdd8ec4d907e0162da0a462b8b07bb9340b926dc
--- /dev/null
+++ b/boards/native/Makefile.dep
@@ -0,0 +1,6 @@
+ifneq (,$(findstring ltc4150,$(USEMODULE)))
+	ifeq (,$(findstring hwtimer,$(USEMODULE)))
+		USEMODULE += hwtimer
+	endif
+endif
+
diff --git a/boards/native/Makefile.include b/boards/native/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..1a5b2e4d2d3d24435f86536928f14ebfef24124b
--- /dev/null
+++ b/boards/native/Makefile.include
@@ -0,0 +1,23 @@
+export INCLUDES += -I$(RIOTBOARD)/native/include
+export CPU = native
+
+# toolchain config
+export PREFIX = 
+#export CC = @$(PREFIX)gcc
+export AR = @$(PREFIX)ar
+export CFLAGS += -std=gnu99 -Wall -m32
+export ASFLAGS =
+export AS = $(PREFIX)as
+export LINK = $(PREFIX)gcc
+export SIZE = $(PREFIX)size
+export OBJCOPY = $(PREFIX)objcopy
+FLASHER = lpc2k_pgm
+TERM = pyterm.py
+
+LINKFLAGS += -m32 -gc
+
+ifeq ($(strip $(PORT)),)
+	export PORT = /dev/ttyUSB0
+endif
+
+include $(RIOTBOARD)/$(BOARD)/Makefile.dep
diff --git a/boards/native/board_config.c b/boards/native/board_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..dafdf747aac99db460c7d2bb3ea62f920fed02bf
--- /dev/null
+++ b/boards/native/board_config.c
@@ -0,0 +1,39 @@
+/**
+ * Native Board config.h implementation
+ *
+ * No functionality implemented at the moment.
+ *
+ * Copyright (C) 2013 Ludwig Ortmann
+ *
+ * This file subject to the terms and conditions of the GNU General Public
+ * License. See the file LICENSE in the top level directory for more details.
+ *
+ * @ingroup native_board
+ * @{
+ * @file
+ * @author  Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
+ * @}
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include <config.h>
+
+/**
+ * XXX: loading not implemented
+ */
+void config_load(void)
+{
+    printf("XXX: config_load(): not implemented\n");
+    return;
+}
+
+/**
+ * XXX: storing not implemented
+ */
+uint8_t config_save(void)
+{
+    printf("XXX: config_save(): not implemented - your config will vanish on process termination\n");
+    return 1;
+}
diff --git a/boards/native/board_init.c b/boards/native/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..0abc01573c6dfa18c55b7a3c3271955f54c57ed4
--- /dev/null
+++ b/boards/native/board_init.c
@@ -0,0 +1,32 @@
+/**
+ * Native Board board_init implementation
+ *
+ * Copyright (C) 2013 Ludwig Ortmann
+ *
+ * This file subject to the terms and conditions of the GNU General Public
+ * License. See the file LICENSE in the top level directory for more details.
+ *
+ * @ingroup native_board
+ * @{
+ * @file
+ * @author  Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
+ * @}
+ */
+#include <stdio.h>
+#include "board.h"
+
+#include "board_internal.h"
+
+/**
+ * Nothing to initialize at the moment.
+ * Turns the red LED on and the green LED off.
+ */
+void board_init()
+{
+#ifdef MODULE_UART0
+    _native_init_uart0();
+#endif
+    LED_GREEN_OFF;
+    LED_RED_ON;
+    puts("RIOT native board initialized.");
+}
diff --git a/boards/native/drivers/Makefile b/boards/native/drivers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f0516a8530a66865184b917e8a329f72c41b921b
--- /dev/null
+++ b/boards/native/drivers/Makefile
@@ -0,0 +1,30 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(BINDIR)native-led.o
+ifneq (,$(findstring ltc4150,$(USEMODULE)))
+	OBJ += $(BINDIR)native-ltc4150.o
+endif
+ifneq (,$(findstring uart0,$(USEMODULE)))
+	OBJ += $(BINDIR)native-uart0.o
+endif
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBOARD)/native/include/
+
+$(BINDIR)native_drivers.a: $(OBJ)
+	@$(AR) rcs $(BINDIR)${ARCH} $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	@$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+
+clean:
+	rm -f $(OBJ) $(DEP)
+
diff --git a/boards/native/drivers/native-led.c b/boards/native/drivers/native-led.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f9296d7c3fdbe786e1274b7b1ef5ca28d03ce61
--- /dev/null
+++ b/boards/native/drivers/native-led.c
@@ -0,0 +1,51 @@
+/**
+ * Native Board LED implementation
+ *
+ * Only prints function calls at the moment.
+ *
+ * Copyright (C) 2013 Ludwig Ortmann
+ *
+ * This file subject to the terms and conditions of the GNU General Public
+ * License. See the file LICENSE in the top level directory for more details.
+ *
+ * @ingroup native_board
+ * @{
+ * @file
+ * @author  Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
+ * @}
+ */
+
+#include <stdio.h>
+
+#include "board.h"
+
+void _native_LED_GREEN_OFF(void)
+{
+    printf("LED_GREEN_OFF\n");
+}
+
+void _native_LED_GREEN_ON(void)
+{
+    printf("LED_GREEN_ON\n");
+}
+
+void _native_LED_GREEN_TOGGLE(void)
+{
+    printf("LED_GREEN_TOGGLE\n");
+}
+
+void _native_LED_RED_OFF(void)
+{
+    printf("LED_RED_OFF\n");
+}
+
+void _native_LED_RED_ON(void)
+{
+    printf("LED_RED_ON\n");
+}
+
+void _native_LED_RED_TOGGLE(void)
+{
+    printf("LED_RED_TOGGLE\n");
+}
+
diff --git a/boards/native/drivers/native-ltc4150.c b/boards/native/drivers/native-ltc4150.c
new file mode 100644
index 0000000000000000000000000000000000000000..babe801616bafd72e13da4d58c6413a5397f72a7
--- /dev/null
+++ b/boards/native/drivers/native-ltc4150.c
@@ -0,0 +1,89 @@
+/**
+ * Native Board ltc4150_arch.h implementation
+ *
+ * Only measures time at the moment. Uses POSIX real-time extension
+ * timer to generate periodic signal/interrupt.
+ *
+ * Copyright (C) 2013 Ludwig Ortmann
+ *
+ * This file subject to the terms and conditions of the GNU General Public
+ * License. See the file LICENSE in the top level directory for more details.
+ *
+ * @ingroup native_board
+ * @ingroup ltc4150
+ * @{
+ * @file
+ * @author  Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <time.h>
+#include <err.h>
+
+#include "ltc4150_arch.h"
+#include "debug.h"
+
+#include "cpu.h"
+#include "cpu-conf.h"
+#include "hwtimer.h"
+
+#define native_ltc4150_startup_delay 10
+
+static int _int_enabled;
+
+/**
+ * native ltc4150 hwtimer - interrupt handler proxy
+ */
+static void _int_handler()
+{
+    DEBUG("ltc4150 _int_handler()\n");
+    ltc4150_interrupt();
+    if (_int_enabled == 1) {
+        if (hwtimer_set(100000, _int_handler, NULL) == -1) {
+            errx(1, "_int_handler: hwtimer_set");
+        };
+    }
+}
+
+/**
+ * unregister signal handler
+ */
+void ltc4150_disable_int(void)
+{
+    DEBUG("ltc4150_disable_int()\n");
+    _int_enabled = 0;
+}
+
+/**
+ * register signal handler
+ */
+void ltc4150_enable_int(void)
+{
+    DEBUG("ltc4150_enable_int()\n");
+    _int_enabled = 1;
+    if (hwtimer_set(100000, _int_handler, NULL) == -1) {
+        errx(1, "ltc4150_enable_int: hwtimer_set");
+    };
+}
+
+/**
+ * elaborate nop
+ */
+void ltc4150_sync_blocking(void)
+{
+    DEBUG("ltc4150_sync_blocking()\n");
+
+    for (int i = native_ltc4150_startup_delay; i > 0; i--);
+}
+
+/**
+ * set up posix real-time timer to simulate coloumb counter ticks
+ */
+void ltc4150_arch_init(void)
+{
+    ltc4150_disable_int();
+
+    puts("Native LTC4150 initialized.");
+}
+/** @} */
diff --git a/boards/native/drivers/native-uart0.c b/boards/native/drivers/native-uart0.c
new file mode 100644
index 0000000000000000000000000000000000000000..b9d8b041d3275bffbe8f6057e6e8d1c9e49f165c
--- /dev/null
+++ b/boards/native/drivers/native-uart0.c
@@ -0,0 +1,98 @@
+/*
+ * native uart0 implementation
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <sys/select.h>
+
+#include "cpu.h"
+#include "debug.h"
+#include "board_uart0.h"
+
+int _native_uart_in;
+int _native_uart_out;
+
+fd_set _native_uart_rfds;
+
+inline int uart0_puts(char *astring, int length)
+{
+    int nwritten, offset;
+
+    nwritten = 0;
+    offset = 0;
+
+    _native_in_syscall = 1;
+
+    while ((length > 0) &&(nwritten = write(_native_uart_out, astring+offset, length-offset)) > 0) {
+        offset += nwritten;
+    }
+    if (nwritten == -1) {
+        err(EXIT_FAILURE, "uart0_puts: write");
+    }
+    else if ((length > 0) && (nwritten == 0)) {
+        /* XXX: handle properly */
+        errx(EXIT_FAILURE, "uart0_puts: Could not write to stdout. I don't know what to do now.");
+    }
+
+    _native_in_syscall = 0;
+
+    return length;
+}
+
+void _native_handle_uart0_input()
+{
+    char buf[42];
+    int nread;
+
+    if (!FD_ISSET(_native_uart_in, &_native_rfds)) {
+        DEBUG("_native_handle_uart0_input - nothing to do\n");
+        return;
+    }
+    DEBUG("_native_handle_uart0_input\n");
+    _native_in_syscall = 0;
+    _native_in_isr = 1;
+
+    nread = read(_native_uart_in, buf, sizeof(buf));
+    if (nread == -1) {
+        err(1, "_native_handle_uart0_input(): read()");
+    }
+    else if (nread == 0) {
+        /* XXX:
+         * preliminary resolution for this situation, will be coped
+         * with properly in #161 */
+        close(_native_uart_in);
+        _native_uart_in = -1;
+        warnx("stdin closed");
+    }
+    for(int pos = 0; pos < nread; pos++) {
+        uart0_handle_incoming(buf[pos]);
+    }
+    uart0_notify_thread();
+
+    _native_in_isr = 0;
+    thread_yield();
+}
+
+int _native_set_uart_fds(void)
+{
+    DEBUG("_native_set_uart_fds");
+    FD_SET(_native_uart_in, &_native_rfds);
+    return _native_uart_in;
+}
+
+void _native_init_uart0()
+{
+    _native_uart_out = STDOUT_FILENO;
+    _native_uart_in = STDIN_FILENO;
+
+    puts("RIOT native uart0 initialized.");
+}
+
+int putchar(int c) {
+    write(_native_uart_out, &c, 1);
+    return 0;
+}
diff --git a/boards/native/include/board.h b/boards/native/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1dca63e6a96589a49d2c20a58d391da7a047d6e
--- /dev/null
+++ b/boards/native/include/board.h
@@ -0,0 +1,37 @@
+#ifndef BOARD_H
+#define BOARD_H
+
+/**
+ * Native Board interface
+ *
+ * The native board uses call level hardware simulation.
+ *
+ * Copyright (C) 2013 Ludwig Ortmann
+ *
+ * This file subject to the terms and conditions of the GNU General Public
+ * License. See the file LICENSE in the top level directory for more details.
+ *
+ * @defgroup native_board
+ * @{
+ * @file
+ * @author  Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
+ * @}
+ */
+
+#include <stdint.h>
+
+void _native_LED_GREEN_OFF(void);
+#define LED_GREEN_OFF (_native_LED_GREEN_OFF())
+void _native_LED_GREEN_ON(void);
+#define LED_GREEN_ON (_native_LED_GREEN_ON())
+void _native_LED_GREEN_TOGGLE(void);
+#define LED_GREEN_TOGGLE (_native_LED_GREEN_TOGGLE())
+void _native_LED_RED_OFF(void);
+#define LED_RED_OFF (_native_LED_RED_OFF())
+void _native_LED_RED_ON(void);
+#define LED_RED_ON (_native_LED_RED_ON())
+void _native_LED_RED_TOGGLE(void);
+#define LED_RED_TOGGLE (_native_LED_RED_TOGGLE())
+
+typedef uint16_t radio_packet_length_t;
+#endif /* BOARD_H */
diff --git a/boards/native/include/board_internal.h b/boards/native/include/board_internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..368d5287de63a9dbbb6a7a2bcdcc4eb0cd58ee3f
--- /dev/null
+++ b/boards/native/include/board_internal.h
@@ -0,0 +1,6 @@
+#ifdef MODULE_UART0
+#include <sys/select.h>
+void _native_handle_uart0_input(void);
+void _native_init_uart0(void);
+int _native_set_uart_fds(void);
+#endif
diff --git a/boards/olimex_lpc2148/board_init.c b/boards/olimex_lpc2148/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..1d1746be4dfd1fa11ec6039860812d94a96fcc32
--- /dev/null
+++ b/boards/olimex_lpc2148/board_init.c
@@ -0,0 +1,88 @@
+/*
+ * bl_board_init.c
+ *
+ *  Created on: 19.08.2008
+ *      Author: heiko, kaspar
+ */
+
+#include "cpu.h"
+#include "bits.h"
+#include "VIC.h"
+
+#define PLOCK 0x400
+
+static void feed(void)
+{
+    PLL0FEED = 0xAA;
+    PLL0FEED = 0x55;
+}
+
+void bl_init_clks(void)
+{
+
+    // 				Setting the Phased Lock Loop (PLL)
+    //               ----------------------------------
+    //
+    // Olimex LPC-P2148 has a 12.0000 mhz crystal
+    //
+    // We'd like the LPC2148 to run at 60 mhz (has to be an even multiple of crystal)
+    //
+    // According to the Philips LPC2148 manual:   M = cclk / Fosc	where:	M    = PLL multiplier (bits 0-4 of PLLCFG)
+    //																		cclk = 60000000 hz
+    //																		Fosc = 12000000 hz
+    //
+    // Solving:	M = 60000000 / 12000000 = 5
+    //
+    //			Note: M - 1 must be entered into bits 0-4 of PLLCFG (assign 4 to these bits)
+    //
+    //
+    // The Current Controlled Oscilator (CCO) must operate in the range 156 mhz to 320 mhz
+    //
+    // According to the Philips LPC2148 manual:	Fcco = cclk * 2 * P    where:	Fcco = CCO frequency
+    //																			cclk = 60000000 hz
+    //																			P = PLL divisor (bits 5-6 of PLLCFG)
+    //
+    // Solving:	Fcco = 60000000 * 2 * P
+    //			P = 2  (trial value)
+    //			Fcco = 60000000 * 2 * 2
+    //			Fcc0 = 240000000 hz    (good choice for P since it's within the 156 mhz to 320 mhz range)
+    //
+    // From Table 22 (page 34) of Philips LPC2148 manual    P = 2, PLLCFG bits 5-6 = 1  (assign 1 to these bits)
+    //
+    // Finally:      PLLCFG = 0  01  00100  =  0x24
+    //
+    // Final note: to load PLLCFG register, we must use the 0xAA followed 0x55 write sequence to the PLLFEED register
+    //             this is done in the short function feed() below
+    //
+
+    // Setting Multiplier and Divider values
+    PLL0CFG = 0x24;
+    feed();
+
+    // Enabling the PLL */
+    PLL0CON = 0x1;
+    feed();
+
+    // Wait for the PLL to lock to set frequency
+    while (!(PLL0STAT & PLOCK)) ;
+
+    // Connect the PLL as the clock source
+    PLL0CON = 0x3;
+    feed();
+
+    // Enabling MAM and setting number of clocks used for Flash memory fetch
+    MAMTIM = 0x3;
+    MAMCR = 0x2;
+
+    // Setting peripheral Clock (pclk) to 1/2 System Clock (cclk)
+    VPBDIV = PCLK_DIV;
+}
+
+
+
+
+void bl_init_ports(void)
+{
+
+}
+
diff --git a/boards/olimex_lpc2148/debug_uart.c b/boards/olimex_lpc2148/debug_uart.c
new file mode 100644
index 0000000000000000000000000000000000000000..90f5144dfefb70e413c15967157d0027b69eea94
--- /dev/null
+++ b/boards/olimex_lpc2148/debug_uart.c
@@ -0,0 +1,14 @@
+#include "lpc214x.h"
+#include "bits.h"
+
+#include "rs232.h"
+
+void debug_putchar(int character)
+{
+    UART1WriteChar(character);
+}
+
+void bl_uart_init(void)
+{
+    UART1Initialize(115200U);
+}
diff --git a/boards/olimex_lpc2148/include/board.h b/boards/olimex_lpc2148/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff961ea36689a009a462aedf9e64234736b4bf37
--- /dev/null
+++ b/boards/olimex_lpc2148/include/board.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+#include "lpc2148.h"
+
+typedef uint8_t radio_packet_length_t;
diff --git a/boards/olimex_lpc2148/include/rs232.h b/boards/olimex_lpc2148/include/rs232.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fe0bf2c872b85df85d0587f0bb8d4025e8fb1cd
--- /dev/null
+++ b/boards/olimex_lpc2148/include/rs232.h
@@ -0,0 +1,40 @@
+//rs232.h
+//#include <iolpc2138.h>
+
+#include "lpc214x.h"
+
+//#define OSCILLATOR_CLOCK_FREQUENCY  14745600      //in MHz
+#define OSCILLATOR_CLOCK_FREQUENCY  12000000      //in MHz
+
+//get real processor clock frequency
+unsigned int processorClockFrequency(void);
+//get peripheral clock frequency
+unsigned int peripheralClockFrequency(void);
+
+/**** UART0 ****/
+//initialize UART0 interface
+void UART0Initialize(unsigned int baud);
+//write char to UART0 (RS232);
+void UART0WriteChar(int ch0);
+//read char from RS232
+unsigned char UART0ReadChar(void);
+
+//this function read/write char from RS232,
+//but they not wait to read/write
+unsigned char UART0ReadChar_nostop(void);
+void UART0WriteChar_nostop(unsigned char ch0);
+
+
+/**** UART1 ****/
+//initialize UART0 interface
+void UART1Initialize(unsigned int baud);
+//write char to UART0 (RS232);
+void UART1WriteChar(int ch0);
+//read char from RS232
+unsigned char UART0ReadChar(void);
+
+//this function read/write char from RS232,
+//but they not wait to read/write
+unsigned char UART1ReadChar_nostop(void);
+void UART1WriteChar_nostop(unsigned char ch0);
+
diff --git a/boards/olimex_lpc2148/rs232.c b/boards/olimex_lpc2148/rs232.c
new file mode 100644
index 0000000000000000000000000000000000000000..ac885b877f276c9131d78d0bb01e97ffde516528
--- /dev/null
+++ b/boards/olimex_lpc2148/rs232.c
@@ -0,0 +1,75 @@
+//rs232.c
+#include "rs232.h"
+
+unsigned int processorClockFrequency(void)
+{
+    //return real processor clock speed
+    return OSCILLATOR_CLOCK_FREQUENCY * (PLL0CON & 1 ? (PLL0CFG & 0xF) + 1 : 1);
+}
+
+unsigned int peripheralClockFrequency(void)
+{
+    //VPBDIV - determines the relationship between the processor clock (cclk)
+    //and the clock used by peripheral devices (pclk).
+    unsigned int divider = 0;
+
+    switch (VPBDIV & 3) {
+        case 0:
+            divider = 4;
+            break;
+
+        case 1:
+            divider = 1;
+            break;
+
+        case 2:
+            divider = 2;
+            break;
+    }
+
+    return processorClockFrequency() / divider;
+}
+
+/**** UART0 ****/
+void UART1Initialize(unsigned int baud)
+{
+    unsigned int divisor = peripheralClockFrequency() / (16 * baud);
+
+    //set Line Control Register (8 bit, 1 stop bit, no parity, enable DLAB)
+    //  U0LCR_bit.WLS   = 0x3;    //8 bit
+    //  U0LCR_bit.SBS   = 0x0;    //1 stop bit
+    //  U0LCR_bit.PE    = 0x0;    //no parity
+    //  U0LCR_bit.DLAB  = 0x1;    //enable DLAB
+    //with one row
+    U1LCR = 0x83;
+
+
+    //devisor
+    U1DLL = divisor & 0xFF;
+    U1DLM = (divisor >> 8) & 0xFF;
+    U1LCR &= ~0x80;
+
+    //set functionalite to pins:  port0.0 -> TX0,  port0.1 -> RXD0
+    //  PINSEL0_bit.P0_0 = 0x1;
+    //  PINSEL0_bit.P0_1 = 0x1;
+    //with one row
+    PINSEL0 |= BIT16;
+    PINSEL0 &= ~BIT17;
+
+}
+
+void UART1WriteChar(int ch0)
+{
+    while (!(U1LSR & BIT5));
+
+    U1THR = ch0;
+}
+
+unsigned char UART0ReadChar(void)
+{
+    //when U0LSR_bit.DR is 1 - U0RBR contains valid data
+    //  while (U0LSR_bit.DR == 0);
+    return U0RBR;
+}
+
+
diff --git a/boards/olimex_lpc2148/tick.c b/boards/olimex_lpc2148/tick.c
new file mode 100644
index 0000000000000000000000000000000000000000..0d627069430b5a49e977ed265e268321fdae8357
--- /dev/null
+++ b/boards/olimex_lpc2148/tick.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
+
+This file is part of the Micro-mesh SensorWeb Firmware.
+
+Micro-Mesh is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+Micro-Mesh is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Micro-Mesh; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "lpc214x.h"
+#include "bits.h"
+//#include "tick.h"
+#include "minimal_dbg_console.h"
+#include "VIC.h"
+
+void Timer0_IRQHandler(void) __attribute__((interrupt("IRQ")));
+
+extern void eINT();
+extern void dINT();
+
+
+void driver_timer_load(void)
+{
+    T0TCR = 0;                  // Disable timer 0.
+    T0PR  = 3000;               // Prescaler is set to relevant pclk , counter is incremented every T0PR tact.
+    T0CCR = 0;                  // Capture is disabled.
+    T0EMR = 0;                  // No external match output.
+    T0TC = 0;
+    T0MR0 = 1000;
+    T0MCR |= BIT0 + BIT1;
+    T0TCR = BIT0;               // Enable timer 0.
+
+    dINT();                      // Disable all interrupts
+    VICIntEnable = BIT4;          // Enable Interrupthandling for Timer0
+    VICVectCntl3 = 4 + BIT5;      // Assign Timer0 to IRQ Slot 3
+    VICVectAddr3 = (unsigned int)Timer0_IRQHandler;    // Assign Isr Address
+    eINT();
+}
+
+int counter = 0;
+
+void Timer0_IRQHandler(void)
+{
+    extern unsigned int sched_context_switch_request;
+    counter++;
+    T0IR |= 0xff;											// reset timer1 interrupt flag
+    sl_printf("#");
+
+    sched_context_switch_request = 1;
+
+    VICVectAddr = 0;										// acknowledge interrupt (if using VIC IRQ)
+}
+
diff --git a/boards/olimex_lpc2148/tools/lpc2148_flash.gdb b/boards/olimex_lpc2148/tools/lpc2148_flash.gdb
new file mode 100644
index 0000000000000000000000000000000000000000..cb308752aecedf4af6232dd52bb479692fd9eddd
--- /dev/null
+++ b/boards/olimex_lpc2148/tools/lpc2148_flash.gdb
@@ -0,0 +1,22 @@
+#winheight regs 11
+set history save on
+set history size 1000
+target remote localhost:3333
+monitor reset
+monitor sleep 100
+monitor halt
+monitor poll
+#monitor arm7_9 sw_bkpts disable
+#monitor arm7_9 force_hw_bkpts enable
+monitor mww 0xE01FC040 0x0001
+monitor mdw 0xE01FC040
+monitor flash erase_sector 0 0 14
+#monitor flash auto_erase on
+monitor flash erase_check 0
+#monitor flash write_image /home/kaspar/FeuerWhere/src/x/bin/arm.elf
+set remote hardware-watchpoint-limit 2
+load
+break bootloader
+mon soft_reset_halt
+continue
+d b 1
diff --git a/boards/pttu/board_init.c b/boards/pttu/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..18ba75d8504efa10ea24015079b7ce7b0562a49d
--- /dev/null
+++ b/boards/pttu/board_init.c
@@ -0,0 +1,163 @@
+/******************************************************************************
+Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+/**
+ * @ingroup	pttu
+ * @{
+ */
+
+/**
+ * @file
+ * @brief 		PTTU board initialization
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author		Heiko Will
+ * @author		Kaspar Schleiser
+ *
+ */
+#include <board.h>
+#include <VIC.h>
+#include <cpu.h>
+
+#define PCRTC         BIT9
+#define CL_CPU_DIV    4
+
+void bl_init_ports(void)
+{
+    SCS |= BIT0;											// Set IO Ports to fast switching mode
+
+    /* UART0 */
+    PINSEL0 |= BIT4 + BIT6;									// RxD0 and TxD0
+    PINSEL0 &= ~(BIT5 + BIT7);
+
+    /*Turn Board on*/
+    PINMODE0 |= BIT1;
+    FIO0DIR |= BIT27;
+    FIO0CLR = BIT27;
+
+    /* 5V*/
+    FIO1DIR |= BIT28; // Synch
+    FIO1SET = BIT28;  // No Powersave
+
+    FIO1DIR |= BIT27; // 5V off
+    FIO1CLR = BIT27;
+
+    /* Disable Resistors on Buttons */
+    PINMODE4 |= BIT9 + BIT11;
+
+    /* Disable Resistors on LED - and Ports to output*/
+    PINMODE7 |= BIT19 + BIT21;
+    PINMODE2 |= BIT1;
+    FIO1DIR |= BIT0;
+    FIO3DIR |= BIT25 + BIT26;
+    FIO1SET = BIT0;
+    FIO3SET = BIT25 + BIT26;
+
+    // Config and Disable PA
+    FIO1DIR |= BIT25 + BIT26 + BIT22;
+    FIO1SET = BIT26;
+    FIO1CLR = BIT25;
+    FIO1CLR = BIT22; // PA /Shutdown
+    FIO0DIR |= BIT26; // **  // Important: First put this Port as DA 2.0V and then turn on PA!!
+    FIO0SET = BIT26; // **
+
+    // Configure GPS
+    PINMODE3 |= BIT3 + BIT7; // No Pullup on 1.17 & 1.19
+    PINMODE9 |= BIT27 + BIT25; // No Pullup for Uart
+    FIO1DIR |= BIT17;
+    FIO1CLR = BIT17; // Turn off GPS
+    FIO1DIR |= BIT19;
+    FIO1CLR = BIT19; // Hold in Reset
+    PINSEL9 |= BIT24 + BIT25 + BIT26 + BIT27; //4.28 & 4.29 as Uart3
+
+    // Nanotron
+    FIO2DIR &= ~BIT8;	// nanotron uC IRQ as input
+    FIO1DIR |= BIT15;	// nanotron power on reset
+    FIO1DIR &= ~BIT14;	// nanotron uC RESET as input
+    FIO1DIR &= ~BIT10;	// nanotron uC Vcc as input
+    FIO1DIR |= BIT9;	// nanotron ENABLE as output
+    FIO1DIR &= ~BIT4;	// nanotron Rx/Tx as input
+
+    FIO1CLR = BIT15;
+    FIO1CLR = BIT9;		// Enable power
+
+    PINMODE1 |= BIT1;   // No Pullup for CS
+    FIO0DIR |= BIT16;   // CS as output
+    FIO0SET = BIT16;	// drive cs inactive
+    FIO0DIR |= BIT18 + BIT15;   // SPi Output
+
+    // RFID
+    FIO1DIR |= BIT1;    // RFID Power
+    FIO1CLR = BIT1;		//
+
+    FIO0DIR |= BIT1;    // RFID Reset
+    FIO0SET = BIT1;     // Hold in Reset
+
+    FIO0DIR &= ~BIT10;  // LED as INPUT
+    FIO0DIR &= ~BIT11;  // DATA as INPUT
+    PINMODE0 |= BIT19 + BIT21; // No Pullups
+
+    // LTC4150 ARM
+    FIO0DIR |= BIT5;
+    FIO0CLR = BIT5;
+
+    // LTC4150 System
+    FIO0DIR |= BIT24;
+    FIO0CLR = BIT24;
+
+    // Battery Voltage (AD)
+    PINMODE1 |= BIT19;
+    PINSEL1 &= ~BIT19;
+    PINSEL1 |= BIT18;
+
+    //cc1100
+    FIO0DIR |= BIT6 + BIT7 + BIT9;
+    FIO0SET = BIT6;
+    FIO0SET = BIT7 + BIT9;
+
+    //SD
+    FIO2DIR |= BIT12 + BIT13 + BIT11;
+    FIO0DIR |= BIT20 + BIT22 + BIT21;
+
+    //Tetra
+    FIO2DIR |= BIT0 + BIT7;
+
+
+    // No Pullups on any port
+    int nopullup = BIT1 + BIT3 + BIT5 + BIT7 + BIT9 + BIT11 + BIT13 + BIT15 + BIT17 + BIT19 + BIT21 + BIT23 + BIT25 + BIT27 + BIT29 + BIT31;
+    PINMODE0 = nopullup - BIT13 - BIT15 - BIT17 - BIT19;
+    PINMODE1 = BIT1 + BIT3 + BIT5 + BIT7 + BIT9 + BIT11 + BIT13 + BIT15 + BIT17 + BIT19 + BIT21;
+    PINMODE2 = nopullup;
+    PINMODE3 = nopullup;
+    PINMODE4 = nopullup;
+    PINMODE5 = nopullup;
+    PINMODE6 = nopullup;
+    PINMODE7 = nopullup;
+    PINMODE8 = nopullup;
+    PINMODE9 = nopullup;
+}
+
+/** @} */
diff --git a/boards/pttu/include/board.h b/boards/pttu/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba7b3f42bfedd2c59365351854e8edb775ffb907
--- /dev/null
+++ b/boards/pttu/include/board.h
@@ -0,0 +1,58 @@
+/******************************************************************************
+Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
+
+These sources were developed at the Freie Universitaet Berlin, Computer Systems
+and Telematics group (http://cst.mi.fu-berlin.de).
+-------------------------------------------------------------------------------
+This file is part of FeuerWare.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+FeuerWare is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program.  If not, see http://www.gnu.org/licenses/ .
+--------------------------------------------------------------------------------
+For further information and questions please use the web site
+	http://scatterweb.mi.fu-berlin.de
+and the mailinglist (subscription via web site)
+	scatterweb@lists.spline.inf.fu-berlin.de
+*******************************************************************************/
+
+#ifndef __BOARD_H
+#define __BOARD_H
+
+/**
+ * @ingroup		pttu
+ * @{
+ */
+
+/**
+ * @file
+ * @brief		PTTU Board
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author		Kaspar Schleiser <kaspar@schleiser.de>
+ * @version     $Revision$
+ *
+ * @note		$Id: board.h 664 2009-02-19 10:54:44Z baar $
+ */
+
+#include <lpc2387.h>
+#include <cpu-conf.h>
+
+#define VICIntEnClear VICIntEnClr
+
+void init_clks1(void);
+void init_clks2(void);
+void bl_init_clks(void);
+
+typedef uint8_t radio_packet_length_t;
+
+/** @} */
+#endif // __BOARD_H
diff --git a/boards/pttu/tools/jtag.txt b/boards/pttu/tools/jtag.txt
new file mode 100644
index 0000000000000000000000000000000000000000..586eea6745c66fdf7719e9e782ad8f84553b897d
--- /dev/null
+++ b/boards/pttu/tools/jtag.txt
@@ -0,0 +1,14 @@
+compile openocd release v0.1:
+[extract to somewhere]
+./configure --prefix=CHANGEMEtowhatever --enable-ft2232_libftdi
+make
+make install
+
+to flash run from within board/pttu/tools:
+./openocd-pttu.sh olimex-usb-jtag-tiny-a "mt_flash CHANGEME/absolute/path/to/hexfile/pttu.hex;shutdown"
+
+
+to debug, first start the following from within board/pttu/tools:
+./openocd-pttu.sh olimex-usb-jtag-tiny-a
+
+then just run "jam debug". this will flash bin/pttu.hex, run it and stop at the bootloader.
diff --git a/boards/pttu/tools/olimex-arm-usb-ocd.cfg b/boards/pttu/tools/olimex-arm-usb-ocd.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..0aaba1d2bb57975b7f58b40d5ee1923282d06e6b
--- /dev/null
+++ b/boards/pttu/tools/olimex-arm-usb-ocd.cfg
@@ -0,0 +1,9 @@
+# 
+set CPUTAPID 0x4f1f0f0f
+
+jtag_speed 100
+
+source [find interface/olimex-arm-usb-ocd.cfg]
+#source [find target/lpc2148.cfg]
+source lpc2378.cfg
+
diff --git a/boards/pttu/tools/openocd-pttu.cfg b/boards/pttu/tools/openocd-pttu.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..b58392f1ee7ee95bad83af8e4ac2549d0d1d4125
--- /dev/null
+++ b/boards/pttu/tools/openocd-pttu.cfg
@@ -0,0 +1,75 @@
+######
+# parts taken from Martin Thomas
+# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html
+#
+
+set CPUTAPID 0x4f1f0f0f
+jtag_speed 100
+
+source [find cpu/lpc2387/tools/openocd-lpc2387.cfg]
+
+fast disable
+
+#
+# scipts/macros/user commands - this is TCL (variant JIM):
+#
+proc mt_internal_rc {} {
+     jtag_khz 100
+     reset run
+     sleep 100
+     reset
+     halt
+     wait_halt 2
+     # PLL disconnect PLLCON
+     mww 0xE01FC080 0x01 
+     mww 0xE01FC08C 0xAA 
+     mww 0xE01FC08C 0x55 
+     # PLL disable PLLCON
+     mww 0xE01FC080 0x00 
+     mww 0xE01FC08C 0xAA 
+     mww 0xE01FC08C 0x55 
+     # no prescaler CCLKCFG
+     mww 0xE01FC104 0x00
+     #  internal RC CLKSRCSEL
+     mww 0xE01FC10C 0x00 
+     #### main oscil. CLKSRCSEL
+     #### mww 0xE01FC10C 0x01
+     # remap to internal flash
+     mww 0xE01FC040 0x01 
+     sleep 100 
+     jtag_khz 500
+     flash probe 0 
+}
+
+proc mt_flash_bin {IMGFILE OFFSET} {
+     mt_internal_rc
+     flash write_image erase $IMGFILE $OFFSET
+     sleep 100 
+     verify_image $IMGFILE $OFFSET
+     sleep 100 
+}
+
+proc mt_flash_v {IMGFILE} {
+     mt_internal_rc
+     flash write_image erase $IMGFILE
+     sleep 100 
+     verify_image $IMGFILE
+     sleep 100
+}
+
+proc mt_flash {IMGFILE} {
+     mt_internal_rc
+     flash write_image erase $IMGFILE
+}
+
+flash bank lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 4000 calc_checksum
+
+arm7_9 dcc_downloads enable 
+
+gdb_flash_program enable
+
+init
+
+fast enable
+jtag_khz 500
+debug_level 1
diff --git a/boards/pttu/tools/openocd-pttu.sh b/boards/pttu/tools/openocd-pttu.sh
new file mode 100755
index 0000000000000000000000000000000000000000..95f11fa14818e62fde70a3c5d78c9ff601224817
--- /dev/null
+++ b/boards/pttu/tools/openocd-pttu.sh
@@ -0,0 +1,30 @@
+#/bin/bash
+
+if [ $# -le 0 ]; then
+	echo "usage: $0 [openocd interface name] [openocd args]" >&2
+	echo "	common interfaces: olimex-arm-usb-ocd olimex-jtag-tiny olimex-jtag-tiny-a"
+	echo ""
+	echo "using default olimex-jtag-tiny-a"
+	INTERFACE=olimex-jtag-tiny-a
+else
+	INTERFACE=$1
+	shift
+fi
+
+if [ $# -ge 1 ]; then
+	COMMAND=$@
+else
+	COMMAND="debug_level 1"
+fi
+
+if [ "${OS}" = "Windows_NT" ]; then
+	WINDOWS=1
+fi
+
+if [ "x${WINDOWS}x" = "xx" ]; then
+	xterm -e "openocd -s ../../.. -f interface/${INTERFACE}.cfg -f board/pttu/tools/openocd-pttu.cfg -c \"${COMMAND}\"|| read" &
+else
+	echo ${COMMAND}
+	#cmd /C start "OpenOCD PTTU using ${INTERFACE}"
+	openocd-ftd2xx.exe -s ../../.. -f interface/${INTERFACE}.cfg -f board/pttu/tools/openocd-pttu.cfg -c "${COMMAND}"
+fi
diff --git a/boards/pttu/tools/pttu_debug.gdb b/boards/pttu/tools/pttu_debug.gdb
new file mode 100644
index 0000000000000000000000000000000000000000..2c8ec0df14c97ddb740387d196037cdb66ce7242
--- /dev/null
+++ b/boards/pttu/tools/pttu_debug.gdb
@@ -0,0 +1,15 @@
+#winheight regs 11
+set history save on
+set history size 1000
+target remote localhost:3333 
+monitor mt_internal_rc
+load
+compare-sections
+monitor soft_reset_halt
+set mem inaccessible-by-default off
+monitor debug_level 0
+
+break bootloader
+continue
+d b 1
+
diff --git a/boards/redbee-econotag/Makefile b/boards/redbee-econotag/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8b1d55d8b49553aff11168c1f643b96f17292bca
--- /dev/null
+++ b/boards/redbee-econotag/Makefile
@@ -0,0 +1,32 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+export ARCH = redbee-econotag_base.a
+
+INCLUDES += -I$(RIOTBOARD)/redbee-econotag/drivers/include
+INCLUDES += -I$(RIOTBASE)/cpu/arm_common/include
+INCLUDES += -I$(RIOTBASE)/cpu/mc1322x/include
+
+.PHONY: $(BINDIR)/$(ARCH)
+
+all: $(BINDIR)$(ARCH)
+	$(MAKE) -C drivers
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(CFLAGS_MTHUMB) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(CFLAGS_MTHUMB) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	${MAKE} -C drivers clean
+	rm -f $(OBJ) $(DEP)
+
diff --git a/boards/redbee-econotag/Makefile.dep b/boards/redbee-econotag/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/boards/redbee-econotag/Makefile.include b/boards/redbee-econotag/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..19179c3c2d4b7b9b59da5f3ba53f33469ec11288
--- /dev/null
+++ b/boards/redbee-econotag/Makefile.include
@@ -0,0 +1,29 @@
+## the cpu to build for
+export CPU = mc1322x
+
+# toolchain config
+export PREFIX = @arm-none-eabi-
+export CC = @$(PREFIX)gcc
+export AR = @$(PREFIX)ar
+export CFLAGS = -std=gnu99 -march=armv4t -mtune=arm7tdmi-s -mlong-calls \
+		-msoft-float -mthumb-interwork -fno-strict-aliasing -fno-common \
+		-ffixed-r8 -ffunction-sections -ffreestanding -fno-builtin \
+		-nodefaultlibs -Wcast-align -Wall -Wstrict-prototypes -Wextra \
+		-Os -pipe 
+export CFLAGS_MTHUMB ?= -mthumb
+$(warning TODO add -mthumb)
+export AFLAGS = -Wa,-gstabs $(CFLAGS)
+export AS = $(PREFIX)as
+export LINK = $(PREFIX)gcc
+export SIZE = $(PREFIX)size
+export OBJCOPY = $(PREFIX)objcopy
+FLASHER = mc1322x-load.pl
+TERM = pyterm.py
+LINKFLAGS = -mcpu=arm7tdmi-s -static -lgcc -nostartfiles -T$(RIOTBASE)/cpu/$(CPU)/mc1322x.lds
+
+ifeq ($(strip $(PORT)),)
+	export PORT = /dev/ttyUSB0
+endif
+export HEXFILE = bin/$(PROJECT).hex
+export FFLAGS = -t $(PORT) -f $(HEXFILE) -c 'bbmc -l redbee-econotag reset'
+export OFLAGS = -O binary --gap-fill=0xff
diff --git a/boards/redbee-econotag/README b/boards/redbee-econotag/README
new file mode 100644
index 0000000000000000000000000000000000000000..7cce0fdd0536ab9f6da6205048dc66f544f02f12
--- /dev/null
+++ b/boards/redbee-econotag/README
@@ -0,0 +1,11 @@
+Flashing:
+tools/mc1322x-load.pl -f <path/to/binary> -t /dev/<tty-device>
+
+more information: https://github.com/malvira/libmc1322x/wiki/libmc1322x#loading-images-to-ram-with-mc1322x-loadpl
+
+Erase:
+cd tools/ftditools/
+make
+./bbmc -l redbee-econotag erase
+
+more information: https://github.com/malvira/libmc1322x/wiki/bbmc
\ No newline at end of file
diff --git a/boards/redbee-econotag/board_init.c b/boards/redbee-econotag/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..18ac6c376ca274dcc134719402458f1dea0034c7
--- /dev/null
+++ b/boards/redbee-econotag/board_init.c
@@ -0,0 +1,22 @@
+/*
+ * board_init.c - redbee-econotag initialization code
+ * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+ *
+ * This source code is licensed under the GNU Lesser General Public License,
+ * Version 2.  See the file LICENSE for more details.
+ */
+
+void board_init(void)
+{
+    asm("nop");
+}
+
+void bl_init_clks(void)
+{
+    // dummy to compile
+}
+
+void bl_init_ports(void)
+{
+    // dummy to compile
+}
diff --git a/boards/redbee-econotag/drivers/Makefile b/boards/redbee-econotag/drivers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..cec1080b6473e4ee8725ae44831955e40be2eeb7
--- /dev/null
+++ b/boards/redbee-econotag/drivers/Makefile
@@ -0,0 +1,26 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBASE)/sys/include/
+
+.PHONY: redbee-econotag_drivers.a
+
+$(BINDIR)redbee-econotag_common_drivers.a: $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(CFLAGS_MTHUMB) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(CFLAGS_MTHUMB) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+
+clean:
+	rm -f $(OBJ) $(DEP)
+
diff --git a/boards/redbee-econotag/drivers/include/nvm.h b/boards/redbee-econotag/drivers/include/nvm.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a8c72bfebeff2fdb57bfab57f8e9d7905e8ffa3
--- /dev/null
+++ b/boards/redbee-econotag/drivers/include/nvm.h
@@ -0,0 +1,58 @@
+/*
+ * nvm.h - non-volatile memory specific definitions
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 3.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#ifndef NVM_H
+#define NVM_H
+
+#include <stdint.h>
+
+typedef enum
+{
+        g_nvm_type_no_nvm_c = 0,
+        g_nvm_type_SST_c,
+        g_nvm_type_ST_c,
+        g_nvm_type_ATM_c,
+        g_nvm_type_Max_c
+} nvm_type_t;
+
+
+typedef enum
+{
+        g_nvm_err_no_error_c = 0,
+        g_nvm_err_invalid_interface_c,
+        g_nvm_err_onvalid_nvm_type_c,
+        g_nvm_err_invalid_pointer_c,
+        g_nvm_err_write_protect_c,
+        g_nvm_err_verify_error_c,
+        g_nvm_err_address_space_overflow_c,
+        g_nvm_err_blank_check_error_c,
+        g_nvm_err_restricted_area_c,
+        g_nvm_err_max_error_c
+} nvm_err_t;
+
+typedef enum
+{
+        g_nvm_internal_interface_c = 0,
+        g_nvm_external_interface_c,
+        g_nvm_interface_max_c
+} nvm_interface_t;
+
+/* ROM code seems to be THUMB */
+/* need to be in a THUMB block before calling them */
+extern nvm_err_t (*nvm_detect)(nvm_interface_t nvm_interface,nvm_type_t* p_nvm_type);
+extern nvm_err_t (*nvm_read)(nvm_interface_t nvm_interface , nvm_type_t nvm_type , void *p_dest, uint32_t address, uint32_t num_bytes);
+extern nvm_err_t (*nvm_write)(nvm_interface_t nvm_interface, nvm_type_t nvm_type ,void *p_src, uint32_t address, uint32_t num_bytes);
+/* sector bit field selects which sector to erase */
+/* SST flash has 32 sectors 4096 bytes each */
+/* bit 0 is the first sector, bit 31 is the last */
+extern nvm_err_t (*nvm_erase)(nvm_interface_t nvm_interface, nvm_type_t nvm_type ,uint32_t sector_bitfield);
+extern void(*nvm_setsvar)(uint32_t zero_for_awesome);
+
+#endif //NVM_H
diff --git a/boards/redbee-econotag/drivers/include/uart.h b/boards/redbee-econotag/drivers/include/uart.h
new file mode 100644
index 0000000000000000000000000000000000000000..252bca811b813044752e2078a0fdad9fc2e21b4f
--- /dev/null
+++ b/boards/redbee-econotag/drivers/include/uart.h
@@ -0,0 +1,105 @@
+/*
+ * uart.h - UART driver for redbee
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU Lesser General Public License,
+ * Version 2.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#ifndef UART_H
+#define UART_H
+
+#include <stdint.h>
+
+/*-----------------------------------------------------------------*/
+/* UART */
+#define UART1_BASE      (0x80005000)
+#define UART2_BASE      (0x8000B000)
+
+struct UART_struct {
+    union {
+        uint32_t CON;
+        struct UART_CON {
+            uint32_t TXE: 1;        /*< Tx Enable */
+            uint32_t RXE: 1;        /*< Rx Enable */
+            uint32_t PEN: 1;        /*< Parity Enable */
+            uint32_t EP: 1;         /*< Even Parity (1=Odd, 0=Even) */
+            uint32_t ST2: 1;        /*< Enable 2 Stop Bits */
+            uint32_t SB: 1;         /*< Send Break */
+            uint32_t CONTX: 1;      /*< Continuous Tx (Test Mode) */
+            uint32_t TXOENB: 1;     /*< TXD Outbut Disable */
+            uint32_t : 2;           /*< reserved */
+            uint32_t XTIM: 1;       /*< Times of Oversampling */
+            uint32_t FCP: 1;        /*< Flow Control Polarity */
+            uint32_t FCE: 1;        /*< Flow Control Enable */
+            uint32_t MTXR: 1;       /*< enable/disable TxRDY Interrupts */
+            uint32_t MRXR: 1;       /*< enable/disable RxRDY Interrupts */
+            uint32_t TST: 1;        /*< Test Loop-Back */
+            uint32_t : 16;          /*< reserved */
+        } CONbits;
+    };
+    union {
+        uint32_t STAT;
+        struct UART_STAT {
+            uint32_t SE: 1;         /*< Start Bit Error */
+            uint32_t PE: 1;         /*< Parity Bit Error */
+            uint32_t FE: 1;         /*< Frame/Stop Bit Error */
+            uint32_t TOE: 1;        /*< Tx FIFO Overrun Error */
+            uint32_t ROE: 1;        /*< Rx FIFO Overrun Error */
+            uint32_t RUE: 1;        /*< Rx FIFO Underrun Error */
+            uint32_t RXRDY: 1;      /*< Receiver is causing Interrupts */
+            uint32_t TXRDY: 1;      /*< Transmitter is causing Interrupts */
+            uint32_t : 24;
+        } USTATbits;
+    };
+    union {
+        uint32_t DATA;
+        struct UART_DATA {
+            uint32_t DATA: 8;
+            uint32_t : 24;
+        } DATAbits;
+    };
+    union {
+        uint32_t RXCON;
+        struct UART_URXCON {
+            uint32_t LVL: 6;
+            uint32_t : 26;
+        } RXCONbits;
+    };
+    union {
+        uint32_t TXCON;
+        struct UART_TXCON {
+            uint32_t LVL: 6;
+            uint32_t : 26;
+        } TXCONbits;
+    };
+    union {
+        uint32_t CTS;
+        struct UART_CTS {
+            uint32_t LVL: 5;
+            uint32_t : 27;
+        } CTSbits;
+    };
+    
+    uint32_t BR;                    /*< BR is 32bit access only */
+};
+
+static volatile struct UART_struct *const UART1 = (void *)(UART1_BASE);
+static volatile struct UART_struct *const UART2 = (void *)(UART2_BASE);
+
+void uart_init(volatile struct UART_struct *uart, uint32_t baud);
+void uart_set_baudrate(volatile struct UART_struct *uart, uint32_t baud);
+void uart_flow_ctl(volatile struct UART_struct *uart, uint8_t on);
+
+
+#define UART0_BUFSIZE (32)
+
+void uart1_putc(uint8_t c);
+uint8_t uart1_getc(void);
+
+void uart2_putc(uint8_t c);
+uint8_t uart2_getc(void);
+
+#endif
\ No newline at end of file
diff --git a/boards/redbee-econotag/drivers/nvm.c b/boards/redbee-econotag/drivers/nvm.c
new file mode 100644
index 0000000000000000000000000000000000000000..5d4538ef264e75c3d14940699369d780b885fdb7
--- /dev/null
+++ b/boards/redbee-econotag/drivers/nvm.c
@@ -0,0 +1,22 @@
+/*
+ * nvm.c - non-volatile memory implementations
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 3.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#include "nvm.h"
+
+nvm_err_t (*nvm_detect) (nvm_interface_t nvm_interface, nvm_type_t* p_nvm_type) 
+                        = (void*) 0x00006cb9;
+nvm_err_t (*nvm_read)   (nvm_interface_t nvm_interface, nvm_type_t nvm_type, void *p_dest, uint32_t address, uint32_t num_bytes) 
+                        = (void*) 0x00006d69;
+nvm_err_t (*nvm_write)  (nvm_interface_t nvm_interface, nvm_type_t nvm_type, void *p_src, uint32_t address, uint32_t numb_bytes)
+                        = (void*) 0x00006ec5;
+nvm_err_t (*nvm_erase)  (nvm_interface_t nvm_interface, nvm_type_t nvm_type, uint32_t sector_bitfield)
+                        = (void*) 0x00006e05;
+void (*nvm_sets_var)    (uint32_t zero_is_for_winners)
+                        = (void*) 0x00007085;
\ No newline at end of file
diff --git a/boards/redbee-econotag/drivers/redbee_uart.c b/boards/redbee-econotag/drivers/redbee_uart.c
new file mode 100644
index 0000000000000000000000000000000000000000..cdeb62bc98ada02200b92e913ef8c12ebaa0ce7c
--- /dev/null
+++ b/boards/redbee-econotag/drivers/redbee_uart.c
@@ -0,0 +1,185 @@
+/*
+ * redbee_uart.c - UART driver for redbee
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU Lesser General Public License,
+ * Version 2.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#include "mc1322x.h"
+#include "uart.h"
+#include "gpio.h"
+
+#define MOD_ 9999
+#define CLK_ 24000000
+#define DIV_ 16 /* uart->CON.XTIM = 0 is 16x oversample (datasheet is incorrect) */
+#define BAUTRATE_UART1 115200
+#define BAUTRATE_UART2 115200
+
+void uart_set_baudrate(volatile struct UART_struct *uart, uint32_t baudrate)
+{
+    uint64_t inc = 0;
+
+    /* calculate inc following equation 13-1 from datasheet */
+    /* multiply by another 10 to get a fixed point*/
+    inc = ((uint64_t) baudrate * DIV_ * MOD_ * 10 / CLK_) - 10;
+    /* add 5 and div by 10 to get a proper rounding */
+    inc = (inc + 5) / 10; 
+
+    /* disable UARTx to set baudrate */
+    uart->CONbits.TXE = 0;
+    uart->CONbits.RXE = 0;
+
+    /* set baudrate */
+    /* BR register is 32bit access only */
+    uart->BR = (((uint16_t) inc << 16) | MOD_);
+
+    /* reenable UARTx again */
+    /* uart->CON.XTIM = 0 is 16x oversample (datasheet is incorrect) */
+    uart->CONbits.XTIM = 0;
+    uart->CONbits.TXE = 1;
+    uart->CONbits.RXE = 1;
+}
+
+void uart_flow_ctl(volatile struct UART_struct *uart, uint8_t on)
+{
+    if (on) {
+        /* enable flow control */
+        if (uart == UART1) {
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_SET.U1CTS = 1;
+            GPIO->PAD_DIR_RESET.U1RTS = 1;
+            /* function select to uart */
+            GPIO->FUNC_SEL.U1CTS = 1;
+            GPIO->FUNC_SEL.U1RTS = 1;
+        }
+        else {
+            /* UART2 */
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_SET.U2CTS = 1;
+            GPIO->PAD_DIR_RESET.U2RTS = 1;
+            /* function select to uart */
+            GPIO->FUNC_SEL.U2CTS = 1;
+            GPIO->FUNC_SEL.U2RTS = 1;
+        }
+
+        /* enable flow control */
+        uart->CONbits.FCE = 1;
+    }
+    else {
+        /* disable flow control */
+        uart->CONbits.FCE = 0;
+
+        if (uart == UART1) {
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_RESET.U1CTS = 1;
+            GPIO->PAD_DIR_RESET.U1RTS = 1;
+            /* function select to GPIO */
+            GPIO->FUNC_SEL.U1CTS = 3;
+            GPIO->FUNC_SEL.U1RTS = 3;
+        }
+        else {
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_RESET.U2CTS = 1;
+            GPIO->PAD_DIR_RESET.U2RTS = 1;
+            /* function select to GPIO */
+            GPIO->FUNC_SEL.U2CTS = 3;
+            GPIO->FUNC_SEL.U2RTS = 3;
+        }
+    }
+}
+
+void uart_init(volatile struct UART_struct *uart, uint32_t baudrate)
+{
+    /* enable the uart so we can set the gpio mode */
+    /* has to be enabled before setting the function with GPIO->FUNC_SEL */
+    uart->CONbits.TXE = 1;
+    uart->CONbits.RXE = 1;
+
+    if (uart == UART1) {
+        /* TX and RX direction */
+        GPIO->PAD_DIR_SET.U1TX = 1;
+        GPIO->PAD_DIR_RESET.U1RX = 1;
+
+        /* set function selection to UART */
+        GPIO->FUNC_SEL.U1TX = 1;
+        GPIO->FUNC_SEL.U1RX = 1;
+
+        UART1->CONbits.TXE = 1;          /*< enable transmit */
+        UART1->CONbits.RXE = 1;          /*< enable receive */
+
+        UART1->CONbits.FCE = 1;          /*< enable flowcontrol */
+        UART1->CONbits.MRXR = 1;         /*< disable Rx interrupt */
+        UART1->CTSbits.LVL = 31;         /*< drop cts when tx buffer at trigger level */
+        GPIO->FUNC_SEL.U1CTS = 1;        /*< set GPIO 16 to UART1 CTS */
+        GPIO->FUNC_SEL.U1RTS = 1;        /*< set GPIO 17 to UART1 RTS */
+
+        ITC->INTENABLEbits.UART1 = 1;
+
+    }
+    else {
+        /* UART2 */
+        /* TX and RX direction */
+        GPIO->PAD_DIR_SET.U2TX = 1;
+        GPIO->PAD_DIR_RESET.U2RX = 1;
+
+        /* set function selection to UART */
+        GPIO->FUNC_SEL.U2TX = 1;
+        GPIO->FUNC_SEL.U2RX = 1;
+
+        UART2->CONbits.TXE = 1;          /*< enable transmit */
+        UART2->CONbits.RXE = 1;          /*< enable receive */
+
+        UART2->CONbits.FCE = 1;          /*< enable flowcontrol */
+        UART2->CONbits.MRXR = 1;         /*< disable Rx interrupt */
+        UART2->CTSbits.LVL = 31;         /*< drop cts when tx buffer at trigger level */
+        GPIO->FUNC_SEL.U2CTS = 1;        /*< set GPIO 20 to UART2 CTS */
+        GPIO->FUNC_SEL.U2RTS = 1;        /*< set GPIO 21 to UART2 RTS */
+
+        ITC->INTENABLEbits.UART2 = 1;
+    }
+
+    uart_set_baudrate(uart, baudrate);
+
+}
+
+static inline uint32_t uart0_puts(uint8_t *astring, uint32_t length)
+{
+    uint32_t i = 0;
+
+    for (; i < length; i++) {
+        uart1_putc(astring[i]);
+    }
+
+    return i;
+}
+
+void stdio_flush(void)
+{
+    ITC->INTENABLEbits.UART1 = 0;
+    ITC->INTENABLEbits.UART2 = 0;
+
+    while (UART1->RXCON != 0 || UART2->RXCON != 0) {
+        UART1->DATA;
+        UART2->DATA;
+    }
+    while (UART1->TXCON != 0 || UART2->TXCON != 0) {
+        /* wait */
+    }
+
+    ITC->INTENABLEbits.UART1 = 1;
+    ITC->INTENABLEbits.UART2 = 1;
+}
+
+
+int fw_puts(char *astring, int length)
+{
+    return uart0_puts((uint8_t *) astring, (uint32_t) length);
+}
+
+int bl_uart_init(void)
+{
+    uart_init(UART1, BAUTRATE_UART1);
+}
\ No newline at end of file
diff --git a/boards/redbee-econotag/drivers/redbee_uart1.c b/boards/redbee-econotag/drivers/redbee_uart1.c
new file mode 100644
index 0000000000000000000000000000000000000000..690d13d381a1aed049ce7d8e6f5b84905302e50b
--- /dev/null
+++ b/boards/redbee-econotag/drivers/redbee_uart1.c
@@ -0,0 +1,58 @@
+/*
+ * uart1.c - UART1 driver for redbee
+ * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+ *               2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU Lesser General Public License,
+ * Version 2.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#include "mc1322x.h"
+#include "board_uart0.h"
+#include "uart.h"
+
+void uart1_isr(void)
+{
+    uint32_t i = 0;
+
+    if (UART1->USTATbits.RXRDY == 1) {
+#ifdef MODULE_UART0
+
+        if (uart0_handler_pid) {
+            while (UART1->RXCON != 0) {
+                uart0_handle_incoming(UART1->DATA);
+
+                if (++i >= UART0_BUFSIZE) {
+                    uart0_notify_thread();
+                    i = 0;
+                }
+            }
+
+            uart0_notify_thread();
+        }
+
+#endif
+    }
+}
+
+void uart1_putc(uint8_t c)
+{
+    /* while uart fifo is full */
+    while (UART1->TXCON == 0) {
+        /* wait */
+    }
+
+    UART1->DATA = c;
+}
+
+uint8_t uart1_getc(void)
+{
+    /* while uart fifo is empty */
+    while (UART1->RXCON == 0) {
+        /* wait */
+    }
+
+    return UART1->DATA;
+}
\ No newline at end of file
diff --git a/boards/redbee-econotag/drivers/redbee_uart2.c b/boards/redbee-econotag/drivers/redbee_uart2.c
new file mode 100644
index 0000000000000000000000000000000000000000..013d42415906ab1e7dd125e5b585839900a6e747
--- /dev/null
+++ b/boards/redbee-econotag/drivers/redbee_uart2.c
@@ -0,0 +1,58 @@
+/*
+ * uart1.c - UART1 driver for redbee
+ * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+ *               2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU Lesser General Public License,
+ * Version 2.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#include "mc1322x.h"
+#include "board_uart0.h"
+#include "uart.h"
+
+void uart2_isr(void)
+{
+    uint32_t i = 0;
+
+    if (UART2->USTATbits.RXRDY == 1) {
+#ifdef MODULE_UART0
+
+        if (uart0_handler_pid) {
+            while (UART2->RXCON != 0) {
+                uart0_handle_incoming(UART2->DATA);
+
+                if (++i >= UART0_BUFSIZE) {
+                    uart0_notify_thread();
+                    i = 0;
+                }
+            }
+
+            uart0_notify_thread();
+        }
+
+#endif
+    }
+}
+
+void uart2_putc(uint8_t c)
+{
+    /* while uart fifo is full */
+    while (UART2->TXCON == 0) {
+        /* wait */
+    }
+
+    UART2->DATA = c;
+}
+
+uint8_t uart2_getc(void)
+{
+    /* while uart fifo is empty */
+    while (UART2->RXCON == 0) {
+        /* wait */
+    }
+
+    return UART2->DATA;
+}
\ No newline at end of file
diff --git a/boards/redbee-econotag/include/board.h b/boards/redbee-econotag/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbcb2b07d329485707a53116f96bf8650bb781db
--- /dev/null
+++ b/boards/redbee-econotag/include/board.h
@@ -0,0 +1,17 @@
+/**
+  * board.h - redbee-econotag Board.
+  * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+  *
+  * This source code is licensed under the GNU Lesser General Public License,
+  * Version 2.  See the file LICENSE for more details.
+  */
+
+#ifndef REDBEE_ECONOTAG_BOARD_H
+#define REDBEE_ECONOTAG_BOARD_H
+
+#define CTUNE 		0xb
+#define IBIAS 		0x1f
+#define FTUNE		0x7
+
+#endif
+
diff --git a/boards/redbee-econotag/tools/ftditools/Makefile b/boards/redbee-econotag/tools/ftditools/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..521d7d14ff292bdadb245ce797f70ca696843a97
--- /dev/null
+++ b/boards/redbee-econotag/tools/ftditools/Makefile
@@ -0,0 +1,17 @@
+INSTALL= /usr/local/bin
+
+################
+
+LDLIBS = -lftdi
+
+TARGETS = bbmc
+
+CFLAGS = -Wall -Wextra #-Werror
+
+all: $(TARGETS)
+
+clean:
+	-rm -f $(TARGETS)
+
+install: all
+	cp bbmc $(INSTALL)
\ No newline at end of file
diff --git a/boards/redbee-econotag/tools/ftditools/bbmc.c b/boards/redbee-econotag/tools/ftditools/bbmc.c
new file mode 100644
index 0000000000000000000000000000000000000000..f211f52eee9c2aa189007e3951c44b89acabc11c
--- /dev/null
+++ b/boards/redbee-econotag/tools/ftditools/bbmc.c
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
+ * to the MC1322x project (http://mc1322x.devl.org)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ *
+ * This file is part of libmc1322x: see http://mc1322x.devl.org
+ * for details.
+ *
+ *
+ */
+
+/* control reset and VREF2 lines */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <ftdi.h>
+
+#define DEBUG 0
+
+#define low(x)  (1 << x)
+#define high(x) (1 << (x + 8))
+
+#define REDBEE_ECONOTAG_RESET    high(2)
+#define REDBEE_ECONOTAG_VREF2L   high(7)
+#define REDBEE_ECONOTAG_VREF2H   high(6)
+#define REDBEE_ECONOTAG_INTERFACE INTERFACE_A
+
+#define REDBEE_USB_RESET    high(2)
+#define REDBEE_USB_VREF2L   low(5)
+#define REDBEE_USB_VREF2H   low(6)
+#define REDBEE_USB_INTERFACE INTERFACE_B
+
+#define FLEXIBITY_USB_RESET    high(2)
+#define FLEXIBITY_USB_VREF2L   high(7)
+#define FLEXIBITY_USB_VREF2H   high(6)
+#define FLEXIBITY_USB_INTERFACE INTERFACE_A
+
+#define BOARD REDBEE_USB
+
+#define STR(x)         #x
+#define STR2(x)        STR(x)
+#define CAT(x,y)       x##y
+#define CAT2(x, y, z)  x##y##z
+
+#define dir(x)            ( CAT(x,_RESET) | CAT(x,_VREF2L) | CAT(x,_VREF2H))
+#define interface(x)      ( CAT(x,_INTERFACE) )
+#define reset_release(x)  ( CAT(x,_RESET)     )
+#define reset_set(x)      ( 0 )
+#define vref2_normal(x)   ( CAT(x,_VREF2H)    )
+#define vref2_erase(x)    ( CAT(x,_VREF2L)    )
+
+/* fgets input buffer length: for prompts and such */
+#define BUF_LEN 32
+
+struct layout {
+    char *name;
+    char *desc;
+    enum ftdi_interface interface;
+    uint16_t dir;
+    uint16_t reset_release;
+    uint16_t reset_set;
+    uint16_t vref2_normal;
+    uint16_t vref2_erase;
+};
+
+int print_and_prompt(struct ftdi_device_list *devlist);
+int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val);
+void reset(struct ftdi_context *ftdic, const struct layout *l);
+void erase(struct ftdi_context *ftdic, const struct layout *l);
+void usage(void);
+
+#define std_layout(x)                        \
+	.interface = interface(x),           \
+        .dir = dir(x),	                     \
+	.reset_release = reset_release(x),   \
+	.reset_set = reset_set(x),	     \
+	.vref2_normal = vref2_normal(x),     \
+	.vref2_erase = vref2_erase(x),
+
+static struct layout layouts[] = {
+    {
+        .name = "redbee-econotag",
+        .desc = "Redbee Econotag",
+        std_layout(REDBEE_ECONOTAG)
+    },
+    {
+        .name = "redbee-usb",
+        .desc = "Redbee USB stick",
+        std_layout(REDBEE_USB)
+    },
+    {
+        .name = "flexibity",
+        .desc = "Flexibity USB Interface",
+        std_layout(FLEXIBITY_USB)
+    },
+    { .name = NULL, /* end of table */ },
+};
+
+struct command {
+    char *name;
+    char *desc;
+    void (*cmd)(struct ftdi_context *ftdic, const struct layout *l);
+};
+
+static const struct command commands[] = {
+    {
+        .name = "reset",
+        .desc = "Toggles reset pin",
+        .cmd = reset,
+    },
+    {
+        .name = "erase",
+        .desc = "Sets VREF2 erase mode; toggles reset; waits 2 sec.; sets normal; toggles reset again",
+        .cmd = erase,
+    },
+    { .name = NULL, /* end of table */ },
+};
+
+struct layout *find_layout(char *str)
+{
+    uint32_t i = 0;
+
+    while (layouts[i].name != NULL) {
+        if (strcmp(layouts[i].name, str) == 0) {
+            return &layouts[i];
+        }
+
+        i++;
+    }
+
+    return NULL;
+}
+
+static uint32_t vendid = 0x0403;
+uint32_t prodid = 0x6010;
+
+#if __APPLE__
+static void restore_ftdi_kext(void)
+{
+    system("sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext");
+}
+#endif
+
+int main(int argc, char **argv)
+{
+    struct ftdi_context ftdic;
+    struct ftdi_device_list *devlist;
+    int dev_index = -1;
+    int num_devs;
+    char layout_str[BUF_LEN];
+    struct layout layout;
+    struct layout *l = NULL;
+    int i, ret;
+
+    /* overrides for layout parameters */
+    int interface      = -1;
+    int dir            = -1;
+    int reset_release  = -1;
+    int reset_set      = -1;
+    int vref2_normal   = -1;
+    int vref2_erase    = -1;
+
+    layout.name = NULL;
+
+    while (1) {
+        int c;
+        int option_index = 0;
+        static struct option long_options[] = {
+            {"layout",        required_argument, 0, 'l'},
+            {"index",         required_argument, 0, 'i'},
+            {"vendor",        required_argument, 0, 'v'},
+            {"product",       required_argument, 0, 'p'},
+            {"dir",           required_argument, 0,  0 },
+            {"reset_release", required_argument, 0,  0 },
+            {"reset_set",     required_argument, 0,  0 },
+            {"vref2_normal",  required_argument, 0,  0 },
+            {"vref2_erase",   required_argument, 0,  0 },
+            {"interface",     required_argument, 0,  0 },
+            {"help",          no_argument,       0, '?'},
+            {0, 0, 0, 0}
+        };
+
+        c = getopt_long(argc, argv, "i:l:v:p:",
+                        long_options, &option_index);
+
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+                /* process long opts */
+            case 0:
+                if (strcmp(long_options[option_index].name, "interface") == 0) {
+                    sscanf(optarg, "%i", &interface);
+                }
+
+                if (strcmp(long_options[option_index].name, "dir") == 0) {
+                    sscanf(optarg, "%i", &dir);
+                }
+
+                if (strcmp(long_options[option_index].name, "reset_release") == 0) {
+                    sscanf(optarg, "%i", &reset_release);
+                }
+
+                if (strcmp(long_options[option_index].name, "reset_set") == 0) {
+                    sscanf(optarg, "%i", &reset_set);
+                }
+
+                if (strcmp(long_options[option_index].name, "vref2_normal") == 0) {
+                    sscanf(optarg, "%i", &vref2_normal);
+                }
+
+                if (strcmp(long_options[option_index].name, "vref2_erase") == 0) {
+                    sscanf(optarg, "%i", &vref2_erase);
+                }
+
+                break;
+
+            case 'l':
+                strncpy(layout_str, optarg, BUF_LEN);
+                break;
+
+            case 'i':
+                dev_index = atoi(optarg);
+                break;
+
+            case 'v':
+                sscanf(optarg, "%i", &vendid);
+                break;
+
+            case 'p':
+                sscanf(optarg, "%i", &prodid);
+                break;
+
+            default:
+                usage();
+                break;
+        }
+    }
+
+    if (!(l = find_layout(layout_str)) &&
+        !((interface >= 0) &&
+          (dir >= 0) &&
+          (reset_release >= 0) &&
+          (reset_set >= 0) &&
+          (vref2_normal >= 0) &&
+          (vref2_erase >= 0))
+       ) {
+
+        printf("*** You must specify a layout or a complete set of overrides\n");
+        return EXIT_FAILURE;
+    }
+
+    if (l) {
+        memcpy(&layout, l, sizeof(struct layout));
+    }
+
+#define override(x) if(x > 0) { layout.x = x; }
+    override(interface);
+    override(dir);
+    override(reset_release);
+    override(reset_set);
+    override(vref2_normal);
+    override(vref2_erase);
+
+    if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0) {
+        fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n",
+                num_devs,
+                ftdi_get_error_string(&ftdic));
+        return EXIT_FAILURE;
+    }
+
+    if (ftdi_init(&ftdic) < 0) {
+        fprintf(stderr, "ftdi_init failed\n");
+        return EXIT_FAILURE;
+    }
+
+    if ((ret = ftdi_set_interface(&ftdic, layout.interface)) < 0) {
+        fprintf(stderr, "couldn't set interface %d, err %d (%s)\n", layout.interface, ret, ftdi_get_error_string(&ftdic));
+        return EXIT_FAILURE;
+    }
+
+    printf("Found %d devices with vendor id 0x%04x product id 0x%04x\n",
+           num_devs, vendid, prodid);
+
+    if (num_devs == 0) {
+        return EXIT_SUCCESS;
+    }
+
+    if (num_devs == 1) {
+        dev_index = 0;
+    }
+
+    while ((dev_index < 0) || (dev_index >= num_devs)) {
+        dev_index = print_and_prompt(devlist);
+    }
+
+    if (layout.name != NULL) {
+        printf("Opening device %d interface %d using layout %s\n",
+               dev_index, layout.interface, layout.name);
+    }
+    else {
+        printf("Opening device %d interface %d without a layout.\n",
+               dev_index, layout.interface);
+    }
+
+    if ((ret = ftdi_usb_open_desc_index(
+                   &ftdic,
+                   vendid,
+                   prodid,
+                   NULL,
+                   NULL,
+                   dev_index)) < 0) {
+#if __APPLE__
+
+        if ((ret == -5) && (0 == system("sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext"))) {
+            // Try again without the FTDI kext loaded this time
+            atexit(&restore_ftdi_kext);
+            ret = ftdi_usb_open_desc_index(
+                      &ftdic,
+                      vendid,
+                      prodid,
+                      NULL,
+                      NULL,
+                      dev_index
+                  );
+        }
+
+        if (ret)
+#endif // __APPLE__
+        {
+            fprintf(stderr, "couldn't open dev_index %d, err %d (%s)\n", dev_index, ret, ftdi_get_error_string(&ftdic));
+            return EXIT_FAILURE;
+        }
+    }
+
+
+    for (i = 0; commands[i].name != NULL; i++) {
+        if ((argv[optind] != NULL) &&
+            (strcmp(commands[i].name, argv[optind]) == 0)) {
+            break;
+        }
+    }
+
+    if (commands[i].name != NULL) {
+        commands[i].cmd(&ftdic, &layout);
+    }
+    else {
+        printf("invalid command\n");
+
+        ftdi_list_free(&devlist);
+        ftdi_deinit(&ftdic);
+
+        return EXIT_FAILURE;
+    }
+
+    printf("done.\n");
+
+    ftdi_list_free(&devlist);
+    ftdi_deinit(&ftdic);
+
+    return EXIT_SUCCESS;
+}
+
+void usage(void)
+{
+    int i;
+    printf("Usage: bbmc [options|overrides] -l|--layout layout command \n");
+    printf("Commands:\n");
+
+    for (i = 0; commands[i].name != NULL; i++) {
+        printf("           %s: %s\n", commands[i].name, commands[i].desc);
+    }
+
+    printf("\n");
+    printf("Required options:\n");
+    printf("           -l|--layout\t specifiy which board layout to use\n");
+    printf("                      \t layout is not necessary with a full\n");
+    printf("                      \t set of overrides\n");
+    printf("\nLayout overrides:\n");
+    printf("           --interface\t\t FTDI interface to use\n");
+    printf("           --dir\t\t direction (1 is output)\n");
+    printf("           --reset_release\t reset release command\n");
+    printf("           --reset_set\t\t reset set command\n");
+    printf("           --vref2_normal\t vref2 normal\n");
+    printf("           --vref2_erase\t vref2 erase\n");
+    printf("\n");
+    printf("Layouts:\n");
+
+    for (i = 0; layouts[i].name != NULL; i++) {
+        printf("\t%s: %s\n", layouts[i].name, layouts[i].desc);
+        printf("\n");
+        printf("\t\tinterface: \t0x%04x\n", layouts[i].interface);
+        printf("\t\tdir: \t\t0x%04x\n", layouts[i].dir);
+        printf("\t\treset release: \t0x%04x\n", layouts[i].reset_release);
+        printf("\t\treset hold:    \t0x%04x\n", layouts[i].reset_set);
+        printf("\t\tvref2 normal:  \t0x%04x\n", layouts[i].vref2_normal);
+        printf("\t\tvref2 erase:   \t0x%04x\n", layouts[i].vref2_erase);
+        printf("\n");
+    }
+
+    printf("\n");
+    printf("Options:\n");
+    printf("           -i|--index     specifiy which device to use (default 0)\n");
+    printf("           -v|--vendor    set vendor id (default 0x0403)\n");
+    printf("           -p|--product   set vendor id (default 0x6010)\n");
+}
+
+int print_and_prompt(struct ftdi_device_list *devlist)
+{
+    int i, ret;
+    struct ftdi_context ftdic;
+    struct ftdi_device_list *curdev;
+    char manufacturer[128], description[128], serial[128];
+    char input[BUF_LEN];
+    char *s;
+    int sel = -1;
+
+    printf("\n");
+
+    i = 0;
+
+    for (curdev = devlist; curdev != NULL; i++) {
+        printf("  [%d]   ", i);
+
+        if (0 > (ret = ftdi_usb_get_strings(&ftdic,
+                                            curdev->dev,
+                                            manufacturer, 128,
+                                            description, 128,
+                                            serial, 128))) {
+            fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n",
+                    ret, ftdi_get_error_string(&ftdic));
+            return EXIT_FAILURE;
+        }
+
+        printf("Manufacturer: %s, Description: %s, Serial %s\n",
+               manufacturer, description, serial);
+        curdev = curdev->next;
+    }
+
+    printf("\nUse which device? ");
+
+    s = fgets(input, BUF_LEN, stdin);
+
+    if (s != NULL) {
+        size_t last = strlen(input) - 1;
+
+        if (input[last] == '\n') {
+            input[last] = '\0';
+        }
+    }
+
+    sscanf(s, "%i", &sel);
+
+    return sel;
+}
+
+void reset(struct ftdi_context *ftdic, const struct layout *l)
+{
+
+    /* using MPSSE since it give access to high GPIO*/
+    /* set as inputs for now */
+    ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
+
+    printf("toggle reset\n");
+
+    bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+    bb_mpsee(ftdic, l->dir, (l->reset_set     | l->vref2_normal));
+    bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+
+    return;
+
+}
+
+
+void erase(struct ftdi_context *ftdic, const struct layout *l)
+{
+    printf("setting VREF2 erase\n");
+
+    /* using MPSSE since it give access to high GPIO*/
+    /* set as inputs for now */
+    ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
+
+    bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+    bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
+
+    printf("toggle reset\n");
+
+    bb_mpsee(ftdic, l->dir, (l->reset_set     | l->vref2_erase));
+    bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
+
+    printf("waiting for erase\n");
+
+    sleep(2);
+
+    printf("setting VREF2 normal\n");
+
+    bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+
+    reset(ftdic, l);
+
+    return;
+
+}
+
+
+int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val)
+{
+    uint8_t buf[3];
+    int ret;
+
+    /* command "set data bits low byte" */
+    buf[0] = 0x80;
+    buf[1] = (val & 0xff);
+    buf[2] = dir & 0xff;
+#if DEBUG
+    fprintf(stderr, "write %x %x %x\n", buf[0], buf[1], buf[2]);
+#endif
+
+    if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0) {
+        perror("ft2232_write error");
+        fprintf(stderr, "ft2232_write command %x\n", buf[0]);
+        return EXIT_FAILURE;
+    }
+
+
+    /* command "set data bits high byte" */
+    buf[0] = 0x82;
+    buf[1] = (val >> 8);
+    buf[2] = dir >> 8;
+#if DEBUG
+    fprintf(stderr, "write %x %x %x\n", buf[0], buf[1], buf[2]);
+#endif
+
+    if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0) {
+        perror("ft2232_write error");
+        fprintf(stderr, "ft2232_write command %x\n", buf[0]);
+        return EXIT_FAILURE;
+    }
+
+    return 0;
+
+}
diff --git a/boards/redbee-econotag/tools/mc1322x-load.c b/boards/redbee-econotag/tools/mc1322x-load.c
new file mode 100644
index 0000000000000000000000000000000000000000..82c59520b9e3fc7079baf5741e37696e183f7061
--- /dev/null
+++ b/boards/redbee-econotag/tools/mc1322x-load.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2012, Maxim Osipov <maxim.osipov@gmail.com>
+ * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
+ * to the MC1322x project (http://mc1322x.devl.org)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdint.h>
+
+
+char *filename;
+char *second;
+char *term = "/dev/ttyUSB0";
+int baud = B115200;
+int verbose = 0;
+char *rts = "rts";
+char *command;
+int first_delay = 50;
+int second_delay = 100;
+int do_exit = 0;
+int zerolen = 0;
+char *args = NULL;
+
+struct stat sbuf;
+struct termios options;
+char buf[256];
+int pfd;
+int ffd;
+int sfd;
+
+void help(void);
+
+int main(int argc, char **argv)
+{
+    int c = 0;
+    int r = 0;
+    int i = 0;
+    uint32_t s = 0;
+    opterr = 0;
+
+    /* Parse options */
+    while ((c = getopt(argc, argv, "f:s:zt:vu:r:c:a:b:eh")) != -1) {
+        switch (c) {
+            case 'f':
+                filename = optarg;
+                break;
+
+            case 's':
+                second = optarg;
+                break;
+
+            case 'z':
+                zerolen = 1;
+                break;
+
+            case 't':
+                term = optarg;
+                break;
+
+            case 'v':
+                verbose = 1;
+                break;
+
+            case 'u':
+                if (strcmp(optarg, "115200")) {
+                    baud = B115200;
+                }
+                else if (strcmp(optarg, "57600")) {
+                    baud = B115200;
+                }
+                else if (strcmp(optarg, "19200")) {
+                    baud = B19200;
+                }
+                else if (strcmp(optarg, "9600")) {
+                    baud = B9600;
+                }
+                else {
+                    printf("Unknown baud rate %s!\n", optarg);
+                    return -1;
+                }
+
+                break;
+
+            case 'r':
+                rts = optarg;
+                break;
+
+            case 'c':
+                command = optarg;
+                break;
+
+            case 'a':
+                first_delay = atoi(optarg);
+                break;
+
+            case 'b':
+                second_delay = atoi(optarg);
+                break;
+
+            case 'e':
+                do_exit = 1;
+                break;
+
+            case 'h':
+            case '?':
+                help();
+                return 0;
+
+            default:
+                abort();
+        }
+    }
+
+    /* Get other arguments */
+    if (optind < argc) {
+        args = argv[optind];
+    }
+
+    /* Print settings */
+    if (verbose) {
+        printf("Primary file (RAM): %s\n", filename);
+        printf("Secondary file (Flash): %s\n", second);
+        printf("Zero secondary file: %s\n", zerolen == 1 ? "Yes" : "No");
+        printf("Port: %s\n", term);
+        printf("Baud rate: %i\n", baud);
+        printf("Flow control: %s\n", rts);
+        printf("Reset command: %s\n", command);
+        printf("Exit after load: %s\n", do_exit == 1 ? "Yes" : "No");
+        printf("Delay 1: %i\n", first_delay);
+        printf("Delay 2: %i\n", second_delay);
+    }
+
+    /* Open and configure serial port */
+    pfd = open(term, O_RDWR | O_NOCTTY | O_NDELAY);
+
+    if (pfd == -1) {
+        printf("Cannot open serial port %s!\n", term);
+        return -1;
+    }
+
+    fcntl(pfd, F_SETFL, FNDELAY);
+    tcgetattr(pfd, &options);
+    cfsetispeed(&options, baud);
+    options.c_cflag |= (CLOCAL | CREAD);
+    options.c_cflag &= ~PARENB;
+    options.c_cflag &= ~CSTOPB;
+    options.c_cflag &= ~CSIZE;
+    options.c_cflag |= CS8;
+
+    if (strcmp(rts, "rts")) {
+        options.c_cflag &= ~CRTSCTS;
+    }
+    else {
+        options.c_cflag |= CRTSCTS;
+    }
+
+    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+    options.c_oflag &= ~OPOST;
+    tcsetattr(pfd, TCSANOW, &options);
+
+    /* Reset the board if we can */
+    printf("Reset the board to enter bootloader (waiting for CONNECT)...\n");
+
+    if (command) {
+        printf("Performing reset: %s\n", command);
+        system(command);
+    }
+
+    /* Primary bootloader wait loop */
+    i = 0;
+
+    while (1) {
+        /* Wait for CONNECT */
+        r = write(pfd, (const void *)"\0", 1);
+        sleep(1);
+        r = read(pfd, &buf[i], sizeof(buf) - 1 - i);
+
+        if (r > 0) {
+            buf[i + r] = '\0';
+            printf("%s", &buf[i]);
+            fflush(stdout);
+
+            if (strstr(&buf[i], "CONNECT")) {
+                printf("\n");
+                break;
+            }
+
+            i += r;
+
+            if (i >= sizeof(buf) - 1) {
+                i = 0;
+            }
+        }
+        else {
+            printf(".");
+            fflush(stdout);
+        }
+    }
+
+    /* Send primary file */
+    if (!filename) {
+        printf("Please specify firmware file name (-f option)!\n");
+        return -1;
+    }
+
+    if (stat(filename, &sbuf)) {
+        printf("Cannot open firmware file %s!\n", filename);
+        return -1;
+    }
+
+    ffd = open(filename, O_RDONLY);
+
+    if (ffd == -1) {
+        printf("Cannot open firmware file %s!\n", filename);
+        return -1;
+    }
+
+    s = sbuf.st_size;
+    printf("Sending %s (%i bytes)...\n", filename, s);
+    r = write(pfd, (const void *)&s, 4);
+    i = 0;
+    r = read(ffd, buf, 1);
+
+    while (r > 0) {
+        do {
+            usleep(first_delay);
+            c = write(pfd, (const void *)buf, r);
+        }
+        while (c < r);
+
+        i += r;
+        printf("Written %i\r", i);
+        fflush(stdout);
+        r = read(ffd, buf, 1);
+    }
+
+    printf("\n");
+
+    /* Secondary loader wait loop */
+    if (second || zerolen) {
+        /* Wait for ready */
+        printf("Sending secondary file (waiting for ready)...\n");
+        i = 0;
+
+        while (1) {
+            sleep(1);
+            r = read(pfd, &buf[i], sizeof(buf) - 1 - i);
+
+            if (r > 0) {
+                buf[i + r] = '\0';
+                printf("%s", &buf[i]);
+                fflush(stdout);
+
+                if (strstr(buf, "ready")) {
+                    printf("\n");
+                    break;
+                }
+
+                i += r;
+
+                if (i >= sizeof(buf) - 1) {
+                    i = 0;
+                }
+            }
+            else {
+                printf(".");
+                fflush(stdout);
+            }
+        }
+
+        /* Send secondary file */
+        if (second) {
+            if (stat(second, &sbuf)) {
+                printf("Cannot open secondary file %s!\n", second);
+                return -1;
+            }
+
+            sfd = open(second, O_RDONLY);
+
+            if (sfd == -1) {
+                printf("Cannot open secondary file %s!\n", second);
+                return -1;
+            }
+
+            s = sbuf.st_size;
+            printf("Sending %s (%i bytes)...\n", second, s);
+            r = write(pfd, (const void *)&s, 4);
+            i = 0;
+            r = read(sfd, buf, 1);
+
+            while (r > 0) {
+                do {
+                    usleep(second_delay);
+                    c = write(pfd, (const void *)buf, r);
+                }
+                while (c < r);
+
+                i += r;
+                printf("Written %i\r", i);
+                fflush(stdout);
+                r = read(sfd, buf, 1);
+            }
+
+            printf("\n");
+        }
+        else if (zerolen) {
+            s = 0;
+            printf("Sending %i...\n", s);
+            write(pfd, (const void *)&s, 4);
+        }
+    }
+
+    /* Send the remaining arguments */
+    if (args) {
+        printf("Sending %s\n", args);
+        r = write(pfd, (const void *)args, strlen(args));
+        r = write(pfd, (const void *)",", 1);
+    }
+
+    /* Drop in echo mode */
+    if (!do_exit) {
+        while (1) {
+            r = read(pfd, buf, sizeof(buf));
+
+            if (r > 0) {
+                buf[r] = '\0';
+                printf("%s", buf);
+                fflush(stdout);
+            }
+        }
+    }
+}
+
+
+void help(void)
+{
+    printf("Example usage: mc1322x-load -f foo.bin -t /dev/ttyS0 -b 9600\n");
+    printf("          or : mc1322x-load -f flasher.bin -s flashme.bin  0x1e000,0x11223344,0x55667788\n");
+    printf("          or : mc1322x-load -f flasher.bin -z  0x1e000,0x11223344,0x55667788\n");
+    printf("       -f required: binary file to load\n");
+    printf("       -s optional: secondary binary file to send\n");
+    printf("       -z optional: send a zero length file as secondary\n");
+    printf("       -t, terminal default: /dev/ttyUSB0\n");
+    printf("       -u, baud rate default: 115200\n");
+    printf("       -r [none|rts] flow control default: rts\n");
+    printf("       -c command to run for autoreset: \n");
+    printf("              e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n");
+    printf("       -e exit instead of dropping to terminal display\n");
+    printf("       -a first  intercharacter delay, passed to usleep\n");
+    printf("       -b second intercharacter delay, passed to usleep\n");
+    printf("\n");
+    printf("Anything on the command line is sent after all of the files.\n\n");
+}
diff --git a/boards/redbee-econotag/tools/mc1322x-load.pl b/boards/redbee-econotag/tools/mc1322x-load.pl
new file mode 100755
index 0000000000000000000000000000000000000000..bfc1d1ffcdcfceb5a855e57de0017f04c42fd832
--- /dev/null
+++ b/boards/redbee-econotag/tools/mc1322x-load.pl
@@ -0,0 +1,171 @@
+#!/usr/bin/perl -w
+
+use Device::SerialPort;
+use Term::ReadKey;
+use Getopt::Long;
+use Time::HiRes qw(usleep);
+
+use strict;
+
+my $filename = '';
+my $second = '';
+my $term = '/dev/ttyUSB0';
+my $baud = '115200';
+my $verbose;
+my $rts = 'rts';
+my $command = '';
+my $first_delay = 50;
+my $second_delay = 100;
+my $do_exit;
+my $zerolen;
+
+GetOptions ('file=s' => \$filename,
+	    'secondfile=s' => \$second,
+	    'zerolen' => \$zerolen,
+	    'terminal=s' => \$term, 
+	    'verbose' => \$verbose, 
+	    'u|baud=s' => \$baud,
+	    'rts=s' => \$rts,
+	    'command=s' => \$command,
+	    'a=s' => \$first_delay,
+	    'b=s' => \$second_delay,
+	    'exit' => \$do_exit,
+    ) or die 'bad options';
+
+$| = 1;
+
+if($filename eq '') {
+    print "Example usage: mc1322x-load.pl -f foo.bin -t /dev/ttyS0 -b 9600\n";
+    print "          or : mc1322x-load.pl -f flasher.bin -s flashme.bin  0x1e000,0x11223344,0x55667788\n";
+    print "          or : mc1322x-load.pl -f flasher.bin -z  0x1e000,0x11223344,0x55667788\n";
+    print "       -f required: binary file to load\n";
+    print "       -s optional: secondary binary file to send\n";
+    print "       -z optional: send a zero length file as secondary\n";
+    print "       -t, terminal default: /dev/ttyUSB0\n";
+    print "       -u, --baud baud rate default: 115200\n";
+    print "       -r [none|rts] flow control default: rts\n";
+    print "       -c command to run for autoreset: \n";
+    print "              e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n";
+    print "       -e exit instead of dropping to terminal display\n";
+    print "       -a first  intercharacter delay, passed to usleep\n";
+    print "       -b second intercharacter delay, passed to usleep\n";
+    print "\n";
+    print "anything on the command line is sent\n";
+    print "after all of the files.\n\n";
+    exit;
+}
+
+if (!(-e $filename)) { die "file $filename not found\n"; }
+if (($second ne '') && !(-e $second)) { die "secondary file $second not found\n"; }
+
+my $ob = Device::SerialPort->new ($term) or die "Can't start $term\n";
+    # next test will die at runtime unless $ob
+
+$ob->baudrate($baud);
+$ob->parity('none');
+$ob->databits(8);
+$ob->stopbits(1);
+if($rts eq 'rts') {
+    $ob->handshake('rts');
+} else {
+    $ob->handshake('none');
+}
+$ob->read_const_time(1000); # 1 second per unfulfilled "read" call
+$ob->rts_active(1);
+
+my $s = 0;
+my $reset = 0;
+my $size = 0;
+
+while(1) { 
+    
+    my $c; my $count; my $ret = ''; my $test='';
+    
+    if($s == 1) { print "secondary send...\n"; }
+    
+    $ob->write(pack('C','0'));
+
+    if(($command ne '') &&
+       ($reset eq 0)) {
+	$reset++;
+	system($command);
+    }
+
+    if($s == 1) { 
+	$test = 'ready'; 
+    } else {
+	$test = 'CONNECT';
+    }
+    
+    until($ret =~ /$test$/) {
+	($count,$c) = $ob->read(1);
+	if ($count == 0) { 
+	    print '.';
+	    $ob->write(pack('C','0')); 
+	    next;
+	}
+	$ret .= $c;
+    }
+    print $ret . "\n";
+    
+    if (-e $filename || (defined($zerolen) && ($s == 1))) {
+	
+	if(defined($zerolen) && ($s == 1)) {
+	    $size = 0;
+	} else {
+	    $size = -s $filename;
+	}
+
+	print ("Size: $size bytes\n");
+	$ob->write(pack('V',$size));
+
+	if(($s == 0) ||
+	   ((!defined($zerolen)) && ($s == 1))) {
+	    open(FILE, $filename) or die($!);
+	    print "Sending $filename\n";
+	    
+	    my $i = 1;
+	    while(read(FILE, $c, 1)) {
+		$i++;
+                usleep($first_delay)  if ( $s == 0 ) && ($first_delay != 0);
+                usleep($second_delay) if ( $s == 1 ) && ($second_delay != 0);
+		$ob->write($c);
+	    }
+	}
+    }
+    
+    last if ($s==1);
+    if((-e $second) || defined($zerolen)) {
+	$s=1; $filename = $second;
+    } else {
+	last;
+    }
+
+} 
+
+print "done sending files.\n";
+
+if(scalar(@ARGV)!=0) {
+    print "sending " ;
+    print @ARGV;
+    print ",\n";
+
+    $ob->write(@ARGV);
+    $ob->write(',');
+}
+
+if(defined($do_exit)) {
+    exit;
+}
+
+my $c; my $count;
+while(1) {
+    ($count, $c) = $ob->read(1);
+    print $c if (defined($count) && ($count != 0));
+}
+
+$ob -> close or die "Close failed: $!\n";
+ReadMode 0;
+undef $ob;  # closes port AND frees memory in perl
+exit;
+
diff --git a/boards/telosb/Makefile b/boards/telosb/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c5eb97b3bc8da2ff13a6baa7ef55800281eca904
--- /dev/null
+++ b/boards/telosb/Makefile
@@ -0,0 +1,34 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+export ARCH = telosb_base.a
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I${RIOTBOARD}/${BOARD}/include/
+INCLUDES += -I${RIOTBASE}/core/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/ -I$(RIOTBASE)/cpu/msp430x16x/include/
+INCLUDES += -I$(RIOTBASE)/drivers/cc2420/include/ -I$(RIOTBASE)/sys/include
+INCLUDES += -I$(RIOTBASE)/sys/net/include
+
+all: $(BINDIR)$(ARCH)
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	mkdir -p $(BINDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	@if [ -d $(BINDIR) ] ; \
+	then rmdir $(BINDIR) ; \
+	fi
diff --git a/boards/telosb/Makefile.dep b/boards/telosb/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..4392a18adb85f0037d18b402effd9d8cebe34532
--- /dev/null
+++ b/boards/telosb/Makefile.dep
@@ -0,0 +1,2 @@
+USEMODULE += msp430_common
+
diff --git a/boards/telosb/Makefile.include b/boards/telosb/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..e07ce0f5daa2046a4414f7efb509ac05605278e8
--- /dev/null
+++ b/boards/telosb/Makefile.include
@@ -0,0 +1,25 @@
+include $(RIOTBOARD)/$(BOARD)/Makefile.dep
+## the cpu to build for
+export CPU = msp430x16x
+export MCU = msp430f1611
+
+# toolchain config
+export PREFIX = @msp430-
+export CC = @$(PREFIX)gcc
+export AR = @$(PREFIX)ar
+export CFLAGS += -std=gnu99 -Wstrict-prototypes -gdwarf-2 -Os -Wall -mmcu=$(MCU)
+export ASFLAGS += -mmcu=$(MCU) --defsym $(MCU)=1 --gdwarf-2
+export AS = $(PREFIX)as
+export LINK = $(PREFIX)gcc
+export SIZE = $(PREFIX)size
+export OBJCOPY = $(PREFIX)objcopy
+export LINKFLAGS = -mmcu=$(MCU) -lgcc $(RIOTBASE)/bin/startup.o
+export TERMPROG = $(RIOTBASE)/dist/tools/pyterm/pyterm.py
+export FLASHER = goodfet.bsl
+ifeq ($(strip $(PORT)),)
+    export PORT = /dev/ttyUSB0
+endif
+export HEXFILE = bin/$(PROJECT).hex
+export FFLAGS = --telosb -c $(PORT) -r -e -I -p $(HEXFILE)
+
+export INCLUDES += -I $(RIOTCPU)/msp430-common/include/
diff --git a/boards/telosb/board.c b/boards/telosb/board.c
new file mode 100644
index 0000000000000000000000000000000000000000..37b21b4caaa3e1f2f0f97b7cc29d88c8c864d39c
--- /dev/null
+++ b/boards/telosb/board.c
@@ -0,0 +1,127 @@
+  /*
+   * board.c - Board initiazilation for the TelosB
+   * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+   *
+   * This file subject to the terms and conditions of the LGPLv2. See the file
+   * LICENSE in the  top level directory for more details.
+   */
+
+#include "cpu.h"
+#include "board.h"
+
+void uart_init(void);
+
+static void telosb_ports_init(void)
+{
+    /* Port 1: GDO, Flash, BSL TX */
+    P1SEL = 0x02;    /* Port1 Select: 00000010 = 0x02 */
+    P1OUT = 0x00;    /* Port1 Output: 00000000 = 0x00 */
+    P1DIR = 0x87;    /* Port1 Direction: 10000111 = 0x87 */
+
+    /* Port 2: GPIO, BSL RX, 1wire */
+    P2SEL = 0x04;    /* Port2 Select: 00000100 = 0x04 */
+    P2OUT = 0x00;    /* Port2 Output: 00000000 = 0x00 */
+    P2DIR = 0xFF;    /* Port2 Direction: 11111111 = 0xFF */
+
+    /* Port 3: UART and SPI */
+    P3SEL = 0xCE;    /* Port3 Select: 11001110 = 0xCE */
+    P3OUT = 0x00;    /* Port3 Output: 00000000 = 0x00 */
+    P3DIR = 0x4E;    /* Port3 Direction: 01001110 = 0x4E */
+
+    /* Port 4: CS */
+    P4SEL = 0x02;    /* Port4 Select: 00000010 = 0x02 */
+    P4OUT = 0x04;    /* Port4 Output: 00000100 = 0x04 */
+    P4DIR = 0x64;    /* Port4 Direction: 01100100 = 0x64 */
+
+    /* Port 5: SPI, LED */
+    P5SEL = 0x00;    /* Port5 Select: 00000000 = 0x00 */
+    P5OUT = 0x70;    /* Port5 Output: 01110000 = 0x70 */
+    P5DIR = 0x70;    /* Port5 Direction: 01110000 = 0x70 */
+
+
+    P6SEL = 0xFF;    /* Port6 Select: 11111111 = 0xFF */
+    P6OUT = 0x00;    /* Port6 Output: 00000000 = 0x00 */
+    P6DIR = 0xFF;    /* Port6 Direction: 11111000 = 0xFF */
+
+}
+
+/*---------------------------------------------------------------------------*/
+/* taken from Contiki code */
+void msp430_init_dco(void)
+{
+    /* This code taken from the FU Berlin sources and reformatted. */
+#define DELTA    (F_CPU / (F_RC_OSCILLATOR / 8))
+
+    unsigned int compare, oldcapture = 0;
+    unsigned int i;
+
+    /* 10100100 = XT2 is off, ACLK divided by 4, RSELx=4 */
+    BCSCTL1 = XT2OFF | DIVA_2 | RSEL2;
+
+    /* Init undivided DCO with internal resistor for MCLK and SMCLK
+     * DCO = 32762Hz -> FLL = 2,4576 MHz */
+    BCSCTL2 = 0x00;
+
+    BCSCTL1 |= DIVA1 + DIVA0;             /* ACLK = LFXT1CLK/8 */
+
+    for (i = 0xFFFF; i > 0; i--) {        /* Delay for XTAL to settle */
+        asm("nop");
+    }
+
+    CCTL2 = CCIS0 + CM0 + CAP;            /* Define CCR2, CAP, ACLK */
+    TACTL = TASSEL1 + TACLR + MC1;        /* SMCLK, continous mode */
+
+    while (1) {
+        while ((CCTL2 & CCIFG) != CCIFG);   /* Wait until capture occured!*/
+
+        CCTL2 &= ~CCIFG;                    /* Capture occured, clear flag */
+        compare = CCR2;                     /* Get current captured SMCLK */
+        compare = compare - oldcapture;     /* SMCLK difference */
+        oldcapture = CCR2;                  /* Save current captured SMCLK */
+
+        if (DELTA == compare) {
+            break;                            /* if equal, leave "while (1)" */
+        }
+        else if (DELTA < compare) {        /* DCO is too fast, slow it down */
+            DCOCTL--;
+
+            if (DCOCTL == 0xFF) {             /* Did DCO role under? */
+                BCSCTL1--;
+            }
+        }
+        else {                            /* -> Select next lower RSEL */
+            DCOCTL++;
+
+            if (DCOCTL == 0x00) {             /* Did DCO role over? */
+                BCSCTL1++;
+            }
+
+            /* -> Select next higher RSEL  */
+        }
+    }
+
+    CCTL2 = 0;                            /* Stop CCR2 function */
+    TACTL = 0;                            /* Stop Timer_A */
+
+    BCSCTL1 &= ~(DIVA1 + DIVA0);          /* remove /8 divisor from ACLK again */
+}
+
+
+//=========================== public ==========================================
+
+void board_init(void)
+{
+    msp430_cpu_init();
+    /* disable watchdog timer */
+    WDTCTL     =  WDTPW + WDTHOLD;
+
+    telosb_ports_init();
+
+    msp430_init_dco();
+
+    /* initialize bsp modules */
+    uart_init();
+
+    /* enable interrupts */
+    __bis_SR_register(GIE);
+}
diff --git a/boards/telosb/driver_cc2420.c b/boards/telosb/driver_cc2420.c
new file mode 100644
index 0000000000000000000000000000000000000000..4ee7ce9d1d43f7d126ff871b0fb7174fdca45e63
--- /dev/null
+++ b/boards/telosb/driver_cc2420.c
@@ -0,0 +1,222 @@
+  /*
+   * driver_cc2420.c - Implementation of the board dependent cc2420 functions.
+   * Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
+   * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+   *
+   * This source code is licensed under the GNU Lesser General Public License,
+   * Version 2.  See the file LICENSE for more details.
+   */
+
+#include <stdio.h>
+
+#include <board.h>
+#include <cpu.h>
+#include <irq.h>
+#include <hwtimer.h>
+
+#include <cc2420.h>
+
+#define ENABLE_DEBUG    (1)
+#include "debug.h"
+
+#define CC2420_RESETn_PIN   0x40
+#define CC2420_VREGEN_PIN   0x20
+
+#define CC2420_FIFOP_PIN    0x01
+#define CC2420_GIO0_PIN     0x08
+#define CC2420_GIO1_PIN     0x10
+#define CC2420_CCA_PIN      0x40
+#define CC2420_SFD_PIN      0x02
+
+#define CC2420_FIFOP        (P1IN & CC2420_FIFOP_PIN)   /* FIFOP <-> packet interrupt (P1.0) */
+#define CC2420_GIO0         (P1IN & CC2420_GIO0_PIN)    /* FIFO  <-> GIO0 - RX data available (P1.3) */
+#define CC2420_GIO1         (P1IN & CC2420_GIO1_PIN)    /* CCA   <-> GIO1 - clear channel (P1.4) */
+#define CC2420_SFD          (P4IN & CC2420_SFD_PIN)     /* SFD   <-> TBL - start frame delimiter (P4.1) */
+
+#define CC2420_CS_LOW       (P4OUT &= ~0x04)            /* P4.2 */
+#define CC2420_CS_HIGH      (P4OUT |= 0x04)
+
+volatile int abort_count;
+volatile int retry_count = 0;
+
+void cc2420_reset(void)
+{
+    P4OUT |= CC2420_VREGEN_PIN;
+    P4OUT &= ~CC2420_RESETn_PIN;
+    hwtimer_wait(500);
+    P4OUT |= CC2420_RESETn_PIN;
+}
+
+void cc2420_gio0_enable(void)
+{
+    P1IFG &= ~CC2420_GIO0_PIN;     /* Clear IFG for GIO0 */
+    P1IE |= CC2420_GIO0_PIN;       /* Enable interrupt for GIO0 */
+}
+
+void cc2420_gio0_disable(void)
+{
+    P1IE &= ~CC2420_GIO0_PIN;      /* Disable interrupt for GIO0 */
+    P1IFG &= ~CC2420_GIO0_PIN;     /* Clear IFG for GIO0 */
+}
+
+void cc2420_gio1_enable(void)
+{
+    P1IFG &= ~CC2420_GIO1_PIN;     /* Clear IFG for GIO1 */
+    P1IE |= CC2420_GIO1_PIN;       /* Enable interrupt for GIO1 */
+}
+
+void cc2420_gio1_disable(void)
+{
+    P1IE &= ~CC2420_GIO1_PIN;      /* Disable interrupt for GIO1 */
+    P1IFG &= ~CC2420_GIO1_PIN;     /* Clear IFG for GIO1 */
+}
+
+void cc2420_before_send(void)
+{
+    /* Disable SFD interrupt before sending packet */
+    /* However this is not used atm */
+}
+
+void cc2420_after_send(void)
+{
+    /* Enable SFD interrupt after sending packet */
+    /* However this is not used atm */
+}
+
+
+int cc2420_get_gio0(void)
+{
+    return  CC2420_GIO0;
+}
+
+int cc2420_get_gio1(void)
+{
+    return  CC2420_GIO1;
+}
+
+int cc2420_get_fifop(void)
+{
+    return  CC2420_FIFOP;
+}
+
+int cc2420_get_sfd(void)
+{
+    return CC2420_SFD;
+}
+
+void cc2420_spi_cs(void)
+{
+    CC2420_CS_LOW;
+}
+
+uint8_t cc2420_txrx(uint8_t data)
+{
+    /* Ensure TX Buf is empty */
+    long c = 0;
+    IFG1 &= ~UTXIFG0;
+    IFG1 &= ~URXIFG0;
+    U0TXBUF = data;
+    while(!(IFG1 & UTXIFG0)) {
+        if (c++ == 1000000) {
+            puts("cc2420_txrx alarm()");
+        }
+    }
+    /* Wait for Byte received */
+    c = 0;
+    while(!(IFG1 & URXIFG0)) {
+        if (c++ == 1000000) {
+            puts("cc2420_txrx alarm()");
+        }
+    }
+    return U0RXBUF;
+}
+
+
+void cc2420_spi_select(void)
+{
+    CC2420_CS_LOW;
+}
+
+void cc2420_spi_unselect(void) {
+    CC2420_CS_HIGH;
+}
+
+void cc2420_init_interrupts(void)
+{
+    unsigned int state = disableIRQ();  /* Disable all interrupts */
+    P1SEL &= ~CC2420_FIFOP_PIN;         /* must be <> 1 to use interrupts */
+    P1SEL &= ~CC2420_GIO0_PIN;         /* must be <> 1 to use interrupts */
+
+    /* FIFO <-> GIO0 interrupt */
+    P1IES |= CC2420_GIO0_PIN;      /* Enables external interrupt on falling edge (for GIO0/FIFO) */
+    P1IE |= CC2420_GIO0_PIN;       /* Enable interrupt */
+    P1IFG &= ~CC2420_GIO0_PIN;     /* Clears the interrupt flag */
+
+    /* FIFOP <-> Packet interrupt */
+    P1IE |= CC2420_FIFOP_PIN;      /* Enable interrupt for FIFOP */
+    P1IFG &= ~CC2420_FIFOP_PIN;     /* Clear IFG for FIFOP */
+    restoreIRQ(state);              /* Enable all interrupts */
+}
+
+void cc2420_spi_init(void)
+{
+    /* Switch off async UART */
+    while(!(U0TCTL & TXEPT));   /* Wait for empty UxTXBUF register */
+    IE1 &= ~(URXIE0 + UTXIE0);  /* Disable USART0 receive&transmit interrupt */
+    ME1 &= ~(UTXE0 + URXE0);
+
+    /* configure SPI-related pins */
+    P3SEL     |=  0x0E;                           /* P3.1 -  SIMO mode, P3.2 - SOMI mode, P3.3 - SCL mode */
+    P3DIR     |=  0x0A;                           /* P3.1 and P3.3 as output */
+    P3DIR     &= ~(0x04);                         /* P3.2 as input for SOMI */
+    P4OUT     |=  0x04;                           /* P4.2 radio CS, hold high */
+    P4DIR     |=  0x04;                           /* P4.2 radio CS, output */
+ 
+    /* Keep peripheral in reset state */
+    U0CTL  = SWRST;
+
+    /* 8-bit SPI Master 3-pin mode, with SMCLK as clock source */
+    /* CKPL works also, but not CKPH+CKPL or none of them!! */
+    U0CTL |= CHAR + SYNC + MM;
+    U0TCTL = CKPH + SSEL1 + SSEL0 + STC + TXEPT;;
+    
+    /* Ignore clockrate argument for now, just use clock source/2 */
+    /* SMCLK = 8 MHz */
+    U0BR0 = 0x02;  /* Ensure baud rate >= 2 */
+    U0BR1 = 0x00;
+    U0MCTL = 0x00; /* No modulation */
+    U0RCTL = 0x00; /* Reset Receive Control Register */
+   
+    /* Enable SPI mode */
+    ME1 |= USPIE0;
+
+    /* Release for operation */
+    U0CTL  &= ~SWRST;
+}
+
+/*
+ * CC1100 receive interrupt
+ */
+interrupt (PORT1_VECTOR) __attribute__ ((naked)) cc2420_isr(void)
+{
+    __enter_isr();
+     /* Check IFG */
+    if ((P1IFG & CC2420_FIFOP_PIN) != 0) {
+        P1IFG &= ~CC2420_FIFOP_PIN;
+        cc2420_rx_irq();
+        DEBUG("rx interrupt");
+    }
+    /* GIO0 is falling => check if FIFOP is high, indicating an RXFIFO overflow */
+    else if ((P1IFG & CC2420_GIO0) != 0) {
+        P1IFG &= ~CC2420_GIO0_PIN;
+        if (cc2420_get_fifop()) {
+            cc2420_rxoverflow_irq();
+            DEBUG("[CC2420] rxfifo overflow");
+        }
+    }
+    else {
+        puts("cc2420_isr(): unexpected IFG!");
+        /* Should not occur - only GDO1 and GIO1 interrupts are enabled */
+    }
+    __exit_isr();
+}
diff --git a/boards/telosb/include/board-conf.h b/boards/telosb/include/board-conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..f65074da9d00a2e5447f6d442a58f203a714fdd7
--- /dev/null
+++ b/boards/telosb/include/board-conf.h
@@ -0,0 +1,13 @@
+/**
+  * board-conf.h.
+  *
+  * This source code is licensed under the GNU Lesser General Public License,
+  * Version 2.  See the file LICENSE for more details.
+  */
+
+#ifndef BOARD_CONF_H
+#define BOARD_CONF_H
+
+#define INFOMEM     (0x1000)
+
+#endif /* BOARD-CONF_H */
diff --git a/boards/telosb/include/board.h b/boards/telosb/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..55fd2a35b47d25db9231ddd90ff747174277c4cd
--- /dev/null
+++ b/boards/telosb/include/board.h
@@ -0,0 +1,61 @@
+/**
+  * board.h - TelosB Board.
+  * Copyright (C) 2013 INRIA
+  *
+  * This source code is licensed under the GNU Lesser General Public License,
+  * Version 2.  See the file LICENSE for more details.
+  */
+
+#ifndef _TELOSB_BOARD_H
+#define _TELOSB_BOARD_H
+
+/**
+ * @defgroup    TelosB
+ * @ingroup		TelosB
+ *
+<h2>Compontents</h2>
+\li MSP430
+\li CC2420
+
+* @{
+*/
+
+/**
+ * @file
+ * @brief		TelosB Board
+ *
+ * @author      Oliver Hahm <oliver.hahm@inria.fr>
+ *
+ */
+
+//MSB430 core
+#define MSP430_INITIAL_CPU_SPEED    8000000uL
+#define MSP430_HAS_DCOR             0
+#define MSP430_HAS_EXTERNAL_CRYSTAL 1
+
+/* LEDs ports MSB430 */
+#define LEDS_PxDIR P5DIR
+#define LEDS_PxOUT P5OUT
+#define LEDS_CONF_RED		0x10
+#define LEDS_CONF_GREEN		0x20
+#define LEDS_CONF_BLUE	0x40
+
+#define LED_RED_ON      LEDS_PxOUT &=~LEDS_CONF_RED
+#define LED_RED_OFF     LEDS_PxOUT |= LEDS_CONF_RED
+#define LED_RED_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_RED
+
+#define LED_GREEN_ON      LEDS_PxOUT &=~LEDS_CONF_GREEN
+#define LED_GREEN_OFF     LEDS_PxOUT |= LEDS_CONF_GREEN
+#define LED_GREEN_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_GREEN
+
+#define LED_BLUE_ON      LEDS_PxOUT &=~LEDS_CONF_BLUE
+#define LED_BLUE_OFF     LEDS_PxOUT |= LEDS_CONF_BLUE
+#define LED_BLUE_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_BLUE
+
+#include <stdint.h>
+#include <msp430x16x.h>
+
+typedef uint8_t radio_packet_length_t;
+
+/** @} */
+#endif // _TELOSB_BOARD_H
diff --git a/boards/telosb/uart.c b/boards/telosb/uart.c
new file mode 100644
index 0000000000000000000000000000000000000000..1e97bfb569715401d35288b6163d044cab7f1f73
--- /dev/null
+++ b/boards/telosb/uart.c
@@ -0,0 +1,118 @@
+/*
+ * uart.c - Implementation for the TelosB UART
+ * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+ *
+ * This file subject to the terms and conditions of the LGPLv2. See the file
+ * LICENSE in the top level directory for more details.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include "cpu.h"
+#include "board.h"
+#include "kernel.h"
+#include "board_uart0.h"
+
+#define   UART1_TX                  U1TXBUF
+#define   UART1_WAIT_TXDONE()       while ( (U1TCTL & TXEPT) == 0 ) { _NOP(); }
+
+#define BAUDRATE    (115200ul)
+
+static uint8_t calc_umctl(uint16_t br)
+{
+    /* from TI slaa049 */
+    register uint8_t CMOD = 256 * br - 256 * (br + 1) / 2;
+    register uint8_t c = 0;
+    register int i = 0;
+    register uint8_t a = CMOD;
+    a <<= 1;
+
+    do {
+        if (a & 0x80) {            /* Overflow to integer? */
+            a = a - 128 + CMOD;    /* Yes, subtract 1.000000 */
+            c |= 0x80;
+        }
+        else {
+            a += CMOD;              /* No, add fraction */
+        }
+
+        if (i == 7) {
+            return c;
+        }
+
+        i++;
+        c >>= 1;
+    }
+    while (1);
+}
+
+void uart_init(void)
+{
+    UCTL1     =  SWRST;           /* hold UART1 module in reset */
+    UCTL1    |=  CHAR;            /* 8-bit character */
+
+    /* 115200 baud, clocked from 4.8MHz SMCLK */
+    UTCTL1   |= SSEL1;        /* UCLK = SCLK */
+    UBR01     = F_CPU / BAUDRATE;
+    UBR11     = (F_CPU / BAUDRATE) >> 8;
+    UMCTL1    = calc_umctl(F_CPU / BAUDRATE);       /* set modulation */
+
+    ME2      |=  UTXE1 + URXE1;   /* enable UART1 TX/RX */
+    UCTL1    &= ~SWRST;           /* clear UART1 reset bit */
+
+    IE2  |= URXIE1;               /* enable rx interrupt */
+    IFG1 &= ~UTXIFG1;
+}
+
+int putchar(int c)
+{
+    UART1_TX = c;
+    UART1_WAIT_TXDONE();
+    return c;
+}
+
+uint8_t uart_readByte(void)
+{
+    return U1RXBUF;
+}
+
+void usart1irq(void);
+/**
+ * \brief the interrupt function
+ */
+interrupt(USART1RX_VECTOR) usart1irq(void)
+{
+    int c = 0;
+
+    /* Check status register for receive errors. */
+    if (U1RCTL & RXERR) {
+        if (U1RCTL & FE) {
+            puts("rx framing error");
+        }
+
+        if (U1RCTL & OE) {
+            puts("rx overrun error");
+        }
+
+        if (U1RCTL & PE) {
+            puts("rx parity error");
+        }
+
+        if (U1RCTL & BRK) {
+            puts("rx break error");
+        }
+
+        /* Clear error flags by forcing a dummy read. */
+        c = U1RXBUF;
+    }
+
+#ifdef MODULE_UART0
+    else if (uart0_handler_pid) {
+        c = U1RXBUF;
+        uart0_handle_incoming(c);
+        uart0_notify_thread();
+    }
+
+#endif
+}
+
diff --git a/boards/wsn430-common/Makefile b/boards/wsn430-common/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8f8f23add94f2a6676778a1adc8b103cad9ad510
--- /dev/null
+++ b/boards/wsn430-common/Makefile
@@ -0,0 +1,33 @@
+SRC = $(wildcard *.c)
+BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I$(RIOTBOARD)/wsn430-common/include/ -I${RIOTBOARD}/${BOARD}/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/mspx16x/include/
+INCLUDES += -I$(RIOTBASE)/drivers/include/
+
+.PHONY: $(BINDIR)$(ARCH)
+
+all: $(BINDIR)$(ARCH) 
+	#$(MAKE) -C drivers
+
+$(BINDIR)$(ARCH): $(OBJ)
+	echo $(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	#$(MAKE) -C drivers clean
+	rm -f $(OBJ) $(DEP)
+	rm -f $(BINDIR)$(ARCH)
diff --git a/boards/wsn430-common/Makefile.include b/boards/wsn430-common/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..346044a3097ed9bd647e44d0085fac4fd4d7220b
--- /dev/null
+++ b/boards/wsn430-common/Makefile.include
@@ -0,0 +1,25 @@
+## the cpu to build for
+export CPU = msp430x16x
+export MCU = msp430f1611
+
+# toolchain config
+export PREFIX = @msp430-
+export CC = @$(PREFIX)gcc
+export AR = @$(PREFIX)ar
+export CFLAGS += -std=gnu99 -Wstrict-prototypes -gdwarf-2 -Os -Wall -mmcu=$(MCU)
+export ASFLAGS += -mmcu=$(MCU) --defsym $(MCU)=1 --gdwarf-2
+export AS = $(PREFIX)as
+export LINK = $(PREFIX)gcc
+export SIZE = $(PREFIX)size
+export OBJCOPY = $(PREFIX)objcopy
+export LINKFLAGS = -mmcu=$(MCU) -lgcc $(RIOTBASE)/bin/startup.o
+export FLASHER = mspdebug
+ifeq ($(strip $(PORT)),)
+    export PORT = /dev/ttyUSB0
+endif
+export HEXFILE = bin/$(PROJECT).hex
+export FFLAGS = -d $(PORT) -j uif "prog $(HEXFILE)"
+
+export INCLUDES += -I $(RIOTCPU)/msp430-common/include/ -I$(RIOTBASE)/sys/net/include/
+export OFLAGS = -O ihex
+
diff --git a/boards/wsn430-common/board_config.c b/boards/wsn430-common/board_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..4e9bc0b69c90fd58ca3852defe908d48bfc39edc
--- /dev/null
+++ b/boards/wsn430-common/board_config.c
@@ -0,0 +1,26 @@
+/**
+  * board-config.c.
+  *
+  * This source code is licensed under the GNU Lesser General Public License,
+  * Version 2.  See the file LICENSE for more details.
+  */
+
+#include <stdint.h>
+#include <string.h>
+#include <board-conf.h>
+#include <config.h>
+#include <flashrom.h>
+
+void config_load(void) {
+   if (*((uint16_t*) INFOMEM) ==  CONFIG_KEY) {
+       memcpy(&sysconfig, (char*) (INFOMEM + sizeof(CONFIG_KEY)), sizeof(sysconfig));
+   }
+   else {
+       config_save();
+   }
+}
+
+uint8_t config_save(void) {
+    configmem_t mem = { CONFIG_KEY, sysconfig  };
+    return (flashrom_erase((uint8_t*) INFOMEM) && flashrom_write((uint8_t*) INFOMEM, (char*) &mem, sizeof(mem)));
+}
diff --git a/boards/wsn430-common/board_init.c b/boards/wsn430-common/board_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b84c699bc7463e5e63d9bd6da8843999077fcc8
--- /dev/null
+++ b/boards/wsn430-common/board_init.c
@@ -0,0 +1,152 @@
+  /*
+   * board_init.c - Implementation of functions to init board.
+   * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de>
+   *
+   * This source code is licensed under the GNU Lesser General Public License,
+   * Version 2.  See the file LICENSE for more details.
+   */
+
+#include "cpu.h"
+#include "board.h"
+#include "kernel_internal.h"
+#include "msp430.h"
+#include "debug.h"
+
+volatile static uint32_t __msp430_cpu_speed = MSP430_INITIAL_CPU_SPEED;
+
+void msp430_init_dco(void);
+
+typedef enum {
+    MCLK_2MHZ_SCLK_1MHZ = 1000002uL,
+    MCLK_4MHZ_SCLK_1MHZ = 1000004uL,
+    MCLK_8MHZ_SCLK_1MHZ = 1000008uL,
+    MCLK_8MHZ_SCLK_8MHZ = 8000000uL
+}speed_t;
+
+/*---------------------------------------------------------------------------*/
+static uint8_t calc_umctl(uint16_t br) {
+    // from TI slaa049
+    register uint8_t CMOD = 256 * br - 256 * (br + 1) / 2;
+    register uint8_t c = 0;
+    register int i = 0;
+    register uint8_t a = CMOD;
+    a <<= 1;
+    do {
+        if( a & 0x80 ) {           // Overflow to integer?
+            a = a - 128 + CMOD;    // Yes, subtract 1.000000
+            c |= 0x80;
+        } else {
+            a += CMOD;              // No, add fraction
+        }
+        if( i == 7 ) {
+            return c;
+        }
+        i++;
+        c >>= 1;
+    } while(1);
+}
+
+static void msb_ports_init(void)
+{
+    // Port 1: GDO, Flash, BSL TX
+    P1SEL = 0x02;    // Port1 Select: 00000010 = 0x02
+    P1OUT = 0x00;    // Port1 Output: 00000000 = 0x00
+    P1DIR = 0x87;    // Port1 Direction: 10000111 = 0x87
+
+    // Port 2: GPIO, BSL RX, 1wire
+    P2SEL = 0x04;    // Port2 Select: 00000100 = 0x04
+    P2OUT = 0x00;    // Port2 Output: 00000000 = 0x00
+    P2DIR = 0xFF;    // Port2 Direction: 11111111 = 0xFF
+
+
+    // Port 3: UART
+    P3SEL = 0xFE;    // Port3 Select: 11111110 = 0xFE
+    P3OUT = 0x00;    // Port3 Output: 00000000 = 0x00
+    P3DIR = 0xFF;    // Port3 Direction: 11111111 = 0xFF
+
+
+    // Port 4: CS
+    P4SEL = 0x00;    // Port4 Select: 00000000 = 0x00
+    P4OUT = 0x14;    // Port4 Output: 00010100 = 0x14
+    P4DIR = 0xFF;    // Port4 Direction: 11111111 = 0xFF
+
+    // Port 5: SPI, LED
+    P5SEL = 0x0E;    // Port5 Select: 00001110 = 0x0E
+    P5OUT = 0x70;    // Port5 Output: 01110000 = 0x70
+    P5DIR = 0x70;    // Port5 Direction: 01110000 = 0x70
+
+
+    P6SEL = 0xFF;    // Port6 Select: 11111111 = 0xFF
+    P6OUT = 0x00;    // Port6 Output: 00000000 = 0x00
+    P6DIR = 0xFF;    // Port6 Direction: 11111000 = 0xF8
+
+}
+
+void msp430_set_cpu_speed(uint32_t speed)
+{
+
+    dint();
+    __msp430_cpu_speed = speed;
+    msp430_init_dco();
+    uint16_t br;
+
+    U0CTL = SWRST;
+    U0CTL = SWRST | CHAR;          // 8-bit character
+    U0TCTL = SSEL1 | TXEPT;        // UCLK = SCLK
+    U0RCTL = 0;
+    // activate
+    ME1 |= UTXE0 + URXE0;          // Enable USART0 TXD/RXD
+    br = (uint16_t)((__msp430_cpu_speed & 0xFFFFF0) / 115200uL);
+    UBR00  = br;                   // set baudrate
+    UBR10  = br>>8;
+    UMCTL0 = calc_umctl(br);       // set modulation
+
+    U0CTL &= ~SWRST;
+
+    //URCTL0 |= URXEIE;            // allow chars to interrupt
+    IE1  |= URXIE0;                // enable rx interrupt
+    IFG1 &= ~UTXIFG0;
+    eint();
+}
+
+/*---------------------------------------------------------------------------*/
+void msp430_init_dco(void)
+{
+  /*----------------------- use external oszillator -------------------------*/
+  uint16_t i;
+
+  // Stop watchdog
+  WDTCTL = WDTPW + WDTHOLD;
+
+  BCSCTL1 = RSEL2;
+
+  // Wait for xtal to stabilize
+  do {
+    IFG1 &= ~OFIFG;                // Clear oscillator fault flag
+    for (i = 0xFF; i > 0; i--);    // Time for flag to set
+  }
+  while ((IFG1 & OFIFG) != 0);     // Oscillator fault flag still set?
+  switch (__msp430_cpu_speed) {
+  case MCLK_2MHZ_SCLK_1MHZ:
+      BCSCTL2  = (SELM_2 | DIVM_2) | (SELS | DIVS_3);
+      break;
+  case MCLK_4MHZ_SCLK_1MHZ:
+      BCSCTL2  = (SELM_2 | DIVM_1) | (SELS | DIVS_3);
+      break;
+  case MCLK_8MHZ_SCLK_1MHZ:
+      BCSCTL2 = SELM_2 | (SELS | DIVS_3);
+      break;
+  default:
+      BCSCTL2 = SELM_2 + SELS;     // MCLK and SMCLK = XT2 (safe)
+      break;
+  }
+}
+
+void board_init() {
+    msp430_cpu_init();
+    msb_ports_init();
+    
+    LED_RED_ON;
+   
+    msp430_set_cpu_speed(MCLK_8MHZ_SCLK_8MHZ);
+}
diff --git a/boards/wsn430-common/drivers/Makefile b/boards/wsn430-common/drivers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/boards/wsn430-common/include/board-conf.h b/boards/wsn430-common/include/board-conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..e54b3d58ebbc58fabb07698c74828aeb362e8ca2
--- /dev/null
+++ b/boards/wsn430-common/include/board-conf.h
@@ -0,0 +1,15 @@
+/**
+  * board-conf.h.
+  *
+  * This source code is licensed under the GNU Lesser General Public License,
+  * Version 2.  See the file LICENSE for more details.
+  */
+
+#ifndef BOARD_CONF_H
+#define BOARD_CONF_H 
+
+#include <stdint.h>
+
+#define INFOMEM     (0x1000)
+
+#endif /* BOARD-CONF_H */
diff --git a/boards/wsn430-common/uart0.c b/boards/wsn430-common/uart0.c
new file mode 100644
index 0000000000000000000000000000000000000000..f743335ec45ae011c9846d6bf449a0b6ffffc0a5
--- /dev/null
+++ b/boards/wsn430-common/uart0.c
@@ -0,0 +1,63 @@
+  /*
+   * uart0.c - Implementation of the uart.
+   * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de>
+   *
+   * This source code is licensed under the GNU General Public License,
+   * Version 3.  See the file LICENSE for more details.
+   */
+
+#include "board.h"
+
+#define   UART0_TX                        U0TXBUF
+#define   UART0_WAIT_TXDONE()       while( (U0TCTL & TXEPT) == 0 ) { _NOP(); }
+
+#include <stdio.h>
+#include <kernel.h>
+
+#include <board_uart0.h>
+
+int putchar(int c)
+{
+    UART0_TX = c;
+    UART0_WAIT_TXDONE();
+
+    if (c == 10) {
+        UART0_TX = 13;
+        UART0_WAIT_TXDONE();
+    }
+
+    return c;
+}
+
+void usart0irq(void);
+/**
+ * \brief the interrupt function
+ */
+interrupt(USART0RX_VECTOR) usart0irq(void) {
+    int dummy = 0;
+    /* Check status register for receive errors. */
+    if(U0RCTL & RXERR) {
+        if (U0RCTL & FE) {
+           puts("rx framing error");
+        }
+        if (U0RCTL & OE) {
+            puts("rx overrun error");
+        }
+        if (U0RCTL & PE) {
+            puts("rx parity error");
+        }
+        if (U0RCTL & BRK) {
+            puts("rx break error");
+        }
+        /* Clear error flags by forcing a dummy read. */
+        dummy = U0RXBUF;
+    }
+#ifdef MODULE_UART0
+    else if (uart0_handler_pid) {
+                dummy = U0RXBUF;
+                uart0_handle_incoming(dummy);
+                uart0_notify_thread();
+            }
+#endif
+}
+
diff --git a/boards/wsn430-v1_3b/Makefile b/boards/wsn430-v1_3b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e19884c6b16a2ab122bf20516fabb2807dce44b0
--- /dev/null
+++ b/boards/wsn430-v1_3b/Makefile
@@ -0,0 +1,36 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+export ARCH = wsn430-v1_3b_base.a
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I${RIOTBASE}/core/include/
+INCLUDES += -Iinclude/ -I$(RIOTBOARD)/wsn430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/ -I$(RIOTBASE)/cpu/msp430x16x/include/
+INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include/ -I$(RIOTBASE)/sys/include
+#INCLUDES += -I/usr/msp430/include/
+
+all: $(BINDIR)$(ARCH)
+	$(MAKE) -C ../wsn430-common
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	mkdir -p $(BINDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	$(MAKE) -C ../wsn430-common clean
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	@if [ -d $(BINDIR) ] ; \
+	then rmdir $(BINDIR) ; \
+	fi 
\ No newline at end of file
diff --git a/boards/wsn430-v1_3b/Makefile.dep b/boards/wsn430-v1_3b/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..5463317289b04329606c07807fe4002cb445d611
--- /dev/null
+++ b/boards/wsn430-v1_3b/Makefile.dep
@@ -0,0 +1,7 @@
+ifneq (,$(findstring cc110x_ng,$(USEMODULE)))
+    ifeq (,$(findstring cc110x_spi,$(USEMODULE)))
+        USEMODULE += cc110x_spi
+    endif
+endif
+
+USEMODULE += msp430_common
\ No newline at end of file
diff --git a/boards/wsn430-v1_3b/Makefile.include b/boards/wsn430-v1_3b/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..267a2fb9cda4bc27178d4f07738494bfe6b2717d
--- /dev/null
+++ b/boards/wsn430-v1_3b/Makefile.include
@@ -0,0 +1,4 @@
+export INCLUDES += -I$(RIOTBOARD)/wsn430-common/include
+include $(RIOTBOARD)/$(BOARD)/Makefile.dep
+
+include $(RIOTBOARD)/wsn430-common/Makefile.include
diff --git a/boards/wsn430-v1_3b/driver_cc110x.c b/boards/wsn430-v1_3b/driver_cc110x.c
new file mode 100644
index 0000000000000000000000000000000000000000..89669e64f7693bd582255c4b9f7c2fae75ca00df
--- /dev/null
+++ b/boards/wsn430-v1_3b/driver_cc110x.c
@@ -0,0 +1,207 @@
+  /*
+   * driver_cc110x.c - Implementation of the board dependent cc1100 functions.
+   * Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
+   * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de>
+   *
+   * This source code is licensed under the GNU Lesser General Public License,
+   * Version 2.  See the file LICENSE for more details.
+   */
+
+#include <stdio.h>
+
+#include <board.h>
+#include <cpu.h>
+#include <irq.h>
+
+#include <cc110x_ng.h>
+#include <cc110x-arch.h>
+
+#define CC1100_GDO0         (P1IN & 0x08)   // read serial I/O (GDO0)
+#define CC1100_GDO1         (P5IN & 0x04)   // read serial I/O (GDO1)
+#define CC1100_GDO2         (P1IN & 0x10)   // read serial I/O (GDO2)
+
+#define CC1100_CS_LOW       (P4OUT &= ~0x04)
+#define CC1100_CS_HIGH      (P4OUT |= 0x04)
+
+#define CC1100_GDO1_LOW_COUNT            (2700)          // loop count (timeout ~ 500 us) to wait
+#define CC1100_GDO1_LOW_RETRY             (100)          // max. retries for GDO1 to go low
+
+volatile int abort_count;
+volatile int retry_count = 0;
+
+void cc110x_gdo0_enable(void)
+{
+    P1IFG &= ~0x08;     /* Clear IFG for GDO0 */
+    P1IE |= 0x08;       /* Enable interrupt for GDO0 */
+}
+
+void cc110x_gdo0_disable(void)
+{
+    P1IE &= ~0x08;      /* Disable interrupt for GDO0 */
+    P1IFG &= ~0x08;     /* Clear IFG for GDO0 */
+}
+
+void cc110x_gdo2_enable(void)
+{
+    P1IFG &= ~0x10;     /* Clear IFG for GDO2 */
+    P1IE |= 0x10;       /* Enable interrupt for GDO2 */
+}
+
+void cc110x_gdo2_disable(void)
+{
+    P1IE &= ~0x10;      /* Disable interrupt for GDO2 */
+    P1IFG &= ~0x10;     /* Clear IFG for GDO2 */
+}
+
+void cc110x_before_send(void)
+{
+    // Disable GDO2 interrupt before sending packet
+    cc110x_gdo2_disable();
+}
+
+void cc110x_after_send(void)
+{
+    // Enable GDO2 interrupt after sending packet
+    cc110x_gdo2_enable();
+}
+
+
+int cc110x_get_gdo0(void) {
+        return  CC1100_GDO0;
+}
+
+int cc110x_get_gdo1(void) {
+        return  CC1100_GDO1;
+}
+
+int cc110x_get_gdo2(void) {
+        return  CC1100_GDO2;
+}
+
+void cc110x_spi_cs(void)
+{
+    CC1100_CS_LOW;
+}
+
+uint8_t cc110x_txrx(uint8_t data)
+{
+    /* Ensure TX Buf is empty */
+    long c = 0;
+    IFG2 &= ~UTXIFG1;
+    IFG2 &= ~URXIFG1;
+    U1TXBUF = data;
+    while(!(IFG2 & UTXIFG1)) {
+        if (c++ == 1000000) {
+            puts("cc110x_txrx alarm()");
+        }
+    }
+    /* Wait for Byte received */
+    c = 0;
+    while(!(IFG2 & URXIFG1)) {
+        if (c++ == 1000000) {
+            puts("cc110x_txrx alarm()");
+        }
+    }
+    return U1RXBUF;
+}
+
+
+void cc110x_spi_select(void)
+{
+    // Switch to GDO mode
+    P5SEL &= ~0x04;
+    P5DIR &= ~0x04;
+    cs_low:
+    // CS to low
+    abort_count = 0;
+    CC1100_CS_LOW;
+    // Wait for SO to go low (voltage regulator
+    // has stabilized and the crystal is running)
+    loop:
+//    asm volatile ("nop");
+    if (CC1100_GDO1) {
+        abort_count++;
+        if (abort_count > CC1100_GDO1_LOW_COUNT) {
+            retry_count++;
+            if (retry_count > CC1100_GDO1_LOW_RETRY) {
+                puts("[CC1100 SPI] fatal error\n");
+                goto final;
+            }
+            CC1100_CS_HIGH;
+            goto cs_low;        // try again
+        }
+        goto loop;
+    }
+    final:
+    /* Switch to SPI mode */
+    P5SEL |= 0x04;
+}
+
+void cc110x_spi_unselect(void) {
+    CC1100_CS_HIGH;
+}
+
+void cc110x_init_interrupts(void)
+{
+    unsigned int state = disableIRQ(); /* Disable all interrupts */
+    P1SEL = 0x00;       /* must be <> 1 to use interrupts */
+    P1IES |= 0x10;      /* Enables external interrupt on low edge (for GDO2) */
+    P1IE |= 0x10;       /* Enable interrupt */
+    P1IFG &= ~0x10;     /* Clears the interrupt flag */
+    P1IE &= ~0x08;      /* Disable interrupt for GDO0 */
+    P1IFG &= ~0x08;     /* Clear IFG for GDO0 */
+    restoreIRQ(state);  /* Enable all interrupts */
+}
+
+void cc110x_spi_init(uint8_t clockrate)
+{
+    // Switch off async UART
+    while(!(U1TCTL & TXEPT));   // Wait for empty UxTXBUF register
+    IE2 &= ~(URXIE1 + UTXIE1);  // Disable USART1 receive&transmit interrupt
+    ME2 &= ~(UTXE1 + URXE1);
+    P5DIR |= 0x0A;              // output for CLK and SIMO
+    P5DIR &= ~(0x04);           // input for SOMI
+    P5SEL |= 0x0E;              // Set pins as SPI
+
+    // Keep peripheral in reset state
+    U1CTL  = SWRST;
+
+    // 8-bit SPI Master 3-pin mode, with SMCLK as clock source
+    // CKPL works also, but not CKPH+CKPL or none of them!!
+    U1CTL |= CHAR + SYNC + MM;
+    U1TCTL = CKPH + SSEL1 + SSEL0 + STC;
+    
+    // Ignore clockrate argument for now, just use clock source/2
+    // SMCLK = 8 MHz
+    U1BR0 = 0x02;  // Ensure baud rate >= 2
+    U1BR1 = 0x00;
+    U1MCTL = 0x00; // No modulation
+    U1RCTL = 0x00; // Reset Receive Control Register
+   
+    // Enable SPI mode
+    ME2 |= USPIE1;
+
+    // Release for operation
+    U1CTL  &= ~SWRST;
+}
+
+/*
+ * CC1100 receive interrupt
+ */
+interrupt (PORT1_VECTOR) __attribute__ ((naked)) cc110x_isr(void){
+    __enter_isr();
+     /* Check IFG */
+    if ((P1IFG & 0x10) != 0) {
+        P1IFG &= ~0x10;
+        cc110x_gdo2_irq();
+    }
+    else if ((P2IFG & 0x08) != 0) {
+        cc110x_gdo0_irq();
+        P1IE &= ~0x08;                // Disable interrupt for GDO0
+           P1IFG &= ~0x08;                // Clear IFG for GDO0
+    } else {
+        puts("cc110x_isr(): unexpected IFG!");
+        /* Should not occur - only GDO1 and GDO2 interrupts are enabled */
+    }
+    __exit_isr();
+}
diff --git a/boards/wsn430-v1_3b/include/board.h b/boards/wsn430-v1_3b/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a23fdf8d7ae77f133ba48d19744350a63b4fe43
--- /dev/null
+++ b/boards/wsn430-v1_3b/include/board.h
@@ -0,0 +1,65 @@
+/**
+  * board.h - wsn430-v1_3b Board.
+  * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de>
+  *
+  * This source code is licensed under the GNU Lesser General Public License,
+  * Version 2.  See the file LICENSE for more details.
+  */
+
+#ifndef _WSN_BOARD_H
+#define _WSN_BOARD_H
+
+/**
+ * @defgroup	wsn430-v1_3b		Senslab WSN430 v1.3b
+ * @ingroup		wsn430
+ *
+<h2>Compontents</h2>
+\li MSP430
+\li CC1100
+
+* @{
+*/
+
+/**
+ * @file
+ * @brief		wsn430-v1_3b Board
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author      Milan Babel <babel@inf.fu-berlin.de>
+ * @version     $Revision$
+ *
+ * @note		$Id$
+ */
+
+#include "board-conf.h"
+
+//MSB430 core
+#define MSP430_INITIAL_CPU_SPEED    800000uL
+#define MSP430_HAS_DCOR             0
+#define MSP430_HAS_EXTERNAL_CRYSTAL 1
+
+/* LEDs ports MSB430 */
+#define LEDS_PxDIR P5DIR
+#define LEDS_PxOUT P5OUT
+#define LEDS_CONF_RED		0x04
+#define LEDS_CONF_GREEN		0x05
+#define LEDS_CONF_BLUE	0x06
+
+#define LED_RED_ON      LEDS_PxOUT &=~LEDS_CONF_RED
+#define LED_RED_OFF     LEDS_PxOUT |= LEDS_CONF_RED
+#define LED_RED_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_RED
+
+#define LED_GREEN_ON      LEDS_PxOUT &=~LEDS_CONF_GREEN
+#define LED_GREEN_OFF     LEDS_PxOUT |= LEDS_CONF_GREEN
+#define LED_GREEN_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_GREEN
+
+#define LED_BLUE_ON      LEDS_PxOUT &=~LEDS_CONF_BLUE
+#define LED_BLUE_OFF     LEDS_PxOUT |= LEDS_CONF_BLUE
+#define LED_BLUE_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_BLUE
+
+#include <msp430x16x.h>
+
+typedef uint8_t radio_packet_length_t;
+
+/** @} */
+#endif // _WSN_BOARD_H
diff --git a/boards/wsn430-v1_4/Makefile b/boards/wsn430-v1_4/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5e426ffbd9fa12ee56ad03f9009aa5a146949d88
--- /dev/null
+++ b/boards/wsn430-v1_4/Makefile
@@ -0,0 +1,35 @@
+SRC = $(wildcard *.c)
+BINDIR = bin/
+OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
+export ARCH = wsn430-v1_4_base.a
+
+DEP = $(SRC:%.c=$(BINDIR)%.d)
+
+INCLUDES += -I${RIOTBASE}/core/include/
+INCLUDES += -Iinclude/ -I$(RIOTBOARD)/wsn430-common/include/
+INCLUDES += -I$(RIOTBASE)/cpu/msp430-common/include/ -I$(RIOTBASE)/cpu/msp430x16x/include/
+INCLUDES += -I$(RIOTBASE)/drivers/cc2420/include/ -I$(RIOTBASE)/sys/include
+
+all: $(BINDIR)$(ARCH)
+	$(MAKE) -C ../wsn430-common
+
+$(BINDIR)$(ARCH): $(OBJ)
+	$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
+
+# pull in dependency info for *existing* .o files
+-include $(OBJ:.o=.d)
+
+# compile and generate dependency info
+$(BINDIR)%.o: %.c
+	mkdir -p $(BINDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
+	$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
+	@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
+
+# remove compilation products
+clean:
+	$(MAKE) -C ../wsn430-common clean
+	rm -f $(BINDIR)$(ARCH) $(OBJ) $(DEP)
+	@if [ -d $(BINDIR) ] ; \
+	then rmdir $(BINDIR) ; \
+	fi
diff --git a/boards/wsn430-v1_4/Makefile.dep b/boards/wsn430-v1_4/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..52516208bc266a0510f6bd38d1badcfd4f8e37c1
--- /dev/null
+++ b/boards/wsn430-v1_4/Makefile.dep
@@ -0,0 +1 @@
+USEMODULE += msp430_common
\ No newline at end of file
diff --git a/boards/wsn430-v1_4/Makefile.include b/boards/wsn430-v1_4/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..267a2fb9cda4bc27178d4f07738494bfe6b2717d
--- /dev/null
+++ b/boards/wsn430-v1_4/Makefile.include
@@ -0,0 +1,4 @@
+export INCLUDES += -I$(RIOTBOARD)/wsn430-common/include
+include $(RIOTBOARD)/$(BOARD)/Makefile.dep
+
+include $(RIOTBOARD)/wsn430-common/Makefile.include
diff --git a/boards/wsn430-v1_4/driver_cc2420.c b/boards/wsn430-v1_4/driver_cc2420.c
new file mode 100644
index 0000000000000000000000000000000000000000..c653c9ba3aca47b966f2eb9602f6eb6f2b928a02
--- /dev/null
+++ b/boards/wsn430-v1_4/driver_cc2420.c
@@ -0,0 +1,213 @@
+  /*
+   * driver_cc2420.c - Implementation of the board dependent cc2420 functions.
+   * Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
+   * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de>
+   *
+   * This source code is licensed under the GNU Lesser General Public License,
+   * Version 2.  See the file LICENSE for more details.
+   */
+
+#include <stdio.h>
+
+#include <board.h>
+#include <cpu.h>
+#include <irq.h>
+#include <hwtimer.h>
+
+#include <cc2420.h>
+
+#define CC2420_RESETn_PIN   0x80
+#define CC2420_VREGEN_PIN   0x01
+
+#define CC2420_GDO0_PIN     0x08
+#define CC2420_GDO2_PIN     0x10
+#define CC2420_SFD_PIN      0x20
+#define CC2420_CCA_PIN      0x40
+
+#define CC2420_GDO0         (P1IN & CC2420_GDO0_PIN)   // read serial I/O (GDO0)
+#define CC2420_GDO2         (P1IN & CC2420_GDO2_PIN)   // read serial I/O (GDO2)
+#define CC2420_SFD          (P1IN & CC2420_SFD_PIN)    // read serial I/0 (SFD)
+#define CC2420_CCA          (P1IN & CC2420_CCA_PIN)    // read serial I/O (CCA)
+
+
+#define CC2420_CS_LOW       (P4OUT &= ~0x04)
+#define CC2420_CS_HIGH      (P4OUT |= 0x04)
+
+#define CC2420_GDO1_LOW_COUNT            (2700)          // loop count (timeout ~ 500 us) to wait
+#define CC2420_GDO1_LOW_RETRY             (100)          // max. retries for GDO1 to go low
+
+volatile int abort_count;
+volatile int retry_count = 0;
+
+void cc2420_reset(void)
+{
+    P3OUT |= CC2420_VREGEN_PIN;
+    P1OUT &= ~CC2420_RESETn_PIN;
+    hwtimer_wait(500);
+    P1OUT |= CC2420_RESETn_PIN;
+}
+
+void cc2420_gdo0_enable(void)
+{
+    P1IFG &= ~CC2420_GDO0_PIN;     /* Clear IFG for GDO0 */
+    P1IE |= CC2420_GDO0_PIN;       /* Enable interrupt for GDO0 */
+}
+
+void cc2420_gdo0_disable(void)
+{
+    P1IE &= ~CC2420_GDO0_PIN;      /* Disable interrupt for GDO0 */
+    P1IFG &= ~CC2420_GDO0_PIN;     /* Clear IFG for GDO0 */
+}
+
+void cc2420_gdo2_enable(void)
+{
+    P1IFG &= ~CC2420_GDO2_PIN;     /* Clear IFG for GDO2 */
+    P1IE |= CC2420_GDO2_PIN;       /* Enable interrupt for GDO2 */
+}
+
+void cc2420_gdo2_disable(void)
+{
+    P1IE &= ~CC2420_GDO2_PIN;      /* Disable interrupt for GDO2 */
+    P1IFG &= ~CC2420_GDO2_PIN;     /* Clear IFG for GDO2 */
+}
+
+void cc2420_before_send(void)
+{
+    // Disable SFD interrupt before sending packet
+    // However this is not used atm
+}
+
+void cc2420_after_send(void)
+{
+    // Enable SFD interrupt after sending packet
+    // However this is not used atm
+}
+
+
+int cc2420_get_gdo0(void)
+{
+    return  CC2420_GDO0;
+}
+
+int cc2420_get_gdo2(void)
+{
+    return  CC2420_GDO2;
+}
+
+int cc2420_get_sfd(void)
+{
+    return CC2420_SFD;
+}
+
+void cc2420_spi_cs(void)
+{
+    CC2420_CS_LOW;
+}
+
+uint8_t cc2420_txrx(uint8_t data)
+{
+    /* Ensure TX Buf is empty */
+    long c = 0;
+    IFG2 &= ~UTXIFG1;
+    IFG2 &= ~URXIFG1;
+    U1TXBUF = data;
+    while(!(IFG2 & UTXIFG1)) {
+        if (c++ == 1000000) {
+            puts("cc2420_txrx alarm()");
+        }
+    }
+    /* Wait for Byte received */
+    c = 0;
+    while(!(IFG2 & URXIFG1)) {
+        if (c++ == 1000000) {
+            puts("cc2420_txrx alarm()");
+        }
+    }
+    return U1RXBUF;
+}
+
+
+void cc2420_spi_select(void)
+{
+    CC2420_CS_LOW;
+}
+
+void cc2420_spi_unselect(void) {
+    CC2420_CS_HIGH;
+}
+
+void cc2420_init_interrupts(void)
+{
+    unsigned int state = disableIRQ(); /* Disable all interrupts */
+    P1SEL = 0x00;       /* must be <> 1 to use interrupts */
+    P1IES |= CC2420_GDO2_PIN;      /* Enables external interrupt on falling edge (for GDO2) */
+    P1IE |= CC2420_GDO2_PIN;       /* Enable interrupt */
+    P1IFG &= ~CC2420_GDO2_PIN;     /* Clears the interrupt flag */
+    P1IES |= CC2420_SFD_PIN;      /* Enables external interrupt on falling edge (for GDO2) */
+    P1IE |= CC2420_SFD_PIN;       /* Enable interrupt */
+    P1IFG &= ~CC2420_SFD_PIN;     /* Clears the interrupt flag */
+    P1IE &= ~CC2420_GDO0_PIN;      /* Disable interrupt for GDO0 */
+    P1IFG &= ~CC2420_GDO0_PIN;     /* Clear IFG for GDO0 */
+    restoreIRQ(state);  /* Enable all interrupts */
+}
+
+void cc2420_spi_init(void)
+{
+    // Switch off async UART
+    while(!(U1TCTL & TXEPT));   // Wait for empty UxTXBUF register
+    IE2 &= ~(URXIE1 + UTXIE1);  // Disable USART1 receive&transmit interrupt
+    ME2 &= ~(UTXE1 + URXE1);
+    P5DIR |= 0x0A;              // output for CLK and SIMO
+    P5DIR &= ~(0x04);           // input for SOMI
+    P5SEL |= 0x0E;              // Set pins as SPI
+
+    // Keep peripheral in reset state
+    U1CTL  = SWRST;
+
+    // 8-bit SPI Master 3-pin mode, with SMCLK as clock source
+    // CKPL works also, but not CKPH+CKPL or none of them!!
+    U1CTL |= CHAR + SYNC + MM;
+    U1TCTL = CKPH + SSEL1 + SSEL0 + STC;
+    
+    // Ignore clockrate argument for now, just use clock source/2
+    // SMCLK = 8 MHz
+    U1BR0 = 0x02;  // Ensure baud rate >= 2
+    U1BR1 = 0x00;
+    U1MCTL = 0x00; // No modulation
+    U1RCTL = 0x00; // Reset Receive Control Register
+   
+    // Enable SPI mode
+    ME2 |= USPIE1;
+
+    // Release for operation
+    U1CTL  &= ~SWRST;
+}
+
+/*
+ * CC1100 receive interrupt
+ */
+interrupt (PORT1_VECTOR) __attribute__ ((naked)) cc2420_isr(void){
+    __enter_isr();
+     /* Check IFG */
+    if ((P1IFG & CC2420_GDO2_PIN) != 0) {
+        puts("rx interrupt");
+        P1IFG &= ~CC2420_GDO2_PIN;
+        cc2420_rx_irq();
+    }
+    else if ((P1IFG & CC2420_GDO0_PIN) != 0) {
+        cc2420_rxoverflow_irq();
+        puts("[CC2420] rxfifo overflow");
+        //P1IE &= ~CC2420_GDO0_PIN;                // Disable interrupt for GDO0
+        P1IFG &= ~CC2420_GDO0_PIN;                // Clear IFG for GDO0
+    } else if ((P1IFG & CC2420_SFD_PIN) != 0) {
+        puts("sfd interrupt");
+        P1IFG &= ~CC2420_SFD_PIN;
+        cc2420_switch_to_rx();
+    }
+
+    else {
+        puts("cc2420_isr(): unexpected IFG!");
+        /* Should not occur - only GDO1 and GDO2 interrupts are enabled */
+    }
+    __exit_isr();
+}
diff --git a/boards/wsn430-v1_4/include/board.h b/boards/wsn430-v1_4/include/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..092bc76998d9bed41afa985c745aafbdb82f5123
--- /dev/null
+++ b/boards/wsn430-v1_4/include/board.h
@@ -0,0 +1,65 @@
+/**
+  * board.h - wsn430-v1_4 Board.
+  * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de>
+  *
+  * This source code is licensed under the GNU Lesser General Public License,
+  * Version 2.  See the file LICENSE for more details.
+  */
+
+#ifndef _WSN_BOARD_H
+#define _WSN_BOARD_H
+
+/**
+ * @defgroup	wsn430-v1_4		Senslab WSN430 v1.4
+ * @ingroup		wsn430
+ *
+<h2>Compontents</h2>
+\li MSP430
+\li CC2420
+
+* @{
+*/
+
+/**
+ * @file
+ * @brief		wsn430-v1_4 Board
+ *
+ * @author      Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
+ * @author      Milan Babel <babel@inf.fu-berlin.de>
+ * @version     $Revision$
+ *
+ * @note		$Id$
+ */
+
+#include "board-conf.h"
+
+//MSB430 core
+#define MSP430_INITIAL_CPU_SPEED    800000uL
+#define MSP430_HAS_DCOR             0
+#define MSP430_HAS_EXTERNAL_CRYSTAL 1
+
+/* LEDs ports MSB430 */
+#define LEDS_PxDIR P5DIR
+#define LEDS_PxOUT P5OUT
+#define LEDS_CONF_RED		0x04
+#define LEDS_CONF_GREEN		0x05
+#define LEDS_CONF_BLUE	0x06
+
+#define LED_RED_ON      LEDS_PxOUT &=~LEDS_CONF_RED
+#define LED_RED_OFF     LEDS_PxOUT |= LEDS_CONF_RED
+#define LED_RED_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_RED
+
+#define LED_GREEN_ON      LEDS_PxOUT &=~LEDS_CONF_GREEN
+#define LED_GREEN_OFF     LEDS_PxOUT |= LEDS_CONF_GREEN
+#define LED_GREEN_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_GREEN
+
+#define LED_BLUE_ON      LEDS_PxOUT &=~LEDS_CONF_BLUE
+#define LED_BLUE_OFF     LEDS_PxOUT |= LEDS_CONF_BLUE
+#define LED_BLUE_TOGGLE     LEDS_PxOUT ^= LEDS_CONF_BLUE
+
+#include <msp430x16x.h>
+
+typedef uint8_t radio_packet_length_t;
+
+/** @} */
+#endif // _WSN_BOARD_H