Change directory structure to align with Atmel softpack

This way we can easily check with 'diff' for differences in our code and
Atmel softpack.  Also, this layout is more suitable for building various
different firmware images (e.g. factory-test, dfu-loader, main
application) for a variety of different boards (simtrace, owhw, qmod).
diff --git a/firmware/libboard/common/include/board_common.h b/firmware/libboard/common/include/board_common.h
new file mode 100644
index 0000000..9943ae1
--- /dev/null
+++ b/firmware/libboard/common/include/board_common.h
@@ -0,0 +1,121 @@
+#ifndef _BOARD_
+#define _BOARD_
+
+/**     Headers     */
+#include "chip.h"
+/* We need this for a nop instruction in USB_HAL.c */
+#define __CC_ARM
+
+/**     Board       */
+#include "board_lowlevel.h"
+#include "uart_console.h"
+#include "iso7816_4.h"
+#include "led.h"
+#include "cciddriver.h"
+#include "usart.h"
+#include "USBD.h"
+
+#include "USBD_Config.h"
+#include "USBDDriver.h"
+
+/**     Highlevel   */
+#include "trace.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "inttypes.h"
+#include "syscalls.h"
+
+#define MIN(a, b)       ((a < b) ? a : b)
+
+#ifdef __GNUC__ 
+#undef __GNUC__ 
+#endif
+
+/** Family definition (already defined) */
+#define sam3s
+/** Core definition */
+#define cortexm3
+
+#define BOARD_MCK     48000000
+
+#define LED_RED PIO_PA17
+#define LED_GREEN PIO_PA18
+
+#define PIN_LED_RED     {LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define PIN_LED_GREEN   {LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define PINS_LEDS       PIN_LED_RED, PIN_LED_GREEN 
+
+#define LED_NUM_RED     0
+#define LED_NUM_GREEN   1
+
+/** USART0 pin RX */
+#define PIN_USART0_RXD    {PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/** USART0 pin TX */
+#define PIN_USART0_TXD    {PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+
+#define BOARD_PIN_USART_RXD     PIN_USART0_RXD
+#define BOARD_PIN_USART_TXD     PIN_USART0_TXD
+
+#define BOARD_ID_USART          ID_USART0
+#define BOARD_USART_BASE        USART0
+
+#define PINS_UART  { PIO_PA9A_URXD0|PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+
+/** UART0 */
+/** Console baudrate always using 115200. */
+#define CONSOLE_BAUDRATE    115200
+/** Usart Hw interface used by the console (UART0). */
+#define CONSOLE_USART       UART0
+/** Usart Hw ID used by the console (UART0). */
+#define CONSOLE_ID          ID_UART0
+/** Pins description corresponding to Rxd,Txd, (UART pins) */
+#define CONSOLE_PINS        {PINS_UART}
+
+/// Smartcard detection pin
+// FIXME: add connect pin as iso pin...should it be periph b or interrupt oder input?
+#define BOARD_ISO7816_BASE_USART    USART0
+#define BOARD_ISO7816_ID_USART      ID_USART0
+
+#define USART_SIM       USART0
+#define ID_USART_SIM    ID_USART0
+#define USART_PHONE       USART1
+#define ID_USART_PHONE    ID_USART1
+
+#define SIM_PWEN        PIO_PA5
+#define VCC_FWD         PIO_PA26
+
+
+//**     USB **/
+// USB pull-up control pin definition (PA16).
+// Default: 1 (USB Pullup deactivated) 
+#define PIN_USB_PULLUP  {1 << 16, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+// Board has UDP controller
+#define BOARD_USB_UDP
+// D+ has external pull-up
+#define BOARD_USB_PULLUP_EXTERNAL
+
+#define BOARD_USB_NUMENDPOINTS      8
+
+// FIXME: in all other cases return 0?
+#define BOARD_USB_ENDPOINTS_MAXPACKETSIZE(i)    (((i == 4) || (i == 5))? 512 : 64)
+#define BOARD_USB_ENDPOINTS_BANKS(i)            (((i == 0) || (i == 3)) ? 1 : 2)
+
+/// USB attributes configuration descriptor (bus or self powered, remote wakeup)
+//#define BOARD_USB_BMATTRIBUTES                  USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
+#define BOARD_USB_BMATTRIBUTES                  USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
+//#define BOARD_USB_BMATTRIBUTES                  USBConfigurationDescriptor_SELFPOWERED_RWAKEUP
+
+#define BOARD_USB_VENDOR	SIMTRACE_VENDOR_ID
+#define BOARD_USB_PRODUCT	SIMTRACE_PRODUCT_ID
+#define BOARD_USB_RELEASE	0
+
+#define BOARD_USB_DFU
+#define BOARD_DFU_BOOT_SIZE	(16 * 1024)
+#define BOARD_DFU_PAGE_SIZE	512
+#define BOARD_DFU_NUM_IF	2
+
+extern void board_exec_dbg_cmd(int ch);
+extern void board_main_top(void);
+#endif
diff --git a/firmware/libboard/common/include/board_lowlevel.h b/firmware/libboard/common/include/board_lowlevel.h
new file mode 100644
index 0000000..cc6cdbe
--- /dev/null
+++ b/firmware/libboard/common/include/board_lowlevel.h
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ * \file
+ *
+ * Interface for the low-level initialization function.
+ *
+ */
+
+#ifndef BOARD_LOWLEVEL_H
+#define BOARD_LOWLEVEL_H
+
+/*----------------------------------------------------------------------------
+ *        Exported functions
+ *----------------------------------------------------------------------------*/
+extern void LowLevelInit( void ) ;
+
+#endif /* BOARD_LOWLEVEL_H */
+
diff --git a/firmware/libboard/common/include/boardver_adc.h b/firmware/libboard/common/include/boardver_adc.h
new file mode 100644
index 0000000..a89d630
--- /dev/null
+++ b/firmware/libboard/common/include/boardver_adc.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int get_board_version_adc(void);
diff --git a/firmware/libboard/common/include/led.h b/firmware/libboard/common/include/led.h
new file mode 100644
index 0000000..87e2fc9
--- /dev/null
+++ b/firmware/libboard/common/include/led.h
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support 
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ * \file
+ *
+ *  \section Purpose
+ * 
+ *  Small set of functions for simple and portable LED usage.
+ * 
+ *  \section Usage
+ * 
+ *  -# Configure one or more LEDs using LED_Configure and
+ *     LED_ConfigureAll.
+ *  -# Set, clear and toggle LEDs using LED_Set, LED_Clear and
+ *     LED_Toggle.
+ * 
+ *  LEDs are numbered starting from 0; the number of LEDs depend on the
+ *  board being used. All the functions defined here will compile properly
+ *  regardless of whether the LED is defined or not; they will simply
+ *  return 0 when a LED which does not exist is given as an argument.
+ *  Also, these functions take into account how each LED is connected on to
+ *  board; thus, \ref LED_Set might change the level on the corresponding pin
+ *  to 0 or 1, but it will always light the LED on; same thing for the other
+ *  methods.
+ */
+
+#ifndef _LED_
+#define _LED_
+
+#include <stdint.h>
+
+//------------------------------------------------------------------------------
+//         Global Functions
+//------------------------------------------------------------------------------
+
+extern uint32_t LED_Configure( uint32_t dwLed ) ;
+
+extern uint32_t LED_Set( uint32_t dwLed ) ;
+
+extern uint32_t LED_Clear( uint32_t dwLed ) ;
+
+extern uint32_t LED_Toggle( uint32_t dwLed ) ;
+
+#endif /* #ifndef LED_H */
+
diff --git a/firmware/libboard/common/include/uart_console.h b/firmware/libboard/common/include/uart_console.h
new file mode 100644
index 0000000..c48c2c1
--- /dev/null
+++ b/firmware/libboard/common/include/uart_console.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+
+#ifndef _UART_CONSOLE_
+#define _UART_CONSOLE_
+
+#include <stdint.h>
+
+extern void UART_Configure( uint32_t dwBaudrate, uint32_t dwMasterClock ) ;
+extern void UART_PutChar( uint8_t uc ) ;
+extern uint32_t UART_GetChar( void ) ;
+extern uint32_t UART_IsRxReady( void ) ;
+
+
+extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize ) ;
+extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress ) ;
+extern uint32_t UART_GetInteger( uint32_t* pdwValue ) ;
+extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint32_t dwMax ) ;
+extern uint32_t UART_GetHexa32( uint32_t* pdwValue ) ;
+
+#endif /* _UART_CONSOLE_ */
diff --git a/firmware/libboard/common/resources/sam3s1/flash.ld b/firmware/libboard/common/resources/sam3s1/flash.ld
new file mode 100644
index 0000000..b6c5428
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s1/flash.ld
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal FLASH on the ATSAM3S1
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+	rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00010000 /* Flash, 64K */
+	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
+}
+
+/* Section Definitions */ 
+SECTIONS 
+{ 
+    .text : 
+    { 
+        . = ALIGN(4);
+        _sfixed = .;
+        KEEP(*(.vectors .vectors.*))
+        *(.text .text.* .gnu.linkonce.t.*) 	      
+        *(.glue_7t) *(.glue_7)		                
+        *(.rodata .rodata* .gnu.linkonce.r.*)		    	                  
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+
+        /* Support C constructors, and C destructors in both user code
+           and the C library. This also provides support for C++ code. */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(0x4);
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+
+        . = ALIGN(4);
+        _efixed = .;            /* End of text section */
+    } > rom
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    PROVIDE_HIDDEN (__exidx_start = .);
+    .ARM.exidx :
+    {
+      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > rom
+    PROVIDE_HIDDEN (__exidx_end = .);
+
+    . = ALIGN(4); 
+    _etext = .;
+
+    .relocate : AT (_etext)
+    {
+        . = ALIGN(4);
+        _srelocate = .;
+        *(.ramfunc .ramfunc.*);
+        *(.data .data.*);
+        . = ALIGN(4);
+        _erelocate = .;
+    } > ram
+
+    /* .bss section which is used for uninitialized data */ 
+    .bss (NOLOAD) :
+    { 
+        . = ALIGN(4);
+        _sbss = . ;
+        _szero = .;
+        *(.bss .bss.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = . ;
+        _ezero = .;
+    } > ram
+
+    /* stack section */
+    .stack (NOLOAD):
+    {
+        . = ALIGN(8);
+        *(.stack .stack.*)
+    } > ram
+
+    . = ALIGN(4); 
+    _end = . ; 
+}
diff --git a/firmware/libboard/common/resources/sam3s1/sram.ld b/firmware/libboard/common/resources/sam3s1/sram.ld
new file mode 100644
index 0000000..22b170a
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s1/sram.ld
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal SRAM on the ATSAM3S1
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+	rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00010000 /* Flash, 64K */
+	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
+}
+
+/* Section Definitions */ 
+SECTIONS 
+{ 
+    .text : 
+    { 
+        . = ALIGN(4);
+        _sfixed = .;
+        KEEP(*(.vectors .vectors.*))
+        *(.text .text.* .gnu.linkonce.t.*) 	      
+        *(.glue_7t) *(.glue_7)		                
+        *(.rodata .rodata* .gnu.linkonce.r.*)		    	                  
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+
+        /* Support C constructors, and C destructors in both user code
+           and the C library. This also provides support for C++ code. */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(0x4);
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+
+        . = ALIGN(4);
+        _efixed = .;            /* End of text section */
+    } > ram
+
+    . = ALIGN(4); 
+    _etext = .;
+
+    .relocate : AT (_etext)
+    {
+        . = ALIGN(4);
+        _srelocate = .;
+        *(.ramfunc .ramfunc.*);
+        *(.data .data.*);
+        . = ALIGN(4);
+        _erelocate = .;
+    } > ram
+
+    /* .bss section which is used for uninitialized data */ 
+    .bss (NOLOAD) :
+    { 
+        . = ALIGN(4);
+        _sbss = . ;
+        _szero = .;
+        *(.bss .bss.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = . ;
+        _ezero = .;
+    } > ram
+
+    /* stack section */
+    .stack (NOLOAD):
+    {
+        . = ALIGN(8);
+        *(.stack .stack.*)
+    } > ram
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    PROVIDE_HIDDEN (__exidx_start = .);
+    .ARM.exidx :
+    {
+      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > ram
+    PROVIDE_HIDDEN (__exidx_end = .);
+
+    . = ALIGN(4); 
+    _end = . ; 
+}
diff --git a/firmware/libboard/common/resources/sam3s1/sram_samba.lds b/firmware/libboard/common/resources/sam3s1/sram_samba.lds
new file mode 100644
index 0000000..0f87ad3
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s1/sram_samba.lds
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal SRAM on the AT91SAM3S1
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(entry)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+    romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
+    sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00003800 /* sram, 16K - sizeof(romcodesram) */
+}
+
+/* Entry point */
+/*ENTRY (ResetException)*/
+
+SECTIONS
+{
+    /* startup code in the .isr_vector */
+    .text :
+    {
+        . = ALIGN(4);
+        _stext = .;
+        KEEP(*(.isr_vector .isr_vector.*))
+        *(.mailbox)
+        *(.text .text.*)
+        *(.rodata .rodata.*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.gcc_except_table)
+        *(.rodata .rodata*)
+        *(.gnu.linkonce.r.*)
+        . = ALIGN(4);
+        _etext = .;
+    } > sram
+
+    /* data */
+    .data :
+    {
+        . = ALIGN(4);
+        _sidata = .;
+        _sdata = .;
+
+        *(.data)
+        *(.data.*)
+        . = ALIGN(4);
+        _edata = .;
+    } > sram
+
+    .bss (NOLOAD) : {
+        _szero = .;
+        *(.bss)
+        . = ALIGN(4);
+        _ezero = .;
+    } >sram
+
+    /* Stack in SRAM */
+    _sstack = 0x20003FFC;
+}
+end = .;
diff --git a/firmware/libboard/common/resources/sam3s2/flash.ld b/firmware/libboard/common/resources/sam3s2/flash.ld
new file mode 100644
index 0000000..22cfe59
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s2/flash.ld
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal FLASH on the ATSAM3S2
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+	rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00020000 /* flash, 128K */
+	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */
+}
+
+/* Section Definitions */ 
+SECTIONS 
+{ 
+    .text : 
+    { 
+        . = ALIGN(4);
+        _sfixed = .;
+        KEEP(*(.vectors .vectors.*))
+        *(.text .text.* .gnu.linkonce.t.*) 	      
+        *(.glue_7t) *(.glue_7)		                
+        *(.rodata .rodata* .gnu.linkonce.r.*)		    	                  
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+
+        /* Support C constructors, and C destructors in both user code
+           and the C library. This also provides support for C++ code. */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(0x4);
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+
+        . = ALIGN(4);
+        _efixed = .;            /* End of text section */
+    } > rom
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    PROVIDE_HIDDEN (__exidx_start = .);
+    .ARM.exidx :
+    {
+      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > rom
+    PROVIDE_HIDDEN (__exidx_end = .);
+
+    . = ALIGN(4); 
+    _etext = .;
+
+    .relocate : AT (_etext)
+    {
+        . = ALIGN(4);
+        _srelocate = .;
+        *(.ramfunc .ramfunc.*);
+        *(.data .data.*);
+        . = ALIGN(4);
+        _erelocate = .;
+    } > ram
+
+    /* .bss section which is used for uninitialized data */ 
+    .bss (NOLOAD) :
+    { 
+        . = ALIGN(4);
+        _sbss = . ;
+        _szero = .;
+        *(.bss .bss.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = . ;
+        _ezero = .;
+    } > ram
+
+    /* stack section */
+    .stack (NOLOAD):
+    {
+        . = ALIGN(8);
+        *(.stack .stack.*)
+    } > ram
+
+    . = ALIGN(4); 
+    _end = . ; 
+}
diff --git a/firmware/libboard/common/resources/sam3s2/sram.ld b/firmware/libboard/common/resources/sam3s2/sram.ld
new file mode 100644
index 0000000..8c14ac6
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s2/sram.ld
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal SRAM on the ATSAM3S2
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+	rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00020000 /* flash, 128K */
+	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */
+}
+
+/* Section Definitions */ 
+SECTIONS 
+{ 
+    .text : 
+    { 
+        . = ALIGN(4);
+        _sfixed = .;
+        KEEP(*(.vectors .vectors.*))
+        *(.text .text.* .gnu.linkonce.t.*) 	      
+        *(.glue_7t) *(.glue_7)		                
+        *(.rodata .rodata* .gnu.linkonce.r.*)		    	                  
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+
+        /* Support C constructors, and C destructors in both user code
+           and the C library. This also provides support for C++ code. */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(0x4);
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+
+        . = ALIGN(4);
+        _efixed = .;            /* End of text section */
+    } > ram
+
+    . = ALIGN(4); 
+    _etext = .;
+
+    .relocate : AT (_etext)
+    {
+        . = ALIGN(4);
+        _srelocate = .;
+        *(.ramfunc .ramfunc.*);
+        *(.data .data.*);
+        . = ALIGN(4);
+        _erelocate = .;
+    } > ram
+
+    /* .bss section which is used for uninitialized data */ 
+    .bss (NOLOAD) :
+    { 
+        . = ALIGN(4);
+        _sbss = . ;
+        _szero = .;
+        *(.bss .bss.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = . ;
+        _ezero = .;
+    } > ram
+
+    /* stack section */
+    .stack (NOLOAD):
+    {
+        . = ALIGN(8);
+        *(.stack .stack.*)
+    } > ram
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    PROVIDE_HIDDEN (__exidx_start = .);
+    .ARM.exidx :
+    {
+      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > ram
+    PROVIDE_HIDDEN (__exidx_end = .);
+
+    . = ALIGN(4); 
+    _end = . ; 
+}
diff --git a/firmware/libboard/common/resources/sam3s2/sram_samba.lds b/firmware/libboard/common/resources/sam3s2/sram_samba.lds
new file mode 100644
index 0000000..00040c8
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s2/sram_samba.lds
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal SRAM on the AT91SAM3S2
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(entry)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+    romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
+    sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00007800 /* sram, 32K - sizeof(romcodesram) */
+}
+
+/* Entry point */
+/*ENTRY (ResetException)*/
+
+SECTIONS
+{
+    /* startup code in the .isr_vector */
+    .text :
+    {
+        . = ALIGN(4);
+        _stext = .;
+        KEEP(*(.isr_vector .isr_vector.*))
+        *(.mailbox)
+        *(.text .text.*)
+        *(.rodata .rodata.*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.gcc_except_table)
+        *(.rodata .rodata*)
+        *(.gnu.linkonce.r.*)
+        . = ALIGN(4);
+        _etext = .;
+    } > sram
+
+    /* data */
+    .data :
+    {
+        . = ALIGN(4);
+        _sidata = .;
+        _sdata = .;
+
+        *(.data)
+        *(.data.*)
+        . = ALIGN(4);
+        _edata = .;
+    } > sram
+
+    .bss (NOLOAD) : {
+        _szero = .;
+        *(.bss)
+        . = ALIGN(4);
+        _ezero = .;
+    } >sram
+
+    /* Stack in SRAM */
+    _sstack = 0x20007FFC;
+}
+end = .;
diff --git a/firmware/libboard/common/resources/sam3s4/flash.ld b/firmware/libboard/common/resources/sam3s4/flash.ld
new file mode 100644
index 0000000..c47a2c5
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s4/flash.ld
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal FLASH on the ATSAM3S4
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+	rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
+	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c000 /* sram, 48K */
+}
+
+/* Section Definitions */ 
+SECTIONS 
+{ 
+    .text : 
+    { 
+        . = ALIGN(4);
+        _sfixed = .;
+        KEEP(*(.vectors .vectors.*))
+        *(.text .text.* .gnu.linkonce.t.*) 	      
+        *(.glue_7t) *(.glue_7)		                
+        *(.rodata .rodata* .gnu.linkonce.r.*)		    	                  
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+
+        /* Support C constructors, and C destructors in both user code
+           and the C library. This also provides support for C++ code. */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(0x4);
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+
+        . = ALIGN(4);
+        _efixed = .;            /* End of text section */
+    } > rom
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    PROVIDE_HIDDEN (__exidx_start = .);
+    .ARM.exidx :
+    {
+      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > rom
+    PROVIDE_HIDDEN (__exidx_end = .);
+
+    . = ALIGN(4); 
+    _etext = .;
+
+    .relocate : AT (_etext)
+    {
+        . = ALIGN(4);
+        _srelocate = .;
+        *(.ramfunc .ramfunc.*);
+        *(.data .data.*);
+        . = ALIGN(4);
+        _erelocate = .;
+    } > ram
+
+    /* .bss section which is used for uninitialized data */ 
+    .bss (NOLOAD) :
+    { 
+        . = ALIGN(4);
+        _sbss = . ;
+        _szero = .;
+        *(.bss .bss.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = . ;
+        _ezero = .;
+    } > ram
+
+    /* stack section */
+    .stack (NOLOAD):
+    {
+        . = ALIGN(8);
+        *(.stack .stack.*)
+    } > ram
+
+    . = ALIGN(4); 
+    _end = . ; 
+}
diff --git a/firmware/libboard/common/resources/sam3s4/sram.ld b/firmware/libboard/common/resources/sam3s4/sram.ld
new file mode 100644
index 0000000..9c68755
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s4/sram.ld
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal SRAM on the ATSAM3S4
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SEARCH_DIR(.)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+	rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
+	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c000 /* sram, 48K */
+}
+
+/* Section Definitions */ 
+SECTIONS 
+{ 
+    .text : 
+    { 
+        . = ALIGN(4);
+        _sfixed = .;
+        KEEP(*(.vectors .vectors.*))
+        *(.text .text.* .gnu.linkonce.t.*) 	      
+        *(.glue_7t) *(.glue_7)		                
+        *(.rodata .rodata* .gnu.linkonce.r.*)		    	                  
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+
+        /* Support C constructors, and C destructors in both user code
+           and the C library. This also provides support for C++ code. */
+        . = ALIGN(4);
+        KEEP(*(.init))
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(0x4);
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+
+        . = ALIGN(4);
+        _efixed = .;            /* End of text section */
+    } > ram
+
+    . = ALIGN(4); 
+    _etext = .;
+
+    .relocate : AT (_etext)
+    {
+        . = ALIGN(4);
+        _srelocate = .;
+        *(.ramfunc .ramfunc.*);
+        *(.data .data.*);
+        . = ALIGN(4);
+        _erelocate = .;
+    } > ram
+
+    /* .bss section which is used for uninitialized data */ 
+    .bss (NOLOAD) :
+    { 
+        . = ALIGN(4);
+        _sbss = . ;
+        _szero = .;
+        *(.bss .bss.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = . ;
+        _ezero = .;
+    } > ram
+
+    /* stack section */
+    .stack (NOLOAD):
+    {
+        . = ALIGN(8);
+        *(.stack .stack.*)
+    } > ram
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    PROVIDE_HIDDEN (__exidx_start = .);
+    .ARM.exidx :
+    {
+      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > ram
+    PROVIDE_HIDDEN (__exidx_end = .);
+
+    . = ALIGN(4); 
+    _end = . ; 
+}
diff --git a/firmware/libboard/common/resources/sam3s4/sram_samba.lds b/firmware/libboard/common/resources/sam3s4/sram_samba.lds
new file mode 100644
index 0000000..16b1dc9
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s4/sram_samba.lds
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------------
+ *      Linker script for running in internal SRAM on the AT91SAM3S4
+ *----------------------------------------------------------------------------*/
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(entry)
+
+/* Memory Spaces Definitions */
+MEMORY
+{
+    romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x01000
+    sram (W!RX) : ORIGIN = 0x20001000, LENGTH = 0x0000B000 /* sram, 48K - sizeof(romcodesram) */
+}
+
+/* Entry point */
+/*ENTRY (ResetException)*/
+
+SECTIONS
+{
+    /* startup code in the .isr_vector */
+    .text :
+    {
+        . = ALIGN(4);
+        _stext = .;
+        KEEP(*(.isr_vector .isr_vector.*))
+        *(.mailbox)
+        *(.text .text.*)
+        *(.rodata .rodata.*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.gcc_except_table)
+        *(.rodata .rodata*)
+        *(.gnu.linkonce.r.*)
+        . = ALIGN(4);
+        _etext = .;
+    } > sram
+
+    /* data */
+    .data :
+    {
+        . = ALIGN(4);
+        _sidata = .;
+        _sdata = .;
+
+        *(.data)
+        *(.data.*)
+        . = ALIGN(4);
+        _edata = .;
+    } > sram
+
+    .bss (NOLOAD) : {
+        _szero = .;
+        *(.bss)
+        . = ALIGN(4);
+        _ezero = .;
+    } >sram
+
+    /* Stack in SRAM */
+    _sstack = 0x2000BFFC;
+}
+end = .;
diff --git a/firmware/libboard/common/resources/sam3s_ek_flash.gdb b/firmware/libboard/common/resources/sam3s_ek_flash.gdb
new file mode 100644
index 0000000..7d79615
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s_ek_flash.gdb
@@ -0,0 +1,31 @@
+#*******************************************************
+#
+#  Connect to J-Link and debug application in flash.
+#
+
+# define 'reset' command
+define reset
+
+# Connect to the J-Link gdb server
+target remote localhost:2331
+# Reset the chip to get to a known state
+monitor reset
+
+# Select flash device
+monitor flash device = AT91SAM3S4C
+# Enable flash download and flash breakpoints
+monitor flash download = 1
+# Load the program
+load
+
+# Reset peripheral  (RSTC_CR)
+set *0x400e1400 = 0xA5000004
+
+# Initializing PC and stack pointer
+mon reg sp=(0x400000)
+set *0x400004 = *0x400004 & 0xFFFFFFFE
+mon reg pc=(0x400004)
+info reg
+
+# end of 'reset' command
+end
diff --git a/firmware/libboard/common/resources/sam3s_ek_sram.gdb b/firmware/libboard/common/resources/sam3s_ek_sram.gdb
new file mode 100644
index 0000000..019bd0a
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s_ek_sram.gdb
@@ -0,0 +1,27 @@
+#*************************************************
+#
+#  Connect to J-Link and debug application in sram on SAM3S
+#
+# Note:
+#     First, users should modify Step1 and Step2 according to their project,
+#     then do Step3.
+
+# Step1: Connect to the J-Link gdb server
+define reset
+target remote localhost:2331
+monitor reset
+
+# Step2: Load file(eg. getting-started project)
+load
+
+# Step3: Reset peripheral  (RSTC_CR)
+set *0x400e1400 = 0xA5000004
+
+# Step4: Initializing PC and stack pointer
+# Modify pc value to even before writing pc register
+mon reg sp=(0x20000000)
+set *0x20000004 = *0x20000004 & 0xFFFFFFFE
+mon reg pc=(0x20000004)
+info reg
+
+end
diff --git a/firmware/libboard/common/resources/sam3s_vb_sram.gdb b/firmware/libboard/common/resources/sam3s_vb_sram.gdb
new file mode 100644
index 0000000..019bd0a
--- /dev/null
+++ b/firmware/libboard/common/resources/sam3s_vb_sram.gdb
@@ -0,0 +1,27 @@
+#*************************************************
+#
+#  Connect to J-Link and debug application in sram on SAM3S
+#
+# Note:
+#     First, users should modify Step1 and Step2 according to their project,
+#     then do Step3.
+
+# Step1: Connect to the J-Link gdb server
+define reset
+target remote localhost:2331
+monitor reset
+
+# Step2: Load file(eg. getting-started project)
+load
+
+# Step3: Reset peripheral  (RSTC_CR)
+set *0x400e1400 = 0xA5000004
+
+# Step4: Initializing PC and stack pointer
+# Modify pc value to even before writing pc register
+mon reg sp=(0x20000000)
+set *0x20000004 = *0x20000004 & 0xFFFFFFFE
+mon reg pc=(0x20000004)
+info reg
+
+end
diff --git a/firmware/libboard/common/source/board_cstartup_gnu.c b/firmware/libboard/common/source/board_cstartup_gnu.c
new file mode 100644
index 0000000..4255646
--- /dev/null
+++ b/firmware/libboard/common/source/board_cstartup_gnu.c
@@ -0,0 +1,196 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2010, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.

+ * ----------------------------------------------------------------------------

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "board.h"

+#include "board_lowlevel.h"

+

+/*----------------------------------------------------------------------------

+ *        Exported variables

+ *----------------------------------------------------------------------------*/

+

+/* Stack Configuration */  

+#define STACK_SIZE       0x900     /** Stack size (in DWords) */

+__attribute__ ((aligned(8),section(".stack")))

+uint32_t pdwStack[STACK_SIZE] ;     

+

+/* Initialize segments */

+extern uint32_t _sfixed;

+extern uint32_t _efixed;

+extern uint32_t _etext;

+extern uint32_t _srelocate;

+extern uint32_t _erelocate;

+extern uint32_t _szero;

+extern uint32_t _ezero;

+

+

+/*----------------------------------------------------------------------------

+ *        ProtoTypes

+ *----------------------------------------------------------------------------*/

+

+/** \cond DOXYGEN_SHOULD_SKIP_THIS */

+extern int main( void ) ;

+/** \endcond */

+void ResetException( void ) ;

+extern void __libc_init_array( void ) ;

+

+/*------------------------------------------------------------------------------

+ *         Exception Table

+ *------------------------------------------------------------------------------*/

+

+__attribute__((section(".vectors")))

+IntFunc exception_table[] = {

+

+    /* Configure Initial Stack Pointer, using linker-generated symbols */

+    (IntFunc)(&pdwStack[STACK_SIZE-1]),

+    ResetException,

+

+    NMI_Handler,

+    HardFault_Handler,

+    MemManage_Handler,

+    BusFault_Handler,

+    UsageFault_Handler,

+    0, 0, 0, 0,         /* Reserved */

+    SVC_Handler,

+    DebugMon_Handler,

+    0,                  /* Reserved  */

+    PendSV_Handler,

+    SysTick_Handler,

+

+    /* Configurable interrupts  */

+    SUPC_IrqHandler,    /* 0  Supply Controller */

+    RSTC_IrqHandler,    /* 1  Reset Controller */

+    RTC_IrqHandler,     /* 2  Real Time Clock */

+    RTT_IrqHandler,     /* 3  Real Time Timer */

+    WDT_IrqHandler,     /* 4  Watchdog Timer */

+    PMC_IrqHandler,     /* 5  PMC */

+    EEFC_IrqHandler,    /* 6  EEFC */

+    IrqHandlerNotUsed,  /* 7  Reserved */

+    UART0_IrqHandler,   /* 8  UART0 */

+    UART1_IrqHandler,   /* 9  UART1 */

+    SMC_IrqHandler,     /* 10 SMC */

+    PIOA_IrqHandler,    /* 11 Parallel IO Controller A */

+    PIOB_IrqHandler,    /* 12 Parallel IO Controller B */

+    PIOC_IrqHandler,    /* 13 Parallel IO Controller C */

+    USART0_IrqHandler,  /* 14 USART 0 */

+    USART1_IrqHandler,  /* 15 USART 1 */

+    IrqHandlerNotUsed,  /* 16 Reserved */

+    IrqHandlerNotUsed,  /* 17 Reserved */

+    MCI_IrqHandler,     /* 18 MCI */

+    TWI0_IrqHandler,    /* 19 TWI 0 */

+    TWI1_IrqHandler,    /* 20 TWI 1 */

+    SPI_IrqHandler,     /* 21 SPI */

+    SSC_IrqHandler,     /* 22 SSC */

+    TC0_IrqHandler,     /* 23 Timer Counter 0 */

+    TC1_IrqHandler,     /* 24 Timer Counter 1 */

+    TC2_IrqHandler,     /* 25 Timer Counter 2 */

+    TC3_IrqHandler,     /* 26 Timer Counter 3 */

+    TC4_IrqHandler,     /* 27 Timer Counter 4 */

+    TC5_IrqHandler,     /* 28 Timer Counter 5 */

+    ADC_IrqHandler,     /* 29 ADC controller */

+    DAC_IrqHandler,     /* 30 DAC controller */

+    PWM_IrqHandler,     /* 31 PWM */

+    CRCCU_IrqHandler,   /* 32 CRC Calculation Unit */

+    ACC_IrqHandler,     /* 33 Analog Comparator */

+    USBD_IrqHandler,    /* 34 USB Device Port */

+    IrqHandlerNotUsed   /* 35 not used */

+};

+

+#if defined (BOARD_USB_DFU) && !defined(dfu)

+static void BootIntoApp(void)

+{

+	unsigned int *pSrc;

+	void (*appReset)(void);

+

+	pSrc = (unsigned int *) ((unsigned char *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE);

+	SCB->VTOR = ((unsigned int)(pSrc)) | (0x0 << 7);

+	appReset = pSrc[1];

+	appReset();

+}

+#endif

+

+/**

+ * \brief This is the code that gets called on processor reset.

+ * To initialize the device, and call the main() routine.

+ */

+void ResetException( void )

+{

+    uint32_t *pSrc, *pDest ;

+

+    /* Low level Initialize */

+    LowLevelInit() ;

+

+#if defined (BOARD_USB_DFU) && !defined(dfu)

+    if (*(unsigned long *)IRAM_ADDR != 0xDFDFDFDF)

+        BootIntoApp();

+#endif

+

+    /* Initialize the relocate segment */

+    pSrc = &_etext ;

+    pDest = &_srelocate ;

+

+    if ( pSrc != pDest )

+    {

+        for ( ; pDest < &_erelocate ; )

+        {

+            *pDest++ = *pSrc++ ;

+        }

+    }

+

+    /* Clear the zero segment */

+    for ( pDest = &_szero ; pDest < &_ezero ; )

+    {

+        *pDest++ = 0;

+    }

+

+    /* Set the vector table base address */

+    pSrc = (uint32_t *)&_sfixed;

+    SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ) ;

+    

+    if ( ((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE) )

+    {

+	    SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;

+    }

+

+    /* Initialize the C library */

+    __libc_init_array() ;

+

+    /* Branch to main function */

+    main() ;

+

+    /* App should have disabled interrupts during the transition */

+    __enable_irq();

+

+    /* Infinite loop */

+    while ( 1 ) ;

+}

+

diff --git a/firmware/libboard/common/source/board_lowlevel.c b/firmware/libboard/common/source/board_lowlevel.c
new file mode 100644
index 0000000..625160e
--- /dev/null
+++ b/firmware/libboard/common/source/board_lowlevel.c
@@ -0,0 +1,185 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2009, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.

+ * ----------------------------------------------------------------------------

+ */

+

+/**

+ * \file

+ *

+ * Provides the low-level initialization function that called on chip startup.

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "board.h"

+

+/*----------------------------------------------------------------------------

+ *        Local definitions

+ *----------------------------------------------------------------------------*/

+

+#define BOARD_OSCOUNT   (CKGR_MOR_MOSCXTST(0x8))

+#define BOARD_MCKR      (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)

+

+#if (BOARD_MCK == 48000000)

+#if (BOARD_MAINOSC == 18432000)

+/* Clock settings at 48MHz  for 18 MHz crystal */

+#define BOARD_PLLAR     (CKGR_PLLAR_STUCKTO1 \

+                       | CKGR_PLLAR_MULA(13-1) \

+                       | CKGR_PLLAR_PLLACOUNT(0x1) \

+                       | CKGR_PLLAR_DIVA(5))

+#elif (BOARD_MAINOSC == 12000000)

+/* QMod has 12 MHz clock, so multply by 8 (96 MHz) and divide by 2 */

+#define BOARD_PLLAR     (CKGR_PLLAR_STUCKTO1 \

+                       | CKGR_PLLAR_MULA(8-1) \

+                       | CKGR_PLLAR_PLLACOUNT(0x1) \

+                       | CKGR_PLLAR_DIVA(2))

+#else

+#error "Please define PLLA config for your MAINOSC frequency"

+#endif /* MAINOSC */

+#elif (BOARD_MCK == 64000000)

+#if (BOARD_MAINOSC == 18432000)

+/* Clock settings at 64MHz  for 18 MHz crystal: 64.512 MHz */

+#define BOARD_PLLAR     (CKGR_PLLAR_STUCKTO1 \

+                       | CKGR_PLLAR_MULA(7-1) \

+                       | CKGR_PLLAR_PLLACOUNT(0x1) \

+                       | CKGR_PLLAR_DIVA(2))

+#elif (BOARD_MAINOSC == 12000000)

+/* QMod has 12 MHz clock, so multply by 10 / div by 2: 60 MHz */

+#define BOARD_PLLAR     (CKGR_PLLAR_STUCKTO1 \

+                       | CKGR_PLLAR_MULA(10-1) \

+                       | CKGR_PLLAR_PLLACOUNT(0x1) \

+                       | CKGR_PLLAR_DIVA(2))

+#error "Please define PLLA config for your MAINOSC frequency"

+#endif /* MAINOSC */

+#else

+    #error "No PLL settings for current BOARD_MCK."

+#endif

+

+/* Define clock timeout */

+#define CLOCK_TIMEOUT    0xFFFFFFFF

+

+/*----------------------------------------------------------------------------

+ *        Exported functions

+ *----------------------------------------------------------------------------*/

+

+/**

+ * \brief Performs the low-level initialization of the chip.

+ * This includes EFC and master clock configuration.

+ * It also enable a low level on the pin NRST triggers a user reset.

+ */

+extern WEAK void LowLevelInit( void )

+{

+    uint32_t timeout = 0;

+

+    /* enable both LED and green LED */

+    PIOA->PIO_PER |= LED_RED | LED_GREEN;

+    PIOA->PIO_OER |= LED_RED | LED_GREEN;

+    PIOA->PIO_CODR |= LED_RED | LED_GREEN;

+

+    /* Set 3 FWS for Embedded Flash Access */

+    EFC->EEFC_FMR = EEFC_FMR_FWS(3);

+

+    /* Select external slow clock */

+/*    if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST)

+    {

+        SUPC->SUPC_CR = (uint32_t)(SUPC_CR_XTALSEL_CRYSTAL_SEL | SUPC_CR_KEY(0xA5));

+        timeout = 0;

+        while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST) );

+    }

+*/

+

+#ifndef qmod

+    /* Initialize main oscillator */

+    if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )

+    {

+        PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;

+        timeout = 0;

+        while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));

+    }

