aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/libboard
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/libboard')
-rw-r--r--firmware/libboard/common/include/board_common.h121
-rw-r--r--firmware/libboard/common/include/board_lowlevel.h46
-rw-r--r--firmware/libboard/common/include/boardver_adc.h3
-rw-r--r--firmware/libboard/common/include/led.h72
-rw-r--r--firmware/libboard/common/include/uart_console.h48
-rw-r--r--firmware/libboard/common/resources/sam3s1/flash.ld140
-rw-r--r--firmware/libboard/common/resources/sam3s1/sram.ld140
-rw-r--r--firmware/libboard/common/resources/sam3s1/sram_samba.lds91
-rw-r--r--firmware/libboard/common/resources/sam3s2/flash.ld140
-rw-r--r--firmware/libboard/common/resources/sam3s2/sram.ld140
-rw-r--r--firmware/libboard/common/resources/sam3s2/sram_samba.lds91
-rw-r--r--firmware/libboard/common/resources/sam3s4/flash.ld140
-rw-r--r--firmware/libboard/common/resources/sam3s4/sram.ld140
-rw-r--r--firmware/libboard/common/resources/sam3s4/sram_samba.lds91
-rw-r--r--firmware/libboard/common/resources/sam3s_ek_flash.gdb31
-rw-r--r--firmware/libboard/common/resources/sam3s_ek_sram.gdb27
-rw-r--r--firmware/libboard/common/resources/sam3s_vb_sram.gdb27
-rw-r--r--firmware/libboard/common/source/board_cstartup_gnu.c196
-rw-r--r--firmware/libboard/common/source/board_lowlevel.c185
-rw-r--r--firmware/libboard/common/source/boardver_adc.c83
-rw-r--r--firmware/libboard/common/source/led.c168
-rw-r--r--firmware/libboard/common/source/uart_console.c380
-rw-r--r--firmware/libboard/owhw/include/board.h53
-rw-r--r--firmware/libboard/owhw/source/owhw.c39
-rw-r--r--firmware/libboard/qmod/include/board.h66
-rw-r--r--firmware/libboard/qmod/include/i2c.h5
-rw-r--r--firmware/libboard/qmod/include/wwan_led.h4
-rw-r--r--firmware/libboard/qmod/include/wwan_perst.h4
-rw-r--r--firmware/libboard/qmod/source/i2c.c203
-rw-r--r--firmware/libboard/qmod/source/wwan_led.c80
-rw-r--r--firmware/libboard/qmod/source/wwan_perst.c76
-rw-r--r--firmware/libboard/simtrace/include/board.h85
32 files changed, 3115 insertions, 0 deletions
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