+

+    /* Switch to 3-20MHz Xtal oscillator */

+    PIOB->PIO_PDR = (1 << 8) | (1 << 9);

+    PIOB->PIO_PUDR = (1 << 8) | (1 << 9);

+    PIOB->PIO_PPDDR = (1 << 8) | (1 << 9);

+    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;

+    /* wait for Main XTAL oscillator stabilization */

+    timeout = 0;

+    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));

+#else

+    /* QMOD has external 12MHz clock source */

+    PIOB->PIO_PDR = (1 << 9);

+    PIOB->PIO_PUDR = (1 << 9);

+    PIOB->PIO_PPDDR = (1 << 9);

+    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTBY| CKGR_MOR_MOSCSEL;

+#endif

+

+    /* disable the red LED after main clock initialization */

+    PIOA->PIO_SODR = LED_RED;

+

+    /* "switch" to main clock as master clock source (should already be the case */

+    PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;

+    /* wait for master clock to be ready */

+    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

+

+    /* Initialize PLLA */

+    PMC->CKGR_PLLAR = BOARD_PLLAR;

+    /* Wait for PLLA to lock */

+    timeout = 0;

+    while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));

+

+    /* Switch to main clock (again ?!?) */

+    PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;

+    /* wait for master clock to be ready */

+    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

+

+    /* switch to PLLA as master clock source */

+    PMC->PMC_MCKR = BOARD_MCKR ;

+    /* wait for master clock to be ready */

+    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

+

+    /* Configure SysTick for 1ms */

+    SysTick_Config(BOARD_MCK/1000);

+}

+

+/* SysTick based delay function */

+

+volatile uint32_t jiffies;

+

+/* Interrupt handler for SysTick interrupt */

+void SysTick_Handler(void)

+{

+	jiffies++;

+}

+

+void mdelay(unsigned int msecs)

+{

+	uint32_t jiffies_start = jiffies;

+	do {

+	} while ((jiffies - jiffies_start) < msecs);

+}

diff --git a/firmware/libboard/common/source/boardver_adc.c b/firmware/libboard/common/source/boardver_adc.c
new file mode 100644
index 0000000..ca3d1fe
--- /dev/null
+++ b/firmware/libboard/common/source/boardver_adc.c
@@ -0,0 +1,83 @@
+#include "board.h"
+#include "boardver_adc.h"
+
+/* FIXME: share this with mode_cardemu.c */
+#define UV_PER_LSB	((3300 * 1000) / 4096)
+static uint32_t adc2uv(uint16_t adc)
+{
+	uint32_t uv = (uint32_t) adc * UV_PER_LSB;
+	return uv;
+}
+
+/***********************************************************************
+ * ADC for board version detection
+ ***********************************************************************/
+
+#ifdef PIN_VERSION_DET
+
+static int adc_sam3s_reva_errata = 0;
+
+static const Pin pin_version_det = PIN_VERSION_DET;
+
+/* Warning: Don't call this while other code (like the SIM VCC voltage
+ * reading) is running.  The idea is you call this once during board
+ * startup and cache the result in a (global) variable if you need it
+ * later throughout the code */
+int get_board_version_adc(void)
+{
+	uint32_t chip_arch = CHIPID->CHIPID_CIDR & CHIPID_CIDR_ARCH_Msk;
+	uint32_t chip_ver = CHIPID->CHIPID_CIDR & CHIPID_CIDR_VERSION_Msk;
+	uint16_t sample;
+	uint32_t uv;
+
+	PIO_Configure(&pin_version_det, 1);
+
+	PMC_EnablePeripheral(ID_ADC);
+
+	ADC->ADC_CR |= ADC_CR_SWRST;
+	if (chip_ver == 0 &&
+	    (chip_arch == CHIPID_CIDR_ARCH_SAM3SxA ||
+	     chip_arch == CHIPID_CIDR_ARCH_SAM3SxB ||
+	     chip_arch == CHIPID_CIDR_ARCH_SAM3SxC)) {
+		TRACE_INFO("Enabling Rev.A ADC Errata work-around\r\n");
+		adc_sam3s_reva_errata = 1;
+	}
+
+	if (adc_sam3s_reva_errata) {
+		/* Errata Work-Around to clear EOCx flags */
+		volatile uint32_t foo;
+		int i;
+		for (i = 0; i < 16; i++)
+			foo = ADC->ADC_CDR[i];
+	}
+
+	/* Initialize ADC for AD2, fADC=48/24=2MHz */
+	ADC->ADC_MR = ADC_MR_TRGEN_DIS | ADC_MR_LOWRES_BITS_12 |
+		      ADC_MR_SLEEP_NORMAL | ADC_MR_FWUP_OFF |
+		      ADC_MR_FREERUN_OFF | ADC_MR_PRESCAL(23) |
+		      ADC_MR_STARTUP_SUT8 | ADC_MR_SETTLING(3) |
+		      ADC_MR_ANACH_NONE | ADC_MR_TRACKTIM(4) |
+		      ADC_MR_TRANSFER(1) | ADC_MR_USEQ_NUM_ORDER;
+	/* enable AD2 channel only */
+	ADC->ADC_CHER = ADC_CHER_CH2;
+
+	/* Make sure we don't use interrupts as that's what the SIM card
+	 * VCC ADC code is using */
+	ADC->ADC_IER = 0;
+	NVIC_DisableIRQ(ADC_IRQn);
+
+	ADC->ADC_CR |= ADC_CR_START;
+
+	/* busy-wait, actually read the value */
+	do { } while (!(ADC->ADC_ISR & ADC_ISR_EOC2));
+	/* convert to voltage */
+	sample = ADC->ADC_CDR[2];
+	uv = adc2uv(sample);
+	TRACE_INFO("VERSION_DET ADC=%u => %u uV\r\n", sample, uv);
+
+	/* FIXME: convert to board version based on thresholds */
+
+	return 0;
+}
+
+#endif /* PIN_VERSION_DET */
diff --git a/firmware/libboard/common/source/led.c b/firmware/libboard/common/source/led.c
new file mode 100644
index 0000000..1a88e45
--- /dev/null
+++ b/firmware/libboard/common/source/led.c
@@ -0,0 +1,168 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2008, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.

+ * ----------------------------------------------------------------------------

+ */

+

+/**

+ * \file

+ */

+

+/*------------------------------------------------------------------------------

+ *         Headers

+ *------------------------------------------------------------------------------*/

+

+#include "board.h"

+

+/*------------------------------------------------------------------------------

+ *         Local Variables

+ *------------------------------------------------------------------------------*/

+

+#ifdef PINS_LEDS

+static const Pin pinsLeds[] = { PINS_LEDS } ;

+static const uint32_t numLeds = PIO_LISTSIZE( pinsLeds ) ;

+#endif

+

+/*------------------------------------------------------------------------------

+ *         Global Functions

+ *------------------------------------------------------------------------------*/

+

+/**

+ *  Configures the pin associated with the given LED number. If the LED does

+ *  not exist on the board, the function does nothing.

+ *  \param led  Number of the LED to configure.

+ *  \return 1 if the LED exists and has been configured; otherwise 0.

+ */

+extern uint32_t LED_Configure( uint32_t dwLed )

+{

+#ifdef PINS_LEDS

+    // Check that LED exists

+    if ( dwLed >= numLeds)

+    {

+

+        return 0;

+    }

+

+    // Configure LED

+    return ( PIO_Configure( &pinsLeds[dwLed], 1 ) ) ;

+#else

+    return 0 ;

+#endif

+}

+

+/**

+ *  Turns the given LED on if it exists; otherwise does nothing.

+ *  \param led  Number of the LED to turn on.

+ *  \return 1 if the LED has been turned on; 0 otherwise.

+ */

+extern uint32_t LED_Set( uint32_t dwLed )

+{

+#ifdef PINS_LEDS

+    /* Check if LED exists */

+    if ( dwLed >= numLeds )

+    {

+        return 0 ;

+    }

+

+    /* Turn LED on */

+    if ( pinsLeds[dwLed].type == PIO_OUTPUT_0 )

+    {

+

+        PIO_Set( &pinsLeds[dwLed] ) ;

+    }

+    else

+    {

+        PIO_Clear( &pinsLeds[dwLed] ) ;

+    }

+

+    return 1 ;

+#else

+    return 0 ;

+#endif

+}

+

+/**

+ *  Turns a LED off.

+ *

+ *  \param led  Number of the LED to turn off.

+ *  \return 1 if the LED has been turned off; 0 otherwise.

+ */

+extern uint32_t LED_Clear( uint32_t dwLed )

+{

+#ifdef PINS_LEDS

+    /* Check if LED exists */

+    if ( dwLed >= numLeds )

+    {

+        return 0 ;

+    }

+

+    /* Turn LED off */

+    if ( pinsLeds[dwLed].type == PIO_OUTPUT_0 )

+    {

+        PIO_Clear( &pinsLeds[dwLed] ) ;

+    }

+    else

+    {

+        PIO_Set( &pinsLeds[dwLed] ) ;

+    }

+

+    return 1 ;

+#else

+    return 0 ;

+#endif

+}

+

+/**

+ *  Toggles the current state of a LED.

+ *

+ *  \param led  Number of the LED to toggle.

+ *  \return 1 if the LED has been toggled; otherwise 0.

+ */

+extern uint32_t LED_Toggle( uint32_t dwLed )

+{

+#ifdef PINS_LEDS

+    /* Check if LED exists */

+    if ( dwLed >= numLeds )

+    {

+        return 0 ;

+    }

+

+    /* Toggle LED */

+    if ( PIO_GetOutputDataStatus( &pinsLeds[dwLed] ) )

+    {

+        PIO_Clear( &pinsLeds[dwLed] ) ;

+    }

+    else

+    {

+        PIO_Set( &pinsLeds[dwLed] ) ;

+    }

+

+    return 1 ;

+#else

+    return 0 ;

+#endif

+}

+

diff --git a/firmware/libboard/common/source/uart_console.c b/firmware/libboard/common/source/uart_console.c
new file mode 100644
index 0000000..e6be514
--- /dev/null
+++ b/firmware/libboard/common/source/uart_console.c
@@ -0,0 +1,380 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2009, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.

+ * ----------------------------------------------------------------------------

+ */

+

+/**

+ * \file

+ *

+ * Implements UART console.

+ *

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "board.h"

+

+#include <stdio.h>

+#include <stdint.h>

+

+/*----------------------------------------------------------------------------

+ *        Definitions

+ *----------------------------------------------------------------------------*/

+

+/*----------------------------------------------------------------------------

+ *        Variables

+ *----------------------------------------------------------------------------*/

+

+/** Is Console Initialized. */

+static uint8_t _ucIsConsoleInitialized=0 ;

+

+/**

+ * \brief Configures an USART peripheral with the specified parameters.

+ *

+ * \param baudrate  Baudrate at which the USART should operate (in Hz).

+ * \param masterClock  Frequency of the system master clock (in Hz).

+ */

+extern void UART_Configure( uint32_t baudrate, uint32_t masterClock)

+{

+    const Pin pPins[] = CONSOLE_PINS;

+    Uart *pUart = CONSOLE_USART;

+

+    /* Configure PIO */

+    PIO_Configure(pPins, PIO_LISTSIZE(pPins));

+

+    /* Configure PMC */

+    PMC->PMC_PCER0 = 1 << CONSOLE_ID;

+

+    /* Reset and disable receiver & transmitter */

+    pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX

+                   | UART_CR_RXDIS | UART_CR_TXDIS;

+

+    /* Configure mode */

+    pUart->UART_MR =  UART_MR_PAR_NO;

+

+    /* Configure baudrate */

+    /* Asynchronous, no oversampling */

+    pUart->UART_BRGR = (masterClock / baudrate) / 16;

+

+    /* Disable PDC channel */

+    pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;

+

+    /* Enable receiver and transmitter */

+    pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;

+

+    _ucIsConsoleInitialized=1 ;

+}

+

+/**

+ * \brief Outputs a character on the UART line.

+ *

+ * \note This function is synchronous (i.e. uses polling).

+ * \param c  Character to send.

+ */

+extern void UART_PutChar( uint8_t c )

+{

+    Uart *pUart=CONSOLE_USART ;

+

+    if ( !_ucIsConsoleInitialized )

+    {

+        UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);

+    }

+

+    /* Wait for the transmitter to be ready */

+    while ( (pUart->UART_SR & UART_SR_TXEMPTY) == 0 ) ;

+

+    /* Send character */

+    pUart->UART_THR=c ;

+

+}

+

+/**

+ * \brief Input a character from the UART line.

+ *

+ * \note This function is synchronous

+ * \return character received.

+ */

+extern uint32_t UART_GetChar( void )

+{

+    Uart *pUart=CONSOLE_USART ;

+

+    if ( !_ucIsConsoleInitialized )

+    {

+        UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);

+    }

+

+    while ( (pUart->UART_SR & UART_SR_RXRDY) == 0 ) ;

+

+    return pUart->UART_RHR ;

+}

+

+/**

+ * \brief Check if there is Input from UART line.

+ *

+ * \return true if there is Input.

+ */

+extern uint32_t UART_IsRxReady( void )

+{

+    Uart *pUart=CONSOLE_USART ;

+

+    if ( !_ucIsConsoleInitialized )

+    {

+        UART_Configure( CONSOLE_BAUDRATE, BOARD_MCK ) ;

+    }

+

+    return (pUart->UART_SR & UART_SR_RXRDY) > 0 ;

+}

+

+/**

+ *  Displays the content of the given frame on the UART0.

+ *

+ *  \param pucFrame Pointer to the frame to dump.

+ *  \param dwSize   Buffer size in bytes.

+ */

+extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize )

+{

+    uint32_t dw ;

+

+    for ( dw=0 ; dw < dwSize ; dw++ )

+    {

+        printf( "%02X ", pucFrame[dw] ) ;

+    }

+

+    printf( "\n\r" ) ;

+}

+

+/**

+ *  Displays the content of the given buffer on the UART0.

+ *

+ *  \param pucBuffer  Pointer to the buffer to dump.

+ *  \param dwSize     Buffer size in bytes.

+ *  \param dwAddress  Start address to display

+ */

+extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )

+{

+    uint32_t i ;

+    uint32_t j ;

+    uint32_t dwLastLineStart ;

+    uint8_t* pucTmp ;

+

+    for ( i=0 ; i < (dwSize / 16) ; i++ )

+    {

+        printf( "0x%08X: ", (unsigned int)(dwAddress + (i*16)) ) ;

+        pucTmp = (uint8_t*)&pucBuffer[i*16] ;

+

+        for ( j=0 ; j < 4 ; j++ )

+        {

+            printf( "%02X%02X%02X%02X ", pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3] ) ;

+            pucTmp += 4 ;

+        }

+

+        pucTmp=(uint8_t*)&pucBuffer[i*16] ;

+

+        for ( j=0 ; j < 16 ; j++ )

+        {

+            UART_PutChar( *pucTmp++ ) ;

+        }

+

+        printf( "\n\r" ) ;

+    }

+

+    if ( (dwSize%16) != 0 )

+    {

+        dwLastLineStart=dwSize - (dwSize%16) ;

+

+        printf( "0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart) ) ;

+        for ( j=dwLastLineStart ; j < dwLastLineStart+16 ; j++ )

+        {

+            if ( (j!=dwLastLineStart) && (j%4 == 0) )

+            {

+                printf( " " ) ;

+            }

+

+            if ( j < dwSize )

+            {

+                printf( "%02X", pucBuffer[j] ) ;

+            }

+            else

+            {

+                printf("  ") ;

+            }

+        }

+

+        printf( " " ) ;

+        for ( j=dwLastLineStart ; j < dwSize ; j++ )

+        {

+            UART_PutChar( pucBuffer[j] ) ;

+        }

+

+        printf( "\n\r" ) ;

+    }

+}

+

+/**

+ *  Reads an integer

+ *

+ *  \param pdwValue  Pointer to the uint32_t variable to contain the input value.

+ */

+extern uint32_t UART_GetInteger( uint32_t* pdwValue )

+{

+    uint8_t ucKey ;

+    uint8_t ucNbNb=0 ;

+    uint32_t dwValue=0 ;

+

+    while ( 1 )

+    {

+        ucKey=UART_GetChar() ;

+        UART_PutChar( ucKey ) ;

+

+        if ( ucKey >= '0' &&  ucKey <= '9' )

+        {

+            dwValue = (dwValue * 10) + (ucKey - '0');

+            ucNbNb++ ;

+        }

+        else

+        {

+            if ( ucKey == 0x0D || ucKey == ' ' )

+            {

+                if ( ucNbNb == 0 )

+                {

+                    printf( "\n\rWrite a number and press ENTER or SPACE!\n\r" ) ;

+                    return 0 ;

+                }

+                else

+                {

+                    printf( "\n\r" ) ;

+                    *pdwValue=dwValue ;

+

+                    return 1 ;

+                }

+            }

+            else

+            {

+                printf( "\n\r'%c' not a number!\n\r", ucKey ) ;

+

+                return 0 ;

+            }

+        }

+    }

+}

+

+/**

+ *  Reads an integer and check the value

+ *

+ *  \param pdwValue  Pointer to the uint32_t variable to contain the input value.

+ *  \param dwMin     Minimum value

+ *  \param dwMax     Maximum value

+ */

+extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint32_t dwMax )

+{

+    uint32_t dwValue=0 ;

+

+    if ( UART_GetInteger( &dwValue ) == 0 )

+    {

+        return 0 ;

+    }

+

+    if ( dwValue < dwMin || dwValue > dwMax )

+ {

+        printf( "\n\rThe number have to be between %d and %d\n\r", (int)dwMin, (int)dwMax ) ;

+

+        return 0 ;

+    }

+

+    printf( "\n\r" ) ;

+

+    *pdwValue = dwValue ;

+

+    return 1 ;

+}

+

+/**

+ *  Reads an hexadecimal number

+ *

+ *  \param pdwValue  Pointer to the uint32_t variable to contain the input value.

+ */

+extern uint32_t UART_GetHexa32( uint32_t* pdwValue )

+{

+    uint8_t ucKey ;

+    uint32_t dw = 0 ;

+    uint32_t dwValue = 0 ;

+

+    for ( dw=0 ; dw < 8 ; dw++ )

+    {

+        ucKey = UART_GetChar() ;

+        UART_PutChar( ucKey ) ;

+

+        if ( ucKey >= '0' &&  ucKey <= '9' )

+        {

+            dwValue = (dwValue * 16) + (ucKey - '0') ;

+        }

+        else

+        {

+            if ( ucKey >= 'A' &&  ucKey <= 'F' )

+            {

+                dwValue = (dwValue * 16) + (ucKey - 'A' + 10) ;

+            }

+            else

+            {

+                if ( ucKey >= 'a' &&  ucKey <= 'f' )

+                {

+                    dwValue = (dwValue * 16) + (ucKey - 'a' + 10) ;

+                }

+                else

+                {

+                    printf( "\n\rIt is not a hexa character!\n\r" ) ;

+

+                    return 0 ;

+                }

+            }

+        }

+    }

+

+    printf("\n\r" ) ;

+    *pdwValue = dwValue ;

+

+    return 1 ;

+}

+

+#if defined __ICCARM__ /* IAR Ewarm 5.41+ */

+/**

+ * \brief Outputs a character on the UART.

+ *

+ * \param c  Character to output.

+ *

+ * \return The character that was output.

+ */

+extern WEAK signed int putchar( signed int c )

+{

+    UART_PutChar( c ) ;

+

+    return c ;

+}

+#endif // defined __ICCARM__

+

diff --git a/firmware/libboard/owhw/include/board.h b/firmware/libboard/owhw/include/board.h
new file mode 100644
index 0000000..c5e67d1
--- /dev/null
+++ b/firmware/libboard/owhw/include/board.h
@@ -0,0 +1,53 @@
+#pragma once
+#include "board_common.h"
+
+/** Name of the board */
+#define BOARD_NAME "OWHW"
+/** Board definition */
+#define owhw
+
+#define BOARD_MAINOSC 18432000
+
+/* USIM 2 interface (USART) */
+#define PIN_USIM2_CLK		{PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_IO		{PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM2	PIN_USIM2_CLK, PIN_USIM2_IO
+
+/* USIM 2 interface (TC) */
+#define PIN_USIM2_IO_TC		{PIO_PA1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_CLK_TC	{PIO_PA4, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM2		PIN_USIM2_IO_TC, PIN_USIM2_CLK_TC
+
+/* USIM 1 interface (USART) */
+#define PIN_USIM1_IO		{PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_USIM1_CLK		{PIO_PA23, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM1	PIN_USIM1_CLK, PIN_USIM1_IO
+
+/* USIM 1 interface (TC) */
+#define PIN_USIM1_IO_TC		{PIO_PA27, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM1_CLK_TC	{PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM1		PIN_USIM1_IO_TC, PIN_USIM1_CLK_TC
+
+#define PIN_SET_USIM1_PRES	{PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define PIN_USIM1_nRST		{PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_USIM1_VCC		{PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PIN_SET_USIM2_PRES	{PIO_PA14, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define PIN_USIM2_nRST		{PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_USIM2_VCC		{PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PINS_USIM1		PINS_TC_USIM1, PINS_ISO7816_USIM1, PIN_USIM1_nRST, PIN_SET_USIM1_PRES
+#define PINS_USIM2		PINS_TC_USIM2, PINS_ISO7816_USIM2, PIN_USIM2_nRST, PIN_SET_USIM2_PRES
+
+#define PINS_CARDSIM		{ PIN_SET_USIM1_PRES, PIN_SET_USIM2_PRES }
+
+#define SIMTRACE_VENDOR_ID          0x1d50
+#define SIMTRACE_PRODUCT_ID         0x60e3	/* FIXME */
+#define USB_VENDOR_ID               SIMTRACE_VENDOR_ID
+#define USB_PRODUCT_ID              SIMTRACE_PRODUCT_ID
+
+#define CARDEMU_SECOND_UART
+/* Disable VCC/ADC detection, as OWHWv2 has no ADCVREF */
+//#define DETECT_VCC_BY_ADC
+
+#define HAVE_CARDEM
diff --git a/firmware/libboard/owhw/source/owhw.c b/firmware/libboard/owhw/source/owhw.c
new file mode 100644
index 0000000..c020d64
--- /dev/null
+++ b/firmware/libboard/owhw/source/owhw.c
@@ -0,0 +1,39 @@
+/* Card simulator specific functions */
+/* (C) 2015 by Harald Welte <hwelte@hmw-consulting.de>
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "chip.h"
+#include "board.h"
+
+static const Pin pins_cardsim[] = PINS_CARDSIM;
+
+void cardsim_set_simpres(uint8_t slot, int present)
+{
+	if (slot > 1)
+		return;
+
+	if (present)
+		PIO_Set(&pins_cardsim[slot]);
+	else
+		PIO_Clear(&pins_cardsim[slot]);
+}
+
+void cardsim_gpio_init(void)
+{
+	PIO_Configure(&pins_cardsim, ARRAY_SIZE(pins_cardsim));
+}
diff --git a/firmware/libboard/qmod/include/board.h b/firmware/libboard/qmod/include/board.h
new file mode 100644
index 0000000..16a38a8
--- /dev/null
+++ b/firmware/libboard/qmod/include/board.h
@@ -0,0 +1,66 @@
+#pragma once
+#include "board_common.h"
+
+/** Name of the board */
+#define BOARD_NAME "QMOD"
+/** Board definition */
+#define qmod
+
+#define BOARD_MAINOSC 12000000
+
+/* USIM 2 interface (USART) */
+#define PIN_USIM2_CLK		{PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_IO		{PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM2	PIN_USIM2_CLK, PIN_USIM2_IO
+
+/* USIM 2 interface (TC) */
+#define PIN_USIM2_IO_TC		{PIO_PA1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM2_CLK_TC	{PIO_PA4, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM2		PIN_USIM2_IO_TC, PIN_USIM2_CLK_TC
+
+/* USIM 1 interface (USART) */
+#define PIN_USIM1_IO		{PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_USIM1_CLK		{PIO_PA23, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PINS_ISO7816_USIM1	PIN_USIM1_CLK, PIN_USIM1_IO
+
+/* USIM 1 interface (TC) */
+#define PIN_USIM1_IO_TC		{PIO_PA27, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_USIM1_CLK_TC	{PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PINS_TC_USIM1		PIN_USIM1_IO_TC, PIN_USIM1_CLK_TC
+
+#define PIN_SET_USIM1_PRES	{PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define PIN_USIM1_nRST		{PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_USIM1_VCC		{PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PIN_SET_USIM2_PRES	{PIO_PA14, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define PIN_USIM2_nRST		{PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_USIM2_VCC		{PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
+
+#define PINS_USIM1		PINS_TC_USIM1, PINS_ISO7816_USIM1, PIN_USIM1_nRST, PIN_SET_USIM1_PRES
+#define PINS_USIM2		PINS_TC_USIM2, PINS_ISO7816_USIM2, PIN_USIM2_nRST, PIN_SET_USIM2_PRES
+
+#define PINS_CARDSIM		{ PIN_SET_USIM1_PRES, PIN_SET_USIM2_PRES }
+
+#define PIN_PRTPWR_OVERRIDE	{PIO_PA8, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+/* inputs reading the WWAN LED level */
+#define PIN_WWAN1		{PIO_PA15, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
+#define PIN_WWAN2		{PIO_PA16, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
+#define PINS_WWAN_IN		{ PIN_WWAN1, PIN_WWAN2 }
+
+/* outputs controlling RESET input of modems */
+#define PIN_PERST1		{PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_PULLUP}
+#define PIN_PERST2		{PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_PULLUP}
+#define PINS_PERST		{ PIN_PERST1, PIN_PERST2 }
+
+#define PIN_VERSION_DET		{PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
+
+#define SIMTRACE_VENDOR_ID          0x1d50
+#define SIMTRACE_PRODUCT_ID         0x60e3	/* FIXME */
+#define USB_VENDOR_ID               SIMTRACE_VENDOR_ID
+#define USB_PRODUCT_ID              SIMTRACE_PRODUCT_ID
+
+#define CARDEMU_SECOND_UART
+#define DETECT_VCC_BY_ADC
+
+#define HAVE_CARDEM
diff --git a/firmware/libboard/qmod/include/i2c.h b/firmware/libboard/qmod/include/i2c.h
new file mode 100644
index 0000000..15e4b37
--- /dev/null
+++ b/firmware/libboard/qmod/include/i2c.h
@@ -0,0 +1,5 @@
+#pragma once
+
+void i2c_pin_init(void);
+int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte);
+int eeprom_read_byte(uint8_t slave, uint8_t addr);
diff --git a/firmware/libboard/qmod/include/wwan_led.h b/firmware/libboard/qmod/include/wwan_led.h
new file mode 100644
index 0000000..7ba72ea
--- /dev/null
+++ b/firmware/libboard/qmod/include/wwan_led.h
@@ -0,0 +1,4 @@
+#pragma once
+
+int wwan_led_active(int wwan);
+int wwan_led_init(void);
diff --git a/firmware/libboard/qmod/include/wwan_perst.h b/firmware/libboard/qmod/include/wwan_perst.h
new file mode 100644
index 0000000..8997a52
--- /dev/null
+++ b/firmware/libboard/qmod/include/wwan_perst.h
@@ -0,0 +1,4 @@
+#pragma once
+
+int wwan_perst_do_reset(int modem_nr);
+int wwan_perst_init(void);
diff --git a/firmware/libboard/qmod/source/i2c.c b/firmware/libboard/qmod/source/i2c.c
new file mode 100644
index 0000000..0549da1
--- /dev/null
+++ b/firmware/libboard/qmod/source/i2c.c
@@ -0,0 +1,203 @@
+#include "board.h"
+#include <stdbool.h>
+
+/* Low-Level I2C Routines */
+
+static const Pin pin_sda = {PIO_PA30, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN };
+static const Pin pin_sda_in = {PIO_PA30, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT };
+static const Pin pin_scl = {PIO_PA31, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN };
+
+static void i2c_delay()
+{
+	volatile int v;
+	int i;
+
+	/* 100 cycles results in SCL peak length of 44us, so it's about
+	 * 440ns per cycle here */
+	for (i = 0; i < 14; i++) {
+		v = 0;
+	}
+}
+
+void i2c_pin_init(void)
+{
+	PIO_Configure(&pin_scl, PIO_LISTSIZE(pin_scl));
+	PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda));
+}
+
+static void set_scl(void)
+{
+	PIO_Set(&pin_scl);
+	i2c_delay();
+}
+
+static void set_sda(void)
+{
+	PIO_Set(&pin_sda);
+	i2c_delay();
+}
+
+static void clear_scl(void)
+{
+	PIO_Clear(&pin_scl);
+	i2c_delay();
+}
+
+static void clear_sda(void)
+{
+	PIO_Clear(&pin_sda);
+	i2c_delay();
+}
+
+static bool read_sda(void)
+{
+	bool ret;
+
+	PIO_Configure(&pin_sda_in, PIO_LISTSIZE(pin_sda_in));
+	if (PIO_Get(&pin_sda_in))
+		ret = true;
+	else
+		ret = false;
+	PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda));
+
+	return ret;
+}
+
+/* Core I2C Routines */
+
+static bool i2c_started = false;
+
+static void i2c_start_cond(void)
+{
+	if (i2c_started) {
+		set_sda();
+		set_scl();
+	}
+
+	clear_sda();
+	i2c_delay();
+	clear_scl();
+	i2c_started = true;
+}
+
+static void i2c_stop_cond(void)
+{
+	clear_sda();
+	set_scl();
+	set_sda();
+	i2c_delay();
+	i2c_started = false;
+}
+
+static void i2c_write_bit(bool bit)
+{
+	if (bit)
+		set_sda();
+	else
+		clear_sda();
+	i2c_delay(); // ?
+	set_scl();
+	clear_scl();
+}
+
+static bool i2c_read_bit(void)
+{
+	bool bit;
+
+	set_sda();
+	set_scl();
+	bit = read_sda();
+	clear_scl();
+
+	return bit;
+}
+
+bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte)
+{
+	uint8_t bit;
+	bool nack;
+
+	if (send_start)
+		i2c_start_cond();
+
+	for (bit = 0; bit < 8; bit++) {
+		i2c_write_bit((byte & 0x80) != 0);
+		byte <<= 1;
+	}
+
+	nack = i2c_read_bit();
+
+	if (send_stop)
+		i2c_stop_cond();
+
+	return nack;
+}
+
+uint8_t i2c_read_byte(bool nack, bool send_stop)
+{
+	uint8_t byte = 0;
+	uint8_t bit;
+
+	for (bit = 0; bit < 8; bit++) {
+		byte = (byte << 1) | i2c_read_bit();
+	}
+
+	i2c_write_bit(nack);
+
+	if (send_stop)
+		i2c_stop_cond();
+
+	return byte;
+}
+
+
+/* EEPROM related code */
+
+int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
+{
+	bool nack;
+
+	/* Write slave address */
+	nack = i2c_write_byte(true, false, slave << 1);
+	if (nack)
+		goto out_stop;
+	nack = i2c_write_byte(false, false, addr);
+	if (nack)
+		goto out_stop;
+	nack = i2c_write_byte(false, true, byte);
+	if (nack)
+		goto out_stop;
+
+out_stop:
+	i2c_stop_cond();
+	if (nack)
+		return -1;
+	else
+		return 0;
+}
+
+int eeprom_read_byte(uint8_t slave, uint8_t addr)
+{
+	bool nack;
+
+	/* dummy write cycle */
+	nack = i2c_write_byte(true, false, slave << 1);
+	if (nack)
+		goto out_stop;
+	nack = i2c_write_byte(false, false, addr);
+	if (nack)
+		goto out_stop;
+	/* Re-start with read */
+	nack = i2c_write_byte(true, false, (slave << 1) | 1);
+	if (nack)
+		goto out_stop;
+
+	return i2c_read_byte(true, true);
+
+out_stop:
+	i2c_stop_cond();
+	if (nack)
+		return -1;
+	else
+		return 0;
+}
diff --git a/firmware/libboard/qmod/source/wwan_led.c b/firmware/libboard/qmod/source/wwan_led.c
new file mode 100644
index 0000000..3bae0ff
--- /dev/null
+++ b/firmware/libboard/qmod/source/wwan_led.c
@@ -0,0 +1,80 @@
+/* Code to read/track the status of the WWAN LEDs of attached modems
+ *
+ * Depending on the board this is running on,  it might be possible
+ * for the controller to read the status of the WWAN LED output lines of
+ * the cellular modem.  If the board supports this, it sets the
+ * PIN_WWAN1 and/or PIN_WWAN2 defines in its board.h file.
+ */
+
+#include "board.h"
+#include "wwan_led.h"
+
+#ifdef PIN_WWAN1
+static const Pin pin_wwan1 = PIN_WWAN1;
+
+static void wwan1_irqhandler(const Pin *pPin)
+{
+	int active = wwan_led_active(1);
+
+	TRACE_INFO("WWAN1 LED %u\r\n", active);
+
+	/* TODO: notify host via USB */
+}
+#endif
+
+#ifdef PIN_WWAN2
+static const Pin pin_wwan2 = PIN_WWAN2;
+
+static void wwan2_irqhandler(const Pin *pPin)
+{
+	int active = wwan_led_active(2);
+	TRACE_INFO("WWAN2 LED %u\r\n", active);
+
+	/* TODO: notify host via USB */
+}
+#endif
+
+/* determine if a tiven WWAN led is currently active or not */
+int wwan_led_active(int wwan)
+{
+	const Pin *pin;
+	int active;
+
+	switch (wwan) {
+#ifdef PIN_WWAN1
+	case 1:
+		pin = &pin_wwan1;
+		break;
+#endif
+#ifdef PIN_WWAN2
+	case 2:
+		pin = &pin_wwan2;
+		break;
+#endif
+	default:
+		return -1;
+	}
+
+	active = PIO_Get(&pin_wwan1) ? 0 : 1;
+	return active;
+}
+
+int wwan_led_init(void)
+{
+	int num_leds = 0;
+
+#ifdef PIN_WWAN1
+	PIO_Configure(&pin_wwan1, 1);
+	PIO_ConfigureIt(&pin_wwan1, wwan1_irqhandler);
+	PIO_EnableIt(&pin_wwan1);
+	num_leds++;
+#endif
+
+#ifdef PIN_WWAN2
+	PIO_Configure(&pin_wwan2, 1);
+	PIO_ConfigureIt(&pin_wwan2, wwan2_irqhandler);
+	PIO_EnableIt(&pin_wwan2);
+	num_leds++;
+#endif
+	return num_leds;
+}
diff --git a/firmware/libboard/qmod/source/wwan_perst.c b/firmware/libboard/qmod/source/wwan_perst.c
new file mode 100644
index 0000000..365acd2
--- /dev/null
+++ b/firmware/libboard/qmod/source/wwan_perst.c
@@ -0,0 +1,76 @@
+/* Code to control the PERST lines of attached modems
+ *
+ * Depending on the board this is running on,  it might be possible
+ * for the controller to set the status of the PERST input line of
+ * the cellular modem.  If the board supports this, it sets the
+ * PIN_PERST1 and/or PIN_PERST2 defines in its board.h file.
+ */
+
+#include "board.h"
+#include "wwan_perst.h"
+#include "osmocom/core/timer.h"
+
+#define PERST_DURATION_MS 300
+
+#ifdef PIN_PERST1
+static const Pin pin_perst1 = PIN_PERST1;
+static struct osmo_timer_list perst1_timer;
+#endif
+
+#ifdef PIN_PERST2
+static const Pin pin_perst2 = PIN_PERST2;
+static struct osmo_timer_list perst2_timer;
+#endif
+
+static void perst_tmr_cb(void *data)
+{
+	const Pin *pin = data;
+	/* release the (low-active) reset */
+	PIO_Clear(pin);
+}
+
+int wwan_perst_do_reset(int modem_nr)
+{
+	const Pin *pin;
+	struct osmo_timer_list *tmr;
+
+	switch (modem_nr) {
+#ifdef PIN_PERST1
+	case 1:
+		pin = &pin_perst1;
+		tmr = &perst1_timer;
+		break;
+#endif
+#ifdef PIN_PERST2
+	case 2:
+		pin = &pin_perst2;
+		tmr = &perst2_timer;
+		break;
+#endif
+	default:
+		return -1;
+	}
+	PIO_Set(pin);
+	osmo_timer_schedule(tmr, PERST_DURATION_MS/1000, (PERST_DURATION_MS%1000)*1000);
+
+	return 0;
+}
+
+int wwan_perst_init(void)
+{
+	int num_perst = 0;
+#ifdef PIN_PERST1
+	PIO_Configure(&pin_perst1, 1);
+	perst1_timer.cb = perst_tmr_cb;
+	perst1_timer.data = (void *) &pin_perst1;
+	num_perst++;
+#endif
+
+#ifdef PIN_PERST2
+	PIO_Configure(&pin_perst2, 1);
+	perst2_timer.cb = perst_tmr_cb;
+	perst2_timer.data = (void *) &pin_perst2;
+	num_perst++;
+#endif
+	return num_perst;
+}
diff --git a/firmware/libboard/simtrace/include/board.h b/firmware/libboard/simtrace/include/board.h
new file mode 100644
index 0000000..6d11dae
--- /dev/null
+++ b/firmware/libboard/simtrace/include/board.h
@@ -0,0 +1,85 @@
+#pragma once
+#include "board_common.h"
+
+/** Name of the board */
+#define BOARD_NAME "SAM3S-SIMTRACE"
+/** Board definition */
+#define simtrace
+
+#define BOARD_MAINOSC 18432000
+
+/** Phone (SIM card emulator)/CCID Reader/MITM configuration    **/
+/*  Normally the communication lines between phone and SIM card are disconnected    */
+// Disconnect SIM card I/O, VPP line from the phone lines
+// FIXME: Per default pins are input, therefore high-impedance, therefore they don not activate the bus switch, right?
+#define PIN_SC_SW_DEFAULT               {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+// Disconnect SIM card RST, CLK line from the phone lines
+#define PIN_IO_SW_DEFAULT               {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+#define PINS_BUS_DEFAULT                PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
+
+/** Sniffer configuration **/
+// Connect VPP, CLK and RST lines from smartcard to the phone
+#define PIN_SC_SW_SNIFF        {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define PIN_IO_SW_SNIFF        {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define PINS_BUS_SNIFF          PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
+
+#define PINS_SIM_SNIFF_SIM      PIN_PHONE_IO,  PIN_PHONE_CLK
+
+#define SIM_PWEN_PIN            {PIO_PA5, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+#define PWR_PINS                                                         \
+    /* Enable power converter 4.5-6V to 3.3V; low: off */               \
+    {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT},               \
+    /* Enable second power converter: VCC_PHONE to VCC_SIM; high: on */ \
+    {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
+
+#define SW_SIM      PIO_PA8
+#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
+//#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE}
+
+/// PIN used for resetting the smartcard
+// FIXME: Card is resetted with pin set to 0 --> PIO_OUTPUT_1 as default is right?
+#define PIN_ISO7816_RSTMC       {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
+/// Pins used for connect the smartcard
+#define PIN_SIM_IO_INPUT    {PIO_PA1, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_SIM_IO          {PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_SIM_CLK         {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
+#define PIN_SIM_CLK_INPUT   {PIO_PA4, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+//#define PINS_ISO7816            PIN_USART1_TXD, PIN_USART1_SCK, PIN_ISO7816_RSTMC
+#define PINS_ISO7816        PIN_SIM_IO,  PIN_SIM_CLK,  PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
+
+#define PINS_TC             PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
+
+#define VCC_PHONE                   {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_ISO7816_RST_PHONE       {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
+#define PIN_PHONE_IO_INPUT          {PIO_PA21, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PIN_PHONE_IO                {PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+#define PIN_PHONE_CLK               {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}     // External Clock Input on PA28
+//#define PIN_PHONE_CLK               {PIO_PA23A_SCK1, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}     // External Clock Input on PA28
+#define PIN_PHONE_CLK_INPUT         {PIO_PA29, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
+#define PINS_ISO7816_PHONE          PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, VCC_PHONE, PIN_PHONE_IO_INPUT, PIN_ISO7816_RST_PHONE
+//, VCC_PHONE
+
+
+//**     SPI interface   **/
+/// SPI MISO pin definition (PA12).
+#define PIN_SPI_MISO   {1 << 12, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
+/// SPI MOSI pin definition (PA13).
+#define PIN_SPI_MOSI   {1 << 13, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/// SPI SPCK pin definition (PA14).
+#define PIN_SPI_SPCK   {1 << 14, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+/// SPI pins definition. Contains MISO, MOSI & SPCK (PA12, PA13 & PA14).
+#define PINS_SPI       PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
+/// SPI chip select 0 pin definition (PA11).
+#define PIN_SPI_NPCS0  {1 << 11, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
+
+#define SIMTRACE_VENDOR_ID          0x1d50
+#define SIMTRACE_PRODUCT_ID         0x60e3
+#define USB_VENDOR_ID               SIMTRACE_VENDOR_ID
+#define USB_PRODUCT_ID              SIMTRACE_PRODUCT_ID
+
+#define HAVE_SNIFFER
+#define HAVE_CCID
+#define HAVE_CARDEM
+#define HAVE_MITM